Registrare una sorgente sonora esterna le funzioni esterne del API di Sndio

Da Gambas-it.org - Wikipedia.

La libreria Sndio consente anche di effettuare una registrazione audio di una sorgente sonora (interna dal dispositivo audio di sistema o esterna da un microfono).

E' necessario avere installata nel proprio sistema e richiamare in Gambas la libreria condivisa: "libsndio.so.7.0 "

Mostriamo un semplice esempio pratico, nel quale, dopo aver ottenuto i dati audio grezzi della registrazione, viene creato un file audio wav:

Private bo As Boolean

Library "libsndio:7.0"

Public Struct sio_par
  bits As Integer      ' bits per sample
  bps As Integer
  sig As Integer       ' 1 = signed, 0 = unsigned
  le As Integer
  msb As Integer
  rchan As Integer     ' number channels for recording direction
  pchan As Integer
  rate As Integer      ' frames per second
  bufsz As Integer
  xrun As Integer
  round As Integer
  appbufsz As Integer
  __pad[3] As Integer
  __magic As Integer
End Struct

' Private Const SIO_DEVANY As String = "default"
Private Const SIO_REC As Integer = 2

' void sio_initpar(struct sio_par *par)
Private Extern sio_initpar(par As Sio_par)

' struct sio_hdl *sio_open(const char *name, unsigned int mode, int nbio_flag)
Private Extern sio_open(name As String, mode As Integer, nbio_flag As Integer) As Pointer

' int sio_setpar(struct sio_hdl *hdl, struct sio_par *par)
Private Extern sio_setpar(hdl As Pointer, par As Sio_par) As Integer

' int sio_getpar(struct sio_hdl *hdl, struct sio_par *par)
Private Extern sio_getpar(hdl As Pointer, par As Sio_par) As Integer

' int sio_start(struct sio_hdl *hdl)
Private Extern sio_start(hdl As Pointer) As Integer

' size_t sio_read(struct sio_hdl *hdl, const void *addr, size_t nbytes)
Private Extern sio_read(hdl As Pointer, addr As Pointer, nbytes As Long) As Long

' void sio_close(struct sio_hdl *hdl)
Private Extern sio_close(hdl As Pointer)


Public Sub Main()
 
 Dim sp As New Sio_par
 Dim wav As String
 Dim sh As Pointer
 Dim tempus As Single
 Dim i, obr, pos As Integer
 Dim bufsz As Long
 Dim fl As File
 Dim buf As Byte[]
 
' Imposta la durata in secondi della registrazione:
 tempus = 5.746
 
 wav = Temp()
 
 fl = Open wav For Create
 
 sio_initpar(sp)
 
 With sp
   .sig = 1
   .bits = 16
   .rchan = 2
   .rate = 44100
 End With
 
 sh = sio_open(SIO_DEVANY, SIO_REC, 0)
 If sh = 0 Then Error.Raise("Errore !")
 
 i = sio_setpar(sh, sp)
 If i = 0 Then Error.Raise("Errore !")
 
 i = sio_getpar(sh, sp)
 If i = 0 Then Error.Raise("Errore !")
 
 bufsz = 1024
 
 i = sio_start(sh)
 If i = 0 Then Error.Raise("Errore !")
 
 buf = New Byte[bufsz]
 
 obr = sp.bits * sp.rchan * sp.rate
 If obr < 1024 Then Error.Raise("Errore !")
 
' Resta in attesa fino a quando, premuto il tasto "Enter" o "Invio", la variabile "bo" non diventa "Vera":
 Repeat
   Wait 0.01
 Until bo = True
 
 Print "Inizio registrazione !\n"
 
 Repeat
   i = sio_read(sh, buf.Data, bufsz)
   If i < 0 Then Error.Raise("Errore !")
   
   buf.Write(fl, 0, buf.Count)
   pos += bufsz
   Write "\rTempo trascorso: \e[40m\e[32m " &
         Time(0, 0, 0, ((pos * 8) / obr) * 1000) & " \e[0m"
 Until ((pos * 8) / obr) > tempus 
 
 Print "\n\nTermine registrazione !"
 sio_close(sh)
 fl.Close
 
 HeaderWav(wav)
 
 Quit
  
End


Private Procedure HeaderWav(tmp As String)    ' Crea l'header del file wav
 
 Dim hdr As Byte[]
 Dim b As Byte
 Dim s As String
 
 hdr = [&52, &49, &46, &46, &00, &00, &00, &00, &57, &41, &56, &45, &66, &6D, &74, &20,
        &10, &00, &00, &00, &01, &00, &02, &00, &44, &AC, &00, &00, &10, &B1, &02, &00,
        &04, &00, &10, &00, &00, &00, &64, &61, &74, &61, &00, &00, &00, &00]
 
 s = File.Load(tmp)
 
 For b = 0 To 3
   hdr[4 + b] = Shr(Len(s) + 38, 8 * b) And &FF
   hdr[42 + b] = Shr(Len(s), 8 * b) And &FF
 Next
 
 File.Save("/tmp/prova.wav", hdr.ToString(0, hdr.Count) & s)
 
End


Public Sub Application_read()    ' Consente di attendere la pressione del tasto "Enter" o "Invio"
 
' Quando viene premuto il tasto "Enter" o "Invio", la variabile "bo" diventa "Vera":
 bo = True
 

End


Riferimenti