Differenze tra le versioni di "Eseguire un file WAV mediante le funzioni esterne del API di libaudio e di Alsa"
Da Gambas-it.org - Wikipedia.
(8 versioni intermedie di uno stesso utente non sono mostrate) | |||
Riga 1: | Riga 1: | ||
E' possibile eseguire un file formato WAV utilizzando le risorse delle librerie ''Libaudio'' ed ''ALSA''. Con le funzioni della libreria ''Libaudio'' si provvederà ad aprire e leggere i dati del file audio WAV, mentre con le funzioni della libreria di ''ALSA'' si provvederà ad inviare i dati audio letti al sub-sistema PCM. | E' possibile eseguire un file formato WAV utilizzando le risorse delle librerie ''Libaudio'' ed ''ALSA''. Con le funzioni della libreria ''Libaudio'' si provvederà ad aprire e leggere i dati del file audio WAV, mentre con le funzioni della libreria di ''ALSA'' si provvederà ad inviare i dati audio letti al sub-sistema PCM. | ||
− | Per fruire di tali risorse in Gambas bisognerà installare e richiamare le librerie dinamiche e condivise: "''libaudio.so.2.4''" e "''libasound.so.2''" | + | Per fruire di tali risorse in Gambas bisognerà installare e richiamare le librerie dinamiche e condivise: "''libaudio.so.2.4'' " e "''libasound.so.2.0.0'' " |
− | |||
Mostriamo un esempio pratico: | Mostriamo un esempio pratico: | ||
Riga 8: | Riga 7: | ||
− | Library "libaudio:2.4" | + | Library "<FONT Color=blue>libaudio:2.4</font>" |
Public Struct WaveInfo | Public Struct WaveInfo | ||
Riga 42: | Riga 41: | ||
− | Library "libasound:2" | + | Library "<FONT Color=red>libasound:2.0.0</font>" |
Private Const SND_PCM_STREAM_PLAYBACK As Integer = 0 | Private Const SND_PCM_STREAM_PLAYBACK As Integer = 0 | ||
Riga 48: | Riga 47: | ||
Private Const SND_PCM_FORMAT_S16_LE As Integer = 2 | Private Const SND_PCM_FORMAT_S16_LE As Integer = 2 | ||
Private Const SND_PCM_ACCESS_RW_INTERLEAVED As Integer = 3 | Private Const SND_PCM_ACCESS_RW_INTERLEAVED As Integer = 3 | ||
− | + | ||
− | |||
<FONT Color=gray>' ''int snd_pcm_open (snd_pcm_t **pcm, const char *name, snd_pcm_stream_t stream, int mode)'' | <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> | ' ''Opens a PCM.''</font> | ||
Riga 61: | Riga 59: | ||
' ''Write interleaved frames to a PCM.''</font> | ' ''Write interleaved frames to a PCM.''</font> | ||
Private Extern snd_pcm_writei(pcm As Pointer, buf As Pointer, size As Integer) As Integer | Private Extern snd_pcm_writei(pcm As Pointer, buf As Pointer, size As Integer) As Integer | ||
− | + | ||
− | |||
− | |||
− | |||
− | |||
<FONT Color=gray>' ''int snd_pcm_drain (snd_pcm_t *pcm)'' | <FONT Color=gray>' ''int snd_pcm_drain (snd_pcm_t *pcm)'' | ||
' ''Stop a PCM preserving pending frames.''</font> | ' ''Stop a PCM preserving pending frames.''</font> | ||
Riga 87: | Riga 81: | ||
If IsNull(info) Then Error.Raise("Errore nella lettura del file wav !") | If IsNull(info) Then Error.Raise("Errore nella lettura del file wav !") | ||
− | buf = Alloc(BUFFER) | + | buf = Alloc(SizeOf(gb.Byte), BUFFER) |
− | If | + | If buf = 0 Then Error.Raise("Impossibile allocare memoria !") |
− | + | ||
+ | Print "File audio: "; fileWav | ||
Print "Numero canali: "; info.channels | Print "Numero canali: "; info.channels | ||
Print "Risoluzione bit: "; info.bitsPerSample; " bit" | Print "Risoluzione bit: "; info.bitsPerSample; " bit" | ||
Riga 96: | Riga 91: | ||
Print "Overall BitRate: "; obr; " bps" | Print "Overall BitRate: "; obr; " bps" | ||
msec = Fix(((info.dataSize * 8) / obr) * 1000) | msec = Fix(((info.dataSize * 8) / obr) * 1000) | ||
− | Print "Durata: "; CStr( | + | Print "Durata: "; CStr(Time(0, 0, 0, msec)) |
Print | Print | ||
Riga 124: | Riga 119: | ||
If frames < 0 Then Error.Raise("Errore nella funzione 'snd_pcm_writei()' !") | If frames < 0 Then Error.Raise("Errore nella funzione 'snd_pcm_writei()' !") | ||
− | |||
− | |||
n += BUFFER | n += BUFFER | ||
+ | Write "\rTempo trascorso: " & Time(0, 0, 0, ((n * 8) / obr) * 1000) | ||
+ | |||
Wend | Wend | ||
Versione delle 17:13, 22 ott 2021
E' possibile eseguire un file formato WAV utilizzando le risorse delle librerie Libaudio ed ALSA. Con le funzioni della libreria Libaudio si provvederà ad aprire e leggere i dati del file audio WAV, mentre con le funzioni della libreria di ALSA si provvederà ad inviare i dati audio letti al sub-sistema PCM.
Per fruire di tali risorse in Gambas bisognerà installare e richiamare le librerie dinamiche e condivise: "libaudio.so.2.4 " e "libasound.so.2.0.0 "
Mostriamo un esempio pratico:
Private Const BUFFER As Integer = 32 Library "libaudio:2.4" Public Struct WaveInfo fp As Pointer comment As Pointer channels As Short bitsPerSample As Short sampleRate As Integer dataOffset As Integer numSamples As Integer fileSize As Integer dataSize As Integer sizeOffset As Integer writing As Integer formatSh As Short End Struct ' WaveInfo * WaveOpenFileForReading(const char *name) ' Open an wave file for reading. Private Extern WaveOpenFileForReading(name As String) As WaveInfo ' int WaveSeekFile(int n, WaveInfo *wi) ' Seek to a position in an wave file. Private Extern WaveSeekFile(n As Integer, wi As WaveInfo) As Integer ' int WaveReadFile(char *p, int n, WaveInfo *wi) ' Read wave data from an audio file. Private Extern WaveReadFile(p As Pointer, n As Integer, wi As WaveInfo) As Integer ' int WaveCloseFile(WaveInfo *wi) ' Close an wave file description. Private Extern WaveCloseFile(wi As WaveInfo) As Integer Library "libasound:2.0.0" Private Const SND_PCM_STREAM_PLAYBACK As Integer = 0 Private Const SND_PCM_FORMAT_U8 As Integer = 1 Private Const SND_PCM_FORMAT_S16_LE 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 Pointer, size As Integer) As Integer ' int snd_pcm_drain (snd_pcm_t *pcm) ' Stop a PCM preserving pending frames. Private Extern snd_pcm_drain(pcmP 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 buf, handle As Pointer Dim fileWav As String Dim err, bit, msec, obr, frames, i, n As Integer Dim info As New WaveInfo fileWav = "/percorso/del/file.wav" info = WaveOpenFileForReading(fileWav) If IsNull(info) Then Error.Raise("Errore nella lettura del file wav !") buf = Alloc(SizeOf(gb.Byte), BUFFER) If buf = 0 Then Error.Raise("Impossibile allocare memoria !") Print "File audio: "; fileWav Print "Numero canali: "; info.channels Print "Risoluzione bit: "; info.bitsPerSample; " bit" Print "Frequenza camp.: "; info.sampleRate; " Hertz" obr = info.channels * info.bitsPerSample * info.sampleRate Print "Overall BitRate: "; obr; " bps" msec = Fix(((info.dataSize * 8) / obr) * 1000) Print "Durata: "; CStr(Time(0, 0, 0, msec)) Print err = snd_pcm_open(VarPtr(handle), "default", SND_PCM_STREAM_PLAYBACK, 0) If err < 0 Then Error.Raise("Impossibile inizializzare la libreria Alsa !") Select Case info.bitsPerSample Case 16 bit = SND_PCM_FORMAT_S16_LE Case 8 bit = SND_PCM_FORMAT_U8 End Select err = snd_pcm_set_params(handle, bit, SND_PCM_ACCESS_RW_INTERLEAVED, info.channels, info.sampleRate, 1, 500000) If err < 0 Then Error.Raise("Impossibile impostare i parametri audio alla libreria Alsa !") i = info.bitsPerSample / (8 / info.channels) While n < info.dataSize err = WaveSeekFile(n, info) If err Then Error.Raise("Impossibile posizionarsi nel file wav !") WaveReadFile(buf, BUFFER, info) frames = snd_pcm_writei(handle, buf, BUFFER / i) If frames < 0 Then Error.Raise("Errore nella funzione 'snd_pcm_writei()' !") n += BUFFER Write "\rTempo trascorso: " & Time(0, 0, 0, ((n * 8) / obr) * 1000) Wend ' Impedisce che al termine l'esecuzione venga troncata inaspettatamente: snd_pcm_drain(handle) ' Va in chiusura: snd_pcm_close(handle) Free(buf) WaveCloseFile(info) End