Audio ed Alsa: introduzione

Da Gambas-it.org - Wikipedia.

DEFINIZIONE

ALSA (acronimo di Advanced Linux Sound Architecture) è un componente del kernel Linux che permette, al posto dell’originario OSS (Open Sound System), di gestire le schede audio mediante dispositivi (device) "driver". Il sistema ALSA è esso stesso un Dispositivo che offre - per quel che qui ci interessa - una modalità uniforme di connettere flussi dati audio tra diversi programmi e tra vari dispositivi hardware.


Struttura del sistema ALSA

Il sistema ALSA è composto da diversi sub-sistemi, ciascuno dei quali esercita una propria specifica funzione controllando un particolare tipo di flusso di dati per il suono. Il sub-sistema che controlla il flusso dei dati di tipo audio è denominato: PCM (Pulse Code Modulation) |1|. Pertanto, nel redigere un programma Gambas di gestione dei dati audio, dovremo sempre considerare questo particolare sub-sistema "PCM" , facente parte del più ampio e complesso dispositivo ALSA.


Apertura del sub-sistema PCM

Per poter interagire con il sub-sistema PCM di ALSA, sia nel caso di riproduzione sonora che di registrazione, bisognerà:

  • aprire il sub-sistema PCM mediante un handle (una "maniglia" d'apertura), che verrà instaurato ed impostato con una specifica funzione delle API di ALSA;
  • specificare la direzione del flusso PCM, che può essere la riproduzione oppure la registrazione;
  • specificare, infine, la dimensione del buffer, la frequenza di campionamento, il formato di dati PCM.


Funzionamento basilare di un'applicazione audio

Sostanzialmente il funzionamento di un'applicazione audio può essere così sintetizzato:

  • apertura del dispositivo PCM;
  • impostazione dei parametri del dispositivo audio;
  • riproduzione di dati audio, oppure registrazione di dati audio;
  • chiusura del dispositivo PCM.


Cenni sull'interfaccia audio

Un'interfaccia audio è un dispositivo che consente a un computer di ricevere e inviare dati audio dal e verso l'esterno. All'interno del computer, i dati audio è rappresentato un flusso di bit, come qualsiasi altro tipo di dati. Tuttavia, l'interfaccia audio può inviare e ricevere audio sia come un segnale analogico (una tensione variabile nel tempo) o come un segnale digitale (flusso di bit). In entrambi i casi, l'insieme di bit utilizzati dal computer per rappresentare un suono particolare dovrà essere trasformato prima che sia inviato all'esterno, ed analogamente, il segnale esterno ricevuto dall'interfaccia audio dovrà essere trasformato prima che possa essere utilizzato dal computer. L'interfaccia audio svolge essenzialmente questi due predetti compiti.

Nell'interfaccia audio v'è una area denominata "hardware buffer". Non appena il segnale audio giunge dall' esterno, l'interfaccia lo converte in un flusso di bit utilizzabili dal computer e lo memorizza nel settore dell'hardware buffer destinato all'invio dei dati al computer. Nel momento in cui viene raccolta una sufficiente quantità di dati nel hardware buffer, l'interfaccia audio comunica al computer che ci sono dati. Un processo simile avviene in senso inverso per i dati che vengono inviati dal computer verso l'esterno.
L'interfaccia audio comunica al computer che v'è spazio nell'hardware buffer, e il computer conseguentemente procede a memorizzare quei dati nel buffer. Successivamente l'interfaccia audio converte i bit nel formato adeguato per inviarli all'esterno; e procede quindi al loro invio.
L'interfaccia audio utilizza questo buffer come un "buffer circolare". Quando si arriva alla fine del buffer, continua tornando in modo circolare all'inizio del processo.

Affinché questo processo funzioni correttamente, bisogna tenere conto di alcuni fattori:

  • il formato che deve essere utilizzato dall'interfaccia audio nella conversione del flusso di bit ed il segnale audio inviato all'esterno;
  • la frequenza alla quale devono essere comunicati i campioni tra l'interfaccia e il computer;
  • la quantità di dati (e/o di spazio) necessaria prima che il dispositivo effettui la prevista comunicazione al computer;
  • la dimensione del hardware buffer.

I primi due fattori sono fondamentali per la definizione della qualità dei dati audio. Gli ultimi due condizionano "latenza" del segnale audio. Il termine "latenza" si riferisce al ritardo tra i dati che arrivano alla interfaccia audio dall'esterno, e disponibili per il computer ("latenza in entrata") ed i dati che provengono dal computer, e che sono inviati all'esterno ("latenza in uscita").


Tipi e Formati PCM di ALSA

ALSA utilizza diversi tipi e formati di dati PCM, che possono essere facilmente visualizzati mediante il seguente codice:

Library "libasound:2.0.0"

Private Const SND_PCM_STREAM_LAST As Byte = 1
Private Const SND_PCM_ACCESS_LAST As Byte = 4
Private Const SND_PCM_FORMAT_LAST As Byte = 49
Private Const SND_PCM_SUBFORMAT_LAST As Byte = 0
Private Const SND_PCM_STATE_LAST As Byte = 8


' const char * snd_pcm_stream_name (const snd_pcm_stream_t stream)
' Get name of PCM stream type.
Private Extern snd_pcm_stream_name(snd_pcm_stream_t As Integer) As String

' const char * snd_pcm_access_name (const snd_pcm_access_t _access)
' Get name of PCM access type.
Private Extern snd_pcm_access_name(snd_pcm_access_t As Integer) As String

' const char * snd_pcm_format_name (const snd_pcm_format_t format)
' Get name of PCM sample format.
Private Extern snd_pcm_format_name(snd_pcm_format_t As Integer) As String

' const char * snd_pcm_format_description (const snd_pcm_format_t format)
' Get description of PCM sample format.
Private Extern snd_pcm_format_description(snd_pcm_format_t As Integer) As String

' const char * snd_pcm_subformat_name (const snd_pcm_subformat_t subformat)
' Get name of PCM sample subformat.
Private Extern snd_pcm_subformat_name(snd_pcm_subformat_t As Integer) As String

' const char * snd_pcm_subformat_description (const snd_pcm_subformat_t subformat)
' Get description of PCM sample subformat.
Private Extern snd_pcm_subformat_description(snd_pcm_subformat_t As Integer) As String

' const char * snd_pcm_state_name (const snd_pcm_state_t state)
' Get name of PCM state.
Private Extern snd_pcm_state_name(snd_pcm_state_t As Integer) As String


Public Sub Main()

 Dim i As Integer

 Print "=== Tipi e Formati PCM di ALSA ==="

 Print "\nTipi di flusso dati PCM:"
 For i = 0 To SND_PCM_STREAM_LAST
   Print "        "; snd_pcm_stream_name(i)
 Next
 
 Print "\nTipi di accesso PCM:"
 For i = 0 To SND_PCM_ACCESS_LAST
   Print "        "; snd_pcm_access_name(i)
 Next
 
 Print "\nFormati PCM:"
 For i = 0 To SND_PCM_FORMAT_LAST
   If snd_pcm_format_name(i) <> Null Then
     Print "        "; snd_pcm_format_name(i), snd_pcm_format_description(i)
   Endif
 Next
  
 Print "\nSottoformati PCM:"
 For i = 0 To SND_PCM_SUBFORMAT_LAST
   Print "        "; snd_pcm_subformat_name(i), "("; snd_pcm_subformat_description(i); ")"
 Next
 
 Print "\n Stati PCM:"
 For i = 0 To SND_PCM_STATE_LAST
   Print "        "; snd_pcm_state_name(i)
 Next

End


Note

[1] Il termine PCM sta sostanzialmente a significare una modalità di rappresentazione del segnale audio da analogico in digitale.