Conoscere con le funzioni esterne di RtAudio i dispositivi audio presenti nel sistema

Da Gambas-it.org - Wikipedia.

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


E' possibile con alcune funzioni esterne della libreria RtAudio conoscere i dispositivi audio presenti nel sistema e le loro caratteristiche principali. Sarà necessario avere installata nel proprio sistema la libreria condivisa: librtaudio.so.4.0.12


Mostriamo di seguito un possibile codice che mostra in una TextArea i dispositivi audio presenti nel sistema. Poiché la libreria RtAudio, 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 RtAudio, 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 RtAudio, 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 "RtAudio.h"


unsigned int devices;


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

  RtAudio audio;
  RtAudio::DeviceInfo info;
  std::string a, du, de, nf;
  std::stringstream n, o, e, d, sr;
  unsigned int i, j;


 /* Determina il numero di dispositivi audio presenti nel sistema */
  if (strcmp((char *)s[0], "getDeviceCount()") == 0) {
    return devices = audio.getDeviceCount();
  }


  if (strcmp((char *)s[0], "getDeviceInfo()") == 0) {
    for ( unsigned int i=0; i<devices; i++ ) {
      info = audio.getDeviceInfo( i );
      if ( info.probed == true ) {
        n << i;
        o << info.outputChannels;
        e << info.inputChannels;
        d << info.duplexChannels;
        if (info.isDefaultOutput) du = "(Canale di Uscita predefinito)";
        if (info.isDefaultInput) de = "(Canale di Entrata predefinito)";
        if ( info.nativeFormats > 0 ) {
          nf = " - formati di dati audio supportati:";
          if ( info.nativeFormats & RTAUDIO_SINT8 )
            nf = nf + "\n   8-bit int";
          if ( info.nativeFormats & RTAUDIO_SINT16 )
            nf = nf + "\n   16-bit int";
          if ( info.nativeFormats & RTAUDIO_SINT24 )
            nf = nf + "\n   24-bit int";
          if ( info.nativeFormats & RTAUDIO_SINT32 )
           nf = nf + "\n   32-bit int";
          if ( info.nativeFormats & RTAUDIO_FLOAT32 )
            nf = nf + "\n   32-bit float";
          if ( info.nativeFormats & RTAUDIO_FLOAT64 )
            nf = nf + "\n   64-bit float";
        }
/* Vengono unite le stringhe di tipo base */
        a = a + "\n" + n.str() + "  " + info.name + ":" +
        + "\n - " + du + "\n - " + de +
        + "\n - numero massimo di canali di Uscita = " + o.str() +
        + "\n - numero massimo di canali di Entrata = " + e.str() + 
        + "\n - numero massimo di canali simultanei 'entrata/uscita' supportati = " + d.str() +
        + "\n" + nf +
        + "\n - frequenze di campionamento supportate: \n";
       
        for (j=0; j<info.sampleRates.size(); j++) {
          sr << info.sampleRates[j];
          a = a + "   Hz " + sr.str() + "\n";
          sr.str("");
        }

/* Si cancella l'attuale contenuto delle seguenti variabili di tipo stringa */
        n.str("");
        o.str("");
        e.str("");
        d.str("");
        du = "";
        de = "";
        nf = "";
        sr.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 numDisp As Integer
 Dim p As Pointer


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

  p = Alloc("getDeviceCount()")
  numDisp = main(0, VarPtr(p))
  If numDisp = 0 Then Error.Raise("Impossibile trovare dispositivi audio !")

  p = Alloc("getDeviceInfo()")
  main(0, VarPtr(p))
  TextArea1.Text = "Numero dispositivi audio trovati: " & numDisp & Chr(10)
  TextArea1.Text &= String@(p)

  TextArea1.Pos = 0
  
End


Public Sub Button1_Click()

 Quit

End



Riferimenti