|
|
(4 versioni intermedie di uno stesso utente non sono mostrate) |
Riga 1: |
Riga 1: |
− | '''SndFile''' è una libreria, scritta in C, per leggere e scrivere file che contengono suono campionato (come il formato WAV ed il formato AIFF) attraverso una libreria interfaccia standard.
| |
| | | |
− | Pertanto, coniugheremo le librerie di ''SndFile'' e di ''Alsa'', assegnando a SndFile il compito di leggere ed estrarre i dati del file audio, ed ad Alsa quello di eseguire tali dati audio.
| + | #REDIRECT [[Eseguire_un_file_audio_usando_l'API_di_SndFile_e_di_Alsa]] |
− | <BR>A tal fine è necessario avere installate nel sistema e richiamare in Gambas le libreria condivise: "''libsndfile.so.1.0.28'' " e "''libasound.so.2.0.0''"
| |
− | | |
− | | |
− | Mostreremo di seguito un semplice codice per l'esecuzione di un file wav:
| |
− | Library "<FONT color=blue>libsndfile:1.0.28</font>"
| |
− |
| |
− | 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 BUFFER_LEN As Short = 1024
| |
− | Private Const SFM_READ As Byte = 16
| |
− |
| |
− | <FONT color=gray>' ''SNDFILE * sf_open (const char *path, int mode, SF_INFO *sfinfo)''
| |
− | ' ''Open the specified file for read, write or both.''</font>
| |
− | Private Extern sf_open(path As String, mode As Integer, SFinf As SF_INFO) As Pointer
| |
− |
| |
− | <FONT color=gray>' ''sf_count_t sf_read_short(SNDFILE *sndfile, float *ptr, sf_count_t items)''
| |
− | ' ''Read the data chunk in terms of frames (in the native short format).''</font>
| |
− | Private Extern sf_read_short(sndfile As Pointer, ptr As Pointer, items As Integer) As Integer
| |
− |
| |
− | <FONT color=gray>' ''int sf_close (SNDFILE *sndfile)''
| |
− | ' ''Close the SNDFILE and clean up all memory allocations associated with this file.''</font>
| |
− | Private Extern sf_close(sndfile As Pointer) As Integer
| |
− |
| |
− |
| |
− | Library "<FONT color=red>libasound:2</font>"
| |
− |
| |
− | Private Const SND_PCM_STREAM_PLAYBACK As Byte = 0
| |
− | Private Const SND_PCM_ACCESS_RW_INTERLEAVED As Byte = 3
| |
− | Private Const SND_PCM_FORMAT_U8 As Byte = 1
| |
− |
| |
− | <FONT color=gray>' ''int snd_pcm_open(snd_pcm_t **pcm, const char *name, snd_pcm_stream_t stream, int mode)''
| |
− | ' ''Opens a PCM.''</font>
| |
− | Private Extern snd_pcm_open(pcmP As Pointer, nome As String, stream As Integer, mode As Integer) As Integer
| |
− |
| |
− | <FONT color=gray>' ''const char * snd_strerror (int errnum)''
| |
− | ' ''Returns the message For an Error code.''</font>
| |
− | Private Extern snd_strerror(errnum As Integer) As String
| |
− |
| |
− | <FONT color=gray>' ''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 aPrivate Const MPG123_ADD_FLAGS As Byte = 2 simple way.''</font>
| |
− | Private Extern snd_pcm_set_params(pcmP As Pointer, format_ As Byte, access_ As Byte, channels As Integer, rate As Integer, soft_resample As Integer, latency As Integer) As Integer
| |
− |
| |
− | <FONT color=gray>' ''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.''</font>
| |
− | Private Extern snd_pcm_writei(pcmP As Pointer, buffP As Pointer, uframes As Long) As Integer
| |
− |
| |
− | <FONT color=gray>' ''int snd_pcm_drain (snd_pcm_t *pcm)''
| |
− | ' ''Stop a PCM preserving pending frames.''</font>
| |
− | Private Extern snd_pcm_drain(pcmP As Pointer) As Integer
| |
− |
| |
− | <FONT color=gray>' ''int snd_pcm_close(snd_pcm_t **pcm)''
| |
− | ' ''Close PCM handle.''</font>
| |
− | Private Extern snd_pcm_close(pcmP As Pointer)
| |
− |
| |
− |
| |
− | '''Public''' Sub Main()
| |
− |
| |
− | Dim fileaudio As String
| |
− | Dim infile, buffer, handle As Pointer
| |
− | Dim sfinfo As New SF_INFO
| |
− | Dim err, lun, frequenza, frames, canali, somma As Integer
| |
− | Dim durata As Single
| |
− |
| |
− | fileaudio = "<FONT color=gray>''/percorso/del/file.wav''</font>"
| |
− | lun = Len(File.Load(fileaudio))
| |
− |
| |
− | <FONT color=darkorange><B>buffer</b></font> = Alloc(BUFFER_LEN * 4)
| |
− |
| |
− | <FONT color=gray>' ''Apre il file wav:''</font>
| |
− | infile = sf_open(fileaudio, SFM_READ, sfinfo)
| |
− | If infile = 0 Then Error.Raise("Errore nell'apertura del file audio !")
| |
− |
| |
− | <FONT color=gray>' ''Ricava la frequenza di campionamento ed il numero di canali del file wav:''</font>
| |
− | With sfinfo
| |
− | frequenza = .samplerate
| |
− | canali = .channels
| |
− | End With
| |
− |
| |
− | Print "File audio: "; fileaudio
| |
− | Print "Frequenza: "; frequenza; " hertz"
| |
− | Print "Numero canali: "; canali
| |
− | durata = (sfinfo.frames / frequenza)
| |
− | Print "Risoluzione: "; Fix(((lun * 8) / (frequenza * canali)) / durata); " bit"
| |
− | Print "Campioni: "; sfinfo.frames
| |
− | Print "Durata: "; Time(0, 0, 0, durata * 1000)
| |
− |
| |
− | <FONT color=gray>'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
| |
− | ' ''Qui inizia la parte relativa alle funzioni di Alsa:''</font>
| |
− |
| |
− | err = snd_pcm_open(VarPtr(handle), "default", SND_PCM_STREAM_PLAYBACK, 0)
| |
− | If err < 0 Then Error.Raise("Playback open error: " & snd_strerror(err))
| |
− |
| |
− | err = snd_pcm_set_params(handle, 2, SND_PCM_ACCESS_RW_INTERLEAVED, canali, frequenza, 1, 500000)
| |
− | If err < 0 Then Error.Raise("Playback open error: " & snd_strerror(err))
| |
− |
| |
− | <FONT color=gray>' ''Inizia il ciclo per la scrittura dei dati e per l'esecuzione del file wav:''</font>
| |
− | Repeat
| |
− |
| |
− | <FONT color=gray>' Legge i dati del file wav e li carica nel buffer:''</font>
| |
− | lun = sf_read_short(infile, <FONT color=darkorange><B>buffer</b></font>, BUFFER_LEN)
| |
− |
| |
− | <FONT color=gray>' ''I dati audio vengono inviati al sub-sistema "PCM" di Alsa, attraverso la lettura della variabile''
| |
− | ' ''qui denominata "buffer". La quantità unitaria di dati scritti nell'handle del sub-sistema PCM deve essere uguale''
| |
− | ' ''al valore del 3° argomento della precedente funzione "sf_read_short" diviso il numero di canali del file audio:''</font>
| |
− | frames = snd_pcm_writei(handle, <FONT color=darkorange><B>buffer</b></font>, BUFFER_LEN / sfinfo.channels)
| |
− | If (frames < 0) Then Error.Raise("Errore alla funzione 'snd_pcm_writei': " & snd_strerror(err))
| |
− |
| |
− | somma += frames
| |
− | Write "\r" & Time(0, 0, 0, (somma / frequenza) * 1000)
| |
− |
| |
− | Until lun = 0
| |
− |
| |
− | <FONT color=gray>' ''Impedisce che al termine l'esecuzione venga troncata inaspettatamente:''</font>
| |
− | snd_pcm_drain(handle)
| |
− |
| |
− | <FONT color=gray>' ''Va in chiusura:''</font>
| |
− | snd_pcm_close(handle)
| |
− | sf_close(infile)
| |
− | Free(buffer)
| |
− |
| |
− | '''End'''
| |
− | | |
− | | |
− | | |
− | =Riferimenti=
| |
− | * Il sito del [http://www.mega-nerd.com/libsndfile/api.html API di SndFile].
| |