Estrarre informazioni da un file audio MOD con le sole risorse di Gambas
Il file audio MOD è formato da pattern di note, nonché campioni audio utilizzati per diversi strumenti. I campioni sonori sono assegnati a diverse tracce all'interno del modulo e vengono riprodotti in base alle note musicali.
L'ordine dei byte nel file Mod è in Big-Endian.
In particolare il file Mod è così costituito:
- dal byte 0 al byte 19: Titolo del brano
- dal byte 20 al byte 949: informazioni sui 31 possibili campioni audio. Tali informazioni sono contenute per ciascun campione audio in 30 byte (quindi in totale sono utilizzati 30 byte * 31 campioni = 930 byte), così specificati:
- - 22 byte per il nome del campione audio;
- - 2 byte per per la dimensione del campione audio;
- - 1 byte per la definizione della lunghezza in byte del campione;
- - 1 byte per l'accordatura (fine-tune);
- - 1 byte per il volume (da 0 a 64);
- - 2 byte per l'inizio del loop;
- - 2 byte per la lunghezza del loop.
- al byte 950: lunghezza del brano espressa in pattern (da 0 a 128);
- al byte 951: byte di riavvio per il ciclo del brano;
- dal byte 952 al byte 1079: ordine delle sequenze dell'esecuzione del brano;
- dal byte 1080 al byte 1083: un identificativo tra questi: M.K., 4CHN, 6CHN, 8CHN, 4FLT, 8FLT (se è presente uno di questi identificativi, allora il file modulo ha 31 strumenti musicali);
- dal byte 1084: iniziano i pattern audio.
Mostriamo di seguito un semplice esempio per estrarre con le sole risorse di Gambas da un file Mod alcune informazioni tra quelle appena sopra indicate:
Public Sub Main() Dim md As String Dim fl As File Dim bb As Byte[] Dim ss As String[] = ["M.K.", "4CHN", "6CHN", "8CHN", "FLT4", "FLT8"] Dim b As Byte Dim p As Pointer Dim c As Short Dim i, tot As Integer md = "/percorso/del/file.mod" Print "File Mod: "; md fl = Open md For Read With bb = New Byte[Lof(fl)] .Read(fl, 0, bb.Count) If ss.Exist(.ToString(1080, 4)) Then Print "\nFile Mod abilitato ad usare 4 canali digitali e 31 strumenti." Else Print "\nFile Mod abilitato ad usare 4 canali digitali e 15 strumenti." Endif p = Alloc(.ToString(0, 20)) Print "\nTitolo: "; String@(p) Free(p) End With For b = 0 To 30 p = Alloc(bb.ToString(20 + (30 * b), 22)) Print "\nNome del "; b + 1; "° campione audio: "; String@(p) i = Val("&" & Hex(bb[42 + (30 * b)], 2) & Hex(bb[43 + (30 * b)], 2)) * 2 Print "Lunghezza del campione audio: "; i;; "byte" If bb[44 + (30 * b)] > 7 Then c = CShort(bb[44 + (30 * b)]) - 16 Else c = CShort(bb[44 + (30 * b)]) Endif Print "Accordatura: "; c Print "Volume: "; bb[45 + (30 * b)] tot += i Free(p) Next Print "\n\nDimensione totale dei dati audio: "; tot;; "byte" Print "\nLunghezza del brano: "; bb[950];; "pattern" fl.Close End