ID3 v2 lesen .. wie gehts?
-
4 Char -> 1 Int
char Bytes[4]; int Big; //Entweder... CopyMemory( &Big, Bytes, 4 ); // oder... Big = *((int*)Bytes); // oder... Big = Big[3]<<24 | Big[2]<<16 | Big[1]<<8 | Big[0];
-
kommen 4401 Byte für einen ID3v2 header hin (kommt mir etwas viel vor)
und wie mach ich das mit nur 3 byte size bereich?..
ich bin mir da noch net so ganz sicher ob das für id3 so geht.. (gerade auch wegen den vorgegeben 0 en an jedem byteanfang im 4byte header
-
poste doch mal bitte deine Quelle für den Header
-
also von der seite:
http://www.id3.org/id3v2-00.txtHier die Ausschnitte
The ID3v2 tag header, which should be the first information in the
file, is 10 bytes as follows:ID3/file identifier "ID3"
ID3 version $02 00
ID3 flags %xx000000
ID3 size 4 * %0xxxxxxxThe headers of the frames are similar in their construction. They
consist of one three character identifier (capital A-Z and 0-9) and
one three byte size field, making a total of six bytes.*ich hoffe das wars was du meinstes
-
War genau das was ich meinte

Gut, jetzt wüsste ich gerne, wie weit du mit dem Einlesen gekommen bist. Soweit ich das verstanden hab, kannst du schon das "ID3" einlesen, die ID3-Version und die ID3-Flags.
The ID3v2 tag header, which should be the first information in the
file, is 10 bytes as follows:ID3/file identifier "ID3"
ID3 version $02 00
ID3 flags %xx000000
ID3 size 4 * %0xxxxxxxZum Einlesen würde ich eine Struktur festlegen, und da reinlesen.
#pragma strict struct ID3V2HEADER { char ID[3]; char MajorVersion; char MinorVersion; char Flags; char Size[4]; }; ID3V2HEADER Header; ReadFile( hFile, &Header, 10, &Dummy, NULL );Die Berechnung der Size ist nicht so einfach. Das oberste Bit jedes Bytes ist 0 und wird ignoriert.
Ich würds so machen (keine Garantie auf Richtigkeit
):ULONG RealTagSize = Header.Size[0] | Header.Size[1]<<7 | Header.Size[2]<<14 | Header.Size[3]<<21;Dann haste immerhin schonmal den Header. Wo kommst du jetzt nicht weiter?
Und bitte benutze für deine Fragen deutliche, eindeutige deutsche Sätze!
-
Also, ich beschreibe mal kurz wie ichs umgesetzt habe:
ich habe erstmal ein struct angelegt, wo alle daten drin sind:struct ID3v2_Header { int version[2]; bool unsynchronisation; bool compression; int size; };in der Funktion lese ich die ersten 10 byte aus und schreibe sie in einen String
//ifs ist ein ifstream mit geöffnerter Datei string tag; for(int i=1; i <= 10; i++) { char abl; ifs >> abl; tag+=abl; }danach werte ich die chars nach und nach aus und "fülle" das Struct, und lösche die char's aus dem string.
Das klappt bis zur Size. Die bekomme ich irgendwie nicht so ganz.ich habe jetzt versucht es nach deinem Code in Nummern zu packen.
ULONG RealTagSize = Header.Size[0] | Header.Size[1]<<7 | Header.Size[2]<<14 | Header.Size[3]<<21;Was ist ein ULONG? ein unsigned long? bei mir erkennt der Compiler das nicht.
Sieht in meinem Code so aus
Data.size = tag[1] | tag[2]<<7 | tag[3]<<14 | tag[4]<<21;Data ist ein object des oberen ID3v2_Header structs.
Allerdings bekomme ich dann einen Wert a la 103038976

-
Ich würde das auf keinen Fall mit einem String machen!
Erstens passt es einfach nicht, weil ein String eine Zeichenkette beinhalten soll und nicht einzelne Daten-Bytes.
Zweitens sind Strings null-terminiert, d.h. der String hört da auf, wo das erste Byte mit dem Wert 0 ist.Badestrand schrieb:
struct ID3V2HEADER
{
char ID[3];
char MajorVersion;
char MinorVersion;
char Flags;
char Size[4];
};Warum liest du nicht einfach die ersten 10 Bytes in diese Struktur ein? Dann kannst du sofort die einzelnen Member-Variablen ansprechen und weißt, welches Byte welche Bedeutung hat.
Ja, ULONG steht für unsigned long. Halt einfach eine 32-Bit-Variable für die positiven Zahlenwerte. Was kommt denn dabei raus, wenn du das mit meiner Methode machst?
-
Okay.. jetzt lese ich das ganze in ein char array ein..
kommt aber die selbe zahl als size raus,
Ich wills deshalb nicht gleich in ein struct reinlesen, weil ich dann 2 structs bräuchte was es nicht übersichtlicher macht.aber letztlich machts auch keinen unterschied ob mans in 10 char oder in ein struct das aus 10 char besteht oder?
Also es besteht leider weiterhin das problem, das die Zahl für die Size zu groß ist
es ist immernoch 103038976
bzw. ist das zu viel?
-
Byte-Array ist super

Kannst du mal die Hauptteile deines Codes posten? Einlesen, und size-Berechnung?
Edit: Btw: Ist definitiv zu viel!
-
einlesen
ifstream ifs(path,ios_base::binary); //,ios_base::binary if (! ifs) { return -2; } char tag[10]; for(int i=0; i < 10; i++) { ifs >> tag[i]; } if((tag[0]=='I') && (tag[1]=='D') && (tag[2]=='3')) { cout << "ID3v2 tag"<< endl; ID3v2_Header Data; ...und dann etwas weiter unten size
data.size ist ein unsigned longData.size = tag[6] | tag[7]<<7 | tag[8]<<14 | tag[9]<<21;
-
Sieht soweit richtig aus... Hab keine Lust zu rechnen: Lass dir mal die einzelnen Bytes ausgeben und schau mit nem Hexeditor in der mp3-Datei nach, ob das übereinstimmt.
Hab bei mir mal geguckt. Hat gestimmt, kam 741 raus.
-
Also wenn ich die bytes einzeln ausgebe stimmen sie mit den werten des Hex editors überein... sind Dezimal 0 | 0 | 17 | 49 | sowohl im editor als auch wenn ich sie ausgebe,
Allerdings stimmt es "zusammengefasst"(in einen int bzw. unsigned int gemacht) halt nicht. Werden die Miteinander multipliziert... oder wie ergibt sich die Size?
-
Data.size = tag[6]<<21 | tag[7]<<14 | tag[8]<<7 | tag[9];?
-
ah so rum kommt "nur" noch 2225 Raus
immernoch etwas hoch oder?
-
Ich glaube 2 KB sind wenig genug für die Infos. Weiß ja nicht, wie die gespeichert sind und vielleicht sind die Lyrics mit drin?
-
in wirklichkeit sinds etwa 50 (ohne header) danach kommen nullen
Edit .. aber du hast recht nullen (so viele da die 2225 Byte gefüllt sind)