//Bits - ?
unit AudioTwinVQ;

interface

uses Windows, KOL, ATLCommon, TagTwinVQ, TagApe;

type TTwinVQAudioInfo = PAudioInfo;

function NewAudioTwinVQ: TTwinVQAudioInfo;

implementation

uses ATLLib;

type
  TChunkHeader = record
    ID: array [1..4] of Char;                                      { Chunk ID }
    Size: Cardinal;                                              { Chunk size }
  end;

  THeaderInfo = packed record
    ID: array [1..4] of Char;                                 { Always "TWIN" }
    Version: array [1..8] of Char;                               { Version ID }
    Size: Cardinal;                                             { Header size }
    Common: TChunkHeader;                                { Common chunk header }
    ChannelMode: Cardinal;               { Channel mode: 0 - mono, 1 - stereo }
    BitRate: Cardinal;                                       { Total bit rate }
    SampleRate: Cardinal;                                 { Sample rate (khz) }
    SecurityLevel: Cardinal;                                       { Always 0 }
  end;

type
  TAudioTwinVQ = object(TAudioInfo)
  private
  end;

function AudioTwinVQReader(const AFileName: KOLstring; AudioInfo: TTwinVQAudioInfo): Boolean; forward;

function NewAudioTwinVQ: TTwinVQAudioInfo;
begin
    New(Result, Create);
    with TAudioTwinVQ(Result^) do begin
      TagAdd(tTwinVQ, NewTagTwinVQ);
      TagAdd(tApe, NewTagAPE);
      FAudioVendor:= aTwinVQ;
      FExistsProps:= [apSampleRate, apBitrate, apChannels, apBits, apDuration, apRatio];
      FReader:= AudioTwinVQReader;
    end;
end;

function AudioTwinVQReader(const AFileName: KOLstring; AudioInfo: TTwinVQAudioInfo): Boolean;
var Header: THeaderInfo;
    SourceFile: PStream;
    TagSize: Cardinal;
begin
    with TAudioTwinVQ(AudioInfo^) do begin
      Result:= False;
      try
        ResetData;
        SourceFile:= OpenFileRead(AFileName);
        if (SourceFile.Read(Header, SizeOf(Header)) = SizeOf(Header)) and (Header.ID = TWIN_ID) then begin

          TagInfo[tTwinVQ].ReadFromFile(AFileName);
          TagInfo[tApe].ReadFromFile(AFileName);
          FFileSize := SourceFile.Size;

          FChannels:= SwapOrder32(Header.ChannelMode)+1;
          FBitRate:= SwapOrder32(Header.BitRate);
          FSampleRate := SwapOrder32(Header.SampleRate);
          FBits:= 16;
          case FSampleRate of
            11: FSampleRate:= 11025;
            22: FSampleRate:= 22050;
            44: FSampleRate:= 44100;
            else FSampleRate:= FSampleRate * 1000;
          end;
          TagSize:= TagInfo[tApe].TagSize + SwapOrder32(Header.Size) - 20;
          FDuration := Abs(8 * (FFileSize - TagSize)) / 1000 / FBitRate;
          FRatio := (FFileSize - TagSize) / ((FDuration * FSampleRate) * (FChannels * FBits / 8) + 44) * 100;
          FValid:= ((FBitRate >= 8) and (FBitRate <= 192) or (FSampleRate >= 8000) or (FSampleRate <= 44100) or (FDuration >= 0.1) or (FDuration <= 10000));
        end;
        Result:= True;
        SourceFile.Free;
      except
      end;
    end;
end;

end.
