Differenze tra le versioni di "Eseguire un file WAV mediante le funzioni esterne del API di libaudiofile e di Alsa"

Da Gambas-it.org - Wikipedia.
Riga 76: Riga 76:
 
   
 
   
 
   Dim afOF, AF_NULL_FILESETUP, handle As Pointer
 
   Dim afOF, AF_NULL_FILESETUP, handle As Pointer
   Dim percorsoFile As String = "''percorso/del/file.wav''"
+
   Dim percorsoFile As String = "''/percorso/del/file.wav''"
 
   Dim canali, frequenza, err, frameLetti, frameScritti As Integer
 
   Dim canali, frequenza, err, frameLetti, frameScritti As Integer
 
   Dim bufferFrames As Short = 4096
 
   Dim bufferFrames As Short = 4096
Riga 207: Riga 207:
 
   
 
   
 
   Dim afOF, sFP, sWP, handle As Pointer
 
   Dim afOF, sFP, sWP, handle As Pointer
   Dim percorsoFile As String = "''percorso/del/file.wav''"
+
   Dim percorsoFile As String = "''/percorso/del/file.wav''"
 
   Dim frameCount, canali, sampleFormat, sampleWidth, frequenza As Integer
 
   Dim frameCount, canali, sampleFormat, sampleWidth, frequenza As Integer
 
   Dim err, frameLetti, frameScritti As Integer
 
   Dim err, frameLetti, frameScritti As Integer

Versione delle 18:37, 3 feb 2015

La libreria Libaudiofile consente la lettura e la scrittura di file audio appartenenti ai formati wav, aiff, aifc, snd, au, voc ed altri.


Per poter fruire delle risorse della libreria Libaudiofile è necessario aver installata nel proprio sistema la libreria (nell'attuale versione): libaudiofile.so.1.0.0


Di seguito mostriamo due semplici codici per l'esecuzione di un file audio di formato WAV mediante la libreria Libaudiofile e la libreria di Alsa.

Primo esempio

Private somma_scritti As Integer


Library "libaudiofile:1.0.0"

Private Const AF_DEFAULT_TRACK As Integer = 1001
Private Const AF_SAMPFMT_TWOSCOMP As Integer = 401      ' linear two's complement

' AFfilehandle afOpenFile (const char *filename, const char *mode, AFfilesetup setup)
' Opens a specified audio file and creates a file handle structure
Private Extern afOpenFile(filename As String, mode As String, setup As Pointer) As Pointer

' int afGetChannels (AFfilehandle, int track)
' Gets number of channels.
Private Extern afGetChannels(AFfilehandle As Pointer, track As Integer) As Integer

' double afGetRate (AFfilehandle, int track)
' Gets sampling rate.
Private Extern afGetRate(AFfilehandle As Pointer, track As Integer) As Float

' int afSetVirtualSampleFormat (AFfilehandle, int track, int sampleFormat, int sampleWidth)
' Set the virtual data format for a track in an audio file
Private Extern afSetVirtualSampleFormat(AFfilehandle As Pointer, track As Integer, sampleFormat As Integer, sampleWidth As Integer) As Integer

' int afReadFrames (AFfilehandle, int track, void *buffer, int frameCount)
' reads sample frames from a given audio track in an audio file.
' Returns the number of frames successfully read from file into the array referred to by samples.
Private Extern afReadFrames(AFfilehandle As Pointer, track As Integer, buf As Short[], frameCount As Integer) As Integer

' int afCloseFile (AFfilehandle file)
' Closes an open audio file.
Private Extern afCloseFile(AFfilehandle As Pointer) As Integer


Library "libasound:2"

Private Const SND_PCM_STREAM_PLAYBACK As Integer = 0
Private Const SND_PCM_FORMAT_S16 As Integer = 2
Private Const SND_PCM_ACCESS_RW_INTERLEAVED As Integer = 3

' int snd_pcm_open (snd_pcm_t **pcm, const char *name, snd_pcm_stream_t stream, int mode)
' Opens a PCM.
Private Extern snd_pcm_open(pcm As Pointer, name As String, streamI As Integer, mode As Integer) As Integer

' int snd_pcm_set_params (snd_pcm_t *pcm, snd_pcm_format_t format, snd_pcm_access_t access, unsigned int channels, unsigned int rate, int soft_resample, unsigned int latency)
' Set the hardware and software parameters in a simple way.
Private Extern snd_pcm_set_params(pcm As Pointer, formatI As Integer, accessI As Integer, channels As Integer, rate As Integer, soft_resample As Integer, latency As Integer) As Integer

' snd_pcm_sframes_t snd_pcm_writei (snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)
' Write interleaved frames to a PCM.
Private Extern snd_pcm_writei(pcm As Pointer, buf As Short[], size As Integer) As Integer

' int snd_pcm_recover (snd_pcm_t * pcm, int err, int silent)
' Recover the stream state from an error or suspend.
Private Extern snd_pcm_recover(pcm As Pointer, errorI As Integer, silent As Integer) As Integer

' snd_pcm_drain (snd_pcm_t *pcm)
' Stop a PCM preserving pending frames.
Private Extern snd_pcm_drain(pcm As Pointer) As Integer

' int snd_pcm_close (snd_pcm_t *pcm)
' Close PCM handle
Private Extern snd_pcm_close(pcm As Pointer) As Integer


Public Sub Main()

 Dim afOF, AF_NULL_FILESETUP, handle As Pointer
 Dim percorsoFile As String = "/percorso/del/file.wav"
 Dim canali, frequenza, err, frameLetti, frameScritti As Integer
 Dim bufferFrames As Short = 4096
 Dim buffer As Short[]
 
' Parte AudioFile:
   afOF = afOpenFile(percorsoFile, "r", AF_NULL_FILESETUP)
   If IsNull(afOF) Then Error.Raise("Impossibile aprire il file !")
   
' Estrae alcune informazioni generali sul file audio:
   canali = afGetChannels(afOF, AF_DEFAULT_TRACK)
   frequenza = afGetRate(afOF, AF_DEFAULT_TRACK)
   Print "Canali audio di uscita: "; canali
   Print "Frequenza di campionamento: Hz "; frequenza

   afSetVirtualSampleFormat(afOF, AF_DEFAULT_TRACK, AF_SAMPFMT_TWOSCOMP, 16)
   
' Parte Alsa:
   err = snd_pcm_open(VarPtr(handle), "default", SND_PCM_STREAM_PLAYBACK, 0)
   If err < 0 Then Error.Raise("Impossibile inizializzare la libreria Alsa !")
   
   err = snd_pcm_set_params(handle, SND_PCM_FORMAT_S16, SND_PCM_ACCESS_RW_INTERLEAVED, canali, frequenza, 1, 500000)
   If err < 0 Then Error.Raise("Impossibile impostare i parametri audio alla libreria Alsa !")
   
   
   buffer = New Short[](bufferFrames * canali)

' Ciclo per eseguire il file wav:
   While True
     
     frameLetti = afReadFrames(afOF, AF_DEFAULT_TRACK, buffer, bufferFrames)
     If frameLetti <= 0 Then Break
     
' Scrive i dati audio nel sub-sistema PCM di Alsa:
     frameScritti = snd_pcm_writei(handle, buffer, bufferFrames)
     If frameScritti < 0 Then
       frameScritti = snd_pcm_recover(handle, frameScritti, 0)
       Error.Raise("Impossibile scrivere dati nel dispositivo di uscita di Alsa !")
     Endif

     somma_scritti += frameScritti
     Print CStr(Date(0, 0, 0, 0, 0, 0, (somma_scritti / frequenza) * 1000))
     
   Wend
   
   
' Va in chiusura:
   snd_pcm_drain(handle)
   snd_pcm_close(handle)
   buffer.Clear()
   afCloseFile(afOF)

End


Secondo esempio

Private somma_scritti As Integer


Library "libaudiofile:1.0.0"

Private Const AF_DEFAULT_TRACK As Integer = 1001
 
' AFfilehandle afOpenFile (const char *filename, const char *mode, AFfilesetup setup)
' Opens a specified audio file and creates a file handle structure
Private Extern afOpenFile(filename As String, mode As String, setup As Pointer) As Pointer

' AFframecount afGetFrameCount (AFfilehandle file, int track)
' Get the total sample frame count.
Private Extern afGetFrameCount(AFfilehandle As Pointer, track As Integer) As Integer

' float afGetFrameSize (AFfilehandle, int track, int expand3to4)
' Calculate the frame size in bytes for an audio track.
Private Extern afGetFrameSize(AFfilehandle As Pointer, track As Integer, expand3to4 As Integer) As Single

' void afGetSampleFormat (AFfilehandle file, int track, int *sampleFormat, int *sampleWidth)
' Get the sample format for a specified audio track.
Private Extern afGetSampleFormat(AFfilehandle As Pointer, track As Integer, sampleFP As Pointer, sampleWP As Pointer)

' int afGetChannels (AFfilehandle, int track)
' Gets number of channels.
Private Extern afGetChannels(AFfilehandle As Pointer, track As Integer) As Integer

' double afGetRate (AFfilehandle, int track)
' Gets sampling rate.
Private Extern afGetRate(AFfilehandle As Pointer, track As Integer) As Float

' int afReadFrames (AFfilehandle, int track, void *buffer, int frameCount)
' reads sample frames from a given audio track in an audio file.
' Returns the number of frames successfully read from file into the array referred to by samples.
Private Extern afReadFrames(AFfilehandle As Pointer, track As Integer, buf As Short[], frameCount As Integer) As Integer

' int afCloseFile (AFfilehandle file)
' Closes an open audio file.
Private Extern afCloseFile(AFfilehandle As Pointer) As Integer


Library "libasound:2"

Private Const SND_PCM_STREAM_PLAYBACK As Integer = 0
Private Const SND_PCM_FORMAT_S16 As Integer = 2
Private Const SND_PCM_ACCESS_RW_INTERLEAVED As Integer = 3

' int snd_pcm_open (snd_pcm_t **pcm, const char *name, snd_pcm_stream_t stream, int mode)
' Opens a PCM.
Private Extern snd_pcm_open(pcm As Pointer, name As String, streamI As Integer, mode As Integer) As Integer

' int snd_pcm_set_params (snd_pcm_t *pcm, snd_pcm_format_t format, snd_pcm_access_t access, unsigned int channels, unsigned int rate, int soft_resample, unsigned int latency)
' Set the hardware and software parameters in a simple way.
Private Extern snd_pcm_set_params(pcm As Pointer, formatI As Integer, accessI As Integer, channels As Integer, rate As Integer, soft_resample As Integer, latency As Integer) As Integer

' snd_pcm_sframes_t snd_pcm_writei (snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)
' Write interleaved frames to a PCM.
Private Extern snd_pcm_writei(pcm As Pointer, buf As Short[], size As Integer) As Integer

' int snd_pcm_recover (snd_pcm_t * pcm, int err, int silent)
' Recover the stream state from an error or suspend.
Private Extern snd_pcm_recover(pcm As Pointer, errorI As Integer, silent As Integer) As Integer

' snd_pcm_drain (snd_pcm_t *pcm)
' Stop a PCM preserving pending frames.
Private Extern snd_pcm_drain(pcm As Pointer) As Integer

' int snd_pcm_close (snd_pcm_t *pcm)
' Close PCM handle
Private Extern snd_pcm_close(pcm As Pointer) As Integer


Public Sub Main()

 Dim afOF, sFP, sWP, handle As Pointer
 Dim percorsoFile As String = "/percorso/del/file.wav"
 Dim frameCount, canali, sampleFormat, sampleWidth, frequenza As Integer
 Dim err, frameLetti, frameScritti As Integer
 Dim frameSize As Single
 Dim bufferFrames As Short = 4096
 Dim buffer As Short[]
 
' Parte AudioFile:
   afOF = afOpenFile(percorsoFile, "r", Null)
   If IsNull(afOF) Then Error.Raise("Impossibile aprire il file !")
   
' Estrae informazioni generali sul file audio:
   frameCount = afGetFrameCount(afOF, AF_DEFAULT_TRACK)
   canali = afGetChannels(afOF, AF_DEFAULT_TRACK)
   sFp = VarPtr(sampleFormat)
   sWP = VarPtr(sampleWidth)
   afGetSampleFormat(afOF, AF_DEFAULT_TRACK, sFP, sWP)
   If (Int@(sWP) <> 16) Or (canali > 2) Then Error.Raise("Il file audio deve essere di formato 16-bit monofonico o stereofonico !")
   frequenza = afGetRate(afOF, AF_DEFAULT_TRACK)
   frameSize = afGetFrameSize(afOF, AF_DEFAULT_TRACK, 1)
   Print "File audio: "; percorsoFile
   Print "Numero di frame nel file: "; frameCount
   Print "Canali audio di uscita: "; canali
   Print "Formato del campionamento: "; Int@(sFP)
   Print "Risoluzione del campionamento: "; Int@(sWP); "-bit"
   Print "Frequenza di campionamento: Hz "; frequenza
   Print "Dimensione dei soli dati audio: "; frameCount * frameSize; " byte"

   buffer = New Short[](frameCount * frameSize)
   
' Parte Alsa:
   err = snd_pcm_open(VarPtr(handle), "default", SND_PCM_STREAM_PLAYBACK, 0)
   If err < 0 Then Error.Raise("Impossibile inizializzare la libreria Alsa !")
   
   err = snd_pcm_set_params(handle, SND_PCM_FORMAT_S16, SND_PCM_ACCESS_RW_INTERLEAVED, canali, frequenza, 1, 500000)
   If err < 0 Then Error.Raise("Impossibile impostare i parametri audio alla libreria Alsa !")

' Ciclo per eseguire il file wav:
   While True
     
     frameLetti = afReadFrames(afOF, AF_DEFAULT_TRACK, buffer, bufferFrames)
     If frameLetti <= 0 Then Break
     
' Scrive i dati audio nel sub-sistema PCM di Alsa:
     frameScritti = snd_pcm_writei(handle, buffer, bufferFrames)
     If frameScritti < 0 Then
       frameScritti = snd_pcm_recover(handle, frameScritti, 0)
       Error.Raise("Impossibile scrivere dati nel dispositivo di uscita di Alsa !")
     Endif

     somma_scritti += frameScritti
     Print CStr(Date(0, 0, 0, 0, 0, 0, (somma_scritti / frequenza) * 1000))
     
   Wend
   
   
' Va in chiusura:
   snd_pcm_drain(handle)
   snd_pcm_close(handle)
   buffer.Clear()
   afCloseFile(afOF)

End



Riferimenti