⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bincuereader.pas

📁 用于CD/DVD烧录的Delphi源码,包括source和demo
💻 PAS
📖 第 1 页 / 共 2 页
字号:
{-----------------------------------------------------------------------------
 Unit Name: BinCueReader
 Author:    Dancemammal
 Purpose:   Read and extract tracks from BIN / CUE files
 History:   First Release
-----------------------------------------------------------------------------}


unit BinCueReader;

interface

Uses Classes,Windows,sysutils,StrUtils;


Const
      MODE_UNKNOWN = 0;
      MODE_AUDIO = 1;
      MODE_MODE1 = 2;
      MODE_MODE2 = 3;
      MODE_MODE2_FORM1 = 4;
      MODE_MODE2_FORM2 = 5;
      MODE_MODE1_2048 = 6;
      MODE_MODE2_2048 = 7;

      CUE_OK               = 0;
      CUE_CUEMISSING       = 1;
      CUE_BINMISSING       = 2;
      CUE_CUEFILEEXPECTED  = 3;
      CUE_BINFILEEXPECTED  = 4;
      CUE_BINARYEXPECTED   = 5;
      CUE_TRACKEXPECTED    = 6;
      CUE_TRACKNUMEXPECTED = 7;
      CUE_INDEXEXPECTED    = 8;
      CUE_INDEXNUMEXPECTED = 9;
      CUE_INDEXMSFEXPECTED = 10;
      CUE_UNKNOWN_ERROR    = 11;

      PostLeadInGapTime    = 150;


type
  TWaveHeader = record
    { RIFF file header }
    RIFFHeader   : array[1..4] of Char; { Must be "RIFF" }
    FileSize     : Integer; { Must be "RealFileSize - 8" }
    WAVEHeader   : array[1..4] of Char; { Must be "WAVE" }
    { Format information }
    FormatHeader : array[1..4] of Char; { Must be "fmt " }
    FormatSize   : DWord; { Must be 16 (decimal) }
    FormatCode   : Word; { Must be 1 }
    ChannelNumber: Word; { Number of channels }
    SampleRate   : DWord; { Sample rate (hz) }
    BytesPerSecond: DWord; { Bytes per second }
    BytesPerSample: Word; { Bytes per Sample }
    BitsPerSample : Word; { Bits per sample }
    ExtraFormatBytes: Word;
    { Data area }
    DataHeader    : array[1..4] of Char; { Must be "data" }
    DataSize      : DWord; { Data size }
  end;



Type
 TATIPCue = Packed Record
    CTL_ADR   : Byte;   // control field
    TNO       : Byte;   // track number
    Index     : Byte;   // Index number
    DataForm  : Byte;   // data form ??
    SCMS      : Byte;   // Serial Copy Managment system
    Min       : Byte;
    Sec       : Byte;
    Frame     : Byte;
  end;



Type
  TATIPCueList = Packed Record
       Cues : Array[0..98] of TATIPCue;
       Count : Integer;
       BurnMode : Integer;
   end;



Type
   TIndex = Packed Record
      LBA      : Integer;
      ATIP     : Integer;
      IndexNum : Integer;
    end;




Type
 TTrack = Packed Record
     Mode       : Integer;
     ModeDesc   : String[30];
     FileType   : String[20];
     FileName   : String[255];
     FileSize   : LongInt;
     PreGap     : Integer;
     PreATIP    : Integer;
     Index      : Array[0..98] of TIndex;
     FirstIndex : Integer;
     IndexCount : Integer;
     TrackNumber : Integer;
   end;

Type
  TTrackList = Packed Record
     Tracks : Array[0..98] of TTrack;
     Count : Integer;
   end;


TExtractProgress = procedure(PercentDone: Integer; Cancel : Boolean) of object;

Type
    TBinCueReader = Class
    Private
       CurrentTrack : Integer;
       CurrentFileType : String;
       CurrentIndexCount : Integer;
       CueBuilderIndex : Integer;
       FCueFileName : String;
       FBinFileName : String;
       FExtractProcess : TExtractProgress;
       FBinTracks : TTrackList;
       FCUEList : Tstringlist;
       FTitle : String;
       FPerformer : String;
       FSongWriter : String;
       FCatalog : String;
       FATIPCounter : Integer;
       FATIPCueList : TATIPCueList;
       FCuePath     : String;
       Function GetATIPCueList : TATIPCueList;
       Function TrackModeToString(TrackMode : Integer): String;
       Function StrToMode(TrackVal : String): Integer;
       Function Parse(CueLine : String) : Integer;
       Procedure AddPostLeadInGap;
       Procedure SetupLeadIn;
       Procedure SetupLeadOut;
       Procedure CheckPreGap(Track : TTrack);
       Procedure AddTrackToCUE(Track : TTrack);
       Function BinLength(FileName : String):Integer;
       Function WavLength(FileName : String):Integer;
    Public
      Function ExtractTrack(TrackNo : Integer; ToFileName : String ) : Boolean;
      Function TrackMode(TrackNo : Integer): Integer;
      Function OpenCueFile(FileName : String) : Integer;
      Procedure SaveATIPCueToFile(FileName : String);
      Constructor Create;
      Destructor Destroy; override;
    Published
      property OnExtractProcess: TExtractProgress read FExtractProcess write FExtractProcess;
      property CueFileName: String read FCueFileName write FCueFileName;
      property BinFileName: String read FBinFileName write FBinFileName;
      Property BinTrackList : TTrackList Read FBinTracks;
      Property ATIPCueList : TATIPCueList Read GetATIPCueList;
      property Title : String read FTitle write FTitle;
      property Performer : String read FPerformer write FPerformer;
      property SongWriter : String read FSongWriter write FSongWriter;
      property Catalog : String read FCatalog write FCatalog;
   end;


implementation

uses covertfuncs,ReadWave;


function HMSFtoLBA(const  AMinute, ASecond, AFrame: Byte): LongWord;
begin
   Result := (AMinute * 60 * 75) + (ASecond * 75) + AFrame;
end;


Function StrToLBA(HSF : String) : LongWord;
var
    AMinute, ASecond, AFrame :Byte;
   TempStr,Coded : String;
begin
   Coded := HSF;
   TempStr := copy(Coded,0,pos(':',Coded)-1);
   AMinute := strtoint(TempStr);
   delete(Coded,1,pos(':',Coded));

   TempStr := copy(Coded,0,pos(':',Coded)-1);
   ASecond := strtoint(TempStr);
   delete(Coded,1,pos(':',Coded));

   TempStr := copy(Coded,0,99);
   AFrame := strtoint(TempStr);

   Result := HMSFtoLBA(AMinute,ASecond,AFrame);
end;



Constructor TBinCueReader.Create;
begin
    FCUEList := Tstringlist.create;
    FATIPCounter := 0;
end;


Destructor TBinCueReader.Destroy;
begin
   FCUEList.Clear;
   FCUEList.Free;
end;


Function TBinCueReader.StrToMode(TrackVal : String): Integer;
begin
      Result := MODE_UNKNOWN;
      If TrackVal = 'AUDIO' then Result := MODE_AUDIO;
      If TrackVal = 'MODE1/2352' then Result := MODE_MODE1;
      If TrackVal = 'MODE2/2352' then Result := MODE_MODE2;
      If TrackVal = 'MODE2FORM1/2352' then Result := MODE_MODE2_FORM1;
      If TrackVal = 'MODE2FORM2/2352' then Result := MODE_MODE2_FORM2;
      If TrackVal = 'MODE1/2048' then Result := MODE_MODE1_2048;
      If TrackVal = 'MODE2/2048' then Result := MODE_MODE2_2048;
End;


Function TBinCueReader.TrackModeToString(TrackMode : Integer): String;
begin
     Result := 'MODE UNKNOWN';
     Case TrackMode of
        1 : Result := 'AUDIO';
        2 : Result := 'MODE1 / 2352';
        3 : Result := 'MODE2 / 2352';
        4 : Result := 'MODE2 FORM1 / 2352';
        5 : Result := 'MODE2 FORM2 / 2352';
        6 : Result := 'MODE1 / 2048';
        7 : Result := 'MODE2 / 2048';
     end;
end;


Function TBinCueReader.TrackMode(TrackNo : Integer):Integer;
begin
    Result := FBinTracks.Tracks[TrackNo -1].Mode;
end;



Function TBinCueReader.WavLength(FileName : String):Integer;
var
  Header: PWaveInformation;
  Count : LongInt;
  Secs, Mins, Frames : Integer;
begin
  Result := 0;
  Header := GetWaveInformationFromFile(FileName);
  Count := round(Header^.Length);
  Dispose(Header);
  Result := Count;
end;


Function TBinCueReader.BinLength(FileName : String):Integer;
begin
  Result := 0;
  with TFileStream.Create(FileName, fmOpenRead) do
    try
     Result := Size;
    finally
      Free;
    end;
end;



{
FILE "VIDEOC~1.BIN" BINARY
TRACK 01 MODE2/2352
INDEX 01 00:00:00
TRACK 02 MODE2/2352
INDEX 00 00:04:00
INDEX 01 00:06:00
TRACK 03 MODE2/2352
INDEX 00 00:37:52
INDEX 01 00:39:52


TITLE "Enter title (disc or track)"
PERFORMER "Enter Performer (disc or track)"
SONGWRITER "Enter Songwriter (disc or track)"
CATALOG 1234567890123

FILE "C:\TRACK1.WAV" WAVE
  TRACK 01 AUDIO
    PREGAP 00:02:00
    INDEX 01 00:00:00
FILE "C:\TRACK2.WAV" WAVE
  TRACK 02 AUDIO
    PREGAP 00:02:00
    INDEX 01 00:00:00
}


Function TBinCueReader.Parse(CueLine : String) : Integer;
var
   Filename,Filetype : String;
   TrackNo, TrackType, IndexNo, TrackSecs : String;
   TempCopy,Line : String;
   IndexInt, TrackLength : Integer;
begin
   Line := Trim(CueLine);
   TempCopy := Copy(Line,0,Pos(' ',Line)-1);  // get KeyWord (FILE, TRACK, INDEX etc)
   Delete(Line,1,Pos(' ',Line));

   if (TempCopy = 'FILE') then //FILE "VIDEOC~1.BIN" BINARY
    begin
        Delete(Line,1,Pos('"',Line));
        Filename := Copy(Line,0,pos('"',Line)-1); // filename
        FileName := AnsiReplaceStr(FileName,'"','');
        Delete(Line,1,Pos('"',Line));
        Filetype := Copy(Line,0,100);
        FBinFileName := trim(FileName);
        CurrentFileType := trim(Filetype);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -