Newsgroup: it.comp.lang.c
Titolo: esame in C ansi - lettura tag id3

Ciao ragazzi, ho preso 2 settimane di ferie per preparare l'esame.
So di essere un pazzo ma ci proverò anche se mi costerà dormire 3-4 ore 
al giorno!
Ho pensato ad un programma che legge un file mp3 estrapolando i tag id3 
per generare delle playlist in base al genere, all'artista, all'anno di 
pubblicazione, ecc...
Mi sapete indicare su come posso leggere i tag id3?
Ho 6 gg di tempo per scriverlo...anzi vedendo l'ora 5 gg!:-(
Grazie mille....
Michele

 Michele
posso sapere dove e cosa studi?
-- 
undefined sign

 Mi sapete indicare su come posso leggere i tag id3?
La tua domanda non riguarda strettamente il C, quindi ti raccomando di
attenerti al topic di questo gruppo.  In ogni caso, alla pagina
http://www.wotsit.org
 (cercando per mp3) trovi tutto ciň di cui hai
bisogno.
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 [cut]
Salve,
ho del codice che fa al caso tuo già pronto.
E` in C++, ma credo non dovrebbe esserti difficile
convertirlo in C (specie se conosci il C++). In questo codice però manca la
gestione del genere musicale, cioè lo visualizza se esiste
ma non permette di inserirlo.
Per qualunque cosa a disposizione.
<code>
------------------- id3tag.hpp --------------------
#ifndef _ID3TAG_HPP_
#define _ID3TAG_HPP_
using namespace std;
typedef struct {
	char title[31];
	char artist[31];
	char album[31];
	char year[5];
	char comment[29];
	char track;
	char genere;
} ID3;
void ctrlFile( fstream& ); // controllo errori sul file in uso; chiamata 
funzioni
bool ctrlTag( fstream& ); // controlla se esiste la stringa TAG
void getTag( fstream& ); // visualizza le informazioni ID3
void setTag( fstream& ); // imposta i tag ID3, anche se non esistono
#endif // _ID3TAG_HPP_
------------------- id3tag.cpp --------------------
#include <iostream>
#include <fstream>
#include "id3tag.hpp"
using namespace std;
void ctrlFile(fstream& file)
{
	if( !file ) {
		cerr << "File o percorso non valido o non esistente!\n\n";
		exit(EXIT_FAILURE);
	}
	if( !ctrlTag(file) ) // controllo se e' presente la stringa TAG
		cerr << "TAG ID3 mancanti o errore di posizionamento all'interno del 
file!\n\n";
	else
		getTag(file);
	char risp;
	cout << "Desideri inserire/modificare i tag ID3? [Si, No]: ";
	cin >> risp;
      if( risp == 's' || risp == 'S' )
      	setTag(file);
}
/////////////////////////////////////////////////////////////////////////////
bool ctrlTag(fstream& file)
{
      char buf[3];
      file.seekp(-128, ios::end); // posizionamento 128 byte prima di EOF
      file.read(buf, 3);
      if( strncmp(buf, "TAG", 3) == 0 )
      	return true; // c'e' la stringa tag
      else
      	return false;
}
/////////////////////////////////////////////////////////////////////////////
void getTag(fstream& file)
{
	char buf[129];
	unsigned short i;
      file.seekp(-128, ios::end);
      file.read(buf, 128); // memorizzazione dei 128 byte dei TAG ID3
      /* titolo traccia, byte 3..32 */
      cout << "\nTITOLO:  ";
      for( i = 3; i < 33; i++ )
           if( (buf[i] == '\0') || (buf[i] == ' ' && buf[i+1] == ' ') )
           	break;
           else
           	cout << buf[i];
	/* artista, byte 33..62 */
      cout << "\nARTISTA: ";
      for( i = 33; i < 63; i++ )
           if( (buf[i] == '\0') || (buf[i] == ' ' && buf[i+1] == ' ') )
           	break;
           else
           	cout << buf[i];
	/* album, byte 63..92 */
      cout << "\nALBUM:   ";
      for( i = 63; i < 93; i++ )
           if( (buf[i] == '\0') || (buf[i] == ' ' && buf[i+1] == ' ') )
           	break;
           else
           	cout << buf[i];
      /* anno, byte 93..96 */
      cout << "\nANNO:    ";
      for( i = 93; i < 97; i++ )
           if( !(buf[i] >= '0' && buf[i+1] <= '9') || (buf[i] == '\0') )
           	break;
           else
           	cout << buf[i];
	/* commento, byte 94..125 */
      cout << "\nCOMMENT: ";
      for( i = 97; i < 126; i++ )
           if( (buf[i] == '\0') || (buf[i] == ' ' && buf[i+1] == ' ') )
           	break;
           else
           	cout << buf[i];
	/* traccia */
      cout << "\nTRACCIA: ";
      cout << static_cast<int>( buf[126] );
	/* genere */
      cout << "\nGENERE:  ";
      cout << buf[127];
      cout << "\n\n";
}
/////////////////////////////////////////////////////////////////////////////
void setTag(fstream& file)
{
	unsigned int size, i, traccia;
	char* tag = "TAG", buf[125], track[4];
	ID3 id3;
      if( !ctrlTag(file) ) {
           file.seekp(0, ios::end);
           file.write(tag, 3);
      } else
		file.seekp(-125, ios::end);
      cin.getline(track, 3);
      cout << "\nTitolo:  ";
      cin.getline(id3.title, 31);
      size = cin.gcount() - 1;
      for( i = size; i < 30; i++ )
      	id3.title[i] = static_cast<char>( NULL ); // errori: 
static_cast<char>( 0x00 );
      for( i = 0; i < 30; i++ )
      	buf[i] = id3.title[i];
      cout << "\nArtista: ";
      cin.getline(id3.artist, 31);
      size = cin.gcount() - 1;
      for( i = size; i < 30; i++ )
      	id3.artist[i] = static_cast<char>( NULL );
      for( i = 0; i < 30; i++ )
      	buf[30+i] = id3.artist[i];
      cout << "\nAlbum:   ";
      cin.getline(id3.album, 31);
      size = cin.gcount() - 1;
      for( i = size; i < 30; i++ )
      	id3.album[i] = static_cast<char>( NULL );
      for( i = 0; i < 30; i++ )
      	buf[60+i] = id3.album[i];
      cout << "\nAnno:    ";
      cin.getline(id3.year, 5);
      size = cin.gcount() - 1;
      if( size < 4 || id3.year[0] == '\n' )
      	for( i = 0; i < 4; i++ )
      		id3.year[i] = static_cast<char>( NULL );
      else
      	for( i = 0; i < 4; i++ )
      		buf[90+i] = id3.year[i];
      cout << "\nComment: ";
      cin.getline(id3.comment, 29);
      size = cin.gcount() - 1;
      for( i = size; i < 28; i++ )
      	id3.comment[i] = static_cast<char>( NULL );
      for( i = 0; i < 28; i++ )
      	buf[94+i] = id3.comment[i];
      cout << "\nTraccia: ";
      cin.getline(track, 4);
      traccia = atoi(track);
      if( traccia >= 0 && traccia <= 127 )
      	id3.track = static_cast<char>( traccia );
      else
      	id3.track = static_cast<char>( NULL );
      buf[122] = static_cast<char>( NULL );
      buf[123] = id3.track;
      buf[124] = static_cast<char>( NULL ); // genere
      file.write(buf, sizeof(buf));
}
</code>
-- 
*** 
http://cikkox.altervista.org
 ***
*** GNU/Linux Registered User #365929 ***
*** GnuPG/OpenPGP key available ***

 ma non permette di inserirlo.
Errata corride, sono un po' rintronato
(il caldo inizia a fare i primi effetti).
La gestione del genere musicale c'e'.
Ecco i file modificati.
<code>
------------------- id3tag.hpp --------------------
#ifndef _ID3TAG_HPP_
#define _ID3TAG_HPP_
using namespace std;
typedef struct {
	char title[31]; // 30 char piu' il terminatore di stringa '\0'
	char artist[31];
	char album[31];
	char year[5];
	char comment[29];
	char track;
	char genere;
} ID3;
static const char* genereM[] = {"Blues", "Classic Rock", "Country", "Dance",
	"Disco", "Funk", "Grunge", "Hip-Hop", "Jazz", "Metal", "New Age",
	"Oldies", "Other", "Pop", "R&B", "Rap", "Reggae", "Rock", "Techno",
	"Industrial", "Alternative", "Ska", "Death Metal", "Pranks", "Soundtrack",
	"Euro-Techno", "Ambient", "Trip-Hop", "Vocal", "Jazz+Funk", "Fusion",
	"Trance", "Classical", "Instrumental", "Acid", "House", "Game",
	"SoundClip", "Gospel", "Noise", "AlternativeRock", "Bass", "Soul", "Punk",
	"Space", "Meditative", "Instrumental Pop", "Instrumental Rock", "Ethnic",
	"Gothic", "Darkwave", "Techno-Industrial", "Electronic", "Pop-Folk",
	"Eurodance", "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta",
	"Top 40", "Christian Rap", "Pop/Funk", "Jungle", "Native American",
	"Cabaret", "New Wave", "Psychadelic", "Rave", "Showtunes", "Trailer",
	"Lo-Fi", "Tribal", "Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical",
	"Rock&Roll", "Hard Rock", "Folk", "Folk-Rock", "National Folk", "Swing",
	"Fast Fusion", "Bebob", "Latin", "Revival", "Celtic", "Bluegrass",
	"Avantgarde", "Gothic Rock", "Progressive Rock", "Psychedelic Rock",
	"Symphonic Rock", "Slow Rock", "Big Band", "Chorus", "Easy Listening",
	"Acoustic", "Humour", "Speech", "Chanson", "Opera", "Chamber Music",
	"Sonata", "Symphony", "Booty Bass", "Primus", "Porn Groove", "Satire",
	"Slow Jam", "Club", "Tango", "Samba", "Folklore", "Ballad", "Power Ballad",
	"Rhythmic Soul", "Freestyle", "Duet", "Punk Rock", "Drum Solo", "A 
Cappella",
	"Euro-House", "Dance Hall"};
void ctrlFile( fstream& ); // controllo errori sul file in uso; chiamata 
funzioni
bool ctrlTag( fstream& ); // controlla se esiste la stringa TAG
void getTag( fstream& ); // visualizza le informazioni ID3
void setTag( fstream& ); // imposta i tag ID3, anche se non esistono
char genere(); // imposta il genere musicale
#endif // _ID3TAG_HPP_
-------------------- id3tag.cpp --------------------
#include <iostream>
#include <fstream>
#include "id3tag.hpp"
using namespace std;
void ctrlFile(fstream& file)
{
	if( !file ) {
		cerr << "File o percorso non valido o non esistente!\n\n";
		exit(EXIT_FAILURE);
	}
	if( !ctrlTag(file) ) // controlla se e' presente la stringa TAG
		cerr << "TAG ID3 mancanti o errore di posizionamento all'interno del 
file!\n\n";
	else
		getTag(file);
	char risp;
	cout << "Desideri inserire/modificare i tag ID3? [Si, No]: ";
	cin >> risp;
      if( risp == 's' || risp == 'S' )
      	setTag(file);
}
/////////////////////////////////////////////////////////////////////////////
bool ctrlTag(fstream& file)
{
      char buf[3];
      file.seekp(-128, ios::end); // posizionamento 128 byte prima di EOF
      file.read(buf, 3);
      if( strncmp(buf, "TAG", 3) == 0 )
      	return true; // c'e' la stringa tag
      else
      	return false;
}
/////////////////////////////////////////////////////////////////////////////
void getTag(fstream& file)
{
	char buf[128];
	unsigned short i;







	if( static_cast<int>( buf[126] ) != '\0' )
		cout << static_cast<int>( buf[126] );
	/* genere */
	cout << "\nGENERE:  ";
	i = 0;
	while( i != static_cast<int>( buf[127] ) && i < 126 )
		i++;
	if( genereM[i] != NULL )
		cout << genereM[i];
      cout << "\n\n";
}
/////////////////////////////////////////////////////////////////////////////









	cout << "\nGenere:\n";
	id3.genere = genere();
	buf[124] = id3.genere;
      file.write(buf, sizeof(buf));
}
/////////////////////////////////////////////////////////////////////////////
char genere()
{
	char ngen[4];
	unsigned short i;
	for( i = 0; i < 126; i++ )
		cout << i << ". " << genereM[i] << endl;
	cout << "Immetti il numero, altrimenti premi Invio per nessun genere: ";
	cin.getline(ngen, 4);
	if( ngen[0] != '\n' ) {
		i = atoi(ngen);
		return static_cast<char>( i );
	}
	else
		return static_cast<char>( NULL );
}
</code>

 
PEr quale motivo non riguarda strettamente il C la mia domanda?
A me interessa salere come leggere i tag id3 con il C, non con altri 
linguaggi.
Grazie per la segnalazione del sito...
Michele

 
Sono io che mi sono ridotto all'osso dei tempi per lavoro, cmq l'esame è 
Computer Programming e sono iscritto ad Informatica Applicata.
Ciao...

 A me interessa salere come leggere i tag id3 con il C
La tua domanda è su come reperire il tag del file mp3. 
Almeno è questo che ho capito e questo non è un problema legato al C.
