Skip to content

Archiv fuer den Monat August, 2013

29
Aug

C++ – Freedb DiscID ermitteln

Ich arbeite zu Hause zur Zeit an einer kleinen MedienVerwaltung. Logisch, dass dort auch CDs erfasst werden sollen. Allerdings wäre es natürlich cool, wenn das Programm die CD und die Titel eigenständig ermitteln kann. Also was liegt nahe? Natürlich freedb. In diesem Tutorial beschreibe ich deshalb wie Ihr am schnellsten die DiscID einer CD ermittelt und die dazugehörigen Titel abruft.

Ich verwende dafür wie üblich den C++ Builder und verwende für die Webanfragen Indy. Genau, ich greife nicht per telnet auf freedb zu, sondern per http.

Damit sind wir bei der ersten Hürde. Wie kann ich über http auf freedb zugreifen? Das hat mich einen Abend gekostet. Doch schlussendlich hat es funktioniert. Wer sich erstmal ein wenig mit dem Protokoll beschäftigen will und evtl. erst einen Test per telnet machen will, kann sich ja hier mal einlesen.

Wichtig beim Zugriff per http ist, dass der „Handshake“ jedesmal übermittelt wird. Wollen wir also die auf dem Server vorhandenen Musikkategorien auflisten, sieht der Link wie folgt aus:

http://freedb.freedb.org/~cddb/cddb.cgi?cmd=cddb+lscat&hello=chris+chris.blog.com+MV+v0.1&proto=1

Als erstes kommt der Server, freedb.freedb.org ist ein Random-Server. Gefolgt von ~cddb/cddb.cgi. Von dort aus kann man dann auf die „API“ zugreifen. Mit „cmd=“ wird das Commando eingeleitet. Darauf folgt das Kommando wie es genau beim telnet auch eingegeben werden würde, der einzige Unterschied dabei ist, dass anstatt Leerzeichen ein „+“ verwendet wird. Mit „&hello=“ wird der Handshake eingeleitet. Der erste Parameter ist Name, gefolgt von URL/Domain, Programm, Version. Eigentlich ist es ziemlich egal was dort eingegeben wird.
Zum Schluß wird mit „&proto=“ noch die Protokollversion angegeben, die verwendet werden soll. Dies könnt Ihr im bereits o. g. Link nachlesen.

Als Ergebnis des obigen Links erhaltet Ihr folgende Liste:

210 OK, category list follows (until terminating `.')
data
folk
jazz
misc
rock
country
blues
newage
reggae
classical
soundtrack
.

Okay, alles noch ganz einfach bis jetzt. Aber wie geht es weiter? Theoretisch könnte man sich die DiscID selbst berechnen. Aber wieso sollte man das tun wenn es von freedb eine Abfrage dafür gibt. Man macht sich das Leben doch gern etwas einfacher. Was brauchen wir also für die Abfrage der DiscID?
Als erstes brauchen wir die Anzahl der Lieder die auf der entsprechenden CD sind. Danach pro Lied die Offsets wo dieses startet. Zum Schluss noch die Länge der gesamten Spielzeit der CD in Sekunden. Okay, was ist ein Offset? Diese Frage habe ich mir auch erstmal gespielt.
Ganz einfach gesagt, um nicht lange das fachliche zu erklären: Sekunden des Songs * 75 = Offset des Songs. Also Minuten * 60 * 75 + Sekunden * 75 + Frames. Dann habt Ihr das Offset des Songs.

Wie aber kommt man am leichtesten an die benötigten Infos? Ich habe 2 Tage lang etliche Seiten durchsucht. Um den einfachsten Weg zu finden um an diese Daten zu kommen. Und das Zauberwort heißt MCI. Ich weiß zwar nicht ob dies die eleganteste Lösung ist, jedenfalls ist es die einfachste.

Also fangen wir mal an. Als erstes ermitteln wir die Anzahl der Audiotracks. Folgende zusätzliche includes und ein pragma link werden benötigt:

#include <mmsystem .h>
#include <stdio .h>

#pragma link "Winmm.lib"

Dann wie gesagt als erstes die Anzahl der Tracks ermitteln:

   int nAnzahlTracks;
   wchar_t strErgebnis[50];
   MCIERROR mciErgebnis;

   // Anzahl der Tracks ermitteln
   mciErgebnis = mciSendString(L"status cdaudio number of tracks", strErgebnis, sizeof(strErgebnis), 0);

   // Falls ein Fehler aufgetreten ist, Funktion verlassen
   if (mciErgebnis != S_OK)
      return;

   nAnzahlTracks = StrToInt(strErgebnis);

Mit „mciSendString“ wird über einen String eine Anfrage geschickt, die die Anzahl der Audio-Tracks auf der CD zurückliefern soll. Das Ergebnis wird in „strErgebnis“ gespeichert, einen eventuell auftretenden Fehler Speichern wir in der Variable mciErgebnis ab.
Ist der Wert in mciErgebnis „S_OK“, hat alles funktioniert und wir können den Ergebnisstring in einen Integer Casten, andernfalls wird die Funktion verlassen.
Die Prüfungen auf „!= S_OK“ lass ich in weiteren Codeteilen weg. Die Prüfung kann aber nach jedem mciSendString durchgeführt werden.

Nachdem wir jetzt die Anzahl der Tracks haben, brauchen wir als nächstes die Offsets. Dazu müssen wir die Offsets jedes einzelnen Tracks ermitteln:

   unsigend uStartMin, uStartSec, uStartFrame
   String strOffsets = "", strMCIBefehl;

   // Alle Titel durchlaufen
   for(int i = 1; i < = nAnzahlTracks; ++i)
   {
      // MCI-Befehl zum ermitteln der Startzeit des Tracks
      strMCIBefehl = "status cdaudio position track " + IntToStr(i);
      // MCI-Befehl sende
      mciSendString(strMCIBefehl.c_str(), strErgebnis, sizeof(strErgebnis), 0);
      // Startminute, -sekunde und -frame aus dem Ergebnis auslesen
      sscanf(((AnsiString)strErgebnis).c_str(), "%02d:%02d:%02d", &uStartMin, &uStartSec, &uStartFrame);
      // Offset berechnen
      uOffset = 60 * 75 * uStartMin + 75 * uStartSec + uStartFrame;
      // An den String anhängen
      strOffsets += "+" + IntToStr(static_cast<int>(uOffset));
   }

Jetzt haben wir die Offsets aller Titel. Jetzt fehlt uns nur noch die Gesamtspielzeit der CD. Diese ermittelt man wie folgt:

   strMCIBefehl = "status cdaudio position track " + IntToStr(nAnzahlTracks);
   mciSendString(strMCIBefehl.c_str(), strErgebnis, sizeof(strErgebnis), 0);
   sscanf(((AnsiString)strErgebnis).c_str(), "%02d:%02d:%02d", &uStartMin, &uStartSec, &uStartFrame);

   strMCIBefehl = "status cdaudio length track " + IntToStr(nAnzahlTracks);
   mciSendString(strMCIBefehl.c_str(), strErgebnis, sizeof(strErgebnis), 0);
   sscanf(((AnsiString)strErgebnis).c_str(), "%02d:%02d:%02d", &uMinLen, &uSecLen, &uFrameLen);

   unsigned uPlayingSeconds = ((uStartMin * 60 * FRAMES_PER_SECOND + uStartSec * FRAMES_PER_SECOND + uStartFrame + uMinLen * FRAMES_PER_SECOND * 60 + uSecLen * FRAMES_PER_SECOND + uFrameLen)) / FRAMES_PER_SECOND;

Da wir jetzt alles haben was wir brauchen können wir nun die URL zusammenbasteln mit der man die DiscID ermitteln kann:

   strGet = "http://freedb.freedb.org/~cddb/cddb.cgi?cmd=discid+" + IntToStr(nAnzahlTracks) + "+" + strOffsets + "+" + IntToStr(static_cast&lt;int&gt;(uPlayingSeconds)) + "&hello=chris+chris.blog.com+mv+v0.1&proto=1";

   ShowMessage(this->IdHTTP->Get(strGet));

Als Ergebnis solltet Ihr sowas ähnliches wie das hier bekommen:

200 Disc ID is 970a920d

Je nachdem welche CD Ihr im Laufwerk habt, kann dies natürlich variieren. Außerdem kann es sein, dass für eine CD mehrere Ergebnisse zurückkommen. Diesen Fall habe ich hier nicht berücksichtigt. Mit diesen Informationen solltet Ihr aber jedenfalls weiterarbeiten können 🙂
Wenn man sich die „Syntax“ ein wenig zu Gemüte führt, ist es eigentlich ganz einfach 🙂

25
Aug

Deutsche Alpenstraße

Wie schon in meinem letzten Post erwähnt, haben ich und meine Freundin eine Cabriotpur entlang der Deutschen Alpenstraße gemacht.
Darum möchte ich euch einen kleinen Eindruck davon vermitteln. Bevor es die Bilder gibt, möchte ich aber noch ein paar Worte schreiben.
Los gings, wie auch schon im letzten Post erwähnt am Bodensee, genauer gesagt in Lindau und dann gehts weiter bis rauf zum Königssee. Dort hatten wir unser erstes Hotel (Bayerischer Hof). Das Hotel war super. Nachdem wir die erste Nacht in Lindau verbracht hatten sind wir zeitig aufgestanden, damit wir pünktlich um 7 Uhr beim Frühstück sein konnten. Wir wollten ja so früh wie möglich los, schließlich hatten wir ja an diesem Tag gute 300km vor uns die es zu fahren galt.
Also sind wir um ca. 8 Uhr ins Auto und losgefahren. Der Anfang der Strecke war schon vielversprechend. Serpentinen. Mit einem Heckantriebler, kann ich nur empfehlen, macht einen Riesenspaß!

Nachdem wir dann gleich mal am Anfang waren, haben wir uns auch mit dem Roadbook ganz gut zurechtgefunden. Navi haben wir eigentlich nur einmal gebraucht und daran war eigentlich nur eine Umleitung schuld. Ich hab mir auch noch gleich gedacht am ersten Tag, wir sind bis Mittag oder kurz nach Mittag im zweiten Hotel, da die ersten 50-60 Kilometer relativ zügig gefahren waren. Damit hatte ich aber dann Unrecht. Man fährt durch viele kleinere und auch größere Ortschaften, durch den ganzen Ferienverkehr staut sich dort dann aber alles. Dank der ganzen Ampeln in den Dörfern und Städten kommt man dann teilweise nur noch im Schritttempo vorwärts. Sobald man wieder Außerorts ist, gehts aber wieder ganz Flott weiter! Jedenfalls waren wir dann um 17 Uhr im zweiten Hotel.
Wie sich jeder vorstellen kann, hatten wir deshalb natürlich keine Zeit uns etwas anzusehen (ausgenommen die Landschaft, die wir ja vom Auto aus sehen konnten).

Die Landschaft entlang der Deutschen Alpenstraße ist richtig Klasse. Auch die Strecke zum fahren ist Spitze. Man fährt viele Bergstraßen was mächtig Spaß macht. Ich kanns nur jedem empfehlen. Allerdings sollte man wenn möglich den Zeitpunkt in dem man fährt eher auf nicht-Ferienzeit legen.

Ich kann die Strecke nur jedem empfehlen. Wirklich eine tolle Strecke mit toller Landschaft.

Aber kommen wir noch zu den etwas „unangenehmen“ Themen. Da wir direkt in den „Touristenzentren“ waren, waren die Preise natürlich auch ziemlich gesalzen. Im ersten Hotel haben wir auf dem Hotelparkplatz geparkt. Der einzige Parkplatz in der nähe des Hotels. Parkplatz kann man das eh nicht wirklich nennen. Der „Parkplatz“ war so eng, dass man es ohne Einweisung komplett vergessen kann, dort hineinzukommen. Für so einen „Parkplatz“ werden dann noch 10€ pro Nacht fällig.

Da wir ja auch nur Nacht mit Frühstück gebucht hatten, war natürlich kein Abendessen dabei. Was für uns dann natürlich hieß: Selbst um etwas essbares schauen. Am ersten Tag hatten wir noch Proviant, das wir von zu Hause mitgenommen hatten. Am zweiten Tag setzten wir uns dann in den Hotelbiergarten.
Auch hier waren die Preise alles andere als Human. 13€ für ein Schnitzel, 3,90€ für ein Weißbier und knapp 7€ für eine Currywurst. Für extra Preiselbeeren für das Schnitzel kamen nochmal 1,50€ dazu.
Und um ehrlich zu sein war das Essen dann auch nicht gerade der Hammer. Um ehrlich zu sein hat meine Currywurst wie ein schlechter(!) Curryking-Klon geschmeckt.
Auch beim Schnitzel ist man normalerweise besseres gewöhnt.

Und jetzt genug der Schreiberei, hier kommen ein paar Bilder 🙂

20
Aug

Urlaub

Seit gestern bin ich für die nächsten 14 Tage im Urlaub. Also gut, was heißt im Urlaub, ich bin ja die meiste Zeit zu Hause, bzw. meine Freundin auch. Wir waren ja schließlich sowieso schon eine Woche in der Türkei dieses Jahr. Gestern hat mein Cousin seinen zweiten Geburtstag gefeiert, von da her waren wir gestern eh schon fast den ganzen Tag verplant.
Vormittag waren wir auch noch schnell in der Stadt.
Dann war der Tag eigentlich eh schon gelaufen.

Da wir aber dann doch die ganzen zwei Wochen nicht komplett zu Hause sitzen wollten, haben wir uns dazu entschlossen eine kleine „Cabriotour“ zu machen. 3 Tage, die Deutsche Alpenstraße abfahren. Also sind wir heute erstmal zum Start der deutschen Alpenstraße in Richtung Bodensee aufgebrochen. Über die Autobahn sind wir ganz gut gekommen, kein Stau nichts. Auch kaum Baustellen. So viel Glück hat man selten.
Also sind wir dann als erstes mal nach Überlingen, haben dort dann die Fähre nach Mainau genommen und haben uns dann das „Blumenparadies“ angesehen. Meine Freundin hat natürlich wieder fleißig Fotografiert. Die Bilder gibts aber erst wenn wird wieder zu Hause sind.

Nachdem wir dann um 15:30 die Fähre wieder zurück genommen hatten und um kurz nach 4 wieder in Überlingen waren, sind wir gleich weiter nach Lindau. Hier haben wir das Hotel für die erste Nacht gebucht „Hotel Bayerischer Hof“. Das Hotel ist soweit ganz in Ordnung. Eigentlich ziemlich gut um ehrlich zu sein. Ich hoffe das Frühstück morgen erfüllt die Erwartungen genauso gut 🙂

Morgen gehts dann erstmal ca. 300km in Richtung Tegernsee, wo wird dann im nächsten Hotel einchecken. Dannach gehts noch den Rest der deutschen Alpenstraße entlang, bis zum Königssee und danach wieder nach Hause.

Jetzt machen wir aber erstmal Lindau noch ein wenig „unsicher“.

11
Aug

Neues Arbeitsgerät!

Nachdem unsere alten Rechner in der Arbeit schon ziemlich „fertig“ waren, haben wir diese Woche neue bekommen. Trotz noch einigermaßen „Potenter“ Ausstattung waren die Kisten doch schon ziemlich langsam. Bis man Arbeiten konnte (Start des PCs, des Compilers, usw.) dauerte es schon ewig. Bis alles offen war was man brauchte vergingen schon mal 15-20 Minuten.

Die alten Rechner (2,4 Ghz Quadcore XEON ohne Hyperthreading, 8GB RAM, NVIDIA Quadro FX 1800, 640GB HDD) wurden durch die neuen ersetzt (2,5 Ghz Quadcore XEON mit Hyperthreading, 16GB RAM, AMD Firepro W5000, 256GB SSD, 1TB HDD). Da geht natürlich gleich ein wenig mehr.
Bis alles was man braucht startklar ist vergeht etwas über eine Minute. Das kann man schon verkraften.

Hauptargument war auch der Geschwindigkeitsvorteil beim Compilieren. Nachdem wir es mal auf einem Macbook Air probiert hatten (Core i5 Dualcore mit 1,7Ghz Taktfrequenz) war beim Compilieren ca. 2 Minuten schneller als unsere Workstations. Eigentlich waren wir der Meinung das MBA wäre um einiges langsamer. Tja da lagen wir falsch…

Die neuen Workstations schaffen das ganze aber doch nochmal ne ganze Ecke schneller. So sind aus ca. 6 Minuten Compilierzeit ca. 2,5 Minuten geworden 🙂

4
Aug

Telekom + Updates = Katastrophe

Wie die meisten schon mitbekommen haben werden, habe ich ja seit geraumer Zeit ein HTC One. Mein iPhone 5 dafür habe ich verkauft. Mit dem Gerät bin ich ja eigentlich ganz zufrieden. Lässt man mal die Tatsache außer acht, dass ich mittlerweile schon das dritte Gerät habe, da bei den ersten beiden etwas nicht gepasst hat.
Das dritte Gerät weißt bis jetzt zum Glück keine Mängel auf. Das einzige Manko bei den Telekomgeräten dafür ist das Updaten. Kein Problem bei anderen Anbietern so wie es scheint. Ca. eine Woche nach Veröffentlichung durch HTC selbst gab es bereits von O2 bzw. Vodafone ein Update für das Gerät.
Nicht so bei der Telekom. Denn die Telekom stellt das Update bis jetzt immer noch nicht bereit. Aktueller Status: Das Update kommt vermutlich Ende August. Begründung: Bei einem Test ist ein Fehler aufgetreten. Darum wurde das Update wieder zum Hersteller zurückgegeben um Nachzubessern.
Seltsamerweise schaffen es alle Hersteller aber früher als die Telekom und die Geräte laufen genauso Problemlos wie die Telekomgeräte.

Einzige Möglichkeit mit einem Telekomgerät schneller in den Genuss eines Updates zu kommen: Die Original-ROM flashen, was allerdings wieder mit root verbunden ist und einige gefahren birgt. Nachdem ich mich schlau gemacht und herausgefunden habe, dass durch Root/Flashen zwar die Garantie verloren geht, aber auch nur im gewissen Rahmen habe ich mich dazu entschieden die Stock-HTC-ROM auf meinem One zu installieren.

Damit bekomme ich jetzt die aktuellen Updates immer von HTC und muss nicht Monate auf das Telekomupdate warten. Perfekt 🙂