2009-11-05 8 views
2

J'essaie d'extraire l'en-tête mp3 d'un fichier. Ceci est différent des tags ID3 - l'en-tête mp3 est l'endroit où sont conservées les informations sur la version MPEG, le débit binaire, la fréquence, etc.Accéder à l'en-tête mp3 binaire en C via fopen

Vous pouvez voir un aperçu de la structure d'en-tête mp3 ici: http://upload.wikimedia.org/wikipedia/commons/0/01/Mp3filestructure.svg

Mon problème est, en dépit du chargement du fichier et de réception maintenant valide (pour autant que je sache) sortie binaire, je ne suis pas voir les valeurs attendues . Les 12 premiers bits du fichier mp3 devraient être tous ceux, pour le mot de synchronisation mp3. Cependant, je reçois quelque chose de différent pour les 8 premiers bits seulement. Cela pourrait suggérer un problème pour moi.

Comme une note de côté, j'ai un fichier mp3 valide étant attaché via fopen

// Main function 
int main (void) 
{ 
    // Declare variables 
    FILE *mp3file; 
    char requestedFile[255] = ""; 
    unsigned long fileLength; 

    // Counters 
    int i; 

    // Tryout 
    unsigned char byte; // Read from file 
    unsigned char mask = 1; // Bit mask 
    unsigned char bits[8]; 

    // Memory allocation with malloc 
    // Ignore this at the moment! Will be used in the future 
    //mp3syncword=(unsigned int *)malloc(20000); 

    // Let's get the name of the file thats requested 
    strcpy(requestedFile,"testmp3.mp3"); // lets hardcode this into here for now 

    // Open the file 
    mp3file = fopen(requestedFile, "rb"); // open the requested file with mode read, binary 
    if (!mp3file){ 
     printf("Not found!"); // if we can't find the file, notify the user of the problem 
    } 

    // Let's get some header data from the file 
    fseek(mp3file,0,SEEK_SET); 
    fread(&byte,sizeof(byte),1,mp3file); 

    // Extract the bits 
    for (int i = 0; i < sizeof(bits); i++) { 
     bits[i] = (byte >> i) & mask; 
    } 

    // For debug purposes, lets print the received data 
    for (int i = 0; i < sizeof(bits); i++) { 
     printf("Bit: %d\n",bits[i]); 
    } 
+0

Je crois me souvenir que ID3v2 s'intègre dans la structure MP3 pour stocker ses informations au début du fichier, mais avec les bits de synchronisation qui ne correspondent pas. Ce n'est pas votre problème principal, cependant - référez-vous aux autres réponses pour cela. –

+0

Même avec le bit de synchronisation commençant à zéro, le même problème se produit. Je m'excuse de ne pas le remettre à zéro (je l'ai changé à un à des fins de test) – BSchlinker

+0

Dans ce cas, jetez un oeil à votre image SVG: "La structure du fichier MP3 peut être" encapsulée "dans un tag ID3." Ouvrez votre fichier MP3 avec un éditeur (hexadécimal) de votre choix, vous verrez très probablement qu'il commence par 'ID3' ce qui signifie que vous allez analyser/ignorer les métadonnées ID3 avant de commencer avec l'en-tête MP3. – schnaader

Répondre

1

Les informations ID3 peut venir en premier lieu. Sont les 3 premiers caractères ID3?

+0

Avez-vous des informations de spécification d'en-tête mp3 qui montreraient que l'information ID3 vient en premier? Je pensais que c'était annexé à la fin. – BSchlinker

+1

C'est le côté droit de la spécification que vous avez publiée. – eduffy

+0

Malgré le fait que les humains lisent de gauche à droite ... Je n'ai pas réussi à regarder tout le chemin vers la droite cette fois. J'ai enlevé les étiquettes et j'ai l'impression de recevoir une sortie considérablement améliorée (le premier octet contient tous les 1 bits). Cependant, la sortie semble être l'inverse - octet 2, que je m'attendais à 10100000 est 00000101. Octet 1 semble être 11011111 au lieu de 11111011. C'est soit une erreur dans ma compréhension, mon code, ou juste une coïncidence. – BSchlinker

1
fseek(mp3file,1,SEEK_SET); 

Y at-il une raison pour laquelle vous sauter le premier octet du fichier?

1

Essayez

fseek(mp3file,0,SEEK_SET) 

au lieu de

fseek(mp3file,1,SEEK_SET). 

Fichiers début à la position de l'octet 0.

+0

ou à défaut ..ne vous embêtez même pas à chercher car vous pointez déjà sur l'octet 0 ... – Goz

+0

Eh bien, je préfère le faire quand même. Vous savez, "n'assumez jamais rien" :) – schnaader

+0

Même avec le bit de synchronisation commençant à zéro, le même problème se produit. Je m'excuse de ne pas le remettre à zéro (je l'ai changé à un à des fins de test) – BSchlinker

1

Je pense que vous voulez probablement

fseek(mp3file,0,SEEK_SET); 
+0

Même avec le bit de synchronisation commençant à zéro, le même problème se produit. Je m'excuse de ne pas le remettre à zéro (je l'ai changé à un à des fins de test) – BSchlinker

0

fseek(mp3file,1,SEEK_SET); faire s vous sauter les 8 premiers bits, donc ce que vous obtenez avec fread sont des bits 9 à 16

+0

Même avec le bit de synchronisation commençant à zéro, le même problème se produit. Je m'excuse de ne pas le remettre à zéro (je l'ai changé à un à des fins de test) – BSchlinker

2

ID3v2 occupe le premier bit du fichier MP3, si elle est là. Les trois premiers octets du fichier sera « ID3 »:

http://www.id3.org/id3v2.4.0-structure

Il y a deux méthodes pour y faire face. Le premier vérifie la présence de la balise ID3, puis analyse l'en-tête de 10 octets pour la taille de la balise, et ignore ces nombreux octets.

EDIT: Si vous analysez l'en-tête, vous devez vérifier que le 4ème bit du champ Indicateurs est défini sur 1, si c'est le cas, vous devez ignorer 10 octets supplémentaires pour dépasser le pied de page.

Ou vous pouvez simplement chercher à travers le MP3 jusqu'à ce que vous frappiez le motif de synchronisation. La façon dont ID3v2 est configuré, 11 bits d'affilée ne devrait pas se produire, pour assurer la compatibilité avec les joueurs qui ne le supportent pas.

+0

eduffy mentionné la même chose, alors je suis allé de l'avant et dépouillé les tags ID3. Cela a aidé, mais j'ai maintenant un autre problème. Cependant, la sortie semble être l'inverse - octet 2, que je m'attendais à 10100000 est 00000101. Octet 1 semble être 11011111 au lieu de 11111011. C'est soit une erreur dans ma compréhension, mon code, ou juste une coïncidence. – BSchlinker

+0

Vous parlez d'un ensemble d'octets blancs? Étant donné que les deux premiers octets dans un en-tête de trame MP3 doivent être 11111111 11111011. Les bits de synchronisation sont un 11 bits, mettant la version, la couche et la protection contre les erreurs dans le deuxième octet lu de l'en-tête. Voici une référence plus complète pour ce que les bits d'en-tête signifient: http://www.mp3-tech.org/programmer/frame_header.html –