unit AudioVerify;

interface

uses KOL, ATLCommon;

type
  PAudioVerify = ^TVerifyAudio;
  TAudioVerify = PAudioVerify;
  TVerifyAudio = object(TObj)
  private
    FAudioInfo: PAudioInfo;
    function ReadAudio(AReader: Pointer; AFileName: KOLString): Boolean;
    function GetAudioVendor: TAudioVendor;
    function GetValid: Boolean;
  public
    constructor Create;
    destructor Destroy; virtual;
    function VerifyAudio(AFileName: KOLString): Boolean;
    property Valid: Boolean read GetValid;
    property AudioVendor: TAudioVendor read GetAudioVendor;
    property AudioInfo: PAudioInfo read FAudioInfo;
  end;

  function NewAudioVerify: PAudioVerify;

implementation

uses ATLConstEx,
     AudioWav, AudioWAVPack, AudioMonkey, AudioOGG, AudioAC3, AudioAAC,
     AudioDTS, AudioTTA, AudioWMA, AudioOptimFrog, AudioFLAC, AudioTwinVQ,
     AudioCDATrack, AudioMPEG, AudioMPEGplus, AudioMP4;

{ TVerifyAudio }

type TReader = function: PAudioInfo;
const Audio: array [TAudioVendor] of Pointer = (@NewAudioWav, @NewAudioWAVPack, @NewAudioMonkey, @NewAudioOGG, @NewAudioAC3, @NewAudioAAC, @NewAudioDTS, @NewAudioTTA, @NewAudioWMA, @NewAudioOptimFrog, @NewAudioFlac, @NewAudioTwinVQ, @NewAudioCDATrack, @NewAudioMPEG, @NewAudioMPEGplus, @NewAudioMP4, nil);

function NewAudioVerify: PAudioVerify;
begin
    New(Result, Create);
end;

constructor TVerifyAudio.Create;
begin
    inherited;
    FAudioInfo:= nil;
end;

destructor TVerifyAudio.Destroy;
begin
    if FAudioInfo <> nil then FAudioInfo.Free;
    inherited;
end;

function TVerifyAudio.GetAudioVendor: TAudioVendor;
begin
    Result:= aUnknown;
    if FAudioInfo <> nil then Result:= FAudioInfo.AudioVendor;  
end;

function TVerifyAudio.GetValid: Boolean;
begin
    Result:= False;
    if FAudioInfo <> nil then Result:= FAudioInfo.Valid;
end;

function TVerifyAudio.ReadAudio(AReader: Pointer; AFileName: KOLString): Boolean;
begin
    if FAudioInfo <> nil then FAudioInfo.Free;
    FAudioInfo:= TReader(AReader);
    Result:= AudioInfo.ReadFromFile(AFileName) and AudioInfo.Valid;
    if not Result then Free_And_Nil(FAudioInfo);
end;

function TVerifyAudio.VerifyAudio(AFileName: KOLString): Boolean;
var i, V: TAudioVendor;
begin
    V:= Ext2AudioVendor(ExtractFileExt(AFileName));
    Result:= ReadAudio(Audio[V], AFileName);
    if Result then Exit;
    for i:= Low(TAudioVendor) to Pred(High(TAudioVendor)) do
      if (i <> V) then begin
        Result:= ReadAudio(Audio[i], AFileName);
        if Result then Exit;
      end;
end;

end.
