Eseguire un file WAV mediante le funzioni esterne del API di PulseAudio
Vai alla navigazione
Vai alla ricerca
Per la esigua quantità di funzioni necessarie e la loro semplicità d'uso mostreremo di seguito direttamente un codice esemplificativo, ma debitamente spiegato, con il quale eseguire un file WAV.
E' necessario avere installata nel sistema e richiamare in Gambas la libreria condivisa: "libpulse-simple.so.0.1.1".
Library "libpulse-simple:0.1.1"
' Dichiariamo una "Struttura" per passare i valori dei campioni audio necessari per l'esecuzione dei dati audio del file WAV:
Public Struct pa_sample_spec
formato As Integer
rate As Integer
channels As Byte
End Struct
Private Const PA_STREAM_PLAYBACK As Byte = 1
Private Const PA_SAMPLE_S16LE As Byte = 3 ' Signed 16 Bit PCM, little endian (PC)
' pa_simple* pa_simple_new (const char *server, const char *name, pa_stream_direction_t dir, const char *dev, const char *stream_name, const pa_sample_spec *ss, const pa_channel_map *map, const pa_buffer_attr *attr, int *error)
' Crea una connessione col server sonoro.
Private Extern pa_simple_new(server$ As String, name As String, direct As Byte, dev As String, stream_name As String, ss As Pa_sample_spec, map As Pointer, attr As Pointer, err As Pointer) As Pointer
' int pa_simple_write (pa_simple *s, const void *data, size_t bytes, int *error)
' Scrive una certa quantità di dati nel server sonoro.
Private Extern pa_simple_write(sP As Pointer, data As Pointer, bytes As Integer, err As Pointer) As Integer
' int pa_simple_drain (pa_simple *s, int *error)
' Attende sino a quando tutti i dati scritti nel server sonoro vengono eseguiti.
Private Extern pa_simple_drain(sP As Pointer, err As Pointer) As Integer
' void pa_simple_free (pa_simple *s)
' Chiude e libera la connessione con il server sonoro.
Private Extern pa_simple_free(sP As Pointer)
Public Sub Main()
Dim pss As New Pa_sample_spec
Dim DimBuffer As Short = 1024
Dim bit As Short
Dim fileWAV As String
Dim p As Pointer
Dim dimensione, obr As Integer
Dim buf As Byte[]
Dim fl As File
fileWAV = ">/percorso/del/file.wav"
fl = Open fileWAV For Read
dimensione = Lof(fl)
' Vengono assegnati ai rispettivi membri della "Struttura" i necessari valori per l'esecuzione del file wav.
' Vengono, altresì, mostrate alcune informazioni sul file wav:
With pss
.formato = PA_SAMPLE_S16LE
Seek #fl, 22
.channels = Read #fl As Short
.rate = Read #fl As Integer
Print "File wav: "; fileWAV
Print "Canali: "; .channels
Print "Frequenza: "; .rate; " hertz"
Seek #fl, 34
bit = Read #fl As Short
Print "Risoluzione: "; bit; " bit"
obr = .rate * bit * .channels
Print "Durata: "; Time(0, 0, 0, ((dimensione * 8) / obr) * 1000)
End With
Print
' Viene quindi creata una connessione con il server sonoro per il flusso di dati audio da eseguire.
' Riguardo ai parametri impostati nella seguente funzione si precisa che:
' - NUll: viene usato il server sonoro di default;
' - "nome qualsiasi": il nome dell'applicazione;
' - PA_STREAM_PLAYBACK: stabilisce che il flusso sarà in uscita, ossia in esecuzione di un file WAV;
' - Null: viene usato il dispositivo sonoro di default;
' - "testo qualsiasi": una testo descrittivo del flusso dati audio del file;
' - pss: le caratteristiche dei campioni audio del flusso di dati;
' - Null: viene usata la mappatura dei canali di default;
' - Null: vengono usati attributi di buffering di default;
' - Null: vengono ignorati i codici di errore sollevati.
p = pa_simple_new(Null, "nome qualsiasi", PA_STREAM_PLAYBACK, Null, "testo qualsiasi", pss, 0, 0, 0)
If p == 0 Then Error.Raise("Impossible inizializzare la libreria 'Pulseaudio' !")
Seek #fl, 0
buf = New Byte[DimBuffer]
' Viene eseguito un ciclo per la lettura dei dati audio dal file, e per la successiva scrittura nel server sonoro:
Repeat
' Viene evitato l'errore di "Out of bound" nel vettore "buf[]":
If dimensione - Seek(fl) < DimBuffer Then DimBuffer = dimensione - Seek(fl)
' Usa un vettore di tipo "Byte[]", che viene ad ogni ciclo riempito da una quantità di dati pari al valore stabilito:
buf.Read(fl, 0, DimBuffer)
' La funzione "pa_simple_write" prevede un Puntatore al buffer contenente i dati da scrivere:
pa_simple_write(p, buf.Data, DimBuffer, 0)
' Mostra il tempo trascorso dall'inizio dell'esecuzione del file audio:
Write "\r" & CStr(Time(0, 0, 0, ((Seek(fl) * 8) / obr) * 1000))
Until Seek(fl) >= dimensione
pa_simple_drain(p, 0)
' Va in Chiusura:
Print "Esecuzione terminata !"
fl.Close
pa_simple_free(p)
End