Suddividere in due o più parti coerenti e funzionali un file audio mp3
Da Gambas-it.org - Wikipedia.
Versione del 17 giu 2024 alle 18:31 di Vuott (Discussione | contributi)
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.
********************************************************************************************************** Il presente codice è la traduzione in Gambas 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) Then2 ' 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