La gestione mediante le funzioni esterne dell'API di SDL

Da Gambas-it.org - Wikipedia.

La libreria SDL è un API multi-piattaforma contenente funzioni per la gestione multimediale dell'audio e del video.


Per poter utilizzare le funzioni esterne di SDL in Gambas, si potranno richiamare anche separatamente le specifiche librerie che attualmente sono le seguenti:

libSDL-1.2.so.0.11.4
libSDL_mixer-1.2.so.0.12.0
libSDL_sound-1.0.so.1.0.2

Per poter riprodurre più suoni contemporaneamente è necessario utilizzare le funzioni della sub-libreria mixer audio multi-canale SDL_mixer.


Eseguire un file WAV intercettando il canale sul quale viene eseguito

E' possibile eseguire file WAV su flussi audio, definiti canali. Questa risorsa consente di eseguire sino a 32 file audio di formato WAV contemporaneamente. Un'apposita funzione intercetterà il canale sul quale il file WAV viene eseguito, restituendone un valore di tipo puntatore che ne consentirà la successiva gestione.

Di seguito mostreremo un semplice codice per eseguire un solo file audio WAV.

Private Const AUDIO_S16SYS As Integer = 32784       ' Campioni a 16-bit
Private Const SDL_INIT_AUDIO As Byte = 10
Private Const STEREO As Byte = 2


Library "libSDL-1.2:0.11.4"

' int SDL_Init(Uint32 flags)
Private Extern SDL_Init(flags As Integer) As Integer

' char * SDL_GetError(void)
Private Extern SDL_GetError() As String

' void SDL_Quit(void)
Private Extern SDL_Quit()


Library "libSDL_mixer-1.2:0.12.0"

' char * Mix_GetError(void)
Private Extern Mix_GetError() As String

' int Mix_OpenAudio(Int frequency, Uint16 Format, Int channels, Int chunksize)
Private Extern Mix_OpenAudio(frequency As Integer, formatSh As Short, channels As Byte, chunksize As Integer) As Integer

' Mix_Chunk * Mix_LoadWAV_RW(SDL_RWops *src, int freesrc)
Private Extern Mix_LoadWAV_RW(src As Pointer, freesrc As Integer) As Pointer

' int Mix_PlayChannelTimed(int channel, Mix_Chunk *chunk, int loops, int ticks)
Private Extern Mix_PlayChannelTimed(channel As Integer, chunk As Pointer, loops As Integer, ticks As Integer) As Integer

' void Mix_FreeChunk(Mix_Chunk *chunk)
Private Extern Mix_FreeChunk(chunk As Pointer)

' void Mix_CloseAudio(void)
Private Extern Mix_CloseAudio()


Library "libSDL_sound-1.0:1.0.2"

' SDL_RWops *SDL_RWFromFile(const char *file, const char *mode)
Private Extern SDL_RWFromFile(src As String, mode As String) As Pointer


Public Sub Button1_Click()

 Dim err, channel As Integer
 Dim audio_rate As Integer = 44100   ' Imposta la frequenza che verrà usata da "SDL_mixer"
 Dim audio_buffers As Short = 4096   ' Determina la quantità di blocchi di memoria utilizzati per incamerare ed eseguire i campioni audio
 Dim fl, sound As Pointer


' Inizializza il dispositivo SDL audio:
   err = SDL_Init(SDL_INIT_AUDIO)
   If err < 0 Then Error.Raise("Impossibile inizializzare la libreria SDL: " & SDL_GetError())

' Inizializza la libreria "SDL_mixer" con specifiche impoostazioni audio:
   err = Mix_OpenAudio(audio_rate, AUDIO_S16SYS, STEREO, audio_buffers)
   If err <> 0 Then Error.Raise("Impossibile inizializzare l'audio: " & Mix_GetError())
   
' Carica il file WAV:
   fl = SDL_RWFromFile("/percorso/del/file.wav", "rb")
   If IsNull(fl) Then Error.Raise("Errore nel caricamento del file !")

   sound = Mix_LoadWAV_RW(fl, 1)

' Esegue il file WAV caricato, ed intercetta il canale sul quale viene eseguito.
' Passando il valore -1 al primo argomento della funzione, il campione audio sarà eseguito sul primo canale audio disponibile:
   channel = Mix_PlayChannelTimed(-1, sound, 0, 0)
   If channel = -1 Then Error.Raise("Impossibile eseguire il file WAV: " & Mix_GetError())

' Attende che sia terminato il file WAV:
   While Mix_Playing(channel) <> 0
     Wait 0.01
   Wend

' Libera la memoria precedentemente allocata per l'esecuzione sonora:
   Mix_FreeChunk(sound)
 
' Chiude l'interfaccia audio SDL e SDL_mixer:
   Mix_CloseAudio()
 
   SDL_Quit()

End


Eseguire due o più file audio WAV

Di seguito mostreremo un codice esemplificativo, nel quale verranno eseguiti due file WAV:

Private Const AUDIO_S16SYS As Integer = 32784       ' Campioni a 16-bit
Private Const SDL_INIT_AUDIO As Byte = 10
Private Const STEREO As Byte = 2


Library "libSDL-1.2:0.11.4"

' int SDL_Init(Uint32 flags)
Private Extern SDL_Init(flags As Integer) As Integer

' char * SDL_GetError(void)
Private Extern SDL_GetError() As String

' void SDL_Quit(void)
Private Extern SDL_Quit()


Library "libSDL_mixer-1.2:0.12.0"

' char * Mix_GetError(void)
Private Extern Mix_GetError() As String

' int Mix_OpenAudio(Int frequency, Uint16 Format, Int channels, Int chunksize)
Private Extern Mix_OpenAudio(frequency As Integer, formatSh As Short, channels As Byte, chunksize As Integer) As Integer

' Mix_Chunk * Mix_LoadWAV_RW(SDL_RWops *src, int freesrc)
Private Extern Mix_LoadWAV_RW(src As Pointer, freesrc As Integer) As Pointer

' int Mix_PlayChannelTimed(int channel, Mix_Chunk *chunk, int loops, int ticks)
Private Extern Mix_PlayChannelTimed(channel As Integer, chunk As Pointer, loops As Integer, ticks As Integer) As Integer

' void Mix_FreeChunk(Mix_Chunk *chunk)
Private Extern Mix_FreeChunk(chunk As Pointer)

' void Mix_CloseAudio(void)
Private Extern Mix_CloseAudio()


Library "libSDL_sound-1.0:1.0.2"

' SDL_RWops *SDL_RWFromFile(const char *file, const char *mode)
Private Extern SDL_RWFromFile(src As String, mode As String) As Pointer


Public Sub Button1_Click()

 Dim err, channel As Integer
 Dim channel as New Integer[]
 Dim audio_rate As Integer = 44100   ' Imposta la frequenza che verrà usata da "SDL_mixer"
 Dim audio_buffers As Short = 4096   ' Determina la quantità di blocchi di memoria utilizzati per incamerare ed eseguire i campioni audio
 Dim fl, sound As New Pointer[]


' Inizializza il dispositivo SDL audio:
   err = SDL_Init(SDL_INIT_AUDIO)
   If err < 0 Then Error.Raise("Impossibile inizializzare la libreria SDL: " & SDL_GetError())

' Inizializza la libreria "SDL_mixer" con specifiche impoostazioni audio:
   err = Mix_OpenAudio(audio_rate, AUDIO_S16SYS, STEREO, audio_buffers)
   If err <> 0 Then Error.Raise("Impossibile inizializzare l'audio: " & Mix_GetError())
   
' Carica il primo file WAV:
   fl.Add(SDL_RWFromFile("/percorso/del/primo/file.wav", "rb"))
   If IsNull(fl[0]) Then Error.Raise("Errore nel caricamento del 1° file !")

' Carica il secondo file WAV:
   fl.Add(SDL_RWFromFile("/percorso/del/secondo/file.wav", "rb"))
   If IsNull(fl[1]) Then Error.Raise("Errore nel caricamento del 2° file !")


   With sound
     .Add(Mix_LoadWAV_RW(fl[0], 1))
     .Add(Mix_LoadWAV_RW(fl[1], 1))
   End With

' Esegue contemporaneamente entrambi i file WAV caricati , ed intercetta il rispettivo canale sul quale ciascuno di essi viene eseguito.
' Passando il valore -1 al primo argomento della funzione, il campione audio sarà eseguito sul primo canale audio disponibile:
   channel.Add(Mix_PlayChannelTimed(-1, sound[0], 0, 0)
   If channel[0] = -1 Then Error.Raise("Impossibile eseguire il 1° file WAV: " & Mix_GetError())

   channel.Add(Mix_PlayChannelTimed(-1, sound[1], 0, 0)
   If channel[1] = -1 Then Error.Raise("Impossibile eseguire il 2° file WAV: " & Mix_GetError())

' Attende che sia terminato il file WAV:
   While Mix_Playing(channel) <> 0
     Wait 0.01
   Wend

' Libera la memoria precedentemente allocata per l'esecuzione sonora:
   Mix_FreeChunk(sound)
 
' Chiude l'interfaccia audio SDL e SDL_mixer:
   Mix_CloseAudio()
 
   SDL_Quit()

End


Eseguire gli altri file audio

Per poter eseguire gli altri file audio (ma compreso anche lo stesso formato WAV) |1|, utilizzeremo particolarmente la libreria libSDL_mixer-1.2.so.0.12.0.

In quest'altro caso, le funzioni utilizzate non ci consentono di poter eseguire più brani contemporaneamente.

Library "libSDL-1.2:0.11.4"

' int SDL_Init(Uint32 flags)
Private Extern SDL_Init(flags As Integer) As Integer

' char * SDL_GetError(void)
Private Extern SDL_GetError() As String

' void SDL_Quit(void)
Private Extern SDL_Quit()


Library "libSDL_mixer-1.2:0.12.0"

' char * Mix_GetError(void)
Private Extern Mix_GetError() As String

' int Mix_OpenAudio(Int frequency, Uint16 Format, Int channels, Int chunksize)
Private Extern Mix_OpenAudio(frequency As Integer, formatSh As Short, channels As Byte, chunksize As Integer) As Integer

' Mix_Music *Mix_LoadMUS(const char *file)
Private Extern Mix_LoadMUS(file As String) As Pointer

' int Mix_PlayMusic(Mix_Music *music, int loops)
Private Extern Mix_PlayMusic(music As Pointer, loops As Integer) As Integer

' Int Mix_PlayingMusic()
Private Extern Mix_PlayingMusic() As Integer

' void Mix_FreeChunk(Mix_Chunk *chunk)
Private Extern Mix_FreeChunk(chunk As Pointer)

' void Mix_CloseAudio(void)
Private Extern Mix_CloseAudio()


Public Sub Button1_Click()

 Dim err As Integer
 Dim audio_rate As Integer = 44100   ' Imposta la frequenza che verrà usata da "SDL_mixer"
 Dim audio_buffers As Short = 4096   ' Determina la quantità di blocchi di memoria utilizzati per incamerare ed eseguire l'audio
 Dim music As Pointer


' Inizializza il dispositivo SDL audio:
   err = SDL_Init(SDL_INIT_AUDIO)
   If err < 0 Then Error.Raise("Impossibile inizializzare la libreria SDL: " & SDL_GetError())

' Inizializza la libreria "SDL_mixer" con specifiche impoostazioni audio:
   err = Mix_OpenAudio(audio_rate, AUDIO_S16SYS, STEREO, audio_buffers)
   If err <> 0 Then Error.Raise("Impossibile inizializzare l'audio: " & Mix_GetError())


' Carica il file audio:
   music = Mix_LoadMUS("/percorso/del/file_audio")
   If IsNull(music) Then Error.Raise("Impossibile caricare il file audio: " & Mix_GetError())

' Esegue il file audio. Se il secondo argomento è posto a 0 il file sarà eseguito soltanto una volta.
' Se è posto a -1 il file sarà esguito all'infinito:
   err = Mix_PlayMusic(music, 0)
   If err < 0 Then Error.Raise("Impossibile eseguire il file audio: " & Mix_GetError())


' Attende che sia terminato il file audio:
   While Mix_PlayingMusic() <> 0
     Wait 0.01
   Wend

' Libera la memoria precedentemente allocata per l'esecuzione sonora:
   Mix_FreeChunk(music)
 
' Chiude l'interfaccia audio SDL e SDL_mixer:
   Mix_CloseAudio()
 
   SDL_Quit()

End


Note

[1] I formati eseguibili sono i seguenti:

  • WAVE/RIFF ( .wav )
  • AIFF ( .aiff )
  • VOC ( .voc )
  • MOD (.mod .xm .s3m .669 .it .med ed altri)
  • MIDI (.mid)
  • OggVorbis (.ogg)
  • MP3 (.mp3)


Riferimenti