Differenze tra le versioni di "Estrarre informazioni da un file MP3 con le funzioni esterne del API di Id3tag"

Da Gambas-it.org - Wikipedia.
 
(20 versioni intermedie di uno stesso utente non sono mostrate)
Riga 1: Riga 1:
Le risorse del API di '''''id3tag''''' consentono anche di ottenere informazioni (''Tag'') dai file audio formato mp3 richiamando l'attuale versione della libreria: ''libid3tag.so.0.3.0''
+
Le risorse del API di '''''id3tag''''' consentono anche di ottenere informazioni (''Tag'') dai file audio formato mp3 richiamando l'attuale versione della libreria: "''libid3tag.so.0.3.0'' ".
  
 +
Poiché l'uso della libreria esterna ''libid3tag'' prevede il richiamo diretto ed indiretto di numerose ''Strutture'', ed al fine di poter [[Gestire_con_sicurezza_le_Strutture_esterne|gestire dette ''Strutture'' esterne in modo assolutamente <SPAN style="text-decoration:underline">sicuro</span>]], ci serviremo di un'apposita libreria esterna scritta in C, che realizzeremo ''ad hoc'' all'interno del codice Gambas e che da esso richiameremo.
  
Poiché l'uso della libreria esterna ''libid3tag'' prevede il richiamo diretto ed indiretto di numerose ''Strutture'', ed al fine di poter [[Gestire_con_sicurezza_le_Strutture_esterne|gestire dette ''Strutture'' esterne in modo assolutamente <SPAN style="text-decoration:underline">sicuro</span>]], ci serviremo di un'apposita libreria esterna scritta in C, che realizzeremo ''ad hoc'' e che richiameremo all'interno del codice Gambas.
+
Il codice Gambas per la lettura di alcuni (in questo esempio) ''tag'' dei file .mp3 potrà essere il seguente:
 
+
  Library "libid3tag:0.3.0"
La libreria ''ad hoc'' per la gestione sicura delle ''Strutture'' utilizzate di ''id3tag'' sarà la seguente:
 
  #include "id3tag.h"
 
 
 
<FONT color=Blue>''// Legge nei campi delle Strutture utilizzate:''</font>
 
 
int obt_frame_nfields(struct id3_frame *p) {
 
  return p->nfields;
 
  }
 
 
int obt_frame_type(struct id3_frame *p) {
 
  return p->fields[1].type;
 
  }
 
 
   
 
   
  union id3_field * obt_frame_fields(struct id3_frame *p) {
+
  Public Struct audio_file_tags
  return &p->fields[1];
+
  title As String
  }
+
  artist As String
Tale codice in linguaggio C in questo esempio sarà posto nella cartella ''Dati'' dell'applicativo Gambas, e andrà poi trasformato in una libreria condivisa ''.so'' , che - come già accennato - sarà richiamata nel codice Gambas.
+
  album As String
 
+
  anno As String
Il codice Gambas per la lettura di alcuni (in questo esempio) ''tag'' dei file .mp3 potrà essere il seguente:
+
  genere As String
'''Public''' Struct audio_file_tags
+
  comment As String
  title As String
+
  track As String
  artist As String
+
  composer As String
  album As String
+
  orig_artist As String
  anno As String
+
  copyright As String
  genere As String
+
  url As String
  comment As String
+
  encoded_b As String
  track As String
+
  End Struct
  composer As String
 
  orig_artist As String
 
  copyright As String
 
  url As String
 
  encoded_b As String
 
  '''End''' Struct
 
 
   
 
   
  '''Private''' aftag As Struct Audio_file_tags
+
  Private aftag As Struct Audio_file_tags
 
   
 
   
  '''Private''' genre_table As String[] = ["Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge",
+
  Private [http://it.wikipedia.org/wiki/Lista_di_generi_musicali_ID3 genre_table] As String[] = ["Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge",
 
  "Hip-Hop", "Jazz", "Metal", "New Age", "Oldies", "Other", "Pop", "R&B", "Rap", "Reggae", "Rock", "Techno",
 
  "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",
 
  "Industrial", "Alternative", "Ska", "Death Metal", "Pranks", "Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop",
Riga 52: Riga 34:
 
  "Latin", "Revival", "Celtic", "Bluegrass", "Avantgarde", "Gothic Rock", "Progress. Rock", "Psychadel. Rock",
 
  "Latin", "Revival", "Celtic", "Bluegrass", "Avantgarde", "Gothic Rock", "Progress. Rock", "Psychadel. Rock",
 
  "Symphonic Rock", "Slow Rock", "Big Band", "Chorus", "Easy Listening", "Acoustic", "Humour", "Speech", "Chanson",
 
  "Symphonic Rock", "Slow Rock", "Big Band", "Chorus", "Easy Listening", "Acoustic", "Humour", "Speech", "Chanson",
  "Opera", "Chamber Music", "Sonata", "Symphony", "Booty Bass", "Primus", "Porn Groove", "Satire"]
+
  "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 capella", "Euro-House", "Dance Hall", "Goa", "Drum & Bass", "Club-House", "Hardcore", "Terror",
 +
"Indie", "BritPop", "Negerpunk", "Polsk Punk", "Beat", "Christian Gangsta Rap", "Heavy Metal", "Black Metal",
 +
  "Crossover", "Contemporary Christian", "Christian Rock", "Merengue", "Salsa", "Thrash Metal", "Anime", "Jpop", "Synthpop"]
 
   
 
   
  Library "libid3tag:0.3.0"
+
  Private Const ID3_FIELD_TYPE_STRINGLIST As Byte = 6
+
  Private Enum ID3_FILE_MODE_READONLY = 0, ID3_FILE_MODE_READWRITE
'''Private''' Const ID3_FIELD_TYPE_STRINGLIST As Byte = 6
 
   
 
'''Private''' Enum ID3_FILE_MODE_READONLY = 0, ID3_FILE_MODE_READWRITE
 
 
   
 
   
 
  <FONT color=gray>' ''id3_file *id3_file_open(char const *, enum id3_file_mode)''</font>
 
  <FONT color=gray>' ''id3_file *id3_file_open(char const *, enum id3_file_mode)''</font>
  '''Private''' Extern id3_file_open(fl As String, id3_file_mode As Byte) As Pointer
+
  Private Extern id3_file_open(fl As String, id3_file_mode As Byte) As Pointer
 
   
 
   
 
  <FONT color=gray>' ''id3_tag *id3_file_tag(struct id3_file const *)''</font>
 
  <FONT color=gray>' ''id3_tag *id3_file_tag(struct id3_file const *)''</font>
  '''Private''' Extern id3_file_tag(id3_file As Pointer) As Pointer
+
  Private Extern id3_file_tag(id3_file As Pointer) As Pointer
 
   
 
   
 
  <FONT color=gray>' ''id3_frame *id3_tag_findframe(struct id3_tag const *, char const *, unsigned int)''</font>
 
  <FONT color=gray>' ''id3_frame *id3_tag_findframe(struct id3_tag const *, char const *, unsigned int)''</font>
  '''Private''' Extern id3_tag_findframe(id3_tag As Pointer, id$ As String, ui As Integer) As Pointer
+
  Private Extern id3_tag_findframe(id3_tag As Pointer, id$ As String, ui As Integer) As Pointer
 
   
 
   
 
  <FONT color=gray>' ''id3_ucs4_t const *id3_field_getstrings(union id3_field const *, unsigned int)''</font>
 
  <FONT color=gray>' ''id3_ucs4_t const *id3_field_getstrings(union id3_field const *, unsigned int)''</font>
Riga 74: Riga 56:
 
   
 
   
 
  <FONT color=gray>' ''id3_utf8_t *id3_ucs4_utf8duplicate(id3_ucs4_t const *)''</font>
 
  <FONT color=gray>' ''id3_utf8_t *id3_ucs4_utf8duplicate(id3_ucs4_t const *)''</font>
  '''Private''' Extern id3_ucs4_utf8duplicate(id3_ucs4_t As Pointer) As Pointer
+
  Private Extern id3_ucs4_utf8duplicate(id3_ucs4_t As Pointer) As Pointer
 
   
 
   
 
  <FONT color=gray>' ''union id3_field *id3_frame_field(struct id3_frame const *, unsigned int)''</font>
 
  <FONT color=gray>' ''union id3_field *id3_frame_field(struct id3_frame const *, unsigned int)''</font>
  '''Private''' Extern id3_frame_field(strFrame As Pointer, ui As Integer) As Pointer
+
  Private Extern id3_frame_field(strFrame As Pointer, ui As Integer) As Pointer
 
   
 
   
 
  <FONT color=gray>' ''unsigned int id3_field_getnstrings(union id3_field const *)''</font>
 
  <FONT color=gray>' ''unsigned int id3_field_getnstrings(union id3_field const *)''</font>
  '''Private''' Extern id3_field_getnstrings(unid3_field As Pointer) As Integer
+
  Private Extern id3_field_getnstrings(unid3_field As Pointer) As Integer
 
   
 
   
 
  <FONT color=gray>' ''id3_latin1_t *id3_ucs4_latin1duplicate(id3_ucs4_t const *)''</font>
 
  <FONT color=gray>' ''id3_latin1_t *id3_ucs4_latin1duplicate(id3_ucs4_t const *)''</font>
  '''Private''' Extern id3_ucs4_latin1duplicate(id3_ucs4_t As Pointer) As Pointer
+
  Private Extern id3_ucs4_latin1duplicate(id3_ucs4_t As Pointer) As Pointer
 
   
 
   
 
  <FONT color=gray>' ''int id3_file_close(struct id3_file *)''</font>
 
  <FONT color=gray>' ''int id3_file_close(struct id3_file *)''</font>
  '''Private''' Extern id3_file_close(id3_file As Pointer) As Integer
+
  Private Extern id3_file_close(id3_file As Pointer) As Integer
 
   
 
   
 
   
 
   
  Library "/tmp/libtag3"
+
  Library "/tmp/libtag3"   <FONT color=gray>' ''Richiama la libreria ad hoc da noi realizzata per la gestione sicura delle Strutture di id3tag''</font>
 
   
 
   
  '''Private''' Extern obt_frame_nfields(fr As Pointer) As Integer
+
  Private Extern obt_frame_nfields(fr As Pointer) As Integer
  '''Private''' Extern obt_frame_type(fr As Pointer) As Integer
+
  Private Extern obt_frame_type(fr As Pointer) As Integer
  '''Private''' Extern obt_frame_fields(fr As Pointer) As Pointer
+
  Private Extern obt_frame_fields(fr As Pointer) As Pointer
 
   
 
   
 
   
 
   
  '''Public''' Sub Main()
+
  Public Sub Main()
 
   
 
   
 
   Dim id3_file, id3_tag As Pointer
 
   Dim id3_file, id3_tag As Pointer
   Dim artista, titolo, album, anno As Pointer
+
  Dim anno As Pointer
   Dim tracce, nomeFl As Pointer
+
   Dim artista, titolo, album As String
  Dim genus As String
+
   Dim genus, tracce, nomeFl As String
   Dim dur as Integer
+
   Dim dur As Integer
 
 
 
<FONT color=gray>' ''Verifica se già è presente la libreria ad hoc''
 
' ''per la gestione "sicura" delle Strutture di Sox:''</font>
 
  If Exist("''/tmplibtag3.so''") = False Then creaId3()
 
 
   
 
   
 +
<FONT color=gray>' ''Verifica se già è presente la libreria ad hoc per la gestione sicura delle "Strutture" utilizzate di "id3tag", altrimenti la va a creare:''</font>
 +
  If Exist("''/tmp/libtag3.so''") = False Then creaId3()
 
    
 
    
   id3_file = id3_file_open("''/percorso/del/file.mp3''", ID3_FILE_MODE_READONLY)
+
   id3_file = id3_file_open("<FONT color=darkgreen>''/percorso/del/file.mp3''</font>", ID3_FILE_MODE_READONLY)
   If IsNull(id3_file) Then Error.Raise("Errore nel'apertura del file audio !")
+
   If id3_file == 0 Then Error.Raise("Impossibile aprire il file !")
 
    
 
    
 
   id3_tag = id3_file_tag(id3_file)
 
   id3_tag = id3_file_tag(id3_file)
 +
  If id3_tag == 0 Then Error.Raise("Impossibile ottenere i tag del file mp3 !")
 
    
 
    
 
   With aftag
 
   With aftag
 
     artista = obtArtista(id3_tag)
 
     artista = obtArtista(id3_tag)
     Print "Artista = "; String@(artista)
+
     Print "Artista = "; artista
 
     titolo = obtTitolo(id3_tag)
 
     titolo = obtTitolo(id3_tag)
     Print "Titolo = "; String@(titolo)
+
     Print "Titolo = "; titolo
 
     anno = obtAnno(id3_tag)
 
     anno = obtAnno(id3_tag)
 
     Print "Anno = "; String@(anno)
 
     Print "Anno = "; String@(anno)
 
     album = obtAlbum(id3_tag)
 
     album = obtAlbum(id3_tag)
     Print "Album = "; String@(album)
+
     Print "Album = "; album
     genus = String@(obtGenere(id3_tag))
+
     genus = obtGenere(id3_tag)
 
     If IsDigit(genus) Then genus = genre_table[Val(genus)]
 
     If IsDigit(genus) Then genus = genre_table[Val(genus)]
 
     Print "Genere = "; genus
 
     Print "Genere = "; genus
 
     tracce = obtTracce(id3_tag)
 
     tracce = obtTracce(id3_tag)
     Print "Tracce = "; String@(tracce)
+
     Print "Tracce = "; tracce
 
     nomeFl = obtOrigFilename(id3_tag)
 
     nomeFl = obtOrigFilename(id3_tag)
 
     Print "Nome file originale = "; nomeFl
 
     Print "Nome file originale = "; nomeFl
 
     dur = obtLen(id3_tag)
 
     dur = obtLen(id3_tag)
     Print "Durata sec. = "; Date(0, 0, 0, 0, 0, 0, dur)
+
     Print "Durata = "; Time(0, 0, 0, dur)
 
   
 
   
 
   End With
 
   End With
 
 
 
   
 
   
 
   id3_file_close(id3_file)
 
   id3_file_close(id3_file)
 
   
 
   
  '''End'''
+
  End
 
   
 
   
 
   
 
   
  '''Private''' Function obtArtista(id3_tag As Pointer) As Pointer
+
  Private Function obtArtista(id3_tag As Pointer) As String
 
    
 
    
 
   Dim nomeArtistaP As Pointer
 
   Dim nomeArtistaP As Pointer
 
    
 
    
    nomeArtistaP = obtFrameText(id3_tag, "TPE1")
+
  nomeArtistaP = obtFrameText(id3_tag, "TPE1")
    If IsNull(nomeartistaP) Then nomeartistaP = obtFrameText(id3_tag, "TPE2")
+
  If nomeartistaP == 0 Then nomeartistaP = obtFrameText(id3_tag, "TPE2")
    If IsNull(nomeartistaP) Then nomeartistaP = obtFrameText(id3_tag, "TPE3")
+
  If nomeartistaP == 0 Then nomeartistaP = obtFrameText(id3_tag, "TPE3")
    If IsNull(nomeartistaP) Then nomeartistaP = obtFrameText(id3_tag, "TPE4")
+
  If nomeartistaP == 0 Then nomeartistaP = obtFrameText(id3_tag, "TPE4")
    If IsNull(nomeartistaP) Then nomeartistaP = obtFrameText(id3_tag, "TCOM")
+
  If nomeartistaP == 0 Then nomeartistaP = obtFrameText(id3_tag, "TCOM")
 
   
 
   
    Return nomeArtistaP
+
  Return String@(nomeArtistaP)
 
    
 
    
  '''End'''
+
  End
 
   
 
   
  '''Private''' Function obtTitolo(id3_tag As Pointer) As Pointer
+
  Private Function obtTitolo(id3_tag As Pointer) As String
 
    
 
    
 
   Dim titoloP As Pointer
 
   Dim titoloP As Pointer
 
    
 
    
    titoloP = obtFrameText(id3_tag, "TIT2")
+
  titoloP = obtFrameText(id3_tag, "TIT2")
    Return titoloP
+
  Return String@(titoloP)
 
    
 
    
  '''End'''
+
  End
 
   
 
   
'''Private''' Function obtAlbum(id3_tag As Pointer) As Pointer
 
 
 
  Dim albumP As Pointer
 
 
 
    albumP = obtFrameText(id3_tag, "TALB")
 
    Return albumP
 
 
 
'''End'''
 
 
   
 
   
  '''Private''' Function obtAnno(id3_tag As Pointer) As Pointer
+
  Private Function obtAnno(id3_tag As Pointer) As String
 
    
 
    
 
   Dim annoP As Pointer
 
   Dim annoP As Pointer
 
    
 
    
    annoP = obtFrameText(id3_tag, "TYER")
+
  annoP = obtFrameText(id3_tag, "TYER")
    If IsNull(annoP) Then annoP = obtFrameText(id3_tag, "TDRC")
+
  If annoP == 0 Then annoP = obtFrameText(id3_tag, "TDRC")
    Return annoP
+
  Return String@(annoP)
 
    
 
    
  '''End'''
+
  End
 +
 +
 +
Private Function obtAlbum(id3_tag As Pointer) As String
 +
 +
  Dim albumP As Pointer
 +
 +
  albumP = obtFrameText(id3_tag, "TALB")
 +
  Return String@(albumP)
 +
 +
End
 +
 +
 +
Private Function obtGenere(id3_tag As Pointer) As String
 
   
 
   
'''Private''' Function obtGenere(id3_tag As Pointer) As Pointer
 
 
 
 
   Dim gnreP As Pointer
 
   Dim gnreP As Pointer
 
    
 
    
    gnreP = obtFrameText(id3_tag, "TCON")
+
  gnreP = obtFrameText(id3_tag, "TCON")
    Return gnreP
+
  Return String@(gnreP)
 
+
  '''End'''
+
  End
 +
 +
 +
Private Function obtTracce(id3_tag As Pointer) As String
 
   
 
   
'''Private''' Function obtTracce(id3_tag As Pointer) As Pointer
 
 
 
 
   Dim tracceP As Pointer
 
   Dim tracceP As Pointer
 
 
    tracceP = obtFrameText(id3_tag, "TRCK")
 
    Return tracceP
 
 
   
 
   
  '''End'''
+
  tracceP = obtFrameText(id3_tag, "TRCK")
 +
  Return String@(tracceP)
 +
 +
  End
 +
 +
 +
Private Function obtOrigFilename(id3_tag As Pointer) As String
 
   
 
   
'''Private''' Function obtOrigFilename(id3_tag As Pointer) As Pointer
 
 
 
 
   Dim nomP As Pointer
 
   Dim nomP As Pointer
    
+
    nomP = obtFrameText(id3_tag, "TOFN")
+
   nomP = obtFrameText(id3_tag, "TOFN")
    Return nomP
+
  Return String@(nomP)
 
      
 
      
  '''End'''
+
  End
 +
 +
 +
Private Function obtLen(id3_tag As Pointer) As Integer
 
   
 
   
'''Private''' Function obtLen(id3_tag As Pointer) As Integer
 
 
 
 
   Dim durI As Integer
 
   Dim durI As Integer
 
    
 
    
    durI = obtDurata(id3_tag, "TLEN")
+
  durI = obtDurata(id3_tag, "TLEN")
    Return durI
+
  Return durI
 
      
 
      
  '''End'''
+
  End
 
   
 
   
 
   
 
   
  '''Private''' Function obtFrameText(tag As Pointer, id As String) As Pointer
+
  Private Function obtFrameText(tag As Pointer, id As String) As Pointer
 
+
 
   Dim frame, field1 As Pointer
 
   Dim frame, field1 As Pointer
 
   Dim ucs4, utf8 As Pointer
 
   Dim ucs4, utf8 As Pointer
 
    
 
    
    frame = id3_tag_findframe(tag, id, 0)
+
  frame = id3_tag_findframe(tag, id, 0)
    If IsNull(frame) Then Return Null
+
  If frame == 0 Then Return 0
 
      
 
      
    If obt_frame_nfields(frame) <> 2 Then Return Null
+
  If obt_frame_nfields(frame) <> 2 Then Return 0
 
      
 
      
    If obt_frame_type(frame) <> ID3_FIELD_TYPE_STRINGLIST Then Return Null
+
  If obt_frame_type(frame) <> ID3_FIELD_TYPE_STRINGLIST Then Return 0
 
      
 
      
    field1 = obt_frame_fields(frame)
+
  field1 = obt_frame_fields(frame)
 
      
 
      
    ucs4 = id3_field_getstrings(field1, 0)
+
  ucs4 = id3_field_getstrings(field1, 0)
    If ucs4 = 0 Then Return Null
+
  If ucs4 == 0 Then Return Null
 
      
 
      
    utf8 = id3_ucs4_utf8duplicate(ucs4)
+
  utf8 = id3_ucs4_utf8duplicate(ucs4)
 
   
 
   
    Return utf8
+
  Return utf8
 
   
 
   
  '''End'''
+
  End
 
   
 
   
 
   
 
   
  '''Private''' Function obtDurata(tag As Pointer, id As String) As Integer
+
  Private Function obtDurata(tag As Pointer, id As String) As Integer
 
+
 
   Dim frame, field, latin1 As Pointer
 
   Dim frame, field, latin1 As Pointer
 
   Dim nstrings, tempI As Integer
 
   Dim nstrings, tempI As Integer
 
   Dim tempu$ As String
 
   Dim tempu$ As String
 
    
 
    
    frame = id3_tag_findframe(tag, id, 0)
+
  frame = id3_tag_findframe(tag, id, 0)
    If IsNull(frame) Then Return Null
+
  If frame == 0 Then Return 0
 
      
 
      
    field = id3_frame_field(frame, 1)
+
  field = id3_frame_field(frame, 1)
 
      
 
      
    nstrings = id3_field_getnstrings(field)
+
  nstrings = id3_field_getnstrings(field)
    If nstrings <= 0 Then Return -1
+
  If nstrings <= 0 Then Return -1
 
      
 
      
    latin1 = id3_ucs4_latin1duplicate(id3_field_getstrings(field, 0))
+
  latin1 = id3_ucs4_latin1duplicate(id3_field_getstrings(field, 0))
    If IsNull(latin1) Then Return -1
+
  If latin1 == 0 Then Return -1
 
      
 
      
  <FONT color=gray>' ''Il frame 'lengh' contiene la durata dei dati audio''
+
  <FONT color=gray>' ''Il frame 'lengh' contiene la durata dei dati audio espressa in millisecondi e rappresentata in una stringa numerica:''</font>
' ''espressa in millisecondi e rappresentata in una stringa numerica:''</font>
+
  tempu$ = String@(latin1)
    tempu$ = String@(latin1)
+
  tempI = Val(tempu$)
    tempI = Val(tempu$)
 
 
          
 
          
    If tempI > 0 Then
+
  If tempI > 0 Then
      Return tempI
+
    Return tempI
    Else
+
  Else
      Return -1
+
    Return -1
    Endif
+
  Endif
 
   
 
   
  '''End'''
+
  End
 
   
 
   
 
   
 
   
 
  <FONT color=gray>' ''Crea l'apposita libreria per la gestione sicura delle Strutture di "id3tag":''</font>
 
  <FONT color=gray>' ''Crea l'apposita libreria per la gestione sicura delle Strutture di "id3tag":''</font>
  '''Private''' Procedure creaId3()
+
  Private Procedure creaId3()
 
   
 
   
  Shell "gcc -o ''/tmp/libtag3.so'' " & Application.Path &/ "''codice.c'' -shared -fPIC" Wait
+
  File.Save("/tmp/libtag3.c", "#include <id3tag.h>" &
 
+
                              "\n\n" &
  '''End'''
+
                              "/* ''Legge nei campi delle Strutture utilizzate:'' */\n" &
 +
                              "int obt_frame_nfields(struct id3_frame *p) {\n" &
 +
                              "  return p->nfields;\n}" &
 +
                              "\n\n" &
 +
                              "int obt_frame_type(struct id3_frame *p) {\n" &
 +
                              "  return p->fields[1].type;\n}" &
 +
                              "\n\n" &
 +
                              "union id3_field * obt_frame_fields(struct id3_frame *p) {\n" &
 +
                              "  return &p->fields[1];\n}")
 +
 +
  Shell "gcc -o ''/tmp/libtag3.so /tmp/libtag3.c -shared -fPIC" Wait
 +
 +
  End
 +
 
 +
 
 +
 
 +
=Riferimenti=
 +
* http://fossies.org/dox/xmmp-0.6.1.1/libid3tag_2id3tag_8h_source.html
 +
* http://www.mars.org/pipermail/mad-dev/2002-January/000439.html

Versione attuale delle 19:02, 13 gen 2024

Le risorse del API di id3tag consentono anche di ottenere informazioni (Tag) dai file audio formato mp3 richiamando l'attuale versione della libreria: "libid3tag.so.0.3.0 ".

Poiché l'uso della libreria esterna libid3tag prevede il richiamo diretto ed indiretto di numerose Strutture, ed al fine di poter gestire dette Strutture esterne in modo assolutamente sicuro, ci serviremo di un'apposita libreria esterna scritta in C, che realizzeremo ad hoc all'interno del codice Gambas e che da esso richiameremo.

Il codice Gambas per la lettura di alcuni (in questo esempio) tag dei file .mp3 potrà essere il seguente:

Library "libid3tag:0.3.0"

Public Struct audio_file_tags
  title As String
  artist As String
  album As String
  anno As String
  genere As String
  comment As String
  track As String
  composer As String
  orig_artist As String
  copyright As String
  url As String
  encoded_b As String
End Struct

Private aftag As Struct Audio_file_tags

Private genre_table As String[] = ["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", "Sound Clip",
"Gospel", "Noise", "Alt. Rock", "Bass", "Soul", "Punk", "Space", "Meditative", "Instrum. Pop", "Instrum. Rock",
"Ethnic", "Gothic", "Darkwave", "Techno-Indust.", "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", "Fusion", "Bebob",
"Latin", "Revival", "Celtic", "Bluegrass", "Avantgarde", "Gothic Rock", "Progress. Rock", "Psychadel. 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 capella", "Euro-House", "Dance Hall", "Goa", "Drum & Bass", "Club-House", "Hardcore", "Terror",
"Indie", "BritPop", "Negerpunk", "Polsk Punk", "Beat", "Christian Gangsta Rap", "Heavy Metal", "Black Metal",
"Crossover", "Contemporary Christian", "Christian Rock", "Merengue", "Salsa", "Thrash Metal", "Anime", "Jpop", "Synthpop"]

Private Const ID3_FIELD_TYPE_STRINGLIST As Byte = 6
Private Enum ID3_FILE_MODE_READONLY = 0, ID3_FILE_MODE_READWRITE

' id3_file *id3_file_open(char const *, enum id3_file_mode)
Private Extern id3_file_open(fl As String, id3_file_mode As Byte) As Pointer

' id3_tag *id3_file_tag(struct id3_file const *)
Private Extern id3_file_tag(id3_file As Pointer) As Pointer

' id3_frame *id3_tag_findframe(struct id3_tag const *, char const *, unsigned int)
Private Extern id3_tag_findframe(id3_tag As Pointer, id$ As String, ui As Integer) As Pointer

' id3_ucs4_t const *id3_field_getstrings(union id3_field const *, unsigned int)
Private Extern id3_field_getstrings(unid3_field As Pointer, ui As Integer) As Pointer

' id3_utf8_t *id3_ucs4_utf8duplicate(id3_ucs4_t const *)
Private Extern id3_ucs4_utf8duplicate(id3_ucs4_t As Pointer) As Pointer

' union id3_field *id3_frame_field(struct id3_frame const *, unsigned int)
Private Extern id3_frame_field(strFrame As Pointer, ui As Integer) As Pointer

' unsigned int id3_field_getnstrings(union id3_field const *)
Private Extern id3_field_getnstrings(unid3_field As Pointer) As Integer

' id3_latin1_t *id3_ucs4_latin1duplicate(id3_ucs4_t const *)
Private Extern id3_ucs4_latin1duplicate(id3_ucs4_t As Pointer) As Pointer

' int id3_file_close(struct id3_file *)
Private Extern id3_file_close(id3_file As Pointer) As Integer


Library "/tmp/libtag3"   ' Richiama la libreria ad hoc da noi realizzata per la gestione sicura delle Strutture di id3tag

Private Extern obt_frame_nfields(fr As Pointer) As Integer
Private Extern obt_frame_type(fr As Pointer) As Integer
Private Extern obt_frame_fields(fr As Pointer) As Pointer


Public Sub Main()

 Dim id3_file, id3_tag As Pointer
 Dim anno As Pointer
 Dim artista, titolo, album As String
 Dim genus, tracce, nomeFl As String
 Dim dur As Integer

' Verifica se già è presente la libreria ad hoc per la gestione sicura delle "Strutture" utilizzate di "id3tag", altrimenti la va a creare:
 If Exist("/tmp/libtag3.so") = False Then creaId3()
 
 id3_file = id3_file_open("/percorso/del/file.mp3", ID3_FILE_MODE_READONLY)
 If id3_file == 0 Then Error.Raise("Impossibile aprire il file !")
 
 id3_tag = id3_file_tag(id3_file)
 If id3_tag == 0 Then Error.Raise("Impossibile ottenere i tag del file mp3 !")
 
 With aftag
   artista = obtArtista(id3_tag)
   Print "Artista = "; artista
   titolo = obtTitolo(id3_tag)
   Print "Titolo = "; titolo
   anno = obtAnno(id3_tag)
   Print "Anno = "; String@(anno)
   album = obtAlbum(id3_tag)
   Print "Album = "; album
   genus = obtGenere(id3_tag)
   If IsDigit(genus) Then genus = genre_table[Val(genus)]
   Print "Genere = "; genus
   tracce = obtTracce(id3_tag)
   Print "Tracce = "; tracce
   nomeFl = obtOrigFilename(id3_tag)
   Print "Nome file originale = "; nomeFl
   dur = obtLen(id3_tag)
   Print "Durata = "; Time(0, 0, 0, dur)

 End With

 id3_file_close(id3_file)

End


Private Function obtArtista(id3_tag As Pointer) As String
 
 Dim nomeArtistaP As Pointer
 
 nomeArtistaP = obtFrameText(id3_tag, "TPE1")
 If nomeartistaP == 0 Then nomeartistaP = obtFrameText(id3_tag, "TPE2")
 If nomeartistaP == 0 Then nomeartistaP = obtFrameText(id3_tag, "TPE3")
 If nomeartistaP == 0 Then nomeartistaP = obtFrameText(id3_tag, "TPE4")
 If nomeartistaP == 0 Then nomeartistaP = obtFrameText(id3_tag, "TCOM")

 Return String@(nomeArtistaP)
 
End

Private Function obtTitolo(id3_tag As Pointer) As String
 
 Dim titoloP As Pointer
 
 titoloP = obtFrameText(id3_tag, "TIT2")
 Return String@(titoloP)
 
End


Private Function obtAnno(id3_tag As Pointer) As String
 
 Dim annoP As Pointer
 
 annoP = obtFrameText(id3_tag, "TYER")
 If annoP == 0 Then annoP = obtFrameText(id3_tag, "TDRC")
 Return String@(annoP)
 
End


Private Function obtAlbum(id3_tag As Pointer) As String

 Dim albumP As Pointer

 albumP = obtFrameText(id3_tag, "TALB")
 Return String@(albumP)

End


Private Function obtGenere(id3_tag As Pointer) As String

 Dim gnreP As Pointer
 
 gnreP = obtFrameText(id3_tag, "TCON")
 Return String@(gnreP)

End


Private Function obtTracce(id3_tag As Pointer) As String

 Dim tracceP As Pointer

 tracceP = obtFrameText(id3_tag, "TRCK")
 Return String@(tracceP)

End


Private Function obtOrigFilename(id3_tag As Pointer) As String

 Dim nomP As Pointer

 nomP = obtFrameText(id3_tag, "TOFN")
 Return String@(nomP)
   
End


Private Function obtLen(id3_tag As Pointer) As Integer

 Dim durI As Integer
 
 durI = obtDurata(id3_tag, "TLEN")
 Return durI
   
End


Private Function obtFrameText(tag As Pointer, id As String) As Pointer

 Dim frame, field1 As Pointer
 Dim ucs4, utf8 As Pointer
 
 frame = id3_tag_findframe(tag, id, 0)
 If frame == 0 Then Return 0
   
 If obt_frame_nfields(frame) <> 2 Then Return 0
   
 If obt_frame_type(frame) <> ID3_FIELD_TYPE_STRINGLIST Then Return 0
   
 field1 = obt_frame_fields(frame)
   
 ucs4 = id3_field_getstrings(field1, 0)
 If ucs4 == 0 Then Return Null
   
 utf8 = id3_ucs4_utf8duplicate(ucs4)

 Return utf8

End


Private Function obtDurata(tag As Pointer, id As String) As Integer

 Dim frame, field, latin1 As Pointer
 Dim nstrings, tempI As Integer
 Dim tempu$ As String
 
 frame = id3_tag_findframe(tag, id, 0)
 If frame == 0 Then Return 0
   
 field = id3_frame_field(frame, 1)
   
 nstrings = id3_field_getnstrings(field)
 If nstrings <= 0 Then Return -1
   
 latin1 = id3_ucs4_latin1duplicate(id3_field_getstrings(field, 0))
 If latin1 == 0 Then Return -1
   
' Il frame 'lengh' contiene la durata dei dati audio espressa in millisecondi e rappresentata in una stringa numerica:
 tempu$ = String@(latin1)
 tempI = Val(tempu$)
       
 If tempI > 0 Then
   Return tempI
 Else
   Return -1
 Endif

End


' Crea l'apposita libreria per la gestione sicura delle Strutture di "id3tag":
Private Procedure creaId3()

 File.Save("/tmp/libtag3.c", "#include <id3tag.h>" &
                             "\n\n" &
                             "/* Legge nei campi delle Strutture utilizzate: */\n" &
                             "int obt_frame_nfields(struct id3_frame *p) {\n" &
                             "   return p->nfields;\n}" &
                             "\n\n" &
                             "int obt_frame_type(struct id3_frame *p) {\n" &
                             "   return p->fields[1].type;\n}" &
                             "\n\n" &
                             "union id3_field * obt_frame_fields(struct id3_frame *p) {\n" &
                             "   return &p->fields[1];\n}")

 Shell "gcc -o /tmp/libtag3.so /tmp/libtag3.c -shared -fPIC" Wait

End


Riferimenti