Autore Topic: Programma per suddividere un file audio mp3  (Letto 293 volte)

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.270
  • Ne mors quidem nos iunget
    • Mostra profilo
Programma per suddividere un file audio mp3
« il: 17 Maggio 2016, 13:23:59 »
Il seguente codice è un'applicazione per dividere in due o più parti coerenti e funzionali un file audio di formato mp3.
Da notare che questa operazione causa la perdita degli eventuali tag ID3 del file; quindi si consiglia di rimuovere tutti i TAG originari e di fare una operazione di ri-codifica successivamente.



Codice: [Seleziona]
'******************************************************************************************************************************************
' Il presente codice è la traduzione in Gambas, effettuata dal membro del foro gambas-it.org "vuott", con variazioni ed integrazioni,
' del codice originale, scritto in linguaggio C, del progetto di Kjetil Erga, chiamato "MP3 Splitting Tool".
'******************************************************************************************************************************************


Private bitrate_matrix As Integer[][] = [[0, 0, 0, 0, 0], [32, 32, 32, 32, 8], [64, 48, 40, 48, 16],
        [96, 56, 48, 56, 24], [128, 64, 56, 64, 32], [160, 80, 64, 80, 40], [192, 96, 80, 96, 48],
        [224, 112, 96, 112, 56], [256, 128, 112, 128, 64], [288, 160, 128, 144, 80],
        [320, 192, 160, 160, 96], [352, 224, 192, 176, 112], [384, 256, 224, 192, 128],
        [416, 320, 256, 224, 144], [448, 384, 320, 256, 160], [0, 0, 0, 0, 0]]

Private sampling_matrix As Integer[][] = [[44100, 22050, 11025], [48000, 24000, 12000],
                                          [32000, 16000, 8000], [0, 0, 0]]
                                         

Public Sub Main()

  Dim i, num_frame, parti, limes As Integer
  Dim src, dst As File
  Dim filename, parte As String

    filename = "/percorso/del/file.mp3"
   
' Stabiliamo che il file mp3 sarà suddiviso - ad esempio - in tre sotto-file:
    parti = 3
    If parti = 0 Then Error.Raise("Numero di parti non valido !")

    src = Open filename For Read
    Write #File.out, "\e[5mAttendere..."
   
    num_frame = read_frames(src, Null, 0)
    If parti > num_frame Then Error.Raise("Sono state specificate più parti che frame disponibili !")
   
    Seek #src, 0

    For i = 1 To parti
      parte = filename & "." & Format(i, "00")

      dst = Open parte For Create
      If IsNull(dst) Then Error.Raise("Impossibile aprire il file audio in scrittura !")
     
      If i = parti Then
        limes = 0
      Else
        limes = num_frame / parti
      Endif

    Write #File.Out, "\r\e[0m" & Format(i, "00:") & "  " & parte & ":" & "  " & CStr(read_frames(src, dst, limes))
    Print
    Write #File.out, "\e[5mAttendere..."
      dst.Close
    Next
    Print #File.Out, "\r\e[0m               "
    src.Close

End


Private Function read_frames(sor As File, des As File, frame_limes As Integer) As Integer
 
  Dim n, lung_frame, num_frame As Integer
  Dim b As Byte
  Dim quad As New Byte[4]
 
    quad[0] = 0
    quad[1] = 0
    quad[2] = 0
    quad[3] = 0
   
    lung_frame = 0
    n = 0
    num_frame = 0
   
    While Not Eof(sor)
   
      Read #sor, b
     
      If Not IsNull(des) Then Write #des, b As Byte
     
      If lung_frame > 0 Then
        Dec lung_frame
        Inc n

        If frame_limes > 0 Then
          If (lung_frame = 0) And (num_frame = frame_limes) Then Return num_frame
        Endif

' Va avanti nel flusso per evitare la lettura di dati inutili:
        Continue
      Endif
     
      quad[0] = quad[1]
      quad[1] = quad[2]
      quad[2] = quad[3]
      quad[3] = b

      If ((quad[0] = &FF) And ((quad[1] And &F0) = &F0)) Then
        Inc num_frame
        lung_frame = decode_header(quad) - 4
        quad[0] = 0
        quad[1] = 0
        quad[2] = 0
        quad[3] = 0
      Endif

      Inc n
     
    Wend
   
    Return num_frame
 
End


Private Function decode_header(header As Byte[]) As Integer
 
  Dim version, layer, padding As Integer
  Dim bitrate_row, bitrate_col, sampling_row, sampling_col As Integer
 
    version = (header[1] And &08) \ CInt(2 ^ 3)     ' MPEG version
    layer = (header[1] And &06) \ CInt(2 ^ 1)       ' MPEG layer
   
    bitrate_row = (header[2] And &F0) \ CInt(2 ^ 4)
    If version = 1 Then
      If layer = 3 Then     '    I
        bitrate_col = 0
      Else If layer = 2     '   II
        bitrate_col = 1
      Else If layer = 1     '  III
        bitrate_col = 2
      Endif
    Else                    ' Versione 2
      If (layer == 3)       '    I
        bitrate_col = 3
      Else If layer = 2     '   II
        bitrate_col = 4
      Else If layer = 1     '  III
        bitrate_col = 4
      Endif
    Endif
   
    sampling_row = (header[2] And &0C) \ CInt(2 ^ 2)
    sampling_col = IIf(version = 0, 1, 0)
   
    padding = (header[2] And &02) \ CInt(2 ^ 1)
   
    If sampling_matrix[sampling_row][sampling_col] = 0 Then Return -1
   
    If layer = 3 Then   '  I
      Return (12 * (bitrate_matrix[bitrate_row][bitrate_col] * 1000) /
      sampling_matrix[sampling_row][sampling_col] + (padding * 4)) * 4
    Else If (layer = 2) Or (layer = 1)      '   II or III
      Return 144 * (bitrate_matrix[bitrate_row][bitrate_col] * 1000) /
      sampling_matrix[sampling_row][sampling_col] + padding
    Else
      Return -1
    Endif
 
End
« Ultima modifica: 17 Maggio 2016, 21:20:03 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »