Differenze tra le versioni di "Eseguire un file WAV con le funzioni esterne del API di LibAo"

Da Gambas-it.org - Wikipedia.
 
(2 versioni intermedie di uno stesso utente non sono mostrate)
Riga 2: Riga 2:
  
 
E' necessario avere installata nel sistema e richiamare in Gambas la libreria condivisa: "''libao.so.4.1.1'' "
 
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.
 
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"
 
  Library "libao:4.1.1"
Riga 58: Riga 56:
 
    
 
    
 
   
 
   
  '''Public''' Sub Main()
+
  Public Sub Main()
 
   
 
   
 
   Dim device As Pointer
 
   Dim device As Pointer
Riga 69: Riga 67:
 
   Dim b As Byte
 
   Dim b As Byte
 
   
 
   
  fileWAV = "<FONT color=gray>''/percorso/del/file.wav''</font>"
+
  fileWAV = "<FONT color=darkgreen>''/percorso/del/file.wav''</font>"
 
   
 
   
  fl = Open fileWAV For Read
+
  fl = Open fileWAV For Read
 
    
 
    
 
  <FONT color=gray>' ''Inizializza la libreria 'libao':''</font>
 
  <FONT color=gray>' ''Inizializza la libreria 'libao':''</font>
  ao_initialize()
+
  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()
+
  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:"
+
  Print "Informazioni sul dispositivo audio utilizzato:"
  info = ao_driver_info(default_driver)
+
  info = ao_driver_info(default_driver)
  With info
+
  With info
    Print "Tipo:                  "; IIf(.type = 1, "Live Output", "File output")
+
    Print "Tipo:                  "; IIf(.type = 1, "Live Output", "File output")
    Print "Nome:                  "; String@(.name)
+
    Print "Nome:                  "; String@(.name)
    Print "Abbreviazione:          "; String@(.short_name)
+
    Print "Abbreviazione:          "; String@(.short_name)
    Print "Realizzatore:          "; String@(.author)
+
    Print "Realizzatore:          "; String@(.author)
    Print "Commento:              "; String@(.comment)
+
    Print "Commento:              "; String@(.comment)
    Select Case .preferred_byte_format
+
    Select Case .preferred_byte_format
      Case AO_FMT_LITTLE
+
      Case AO_FMT_LITTLE
        fmt = "little-endian order"
+
        fmt = "little-endian order"
      Case AO_FMT_BIG
+
      Case AO_FMT_BIG
        fmt = "big-endian order"
+
        fmt = "big-endian order"
      Case AO_FMT_NATIVE
+
      Case AO_FMT_NATIVE
        fmt = "native ordering of the computer"
+
        fmt = "native ordering of the computer"
    End Select
+
    End Select
    Print "Formato byte preferito: "; fmt
+
    Print "Formato byte preferito: "; fmt
    Print "Priorità:              "; .priority
+
    Print "Priorità:              "; .priority
    Print "Opzioni:                ";
+
    Print "Opzioni:                ";
    For b = 1 To .option_count
+
    For b = 1 To .option_count
      Print String@(Pointer@(.options + CInt(8 * b))); ", ";
+
      Print String@(Pointer@(.options + CInt(8 * b))); ", ";
    Next
+
    Next
  End With
+
  End With
  Print "\n____________________________"
+
  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
+
  With ao_sf
    Seek #fl, 34
+
    Seek #fl, 34
    .bits = Read #fl As Short
+
    .bits = Read #fl As Short
    Seek #fl, 22
+
    Seek #fl, 22
    .channels = Read #fl As Short
+
    .channels = Read #fl As Short
    .rate = Read #fl As Integer
+
    .rate = Read #fl As Integer
    .byte_format = info.preferred_byte_format
+
    .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 "File wav:    "; fileWAV
    Print "Dimensione:  "; Lof(fl); " byte"
+
  Print "Dimensione:  "; Lof(fl); " byte"
    Print "Risoluzione: "; .bits; " bit"
+
  Print "Risoluzione: "; .bits; " bit"
    Print "Canali:      "; .channels
+
  Print "Canali:      "; .channels
    Print "Frequenza:  "; .rate; " hertz"
+
  Print "Frequenza:  "; .rate; " hertz"
    rbc = .rate * .bits * .channels
+
  rbc = .rate * .bits * .channels
    Print "Durata:      "; Date(0, 0, 0, 0, 0, 0, ((Lof(fl) * 8) / rbc) * 1000)
+
  Print "Durata:      "; Time(0, 0, 0, ((Lof(fl) * 8) / rbc) * 1000)
    Print
+
  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, Null)
+
   device = ao_open_live(default_driver, ao_sf, 0)
   If device = 0 Then Error.Raise("Errore nell'apertura del dispositivo audio !")
+
   If device == 0 Then Error.Raise("Errore nell'apertura del dispositivo audio !")
 
      
 
      
  buffer = New Byte[Lof(fl)]
+
  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
+
  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)
+
    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)
+
    err = ao_play(device, buffer.Data, 1024)
    If err < 1 Then Error.Raise("Errore nell'esecuzione dei dati audio !")
+
    If err < 1 Then Error.Raise("Errore nell'esecuzione dei dati audio !")
    Write #File.out, "\r" & CStr(Date(0, 0, 0, 0, 0, 0, ((Seek(fl) * 8) / rbc) * 1000))
+
    Write #File.out, "\r" & CStr(Time(0, 0, 0, ((Seek(fl) * 8) / rbc) * 1000))
     
+
  Next
  Next
+
 
 
 
 
 
  <FONT color=gray>' ''Va in chiusura:''</font>
 
  <FONT color=gray>' ''Va in chiusura:''</font>
  fl.Close
+
  fl.Close
  ao_shutdown()
+
  ao_shutdown()
 
   
 
   
  '''End'''
+
  End
 
 
  
  
Riga 210: Riga 203:
 
   
 
   
 
   
 
   
  '''Public''' Sub Main()
+
  Public Sub Main()
 
   
 
   
 
   Dim device As Pointer
 
   Dim device As Pointer
Riga 219: Riga 212:
 
   Dim fl As File
 
   Dim fl As File
 
   
 
   
  fileWAV = "<FONT color=gray>''/percorso/del/file.wav''</font>"
+
  fileWAV = "<FONT color=darkgreen>''/percorso/del/file.wav''</font>"
 
   
 
   
  fl = Open fileWAV For Read
+
  fl = Open fileWAV For Read
 
    
 
    
 
  <FONT color=gray>' ''Inizializza la libreria 'libao':''</font>
 
  <FONT color=gray>' ''Inizializza la libreria 'libao':''</font>
  ao_initialize()
+
  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()
+
  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
+
  With ao_sf
    Seek #fl, 34
+
    Seek #fl, 34
    .bits = Read #fl As Short
+
    .bits = Read #fl As Short
    Seek #fl, 22
+
    Seek #fl, 22
    .channels = Read #fl As Short
+
    .channels = Read #fl As Short
    .rate = Read #fl As Integer
+
    .rate = Read #fl As Integer
    .byte_format = AO_FMT_LITTLE
+
    .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 244: Riga 237:
 
     Print "Frequenza:  "; .rate; " hertz"
 
     Print "Frequenza:  "; .rate; " hertz"
 
     rbc = .rate * .bits * .channels
 
     rbc = .rate * .bits * .channels
     Print "Durata:      "; Date(0, 0, 0, 0, 0, 0, ((Lof(fl) * 8) / rbc) * 1000)
+
     Print "Durata:      "; Time(0, 0, 0, ((Lof(fl) * 8) / rbc) * 1000)
 
     Print
 
     Print
  End With
+
  End With
 
    
 
    
  Sleep 0.1
+
  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, Null)
+
  device = ao_open_live(default_driver, ao_sf, 0)
  If device = 0 Then Error.Raise("Errore nell'apertura del dispositivo audio !")
+
  If device == 0 Then Error.Raise("Errore nell'apertura del dispositivo audio !")
 
   
 
   
  err = ao_plugin_test()
+
  err = ao_plugin_test()
  If err = 0 Then Error.Raise("Il driver audio ha bisogno che vengano impostate alcune opzioni !")
+
  If err == 0 Then Error.Raise("Il driver audio ha bisogno che vengano impostate alcune opzioni !")
   
+
 
  ao_plugin_device_init(device)
+
  ao_plugin_device_init(device)
 
    
 
    
  ao_plugin_open(device, ao_sf)
+
  ao_plugin_open(device, ao_sf)
 
   
 
   
  buffer = New Byte[Lof(fl)]
+
  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
+
  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
+
  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)
+
    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)
+
    err = ao_plugin_play(device, buffer.Data, 1024)
    If err < 1 Then Error.Raise("Errore nell'esecuzione dei dati audio !")
+
    If err < 1 Then Error.Raise("Errore nell'esecuzione dei dati audio !")
    Write #File.out, "\r" & CStr(Date(0, 0, 0, 0, 0, 0, ((Seek(fl) * 8) / rbc) * 1000))
+
    Write #File.out, "\r" & CStr(Time(0, 0, 0, ((Seek(fl) * 8) / rbc) * 1000))
     
+
  Next
  Next
 
 
   
 
   
 
 
 
  <FONT color=gray>' ''Va in chiusura:''</font>
 
  <FONT color=gray>' ''Va in chiusura:''</font>
  fl.Close
+
  fl.Close
  ao_plugin_close(device)
+
  ao_plugin_close(device)
  ao_plugin_device_clear(device)
+
  ao_plugin_device_clear(device)
  ao_shutdown()
+
  ao_shutdown()
 
   
 
   
  '''End'''
+
  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


Riferimenti