Eseguire un file MIDI mediante il componente gb.openal
Il componente gb.openal utilizza le risorse dell'API di Openal.
Oltre all'esecuzione dei file audio, con il componente gb.openal è possibile eseguire anche i file Midi, utilizzando in particolare la funzione:
SetStreamPatchset(Stream as AlureStream, Patchset As String) As Boolean
appartenente alla Classe Alure. [nota 1]
Questa funzione specifica il patchset da utilizzare per i flussi MIDI.
Tale patchset è sostanzialmente un file contenente il banco di suoni (soundfont bank) con estensione .sf2 . Pertanto sarà sufficiente in quel parametro indicare il percorso del file soundfont .sf2 che si intende utilizzare.
Mostriamo di seguito un semplice codice per eseguire un file Midi:
Private src As Integer[] Private ast As AlureStream Private ciclo As Boolean Public Sub Form_Open() Dim err As Boolean ' Inizializza la libreria "Alure": err = Alure.InitDevice(Null, Null) If err = False Then Error.Raise("Impossibile inizializzare la libreria 'Alure' !") End Public Sub Button1_Click() Dim percorsoFile As String = "/percorso/del/file.mid" Dim lungh As Integer Dim tm As Date src = Al.GenSources(1) If IsNull(src) Then al.DeleteSources(src) lungh = Stat(percorsoFile).Size ast = Alure.CreateStreamFromFile(percorsoFile, lungh, 0) If IsNull(ast) Then Error.Raise("Impossibile creare il flusso di dati audio dal file !") ' Nel secondo parametro della seguente funzione va specificato il percorso del file soundfont-bank di formato .SF2: Alure.SetStreamPatchset(ast, "/percorso/del/soundfont/file.sf2") ' Esegue il flusso di dati Midi. ' Il terzo parametro della funzione rappresenta il numero dei buffer utilizzati da accodare alla fonte di "OpenAL". ' Ogni buffer verrà riempito con la lunghezza del "chunk" specificato quando il flusso è stato creato. ' Tale valore nell'esecuzione di un file Midi deve essere di almeno 2. Alure.PlaySourceStream(src[0], ast, 3, 0) ciclo = True tm = Time Repeat ' Mostra nell'intestazione della finestra del "Form" il tempo trascorso dall'inizio dell'esecuzione del file Midi: Me.Title = Str(Time(0, 0, 0, DateDiff(tm, Time, gb.Millisecond))) ' Una brevissima attesa consente di agire su eventuali oggetti posti sul "Form": Wait 0.01 Alure.Update() Until ciclo == False End Public Sub Button2_Click() ' Arresta l'esecuzione del file Midi If IsNull(ast) Then Return Alure.StopSource(src[0]) ciclo = False End Public Sub Button3_Click() ' Arresta l'esecuzione del file Midi e chiude la finestra del programma ciclo = False If IsNull(ast) = False Then Alure.DestroyStream(ast) Alure.StopSource(src[0]) Al.DeleteSources(src) Endif Alure.ShutdownDevice() Me.Close End
Caso di applicazione a riga di comando
Nel caso in cui l'applicazione per l'esecuzione di file Midi sia stata realizzata senza componenti grafici, e dunque a riga di comando, al termine del codice sarà assolutamente necessario prevedere un ciclo, all'interno del quale si dovrà porre il Metodo "Alure.Update()".
Nel seguente esempio il percorso del file Midi va inserito nell'apposito spazio sottostante della console (ovvero nel Terminale, ma in questo caso il percorso deve essere privo di apici). Alla fine dell'esecuzione o anche durante l'esecuzione medesima di un file Midi è possibile - sempre con la modalità prima descritta inserire il percorso di un altro file Midi ed eseguirlo.
Durante l'esecuzione lanciando il carattere "p" dall'apposito spazio sottostante della console (ovvero nel Terminale) è possibile mettere in pausa l'esecuzione del file Midi. Premendo poi il tasto "Invio" verrà ripresa l'esecuzione del file.
Infine, inserendo e lanciando un qualsiasi carattere (diverso ovviamente la "p"), si porrà termine all'esecuzione del file.
Private s As String Public Sub Main() Dim err As Boolean Dim src As Integer[] Dim lungh As Integer Dim ast As AlureStream ' Il ciclo dura fino a che non viene inserito nell'apposito spazio della console o nel Terminale il percorso e il nome (ma senza apici) di un file Midi: Repeat Wait 0.01 Until s Begins "/" ' Inizializza la libreria "Alure": err = Alure.InitDevice(Null, Null) If err == False Then Error.Raise("Impossibile inizializzare la libreria 'Alure' !") src = Al.GenSources(1) lungh = Stat(s).Size ast = Alure.CreateStreamFromFile(s, lungh, 0) If IsNull(ast) Then Error.Raise("Impossibile creare il flusso di dati audio dal file !") ' Nel secondo parametro della seguente funzione va specificato il percorso del file soundfont-bank di formato .SF2: Alure.SetStreamPatchset(ast, "/percorso/del/soundfont/file.sf2") Alure.PlaySourceStream(src[0], ast, 3, 0) s = Null ' Inviando il carattere "p" dal Terminale o dalla console, l'esecuzione è posta in "Pausa", inviando ogni altro carattere essa viene terminata: Repeat Alure.Update() Wait 0.01 If s == "p" Then Pausa(src[0]) Until s <> Null ' Va in chiusura: Alure.DestroyStream(ast) Alure.StopSource(src[0]) Al.DeleteSources(src) Alure.ShutdownDevice() If s Begins "/" Then Main() Else Quit Endif End Private Procedure Pausa(sAl As Integer) Dim ripresa As String Al.SourcePause(sAl) Print "Pausa !" ' Per riprendere l'esecuzione, è sufficiente premere il tasto "Invio". In altri casi si è visto essere necessario inserire in console/terminale un carattere e poi premere "Invio". Input ripresa Al.SourcePlayv([sal]) Print "Riprende esecuzione." s = Null End Public Sub Application_Read() Line Input s End
Note
[1] La Classe Alure del componente gb.openal consente di gestire le funzioni di ALURE, che è una libreria di supporto di Openal.