IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Probleme taille structure / parsing tag mp3


Sujet :

C

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 3
    Points : 1
    Points
    1
    Par défaut Probleme taille structure / parsing tag mp3
    Bonjour a tous,
    voila j'essaye d'écrire un petit programme qui lit les tag ID3 d'un fichier mp3,
    j'ai bien regardé la spec du format, et j'ai la structure suivante pour récupere le header d'un tag :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    typedef struct {
      unsigned char		id[3];
      unsigned char		revision[2];
      unsigned char		flags;
      unsigned int		size;
    } ID3V2_header_t;
    Le header fait donc exactement 10 bytes, seulement voila, alors que ma structure devait en faire 10 aussi (3 + 2 + 1 + 4), lorque que je fait
    sizeof(ID3V2_header_t) j'obtient 12 ...

    J'ai regardé sur la FAQ C ou il est dit que cela peut venir d'un probleme d'alignement des bits ? mais comment y remédier ? Est qu'il faut que je passe par l'operateur ":" pour spécifier explicitement la taille de chacun de mes champs en bits ? cad :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    typedef struct {
      unsigned char		id[3] : 24
      unsigned char		revision[2] : 16
      unsigned char		flags : 8
      unsigned int		size : 32
    } ID3V2_header_t;
    ?

    Voila, tout aide sera la bienvennue
    (sachant que j'ai deja un autre pb en rab, mais je le garde pour le prochain post )

    PS : si vous voulez plus d'informations, voila un lien vers la spec des tags :
    http://www.id3.org/id3v2.3.0.html

  2. #2
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut Re: Probleme taille structure / parsing tag mp3
    Citation Envoyé par lucas_sophia
    voila j'essaye d'écrire un petit programme qui lit les tag ID3 d'un fichier mp3,
    j'ai bien regardé la spec du format, et j'ai la structure suivante pour récupere le header d'un tag :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    typedef struct {
      unsigned char		id[3];
      unsigned char		revision[2];
      unsigned char		flags;
      unsigned int		size;
    } ID3V2_header_t;
    Erreur de conception fréquente. En C, il n'est pas possible de mapper une structure sur un flux de bytes de façon portable, et ce pour de nombreuses raisons :
    • La taille des types n'est pas portable
    • La représentation des valeurs numériques n'est pas portable
    • L'alignement des données n'est pas portable

    Le header fait donc exactement 10 bytes, seulement voila, alors que ma structure devait en faire 10 aussi (3 + 2 + 1 + 4), lorque que je fait
    sizeof(ID3V2_header_t) j'obtient 12 ...
    Démonstration faite.

    Pour être portable, extraire les données à la main (tableau de unsigned char) dans une structure interne.

    Idem dans l'autre sens. Les structures ne peuvent pas servir à implémenter des interfaces externes de façon portable. Jamais.
    Pas de Wi-Fi à la maison : CPL

  3. #3
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    Merci Emmanuel,
    en fait l'idée de mapper la structure sur le header était principalement de pourvoir ensuite utiliser le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    FILE* fIn;
    ID3V2_header_t header;
    if((fIn= fopen(mp3filename, "r")) == NULL) {
    	return EXIT_FAILURE;
    }
    fread(&header, sizeof(ID3V2_header_t), 1, fIn);
    pour remplir directement toute la structure.
    Si j'utilise ce code, c'est en fait parce que j'avais lu un tutorial sur le chargement de bitmap, et la personne qui l'avait rédigé utilisait cette technique pour lire le header du fichier :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    fread(&bmpheader, sizeof(BITMAPINFOHEADER), 1, fIn);
    Bon ben je vais remplir les structures au fur et fur, j'avais testé, mais je trouvais ca un peu long ...

    J'en profite pour poser ma deuxieme question :
    voila une fois que j'ai reussi a recuperer le header de mon tag, je dois récuperer les frames du tag, pour etre plus clair, voila comment se présente un tag :

    -------------------------------
    TAG HEADER
    -------------------------------
    EXTENDED HEADER (falcultatif)
    -------------------------------
    FRAMES
    ....
    ....
    --------------------------------

    Le principe et de recuperer le header de la frame, qui est constitué d'un id (4 bytes), puis sa taille (4 bytes), si la frame nous interresse (par exemple la frame qui contient le nom de l'artiste, le nom de l'album etc...), on la lit, sinon on regarde la taille, et on passe a la frame suivante.
    Mon probleme, c'est que j'arrive a lire l'id de la premiere frame, "TABL" qui correspond aux informations sur la chanson , mais quand je recupere la taille, j'obient un chiffre completement exhorbitant ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    // frame header
    char fid[4];
    char fsize[4];
     
    printf("Reading frame header\n");
    fread(&fid, sizeof(fid), 1, fIn);
    printf("fid read : %c%c%c%c\n", fid[0], fid[1], fid[2], fid[3]);
    fread(&fsize, sizeof(fsize), 1, fIn);
    printf("fsize read : %d\n", fsize);
    ce qui me donne comme trace :
    Reading frame header
    fid read : TALB
    fsize read :1310576
    le probleme c'est que mon .mp3 fait seulement 258ko
    PS : sachant qu'il est dit dans la spec :
    The bitorder in ID3v2 is most significant bit first (MSB). The byteorder in multibyte numbers is most significant byte first (e.g. $12345678 would be encoded $12 34 56 78).
    Merci, J'espere que j'ai été clair, et pas trop long

  4. #4
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par lucas_sophia
    Merci Emmanuel,
    en fait l'idée de mapper la structure sur le header était principalement de pourvoir ensuite utiliser le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    FILE* fIn;
    ID3V2_header_t header;
    if((fIn= fopen(mp3filename, "r")) == NULL) {
    	return EXIT_FAILURE;
    }
    fread(&header, sizeof(ID3V2_header_t), 1, fIn);
    pour remplir directement toute la structure.
    Oui, j'avais compris ! Mais cette technique, bien que séduisante, n'est pas portable. Tu en as toi même apporté la preuve.
    Si j'utilise ce code, c'est en fait parce que j'avais lu un tutorial sur le chargement de bitmap, et la personne qui l'avait rédigé utilisait cette technique pour lire le header du fichier :
    D'où ma remarque 'erreur de conception courante'...
    Bon ben je vais remplir les structures au fur et fur, j'avais testé, mais je trouvais ca un peu long ...
    Oui, la portabilité a un coût.
    Pas de Wi-Fi à la maison : CPL

  5. #5
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    Haleluyah !
    ca y est, le probleme venait bien de "l'endianess", aprés avoir bien regardé comment ca marchait, il s'avere que mon int qui contenait la size de ma frame était lu a l'envers (Big endian), donc il faut que je passe par une convevrsion :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    nsize = ntohl(fsize);
    et voila, tout de suite les tailles sont plus cohérentes, 29, 25 bytes.

  6. #6
    Membre éclairé
    Avatar de Edouard Kaiser
    Profil pro
    Inscrit en
    Février 2004
    Messages
    521
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2004
    Messages : 521
    Points : 756
    Points
    756
    Par défaut
    Si tu utilises gcc tu peux utiliser l'attribut : __attribute__ ((packed)), la taille des structures sera exactement comme tu l'attends, mais la en effet on perd la portabilité.

  7. #7
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par lucas_sophia
    ca y est, le probleme venait bien de "l'endianess",
    Ben oui. Déjà signalé :

    Citation Envoyé par -ed
    La représentation des valeurs numériques n'est pas portable
    Pas de Wi-Fi à la maison : CPL

Discussions similaires

  1. probleme taille ligne
    Par rafaleee dans le forum Balisage (X)HTML et validation W3C
    Réponses: 5
    Dernier message: 24/01/2006, 12h35
  2. tag mp3
    Par bidoo dans le forum Bibliothèques
    Réponses: 6
    Dernier message: 19/10/2005, 18h58
  3. TSearchRec probleme taille du fichier
    Par beastman007 dans le forum Langage
    Réponses: 8
    Dernier message: 24/05/2005, 16h56
  4. Réponses: 3
    Dernier message: 28/09/2003, 17h08

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo