Individuare le frequenze presenti in un'onda audio 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 (tradotto in Gambas con modifiche da un analogo esempio scritto in C da Paul Brossier), nel quale verranno individuate le frequenze sonore presenti in un'onda audio su un asse temporale.

Library "libaubio:4.0.0"

Public Struct fvec_t
  length As Integer
  data As Pointer
End Struct

' aubio_source_t * new_aubio_source(char_t * uri, uint_t samplerate, uint_t hop_size)
' Creates a new source object.
Private Extern new_aubio_source(uri As String, samplerate As Integer, hopsize As Integer) As Pointer

' uint_t aubio_source_get_samplerate(aubio_source_t * s)
' Get samplerate of source object.
Private Extern aubio_source_get_samplerate(aubio_source As Pointer) As Integer

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

' aubio_pitch_t *new_aubio_pitch (char_t * method, uint_t buf_size, uint_t hop_size, uint_t samplerate)
' Creation of the pitch detection object.
Private Extern new_aubio_pitch(method As String, buf_size As Integer, hopsize As Integer, samplerate As Integer) As Pointer

' uint_t aubio_pitch_set_unit (aubio_pitch_t * o, char_t * mode)
' Set the output unit of the pitch detection object.
Private Extern aubio_pitch_set_unit(aubio_pitch As Pointer, mode As String) As Integer

' void aubio_source_do(aubio_source_t * s, fvec_t * read_to, uint_t * read)
' Read monophonic vector of length hop_size from source object.
Private Extern aubio_source_do(aubio_source As Pointer, read_to As Fvec_t, readP As Pointer)

' void aubio_pitch_do (aubio_pitch_t * o, fvec_t * in, fvec_t * out)
' Execute pitch detection on an input signal frame.
Private Extern aubio_pitch_do(aubio_pitch As Pointer, fvin As Fvec_t, fvout As Fvec_t)

' smpl_t fvec_get_sample(fvec_t *s, uint_t position)
' Read sample value in a buffer.
Private Extern fvec_get_sample(fvs As Fvec_t, position As Integer) As Single

' void del_aubio_pitch (aubio_pitch_t * o)
' Deletion of the pitch detection object.
Private Extern del_aubio_pitch(aubio_pitch As Pointer)

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

' void del_aubio_source(aubio_source_t * s)
' Close source and cleanup memory.
Private Extern del_aubio_source(aubio_source As Pointer)


Public Sub Main()

 Dim buffer_size As Integer = 2048
 Dim hop_size As Integer = 256
 Dim frequenza, blocks, total_read, letti As Integer
 Dim fileAudio As String
 Dim source, o As Pointer
 Dim ibuf, obuf, pitch As New Fvec_t
 Dim pitch_method As String = "default"
 Dim pitch_unit As String = "default"
 Dim pitch_tolerance, pitch_found As Single
 
  fileAudio = "/percorso/del/file/audio"
 
  source = new_aubio_source(fileAudio, frequenza, hop_size)
  If IsNull(source) Then Error.Raise("Impossibile aprire il file audio: " & fileAudio)
   
  frequenza = aubio_source_get_samplerate(source)

  ibuf = new_fvec(hop_size)
  obuf = new_fvec(hop_size)
   
  Print "Uso del file audio: "; fileAudio; " ad una frequenza di campionamento di Hz "; frequenza
  Print "Metodo intonazione: "; pitch_method
  Print "Unità di intonazione: "; pitch_unit
  Print "Dimensione del buffer: "; buffer_size
  Print "Hop size: "; hop_size
  Print "Tolleranza: "; pitch_tolerance
  Print "\nAnalisi dell'onda audio.";
  Wait 0.4
  Print ".";
  Wait 0.4
  Print ".";
  Wait 0.4
  Print ".";
  Wait 0.4
  Print ".";
  Wait 0.4
  Print "."
  Wait 0.5

  o = new_aubio_pitch(pitch_method, buffer_size, hop_size, frequenza)
   
  aubio_pitch_set_unit(o, pitch_unit)
   
  pitch = new_fvec(1)
   
  Repeat
    aubio_pitch_do(o, ibuf, pitch)
    aubio_source_do(source, ibuf, VarPtr(letti))
    pitch_found = fvec_get_sample(pitch, 0)
    Print CStr(Date(0, 0, 0, 0, 0, 0, (blocks * hop_size / CSingle(frequenza) * 1000))), Null; Format(pitch_found, "####0.00")
    Inc blocks
    total_read += letti
  Until letti <> hop_size
   
   
' Va in chiusura:
  del_fvec(ibuf)
  del_fvec(obuf)
  del_aubio_pitch(o)
  del_fvec(pitch)
  del_aubio_source(source)

End



Riferimenti