Differenze tra le versioni di "Generare un file WAV da dati audio grezzi con le funzioni esterne del API di LibAo"

Da Gambas-it.org - Wikipedia.
Riga 1: Riga 1:
 
Per l'uso delle risorse della libreria ''libao'' bisognerà richiamare nel proprio applicativo Gambas la libreria attualmente alla versione: "''libao.so.4.0.0''" .
 
Per l'uso delle risorse della libreria ''libao'' bisognerà richiamare nel proprio applicativo Gambas la libreria attualmente alla versione: "''libao.so.4.0.0''" .
  
Di seguito un possibile codice per generare con le risorse della libreria ''libao'' un file wav utilizzando i dati audio grezzi creati per ottenere un'onda sinusoidale:
+
Di seguito un possibile codice per generare con le risorse della libreria ''libao'' un file wav utilizzando i dati audio grezzi ottenuti per creare un'onda sinusoidale:
  '''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>
 
   rate As Integer            <FONT color=gray>' ''samples per second (in a single channel)''</font>
 
   rate As Integer            <FONT color=gray>' ''samples per second (in a single channel)''</font>
Riga 8: Riga 8:
 
   byte_format As Integer      <FONT color=gray>' ''Byte ordering in sample, see constants below''</font>
 
   byte_format As Integer      <FONT color=gray>' ''Byte ordering in sample, see constants below''</font>
 
   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''' ao_sf As Struct Ao_sample_format
 
 
 
   
 
   
 
  Library "libao:4.0.0"
 
  Library "libao:4.0.0"
 
   
 
   
  '''Private''' Const AO_FMT_LITTLE As Integer = 1
+
  Private Const AO_FMT_LITTLE As Integer = 1
 
   
 
   
 
  <FONT color=gray>' ''void ao_initialize(void)''
 
  <FONT color=gray>' ''void ao_initialize(void)''
 
  ' ''library setup''</font>
 
  ' ''library setup''</font>
  '''Private''' Extern ao_initialize()
+
  Private Extern ao_initialize()
 
   
 
   
 
  <FONT color=gray>' ''int ao_driver_id(void)''
 
  <FONT color=gray>' ''int ao_driver_id(void)''
 
  ' ''driver information''</font>
 
  ' ''driver information''</font>
  '''Private''' Extern ao_driver_id(s As String) As Integer
+
  Private Extern ao_driver_id(s As String) As Integer
 
   
 
   
 
  <FONT color=gray>' ''int ao_default_driver_id(void)''
 
  <FONT color=gray>' ''int ao_default_driver_id(void)''
 
  ' ''driver information''</font>
 
  ' ''driver information''</font>
  '''Private''' Extern ao_default_driver_id() As Integer
+
  Private Extern ao_default_driver_id() As Integer
 
   
 
   
 
  <FONT color=gray>' ''ao_device* ao_open_file(int driver_id, const char *filename, int overwrite,  ao_sample_format *format, ao_option *options)''
 
  <FONT color=gray>' ''ao_device* ao_open_file(int driver_id, const char *filename, int overwrite,  ao_sample_format *format, ao_option *options)''
 
  ' ''Open a file for audio output. The file format is determined by the audio driver used.
 
  ' ''Open a file for audio output. The file format is determined by the audio driver used.
 
  ' ''on-NULL pointer inicates success. This pointer must be passed in subsequent calls to ao_play() and ao_close().''</font>
 
  ' ''on-NULL pointer inicates success. This pointer must be passed in subsequent calls to ao_play() and ao_close().''</font>
  '''Private''' Extern ao_open_file(driver_id As Integer, filename As String, overwrite As Integer, fmt As Ao_sample_format, options As Pointer) As Pointer
+
  Private Extern ao_open_file(driver_id As Integer, filename As String, overwrite As Integer, fmt As Ao_sample_format, options As Pointer) As Pointer
 
+
 
<FONT color=gray>' ''ao_device * ao_open_live(int driver_id, ao_sample_format *format, ao_option *option)''
 
' ''driver information''</font>
 
'''Private''' Extern ao_open_live(driver_id As Integer, fmt As Ao_sample_format, option As Pointer) As Pointer
 
 
<FONT color=gray>' ''int ao_play(ao_device *device, char *output_samples, uint_32 num_bytes)''
 
' ''Write samples to the device. Channels are interleaved. 1 indicates success.''</font>
 
'''Private''' Extern ao_play(device As Pointer, output_samples As Byte[], num_bytes As Integer) As Integer
 
 
 
  <FONT color=gray>' ''int ao_close(ao_device *device)''
 
  <FONT color=gray>' ''int ao_close(ao_device *device)''
 
  ' ''Chiude il dispositivo audio''</font>
 
  ' ''Chiude il dispositivo audio''</font>
  '''Private''' Extern ao_close(device As Pointer) As Integer
+
  Private Extern ao_close(device As Pointer) As Integer
 
   
 
   
 
  <FONT color=gray>' ''void ao_shutdown(void)''</font>
 
  <FONT color=gray>' ''void ao_shutdown(void)''</font>
 
  <FONT color=gray>' ''library teardown''</font>
 
  <FONT color=gray>' ''library teardown''</font>
  '''Private''' Extern ao_shutdown()
+
  Private Extern ao_shutdown()
 
   
 
   
 
   
 
   
 
  '''Public''' Sub Main()
 
  '''Public''' Sub Main()
 
   
 
   
  Dim deviceWav, device As Pointer
+
  Dim ao_sf As New Ao_sample_format
  Dim driver, default_driver, buf_size As Integer
+
  Dim deviceWav, device As Pointer
  Dim buffer As Byte[]
+
  Dim driver, default_driver, buf_size As Integer
  Dim freq As Single = 440.0
+
  Dim buffer As Byte[]
 +
  Dim freq As Single = 440.0
 
    
 
    
 
   
 
   
 
  <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 dell'audio in uscita:''</font>
 
  <FONT color=gray>' ''Imposta le caratteristiche dell'audio in uscita:''</font>
    With ao_sf
+
  With ao_sf
      .bits = 16
+
    .bits = 16
      .channels = 2
+
    .channels = 2
      .rate = 44100
+
    .rate = 44100
      .byte_format = AO_FMT_LITTLE
+
    .byte_format = AO_FMT_LITTLE
    End With  
+
  End With  
+
 
    buf_size = ao_sf.bits / 8 * ao_sf.channels * ao_sf.rate
 
 
 
   
 
   
 
  <FONT color=gray>' '''''Crea il file wav'''''
 
  <FONT color=gray>' '''''Crea il file wav'''''
 
   
 
   
 
  ' ''Imposta il driver audio per il wav:''</font>
 
  ' ''Imposta il driver audio per il wav:''</font>
    driver = ao_driver_id("wav")
+
  driver = ao_driver_id("wav")
 
   
 
   
    deviceWav = ao_open_file(driver, "/tmp/file.wav", 1, VarPtr(ao_sf), Null)
+
  deviceWav = ao_open_file(driver, "/tmp/file.wav", 1, ao_sf, Null)
    If IsNull(deviceWav) Then Error.Raise("Errore nell'apertura del dispositivo audio !")
+
  If IsNull(deviceWav) Then Error.Raise("Errore nell'apertura del dispositivo audio !")
 
    
 
    
    buffer = elaboraSuono(deviceWav, buf_size, freq)
+
  buffer = ElaboraOnda(ao_sf, freq)
 
   
 
   
+
  Crea_File_Wav(buffer)
<FONT color=gray>' '''''Esegue i dati audio'''''
 
 
' ''Imposta il driver audio come predefinito:''</font>
 
    default_driver = ao_default_driver_id()
 
 
      
 
      
<FONT color=gray>' ''Apre il driver:''</font>
 
    device = ao_open_live(default_driver, VarPtr(ao_sf), Null)
 
    If IsNull(device) Then Error.Raise("Errore nell'apertura del dispositivo audio !")
 
 
    audio_file(device, buffer, buf_size)
 
 
      
 
      
 
 
 
  <FONT color=gray>' ''Va in chiusura:''</font>
 
  <FONT color=gray>' ''Va in chiusura:''</font>
    buffer.Clear()
+
  buffer.Clear()
    ao_close(device)
+
  ao_close(device)
    ao_shutdown()
+
  ao_shutdown()
 
   
 
   
 
  '''End'''
 
  '''End'''
 
   
 
   
 
   
 
   
  '''Private''' Function elaboraSuono(dev_audio As Pointer, buff_dim As Integer, frequenza As Integer) As Byte[]
+
  '''Private''' Function ElaboraOnda(aosf As Ao_sample_format, frequenza As Integer) As Byte[]
 
    
 
    
   Dim i, sample As Integer
+
   Dim buff_dim, i, sample As Integer
 
   Dim buffer As Byte[]
 
   Dim buffer As Byte[]
 
    
 
    
 
  <FONT color=gray>' ''Elabora il suono:''</font>
 
  <FONT color=gray>' ''Elabora il suono:''</font>
    buff_dim = ao_sf.bits / 8 * ao_sf.channels * ao_sf.rate
+
  buff_dim = aosf.bits / 8 * aosf.channels * aosf.rate
 
   
 
   
    buffer = New Byte[buff_dim]
+
  buffer = New Byte[buff_dim]
 
      
 
      
    For i = 0 To ao_sf.rate - 1
+
  For i = 0 To aosf.rate - 1
 
   
 
   
 
  <FONT color=gray>' ''Genera l'onda sinusoidale:''</font>
 
  <FONT color=gray>' ''Genera l'onda sinusoidale:''</font>
      sample = CInt(0.75 * 32768.0 * Sin(2 * Pi * frequenza * CSingle(i / ao_sf.rate)))
+
    sample = CInt(0.75 * 32768.0 * Sin(2 * Pi * frequenza * CSingle(i / aosf.rate)))
 
   
 
   
 
  <FONT color=gray>' ''Imposta il medesimo suono nei canali destro e sinistro:''</font>
 
  <FONT color=gray>' ''Imposta il medesimo suono nei canali destro e sinistro:''</font>
      buffer[4 * i] = sample And &FF
+
    buffer[4 * i] = sample And &FF
      buffer[4 * i + 2] = sample And &FF
+
    buffer[4 * i + 2] = sample And &FF
      buffer[4 * i + 1] = Shr(sample, 8) And &FF
+
    buffer[4 * i + 1] = Shr(sample, 8) And &FF
      buffer[4 * i + 3] = Shr(sample, 8) And &FF
+
    buffer[4 * i + 3] = Shr(sample, 8) And &FF
 
        
 
        
    Next
+
  Next
   
+
   
    audio_file(dev_audio, buffer, buff_dim)
+
  Return buffer
   
 
    Return buffer
 
 
      
 
      
 
  '''End'''
 
  '''End'''
 
   
 
   
 
   
 
   
  '''Private''' Procedure audio_file(da As Pointer, buf As Byte[], bd As Integer)
+
  '''Private''' Procedure Crea_File_Wav(buf As Byte[])
 
    
 
    
   Dim err As Integer
+
   Dim s As String
 +
   
 +
  s = buf.ToString(0, buf.Count)
 +
  If IsNull(s) Then Error.Raise("Dati audio grezzi inesistenti !")
 
      
 
      
    err = ao_play(da, buf, bd)
+
  File.Save("/tmp/file.wav", File.Load("/tmp/file.wav") & s)
    If err < 1 Then Error.Raise("Errore nell'esecuzione dei dati audio !")
 
 
    
 
    
 
  '''End'''
 
  '''End'''

Versione delle 09:31, 9 mag 2015

Per l'uso delle risorse della libreria libao bisognerà richiamare nel proprio applicativo Gambas la libreria attualmente alla versione: "libao.so.4.0.0" .

Di seguito un possibile codice per generare con le risorse della libreria libao un file wav utilizzando i dati audio grezzi ottenuti per creare un'onda sinusoidale:

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
 

Library "libao:4.0.0"

Private Const AO_FMT_LITTLE As Integer = 1

' void ao_initialize(void)
' library setup
Private Extern ao_initialize()

' int ao_driver_id(void)
' driver information
Private Extern ao_driver_id(s As String) As Integer

' int ao_default_driver_id(void)
' driver information
Private Extern ao_default_driver_id() As Integer

' ao_device* ao_open_file(int driver_id, const char *filename, int overwrite,  ao_sample_format *format, ao_option *options)
' Open a file for audio output. The file format is determined by the audio driver used.
' on-NULL pointer inicates success. This pointer must be passed in subsequent calls to ao_play() and ao_close().
Private Extern ao_open_file(driver_id As Integer, filename As String, overwrite As Integer, fmt As Ao_sample_format, options As Pointer) As Pointer
  
' int ao_close(ao_device *device)
' Chiude il dispositivo audio
Private Extern ao_close(device As Pointer) As Integer

' void ao_shutdown(void)
' library teardown
Private Extern ao_shutdown()


Public Sub Main()

 Dim ao_sf As New Ao_sample_format
 Dim deviceWav, device As Pointer
 Dim driver, default_driver, buf_size As Integer
 Dim buffer As Byte[]
 Dim freq As Single = 440.0
 

' Inizializza la libreria 'libao':
  ao_initialize()
   
' Imposta il driver audio come predefinito:
  default_driver = ao_default_driver_id()

' Imposta le caratteristiche dell'audio in uscita:
  With ao_sf
    .bits = 16
    .channels = 2
    .rate = 44100
    .byte_format = AO_FMT_LITTLE
  End With 
 

' Crea il file wav

' Imposta il driver audio per il wav:
  driver = ao_driver_id("wav")

  deviceWav = ao_open_file(driver, "/tmp/file.wav", 1, ao_sf, Null)
  If IsNull(deviceWav) Then Error.Raise("Errore nell'apertura del dispositivo audio !")
  
  buffer = ElaboraOnda(ao_sf, freq)

  Crea_File_Wav(buffer)
   
   
' Va in chiusura:
  buffer.Clear()
  ao_close(device)
  ao_shutdown()

End


Private Function ElaboraOnda(aosf As Ao_sample_format, frequenza As Integer) As Byte[]
 
 Dim buff_dim, i, sample As Integer
 Dim buffer As Byte[]
 
' Elabora il suono:
  buff_dim = aosf.bits / 8 * aosf.channels * aosf.rate

  buffer = New Byte[buff_dim]
   
  For i = 0 To aosf.rate - 1

' Genera l'onda sinusoidale:
    sample = CInt(0.75 * 32768.0 * Sin(2 * Pi * frequenza * CSingle(i / aosf.rate)))

' Imposta il medesimo suono nei canali destro e sinistro:
    buffer[4 * i] = sample And &FF
    buffer[4 * i + 2] = sample And &FF
    buffer[4 * i + 1] = Shr(sample, 8) And &FF
    buffer[4 * i + 3] = Shr(sample, 8) And &FF
     
  Next
    
  Return buffer
   
End


Private Procedure Crea_File_Wav(buf As Byte[])
 
 Dim s As String
   
  s = buf.ToString(0, buf.Count)
  If IsNull(s) Then Error.Raise("Dati audio grezzi inesistenti !")
   
  File.Save("/tmp/file.wav", File.Load("/tmp/file.wav") & s)
 
End


Riferimenti

[1] L'API di LibAo