Zum Inhalt springen

Empfohlene Beiträge

Geschrieben

Also, ich versuche grade ein Programm zu schreiben, das MP3 Tags auslesen kann. Ich möchte nun die ID3-Daten am anfang der Dateien auslesen. Dazu schreibe ich den Anfang der Datei in einen String, z.B. char temp [ 255 ].

Nach den ersten 10 Bytes kommen endlich die Frames mit den Infos.

Jeder Frame ist folgendermaßen aufgebaut:

Frameheader:

4 Bytes Schlüsselbegriff

4 Bytes Framebodysize

2 Bytes Flags

Framebody:

Text

Damit ich nun den Text im Framebody genau auslesen kann brauch ich die Framebodysize. Dummerweise ist die bei mir in Strings mit 4 Byte Länge ( z.B. char xyz [ 3 ] ) gespeichert. Wie krieg ich die in eine Integerzahl?

Geschrieben

Ich glaube nicht, dass die Länge als Text im Header steht. Sehr wahrscheinlich ist sie binär. Da hilft atoi nicht weiter.

Man braucht nur einen Zeiger auf den Anfang der Framebodysize, wandelt den in einen Zeiger auf einen 32-Bit-Ganzzahltyp um (je nach Plattform z.B. unsigned int) und dereferenziert diesen.

Man muss aber auf Big-/Little-Endian-Konflikte achten.

Geschrieben

Also, ich hab die Daten ausgelesen und in char cache [ 255 ] gespeichert.

Daraufhin eine schleife erzeugt, die nach bestimmten Buchstabenfolgen (den Schlüsselwörtern) sucht. Hier ein Ausschnitt:

//beta ist der counter der Hauptschleife

if ( cache [ beta ] == 'T' )

{

if ( cache [ beta + 1 ] == 'A' )

{

if ( cache [ beta + 2 ] == 'L' )

if ( cache [ beta + 3 ] == 'B' ) //Prüfe nach Album (TALB)

{

for ( int xy = 0; xy < 4; xy ++ )

aalbum [ xy ] = cache [ beta + 4 + xy ];

}

//aalbum enthält die Längenangabe des Framebodys für das Album

Wie transferiere ich in diesem Beispiel den Wert von aalbum in eine Integervariable? Diese brauche ich dann um die Werte von cache in einen String album [ bodysize ] zu packen.

Geschrieben

Hmmmm, das liefert mir einen Wert von 301989888 statt den 18, die aalbum laut quickwatch hat.


	input.seekg ( ios::beg );

	char cache [ 255 ];

	memset ( &cache, 0, sizeof ( cache ) );

	input.read ( cache, sizeof ( cache ) );


	// ID3v2 Sizeinformationen über die Framebodies

	char aalbum [ 3 ], agenre [ 3 ], atitel [ 3 ], ainterpret [ 3 ], 

		atrack [ 3 ], ajahr [ 3 ], akommentar [ 3 ];


	//ID3v2 Framebodyinformationen

	char album [ 31 ], genre [ 31 ], titel [ 31 ], interpret [ 31 ],

		track [ 3 ], jahr [ 3 ], kommentar [ 31 ];


	if ( ( cache [ 0 ] == 'I' ) && ( cache [ 1 ] == 'D' ) && ( cache [ 2 ] == '3' ) )

    //Prüfe ob ID3-Tag vorhanden

	{			

		for ( int beta = 10; beta < 250; beta ++ )

		{

			if ( ( cache [ beta ] == 'T' ) && ( cache [ beta + 1 ] == 'A' ) && ( cache [ beta + 2 ] == 'L' ) && ( cache [ beta + 3 ] == 'B' ) )

			//Prüfe nach Album

			{

				for ( int xy = 0; xy < 4; xy ++ )

					aalbum [ xy ] = cache [ beta + 4 + xy ];


				unsigned int n = * ( reinterpret_cast < unsigned int* > ( aalbum ) );


				for ( unsigned int yx = 0; yx < n; yx ++ )

					album [ yx ] = cache [ beta + 10 + yx ];	

			}

Geschrieben
Hmmmm, das liefert mir einen Wert von 301989888 statt den 18, die aalbum laut quickwatch hat.

Ich habe mal nachgesehen. Das Binärformat ist Big Endian (d.h. das höchstwertige Byte kommt zuerst), dann passt der Wert, denn dein Computer ist offenbar Little Endian:



dez. 301989888 hex 12000000
dez. 18 hex 00000012
[/code] Du musst also die Reihenfolge der Bytes umdrehen:
[CODE]unsigned int framebodysize = *(reinterpret_cast<unsigned int*>(aalbum));
char* p = reinterpret_cast<char*>(&framebodysize);
std::swap(p[0], p[3]);
std::swap(p[1], p[2]);
Danach sollte in framebodysize der richtige Wert stehen. Alternativ könntest du auch die Funktion htonl benutzen, die sollte das gleiche machen. Das hier:
if ( ( cache [ 0 ] == 'I' ) && ( cache [ 1 ] == 'D' ) && ( cache [ 2 ] == '3' ) )
kannst du übrigens einfacher so schreiben:
if(0 == memcmp(&cache[0], "ID3", 3))

Geschrieben

Willst du es denn zu Uebungszwecken wirklich komplett selbst machen, oder kommt es dir eher auf das Ergebnis an?

Es gibt eine nette Lib die einem schon einiges erleichtert. (Ok, es gibt noch viel mehr davon, aber diese hab ich mal verwendet)

Goos

Geschrieben

Soweit ich weiß, ist bei id3 die Länge aber nicht komplett in allen 8 Bits eines Bytes gespeichert, sondern nur in sieben davon, das MSB muß glaub ich Null sein, wenn ich mich richtig erinnere. Sonst mußt du in der ID3v2-Spezifikation nachschauen.

Geschrieben

Hallo,

Frameheader:

4 Bytes Schlüsselbegriff

4 Bytes Framebodysize

2 Bytes Flags

Framebody:

Text

Ich würde bei diesem Headeraufbau nicht über ein char-Array gehen, sondern eine Struktur verwenden:

struct header {

char key[4];

int size;

short flags;

}

Den Header kannst Du dann problemlos in die Struktur einlesen. Nachdem Du die Größe des Bodies ermittelt hast, läßt sich der Body mit einem weiteren Funktionsaufruf einlesen. GGf. auf htonl() zurückgreifen. Diese Macros sind portable und damit auf jeder Plattform verfügbar.

Nic

Geschrieben

Da ich Anfänger bin und bisher nur schulmäßig in Pascal programmiert hab sind mir Strukturen noch nicht ganz geheuer. *g*

Ich schätze ich werd mir das zu Herzen nehmen wenn mein Programm das Betastadium verlässt. ^^

Zumal ich momentan noch bei den Grundlagen so meine Probleme habe.

Geschrieben

Kennt sich einer hier mit den MP3-Strukturen aus?

Ich hab da ein Problem:

Das Kommentarfeld, der Frame ist folgendermaßen aufgebaut:

Frameheader:

- 4 Bytes COMM

- 4 Bytes Framebodysize

- 2 Bytes Flags

Framebody:

- Kommentar

Nun, normalerweise klappt das sehr gut mit dem auslesen der Infos.

Aber leider hab ich festgestellt, dass Winamp manchmal einfach noch ein paar Bytes vor den eigentlichen Kommentar schiebt. Sprich ein leeres Byte und zwei Bytes mit Informationen. Diese haben glaub ich irgendwas mit dem Inhalt des Kommentars zu tun. Aber noch nicht herausgefunden, was da zugrunde liegt.

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...