SDL2.0學習筆記6--用SDL播放音訊wave檔案
阿新 • • 發佈:2019-02-06
#include "SDL.h" struct { Uint8 *sound; // pointer to wave data Uint32 soundlen; // length of wave data int soundpos; // current play position }wave; int done; static void quit(int rc) { SDL_Quit(); exit(rc); } void SDLCALL fill_audio(void *unused, Uint8 *stream, int len) { Uint8 *waveptr; int waveleft; int copylen; SDL_memset(stream, 0, len); if (wave.soundpos == wave.soundlen) { done = 1; return; } waveptr = wave.sound + wave.soundpos; waveleft = wave.soundlen - wave.soundpos; waveleft <= len ? (copylen = waveleft) : (copylen = len); SDL_memcpy(stream, waveptr, copylen); wave.soundpos += copylen; SDL_Log("len: %d, copylen:%d\n", len, copylen); } /* SDL播放音訊wave檔案測試 */ int audio_test() { SDL_AudioSpec spec; const char * audio_file = "sample.wav"; done = 0; // 1. init SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); if (SDL_Init(SDL_INIT_AUDIO) < 0) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL:%s\n", SDL_GetError()); return (1); } // 2. open audio wave file if (SDL_LoadWAV(audio_file, &spec, &wave.sound, &wave.soundlen) == NULL) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", audio_file, SDL_GetError()); quit(1); } spec.callback = fill_audio; // 3. open audio if (SDL_OpenAudio(&spec, NULL) < 0) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open audio: %s\n", SDL_GetError()); SDL_FreeWAV(wave.sound); quit(2); } SDL_Log("Using audio driver: %s\n", SDL_GetCurrentAudioDriver()); // 4. play SDL_PauseAudio(0); /* 5. fill audio data, it's be done by fill_audio */ // 6. waiting for play end while (0 == done) { SDL_Delay(1); } // 7. close SDL_CloseAudio(); SDL_FreeWAV(wave.sound); SDL_Quit(); return 0; }
以上程式碼參考自SDL的test資料夾下的loopwave.c函式。
由上,用SDL播放音訊wave檔案包含如下流程:
1、 呼叫SDL_Init(SDL_INIT_AUDIO)初始化音訊子系統;
2、 呼叫SDL_LoadWAW()開啟音訊wave檔案,獲取對應的spec、波形資料及波形資料長度等資訊;
3、 呼叫SDL_OpenAudio()開啟音訊裝置(在這之前還需要設定spec的callback成員),這函式實際上是啟動了SDL_RunAudio執行緒,用於實際的音訊播放;
4、 呼叫SDL_PauseAudio(0)播放音訊;
5、 呼叫spec.callback()函式,填充音訊資料(這一步由SDL_RunAudio執行緒完成);
6、 待播放完成後,關閉音訊音訊裝置(SDL_CloseAudio()),釋放波形資料buffer(SDL_FreeWAV()),然後退出。