Differenze tra le versioni di "Conoscere con le funzioni esterne di TSE3 le porte Midi disponibili nel sistema"

Da Gambas-it.org - Wikipedia.
(Creata pagina con 'La libreria '''TSE3''' (''Trax Sequencer Engine version 3.00'') è un motore sequencer ''open source'' scritto in C++. Utilizzando alcune sue funzioni esterne, è possibile c...')
 
 
(7 versioni intermedie di uno stesso utente non sono mostrate)
Riga 3: Riga 3:
 
Utilizzando alcune sue funzioni esterne, è possibile conoscere le porte Midi, e loro caratteristiche, appartenenti agli applicativi Client di Alsa disponibili nel sistema.
 
Utilizzando alcune sue funzioni esterne, è possibile conoscere le porte Midi, e loro caratteristiche, appartenenti agli applicativi Client di Alsa disponibili nel sistema.
  
Mostriamo di seguito un possibile codice che fa uso della Classe ''MidiScheduler'' per individuare le porte disponibili ed attive nel sistema. Poiché la libreria ''TSE3'', come già accennato, è critta 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 ''TSE3'', 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 ''TSE3'', bensì tutte in quella sola principale, si è cercato un escamotage (come si potrà facilmente notare) per individuare e gestire ogni singola funzione esterna necessaria.
+
Mostriamo di seguito un possibile codice che fa uso della Classe ''MidiScheduler'' per individuare le porte disponibili ed attive nel sistema. Poiché la libreria ''TSE3'', 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 ''TSE3'', 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 ''TSE3'', bensì tutte in quella sola principale, si è cercato un escamotage (come si potrà facilmente notare) per individuare e gestire ogni singola funzione esterna necessaria.
  
La libreria esterna, da noi scritta, il cui sorgente in linguaggio C++ chiameremo ad esempio ''libadhoc.c'' è la seguente:
+
La libreria esterna, da noi scritta, il cui sorgente in linguaggio C++ chiameremo ad esempio ''libadhoc.cpp'' è la seguente:
 
  #include <sstream>
 
  #include <sstream>
 
  #include "tse3/MidiScheduler.h"
 
  #include "tse3/MidiScheduler.h"
Riga 17: Riga 17:
 
   
 
   
 
  int main(int v, char **c, char **s) {
 
  int main(int v, char **c, char **s) {
 +
 +
  int r = 0;
 
    
 
    
  if (v==0)
 
    *c = (char *) sch->implementationName();
 
 
  if (v==1)
 
    *c = (char *) sch->numPorts();
 
     
 
 
   std::vector<int> portNums;
 
   std::vector<int> portNums;
 
   sch->portNumbers(portNums);
 
   sch->portNumbers(portNums);
Riga 33: Riga 29:
 
   strValue >> port;
 
   strValue >> port;
 
   
 
   
 
+
<FONT color=gray>/* ''Individua la funzione esterna da utilizzare sulla base del valore passato da Gambas alla variabile "v"'' */</font>
   if (v==2)
+
   switch (v) {
     *c = (char *) portNums[port];
+
    case 0:
   
+
      *c = (char *) sch->implementationName();
  if (v==3)
+
      break;
    *c = (char *) sch->portType(portNums[port]);
+
    case 1:
   
+
      *c = (char *) sch->numPorts();
  if (v==4)
+
      break;
    *c = (char *) sch->portName(portNums[port]);
+
     case 2:
   
+
      *c = (char *) portNums[port];
  if (v==5)
+
      break;
    *c = (char *) sch->portReadable(portNums[port]);
+
    case 3:
   
+
      *c = (char *) sch->portType(portNums[port]);
  if (v==6)
+
      break;
     *c = (char *) sch->portWriteable(portNums[port]);
+
    case 4:
+
      *c = (char *) sch->portName(portNums[port]);
+
      break;
   return (0);
+
    case 5:
 +
      *c = (char *) sch->portReadable(portNums[port]);
 +
      break;
 +
    case 6:
 +
      *c = (char *) sch->portWriteable(portNums[port]);
 +
      break;
 +
     case 7:
 +
      *c = (char *) sch->portInternal(portNums[port]);
 +
      break;
 +
    default:
 +
      r = -1;
 +
      break;
 +
  }
 +
 
 +
   return r;
 
   
 
   
 
  }
 
  }
Riga 56: Riga 66:
  
  
Il codice dell'applicativo Gambas sarà invece il seguente:
+
Il codice dell'applicativo Gambas, che tra l'altro prevede anche una ''ListBox'' posta sul ''Form'', sarà invece il seguente:
 
  Private numeroPorte As Byte
 
  Private numeroPorte As Byte
 
  Private p2 As Pointer
 
  Private p2 As Pointer
Riga 117: Riga 127:
 
     Else
 
     Else
 
       ListBox1.Add("          Non scrivibile")
 
       ListBox1.Add("          Non scrivibile")
 +
    Endif
 +
 +
    err = main(7, VarPtr(p1), p2)
 +
    If err <> 0 Then Error.Raise("Errore nella chiamata della funzione esterna 'main()' !")
 +
    If Val("&" & CStr(p1)) Then
 +
      ListBox1.Add("          Destinazione: Interna")
 +
    Else
 +
      ListBox1.Add("          Destinazione: Esterna")
 
     Endif
 
     Endif
 
     ListBox1.Add(" ")
 
     ListBox1.Add(" ")
Riga 123: Riga 141:
 
   
 
   
 
   
 
   
  <FONT color=gray>' ''Va in chiusura liberando memoria precedentemente allocata:''</font>
+
  <FONT color=gray>' ''Va in chiusura liberando la memoria precedentemente allocata:''</font>
 
   Free(p2)
 
   Free(p2)
 
   
 
   
 
  '''End'''
 
  '''End'''
 +
 +
 +
 +
=Riferimenti=
 +
[1] [http://tse3.sourceforge.net Il sito di TSE3]

Versione attuale delle 12:13, 26 lug 2014

La libreria TSE3 (Trax Sequencer Engine version 3.00) è un motore sequencer open source scritto in C++.

Utilizzando alcune sue funzioni esterne, è possibile conoscere le porte Midi, e loro caratteristiche, appartenenti agli applicativi Client di Alsa disponibili nel sistema.

Mostriamo di seguito un possibile codice che fa uso della Classe MidiScheduler per individuare le porte disponibili ed attive nel sistema. Poiché la libreria TSE3, 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 TSE3, 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 TSE3, bensì tutte in quella sola principale, si è cercato un escamotage (come si potrà facilmente notare) per individuare e gestire 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 "tse3/MidiScheduler.h"


using namespace std;

TSE3::MidiSchedulerFactory factory;
TSE3::MidiScheduler *sch = factory.createScheduler();


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

  int r = 0;
 
  std::vector<int> portNums;
  sch->portNumbers(portNums);
     
/* Converte un valore di tipo "char *" in un "Intero" */
  std::stringstream strValue;
  strValue << (char *)s;
  size_t port;
  strValue >> port;

/* Individua la funzione esterna da utilizzare sulla base del valore passato da Gambas alla variabile "v" */
  switch (v) {
    case 0:
      *c = (char *) sch->implementationName();
      break;
    case 1:
      *c = (char *) sch->numPorts();
      break;
    case 2:
      *c = (char *) portNums[port];
      break;
    case 3:
      *c = (char *) sch->portType(portNums[port]);
      break;
    case 4:
      *c = (char *) sch->portName(portNums[port]);
      break;
    case 5:
      *c = (char *) sch->portReadable(portNums[port]);
      break;
    case 6:
      *c = (char *) sch->portWriteable(portNums[port]);
      break;
    case 7:
      *c = (char *) sch->portInternal(portNums[port]);
      break;
    default:
      r = -1;
      break;
  }
  
  return r;

}

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 una ListBox posta sul Form, sarà invece il seguente:

Private numeroPorte As Byte
Private p2 As Pointer

Library "/tmp/libadhoc"

Private Extern main(vI As Integer, po1 As Pointer, po2 As Pointer) As Integer


Public Sub Form_Open()

 Dim p1 As Pointer
 Dim err As Integer
 Dim numPorta As Byte

   
' Compiliamo la libreria esterna condivisa da noi scritta in C++ :
  Shell "g++ -o /tmp/libadhoc.so " & Application.Path &/ "libadhoc.cpp -shared -fPIC -ltse3" Wait
   

  err = main(0, VarPtr(p1), 0)
  If err <> 0 Then Error.Raise("Errore nella chiamata della funzione esterna 'main()' !")
  ListBox1.Add("Nome implementazione:  " & String@(p1))

  err = main(1, VarPtr(p1), 0)
  If err <> 0 Then Error.Raise("Errore nella chiamata della funzione esterna 'main()' !")
  ListBox1.Add("                Numero porte: " & CStr(p1))
  ListBox1.Add(" ")
  numeroPorte = Val(CStr(p1))
 
   
  For numPorta = 0 To numeroPorte - 1

    p2 = Alloc(CStr(numPorta))
   
    err = main(2, VarPtr(p1), p2)
    If err <> 0 Then Error.Raise("Errore nella chiamata della funzione esterna 'main()' !")
    ListBox1.Add("   -------Numero porta: " & Val("&" & CStr(p1)))
   
    err = main(3, VarPtr(p1), p2)
    If err <> 0 Then Error.Raise("Errore nella chiamata della funzione esterna 'main()' !")
    ListBox1.Add("           Tipo porta: " & String@(p1))
   
    err = main(4, VarPtr(p1), p2)
    If err <> 0 Then Error.Raise("Errore nella chiamata della funzione esterna 'main()' !")
    ListBox1.Add("           Nome porta: " & String@(p1))
  
    err = main(5, VarPtr(p1), p2)
    If err <> 0 Then Error.Raise("Errore nella chiamata della funzione esterna 'main()' !")
    If Val("&" & CStr(p1)) Then
      ListBox1.Add("           Leggibile ")
    Else
      ListBox1.Add("           Non leggibile")
    Endif
   
    err = main(6, VarPtr(p1), p2)
    If err <> 0 Then Error.Raise("Errore nella chiamata della funzione esterna 'main()' !")
    If Val("&" & CStr(p1)) Then
      ListBox1.Add("           Scrivibile")
    Else
      ListBox1.Add("           Non scrivibile")
    Endif

    err = main(7, VarPtr(p1), p2)
    If err <> 0 Then Error.Raise("Errore nella chiamata della funzione esterna 'main()' !")
    If Val("&" & CStr(p1)) Then
      ListBox1.Add("           Destinazione: Interna")
    Else
      ListBox1.Add("           Destinazione: Esterna")
    Endif
    ListBox1.Add(" ")
   
  Next


' Va in chiusura liberando la memoria precedentemente allocata:
  Free(p2)

End


Riferimenti

[1] Il sito di TSE3