Generare un'onda sinusoidale con le funzioni esterne della libreria Libaubio

Da Gambas-it.org - Wikipedia.

La libreria Libaubio è progettata per l'estrazione di particolari elementi da segnali audio.

Per poter fruire in Gambas delle risorse di Libaubio, è necessario installare e richiamare la libreria dinamica e condivisa: "libaubio.so.4.0.0"


Mostriamo di seguito un esempio, nel quale verrà generata un'onda sinusoidale a Hz 440 ed i cui dati audio sono salvati in un file di tipo WAV:

Library "libaubio:4.0.0"

Public Struct fvec_t
  length As Integer
  data As Pointer
End Struct

' fvec_t * new_fvec(uint_t length)
' fvec_t buffer creation function.
Private Extern new_fvec(length As Integer) As Fvec_t

' aubio_sink_t * new_aubio_sink(char_t * uri, uint_t samplerate)
' Creates a new sink object.
Private Extern new_aubio_sink(uri As String, samplerate As Integer) As Pointer

' aubio_wavetable_t * new_aubio_wavetable(uint_t samplerate, uint_t hop_size)
' Create new wavetable object.
Private Extern new_aubio_wavetable(samplerate As Integer, hopsize As Integer) As Pointer

' uint_t aubio_wavetable_play(aubio_wavetable_t * o)
' Play sample from start.
Private Extern aubio_wavetable_play(aubio_wavetable As Pointer) As Integer

' uint_t aubio_wavetable_set_freq(aubio_wavetable_t * o, smpl_t freq)
' Set wavetable frequency.
Private Extern aubio_wavetable_set_freq(aubio_wavetable As Pointer, freq As Single) As Integer

' uint_t aubio_wavetable_stop(aubio_wavetable_t * o)
' Stop wavetable.
Private Extern aubio_wavetable_stop(aubio_wavetable As Pointer) As Integer

' void aubio_wavetable_do(aubio_wavetable_t * o, fvec_t * input, fvec_t * output)
' Adds the new samples from the playing wavetable to the output.
Private Extern aubio_wavetable_do(aubio_wavetable As Pointer, inp As Fvec_t, out As Fvec_t)

' void aubio_sink_do(aubio_sink_t * s, fvec_t * write_data, uint_t write)
' Writes monophonic vector of length hop_size to sink.
Private Extern aubio_sink_do(aubio_sink As Pointer, write_data As Fvec_t, writI As Integer)

' void del_aubio_wavetable(aubio_wavetable_t * o)
' Destroy aubio_wavetable_t object.
Private Extern del_aubio_wavetable(aubio_wavetable As Pointer)

' void del_aubio_sink(aubio_sink_t * s)
' Close sink and cleanup memory.
Private Extern del_aubio_sink(aubio_sink As Pointer)

' void del_fvec(fvec_t * s)
' fvec_t buffer deletion function.
Private Extern del_fvec(fvs As Fvec_t)


Public Sub Main()

 Dim hop_size, freq_camp, durata As Integer
 Dim n_frames, scrive, regione As Integer
 Dim frequenza As Single
 Dim vec As New Fvec_t
 Dim fileWAV As String
 Dim sink, wavetable As Pointer
 
  freq_camp = 44100
  hop_size = 256
  frequenza = 440
  fileWAV = "/percorso/del/file.wav"

  vec = new_fvec(hop_size)
   
  sink = new_aubio_sink(fileWAV, freq_camp)
   
  wavetable = new_aubio_wavetable(freq_camp, hop_size)
   
' Imposta la durata dell'onda (in questo caso 10 secondi):
  durata = 10 * freq_camp

  aubio_wavetable_play(wavetable)
  aubio_wavetable_set_freq(wavetable, frequenza)
   
  Repeat
    If (n_frames > durata / 1) And (regione < 1) Then
      aubio_wavetable_stop(wavetable)
      Inc regione
    Endif
    If (durata - n_frames) < (hop_size * 2) Then aubio_wavetable_stop(wavetable)
    If (durata - n_frames) < hop_size Then
      scrive = durata - n_frames
    Else
      scrive = hop_size
    Endif
    aubio_wavetable_do(wavetable, vec, vec)
    aubio_sink_do(sink, vec, scrive)
    n_frames += hop_size
    
' Mostra la durata dell'onda man mano che viene realizzato il suo file .wav:
    Write #File.Out, "\rTempo trascorso: " & Date(0, 0, 0, 0, 0, 0, (n_frames / freq_camp) * 1000)
  Until n_frames > durata
   
' Va in chiusura:
  del_aubio_wavetable(wavetable)
  del_aubio_sink(sink)
  del_fvec(vec)

End



Riferimenti