Eseguire un file WAV con le funzioni esterne del API di LibAo
Vai alla navigazione
Vai alla ricerca
Libao è una libreria multi-piattaforma che permette ai programmi di inviare dati audio PCM ai dispositivi audio nativi su una vasta gamma di piattaforme.
E' necessario avere installata nel sistema e richiamare in Gambas la libreria condivisa: "libao.so.4.1.1 "
Possiamo utilizzare almeno due modalità per eseguire un file WAV.
1a modalità
Library "libao:4.1.1"
Public Struct ao_sample_format
bits As Integer ' bits per sample
rate As Integer ' samples per second (in a single channel)
channels As Integer ' number of audio channels
byte_format As Integer ' Byte ordering in sample, see constants below
matrix As Pointer ' input channel location/ordering
End Struct
Public Struct ao_info
type As Integer
name As Pointer
short_name As Pointer
author As Pointer
comment As Pointer
preferred_byte_format As Integer
priority As Integer
options As Pointer
option_count As Integer
End Struct
Private Const AO_FMT_LITTLE As Integer = 1
Private Const AO_FMT_BIG As Integer = 2
Private Const AO_FMT_NATIVE As Integer = 4
' void ao_initialize(void)
' Library setup.
Private Extern ao_initialize()
' int ao_default_driver_id(void)
' Driver information.
Private Extern ao_default_driver_id() As Integer
' ao_info *ao_driver_info(int driver_id)
' Get information about a particular driver.
Private Extern ao_driver_info(driver_id As Integer) As Ao_info
' ao_device * ao_open_live(int driver_id, ao_sample_format *format, ao_option *option)
' Open a live playback audio device for output.
Private Extern ao_open_live(driver_id As Integer, ao_format As Ao_sample_format, option As Pointer) As Pointer
' int ao_play(ao_device *device, char *output_samples, uint_32 num_bytes)
' Play a block of audio data to an open device.
Private Extern ao_play(device As Pointer, output_samples As Pointer, num_bytes As Integer) As Integer
' void ao_shutdown(void)
' Unloads all of the plugins and deallocates any internal data structures the library has created.
Private Extern ao_shutdown()
Public Sub Main()
Dim device As Pointer
Dim ao_sf As New Ao_sample_format
Dim info As Ao_info
Dim default_driver, i, err, rbc As Integer
Dim buffer As Byte[]
Dim fileWAV, fmt As String
Dim fl As File
Dim b As Byte
fileWAV = "/percorso/del/file.wav"
fl = Open fileWAV For Read
' Inizializza la libreria 'libao':
ao_initialize()
' Imposta il driver audio come predefinito:
default_driver = ao_default_driver_id()
' Raccoglie alcune informazioni del dipositivo audio di sistema utilizzato:
Print "Informazioni sul dispositivo audio utilizzato:"
info = ao_driver_info(default_driver)
With info
Print "Tipo: "; IIf(.type = 1, "Live Output", "File output")
Print "Nome: "; String@(.name)
Print "Abbreviazione: "; String@(.short_name)
Print "Realizzatore: "; String@(.author)
Print "Commento: "; String@(.comment)
Select Case .preferred_byte_format
Case AO_FMT_LITTLE
fmt = "little-endian order"
Case AO_FMT_BIG
fmt = "big-endian order"
Case AO_FMT_NATIVE
fmt = "native ordering of the computer"
End Select
Print "Formato byte preferito: "; fmt
Print "Priorità: "; .priority
Print "Opzioni: ";
For b = 1 To .option_count
Print String@(Pointer@(.options + CInt(8 * b))); ", ";
Next
End With
Print "\n____________________________"
' Imposta le caratteristiche del file wav caricato, leggendole da esso:
With ao_sf
Seek #fl, 34
.bits = Read #fl As Short
Seek #fl, 22
.channels = Read #fl As Short
.rate = Read #fl As Integer
.byte_format = info.preferred_byte_format
' Mostra alcune informazioni generali sul file wav caricato:
Print "File wav: "; fileWAV
Print "Dimensione: "; Lof(fl); " byte"
Print "Risoluzione: "; .bits; " bit"
Print "Canali: "; .channels
Print "Frequenza: "; .rate; " hertz"
rbc = .rate * .bits * .channels
Print "Durata: "; Time(0, 0, 0, ((Lof(fl) * 8) / rbc) * 1000)
Print
End With
' Apre il driver:
device = ao_open_live(default_driver, ao_sf, 0)
If device == 0 Then Error.Raise("Errore nell'apertura del dispositivo audio !")
buffer = New Byte[Lof(fl)]
' Ciclo per l'elaborazione dell'audio:
For i = 1 To (buffer.Count) / 1024
' Carica i dati audio nel vettore di tipo "Byte[]":
buffer.Read(fl, 0, 1024)
' Esegue i dati audio:
err = ao_play(device, buffer.Data, 1024)
If err < 1 Then Error.Raise("Errore nell'esecuzione dei dati audio !")
Write #File.out, "\r" & CStr(Time(0, 0, 0, ((Seek(fl) * 8) / rbc) * 1000))
Next
' Va in chiusura:
fl.Close
ao_shutdown()
End
2a modalità
La seconda modalità fa uso sia della libreria principale "libao.so.4.1.1", sia della libreria "libalsa.so".
Library "libao:4.1.1"
Public Struct ao_sample_format
bits As Integer ' bits per sample
rate As Integer ' samples per second (in a single channel)
channels As Integer ' number of audio channels
byte_format As Integer ' Byte ordering in sample, see constants below
matrix As Pointer ' input channel location/ordering
End Struct
Private Const AO_FMT_LITTLE As Integer = 1
' void ao_initialize(void)
' Library setup
Private Extern ao_initialize()
' int ao_default_driver_id(void)
' Driver information
Private Extern ao_default_driver_id() As Integer
' ao_device * ao_open_live(int driver_id, ao_sample_format *format, ao_option *option)
' Driver information
Private Extern ao_open_live(driver_id As Integer, fmt As Ao_sample_format, option As Pointer) As Pointer
' void ao_shutdown(void)
' Library teardown
Private Extern ao_shutdown()
Library "/usr/lib/x86_64-linux-gnu/ao/plugins-4/libalsa" ' In alcune distribuzioni Linux questa libreria potrebbe trovarsi nel percorso "/usr/lib/ao/plugins-4/libalsa.so")
' int ao_plugin_test()
' Determine if parameters are requires for this particular plugin.
Private Extern ao_plugin_test() As Integer
' int ao_plugin_device_init(ao_device *device)
' Initialize internal data structures.
Private Extern ao_plugin_device_init(ao_dev As Pointer) As Integer
' int ao_plugin_open(ao_device *device, ao_sample_format *format)
' Prepare the audio device for playback.
Private Extern ao_plugin_open(ao_dev As Pointer, fmt As Ao_sample_format) As Integer
' int ao_plugin_play(ao_device *device, const char *output_samples, uint_32 num_bytes)
' Play num_bytes of audio data.
Private Extern ao_plugin_play(ao_dev As Pointer, output_samples As Pointer, num_bytes As Integer) As Integer
' int ao_plugin_close(ao_device *device)
' Close the audio device.
Private Extern ao_plugin_close(ao_dev As Pointer) As Integer
' void ao_plugin_device_clear(ao_device *device)
' Free the internal data structures.
Private Extern ao_plugin_device_clear(ao_dev As Pointer)
Public Sub Main()
Dim device As Pointer
Dim ao_sf As New Ao_sample_format
Dim default_driver, i, err, rbc As Integer
Dim buffer As Byte[]
Dim fileWAV As String
Dim fl As File
fileWAV = "/percorso/del/file.wav"
fl = Open fileWAV For Read
' Inizializza la libreria 'libao':
ao_initialize()
' Imposta il driver audio come predefinito:
default_driver = ao_default_driver_id()
' Imposta le caratteristiche del file wav caricato, leggendole da esso:
With ao_sf
Seek #fl, 34
.bits = Read #fl As Short
Seek #fl, 22
.channels = Read #fl As Short
.rate = Read #fl As Integer
.byte_format = AO_FMT_LITTLE
' Mostra alcune informazioni generali sul file wav caricato:
Print "File wav: "; fileWAV
Print "Dimensione: "; Lof(fl); " byte"
Print "Risoluzione: "; .bits; " bit"
Print "Canali: "; .channels
Print "Frequenza: "; .rate; " hertz"
rbc = .rate * .bits * .channels
Print "Durata: "; Time(0, 0, 0, ((Lof(fl) * 8) / rbc) * 1000)
Print
End With
Wait 0.1
' Apre il driver:
device = ao_open_live(default_driver, ao_sf, 0)
If device == 0 Then Error.Raise("Errore nell'apertura del dispositivo audio !")
err = ao_plugin_test()
If err == 0 Then Error.Raise("Il driver audio ha bisogno che vengano impostate alcune opzioni !")
ao_plugin_device_init(device)
ao_plugin_open(device, ao_sf)
buffer = New Byte[Lof(fl)]
' Riportiamo il puntatore interno del flusso del file a zero:
Seek #fl, 0
' Ciclo per l'elaborazione dell'audio:
For i = 1 To (buffer.Count) / 1024
' Carica i dati audio nel vettore di tipo "Byte[]":
buffer.Read(fl, 0, 1024)
' Esegue i dati audio:
err = ao_plugin_play(device, buffer.Data, 1024)
If err < 1 Then Error.Raise("Errore nell'esecuzione dei dati audio !")
Write #File.out, "\r" & CStr(Time(0, 0, 0, ((Seek(fl) * 8) / rbc) * 1000))
Next
' Va in chiusura:
fl.Close
ao_plugin_close(device)
ao_plugin_device_clear(device)
ao_shutdown()
End