|
|
Riga 1: |
Riga 1: |
− | La libreria '''SDL2''' è un [http://it.wikipedia.org/wiki/Application_programming_interface API] multi-piattaforma contenente funzioni per la gestione multimediale dell'audio e del video.
| + | #REDIRECT [[Eseguire_un_file_audio_mediante_le_funzioni_esterne_del_API_di_SDL_2]] |
− | | |
− | | |
− | Per poter utilizzare le funzioni esterne di ''SDL2'' in Gambas, si richiameranno anche separatamente per lo più le seguenti librerie (con le attuali versioni):
| |
− | * ''libSDL2-2.0.so''
| |
− | * ''libSDL2_mixer-2.0.so''
| |
− | | |
− | | |
− | E' possibile riprodurre più suoni contemporaneamente utilizzando le funzioni della sub-libreria mixer audio multi-canale ''libSDL2_mixer''.
| |
− | | |
− | | |
− | ==Eseguire un file WAV intercettando il canale sul quale viene eseguito==
| |
− | E' possibile eseguire file '''WAV''' su flussi audio, definiti ''canali''. L'esecuzione sarà effettuata usando la funzione ''Mix_PlayChannelTImed''. Questa risorsa consente di eseguire sino a 32 file audio di formato WAV contemporaneamente. La predetta 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.
| |
− | Library "libSDL2-2.0"
| |
− |
| |
− | Private Const SDL_INIT_AUDIO As Integer = 16
| |
− | Private Const MIX_DEFAULT_FORMAT As Integer = 32784
| |
− |
| |
− | <FONT Color=gray>' ''int SDL_Init(Uint32 flags)''
| |
− | ' ''Initialize the SDL library.''</font>
| |
− | Private Extern SDL_Init(flags As Integer) As Integer
| |
− |
| |
− | <FONT Color=gray>' ''const char* SDL_GetError(void)''
| |
− | ' Retrieve a message about the last error that occurred.''</font>
| |
− | Private Extern SDL_GetError() As String
| |
− |
| |
− | <FONT Color=gray>' ''void SDL_Quit(void)''
| |
− | ' Clean up all initialized subsystems.''</font>
| |
− | Private Extern SDL_Quit()
| |
− |
| |
− |
| |
− | Library "libSDL2_mixer-2.0"
| |
− |
| |
− | Private Const MIX_DEFAULT_FREQUENCY As Integer = 22050
| |
− |
| |
− | <FONT Color=gray>' ''int Mix_OpenAudio(int frequency, Uint16 format, int channels, int chunksize)''
| |
− | ' ''Initialize the mixer API.''</font>
| |
− | Private Extern Mix_OpenAudio(frequency As Integer, format16 As Short, channels As Integer, chunksize As Integer) As Integer
| |
− |
| |
− | <FONT Color=gray>' ''int Mix_QuerySpec(int *frequency, Uint16 *format, int *channels)''
| |
− | ' ''Get the actual audio format in use by the opened audio device.''</font>
| |
− | Private Extern Mix_QuerySpec(frequencyP As Pointer, formatP As Pointer, channelsP As Pointer) As Integer
| |
− |
| |
− | <FONT Color=gray>' ''SDL_RWops * SDL_RWFromFile(const char *file, const char *mode)''
| |
− | ' ''Create a new SDL_RWops structure for reading from and/or writing to a named file. ''</font>
| |
− | Private Extern SDL_RWFromFile(filewav As String, mode As String) As Pointer
| |
− |
| |
− | <FONT Color=gray>' ''Mix_Chunk * Mix_LoadWAV_RW(SDL_RWops *src, int freesrc)''
| |
− | ' ''Load a wave file or a music.''</font>
| |
− | Private Extern Mix_LoadWAV_RW(src As Pointer, freesrc As Integer) As Pointer
| |
− |
| |
− | <FONT Color=gray>' ''int Mix_PlayChannelTimed(int channel, Mix_Chunk *chunk, int loops, int ticks)''
| |
− | ' ''Play an audio chunk on a specific channel.''</font>
| |
− | Private Extern Mix_PlayChannelTimed(channel As Integer, chunk As Pointer, loops As Integer, ticks As Integer) As Integer
| |
− |
| |
− | <FONT Color=gray>' ''int Mix_Playing(int channel)''
| |
− | ' ''Check the status of a specific channel.''</font>
| |
− | Private Extern Mix_Playing(channel As Integer) As Integer
| |
− |
| |
− | <FONT Color=gray>' ''void Mix_FreeChunk(Mix_Chunk *chunk)''
| |
− | ' ''Free an audio chunk previously loaded.''</font>
| |
− | Private Extern Mix_FreeChunk(chunk As Pointer)
| |
− |
| |
− | <FONT Color=gray>' ''void Mix_CloseAudio(void)''
| |
− | ' ''Close the mixer, halting all playing audio.''</font>
| |
− | Private Extern Mix_CloseAudio()
| |
− |
| |
− |
| |
− | '''Public''' Sub Main()
| |
− |
| |
− | Dim err, canale As Integer
| |
− | Dim canali As String
| |
− | Dim wave As Pointer
| |
− | <FONT Color=gray>' ''Vengono impostati i valori predefiniti iniziali della frequenza, del formato e del numero dei canali del file WAV caricato.''
| |
− | ' ''Volendo adattare tali valori alle reali caratteristiche del file WAV caricato, bisognerà variare i valori iniziali delle rispettive variabili:''</font>
| |
− | Dim audio_rate As Integer = MIX_DEFAULT_FREQUENCY
| |
− | Dim audio_format As Short = MIX_DEFAULT_FORMAT
| |
− | Dim audio_channels As Integer = 2
| |
− |
| |
− | <FONT Color=gray>' ''Inizializza la libreria SDL2:''</font>
| |
− | err = SDL_Init(SDL_INIT_AUDIO)
| |
− | If err < 0 Then Error.Raise("Impossibile inizializzare la libreria SDL2: " & SDL_GetError())
| |
− |
| |
− | <FONT Color=gray>' ''Apre il dispositivo audio:''</font>
| |
− | If Mix_OpenAudio(audio_rate, audio_format, audio_channels, 4096) < 0 Then
| |
− | Error.Raise("Impossibile aprire il dispositivo audio: " & SDL_GetError())
| |
− | Else
| |
− | Mix_QuerySpec(VarPtr(audio_rate), VarPtr(audio_format), VarPtr(audio_channels))
| |
− | Endif
| |
− | If audio_channels > 2 Then
| |
− | canali = "surround"
| |
− | Else
| |
− | If audio_channels > 1 Then
| |
− | canali = "stereo"
| |
− | Else
| |
− | canali = "mono"
| |
− | Endif
| |
− | Endif
| |
− | Print "Audio aperto a "; audio_rate; " Hz, "; audio_format And 255; " bit, "; canali
| |
− |
| |
− | <FONT Color=gray>' ''Carica il file WAV:''</font>
| |
− | wave = Mix_LoadWAV_RW(SDL_RWFromFile("<FONT Color=gray>''/percorso/del/file.wav''</font>", "rb"), 1)
| |
− | If IsNull(wave) Then Error.Raise("Impossibile caricare il file WAV: " & SDL_GetError())
| |
− |
| |
− | canale = Mix_PlayChannelTimed(-1, wave, 0, 0)
| |
− | If canale = -1 Then Error.Raise("Impossibile eseguire il file WAV: " & SDL_GetError())
| |
− |
| |
− | While Mix_Playing(canale) <> 0
| |
− | Wait 0.01
| |
− | Wend
| |
− |
| |
− |
| |
− | <FONT Color=gray>' ''Va in chiusura:''</font>
| |
− | Mix_FreeChunk(wave)
| |
− | 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:
| |
− | Library "libSDL2-2.0"
| |
− |
| |
− | Private Const SDL_INIT_AUDIO As Integer = 16
| |
− | Private Const MIX_DEFAULT_FORMAT As Integer = 32784
| |
− |
| |
− | <FONT Color=gray>' ''int SDL_Init(Uint32 flags)''
| |
− | ' ''Initialize the SDL library.''</font>
| |
− | Private Extern SDL_Init(flags As Integer) As Integer
| |
− |
| |
− | <FONT Color=gray>' ''const char* SDL_GetError(void)''
| |
− | ' Retrieve a message about the last error that occurred.''</font>
| |
− | Private Extern SDL_GetError() As String
| |
− |
| |
− | <FONT Color=gray>' ''void SDL_Quit(void)''
| |
− | ' Clean up all initialized subsystems.''</font>
| |
− | Private Extern SDL_Quit()
| |
− |
| |
− |
| |
− | Library "libSDL2_mixer-2.0"
| |
− |
| |
− | Private Const MIX_DEFAULT_FREQUENCY As Integer = 22050
| |
− |
| |
− | <FONT Color=gray>' ''int Mix_OpenAudio(int frequency, Uint16 format, int channels, int chunksize)''
| |
− | ' ''Initialize the mixer API.''</font>
| |
− | Private Extern Mix_OpenAudio(frequency As Integer, format16 As Short, channels As Integer, chunksize As Integer) As Integer
| |
− |
| |
− | <FONT Color=gray>' ''int Mix_QuerySpec(int *frequency, Uint16 *format, int *channels)''
| |
− | ' ''Get the actual audio format in use by the opened audio device.''</font>
| |
− | Private Extern Mix_QuerySpec(frequencyP As Pointer, formatP As Pointer, channelsP As Pointer) As Integer
| |
− |
| |
− | <FONT Color=gray>' ''SDL_RWops * SDL_RWFromFile(const char *file, const char *mode)''
| |
− | ' ''Create a new SDL_RWops structure for reading from and/or writing to a named file. ''</font>
| |
− | Private Extern SDL_RWFromFile(filewav As String, mode As String) As Pointer
| |
− |
| |
− | <FONT Color=gray>' ''Mix_Chunk * Mix_LoadWAV_RW(SDL_RWops *src, int freesrc)''
| |
− | ' ''Load a wave file or a music.''</font>
| |
− | Private Extern Mix_LoadWAV_RW(src As Pointer, freesrc As Integer) As Pointer
| |
− |
| |
− | <FONT Color=gray>' ''int Mix_PlayChannelTimed(int channel, Mix_Chunk *chunk, int loops, int ticks)''
| |
− | ' ''Play an audio chunk on a specific channel.''</font>
| |
− | Private Extern Mix_PlayChannelTimed(channel As Integer, chunk As Pointer, loops As Integer, ticks As Integer) As Integer
| |
− |
| |
− | <FONT Color=gray>' ''int Mix_Playing(int channel)''
| |
− | ' ''Check the status of a specific channel.''</font>
| |
− | Private Extern Mix_Playing(channel As Integer) As Integer
| |
− |
| |
− | <FONT Color=gray>' ''void Mix_FreeChunk(Mix_Chunk *chunk)''
| |
− | ' ''Free an audio chunk previously loaded.''</font>
| |
− | Private Extern Mix_FreeChunk(chunk As Pointer)
| |
− |
| |
− | <FONT Color=gray>' ''void Mix_CloseAudio(void)''
| |
− | ' ''Close the mixer, halting all playing audio.''</font>
| |
− | Private Extern Mix_CloseAudio()
| |
− |
| |
− |
| |
− | '''Public''' Sub Main()
| |
− |
| |
− | Dim err, cnl As Integer
| |
− | Dim canale As New Integer[]
| |
− | Dim canali As String
| |
− | Dim percorsoFile As String[] = ["<FONT Color=gray>''/percorso/del/primo/file.wav''</font>", "<FONT Color=gray>''/percorso/del/secondo/file.wav''</font>"]
| |
− | Dim wave As New Pointer[]
| |
− | <FONT Color=gray>' ''Vengono impostati i valori predefiniti iniziali della frequenza, del formato e del numero dei canali del file WAV caricato.''
| |
− | ' ''Volendo adattare tali valori alle reali caratteristiche del file WAV caricato, bisognerà variare i valori iniziali delle rispettive variabili:''</font>
| |
− | Dim audio_rate As Integer = MIX_DEFAULT_FREQUENCY
| |
− | Dim audio_format As Short = MIX_DEFAULT_FORMAT
| |
− | Dim audio_channels As Integer = 2
| |
− |
| |
− | <FONT Color=gray>' ''Inizializza la libreria SDL2:''</font>
| |
− | err = SDL_Init(SDL_INIT_AUDIO)
| |
− | If err < 0 Then Error.Raise("Impossibile inizializzare la libreria SDL2: " & SDL_GetError())
| |
− |
| |
− | <FONT Color=gray>' ''Apre il dispositivo audio:''</font>
| |
− | If Mix_OpenAudio(audio_rate, audio_format, audio_channels, 4096) < 0 Then
| |
− | Error.Raise("Impossibile aprire il dispositivo audio: " & SDL_GetError())
| |
− | Else
| |
− | Mix_QuerySpec(VarPtr(audio_rate), VarPtr(audio_format), VarPtr(audio_channels))
| |
− | Endif
| |
− | If audio_channels > 2 Then
| |
− | canali = "surround"
| |
− | Else
| |
− | If audio_channels > 1 Then
| |
− | canali = "stereo"
| |
− | Else
| |
− | canali = "mono"
| |
− | Endif
| |
− | Endif
| |
− | Print "Audio aperto a "; audio_rate; " Hz, "; audio_format And 255; " bit, "; canali
| |
− |
| |
− | With wave
| |
− | <FONT Color=gray>' ''Carica il primo file WAV:''</font>
| |
− | .Add(Mix_LoadWAV_RW(SDL_RWFromFile(percorsoFile[0], "rb"), 1))
| |
− | <FONT Color=gray>' ''Carica il secondo file WAV:''</font>
| |
− | .Add(Mix_LoadWAV_RW(SDL_RWFromFile(percorsoFile[1], "rb"), 1))
| |
− | End With
| |
− |
| |
− | <FONT Color=gray>' ''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:''</font>
| |
− | canale.Add(Mix_PlayChannelTimed(-1, wave[0], 0, 0))
| |
− | If canale[0] = -1 Then Error.Raise("Impossibile eseguire il 1° file WAV: " & SDL_GetError())
| |
− |
| |
− | canale.Add(Mix_PlayChannelTimed(-1, wave[1], 0, 0))
| |
− | If canale[1] = -1 Then Error.Raise("Impossibile eseguire il 2° file WAV: " & SDL_GetError())
| |
− |
| |
− | <FONT Color=gray>' ''Verifica quale file wav possiede la maggiore dimensione:''</font>
| |
− | If Stat(percorsoFile[0]).Size > Stat(percorsoFile[1]).Size Then cnl = 0
| |
− |
| |
− | <FONT Color=gray>' ''Attende che sia terminato il file WAV di maggiore dimensione (e quindi presumibilmente quello con maggiore durata):''</font>
| |
− | While Mix_Playing(cnl) <> 0
| |
− | Wait 0.01
| |
− | Wend
| |
− |
| |
− | <FONT Color=gray>' ''Libera la memoria precedentemente allocata per l'esecuzione dei due file wav:''</font>
| |
− | Mix_FreeChunk(wave[0])
| |
− | Mix_FreeChunk(wave[1])
| |
− |
| |
− | <FONT Color=gray>' ''Chiude l'interfaccia audio SDL e SDL_mixer:''</font>
| |
− | Mix_CloseAudio()
| |
− |
| |
− | SDL_Quit()
| |
− |
| |
− | '''End'''
| |
− | | |
− | | |
− | | |
− | ==Eseguire gli altri formati di file audio==
| |
− | Per poter eseguire i file audio di altro formato (ma compreso anche lo stesso formato WAV) |'''[[#Note|1]]'''|, bisognerà utilizzare la funzione ''Mix_PlayMusic()'' appartenente alla libreria ''libSDL2_mixer-2.0.so.0.0.0''.
| |
− | <BR>Detta funzione non consente di poter eseguire più file contemporaneamente.
| |
− | Library "libSDL2-2.0"
| |
− |
| |
− | Private Const SDL_INIT_AUDIO As Integer = 16
| |
− | Private Const MIX_DEFAULT_FORMAT As Integer = 32784
| |
− |
| |
− | <FONT Color=gray>' ''int SDL_Init(Uint32 flags)''
| |
− | ' ''Initialize the SDL library.''</font>
| |
− | Private Extern SDL_Init(flags As Integer) As Integer
| |
− |
| |
− | <FONT Color=gray>' ''const char* SDL_GetError(void)''
| |
− | ' Retrieve a message about the last error that occurred.''</font>
| |
− | Private Extern SDL_GetError() As String
| |
− |
| |
− | <FONT Color=gray>' ''void SDL_Quit(void)''
| |
− | ' Clean up all initialized subsystems.''</font>
| |
− | Private Extern SDL_Quit()
| |
− |
| |
− |
| |
− | Library "libSDL2_mixer-2.0"
| |
− |
| |
− | Private Const MIX_DEFAULT_FREQUENCY As Integer = 22050
| |
− |
| |
− | <FONT Color=gray>' ''int Mix_OpenAudio(int frequency, Uint16 format, int channels, int chunksize)''
| |
− | ' ''Initialize the mixer API.''</font>
| |
− | Private Extern Mix_OpenAudio(frequency As Integer, format16 As Short, channels As Integer, chunksize As Integer) As Integer
| |
− |
| |
− | <FONT Color=gray>' ''int Mix_QuerySpec(int *frequency, Uint16 *format, int *channels)''
| |
− | ' ''Get the actual audio format in use by the opened audio device.''</font>
| |
− | Private Extern Mix_QuerySpec(frequencyP As Pointer, formatP As Pointer, channelsP As Pointer) As Integer
| |
− |
| |
− | <FONT Color=gray>' ''Mix_Music * Mix_LoadMUS(const char *file)''
| |
− | ' ''Load a wave file or a music.''</font>
| |
− | Private Extern Mix_LoadMUS(file As String) As Pointer
| |
− |
| |
− | <FONT Color=gray>' ''int Mix_PlayMusic(Mix_Music *music, int loops)''
| |
− | ' ''Play an audio chunk on a specific channel.''</font>
| |
− | Private Extern Mix_PlayMusic(music As Pointer, loops As Integer) As Integer
| |
− |
| |
− | <FONT Color=gray>' ''int Mix_PlayingMusic()''
| |
− | ' ''Check the status of a specific channel.''</font>
| |
− | Private Extern Mix_PlayingMusic() As Integer
| |
− |
| |
− | <FONT Color=gray>' ''void Mix_FreeChunk(Mix_Chunk *chunk)''
| |
− | ' ''Free an audio chunk previously loaded.''</font>
| |
− | Private Extern Mix_FreeChunk(chunk As Pointer)
| |
− |
| |
− | <FONT Color=gray>' ''void Mix_CloseAudio(void)''
| |
− | ' ''Close the mixer, halting all playing audio.''</font>
| |
− | Private Extern Mix_CloseAudio()
| |
− |
| |
− |
| |
− | '''Public''' Sub Main()
| |
− |
| |
− | Dim err As Integer
| |
− | Dim canali As String
| |
− | Dim music As Pointer
| |
− | <FONT Color=gray>' ''Vengono impostati i valori predefiniti iniziali della frequenza, del formato e del numero dei canali del file WAV caricato.''
| |
− | ' ''Volendo adattare tali valori alle reali caratteristiche del file audio caricato, bisognerà variare i valori iniziali delle rispettive variabili:''</font>
| |
− | Dim audio_rate As Integer = MIX_DEFAULT_FREQUENCY
| |
− | Dim audio_format As Short = MIX_DEFAULT_FORMAT
| |
− | Dim audio_channels As Integer = 2
| |
− |
| |
− | <FONT Color=gray>' ''Inizializza la libreria SDL2:''</font>
| |
− | err = SDL_Init(SDL_INIT_AUDIO)
| |
− | If err < 0 Then Error.Raise("Impossibile inizializzare la libreria SDL2: " & SDL_GetError())
| |
− |
| |
− | <FONT Color=gray>' ''Apre il dispositivo audio:''</font>
| |
− | If Mix_OpenAudio(audio_rate, audio_format, audio_channels, 4096) < 0 Then
| |
− | Error.Raise("Impossibile aprire il dispositivo audio: " & SDL_GetError())
| |
− | Else
| |
− | Mix_QuerySpec(VarPtr(audio_rate), VarPtr(audio_format), VarPtr(audio_channels))
| |
− | Endif
| |
− | If audio_channels > 2 Then
| |
− | canali = "surround"
| |
− | Else
| |
− | If audio_channels > 1 Then
| |
− | canali = "stereo"
| |
− | Else
| |
− | canali = "mono"
| |
− | Endif
| |
− | Endif
| |
− | Print "Audio aperto a "; audio_rate; " Hz, "; audio_format And 255; " bit, "; canali
| |
− |
| |
− | <FONT Color=gray>' ''Carica il file audio:''</font>
| |
− | music = Mix_LoadMUS("<FONT Color=gray>''/percorso/del/file/audio''</font>")
| |
− | If IsNull(music) Then Error.Raise("Impossibile caricare il file audio: " & SDL_GetError())
| |
− |
| |
− | <FONT Color=gray>' ''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:''</font>
| |
− | err = Mix_PlayMusic(music, 0)
| |
− | If err < 0 Then Error.Raise("Impossibile eseguire il file audio: " & SDL_GetError())
| |
− |
| |
− | While Mix_PlayingMusic() <> 0
| |
− | Wait 0.01
| |
− | Wend
| |
− |
| |
− |
| |
− | <FONT Color=gray>' ''Va in chiusura:''</font>
| |
− | Mix_FreeChunk(music)
| |
− | Mix_CloseAudio()
| |
− | SDL_Quit()
| |
− |
| |
− | '''End'''
| |
− | | |
− | | |
− | | |
− | | |
− | =Note=
| |
− | [1] I formati eseguibili sono i seguenti:
| |
− | * .WAV (WAV/RIFF)
| |
− | * .VOC (Creative Labs' Voice format)
| |
− | * .MP3 (MPEG-1 Layer 3 support)
| |
− | * [[La_gestione_dei_file_MIDI_mediante_le_funzioni_esterne_del_API_di_SDL|.MID]] (Musical Instrument Digital Interface)
| |
− | * .MOD (MOD file: .mod .xm .s3m .669 .it .med ed altri)
| |
− | * .OGG (Ogg file)
| |
− | * .SPX (Speex file)
| |
− | * .SHN (Shorten file)
| |
− | * .RAW (Raw sound data in any format)
| |
− | * .AU (Sun's Audio format)
| |
− | * .AIFF (Audio Interchange format)
| |
− | * .FLAC (Lossless audio compression)
| |
− | | |
− | | |
− | | |
− | | |
− | =Riferimenti=
| |
− | * http://wiki.libsdl.org/CategoryAPI
| |
− | * https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer_toc.html
| |