MP3 Header problem



  • 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



  • AJ schrieb:

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

    jo, hab ich probiert : kommt das selbe bei raus...

    @junix, öhm... ich weiß nicht mal was das ist, bitte um Aufklärung! Ist das die Anlegung der Struktur im Speicher?h ab den Free Borland Compiler, wie kann ich das da einstellen? (hab da nur die Option "align on n-bytes", aber was soll da rein?)

    danke



  • Paul W. schrieb:

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

    Da hast du gesagt, dass es wunderbar funktioniert. Warum jetzt aufeinmal nicht mehr? Zeig mal wie du mit der union deine Daten einliest (Code).


Anmelden zum Antworten