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 8: Riga 8:
  
 
====Primo esempio====
 
====Primo esempio====
Private Const bufferFrames As Short = 4096
 
 
  Private somma_scritti As Integer
 
  Private somma_scritti As Integer
 
   
 
   
Riga 79: Riga 78:
 
   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 buffer As Short[]
 
   Dim buffer As Short[]
 
    
 
    

Versione delle 18:36, 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