mci zum auslesen von audiocd -> freedb abfragen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
genrich
User
Beiträge: 91
Registriert: Sonntag 27. Juni 2004, 17:46

mci zum auslesen von audiocd -> freedb abfragen

Beitragvon genrich » Dienstag 9. November 2004, 09:03

Hab das Projekt gefunden:
http://sourceforge.net/projects/cddb-py/
(Wobei es mittlerweile mit freeDB funktioniert)

Bei diesem Projekt wird eine Audio CD mit mci.dll (eine in C geschriebenes Modul) ausgelesen, um die DiscID zu erhalten...

Leider ist diese Modul für Python 2.0 kompiliert... Nun hab ich bei http://www.pkshiu.com/tech/cddb.html folgendes gefunden:
The currently CDDB project works well under *NIX and Python 2.0. However, the pre-compiled mci.dll for windows is built for Python 2.0. To make it work with 2.1, edit it with an editor (emacs works nicely) and search for reference to the python 2.0 dll. Change 2.0 to 2.1. ALso the python source files have some references to UNIX only API calls that is not in the Windows platform (geteuid). Comment out that line will make the software work.


Leider kann ich das Beschrieben aber nicht umsetzen. Hab keinen blassen schimmer, wie man mit C kompiliert...

Generell wäre es auch schön, wenn man system unabhängig an's CD-ROM dran kommt, um die DicsID zu bestimmen... Gibt es da was???
genrich
User
Beiträge: 91
Registriert: Sonntag 27. Juni 2004, 17:46

Beitragvon genrich » Dienstag 9. November 2004, 11:58

Hab was gefunden!

http://www.pygame.org

Ist zwar eigentlich für Spiele...
Hat aber ein CDROM Modul:
http://www.pygame.org/docs/ref/pygame_cdrom.html

Hier ein Tutorial:
http://www.pygame.org/pcr/cd_tutorial/index.php


Das ganze gibt es Windows, verschiedene Unix Distributions, MacOS und BeOS.


Jetzt muß ich mir nur was basten, das ich aus den Tack-Information die freeDB DiscID berechnen kann...
genrich
User
Beiträge: 91
Registriert: Sonntag 27. Juni 2004, 17:46

Beitragvon genrich » Dienstag 9. November 2004, 12:55

Habe mir jetzt aus verschiedenen Quellen ein skript zusammengebastelt, welches eigentlich eine DiscID einer Audio CD generieren soll... Es klappt aber nicht wie erwartet, die DiscID ist einfach falsch :(
Das liegt wohl daran, das ich die gefundenen Codestücke nicht richtig verstanden habe...



[alter CODE gelöscht, s. aktueller Version unten]



ich bekomme auch einen Fehler, mit dem ich nicht's anfangen kann:
FutureWarning: x<<y losing bits or changing sign will return a long in Python 2.4 and up
Zuletzt geändert von genrich am Dienstag 9. November 2004, 18:06, insgesamt 1-mal geändert.
genrich
User
Beiträge: 91
Registriert: Sonntag 27. Juni 2004, 17:46

Beitragvon genrich » Dienstag 9. November 2004, 15:49

Hier eine aktualisierte Version... Doch leider stimmt die DiscID immer noch nicht :(

[alter CODE gelöscht, s. aktueller Version unten]
Zuletzt geändert von genrich am Dienstag 9. November 2004, 18:06, insgesamt 1-mal geändert.
Benutzeravatar
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Beitragvon Dookie » Dienstag 9. November 2004, 17:43

Hi,

in der Pythonmailingliste die Nummer stimmt aber.

zum Umwandeln in Hex kannst Du auch die eingebaute Funktion hex() nutzen:

Code: Alles auswählen

>>> hex(-1102853104)
... '0xbe43cc10'


das 0x bekommst du einfach so weg:

Code: Alles auswählen

>>> hex(-1102853104)[2:]
... 'be43cc10'



Gruß

Dookie

Code: Alles auswählen

#!/usr/bin/env python
import this
genrich
User
Beiträge: 91
Registriert: Sonntag 27. Juni 2004, 17:46

Beitragvon genrich » Dienstag 9. November 2004, 18:04

Code: Alles auswählen

"%08lx" % RAWdiscID

ist doch das selbe wie

Code: Alles auswählen

hex(-1102853104)[2:]


Zur eigentlichen Datenbankabfrage nutze ich ja http://sourceforge.net/projects/cddb-py/


Ich hab per Hand nach der CD gesucht... Es kommen nur folgende IDs in Frage:

d40e9010
db0e9210
d60e5910


Also es liegt wohl noch ein Grundlegendes Problem vor :(
Ich habe mit noch mal genau die Spezifikationen angeschaut:
http://www.freedb.org/modules.php?name= ... le&artid=6

Ganz merkwürdig finde ich die berechnung von t:
t = ((cdtoc[tot_trks].min * 60) + cdtoc[tot_trks].sec) -
((cdtoc[0].min * 60) + cdtoc[0].sec);


Und was mich auch mulmig stimmt sind die:
Important note for clients using the MS-Windows MCI interface

Ich weiß leider nicht ob pygames eigentlich nur auf das MCI zurückgreift...
Naja die Trackzeiten mit Sek und Frames stimmen ja zumindest mit den angaben von EAC überein...

Gibt es vielleicht doch nicht etwas fertiges in der Richtung??? Ich schein das ja nicht auf die Kette zu bekommen :oops:
genrich
User
Beiträge: 91
Registriert: Sonntag 27. Juni 2004, 17:46

Beitragvon genrich » Dienstag 9. November 2004, 18:05

Ach so, hier noch mal eine aktualisierte Version:

Code: Alles auswählen

from pygame import cdrom

cdrom.init()
print "CDROM initialized: ", cdrom.get_init()
print "Number of CDROMs:  ", cdrom.get_count()


def GetHMS(s):
    h,s = divmod(s,3600)
    m,s=divmod(s,60)
    return "%02.f:%02.f:%02.f" % (h, m, s)

def Sek_Frames(s):
    nurSek = int( s )
    Frames = int( round( (s - nurSek) * 75 ) )
    return nurSek, Frames


def cddb_sum(n):
    # cddb_sum(123456789) => 1+2+3+4+5+6+7+8+9 = 45
    ret = 0
    while n > 0:
        ret += (n % 10)
        n = n / 10
    return ret


def DiscID(cd_object):
    print "\n Nr.   Länge"
    print "--------------------------"

    checksum=0
    TotalFrames=0
    TotalSek=0
    for i in range(TrackAnzahl):
        track_length = cd_object.get_track_length(i)

        nurSek, Frames = Sek_Frames( track_length )
        checksum += cddb_sum(nurSek)

        print " %2d   %s.%2d Frames" % (i, GetHMS(nurSek), Frames)

        TotalSek += nurSek

    nurSek, Frames = Sek_Frames( TotalSek )
    print "\nTotalZeit:",nurSek,"sek"
    print "TotalZeit: %s.%d" % (GetHMS(nurSek),Frames)

    sek_LetzterTrack = Sek_Frames(cd_object.get_track_length(TrackAnzahl-1))[0]
    sek_ErsterTrack  = Sek_Frames(cd_object.get_track_length(0))[0]

    t=sek_LetzterTrack - sek_ErsterTrack

    RAWdiscID=( checksum % 0xff << 24 | t << 8 | TrackAnzahl )



for i in range(cdrom.get_count()):
    cd_object = cdrom.CD(i)
    print "\nNr.:",i," Laufwerk:",cd_object.get_name()

    print "Initialisierte..."
    cd_object.init()

    TrackAnzahl = cd_object.get_numtracks()

    if TrackAnzahl!=0:
        RAWdiscID = DiscID(cd_object)
        print "\nRAW discID..:", RAWdiscID
        print "freedb ID...: %08lx" % RAWdiscID


verbesserte Version
Zuletzt geändert von genrich am Dienstag 9. November 2004, 18:28, insgesamt 1-mal geändert.
Benutzeravatar
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Beitragvon Dookie » Dienstag 9. November 2004, 18:13

ich denke mal hier liegt der Fehler:

Code: Alles auswählen

    sek_LetzterTrack = Sek_Frames(cd_object.get_track_length(i))[0]

i zeigt da nicht auf den letzten Track sondern hat den wert TrackAnzahl
nimm besser

Code: Alles auswählen

    sek_LetzterTrack = Sek_Frames(cd_object.get_track_length(TrackAnzahl-1))[0]


Gruß

Dookie

Code: Alles auswählen

#!/usr/bin/env python
import this
genrich
User
Beiträge: 91
Registriert: Sonntag 27. Juni 2004, 17:46

Beitragvon genrich » Dienstag 9. November 2004, 18:27

Hast recht, danke...

Hab ich verbessert... Jetzt bekomme ich als ID "be00b210"... Stimmt leider auch nicht :(
Benutzeravatar
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Beitragvon Dookie » Dienstag 9. November 2004, 19:28

Hi genrich,

firsttrack muss auch nicht unbeding track0 sein.

noch ein Tipp, lad dir das CDDB-1.3.tar.gz runter und entpacke es, dann kannst Du in das DiskID.py reinschauen, da ist auch eine Funktion disc_id drinnen mit der Berechnung.


Gruß

Dookie

Code: Alles auswählen

#!/usr/bin/env python
import this
Benutzeravatar
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Beitragvon Dookie » Dienstag 9. November 2004, 19:41

Du brauchsts nichtmal runterladen, einfach hier gucken:
http://csl.cse.ucsc.edu/~ben/python/CDDB/DiscID.py


Gruß

Dookie

Code: Alles auswählen

#!/usr/bin/env python
import this
Benutzeravatar
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Beitragvon Dookie » Dienstag 9. November 2004, 19:44

nochwas,

in dem source findest Du öfter solche Zeilen:

Code: Alles auswählen

(first, last) = cdrom.toc_header(device)

mach da am besten die Klammern vorne weg:

Code: Alles auswählen

first, last = cdrom.toc_header(device)

Dann klappts auch mit Python2.3


Gruß

Dookie

Code: Alles auswählen

#!/usr/bin/env python
import this
genrich
User
Beiträge: 91
Registriert: Sonntag 27. Juni 2004, 17:46

Beitragvon genrich » Dienstag 9. November 2004, 20:14

Dookie hat geschrieben:http://csl.cse.ucsc.edu/~ben/python/CDDB/DiscID.py


Darauf basiert mein Code... In diesem Projekt ist eigentlich alles enthalten, nur es benutze eine eigene C-Lib um an die TOC Informationen der Audio CD zu gelangen... Es ist auch eigentlich ein fertig kompilierte DLL dabei, die läuft allerdings nur mit Python v2.0 :(

Auf der Mailingliste von pygames habe ich ein anderes Problem erfahren:
Und zwar braucht man eigentlich die "lead in" und "lead out" Daten... Die sind glaube ich nicht immer die selben, wie die normalen Start und Längen angaben... Kenne mich da aber auch nicht so dolle aus...
Ich habe auch ein Source mitgeschickt bekommen... Ich habs mal ein wenig angepasst, sodas es direkt läuft, wenn man pygame installiert hat:

Altes Listing entfernt... s.unten

Bei meiner "Depeche Mode" - "Speak & Spell" CD bekomme ich damit folgende Werte:

Code: Alles auswählen

RAW_ID......: 1660956944
freedb ID...: 63003110
Zuletzt geändert von genrich am Mittwoch 10. November 2004, 06:36, insgesamt 1-mal geändert.
genrich
User
Beiträge: 91
Registriert: Sonntag 27. Juni 2004, 17:46

Beitragvon genrich » Dienstag 9. November 2004, 22:53

Mit dem Kommandozeilen Programm http://www.freedb.org/software/cddbidgen.zip kann ich nun entlich sichergehen, welchen DiscID der richtige ist:
dd0e8e10

spuckt es aus und das passt: http://www.freedb.org/freedb/data/dd0e8e10

Für mein Skript bringt mich das aber nicht weiter :(
Benutzeravatar
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Beitragvon Dookie » Dienstag 9. November 2004, 22:59

warum, du kannst das Tool ja mit system oder os.popen oder sonstwas aufrufen und das Ergebnis so erhalten.


Gruß

Dookie

Code: Alles auswählen

#!/usr/bin/env python
import this

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder