Eseguire un file MIDI mediante le funzioni esterne del API di Fluidsynth

Da Gambas-it.org - Wikipedia.

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.2.4 ".

Si dovrà individuare un file soundfont bank con estensione .sf2, da far caricare dalla funzione esterna "fluid_synth_sfload" per poter ottenere i suoni.

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".

Mostriamo un semplice esempio pratico:

Library "libfluidsynth:3.2.4"

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


Riferimenti