Differenze tra le versioni di "Intercettare ed inviare dati Midi grezzi con le funzioni esterne del API di PortMidi"
Da Gambas-it.org - Wikipedia.
Riga 53: | Riga 53: | ||
' ''Sets filters on an open input stream to drop selected input types.''</font> | ' ''Sets filters on an open input stream to drop selected input types.''</font> | ||
Private Extern Pm_SetFilter(pstream As Pointer, filters As Integer) As Integer | Private Extern Pm_SetFilter(pstream As Pointer, filters As Integer) As Integer | ||
+ | |||
+ | <FONT color=gray>' ''PmError Pm_Poll( PortMidiStream *stream)'' | ||
+ | ' ''Tests whether input is available.''</font> | ||
+ | Private Extern Pm_Poll(pstream As Pointer) As Boolean | ||
<FONT color=gray>' ''int Pm_Read( PortMidiStream *stream, PmEvent *buffer, int32_t length )'' | <FONT color=gray>' ''int Pm_Read( PortMidiStream *stream, PmEvent *buffer, int32_t length )'' | ||
Riga 64: | Riga 68: | ||
<FONT color=gray>' ''PmError Pm_Close( PortMidiStream* stream )'' | <FONT color=gray>' ''PmError Pm_Close( PortMidiStream* stream )'' | ||
' ''Closes a midi stream, flushing any pending buffers.''</font> | ' ''Closes a midi stream, flushing any pending buffers.''</font> | ||
− | Pm_Close(pstream) As Integer | + | Private Extern Pm_Close(pstream As Pointer) As Integer |
<FONT color=gray>' ''PmError Pm_Terminate( void )'' | <FONT color=gray>' ''PmError Pm_Terminate( void )'' | ||
Riga 73: | Riga 77: | ||
'''Public''' Sub Main() | '''Public''' Sub Main() | ||
− | Dim err, i As Integer | + | Dim def_in, def_out, err, i As Integer |
Dim info As PmDeviceInfo | Dim info As PmDeviceInfo | ||
+ | Dim def As String | ||
Dim midi_in, midi_out As Pointer | Dim midi_in, midi_out As Pointer | ||
Print "Dispositivi Midi e loro porte disponibili:\n" | Print "Dispositivi Midi e loro porte disponibili:\n" | ||
− | + | def_in = Pm_GetDefaultInputDeviceID() | |
+ | def_out = Pm_GetDefaultOutputDeviceID() | ||
For i = 0 To Pm_CountDevices() - 1 | For i = 0 To Pm_CountDevices() - 1 | ||
info = Pm_GetDeviceInfo(i) | info = Pm_GetDeviceInfo(i) | ||
− | If | + | If info.inputI > 0 Then |
+ | def = IIf(i = def_in, "default ", Null) | ||
+ | Print i; ": "; String@(info.interf); " "; String@(info.name); " ("; def; "input)" | ||
+ | def = Null | ||
+ | Endif | ||
+ | If info.outputI > 0 Then | ||
+ | def = IIf(i = def_out, "default ", Null) | ||
+ | Print i; ": "; String@(info.interf); " "; String@(info.name); " ("; def; "output)" | ||
+ | Endif | ||
Next | Next | ||
Riga 88: | Riga 102: | ||
Input s | Input s | ||
Print "Porta del dispositivo Midi scelta: "; s | Print "Porta del dispositivo Midi scelta: "; s | ||
− | err = Pm_OpenInput(VarPtr(midi_in), Val(s), 0, | + | err = Pm_OpenInput(VarPtr(midi_in), Val(s), 0, 128, 0, 0) |
If err Then | If err Then | ||
Print Pm_GetErrorText(err) | Print Pm_GetErrorText(err) | ||
Riga 110: | Riga 124: | ||
Print "\nMidi Monitor pronto...\n" | Print "\nMidi Monitor pronto...\n" | ||
Print "Assicurarsi di aver connesso le porte dei dispositivi Midi coinvolti !" | Print "Assicurarsi di aver connesso le porte dei dispositivi Midi coinvolti !" | ||
− | + | ||
− | + | Intercetta_Messaggi(midi_in, midi_out) | |
− | |||
− | |||
− | |||
− | |||
− | |||
<FONT color=gray>' ''Va in chiusura:''</font> | <FONT color=gray>' ''Va in chiusura:''</font> | ||
Riga 127: | Riga 136: | ||
Dim pe As New PmEvent | Dim pe As New PmEvent | ||
− | Dim count As Integer | + | Dim status, count As Integer |
+ | |||
+ | Print "\n\nMidi Monitor pronto...\n\nStatus", "nota", "velocità" | ||
<FONT color=gray>' ''Riceve i dati Midi dal dispositivo Midi, leggendoli dalla sua porta in Uscita:''</font> | <FONT color=gray>' ''Riceve i dati Midi dal dispositivo Midi, leggendoli dalla sua porta in Uscita:''</font> | ||
− | + | While True | |
− | |||
− | While | ||
− | If count = 1 Then | + | status = Pm_Poll(midIn) |
+ | If status = True Then | ||
+ | count = Pm_Read(midIn, pe, 1) | ||
+ | If count > 0 Then | ||
<FONT color=gray>' ''Volendo, possiamo stampare nella console i dati Midi ricevuti:''</font> | <FONT color=gray>' ''Volendo, possiamo stampare nella console i dati Midi ricevuti:''</font> | ||
− | + | Print (pe.message And &FF) And &f, (pe.message \ CInt(2 ^ 8)) And 255, (pe.message \ CInt(2 ^ 16)) And 255 | |
<FONT color=gray>' ''Invia i dati al dispositivo Midi, scrivendoli sulla sua porta in Entrata:''</font> | <FONT color=gray>' ''Invia i dati al dispositivo Midi, scrivendoli sulla sua porta in Entrata:''</font> | ||
− | + | Pm_Write(midEx, pe, 1) | |
− | + | Else | |
<FONT color=gray>' ''Va in chiusura:''</font> | <FONT color=gray>' ''Va in chiusura:''</font> | ||
− | + | Chiude(midEx) | |
− | + | Error.Raise("Errore nella ricezione dei Messaggi Midi:" & Pm_GetErrorText(count)) | |
+ | Endif | ||
Endif | Endif | ||
− | |||
Wend | Wend | ||
Riga 156: | Riga 168: | ||
Pm_Terminate() | Pm_Terminate() | ||
Quit | Quit | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
'''End''' | '''End''' |
Versione delle 16:17, 3 giu 2016
La libreria PortMidi è una libreria per la gestione in tempo reale dei dati Midi in entrata ed in uscita. Essa fa parte di un assortimento di API e librerie create per la musica e per altri media.
E' possibile con alcune funzioni esterne della libreria PortMidi intercettare i dati Midi grezzi, provenienti da un dispositivo Midi, ed inviarli ad altri dispositivi Midi.
Sarà necessario avere installata nel proprio sistema e richiamare nel programma Gambas la libreria condivisa: ''libportmidi.so.0.0.0
Mostriamo di seguito un possibile codice che intercetta i dati Midi grezzi provenienti da un dispositivo esterno e li invia ad altro dispositivo Midi:
Private s As String Library "libportmidi:0.0.0" Public Struct PmDeviceInfo structVersion As Integer interf As Pointer name As Pointer inputI As Integer outputI As Integer opened As Integer End Struct Public Struct PmEvent message As Integer timestamp As Integer End Struct Private Const PM_FILT_ACTIVE As Integer = 16384 Private Const PM_FILT_CLOCK As Integer = 256 Private Const PM_FILT_SYSEX As Integer = 1 ' int Pm_CountDevices (void) ' Get devices count, ids range from 0 to Pm_CountDevices()-1. Private Extern Pm_CountDevices() As Integer ' const char *Pm_GetErrorText( PmError errnum ) ' Translate portmidi error number into human readable message. Private Extern Pm_GetErrorText(errnum As Integer) As String ' const PmDeviceInfo* Pm_GetDeviceInfo( PmDeviceID id ) ' Returns a pointer to a PmDeviceInfo structure referring to the device specified by id. Private Extern Pm_GetDeviceInfo(id As Integer) As PmDeviceInfo ' PmError Pm_OpenInput( PortMidiStream** stream, PmDeviceID inputDevice, void *inputDriverInfo, int32_t bufferSize, PmTimeProcPtr time_proc, void *time_info ) ' Open Input device. Private Extern Pm_OpenInput(pstream As Pointer, inputDevice As Integer, inputDriverInfo As Pointer, bufferSize As Integer, time_proc As Pointer, time_info As Pointer) As Integer ' PmError Pm_OpenOutput (PortMidiStream **stream, PmDeviceID outputDevice, void *outputDriverInfo, long bufferSize, PmTimeProcPtr time_proc, void *time_info, long latency) ' Open Output device. Private Extern Pm_OpenOutput(pstream As Pointer, outputDevice As Integer, outputDriverInfo As Pointer, bufferSize As Integer, time_proc As Pointer, latency As Long) As Integer ' PmError Pm_SetFilter( PortMidiStream* stream, int32_t filters ) ' Sets filters on an open input stream to drop selected input types. Private Extern Pm_SetFilter(pstream As Pointer, filters As Integer) As Integer ' PmError Pm_Poll( PortMidiStream *stream) ' Tests whether input is available. Private Extern Pm_Poll(pstream As Pointer) As Boolean ' int Pm_Read( PortMidiStream *stream, PmEvent *buffer, int32_t length ) ' Retrieves midi data into a buffer, and returns the number of events read. Private Extern Pm_Read(pstream As Pointer, buffer As PmEvent, lenght As Integer) As Integer ' PmError Pm_Write( PortMidiStream *stream, PmEvent *buffer, int32_t length ) ' Writes midi data from a buffer. Private Extern Pm_Write(pstream As Pointer, buffer As PmEvent, lenght As Integer) As Integer ' PmError Pm_Close( PortMidiStream* stream ) ' Closes a midi stream, flushing any pending buffers. Private Extern Pm_Close(pstream As Pointer) As Integer ' PmError Pm_Terminate( void ) ' Library termination function. Private Extern Pm_Terminate() As Integer Public Sub Main() Dim def_in, def_out, err, i As Integer Dim info As PmDeviceInfo Dim def As String Dim midi_in, midi_out As Pointer Print "Dispositivi Midi e loro porte disponibili:\n" def_in = Pm_GetDefaultInputDeviceID() def_out = Pm_GetDefaultOutputDeviceID() For i = 0 To Pm_CountDevices() - 1 info = Pm_GetDeviceInfo(i) If info.inputI > 0 Then def = IIf(i = def_in, "default ", Null) Print i; ": "; String@(info.interf); " "; String@(info.name); " ("; def; "input)" def = Null Endif If info.outputI > 0 Then def = IIf(i = def_out, "default ", Null) Print i; ": "; String@(info.interf); " "; String@(info.name); " ("; def; "output)" Endif Next ' Attende che sia inserito il numero del dispositivo Midi, da cui si riceverranno i dati Midi. Print "\nInserire il numero del dispositivo Midi, dal quale si riceveranno i dati Midi..." Input s Print "Porta del dispositivo Midi scelta: "; s err = Pm_OpenInput(VarPtr(midi_in), Val(s), 0, 128, 0, 0) If err Then Print Pm_GetErrorText(err) Chiude() Endif ' Attende che sia inserito il numero del dispositivo Midi, al quale si invieranno i dati Midi. Print "\nInserire il numero del dispositivo Midi, al quale si invieranno i dati Midi..." Input s Print "Porta del dispositivo Midi scelta: "; s err = Pm_OpenOutput(VarPtr(midi_out), Val(s), 0, 512, 0, 0) If err Then Print Pm_GetErrorText(err) Chiude() Endif s = Null ' Filtriamo i dati Midi ricevuti che non ci interessano: Pm_SetFilter(midi_in, PM_FILT_ACTIVE Or PM_FILT_CLOCK Or PM_FILT_SYSEX) Print "\nMidi Monitor pronto...\n" Print "Assicurarsi di aver connesso le porte dei dispositivi Midi coinvolti !" Intercetta_Messaggi(midi_in, midi_out) ' Va in chiusura: Chiude(midi_out) End Private Procedure Intercetta_Messaggi(midIn As Pointer, midEx As Pointer) Dim pe As New PmEvent Dim status, count As Integer Print "\n\nMidi Monitor pronto...\n\nStatus", "nota", "velocità" ' Riceve i dati Midi dal dispositivo Midi, leggendoli dalla sua porta in Uscita: While True status = Pm_Poll(midIn) If status = True Then count = Pm_Read(midIn, pe, 1) If count > 0 Then ' Volendo, possiamo stampare nella console i dati Midi ricevuti: Print (pe.message And &FF) And &f, (pe.message \ CInt(2 ^ 8)) And 255, (pe.message \ CInt(2 ^ 16)) And 255 ' Invia i dati al dispositivo Midi, scrivendoli sulla sua porta in Entrata: Pm_Write(midEx, pe, 1) Else ' Va in chiusura: Chiude(midEx) Error.Raise("Errore nella ricezione dei Messaggi Midi:" & Pm_GetErrorText(count)) Endif Endif Wend End Private Procedure Chiude(midi As Pointer) Pt_Close(midi) Pm_Terminate() Quit End