Convertire un file WAV in testo con le risorse del API di Sndfile

Da Gambas-it.org - Wikipedia.

Mostriamo un semplice esempio per ottenere da un file audio di formato WAV i valori dei campioni audio trascritti in un file di testo per ciascun canale audio.

E' necessario avere installata nel sistema e richiamare in Gambas la libreria condivisa: "libsndfile.1.0.37 ".

Private Const DIM_BLOCCO As Integer = 4096

Library "libsndfile:1.0.37"

Public Struct SF_INFO
  frames As Long
  samplerate As Integer
  channels As Integer
  format_ As Integer
  sections As Integer
  seekable As Integer
End Struct

Private Const SFM_READ As Integer = 16

' SNDFILE * sf_open (const char *path, int mode, SF_INFO *sfinfo)
' Open the specified file for read, write or both.
Private Extern sf_open(path As String, mode As Integer, sfinfo As SF_INFO) As Pointer

' sf_count_t sf_readf_float (SNDFILE *sndfile, float *ptr, sf_count_t items)
' Function for reading the data chunk in terms of items.
Private Extern sf_readf_float(sndfile As Pointer, ptr As Pointer, items As Long) As Long

' const char* sf_strerror (SNDFILE *sndfile)
' Returns to the caller a pointer to the current error message for the given SNDFILE.
Private Extern sf_strerror(sndfile As Pointer) As String

' int sf_close (SNDFILE *sndfile)
' Close the SNDFILE and clean up all memory allocations associated with this file.
Private Extern sf_close(sndfile As Pointer) As Integer


Public Sub Main()
 
 Dim wav, txt As String
 Dim sfi As New SF_INFO
 Dim fen As Pointer
 
 wav = "/percorso/del/file.wav"
 txt = "/percorso/del/file/di/testo"
 If Comp(wav, txt, gb.IgnoreCase) == 0 Then Error.Raise("Errore: il file d'origine e lo stesso di quello di destinazione !")
 
 fen = sf_open(wav, SFM_READ, sfi)
 If fen == 0 Then Error.Raise("Errore: " & sf_strerror(0))
 
 Converte_a_testo(fen, wav, txt, sfi)
 
 sf_close(fen)
  
End


Private Procedure Converte_a_testo(flin As Pointer, ori As String, testo As String, info As SF_INFO)
 
 Dim buf As New Single[DIM_BLOCCO]
 Dim frames As Long
 Dim k, m, readcount As Integer
 Dim fl As File
 
 frames = DIM_BLOCCO / info.channels
 
 fl = Open testo For Create
 
 Write #fl, "Conversione dal file: " & ori &
 "\x0ACanali: " & CStr(info.channels) &
 "   Frequenza: hz " & CStr(info.samplerate) & String(2, Chr(&0A))
 
 readcount = sf_readf_float(flin, buf.Data, frames)
 While readcount > 0
   For k = 0 To readcount - 1
     For m = 0 To info.channels - 1
       Write #fl, Format(buf[k * info.channels + m], "0.00000000") & "   "
     Next
     Write #fl, &0A As Byte
   Next
   readcount = sf_readf_float(flin, buf.Data, frames)
 Wend
 
 fl.Close
 
End