MP3 Header problem



  • Hoi,
    wie der MP3-Header aufgebaut ist, steht unter www.wotsit.org, hab ich auch gelesen, hab dennoch ein kleines Problem:

    wenn die *.mp3-Datei einen ID3v2 Tag besitzt (enthält Informationen über Interpreten etc.), befindet sich dieser ID3v2 Tag am Anfang der Datei, danach kommt der Header.
    Wie finde ich jetzt den Header sauber?
    Hatte schon ein paar Versuche gestartet, die auch funktionierten, jedoch nicht unbedingt sauber waren...

    Bin für jede Hilfe dankbar!



  • Moin!

    Vielleicht kann dir das weiter helfen.

    http://www.mp3-tech.org/programmer/frame_header.html

    Habe zwar selber noch nicht versucht irgendwas mit mp3 zu machen, aber interessiert hat es mich mal wie der Header aussieht.
    Da kann man sehen, wie gross (in bit) jeder Header Teil ist.
    So sollte man dann auch den gesamten Header 'sauber' auslesen/schreiben können.
    Würde mich mal interessieren ob du das hinbekommen hast!?

    Gruss flouser

    OH! Sorry! Merke gerade, dass das ja nicht wirklich deine Frage beantwortet!
    Da kann ich nur sagen : Google: mp3 Header



  • Hab jetzt grade folgendes probiert (erstmal ohne id3v2, header steht also am anfang) :

    typedef struct
    {
     unsigned int FrameSync:11;
     unsigned int MPEGVersion:2;
     unsigned int MPEGLayer:2;
     unsigned int Protection:1;
     unsigned int Bitrate:  4;
     unsigned int Samplefrq:  2;
     unsigned int Padding:1;
     unsigned int Private:1;
     unsigned int Mode:2;
     unsigned int Mode_Ext:2;
     unsigned int Copyright:1;
     unsigned int Original:1;
     unsigned int Emphasis:2;
    
    }MP3_HEADER;
    

    Diese Struktur lese ich sofort beim öffnen der Datei ein, bekomme für FrameSync aber nur den Wert 767 -> neun Bits sind nur gesetzt, wieso nicht alle 11, wie es eigentlich sein müsste? Die MP3 ist korrekt, hab mit einem Hex-Editor reingeschaut (die ersten zwei Bytes : FF FA).
    bin für jede Hilfe dankbar



  • Wie liest du die Struktur ein?



  • mit fread(target, sizeof(MP3_HEADER), 1, file); target ist ein Zeiger auf eine MP3_HEADER Struktur.



  • Das ist schon mal gut. Öffnest du die Datei auch im Binärmodus? ( fopen(..., "rb") )



  • Jo, öffne sie binär.
    Wenn ich vier Bytea auslese (also char test[4]), dann stimmt auch alles, nur die Struktur will er nicht richtig einlesen.
    cu



  • Paul W. schrieb:

    Wenn ich vier Bytea auslese (also char test[4]), dann stimmt auch alles, nur die Struktur will er nicht richtig einlesen.

    Nur so als Idee: hast du schonmal mit sizeof() gecheckt ob die struct die richtige größe hat? uU sind padding bytes/bits drinnen...



  • Jo, hab ich eben gechekt, sizeof() liefert den Wert 4.



  • Paul W. schrieb:

    Jo, hab ich eben gechekt, sizeof() liefert den Wert 4.

    sizeof(MP3_HEADER) kann keine 4 bytes haben,
    sondern 13 * 4 (sizeof(unsigned int)) = 52bytes



  • Also bei mit liefert sizeof ganz sicher den Wert 4, kann dir sogar nen Screenshot von machen ;).
    Das sind zwar alles unsigned ints, jedoch hab ich überall bitfelder angegeben... oder werden die hier gar nicht berücksichtigt?



  • mist habe die bitfelder übersehen. 😃



  • @Paul
    Wirklich seltsam. Kannst du mal dein Codestück dafür zeigen?



  • Hoi,
    So, hier mal ein kleines prog :

    #include <windows.h>
    #include <stdio.h>
    
    typedef struct
    {
     unsigned int FrameSync:11;
     unsigned int MPEGVersion:2;
     unsigned int MPEGLayer:2;
     unsigned int Protection:1;
     unsigned int Bitrate:  4;
     unsigned int Samplefrq:  2;
     unsigned int Padding:1;
     unsigned int Private:1;
     unsigned int Mode:2;
     unsigned int Mode_Ext:2;
     unsigned int Copyright:1;
     unsigned int Original:1;
     unsigned int Emphasis:2;
    }MP3_HEADER;
    
    int main(void)   //hab kein bock auf die Warnungen bei argc und argv
    {
     FILE* file;
     MP3_HEADER header;
     char datei[MAX_PATH];
    
     printf("Dateipfad : ");
     scanf("%s", datei);
    
     memset(&header, 0, sizeof(MP3_HEADER));
    
     if((file = fopen(datei, "rb")) == NULL)
     {
      printf("Konnte MP3-Datei nicht oeffnen!");
      return 0;
     }
     else
     {
      fread(&header, sizeof(MP3_HEADER), 1, file);
      printf("FrameSync : %d\n", header.FrameSync);
      fclose(file);
     }
    
     return 0;
    }
    

    jetzt is mir eins aufgefallen :
    wenn die ersten beiden Bytes der Datei 0xFF 0xFB sind, dann macht er alles richtig (FrameSync is dann 1023, 2^10 - 1, alle Bits sind gesetzt).Bei 0xFF 0xFA kommt aber wieder 767 raus.
    Dabei ist da kein Unterschied in den ersten elf Bits.
    Ich hab echt keine Ahnung, wo der Fehler liegt...

    danke



  • Hmmm kann mir nur noch vorstellen, dass fread() vielleicht Probleme hat, wenn die Struktur aus Bitfeldern besteht. Obwohl das eigentlich nichts ausmachen dürfte. Hast du schon mal probiert einfach den Header in einen long (4 Byte) einzulesen und dann hexadezimal auszugeben?

    Du kannst dir übrigens das memset sparen, wenn du bei der Deklaration von header einfach ein = {0} dahinterschreibst. 🙂



  • ja, das hab ich mit 4 chars gemacht (jeweils ein byte groß), da funzt alles wunderbar...



  • Gehts auch mit einem long?

    Wenn ja dann änder mal deine Datenstruktur wie folgt um, ansonsten nimm einfach vier chars anstatt dem long ;):

    typedef struct
    {
     unsigned int FrameSync:11;
     unsigned int MPEGVersion:2;
     unsigned int MPEGLayer:2;
     unsigned int Protection:1;
     unsigned int Bitrate:  4;
     unsigned int Samplefrq:  2;
     unsigned int Padding:1;
     unsigned int Private:1;
     unsigned int Mode:2;
     unsigned int Mode_Ext:2;
     unsigned int Copyright:1;
     unsigned int Original:1;
     unsigned int Emphasis:2;
    
    }MP3_HEADER_DETAIL;
    
    typedef union
    {
     long bytes;
     MP3_HEADER_DETAIL detail;
    }MP3_HEADER;
    


  • kommt das gleiche bei raus, bei FF FB isses richtig, bei FF FA isses falsch...



  • Enthält denn der long wert den richtigen Wert? Bei 4 chars meintest du funktioniert es. Hast du anstatt dem long schon char bytes[4] verwendet??



  • Könnte es was mit dem byte-Alignment zu tun haben? Oder hast du das entsprechend konfiguriert? ->Compilereinstellungen.

    -junix


Log in to reply