Calcolare la durata di un file MP3

Da Gambas-it.org - Wikipedia.

Per calcolare la durata di un file MP3, sia esso "mono" che "stereo", si effettuerà il seguente calcolo:

durata = (dimp3 / bitrate) * 8

laddove:

  • dimp3 è la dimensione del file MP3 in byte;
  • bitrate è il bitrate del file MP3. [Nota 1]

Se il valore della dimensione del file MP3 è espresso in "byte", come di consueto, poiché il valore dl bitrate è invece espresso in "bit", non sussiste coerenza ed uniformità di unità di misura fra i due valori: la dimensione del file è espressa in "Byte", mentre il bitrate è espresso in "bit". Bisognerà, allora, moltiplicare per "8" il risultato della divisione fra dimp3 e bitare (come appunto abbiamo mostrato all'inizio); oppure si dovrà trasformare in "bit" il valore della dimensione del file MP3 moltiplicandolo per "8", e dividendo infine il risultato per il bitrate:

durata = (dimp3 * 8) / bitrate


Esempio con le sole risorse di Gambas

Mostriamo di seguito un esempio pratico, nel quale si otterrà la durata di un file MP3 utilizzando le sole risorse native di Gambas.

Public Sub Main()
 
 Dim fileMP3,dati As String
 Dim dur As Integer
   
  fileMP3 = "/percorso/del/file.mp3"
  Print "File audio mp3: "; Quote(File.Name(fileMP3))
  dati = File.Load(fileMP3)
  Print "\nDimensione: "; Len(dati); " byte"
  
' Invoca la funzione per ottenere la durata del file audio MP3:
  dur = DurataMP3(dati)
  
  Print "Durata: "; Date(0, 0, 0, 0, 0, 0, dur)
  
End


Private Function DurataMP3(s As String) As Integer
 
 Dim ver_mp3, layer As String
 Dim j, durata As Integer
 Dim vB, lB, brB As Byte
 Dim initium, bitrate As Short
  
  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
    
' Individua 2° byte dell'header per estrarre le seguenti informazioni generali sul file mp3:
' - vesione MPEG;
' - layer.
' 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
     
      Print "Versione MPEG = "; ver_mp3, "Layer = "; layer
      
' Si analizza, quindi, il terzo byte per estrarre il "bitrate" del file mp3. Questa informazione è condizionata dalla versione e dal layer del file MPEG.
      brB = Asc(s, j + 2) And 240
      bitrate = EstraeBitRate(ver_mp3, layer, brB)
  
      Exit
      
    Endif
  Next
  
' Formula per calcolare la durata di un file audio MP3:
  durata = Fix((Len(s) / bitrate) * 8)
  
  Print "BitRate = "; bitrate; " kbps"
  
  Return durata
  
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


Conoscere la durata ottenendo il bitrate variabile medio

Ogni frame contiene all'inizio anche le informazioni attinenti al suo relativo bitrate. Pertanto nell'arco dell'intero file audio mp3 il bitrate può variare.

Per ottenere il bitrate variabile medio di tutti i frame costituenti il file audio mp3, è possibile utilizzare il seguente codice:

 Public Sub Main()
 
 Dim fileMP3,dati As String
   
  fileMP3 = "/percorso/del/file.mp3"
  Print "File audio mp3: "; Quote(File.Name(fileMP3))
  dati = File.Load(fileMP3)
  Print "\nDimensione: "; Len(dati); " byte"
  
' Invoca la Procedura per ottenere la durata del file audio MP3:
  DurataMP3(dati)
  
End


Private Procedure DurataMP3(s As String)
 
 Dim ver_mp3, layer, medio, circa As String
 Dim j, frequenza, num_frame, brVar, totBR, durata1, durata2, durata As Integer
 Dim vB, lB, brB, frB As Byte
 Dim initium, secundum, tertium, bitrate, cpf As Short
  
  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.
' 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
     
      Print "Versione MPEG = "; ver_mp3, "Layer = "; layer
      
' Si analizza, quindi, il terzo byte per estrarre il "bitrate" del file mp3. Questa informazione è condizionata 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   ' Se interessa ottenere il bitrate variabile medio
    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
' Formula per calcolare la durata di un file audio MP3:
    durata = Fix((Len(s) / bitrate) * 8)
  Endif
  Print "BitRate " & medio & "= "; bitrate; " kbps"
  Print "Frequenza = hz "; frequenza
  Print "Durata " & circa & "= "; Date(0, 0, 0, 0, 0, 0, durata)
  
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



Note

[1] Il valore del bitrate di un file MP3 potrà essere estratto mediante una della varie modalità mostrate in alcune pagine della Wiki dedicate ai file MP3:
http://www.gambas-it.org/wiki/index.php?title=Guide_della_comunit%C3%A0#Gestione_dei_dati_audio_e_dei_file_audio


Riferimenti