DISCIDの算出に使うのは、各曲の開始位置のフレーム番号ではなく、各曲の開始位置の秒数でした。
間違いに気が付いたのは、やはり英語ドキュメントをざっと読んだから。
で、ドライブを指定して、その中のcdaファイルを取得し、そこからDiscIDを計算するロジックなんてものを、さらっとDelphiで書いてみたので参考までに。手持ちのCD3枚程度で試したけど、結果良好でした。
function calcFingerPrint(n: LongInt) : Integer;varR : Integer;beginR := 0;while (n > 0) do beginR := R + (n mod 10);n := (n div 10);end;Result := R;end;function getDiscID(Drive: String) : String;typerowdata = array[0..43] of byte;TCDA = recordRow: rowdata;StartFrame: Integer;StartSec: Integer;StartMin: Integer;StartHur: Integer;StartTime: LongInt;StartFrames: LongInt;LengFrame: Integer;LengSec: Integer;LengMin: Integer;LengHur: Integer;LengTime: LongInt;LengFrames: LongInt;FingerPrint: Integer;end;cdafile = file of rowdata;varDS : String;SR : TSearchRec;CT : Integer;FL : TStringList;CDAS: Array of TCDA;I : Integer;FN : String;FS: TFileStream;SF : LongInt;FT : Integer;LN : Integer;KV : LongInt;KVS : String;CMD : String;TT : LongInt;beginDS := Drive + ':\';CT := 0;FT := 0;TT := 0;FL := TStringList.Create;// 指定されたドライブのトラック数取得if FindFirst(DS + '*.cda', faAnyFile, SR) = 0 then beginrepeatif not( (SR.Name = '.') or (SR.Name = '..') ) then beginif ExtractFileExt(SR.Name)= '.cda' then begininc(CT);FL.Add(SR.Name);end;end;until FindNext(SR) <> 0;FindClose(SR);SetLength(CDAS,CT);end;// CDAファイルの内容読込みfor I := 0 to CT - 1 do beginFN := DS + FL[I];FS := TFileStream.Create(FN,fmShareExclusive);FS.Read(CDAS[I].Row,SizeOf(CDAS[I].Row));FS.Free;end;// CDAファイルの解釈for I := 0 to CT - 1 do beginwith CDAS[I] do beginStartFrame := Ord(Row[36]);StartSec := Ord(Row[37]);StartMin := Ord(Row[38]);StartHur := Ord(Row[39]);LengFrame := Ord(Row[40]);LengSec := Ord(Row[41]);LengMin := Ord(Row[42]);LengHur := Ord(Row[43]);StartTime := StartHur * 3600 + StartMin * 60 + StartSec;LengTime := LengHur * 3600 + LengMin * 60 + LengSec;TT := TT + LengTime;// スタートフレーム数SF := StartFrame + StartTime * 75;StartFrames := SF;LengFrames := LengFrame + LengTime * 75;FingerPrint := calcFingerPrint(StartTime);FT := FT + FingerPrint;end;end;// キー生成FT := FT mod 255;LN := round((CDAS[CT - 1].StartFrames + CDAS[CT - 1].LengFrames -CDAS[0].StartFrames) / 75);KV := FT * 16777216 + LN * 256 + CT;KVS := IntToHex(KV,8);// コマンド生成CMD := 'cmd=cddb+query+' + KVS + '+' + IntToStr(CT) + '+';for I := 0 to CT - 1 doCMD := CMD + IntToStr(CDAS[I].StartFrames) + '+';CMD := CMD + IntToStr(TT);Result := CMD;end;
【Delphiの最新記事】