Differenze tra le versioni di "La gestione dei file MIDI mediante le funzioni esterne del API di WildMidi"

Da Gambas-it.org - Wikipedia.
 
(2 versioni intermedie di uno stesso utente non sono mostrate)
Riga 1: Riga 1:
La libreria di '''''WildMidi''''' contiene funzioni e risorse per leggere e gestire file Midi.
+
* [[Conoscere la durata di un file Midi mediante le funzioni esterne del API di WildMidi]]
 
+
* [[Eseguire un file Midi con le risorse del API di WildMidi e di ALSA]]
In particolare la libreria ''WildMIDI'' converte i file MIDI in dati ''audio'' che potranno essere inviati ad altra applicazione capace di eseguire i dati audio, come ad esempio Alsa, per farli ascoltare. L'[http://it.wikipedia.org/wiki/Application_programming_interface API] della libreria è progettata in modo che sia facile inserire ''WildMIDI'' in applicazioni che prevedono anche la riproduzione di file Midi.
+
* [[Ottenere un file Midi da un file XMI con le funzioni esterne del API di WildMidi]]
 
+
* [[Ottenere un file WAV da un file Midi con le funzioni esterne del API di WildMidi]]
 
 
La libreria da utilizzare in Gambas è attualmente la seguente:
 
libWildMidi.so.2.1.0
 
 
 
Bisognerà avere installato nel sistema il banco di suoni (''soundfont bank''):  ''Freepats''.
 
 
 
 
 
===Esempio pratico===
 
Il semplice esempio che segue è sostanzialmente strutturato in due parti:
 
* la prima dedicata alle funzionalità di ''WildMidi'' che passeranno i dati audio, derivati dalla conversione di un file Midi, ad Alsa;
 
* la seconda dedicata ad Alsa, che, ricevuti i dati audio da ''WildMidi'', li eseguirà effettivamente.
 
I dati audio (ottenuti dalla conversione dei dei dati Midi) saranno passati da ''WildMidi'' ad Alsa attraverso una variabile di tipo ''Puntatore'' che punta ad un'area allocata riempita dei predetti dati audio dalla funzione ''WildMidi_GetOutput()'' di ''WildMidi''.
 
Library "libWildMidi:2.1.0"
 
 
<FONT color=gray>' ''WildMidi_Init  (const char *config_file, unsigned short int rate, unsigned short int options)''
 
' ''Intializes "libWildMidi" in preparation for playback.''</font>
 
Private Extern WildMidi_Init(config_file As String, rate As Short, options As Short) As Integer
 
 
<FONT color=gray>' ''int WildMidi_MasterVolume (unsigned char master_volume)''
 
' ''Sets the overall library volume level to master_volume. The range of master_volume is between 0 And 127 with 100 being the default.''</font>
 
Private Extern WildMidi_MasterVolume(master_volume As Byte) As Integer
 
 
<FONT color=gray>' ''midi *WildMidi_Open (const char *midifile)''
 
' ''Open  a MIDI file pointed to by midifile for processing. This file must be in standard midi format.''
 
' ''It returns a handle for the midi file opened. This handle is used by most functions in libWildMidi to identify which midi file we are refering to.''</font>
 
Private Extern WildMidi_Open(midifile As String) As Pointer
 
 
<FONT color=gray>' ''int  WildMidi_GetOutput  (midi *handle, char *buffer, unsigned long insize)''
 
' ''Places size bytes of audio data from a  handle,  previously  opened  by WildMidi_Open() or WildMidi_OpenBuffer(), into a buffer pointer to by buffer.''
 
' ''Buffer must be atleast size bytes, <SPAN style="text-decoration:underline">with size being a multiple of 4 as the data is stored in 16 bit interleaved stereo format</span>.''</font>
 
Private Extern WildMidi_GetOutput(handle As Pointer, buffer As Pointer, insize As Long) As Integer
 
 
<FONT color=gray>' ''int WildMidi_Close (midi *handle)''
 
' ''Finish processing MIDI data or file. "handle" the indentifier obtained from opening a midi file with "WildMidi_Open()".''</font>
 
Private Extern WildMidi_Close(handle As Pointer) As Integer
 
 
<FONT color=gray>' ''void WildMidi_Shutdown(void)''
 
' ''Shuts  down  the wildmidi library, resetting data and freeing up memory used by the library.''
 
' ''Once this is called, the library is no-longer initiaized and "WildMidi_Init()" will need to be called again.''</font>
 
Private Extern WildMidi_Shutdown()
 
 
<FONT color=darkgray>''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''</font>
 
 
 
Library "libasound:2"
 
 
<FONT color=gray>' ''int  snd_pcm_open(snd_pcm_t **pcm, const char *name, snd_pcm_stream_t stream, int mode)  --> Apre il sub-sistema PCM''</font>
 
Private Extern snd_pcm_open(pcmP As Pointer, nome As String, stream As Integer, mode As Integer) As Integer
 
 
<FONT color=gray>' ''const char * snd_strerror (int errnum)  --> Ritorna un messaggio relativo ad un codice di Errore.''</font>
 
Private Extern snd_strerror(errnum As Integer) As String
 
 
<FONT color=gray>' ''int snd_pcm_set_params (snd_pcm_t *pcm, snd_pcm_format_t format, snd_pcm_access_t access, unsigned int canali, unsigned int rate, int soft_resample, unsigned int latency)''</font>
 
Private Extern snd_pcm_set_params(pcmP As Pointer, formatB As Byte, accessB As Byte, canali As Integer, rate As Integer, soft_resample As Integer, latency As Integer) As Integer
 
 
<FONT color=gray>' ''snd_pcm_sframes_t snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)''</font>
 
Private Extern snd_pcm_writei(pcmP As Pointer, buffP As Pointer, uframes As Long) As Integer
 
 
<FONT color=gray>' ''int snd_pcm_close(snd_pcm_t *pcm)  --> Chiude il sub-sistema PCM''</font>
 
Private Extern snd_pcm_close(pcmP As Pointer) As Integer
 
 
 
'''Public''' Sub Button1_Click()
 
 
  Dim err As Integer
 
  Dim midi, buffer, handle as Pointer
 
  Dim <FONT color=darkorange>frequenza</font> As Integer = 44100
 
 
<FONT color=gray>' ''Va ad inizializzare l'interfaccia PCM di Alsa:''</font>
 
    handle = inizializzaAlsa(<FONT color=darkorange>frequenza</font>)
 
 
 
<FONT color=gray>' ''Inizializza la libreria di "WildMidi":
 
' '''''-''' il primo parametro richiama il file che contiene la configurazione degli strumenti musicali che sarà utilizzata dalla libreria.''
 
' ''  Il file di configurazione potrà essere: "/etc/timidity/freepats.cfg" o "/etc/wildmidi/wildmidi.cfg" oppure "/etc/timidity/eawpats.cfg".''
 
' '''''-''' il secondo argomento della funzione deve essere identico al 5° parametro (frequenza) di "snd_pcm_set_params()" ):''</font>
 
    err = WildMidi_Init("/etc/timidity/freepats.cfg", <FONT color=darkorange>frequenza</font>, 0)
 
    If err < 0 Then Error.Raise("Errore nell'inizializzazione dell'interfaccia libWildMidi !")
 
   
 
<FONT color=gray>' ''Imposta il volume generale (da 0 a 127):''</font>
 
    err = WildMidi_MasterVolume(100)
 
    If err < 0 Then Error.Raise("Errore nell'impostazione del Volume Generale !")
 
   
 
<FONT color=gray>' ''Apre il file Midi che dovrà essere eseguito:''</font>
 
    midi = WildMidi_Open("<FONT color=gray>''/percorso/del/file.mid''</font>")
 
    If IsNull(midi) Then Error.Raise("Impossibile aprire il file Midi !")
 
 
<FONT color=gray>' ''Alloca un'area di memoria che sarà puntata da una variabile di tipo "Puntatore":''</font>
 
    buffer = Alloc(<FONT color=maroon>128</font>)
 
 
    Do
 
 
<FONT color=gray>' ''Ad ogni giro viene riempita l'area allocata con un certo numero di dati Midi convertiti in dati audio da passare successivamente ad Alsa.''
 
' ''(In particolare, ad Alsa sarà passata la variabile di tipo "puntatore" - qui chiamata "buffer" - che ora viene riempita di dati):</font>
 
      err = WildMidi_GetOutput(midi, <FONT color=blue>buffer</font>, <FONT color=maroon>128</font>)
 
 
<FONT color=gray>' ''Viene passata la variabile di tipo "puntatore" (qui chiamata "buffer") alla seguente funzione, che provvede ad inviare i dati audio ad Alsa'
 
' ''(il terzo parametro deve essere uguale ad 1/4 del valore del secondo parametro):''</font>
 
      snd_pcm_writei(handle, <FONT color=blue>buffer</font>, <FONT color=maroon>128</font> / SizeOf(gb.Integer))
 
 
    Loop Until err = 0
 
 
 
<FONT color=gray>' ''Chiude l'elaborazione dei dati Midi da parte di "WildMidi":''</font>
 
    err = WildMidi_Close(midi)
 
    If err < 0 Then Error.Raise("Errore nella chiusura del processo dei dati Midi !")
 
 
    Free(buffer)
 
   
 
<FONT color=gray>' ''Chiude la libreria di "WildMidi":''</font>
 
    WildMidi_Shutdown()
 
   
 
<FONT color=gray>' ''Chiude infine anche l 'handle della libreria di Alsa:''</font>
 
  snd_pcm_close(handle)
 
 
'''End'''
 
 
 
'''Private''' Function inizializzaAlsa(<FONT color=darkorange>frequenza</font> As Integer) As Pointer
 
 
 
  Dim err As Integer
 
  Dim handle as Pointer
 
  Dim nomen As String = "default"
 
  Dim SND_PCM_STREAM_PLAYBACK As Byte = 0
 
  Dim SND_PCM_ACCESS_RW_INTERLEAVED As Byte = 3
 
  Dim canali As Byte = 2
 
 
 
 
<FONT color=gray>' ''Apre il sub-sistema PCM di Alsa creando un apposito "handle":''</font>
 
    err = snd_pcm_open(VarPtr(handle), nomen, SND_PCM_STREAM_PLAYBACK, 0)
 
    If err < 0 Then Error.Raise("Playback open error: " & snd_strerror(err))
 
 
<FONT color=gray>' ''Imposta i parametri hardware/software dell'interfaccia PCM di ALsa:''</font>
 
    err = snd_pcm_set_params(handle, 2, SND_PCM_ACCESS_RW_INTERLEAVED, canali, <FONT color=darkorange>frequenza</font>, 1, 500000)
 
    If err < 0 Then Error.Raise("Playback open error: " & snd_strerror(err))
 
 
    Return handle
 
   
 
'''End'''
 
 
 
 
 
 
 
=Riferimenti=
 
* http://wildmidi.sourceforge.net/?id=about
 
* http://manpages.ubuntu.com/manpages/saucy/man5/wildmidi.cfg.5.html
 
* https://natonelbronx.wordpress.com/2007/07/12/ascoltare-midi-su-linux-debianubuntu/
 

Versione attuale delle 18:11, 19 ago 2020