Il seguente codice è un'applicazione per dividere in due o più parti coerenti e funzionali un file audio di formato
.
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.
'******************************************************************************************************************************************
' 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