Eseguire un file WAV mediante le funzioni esterne del API di Sndio

Da Gambas-it.org - Wikipedia.

La libreria libsndio consente di eseguire un file WAV.
E' necessario avere installata nel sistema e richiamare in Gambas la libreria condivisa: "libsndio.so.7.3 ".

Mostriamo un esempio pratico:

Library "libsndio:7.3"

Public Struct sio_par
  bits As Integer
  bps As Integer
  sig As Integer
  le As Integer
  msb As Integer
  rchan As Integer
  pchan As Integer
  rate As Integer
  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_PLAY As Integer = 1

' 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_write(struct sio_hdl *hdl, const void *addr, size_t nbytes)
Private Extern sio_write(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 lun, i, obr, pos As Integer
 Dim bufsz As Long
 Dim fl As File
 Dim buf As Byte[]
 
 wav = "/percorso/del/file.wav"
 If Not Exist(wav) Then Error.Raise("Errore: file inesistente !")
 
 fl = Open wav For Read
 lun = Lof(fl)
 
 sio_initpar(sp)
 
 sh = sio_open(SIO_DEVANY, SIO_PLAY, 0)
 If sh == 0 Then Error.Raise("Errore !")
 
' Estrae dal file wav il numero dei canali, la frequenza di campionamento e la risoluzione:
 Seek #fl, 22
 sp.pchan = Read #fl As Short
 sp.rate = Read #fl As Integer
 Seek #fl, 34
 sp.bits = Read #fl As Short
 
 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
 obr = sp.rate * sp.bits * sp.pchan
 Print "File audio:  "; wav
 Print "Canali:      "; sp.pchan
 Print "Frequenza:   "; sp.rate; " hertz"
 Print "Risoluzione: "; sp.bits; " bit"
 Print "Durata:      "; Time(0, 0, 0, ((lun * 8) / obr) * 1000)
 Print
 
 i = sio_start(sh)
 If i = 0 Then Error.Raise("Errore !")
 
 buf = New Byte[bufsz]
 
 Repeat
   buf.Read(fl, 0, bufsz)
   
   i = sio_write(sh, buf.Data, bufsz)
   If i < 0 Then Error.Raise("Errore !")
   
   Write "\rTempo trascorso: \e[40m\e[32m " & Time(0, 0, 0, ((pos * 8) / obr) * 1000) & " \e[0m"
   
   pos += bufsz
   If (lun - pos) < 1024 Then bufsz = lun - Seek(fl)
 Until Seek(fl) = lun
 
 sio_close(sh)
 
End


Riferimenti