Differenze tra le versioni di "Eseguire un file WAV con le funzioni esterne del API di LibAo"
Da Gambas-it.org - Wikipedia.
(4 versioni intermedie di uno stesso utente non sono mostrate) | |||
Riga 1: | Riga 1: | ||
'''Libao''' è una libreria multi-piattaforma che permette ai programmi di inviare dati audio PCM ai dispositivi audio nativi su una vasta gamma di piattaforme. | '''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. | ||
===1<SUP>a</sup> modalità=== | ===1<SUP>a</sup> modalità=== | ||
− | + | Library "libao:4.1.1" | |
− | + | ||
− | |||
Public Struct ao_sample_format | Public Struct ao_sample_format | ||
bits As Integer <FONT color=gray>' ''bits per sample''</font> | bits As Integer <FONT color=gray>' ''bits per sample''</font> | ||
Riga 27: | Riga 26: | ||
option_count As Integer | option_count As Integer | ||
End Struct | End Struct | ||
− | |||
− | |||
Private Const AO_FMT_LITTLE As Integer = 1 | Private Const AO_FMT_LITTLE As Integer = 1 | ||
Riga 59: | Riga 56: | ||
− | + | Public Sub Main() | |
Dim device As Pointer | Dim device As Pointer | ||
Riga 70: | Riga 67: | ||
Dim b As Byte | Dim b As Byte | ||
− | + | fileWAV = "<FONT color=darkgreen>''/percorso/del/file.wav''</font>" | |
− | + | fl = Open fileWAV For Read | |
<FONT color=gray>' ''Inizializza la libreria 'libao':''</font> | <FONT color=gray>' ''Inizializza la libreria 'libao':''</font> | ||
− | + | ao_initialize() | |
<FONT color=gray>' ''Imposta il driver audio come predefinito:''</font> | <FONT color=gray>' ''Imposta il driver audio come predefinito:''</font> | ||
− | + | default_driver = ao_default_driver_id() | |
<FONT color=gray>' ''Raccoglie alcune informazioni del dipositivo audio di sistema utilizzato:''</font> | <FONT color=gray>' ''Raccoglie alcune informazioni del dipositivo audio di sistema utilizzato:''</font> | ||
− | + | 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____________________________" | |
<FONT color=gray>' ''Imposta le caratteristiche del file wav caricato, leggendole da esso:''</font> | <FONT color=gray>' ''Imposta le caratteristiche del file wav caricato, leggendole da esso:''</font> | ||
− | + | 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 | |
<FONT color=gray>' ''Mostra alcune informazioni generali sul file wav caricato:''</font> | <FONT color=gray>' ''Mostra alcune informazioni generali sul file wav caricato:''</font> | ||
− | + | 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 | End With | ||
<FONT color=gray>' ''Apre il driver:''</font> | <FONT color=gray>' ''Apre il driver:''</font> | ||
− | device = ao_open_live(default_driver, ao_sf, | + | device = ao_open_live(default_driver, ao_sf, 0) |
− | If | + | If device == 0 Then Error.Raise("Errore nell'apertura del dispositivo audio !") |
− | + | buffer = New Byte[Lof(fl)] | |
<FONT color=gray>' ''Ciclo per l'elaborazione dell'audio:''</font> | <FONT color=gray>' ''Ciclo per l'elaborazione dell'audio:''</font> | ||
− | + | For i = 1 To (buffer.Count) / 1024 | |
− | |||
<FONT color=gray>' ''Carica i dati audio nel vettore di tipo "Byte[]":''</font> | <FONT color=gray>' ''Carica i dati audio nel vettore di tipo "Byte[]":''</font> | ||
− | + | buffer.Read(fl, 0, 1024) | |
− | |||
<FONT color=gray>' ''Esegue i dati audio:''</font> | <FONT color=gray>' ''Esegue i dati audio:''</font> | ||
− | + | 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 | |
− | + | ||
− | |||
− | |||
<FONT color=gray>' ''Va in chiusura:''</font> | <FONT color=gray>' ''Va in chiusura:''</font> | ||
− | + | fl.Close | |
− | + | ao_shutdown() | |
− | + | End | |
− | |||
===2<SUP>a</sup> modalità=== | ===2<SUP>a</sup> modalità=== | ||
− | La seconda modalità fa uso sia della libreria principale "''libao.so.4. | + | 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 | Public Struct ao_sample_format | ||
bits As Integer <FONT color=gray>' ''bits per sample''</font> | bits As Integer <FONT color=gray>' ''bits per sample''</font> | ||
Riga 164: | Riga 156: | ||
matrix As Pointer <FONT color=gray>' ''input channel location/ordering''</font> | matrix As Pointer <FONT color=gray>' ''input channel location/ordering''</font> | ||
End Struct | End Struct | ||
− | |||
− | |||
− | |||
Private Const AO_FMT_LITTLE As Integer = 1 | Private Const AO_FMT_LITTLE As Integer = 1 | ||
Riga 214: | Riga 203: | ||
− | + | Public Sub Main() | |
Dim device As Pointer | Dim device As Pointer | ||
Riga 223: | Riga 212: | ||
Dim fl As File | Dim fl As File | ||
− | + | fileWAV = "<FONT color=darkgreen>''/percorso/del/file.wav''</font>" | |
− | + | fl = Open fileWAV For Read | |
<FONT color=gray>' ''Inizializza la libreria 'libao':''</font> | <FONT color=gray>' ''Inizializza la libreria 'libao':''</font> | ||
− | + | ao_initialize() | |
<FONT color=gray>' ''Imposta il driver audio come predefinito:''</font> | <FONT color=gray>' ''Imposta il driver audio come predefinito:''</font> | ||
− | + | default_driver = ao_default_driver_id() | |
<FONT color=gray>' ''Imposta le caratteristiche del file wav caricato, leggendole da esso:''</font> | <FONT color=gray>' ''Imposta le caratteristiche del file wav caricato, leggendole da esso:''</font> | ||
− | + | 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 | |
<FONT color=gray>' ''Mostra alcune informazioni generali sul file wav caricato:''</font> | <FONT color=gray>' ''Mostra alcune informazioni generali sul file wav caricato:''</font> | ||
Print "File wav: "; fileWAV | Print "File wav: "; fileWAV | ||
Riga 248: | Riga 237: | ||
Print "Frequenza: "; .rate; " hertz" | Print "Frequenza: "; .rate; " hertz" | ||
rbc = .rate * .bits * .channels | rbc = .rate * .bits * .channels | ||
− | Print "Durata: "; | + | Print "Durata: "; Time(0, 0, 0, ((Lof(fl) * 8) / rbc) * 1000) |
Print | Print | ||
− | + | End With | |
− | + | Wait 0.1 | |
<FONT color=gray>' ''Apre il driver:''</font> | <FONT color=gray>' ''Apre il driver:''</font> | ||
− | + | 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)] | |
<FONT color=gray>' ''Riportiamo il puntatore interno del flusso del file a zero:''</font> | <FONT color=gray>' ''Riportiamo il puntatore interno del flusso del file a zero:''</font> | ||
− | + | Seek #fl, 0 | |
<FONT color=gray>' ''Ciclo per l'elaborazione dell'audio:''</font> | <FONT color=gray>' ''Ciclo per l'elaborazione dell'audio:''</font> | ||
− | + | For i = 1 To (buffer.Count) / 1024 | |
− | |||
<FONT color=gray>' ''Carica i dati audio nel vettore di tipo "Byte[]":''</font> | <FONT color=gray>' ''Carica i dati audio nel vettore di tipo "Byte[]":''</font> | ||
− | + | buffer.Read(fl, 0, 1024) | |
− | |||
<FONT color=gray>' ''Esegue i dati audio:''</font> | <FONT color=gray>' ''Esegue i dati audio:''</font> | ||
− | + | 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 | |
− | |||
− | |||
<FONT color=gray>' ''Va in chiusura:''</font> | <FONT color=gray>' ''Va in chiusura:''</font> | ||
− | + | fl.Close | |
− | + | ao_plugin_close(device) | |
− | + | ao_plugin_device_clear(device) | |
− | + | ao_shutdown() | |
− | + | End | |
Versione attuale delle 18:47, 13 gen 2024
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" ' 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