Eseguire un file MIDI mediante le funzioni esterne del API di Fluidsynth
Mostriamo di seguito il codice per di un semplice applicativo a riga di comando per la esecuzione di file Midi.
E' necessario avere installata e richiamare in Gambas la libreria condivisa: "libfluidsynth.so.3.3.8 ".
Si dovrà individuare un file soundfont bank con estensione .sf2, da far caricare dalla funzione esterna "fluid_synth_sfload()" per poter ottenere i suoni.
Mostriamo un semplice esempio pratico:
Library "libfluidsynth:3.3.8"
Private Enum FLUID_PLAYER_READY = 0, FLUID_PLAYER_PLAYING, FLUID_PLAYER_DONE
' fluid_settings_t* new_fluid_settings(void)
' Create a new settings object.
Private Extern new_fluid_settings() As Pointer
' fluid_synth_t * new_fluid_synth (fluid_settings_t *settings)
' Create new FluidSynth instance.
Private Extern new_fluid_synth(settings As Pointer) As Pointer
' fluid_player_t* new_fluid_player(fluid_synth_t * synth)
' Create a new MIDI player.
Private Extern new_fluid_player(synth As Pointer) As Pointer
' fluid_audio_driver_t* new_fluid_audio_driver(fluid_settings_t * settings, fluid_synth_t * synth)
' Create a new audio driver.
Private Extern new_fluid_audio_driver(settings As Pointer, synth As Pointer) As Pointer
' int fluid_is_soundfont(const char * filename)
' Check if a file is a SoundFont file.
Private Extern fluid_is_soundfont(filename As String) As Integer
' int fluid_synth_sfload(fluid_synth_t * synth, const char * filename, nt reset_presets)
' Load a SoundFont file (filename is interpreted by SoundFont loaders).
Private Extern fluid_synth_sfload(synth As Pointer, filename As String, reset_presets As Integer) As Integer
' int fluid_is_midifile(const char * filename)
' Check if a file is a MIDI file.
Private Extern fluid_is_midifile(filename As String) As Integer
' int fluid_player_add(fluid_player_t * player, Const char * midifile)
' Add a MIDI file to a player queue.
Private Extern fluid_player_add(player As Pointer, midifile As String) As Integer
' int fluid_player_play(fluid_player_t * player)
' Activates play mode for a MIDI player if not already playing.
Private Extern fluid_player_play(player As Pointer) As Integer
' int fluid_player_get_status(fluid_player_t * player)
' Get MIDI player status.
Private Extern fluid_player_get_status(player As Pointer) As Integer
' void delete_fluid_audio_driver(fluid_audio_driver_t * driver)
' Deletes an audio driver instance.
Private Extern delete_fluid_audio_driver(driver As Pointer)
' int delete_fluid_player(fluid_player_t * player)
' Delete a MIDI player instance.
Private Extern delete_fluid_player(player As Pointer) As Integer
' int delete_fluid_synth(fluid_synth_t * synth)
' Delete a FluidSynth instance.
Private Extern delete_fluid_synth(synth As Pointer) As Integer
' void delete_fluid_settings(fluid_settings_t * settings)
' Delete the provided settings object.
Private Extern delete_fluid_settings(settings As Pointer)
Public Sub Main()
Dim set, syn, pla, drv As Pointer
Dim filesbk, fileMidi As String
Dim tempus As Date
set = new_fluid_settings()
If set == 0 Then Error.Raise("Errore !")
syn = new_fluid_synth(set)
If syn == 0 Then Error.Raise("Errore !")
pla = new_fluid_player(syn)
If pla == 0 Then Error.Raise("Errore !")
' Carica il soundfont bank per i suoni:
filesbk = "/percorso/del/file/soundfont.sf2"
If Not fluid_is_soundfont(filesbk) Then Error.Raise("Il file non è un soundfont bank !")
If fluid_synth_sfload(syn, filesbk, 1) < 0 Then Error.Raise("Errore !")
' Carica il file Midi prescelto:
fileMidi = "/percorso/del/file.mid"
If fluid_is_midifile(fileMidi) < 0 Then Error.Raise("Il file non è un file 'Midi' !")
If fluid_player_add(pla, fileMidi) < 0 Then Error.Raise("Errore !")
drv = new_fluid_audio_driver(set, syn)
If drv == 0 Then Error.Raise("Impossibile creare un driver audio !")
' Avvia l'esecuzione del file Midi:
If fluid_player_play(pla) < 0 Then Error.Raise("Errore !")
Print
tempus = Now
While fluid_player_get_status(pla) == FLUID_PLAYER_PLAYING
Write "\r\e[0mFile Midi: " & fileMidi & " - \e[31m" &
Str(Time(0, 0, 0, DateDiff(tempus, Now, gb.Millisecond)))
Wait 0.01
Wend
' Libera la memoria precedentemente occupata e chiude il programma:
delete_fluid_audio_driver(drv)
delete_fluid_player(pla)
delete_fluid_synth(syn)
delete_fluid_settings(set)
Print "\nEsecuzione terminata !"
End
Uso contestuale del programma Jackd
Se si desidera usare contestualmente il programma Jackd, una volta lanciato il codice sottostante: aprire Jackd e nella parte "Audio" della finestra "Connessioni" connettere il dispositivo "Fluidsynth", presente nella colonna "Clients leggibili/Porte d'uscita", al dispositivo "system" presente nella colonna "Clients scrivibili/Porte d'entrata".