📄 bincuereader.pas
字号:
exit;
end;
if (TempCopy = 'TITLE') then //TITLE "Enter title (disc or track)"
begin
Filename := Copy(Line,0,99); // title
FileName := AnsiReplaceStr(FileName,'"','');
FTitle := trim(FileName);
exit;
end;
if (TempCopy = 'PERFORMER') then //PERFORMER "Enter Performer (disc or track)"
begin
Filename := Copy(Line,0,99); // title
FileName := AnsiReplaceStr(FileName,'"','');
FPerformer := trim(FileName);
exit;
end;
if (TempCopy = 'SONGWRITER') then //SONGWRITER "Enter Songwriter (disc or track)"
begin
Filename := Copy(Line,0,99); // title
FileName := AnsiReplaceStr(FileName,'"','');
FSongWriter := trim(FileName);
exit;
end;
if (TempCopy = 'CATALOG') then //CATALOG 1234567890123
begin
Filename := Copy(Line,0,99); // title
FCatalog := trim(FileName);
exit;
end;
if (TempCopy = 'TRACK') then //TRACK 01 MODE2/2352
begin
TrackNo := Copy(Line,0,pos(' ',Line)-1); // Track no
Delete(Line,1,Pos(' ',Line));
TrackType := Copy(Line,0,100);
if (CurrentTrack > 0) then
inc(FATIPCounter,FBinTracks.Tracks[CurrentTrack -1].FileSize); // add on length of last file ?
CurrentTrack := strtoint(TrackNo);
FBinTracks.Tracks[CurrentTrack -1].FileName := FBinFileName;
FBinTracks.Tracks[CurrentTrack -1].Mode := StrToMode(trim(TrackType));
FBinTracks.Tracks[CurrentTrack -1].ModeDesc := TrackModeToString(StrToMode(trim(TrackType)));
FBinTracks.Tracks[CurrentTrack -1].FirstIndex := -1;
FBinTracks.Tracks[CurrentTrack -1].PreGap := 0;
FBinTracks.Tracks[CurrentTrack -1].TrackNumber := CurrentTrack;
if CurrentFileType = 'WAVE' then
begin
TrackLength := WavLength(FBinFileName);
FBinTracks.Tracks[CurrentTrack -1].FileSize := TrackLength;
end
else
if CurrentFileType = 'BINARY' then
begin
TrackLength := BinLength(FBinFileName);
FBinTracks.Tracks[CurrentTrack -1].FileSize := TrackLength;
end;
CurrentIndexCount := 0;
Exit;
end;
if (TempCopy = 'PREGAP') then //PREGAP 00:02:00
begin
TrackSecs := Copy(Line,0,100); //00:02:00
FBinTracks.Tracks[CurrentTrack -1].PreGap := StrToLBA(TrackSecs);
inc(FATIPCounter,FBinTracks.Tracks[CurrentTrack -1].PreGap);
FBinTracks.Tracks[CurrentTrack -1].PreATIP := FATIPCounter;
Exit;
end;
if (TempCopy = 'INDEX') then //INDEX 00 00:00:00 INDEX 01 03:28:42
begin
IndexNo := Copy(Line,0,pos(' ',Line)-1); // Index no
IndexInt := strtoint(IndexNo);
Delete(Line,1,Pos(' ',Line));
TrackSecs := Copy(Line,0,100);
if (FBinTracks.Tracks[CurrentTrack -1].FirstIndex = -1) then
FBinTracks.Tracks[CurrentTrack -1].FirstIndex := IndexInt;
FBinTracks.Tracks[CurrentTrack -1].Index[IndexInt].LBA := StrToLBA(TrackSecs);
inc(FATIPCounter,FBinTracks.Tracks[CurrentTrack -1].Index[IndexInt].LBA);
FBinTracks.Tracks[CurrentTrack -1].Index[IndexInt].ATIP := FATIPCounter;
FBinTracks.Tracks[CurrentTrack -1].Index[IndexInt].IndexNum := IndexInt;
FBinTracks.Tracks[CurrentTrack -1].IndexCount := (CurrentIndexCount + 1);
inc(CurrentIndexCount);
FBinTracks.Tracks[CurrentTrack -1].FileType := CurrentFileType;
Exit;
end;
end;
Function TBinCueReader.OpenCueFile(FileName : String) : Integer;
var
Count : Integer;
BufString : String;
begin
Result := CUE_OK;
if not fileexists(Filename) then
begin
Result := CUE_CUEMISSING;
exit;
end;
CurrentTrack := 0;
CurrentIndexCount := 0;
FATIPCounter := 150;
FCUEList.LoadFromFile(Filename);
FCuePath := ExtractFilePath(FileName);
for Count := 0 to FCUEList.Count -1 do
begin
BufString := FCUEList.Strings[Count];
Result := Parse(Trim(BufString));
end;
inc(FATIPCounter,FBinTracks.Tracks[CurrentTrack -1].FileSize); // add on length of last file for lead out
FBinTracks.Count := CurrentTrack;
end;
Function TBinCueReader.ExtractTrack(TrackNo : Integer; ToFileName : String ) : Boolean;
Const
ChunkSize = 65535;
var
lngStart, lngEnd, Counter : Integer; //start and end offset
BinFileStream, OUTFileStream : TFileStream; // file Streams
StreamBuf : PChar; //read buffer
blnCancel : Boolean;
BytesWritten : Integer;
Begin
BytesWritten := 0;
blnCancel := False;
BinFileStream := TFileStream.Create(FBinFileName, fmOpenRead);
//Get Start LBA
with FBinTracks.Tracks[TrackNo -1] do
if FirstIndex = 0 then
lngStart := Index[1].LBA * 2352
else
lngStart := index[0].LBA * 2352;
//get the LBA of the next track
If TrackNo = FBinTracks.Count Then
lngEnd := (BinFileStream.Size - lngStart)
Else
lngEnd := FBinTracks.Tracks[TrackNo].index[0].LBA * 2352;
// Setup seek pos and output file
BinFileStream.Seek((lngStart + 1), soFromBeginning);
OUTFileStream := TFileStream.Create(ToFileName, fmOpenRead);
// extract data
While (BytesWritten < (lngEnd - lngStart)) do
begin
If (ChunkSize + BinFileStream.Position > lngEnd) Then
Counter := (lngEnd - BinFileStream.Position)
else
Counter := ChunkSize;
BytesWritten := BytesWritten + BinFileStream.Read(StreamBuf^,Counter);
OUTFileStream.Write(StreamBuf^,Counter);
if Assigned(FExtractProcess) then FExtractProcess(BytesWritten div ((lngEnd - lngStart) div 100), blnCancel);
If blnCancel Then Exit;
end;
OUTFileStream.free;
BinFileStream.free;
End;
// add cue line for 2 second gap (150 lba) after lead in
Procedure TBinCueReader.AddPostLeadInGap;
begin
FATIPCueList.Cues[CueBuilderIndex].CTL_ADR := $01;
FATIPCueList.Cues[CueBuilderIndex].TNO := $01;
FATIPCueList.Cues[CueBuilderIndex].Index := $00;
FATIPCueList.Cues[CueBuilderIndex].DataForm := $01;
FATIPCueList.Cues[CueBuilderIndex].SCMS := $00;
FATIPCueList.Cues[CueBuilderIndex].Min := $00;
FATIPCueList.Cues[CueBuilderIndex].Sec := $00;
FATIPCueList.Cues[CueBuilderIndex].Frame := $00;
inc(CueBuilderIndex);
end;
// set up first CUE as disk lead in
Procedure TBinCueReader.SetupLeadIn;
begin
FATIPCueList.Cues[0].CTL_ADR := $01;
FATIPCueList.Cues[0].TNO := $00;
FATIPCueList.Cues[0].Index := $00;
FATIPCueList.Cues[0].DataForm := $01;
FATIPCueList.Cues[0].SCMS := $00;
FATIPCueList.Cues[0].Min := $00;
FATIPCueList.Cues[0].Sec := $00;
FATIPCueList.Cues[0].Frame := $00;
CueBuilderIndex := 1;
AddPostLeadInGap;
end;
// set up Last CUE as disk lead out
Procedure TBinCueReader.SetupLeadOut;
var
Min, Sec, Frm : Integer;
begin
LBA2MSF(FATIPCounter, Min, Sec, Frm);
FATIPCueList.Cues[CueBuilderIndex].CTL_ADR := $01;
FATIPCueList.Cues[CueBuilderIndex].TNO := $AA;
FATIPCueList.Cues[CueBuilderIndex].Index := $01;
FATIPCueList.Cues[CueBuilderIndex].DataForm := $01;
FATIPCueList.Cues[CueBuilderIndex].SCMS := $00;
FATIPCueList.Cues[CueBuilderIndex].Min := Min;
FATIPCueList.Cues[CueBuilderIndex].Sec := Sec;
FATIPCueList.Cues[CueBuilderIndex].Frame := Frm;
FATIPCueList.Count := CueBuilderIndex;
end;
Procedure TBinCueReader.CheckPreGap(Track : TTrack);
var
Min, Sec, Frm : Integer;
begin
if (Track.PreGap <> 0) then
begin
LBA2MSF(Track.PreATIP, Min, Sec, Frm);
FATIPCueList.Cues[CueBuilderIndex].CTL_ADR := $41;
FATIPCueList.Cues[CueBuilderIndex].TNO := Track.TrackNumber;
FATIPCueList.Cues[CueBuilderIndex].Index := $00;
FATIPCueList.Cues[CueBuilderIndex].DataForm := $10;
FATIPCueList.Cues[CueBuilderIndex].SCMS := $00;
FATIPCueList.Cues[CueBuilderIndex].Min := Min;
FATIPCueList.Cues[CueBuilderIndex].Sec := Sec;
FATIPCueList.Cues[CueBuilderIndex].Frame := Frm;
inc(CueBuilderIndex);
end;
end;
Procedure TBinCueReader.AddTrackToCUE(Track : TTrack);
Var
IndexCnt : Integer;
Min, Sec, Frm : Integer;
Count : Integer;
begin
CheckPreGap(Track);
FATIPCueList.BurnMode := Track.Mode;
for IndexCnt := Track.FirstIndex to Track.IndexCount do
begin
LBA2MSF(Track.Index[IndexCnt].ATIP, Min, Sec, Frm);
FATIPCueList.Cues[CueBuilderIndex].CTL_ADR := $41; // can copy and is trc index
FATIPCueList.Cues[CueBuilderIndex].TNO := Track.TrackNumber;
FATIPCueList.Cues[CueBuilderIndex].Index := Track.Index[IndexCnt].IndexNum;
FATIPCueList.Cues[CueBuilderIndex].DataForm := $C0;
FATIPCueList.Cues[CueBuilderIndex].SCMS := $00;
FATIPCueList.Cues[CueBuilderIndex].Min := Min;
FATIPCueList.Cues[CueBuilderIndex].Sec := Sec;
FATIPCueList.Cues[CueBuilderIndex].Frame := Frm;
inc(CueBuilderIndex);
end;
end;
Procedure TBinCueReader.SaveATIPCueToFile(FileName : String);
var
Index : Integer;
CueFile : TStringlist;
Temp : String;
begin
CueFile := TStringlist.create;
GetATIPCueList;
CueFile.Add('| Count | CTL/ADR | TRK No | Index | Data Form | SCMS | MIN | SEC | Frame |');
CueFile.add('-------------------------------------------------------------------------------------------');
for Index := 0 to 98 do
begin
Temp := '| '+Inttostr(Index)+' ';
Temp :=Temp+'| '+InttoHex(FATIPCueList.Cues[index].CTL_ADR,2)+' ';
Temp :=Temp+'| '+InttoHex(FATIPCueList.Cues[index].TNO,2)+' ';
Temp :=Temp+'| '+InttoHex(FATIPCueList.Cues[index].Index,2)+' ';
Temp :=Temp+'| '+InttoHex(FATIPCueList.Cues[index].DataForm,2)+' ';
Temp :=Temp+'| '+InttoHex(FATIPCueList.Cues[index].SCMS,2)+' ';
Temp :=Temp+'| '+Inttostr(FATIPCueList.Cues[index].Min)+' ';
Temp :=Temp+'| '+Inttostr(FATIPCueList.Cues[index].Sec)+' ';
Temp :=Temp+'| '+Inttostr(FATIPCueList.Cues[index].Frame)+' ';
CueFile.add(Temp);
end;
CueFile.SaveToFile(Filename);
end;
Function TBinCueReader.GetATIPCueList : TATIPCueList;
var
Index : Integer;
begin
CueBuilderIndex := 0;
SetupLeadIn;
for Index := 0 to BinTrackList.Count -1 do
AddTrackToCUE(BinTrackList.Tracks[Index]);
SetupLeadOut;
result := FATIPCueList;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -