Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   MusicBrainz DiscID (https://www.delphipraxis.net/167948-musicbrainz-discid.html)

Garfield 26. Apr 2012 21:52


MusicBrainz DiscID
 
Hallo,

ich möchte zu einer eingelegten AudioCd die Informationen und das Cover erhalten. Eine Abfrage der FreeDB mittels FreeDBDiscId funktioniert. Aber da gibt es leider kein Cover. Deshalb will ich es mit MusicBrainz versuchen.

Die Ermittlung der DiskID ist auf dieser Seite.

Zum Ausprobieren ist mir diese CD in die Hände gefallen.

Die CD hat die Informationen
Firsttrack: 1
Lasttrack: 11
Duration: 178820 Frames
Offsets: 182 14957 33825 47195 63957 77557 93757 111007 128232 145792 161587

Diese Daten schreibe ich als Hexwerte (Tracks als 1 Byte, Frames als 4 Byte) in einen String:

'010B0002BA84000000B600003A6D000084210000B85B0000F 9D500012EF500016E3D0001B19F0001F4E8000239800002773 3'

Davon wird ein SHA-1-Hash gebildet (z.B. Jedi oder jmrds):

'9c41013ace4617521cca01d54320dde90bc21e81'

Aus diesen 20 Byte muss nun mittels Base64.c ein String mit 28 Zeichen gebildet werden. Dafür habe ich die "A Base64 encoding unit, Written by David Barton" verwendet.

'nEEBOs5GF1IcygHVQyDd6QvCHoH-'

Dieser Wert stimmt jedoch nicht. Richtig wäre

'2V5nq.IgjSVTMEAozGOZwS41Dkg-'

Hat jemand eine Ahnung wo der Fehler sein könnte?

Garfield 27. Apr 2012 04:17

AW: MusicBrainz DiscID
 
Damit am Ende die DiscId

'2V5nq.IgjSVTMEAozGOZwS41Dkg-'

herauskommt müßte der SHA-1 den Wert

'D95E67ABE2208D2553304028CC6399C12E350E48'

besitzen. Das bedeutet die Abfrage ist bereits falsch. :?

Sir Rufo 27. Apr 2012 05:49

AW: MusicBrainz DiscID
 
Warum baust du denn den String nicht so auf, wie hier gezeigt
Zitat:

Zitat von Garfield (Beitrag 1163744)
Die Ermittlung der DiskID ist auf dieser Seite.

Die schreiben dort 1+99 Track-Einträge und wenn keine Tracks mehr kommen, dann einfach Nullen ;)
Zitat:

Calculating the Disc ID
The CD Index algorithm simply takes the following pieces of data and runs them through the SHA-1 hash function:
  • First track number (normally one): 1 byte
  • Last track number: 1 byte
  • Lead-out track offset: 4 bytes
  • 99 frame offsets: 4 bytes for each track
  • If there are less than 99 tracks (almost certainly), the value 0 will be used instead.

Ich bin mir da jetzt auch nicht ganz sicher, aber
Code:
sprintf(temp, "%02X", pCDInfo->First*Track);
sha_update(&sha, (unsigned char*) temp, strlen(temp));

sprintf(temp, "%02X", pCDInfo->Last*Track);
sha_update(&sha, (unsigned char*) temp, strlen(temp));

for (i = 0; i < 100; i++) {
    sprintf(temp, "%08X", pCDInfo->Frame*Offset[i]);
    sha_update(&sha, (unsigned char*) temp, strlen(temp));
}
sha_final(digest, &sha);
ist wohl etwas anderes als alles in einen String zu packen und dann durch den Hash zu jagen

Garfield 27. Apr 2012 07:20

AW: MusicBrainz DiscID
 
Hallo Sir Rufo,

ich musste feststellen, dass es unwichtig ist, ob der String im ganzen oder in Teilen übergeben wird.

Das Auffüllen auf 99 Tracks habe ich übersehen. :oops:
Wobei das Codebeispiel auch falsch sein dürfte. Darin fehlt das Lead-out track offset.

Wie ich sehe, habe ich auch nicht das Lead-Out sondern die Spieldauer der CD genommen. Aber mit
Delphi-Quellcode:
  SHA1Init(Context);

  temp := Format('%2.2x', [fCD.FirstTrack]);
  SHA1Update(Context,@temp[1],length(temp));

  temp := Format('%2.2x', [fCD.LastTrack]);
  SHA1Update(Context,@temp[1],length(temp));

  temp := Format('%8.8x', [msf2frames(fCD.LeadOut)]);
  SHA1Update(Context,@temp[1],length(temp));

  for i := 0 to 99
  do begin
    if i < Length(fCD.Track)
    then temp := Format('%8.8x', [msf2frames(fCD.Track[i].Start)])
    else temp := Format('%8.8x', [0]);
    SHA1Update(Context,@temp[1],length(temp));
  end;

  SHA1Final(Context, Digest);
Delphi-Quellcode:
function msf2frames(addr: TAddr): Cardinal;
begin
  Result := (((addr[1] * 60) + addr[2]) * 75) + addr[3];
end;
bekomme ich leider immer noch nicht den richtigen Wert. :pale:

In der disc.c befindet sich die Erstellung der DiscID:
Code:
242    static void create_disc_id(mb_disc_private *d, char buf[]) {
243        SHA_INFO   sha;
244        unsigned char  digest[20], *base64;
245        unsigned long  size;
246        char       tmp[17]; /* for 8 hex digits (16 to avoid trouble) */
247        int    i;
248    
249        assert( d != NULL );
250    
251        sha_init(&sha);
252    
253        sprintf(tmp, "%02X", d->first_track_num);
254        sha_update(&sha, (unsigned char *) tmp, strlen(tmp));
255    
256        sprintf(tmp, "%02X", d->last_track_num);
257        sha_update(&sha, (unsigned char *) tmp, strlen(tmp));
258    
259        for (i = 0; i < 100; i++) {
260            sprintf(tmp, "%08X", d->track_offsets[i]);
261            sha_update(&sha, (unsigned char *) tmp, strlen(tmp));
262        }
263    
264        sha_final(digest, &sha);
265    
266        base64 = rfc822_binary(digest, sizeof(digest), &size);
267    
268        memcpy(buf, base64, size);
269        buf[size] = '\0';
270    
271        free(base64);
272    }

angos 27. Apr 2012 07:54

AW: MusicBrainz DiscID
 
Hi,

du brauchst 99 Tracks, fügst aber 100 an:

Delphi-Quellcode:
//for i := 0 to 99
for i := 0 to 98

Gruß

Garfield 27. Apr 2012 08:18

AW: MusicBrainz DiscID
 
Danke angos. Ich habe mich von
Code:
for (i = 0; i < 100; i++)
ablenken lassen. An Stelle 0 steht das Lead-out. Mit for i := 0 to 98 funktioniert es.


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:50 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz