Conoscere con le funzioni esterne di RtMidi le porte Midi disponibili nel sistema

Da Gambas-it.org - Wikipedia.
Versione del 27 lug 2014 alle 09:44 di Vuott (Discussione | contributi)

(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 conoscere le porte Midi di Entrata e di Uscita presenti nel sistema. Sarà necessario avere installata nel proprio sistema la libreria condivisa: librtmidi.so.1.2.0.1


Mostriamo di seguito un possibile codice che mostra in una TextArea le porte Midi di Entrata e di Uscita presenti nel sistema. 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 <sstream>
#include <string.h>
#include <cstdlib>
#include "RtMidi.h"


RtMidiIn *midiIn = 0;
RtMidiOut *midiOut = 0;
unsigned int nPorteIn, nPorteEx;


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

  std::string nomePortaIn, nomePortaOut, a;
  std::stringstream n;
  unsigned int i;


  midiIn = new RtMidiIn();
  midiOut = new RtMidiOut();

  if (strcmp((char *)s[0], "PorteEntrata") == 0) {
    nPorteIn = midiIn->getPortCount();
    return nPorteIn;
  }


  if (strcmp((char *)s[0], "PorteUscita") == 0) {
    nPorteEx = midiOut->getPortCount();
    return nPorteEx;
  }

 
  if (strcmp((char *)s[0], "NomePorteIn") == 0) {
    for ( i=0; i<nPorteIn; i++ ) {
      nomePortaIn = midiIn->getPortName(i);
/* Si converte la variabile "i" di tipo unsigned int in tipo stringa */
      n << i;
/* Vengono unite le stringhe di tipo base */
      a = a + "\n" + n.str() + " " + nomePortaIn;
/* Si cancella l'attuale contenuto della variabile di tipo stringa "n" */
      n.str("");
    }
/* La variabile base stringa "a" viene convertita nel tipo 'char*'
   affinché possa essere restituita al codice Gambas attraverso il parametro "char** s" della routine "main()" */
    char* ritornare = strcpy((char*)malloc(a.length()+1), a.c_str());
    *s =  ritornare;
  }


  if (strcmp((char *)s[0], "NomePorteEx") == 0) {
    for ( i=0; i<nPorteEx; i++ ) { 
      nomePortaOut = midiOut->getPortName(i);
      /* Si converte la variabile "i" di tipo unsigned int in tipo stringa */
      n << i;
/* Vengono unite le stringhe di tipo base */
      a = a + "\n" + n.str() + " " + nomePortaOut;
/* Si cancella l'attuale contenuto della variabile di tipo stringa "n" */
      n.str("");
    }
/* La variabile base stringa "a" viene convertita nel tipo 'char*'
   affinché possa essere restituita al codice Gambas attraverso il parametro "char** s" della routine "main()" */
    char* ritornare = strcpy((char*)malloc(a.length()+1), a.c_str());
    *s =  ritornare;
   }
  

  return (0);
 
}

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 ed una TextArea posti sul Form, sarà invece il seguente:

Library "/tmp/libadhoc"

Private Extern main(a As Integer, po As Pointer) As Integer


Public Sub Form_Open()

 Dim numPorteIn, numPorteEx As Integer
 Dim p As Pointer

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

  p = Alloc("PorteEntrata")
  numPorteIn = main(0, VarPtr(p))
  If numPorteIn = 0 Then Error.Raise("Impossibile trovare porte Midi in Entrata !")
 
  p = Alloc("PorteUscita")
  numPorteEx = main(0, VarPtr(p))
  If numPorteEx = 0 Then Error.Raise("Impossibile trovare porte Midi in Entrata !")

  p = Alloc("NomePorteIn")
  main(0, VarPtr(p))
  TextArea1.Text = "Numero porte Midi di Entrata trovate: " & numPorteIn & Chr(10)
  TextArea1.Text &= String@(p)
     
  p = Alloc("NomePorteEx")
  main(0, VarPtr(p))
  TextArea1.Text &= "\n\n\nNumero porte Midi di Uscita trovate: " & numPorteEx & Chr(10)
  TextArea1.Text &= String@(p)
  
End


Public Sub Button1_Click()

 Quit

End



Riferimenti