mp3 id3 z cddb

Patrik Skovajsa cracken na zoznam.sk
Středa Červen 18 22:16:34 CEST 2003


Zdravim vsetkych v konfere, mp3 id3 z cddb je zaujmavy problem o ktorom
som i ja v minulosti rozmyslal avsak vtedy to bolo na mna dost. Robil
som nejake pokusy s vypalovanim AudioCD z Mp3 a nasledne vyskusat dane 
CD na CDDB/FREEDB a zakazdym to fungovalo ako z originalneho CD. Ako
MP3compresor som pouzil bladeenc i lame. Usudil som, ze z MP3 sa urcite 
bude dat vygenerovat discid. Tymto sa vas chcem opytat ci by niekto 
nemal zaujem napisat program (napr. v C) ktory by riesil dany problem.
Mohol by 
fungovat napr. tak, ze mu zadame vstupny adresar z MP3, ktore musia 
byt samozrejme riadne ocislovane napr. 01xxx.mp3 az 25xxx.mp3. 
Program spli ulohu a zapise id3tag. Keby sa do pisania programu 
zapojilo viac ludi som si isty, ze by to ani dlho netrvalo. Tu je
discid algoritmus z freedb.org:

CDDB/FREEDB DISCID ALGORITHM
----------------------------

The following is a C code example that illustrates how to generate the
CDDB/freedb disc ID. Examples in other programming languages may be
found on
the freedb web site at http://www.freedb.org in the developers-section.
A text description of the algorithm follows, which should contain the
necessary
information to code the algorithm in any programming language.


struct toc {
	int	min;
	int	sec;
	int	frame;
};

struct toc cdtoc[100];

int
read_cdtoc_from_drive(void)
{
	/* Do whatever is appropriate to read the TOC of the CD
	 * into the cdtoc[] structure array.
	 */
	return (tot_trks);
}

int
cddb_sum(int n)
{
	int	ret;

	/* For backward compatibility this algorithm must not change */

	ret = 0;

	while (n > 0) {
		ret = ret + (n % 10);
		n = n / 10;
	}

	return (ret);
}

unsigned long
cddb_discid(int tot_trks)
{
	int	i,
		t = 0,
		n = 0;

	/* For backward compatibility this algorithm must not change */

	i = 0;

	while (i < tot_trks) {
		n = n + cddb_sum((cdtoc[i].min * 60) + cdtoc[i].sec);
		i++;
	}

	t = ((cdtoc[tot_trks].min * 60) + cdtoc[tot_trks].sec) -
	    ((cdtoc[0].min * 60) + cdtoc[0].sec);

	return ((n % 0xff) << 24 | t << 8 | tot_trks);
}

main()
{
	int tot_trks;

	tot_trks = read_cdtoc_from_drive();
	printf("The discid is %08x", cddb_discid(tot_trks));
}


This code assumes that your compiler and architecture support 32-bit
integers.

The cddb_discid function computes the discid based on the CD's TOC data
in MSF
form.  The frames are ignored for this purpose.  The function is passed
a
parameter of tot_trks (which is the total number of tracks on the CD),
and
returns the discid integer number.

It is assumed that cdtoc[] is an array of data structures (records)
containing
the fields min, sec and frame, which are the minute, second and frame
offsets
(the starting location) of each track.  This information is read from
the TOC
of the CD.  There are actually tot_trks + 1 "active" elements in the
array, the
last one being the offset of the lead-out (also known as track 0xAA).

The function loops through each track in the TOC, and for each track it
takes
the (M * 60) + S (total offset in seconds) of the track and feeds it to
cddb_sum() function, which simply adds the value of each digit in the
decimal
string representation of the number. A running sum of this result for
each
track is kept in the variable n.

At the end of the loop:
1. t is calculated by subtracting the (M * 60) + S offset of the
lead-out minus
the (M * 60) + S offset of first track (yielding the length of the disc
in
seconds).

2. The result of (n modulo FFh) is left-shifted by 24 bits.

3. t is left shifted by 8.

The bitwise-OR operation of result 2., 3. and the tot_trks number is
used as
the discid.

The discid is represented in hexadecimal form for the purpose of xmcd
cddb file
names and the DISCID= field in the xmcd cddb file itself. If the
hexadecimal
string is less than 8 characters long, it is zero-padded to 8 characters
(i.e.,
3a8f07 becomes 003a8f07).  All alpha characters in the string should be
in
lower case, where applicable.

-----------------

Tu je trochu iny sposob:

/* Code to get discid for a cddb query.

  *** Linux Version ***

  $Id: discid.c,v 1.3 2001/04/14 17:54:53 jzawodn Exp $

  Copyright (c) 1998-2000 Jeremy D. Zawodny <Jeremy na Zawodny.com>

  This software is covered by the GPL.

  Is is based on code found in:

    To: code-review na azure.humbug.org.au
    Subject: CDDB database reader
    From: Byron Ellacott <rodent na route-qn.uqnga.org.au>
    Date: Fri, 5 Jun 1998 17:32:40 +1000

*/

/* Stripped net code, 'cause I only care about the discid */

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <stdarg.h>
#include <errno.h>
#include <netdb.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>

#include <linux/cdrom.h>

struct toc {
    int min, sec, frame;
} cdtoc[100];

int read_toc(void) {
    int drive = open("/dev/cdrom", O_RDONLY | O_NONBLOCK);
    struct cdrom_tochdr tochdr;
    struct cdrom_tocentry tocentry;
    int i;

    ioctl(drive, CDROMREADTOCHDR, &tochdr);
    for (i = tochdr.cdth_trk0; i <= tochdr.cdth_trk1; i++) {
        tocentry.cdte_track = i;
        tocentry.cdte_format = CDROM_MSF;
        ioctl(drive, CDROMREADTOCENTRY, &tocentry);
        cdtoc[i-1].min = tocentry.cdte_addr.msf.minute;
        cdtoc[i-1].sec = tocentry.cdte_addr.msf.second;
        cdtoc[i-1].frame = tocentry.cdte_addr.msf.frame;
        cdtoc[i-1].frame += cdtoc[i-1].min*60*75;
        cdtoc[i-1].frame += cdtoc[i-1].sec*75;
    }
    tocentry.cdte_track = 0xAA;
    tocentry.cdte_format = CDROM_MSF;
    ioctl(drive, CDROMREADTOCENTRY, &tocentry);
    cdtoc[tochdr.cdth_trk1].min = tocentry.cdte_addr.msf.minute;
    cdtoc[tochdr.cdth_trk1].sec = tocentry.cdte_addr.msf.second;
    cdtoc[tochdr.cdth_trk1].frame = tocentry.cdte_addr.msf.frame;
    cdtoc[tochdr.cdth_trk1].frame += cdtoc[tochdr.cdth_trk1].min*60*75;
    cdtoc[tochdr.cdth_trk1].frame += cdtoc[tochdr.cdth_trk1].sec*75;
    close(drive);
    return tochdr.cdth_trk1;
}

unsigned int cddb_sum(int n) {
    unsigned int ret;

    ret = 0;
    while (n > 0) {
      ret += (n % 10);
      n /= 10;
    }
    return ret;
}

unsigned long cddb_discid(int tot_trks) {
    unsigned int i, t = 0, n = 0;

    i = 0;
    while (i < tot_trks) {
      n = n + cddb_sum((cdtoc[i].min * 60) + cdtoc[i].sec);
      i++;
    }
    t = ((cdtoc[tot_trks].min * 60) + cdtoc[tot_trks].sec) -
      ((cdtoc[0].min * 60) + cdtoc[0].sec);
    return ((n % 0xff) << 24 | t << 8 | tot_trks);
}

void main(void) {
    unsigned long discid;
    int tracks, i;

    tracks = read_toc();
    discid = cddb_discid(tracks);
    printf("%08x %d", discid, tracks);
    for (i = 0; i < tracks; i++) printf(" %d", cdtoc[i].frame);
    printf(" %d\n", (cdtoc[tracks].frame)/75);
    printf("\n");
    exit(0);
}

--
Skuska:

[cracken na cracken_house linux]$ ./discid 
3b127718 24 150 1460 15858 32207 45639 58258 73874 86336 101453 116466
129933 143651 154810 169153 183098 198923 210750 225482 240652 258799
277872 298870 315703 335409 4729

[cracken na cracken_house linux]$ ./discid 
bb119f0e 14 150 17777 36809 65584 87314 107183 127639 151099 172946
191136 214565 254729 273463 317543 4513

[cracken na cracken_house linux]$ ./discid
b70b820e 14 150 15089 30965 46570 62487 80643 96460 110721 126593 144242
159270 171706 187078 203099 2948
--
A takto z tychto cisel dostanme co chceme.
http://freedb.freedb.org/~cddb/cddb.cgi?cmd=cddb+query+7c0b8b0b+11+150+23115+
42165+60015+79512+101560+118757+136605+159492+176067+198875+2957&hello=
user+
hostname+program+version&proto=3

---------
Dufam, ze sa tento problem vyriesi a ospravedlnujem sa za dlhy nudny mail.



Další informace o konferenci Linux