ID3 v2 lesen .. wie gehts?
-
download123 schrieb:
*warum kann man ID3v2 nicht mal einfach für die progger machen :-P*
hehe^^ find ich auch
Aber die Mp3-Datei soll halt möglichst klein und flexibel sein.download123 schrieb:
wie ist das jetzt mit dem bit
Naja... Den Post über dir hast du schon gesehen, oder?
-
sehen verstehen und umsätzen ... 3. dinge
ID3v2 wäre mal ne anregung für ein tutorial... (wie mache ichs richtig am besten noch mit beispiel code)
Mal sehen ob ichs halbwegs verstanden habe...
die zahlen hinter dem struct geben die größe davon in bit an ... der rest wird mit nullen gefüllt richtig?..nochmal edit....
wie lese ich das ganze in mein struct ein
bzw. wie kriege ich das da rein...
ach ist das ein mülljetzt muss ich nur noch die doofe doku raffen... und das wie ichs gescheit
einlese... und dann hab ichs (was ne hoffnung :-P)edit x tausend..
langsam komm ich dahinter :p
-
Nanana! Eigentlich ist das gar nicht so schwer! Ein Tutorial werd ich dir zwar nicht schreiben, aber ich versuchs dir nochmal ein wenig zu erklären:
Du weißt ja bestimmt, dass im Arbeitsspeicher gaaaaanz viele 0en und 1en aneinanderliegen. Eine 0 bzw. eine 1 ist dabei ein Bit. 8 Bit fasst man zu einem Char zusammen, 16 Bit zu einem Word und 32 Bit zu einem Long.
Angenommen, du deklarierst eine 8-Bit-Variable und setzt sie auf 0, etwa so:
char a; a = 0;Dann sehen diese 8 Bit im Arbeitsspeicher (dick markiert) so aus:
...0101011010100100000000010101000100110101...
Setzt du sie auf 67, sehen sie so aus (nur der Ausschnitt mit den 8 Bit):
01000011
Das bekommst du raus, indem du den Windows-Rechner startest, im Modus Dez die Zahl 67 eingibst und in den Modus Binschaltest.So.
Wie irgendwo schon gesagt, besteht der Mp3-Header aus 32 Bit. und könnte z.B. so aussehen:
11101010101010101101010010110010
Praktischerweise passen diese Bits alle genau in eine Variable vom Typ Long.
Also liest du als erstes aus der Datei die 32 Bit, die als Header fungieren, in eine Long-Variable ein.Btw: Hast du schon mal was vom Shiften gehört? Und vom &-Operator?
Wenn nicht:
Wenn du die Bits oben um 3 nach rechts shiftest, sehen sie so aus: 00011101010101010101101010010110.
Wenn du den 8-Bit-Wert 01101010 mit 00001111 &-operierst, kommt 00001010 raus.Also, du liest den Header ein, und willst die Mpeg-Version haben (Bit 12).
Also nimmst du deinen Long-Wert (=Header), shiftest ihn 12 nach rechts und operierst ihn mit & 1.long Header; long MpegVersion = (Header>>12)&1.So, keine Lust mehr... Verstanden?
-
Also soweit verstanden... aber
der IDEv2 Header besteht aus 80 bit (10 byte :-P) klugscheiß...
ich habe schon ne menge rausbekommen
ich kann schon bist unsynchronisation auslesen...
bisher habe ich erstmal den gesamten header... (alle 10 byte) in einen string eingelesen...dann die ersten 3 char auf "IDE" überprüft .. danach weggeschmissen...
die nächsten zwei in ints getan, (versionsnummer 4.0) passt... den nächsten char besorg ich mir die ersten zwei bit (mit (c & 0x01) ) etc. (um zu checken ob unsynchronisation)...jetzt ist die frage ob ich die size in ints packen kann
in der doku heißt es
ID3 size 4 * %0xxxxxxx
das heißt 4 byte size...
nur sind das int? bzw. kann ich den inhalt "%0xxxxxxx" einfach in einen int reinschmeißen?(ich kanns halt leider nicht überprüfen)
habs einfach mal ausprobiert...
0 0 17 49 also so vom gefühl her könntes meiner Meinung nach hinkommen
aber klärt mich auf...
-
also das mit der size raf ich nicht...
mit der 1 seite des gesamttags,
und mit der framesize
zitate
"and
one three byte size field"... schmeiße ich das auch in einfach in 3 ints... kann mir jemand helfen ... wie mache ich das mti den sizen
... naja okay ... die size des gesamt headers könnte ich (4 x 8 bit = 32 ) in einen unsignet long packen
aber wie mach ich das momentan ist es in 4 chars wie pack ich die in einen long... und was mache ich mit den 3 byte size angabe einer frame?
-
sorry das ich nochmal poste...
Aber ich habe jetzt wirklich ein problem was ich nicht hinbekomme
die size
ich habe 4 byte ... in 4 char eingelesen...
jetzt muss ich die info irgendwie zur verarbeitung in eine zahl (einen int) verwandelnproblem 1. die bytes fangen jeweils mit null an (die null scheint nicht zur info zu gehören) [ 4 * %0xxxxxxx]
wie berücksichtige ich das bzw. generell wie packe ich 4 char in ein int?und das ganze nochmal mit den frame hedern [ one three byte size field] da sinds 3 byte... wie packe ich das in einen header...
Danke wenn mir jemand helfen kann *ich verzweifle*

-
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?