Differenze tra le versioni di "Estrarre informazioni e TAG da un file MP3 con le sole funzioni di Gambas"

Da Gambas-it.org - Wikipedia.
 
(6 versioni intermedie di uno stesso utente non sono mostrate)
Riga 1: Riga 1:
 
E' possibile estrarre informazioni generali e TAG da un file MP3 con le sole funzioni di Gambas.
 
E' possibile estrarre informazioni generali e TAG da un file MP3 con le sole funzioni di Gambas.
  
Un possibile codice è il seguente:
+
Un esempio:
  '''Private''' initium As Short
+
  Private initium As Short
 
   
 
   
 
   
 
   
 
  '''Public''' Sub Main()
 
  '''Public''' Sub Main()
 
   
 
   
Dim fl, s, ver_mp3, layer, prot, medio, circa As String
+
  Dim fl, s, ver_mp3, layer, prot, medio, circa As String
Dim j, frequenza, num_frame, brVar, totBR, durata1, durata2, durata As Integer
+
  Dim j, frequenza, num_frame, brVar, totBR, durata1, durata2, durata As Integer
Dim vB, lB, pB, brB, frB As Byte
+
  Dim vB, lB, pB, brB, frB As Byte
Dim secundum, tertium, bitrate, cpf As Short
+
  Dim secundum, tertium, bitrate, cpf As Short
Dim tags As String[]
 
 
   
 
   
+
   fl = "<FONT Color=gray>''/percorso/del/file.mp3</font>''"
   fl = "''/percorso/del/file.mp3''"
 
 
    
 
    
 
   Print "File audio mp3: '"; File.Name(fl)
 
   Print "File audio mp3: '"; File.Name(fl)
Riga 20: Riga 18:
 
   s = File.Load(fl)
 
   s = File.Load(fl)
 
   Print "\nDimensione: "; Len(s); " byte"
 
   Print "\nDimensione: "; Len(s); " byte"
 +
  Write "\e[5m\e[1mAttendere !\e[0m"
 +
  Flush
 
    
 
    
 
   initium = 1
 
   initium = 1
 
    
 
    
  tags = EstraeTag(s)
 
 
 
   For j = initium To Len(s) - 1
 
   For j = initium To Len(s) - 1
 
   
 
   
Riga 71: Riga 69:
 
     End Select
 
     End Select
 
      
 
      
     Print "Versione MPEG = "; ver_mp3, "Layer = "; layer, "Protezione CRC = "; prot
+
     Write "\rVersione MPEG = " & ver_mp3 & "   Layer = " & layer & "   Protezione CRC = " & prot
 
   
 
   
 
   
 
   
Riga 126: Riga 124:
 
     Endif
 
     Endif
 
   
 
   
     Print "BitRate " & medio & "= "; bitrate
+
     Print "\nBitRate " & medio & "= "; bitrate
 
     Print "Frequenza = hz "; frequenza
 
     Print "Frequenza = hz "; frequenza
     Print "Durata " & circa & "= "; Date(0, 0, 0, 0, 0, 0, durata)
+
     Print "Durata " & circa & "= "; Time(0, 0, 0, durata)
 
    
 
    
 
     Print "\n== T A G =="
 
     Print "\n== T A G =="
+
     EstraeTag(s)
     If tags.Count > 0 Then
 
      For j = 0 To tags.Max
 
        Print tags[j]
 
      Next
 
    Else
 
        Print "Assenti !"
 
    Endif
 
 
   
 
   
 
  '''End'''
 
  '''End'''
Riga 360: Riga 351:
 
   
 
   
 
   
 
   
  '''Private''' Function EstraeTag(s As String) As String[]
+
  '''Private''' Procedure EstraeTag(s As String)
 +
 +
<FONT Color=gray>' ''Sono impostati alcuni TAG (ovviamente alla seguente lista possono essere aggiunti altri di quelli previsti):''</font>
 +
  Dim tag As String[] = ["TALB", "TCOM", "TCOP", "TDAT", "TDEN", "TDLY", "TDRC", "TENC", "TFLP", "TIT1",
 +
                        "TIT2", "TIT3", "TKEY", "TLAN", "TLEN", "TMCL", "TMED", "TOAL", "TOFN", "TOLY",
 +
                        "TOPE", "TORY", "TOWN", "TPE1", "TPE2", "TPE3", "TPE4", "TPUB", "TCON", "TDRC",
 +
                        "TRCK", "TRDA", "TRSN", "TRSO", "TSRC", "TSSE", "TYER", "COMM", "WXXX", "TXXX",
 +
                        "PRIV"]
 +
  Dim t As String
 +
  Dim d, i As Integer
 
    
 
    
   Dim ordo As New Integer[]
+
<FONT Color=gray>' ''Cerca i TAG nel file mp3:''</font>
   Dim j, rm, k, a As Integer
+
   d = Len(s)
  Dim tag As String
+
   For Each t In tag
   Dim tagg As New String[]
+
    i = InStr(s, t)
 +
    If i > 0 Then d = Min(i, d)
 +
   Next
 
    
 
    
 +
  While tag.Find(Mid(s, d, 4)) > -1
 +
<FONT Color=gray>' ''Evita di prendere in considerazione eventuali falsi TAG:''</font>
 +
    If Asc(Mid(s, d + 4, 1)) > 0 Then
 +
      d += 4
 +
      Continue
 +
    Endif
 +
<FONT Color=gray>' ''Memorizza i 4 caratteri-byte dopo il nome del TAG che indicano la lunghezza del testo:''</font>
 +
    t = Mid(s, d + 4, 4)
 +
<FONT Color=gray>' ''Ottiene il valore numerico di tipo Intero, tenendo conto che il valore è rappresentato in "Big-Endian":''</font>
 +
    i = Asc(t, 1) * 16777216  ' &01000000
 +
    i += Asc(t, 2) * 65536      ' &010000
 +
    i += Asc(t, 3) * 256        ' &0100
 +
    i += Asc(t, 4)
 +
    Print "\e[1m"; s[d - 1, 4]; "\e[0m", Replace(Mid(s, d + 11, i - 1), Chr(&00), Chr(&20))
 +
    d += 10 + i
 +
  Wend
 
    
 
    
    With ordo
+
  If InStr(s, "APIC") Then Print "\e[1m"; "APIC\e[0m \e[31m(Il file contiene anche anche dati immagine)\e[0m"
      .add(InStr(s, "TALB")
+
  If i == 0 Then Print "TAG assenti !"
      .add(InStr(s, "TCOM")) 
 
      .add(InStr(s, "TCOP"))  
 
      .add(InStr(s, "TDAT")
 
      .add(InStr(s, "TDEN")) 
 
      .add(InStr(s, "TDLY")) 
 
      .add(InStr(s, "TDRC")) 
 
      .add(InStr(s, "TENC")) 
 
      .add(InStr(s, "TFLP")) 
 
      .add(InStr(s, "TIT1")) 
 
      .add(InStr(s, "TIT2")) 
 
      .add(InStr(s, "TIT3")) 
 
      .add(InStr(s, "TKEY")) 
 
      .add(InStr(s, "TLAN")) 
 
      .add(InStr(s, "TLEN")) 
 
      .add(InStr(s, "TMCL")) 
 
      .add(InStr(s, "TMED")) 
 
      .add(InStr(s, "TOAL")) 
 
      .add(InStr(s, "TOFN")) 
 
      .add(InStr(s, "TOLY")) 
 
      .add(InStr(s, "TOPE")) 
 
      .add(InStr(s, "TORY")) 
 
      .add(InStr(s, "TOWN")) 
 
      .add(InStr(s, "TPE1")) 
 
      .add(InStr(s, "TPE2")) 
 
      .add(InStr(s, "TPE3")) 
 
      .add(InStr(s, "TPE4")) 
 
      .add(InStr(s, "TPUB")) 
 
      .add(InStr(s, "TCON")) 
 
      .add(InStr(s, "TDRC")) 
 
      .add(InStr(s, "TRCK")) 
 
      .add(InStr(s, "TRDA")) 
 
      .add(InStr(s, "TRSN")) 
 
      .add(InStr(s, "TRSO")) 
 
      .add(InStr(s, "TSRC")) 
 
      .add(InStr(s, "TSSE")) 
 
      .add(InStr(s, "TYER")) 
 
      .add(InStr(s, "TXXX")) 
 
      .add(RInStr(s, "TXXX")) 
 
      .add(InStr(s, "COMM")) 
 
      .add(InStr(s, "PRIV")) 
 
      .add(RInStr(s, "PRIV")) 
 
      .add(RInStr(s, "WXXX"))
 
    End With
 
 
  If ordo.Count > 0 Then    <FONT color=gray>' ''Se è stato trovato almeno un Tag''</font>
 
 
    While j < ordo.Count
 
      If ordo[j] = 0 Then
 
        ordo.Remove(j)
 
        Inc rm
 
        Dec j
 
      Endif
 
      Inc j
 
    Wend
 
 
 
 
    ordo.Sort()
 
 
   
 
    For j = 0 To ordo.Max
 
 
      k = ordo[j]
 
 
      While k < ordo[ordo.max] + 24
 
       
 
        If j < ordo.Max Then
 
<FONT color=gray>' ''Verifica che il carattere ASCII sia una lettera o un numero oppure un segno di punteggiatura:''</font>
 
          If (k < ordo[j + 1]) And ((IsLetter(Mid(s, k, 1))) Or (IsDigit(Mid(s, k, 1))) Or (IsPunct(Mid(s, k, 1)))) Then
 
            tag &= Mid(s, k, 1)
 
          Else
 
            tag &= " "
 
          Endif
 
        Else
 
<FONT color=gray>' ''Verifica che il carattere ASCII sia una lettera o un numero oppure un segno di punteggiatura:''</font>
 
          If ((IsLetter(Mid(s, k, 1))) Or (IsDigit(Mid(s, k, 1))) Or (IsPunct(Mid(s, k, 1)))) Then
 
            tag &= Mid(s, k, 1)
 
          Else
 
            tag &= " "
 
          Endif
 
 
        Endif
 
       
 
        Inc k
 
     
 
      Wend
 
     
 
      tagg.Add(tag)
 
      tag = Null
 
   
 
<FONT color=gray>' ''Cerca di evitare di leggere l'header del 1° frame all'interno del gruppo dei Tag:''</font>
 
      For a = 0 To ordo.Max - 1
 
        If ordo[a + 1] - ordo[a] > 68 Then initium = ordo[a] + 24
 
      Next
 
 
   
 
   
    Next
 
   
 
    Endif
 
 
    Return tagg
 
 
 
 
  '''End'''
 
  '''End'''
  
Riga 475: Riga 394:
  
 
=Riferimenti=
 
=Riferimenti=
[1] [[La_struttura_di_un_file_MPEG|La struttura di un file MPEG]]
+
* [[La_struttura_di_un_file_MPEG|La struttura di un file MPEG]]
 +
* https://kid3.sourceforge.io/kid3_en.html#tag3

Versione attuale delle 09:58, 30 ott 2021

E' possibile estrarre informazioni generali e TAG da un file MP3 con le sole funzioni di Gambas.

Un esempio:

Private initium As Short


Public Sub Main()

 Dim fl, s, ver_mp3, layer, prot, medio, circa As String
 Dim j, frequenza, num_frame, brVar, totBR, durata1, durata2, durata As Integer
 Dim vB, lB, pB, brB, frB As Byte
 Dim secundum, tertium, bitrate, cpf As Short

 fl = "/percorso/del/file.mp3"
 
 Print "File audio mp3: '"; File.Name(fl)

 s = File.Load(fl)
 Print "\nDimensione: "; Len(s); " byte"
 Write "\e[5m\e[1mAttendere !\e[0m"
 Flush
 
 initium = 1
 
 For j = initium To Len(s) - 1

   If (Asc(s, j) = 255) And (Asc(s, j + 1) > 241) And (Asc(s, j + 2) > 15) Then

   secundum = Asc(s, j + 1)
   tertium = Asc(s, j + 2)

' Individua 2° byte dell'header per estrarre le seguenti informazioni generali sul file mp3:
' - vesione MPEG;
' - layer;
' - protezione.
' I primi 3 bit più significativi (tutti posti a 1) appartengono con quelli del 1° byte all'identificazione dell'header.
 
' Viene individuata la versione del file mp3:
   vB = Asc(s, j + 1) And 24
   Select Case vB
     Case 0
       ver_mp3 = "2.5"
     Case 16
       ver_mp3 = "2"
     Case 24
       ver_mp3 = "1"
   End Select


' Viene individuato il "Layer" del file mp3:
   lB = Asc(s, j + 1) And 6
   Select Case lB
     Case 2
       layer = "III"
     Case 4
       layer = "II"
     Case 6
       layer = "I"
   End Select
   

' Viene verificata la Protezione:
   pB = Asc(s, j + 1) And 1
   Select Case pB
     Case 0
       prot = "Non protetto"
     Case 1
       prot = "Protetto"
   End Select
   
   Write "\rVersione MPEG = " & ver_mp3 & "   Layer = " & layer & "   Protezione CRC = " & prot


' Si analizza, quindi, il terzo byte per estrarre le seguenti informazioni generali sul file mp3:
' - bitrate;
' - frequenza di campionamento;
' Tali informazioni sono condizionate dalla versione e dal layer del file MPEG.
   brB = Asc(s, j + 2) And 240
   bitrate = EstraeBitRate(ver_mp3, layer, brB)

   frB = Asc(s, j + 2) And 12
   frequenza = EstraeFrequenza(ver_mp3, frB)

     Exit

   Endif

 Next


   For j = 1 To Len(s) - 2
     If (Asc(s, j) = 255) And (Asc(s, j + 1) = secundum) Then Inc num_frame
     If (Asc(s, j) = 255) And (Asc(s, j + 1) = secundum) And (Asc(s, j + 2) <> tertium) Then
       Inc brVar
       brB = Asc(s, j + 2) And 240
       totBR += EstraeBitRate(ver_mp3, layer, brB)
     Endif
   Next


   If brVar > num_frame * 0.1 Then

     Select Case layer
       Case "I"
         cpf = 384
       Case "II"
         cpf = 1152
       Case "III"
         If ver_mp3 = "1" Then
           cpf = 1152
         Else
           cpf = 576
         Endif
     End Select
     durata1 = Fix((num_frame * cpf / frequenza) * 1000)
     bitrate = totBR / brVar
     durata2 = Fix((Len(s) / bitrate) * 8)
     durata = (durata1 + durata2) / 2
     medio = "variabile medio "
     circa = "circa "
   Else
     durata = Fix((Len(s) / bitrate) * 8)

   Endif

   Print "\nBitRate " & medio & "= "; bitrate
   Print "Frequenza = hz "; frequenza
   Print "Durata " & circa & "= "; Time(0, 0, 0, durata)
 
   Print "\n== T A G =="
   EstraeTag(s)

End



Private Function EstraeBitRate(Vmpeg As String, layB As String, bitB As Byte) As Short
 
   Dim velCamp As Short
 
   If Vmpeg = "1" Then   ' Nel caso di Mpeg vers. 1
   
     Select Case layB   ' Verifica il Layer
       Case "I"
         Select Case bitB
           Case 16
             velCamp = 32
           Case 32
             velCamp = 64
           Case 48
             velCamp = 96
           Case 64
             velCamp = 128
           Case 80
             velCamp = 160
           Case 96
             velCamp = 192
           Case 112
             velCamp = 224
           Case 128
             velCamp = 256
           Case 144
             velCamp = 288
           Case 160
             velCamp = 320
           Case 176
             velCamp = 352
           Case 192
             velCamp = 384
           Case 208
             velCamp = 416
           Case 224
             velCamp = 448
         End Select
       Case "II"
         Select Case bitB
           Case 16
             velCamp = 32
           Case 32
             velCamp = 48
           Case 48
             velCamp = 56
           Case 64
             velCamp = 64
           Case 80
             velCamp = 80
           Case 96
             velCamp = 96
           Case 112
             velCamp = 112
           Case 128
             velCamp = 128
           Case 144
             velCamp = 160
           Case 160
             velCamp = 192
           Case 176
             velCamp = 224
           Case 192
             velCamp = 256
           Case 208
             velCamp = 320
           Case 224
             velCamp = 384
         End Select
       Case "III"
         Select Case bitB
           Case 16
             velCamp = 32
           Case 32
             velCamp = 40
           Case 48
             velCamp = 48
           Case 64
             velCamp = 56
           Case 80
             velCamp = 64
           Case 96
             velCamp = 80
           Case 112
             velCamp = 96
           Case 128
             velCamp = 112
           Case 144
             velCamp = 128
           Case 160
             velCamp = 160
           Case 176
             velCamp = 192
           Case 192
             velCamp = 224
           Case 208
             velCamp = 256
           Case 224
             velCamp = 320
         End Select
     End Select
     
   Else
     
     Select Case layB    ' Verifica il Layer
       Case "I"
         Select Case bitB
           Case 16
             velCamp = 32
           Case 32
             velCamp = 48
           Case 48
             velCamp = 56
           Case 64
             velCamp = 64
           Case 80
             velCamp = 80
           Case 96
             velCamp = 96
           Case 112
             velCamp = 112
           Case 128
             velCamp = 128
           Case 144
             velCamp = 144
           Case 160
             velCamp = 160
           Case 176
             velCamp = 176
           Case 192
             velCamp = 192
           Case 208
             velCamp = 224
           Case 224
             velCamp = 256
         End Select
       Case "II" To "III"
         Select Case bitB
           Case 16
             velCamp = 8
           Case 32
             velCamp = 16
           Case 48
             velCamp = 24
           Case 64
             velCamp = 32
           Case 80
             velCamp = 40
           Case 96
             velCamp = 48
           Case 112
             velCamp = 56
           Case 128
             velCamp = 64
           Case 144
             velCamp = 80
           Case 160
             velCamp = 96
           Case 176
             velCamp = 112
           Case 192
             velCamp = 128
           Case 208
             velCamp = 144
           Case 224
             velCamp = 320
         End Select
     End Select
     
   Endif
   
   Return velCamp
 
End


Private Function EstraeFrequenza(Vmpeg As String, fre As Byte) As Integer
 
 Dim frq As Integer
 
 
   Select Case Vmpeg
     Case "1"         '  Nel caso di Mpeg vers. 1
       Select Case fre
         Case 0
           frq = 44100
         Case 4
           frq = 48000
         Case 8
           frq = 32000
       End Select
     Case "2"         ' Nel caso di Mpeg vers. 2
       Select Case fre
         Case 0
           frq = 22050
         Case 4
           frq = 24000
         Case 8
           frq = 16000
       End Select
     Case "2.5"       ' Nel caso di Mpeg vers. 2.5
       Select Case fre
         Case 0
           frq = 11025
         Case 4
           frq = 12000
         Case 8
           frq = 8000
       End Select
   End Select

   Return frq
   
End


Private Procedure EstraeTag(s As String)

' Sono impostati alcuni TAG (ovviamente alla seguente lista possono essere aggiunti altri di quelli previsti):
 Dim tag As String[] = ["TALB", "TCOM", "TCOP", "TDAT", "TDEN", "TDLY", "TDRC", "TENC", "TFLP", "TIT1", 
                        "TIT2", "TIT3", "TKEY", "TLAN", "TLEN", "TMCL", "TMED", "TOAL", "TOFN", "TOLY",
                        "TOPE", "TORY", "TOWN", "TPE1", "TPE2", "TPE3", "TPE4", "TPUB", "TCON", "TDRC",
                        "TRCK", "TRDA", "TRSN", "TRSO", "TSRC", "TSSE", "TYER", "COMM", "WXXX", "TXXX",
                        "PRIV"]
 Dim t As String
 Dim d, i As Integer
 
' Cerca i TAG nel file mp3:
 d = Len(s)
 For Each t In tag
   i = InStr(s, t)
   If i > 0 Then d = Min(i, d)
 Next
 
 While tag.Find(Mid(s, d, 4)) > -1
' Evita di prendere in considerazione eventuali falsi TAG:
   If Asc(Mid(s, d + 4, 1)) > 0 Then 
     d += 4
     Continue 
   Endif
' Memorizza i 4 caratteri-byte dopo il nome del TAG che indicano la lunghezza del testo:
   t = Mid(s, d + 4, 4)
' Ottiene il valore numerico di tipo Intero, tenendo conto che il valore è rappresentato in "Big-Endian":
   i = Asc(t, 1) * 16777216   ' &01000000
   i += Asc(t, 2) * 65536      ' &010000
   i += Asc(t, 3) * 256        ' &0100
   i += Asc(t, 4) 
   Print "\e[1m"; s[d - 1, 4]; "\e[0m", Replace(Mid(s, d + 11, i - 1), Chr(&00), Chr(&20))
   d += 10 + i
 Wend 
 
 If InStr(s, "APIC") Then Print "\e[1m"; "APIC\e[0m  \e[31m(Il file contiene anche anche dati immagine)\e[0m"
 If i == 0 Then Print "TAG assenti !"

End


Riferimenti