Intercettare dati Midi grezzi con le funzioni esterne del API di RtMidi

Da Gambas-it.org - Wikipedia.
Versione del 26 lug 2014 alle 12:28 di Vuott (Discussione | contributi) (Creata pagina con 'La libreria ''RtMidi'' è un insieme di classi C++ che fornisce funzionalità per la gestione dei dati Midi in entrata ed in uscita. E' possibile con alcune funzioni esterne...')

(diff) ← Versione meno recente | Versione attuale (diff) | Versione più recente → (diff)

La libreria RtMidi è un insieme di classi C++ che fornisce funzionalità per la gestione dei dati Midi in entrata ed in uscita.


E' possibile con alcune funzioni esterne della libreria RtMidi intercettare i dati Midi grezzi provenienti da un dispositivo Midi. Sarà necessario avere installata nel proprio sistema la libreria condivisa: librtmidi.so.1.2.0.1


Mostriamo di seguito un possibile codice che intercetta i dati Midi grezzi provenienti da un dispositivo esterno e li scrive in console. Poiché la libreria RtMidi, come già accennato, è scritta in C++, non è possibile richiamare direttamente nel modo consueto con il comando Extern le sue necessarie funzioni esterne. Si rende, pertanto, necessario scrivere in C++ in un'apposita libreria condivisa, da noi realizzata, la parte di codice che richiama le predette funzioni esterne della libreria RtMidi, lasciando al codice dell'applicativo Gambas quanto più possibile e in particolare una funzione di coordinamento dell'intero processo. V'è da aggiungere che nell'esempio che segue, poiché non è stato possibile scrivere in autonome routine le varie funzioni esterne della libreria RtMidi, bensì tutte in quella sola principale, si è cercato un escamotage (come si potrà facilmente notare) per individuare e gestire da Gambas ogni singola funzione esterna necessaria.

La libreria esterna, da noi scritta, il cui sorgente in linguaggio C++ chiameremo ad esempio libadhoc.cpp è la seguente:

#include <iostream>
#include <cstdlib>
#include "RtMidi.h"
#include <string.h>


RtMidiIn *rtmidi = 0;

void callback( double, std::vector< unsigned char > *, void * );


int main(int c, char** s) {

  unsigned int i = 0, nPorte;

  std::string nomePorta;

  rtmidi = new RtMidiIn();

  if (strcmp((char *)s[0], "getPortCount()") == 0) {
    nPorte = rtmidi->getPortCount();
     std::cout << "Porte Midi in Entrata trovate: " << nPorte  << '\n' << std::endl;
     return nPorte;
   }
 
 
   if (strcmp((char *)s[0], "getPortName()") == 0) {
   
     if ( nPorte == 1 ) {
       std::cout << "\nApertura della porta: " << rtmidi->getPortName() << std::endl;
     }
     else { 
       for ( i=0; i<nPorte; i++ ) {
       nomePorta = rtmidi->getPortName(i);
       std::cout << " Porta di Entrata #" << i << ": " << nomePorta << '\n';
       }
     }

   }

   
   if (strcmp((char *)s[0], "openPort()") == 0) {
     rtmidi->openPort( c );
     rtmidi->setCallback( &callback );
   }
   
   
/* Imposta i valori booleani, se deve ignorare rispettivamente i messaggi: sysex, timing, active sensing*/
   if (strcmp((char *)s[0], "ignoreTypes()") == 0) {
     rtmidi->ignoreTypes( false, true, true);
   }
 
 return (0);
 
}


void callback( double tempodelta, std::vector< unsigned char > *messaggio, void */*userData*/ ) {
  unsigned int nByte = messaggio->size();
  for ( unsigned int j=0; j<nBytes; j++ )
    std::cout << "Byte " << j << " = " << (int)messaggio->at(j) << ", ";
  if ( nByte > 0 )
    std::cout << "timestamp = " << tempodelta << std::endl;
}

Tale sorgente, da noi scritto, della libreria condivisa sarà posto ad esempio nella cartella "Dati" dell'applicativo.


Il codice dell'applicativo Gambas, che tra l'altro prevede anche un Button posto sul Form, sarà invece il seguente:

Public Sub Form_Open()

 Dim ss As New String[4]
 Dim numPorte, porta As Integer

  Shell "g++ -o /tmp/libadhoc.so " & Application.Path &/ "libadhoc.cpp -shared -fPIC 'librtmidi.so.1.2.0.1'" Wait

  ss[0] = "getPortCount()"
  numPorte = main(0, ss)
  If numPorte = 0 Then Error.Raise("Impossibile trovare porte Midi in Entrata !")

  ss[0] = "getPortName()"
  main(0, ss)
  
  porta = Val(InputBox("Porte Midi di Entrata trovate: " & numPorte & "\nScegli una porta:"))
  
  ss[0] = "openPort()"
  main(porta, ss)
   
  ss[0] = "ignoreTypes()"
  main(0, ss)

End


Public Sub Button1_Click()

 Quit

End



Riferimenti