AudioCD / DiscID für FreeDB Abfragen generieren (Win/GUI)

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
alen
Beiträge: 107
Registriert: 09.04.2007 17:38
Computerausstattung: Main Hardware: AMD Ryzen 5 1600 - 6 Core / Gigabyte B450 Aorus Pro / Sapphire RX580 8GB
PB 5.61 and earlier @ Manjaro Linux XFCE x64/ Fedora Linux Cinnamon x64 / Windows 10 x64 on various Hardware Platforms
Wohnort: Duisburg
Kontaktdaten:

AudioCD / DiscID für FreeDB Abfragen generieren (Win/GUI)

Beitrag von alen »

Hallo Community,

hier eine kleine Fallstudie. Mit dem Stück Code kann man die DiscID für eine FreeDB Abfrage erzeugen, mit der man die Tracklisten zu der eingelegten Audio CD dann abfragen kann. Das ganze basiert auf der FreeDB API. Der unten aufgeführte Code kommt ohne API Aufrufe des Betriebsystems, nur mit Purebasic Mitteln aus.

Wenn das Programm eine DiscID generiert hat kann man diese ID dann hier auf der FreeDB Seite eingeben und bekommt eine Liste mit passenden Alben zurück. Da das ganze aus den Track Längen und den jeweiligen Startzeiten der einzelnen Tracks generiert wird, kann es bei der Masse an Audio CDs auf dem Markt auch zu mehrfachen Übereinstimmungen kommen. Daher spielt mal damit herum.

Einfache Anleitung:
1. Code per Cut and Paste aus dem Forum in die PB GUI rein -> Run !
2. Audio CD einlegen -> Go Buttton klicken
3. Ausgabe des Programmes DiscID in die Zwischenablage kopieren (z.B. Calculated DiscID: 95097f0b)
4. DiscID in das Eingabefeld der unten genannten Seite rein.
5. Sich an den Ergebnissen erfreuen

Hier die URL wo man eine Abfrage üner die DiscID machen kann:
http://www.freedb.org/freedb_discid_check.php

Weitere Informationen über die API und Beispiele wie man diese nutzt findet man hier:
http://www.freedb.org/en/download__misc ... us.11.html

Im Moment ist der Code nur unter Windows 7 (64Bit) gestestet. Wenn ich ihn auch unter Linux getestet habe liefere ich das Ergebnis nach.

Viel Spaß damit erstmal.

Und auch ein grosses Dankeschön an die Community des Forums das mir so oft schon geholfen hat wenn ich mal nicht weiter kam.

Grüße
Alen

Code: Alles auswählen

Enumeration
  #MainWindow
  #Editor_2
  #Button_1
  #Button_2
  #Button_3
EndEnumeration

Global RawDiscID.S
Global NewList StartTrackList()
Global NewList TrackLengthList()
Global NumberOfDrives = InitAudioCD()

#CRLF         = Chr(13) + Chr(10)
#Tray_Open    = 1
#Tray_Closed  = 0

;- Helper Functions
Procedure.S GetHourFormat(LengthInSeconds)
  Minutes = LengthInSeconds / 60
  Seconds = LengthInSeconds - Minutes * 60
  If Seconds < 10:  Null.S = "0"
    Else: Null.S = "": EndIf
  ProcedureReturn RSet(Str(Minutes),2,"0")+":" + Null.S + Str(Seconds)
EndProcedure

Procedure  DebugListZeiten (List Liste(),Name.S)
  Protected *Old_Element
  If ListSize(Liste())
    *Old_Element = @Liste()
    Counter = 1
    Debug "*****" +Name  + "*****"
    ForEach Liste() ;beliebige Liste
      Debug  RSet(Str(Counter),2,"0") + "--> " + GetHourFormat(Liste()) ;debugen
      Counter + 1;
    Next
    ChangeCurrentElement(Liste(), *Old_Element)
  EndIf
EndProcedure

Procedure  DebugList (List Liste.S(),Name.S)
  Protected *Old_Element
  If ListSize(Liste())
    *Old_Element = @Liste()
    Counter = 1
    Debug "*****" +Name  + "*****"
    ForEach Liste() ;beliebige Liste
      Debug  Liste() ;debugen
      Counter + 1;
    Next
    ChangeCurrentElement(Liste(), *Old_Element)
  EndIf
EndProcedure


;- DiscID Calculate Routines
Procedure.l SumDigits(numbers)
  While numbers > 0
    qs = qs + (numbers % 10)
    numbers = numbers / 10
  Wend
  ProcedureReturn qs
EndProcedure

Procedure.S CalcRawDiscID(List StartTrackList())
  Protected temp.q
  Counter = 1
  ForEach StartTrackList()
    track_length = AudioCDTrackLength(Counter)
    total_length + track_length
    CheckSum + SumDigits(StartTrackList())               
    Counter + 1
  Next
  Debug CheckSum
  
  temp    = (CheckSum % $FF) << 24
  
  XX.S    = LCase(RSet(Hex(temp,#PB_Quad), 2, "0"))               
  YYYY.S  = LCase(RSet(Hex(AudioCDLength(),#PB_Quad), 4, "0"))
  ZZ.S    = LCase(RSet(Hex(AudioCDTracks(),#PB_Quad), 2, "0"))
  
  RawDiscID.S = XX.S + YYYY.S + ZZ.S
  ProcedureReturn RawDiscID.S
EndProcedure

Procedure CreateTrackLists() 
  If NumberOfDrives > 0
    For Drive = 1 To NumberOfDrives
      UseAudioCD(Drive-1)
      If AudioCDTracks() > 0
        NumTracks     = AudioCDTracks() 
        InsertElement(StartTrackList())
        InsertElement(TrackLengthList())
        StartTrackList() = 2
        
        For Track = 1 To NumTracks          
          StartTimeTrack = StartTimeTrack + AudioCDTrackLength(Track)
          AddElement(StartTrackList())
          AddElement(TrackLengthList())
          StartTrackList()  = StartTimeTrack
          TrackLengthList() = AudioCDTrackLength(Track)
        Next
        
        LastElement(StartTrackList())
        DeleteElement(StartTrackList())     
        
        Counter = 1 
        ForEach StartTrackList()
          track_length = AudioCDTrackLength(Counter)
          total_length + track_length
          Counter + 1
        Next 
      EndIf
    Next
  EndIf  
EndProcedure

;- Create Info Routines
Procedure.S ShowEachTrackLength(List StartTrackList())
  Counter = 1
  Info.S = "Length of each track:" + #CRLF
  
  FirstElement(TrackLengthList())
  DeleteElement(TrackLengthList())     
  
  ForEach TrackLengthList()
    Info.S + RSet(Str(Counter),2,"0") + " --- " + GetHourFormat(TrackLengthList()) + #CRLF
    Counter + 1
  Next
  
  ProcedureReturn Info
EndProcedure

Procedure.S ShowEachTrackStart(List StartTrackList())
  Counter = 1
  Info.S = "Start times of each track:" + #CRLF
  
  ForEach StartTrackList()
    Info.S + RSet(Str(Counter),2,"0") + " --- " + GetHourFormat(StartTrackList()) + #CRLF
    Counter + 1
  Next
  ProcedureReturn Info
EndProcedure

Procedure.S ShowAudioCDinfo()
  NumTracks = AudioCDTracks()
  
  Info.S = "AudioCD in drive " + AudioCDName() + #CRLF
  Info + "Number of tracks: "
  Info + Str(NumTracks) + #CRLF
  Info + "Total CD Length: " + GetHourFormat(AudioCDLength()) + " minutes "
  Info + " / " + Str(AudioCDLength()) + " seconds" + #CRLF
  
  ProcedureReturn Info
EndProcedure


;- Main Program Section
Procedure DoTheJob()
  ClearList(StartTrackList())
  ClearList(TrackLengthList())
  CreateTrackLists()
  
  msg.S = "" 
  msg + ShowAudioCDinfo() + #CRLF
  msg + "Calculated DiscID: " + CalcRawDiscID(StartTrackList()) + #CRLF + #CRLF
  msg + ShowEachTrackLength(StartTrackList()) + #CRLF
  msg + ShowEachTrackStart(StartTrackList()) + #CRLF
  
  ;DebugListZeiten(StartTrackList(),"TrackListZeiten")
  ;DebugListZeiten(TrackLengthList(),"TrackLenZeiten")
  
  SetGadgetText(#Editor_2,msg)
EndProcedure


;- Draw UI
Procedure OpenWindow_MainWindow()
  app_title.S = " Calculate DiscID GUI"
  
  If OpenWindow(#MainWindow, 414, 199, 437, 355, app_title, #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_TitleBar|#PB_Window_ScreenCentered)
    EditorGadget(#Editor_2, 10, 40, 415, 300, #PB_Editor_ReadOnly)
    SetGadgetText(#Editor_2, "")
    ButtonGadget(#Button_1, 175, 10, 80, 20, "Open Tray")
    ButtonGadget(#Button_2, 265, 10, 80, 20, "Close Tray")
    ButtonGadget(#Button_3, 375, 10, 50, 20, "Go")
  EndIf
EndProcedure


If NumberOfDrives = 0
  MessageRequester("Fehler", "Keine CD-Audio Laufwerke gefunden", 0)
  End
Else
  OpenWindow_MainWindow()
  
  ;- Define Acions
  Repeat
    Event = WaitWindowEvent()
    Select Event
        
      Case #WM_KEYDOWN  
        If EventwParam() = 13
          SetGadgetText(#Editor_2,"")
          DoTheJob()
        EndIf 
        
      Case #PB_Event_Gadget
        EventGadget = EventGadget()
        EventType = EventType()
        
        If EventGadget = #Button_1
          EjectAudioCD(#Tray_Open)
        EndIf
        
        If EventGadget = #Button_2
          EjectAudioCD(#Tray_Closed)
        EndIf
        
        If EventGadget = #Button_3
          SetGadgetText(#Editor_2,"")
          If AudioCDStatus() = -1 
            MessageRequester("FEHLER", "Es befindet sich keine Audio CD im Laufwerk")
          Else
            DoTheJob()
          EndIf
        EndIf
        
        
      Case #PB_Event_CloseWindow
        EventWindow = EventWindow()
        If EventWindow = #MainWindow
          CloseWindow(#MainWindow)
          Break
        EndIf
    EndSelect
  ForEver
  
EndIf
---
Main Hardware: AMD Ryzen 5 1600 - 6 Core / Asus B350M-A / Nvidia GTX650
PB 5.61 and earlier @ Manjaro Linux XFCE x64/ Fedora Linux Cinnamon x64 / Windows 10 x64
on various Hardware Platforms (Notebook and Desktop)