1. 程式人生 > >SDL音訊 播放庫 函式介紹

SDL音訊 播放庫 函式介紹

Dir: 參考了各種文章,先儲存,隨需隨查。目前包含以下內容: SDL_OpenAudio SDL_PauseAudio PCM SDL_mixAudio SDL_CreateThread


1.SDL_OpenAudio

這個函式很關鍵,這個函式將獲取你裝置的Audio並將其開啟,無論你在當前的軟體中的哪一個程序,都可以訪問到這個裝置,並對裝置進行操作(列如:SDL_PauseAudioSDL_CloseAudio)

值得注意的是,裝置Audio只能開啟一次,我曾經嘗試多執行緒開啟多個
Audio裝置,最後都失敗了,返回ErrorAudio已經開啟,那一瞬間我懵了,既然不能用多執行緒,如何播放多個音訊呢?別急,奧祕在SDL_mixAudio裡面,稍後我回提。

2.SDL_PauseAudio

每次呼叫這個函式,裝置都將回調你在開啟Audio時預設的回撥函式(也就是SDL_AudioSpec.callback)。這樣的回撥允許你一次次的將PCMbuffer填入Audio預設的steam中,使得裝置順利的播放音訊檔案。而如何將buffer填入steam中呢?則需要使用SDL_mixAudio

3.PCM

什麼是PCM?可以自習搜尋

PCM看詳細的介紹。簡單的來說,音訊檔案解壓後的檔案格式就是PCM,而SDL僅提供播放PCMWAV(都是未壓縮的檔案格式)的播放方法。簡單來說,要想播放MP3等通用格式,必須先解碼成音訊格式檔案,再進行播放,當然也可以一邊解壓一邊播放,只是需要使用多執行緒罷了。使用SDL_Thread來建立並管理執行緒,蠻方便的。(執行緒我以後再總結)

4.SDL_mixAudio

我最想說的就是這個,因為我苦苦尋求了半天的同時播放多個音訊檔案,奧祕就在SDL_mixAudio。這個函式其實很傻很簡單,無非是把兩個buffer內容疊加起來。於是你只需要把希望播放的音訊buffer疊加在一起,就可以成功的播放多個音訊檔案。官方給的例子是這樣的

void audio_callback(void*udata, Uint8 *stream, int len)
{
   
SDL_MixAudio(stream, audio_pos, len,SDL_MIX_MAXVOLUME);
}

這就是把streamaudio_pos兩個buffer疊加到stream當中,其中的使用方式大家多試一試吧。

來自 <http://blog.csdn.net/tropicofcancer9/article/details/53996980>

 

當我們開始播放音訊時,SDL將持續的呼叫回撥函式,且用一些位元組來填充聲音buffer

freq: 取樣率

format:這告訴SDL我們將使用什麼格式。S16SYS中的第一個S表示“signed"(有符號),16表示每個取樣有16位,SYS表示大小端順序依賴系統。這就是avcodec_decode_audio2告訴我們進來的音訊的格式。

channels: 音訊通道的數量

silence:這是表示是否靜音。因為音訊是signed,0就是預設值。

samples:這個表示當SDL需要更多音訊時,我們要SDL分配的buffer的大小。一個比較好的值是512和8192之間的值。ffplay用1024.

callback這裡我們傳遞真正的回撥函式。下面再詳細討論。

userdata:SDL給我們的回撥函式一個紙箱userdata的void指標,這個資料時我們的回撥函式需要的。我們要讓它知道我們的codeccontext;

 

來自 <http://blog.csdn.net/gengxt2003/article/details/51494653>

 

SDL_OpenAudio函式:

用此函式來開啟音響裝置。

int SDL_OpenAudio(SDL_AudioSpec* desired,
                 
SDL_AudioSpec*obtained)

例子:

[cpp]view plaincopyprint?

1.  SDL_AudioSpec want, have;  

2.    

3.  SDL_memset(&want, 0, sizeof(want)); /* or SDL_zero(want) */  

4.  want.freq = 48000;  

5.  want.format = AUDIO_F32;  

6.  want.channels = 2;  

7.  want.samples = 4096;  

8.  want.callback = MyAudioCallback; /* you wrote this function elsewhere. */  

9.    

1        ifif(SDL_OpenAudio(&want, &have) < 0) {  

11.    SDL_Log("Failed to open audio: %s", SDL_GetError());  

12.}else{  

13.    if (have.format != want.format) {  

14.        SDL_Log("We didn't get Float32 audio format.");  

15.    }  

16.    SDL_PauseAudio(0); /* start audio playing. */  

17.    SDL_Delay(5000); /* let the audio callback play some sound for 5 seconds. */  

18.    SDL_CloseAudio();  

19.}  

 

來自 <http://blog.csdn.net/caimouse/article/details/53508316>

 

 

SDL_MixAudio函式

SDL_MixAudio函式:

對音樂資料進行混音。

void SDL_MixAudio(Uint8*       dst,
                  const Uint8*src,
                 
Uint32       len,
                  int          volume)

例子:

[cpp]view plaincopyprint?

1.  SDL_MixAudio(stream, gSndPlayer.pos[i], len, SDL_MIX_MAXVOLUME);  

 

[cpp]view plaincopyprint?

1. vvoid fill_audio(void *udata, Uint8 *stream, int len)  

2.  {  

3.  ifif (audio_len == 0)  

4.  {  

5.     printf("audio_len=0\n");  

6.     return;  

7.  }  

8.  len = (len>audio_len?audio_len:len);  

9.  SDL_MixAudio(stream,audio_pos,len,SDL_MIX_MAXVOLUME);//對音訊資料進行混音  

10.audio_pos+=len;//更新播放位置  

11.audio_len-=len;//更新資料長度  

12.}  

 

來自 <http://blog.csdn.net/caimouse/article/details/53502024>

 

 

SDL_CreateThread

1.    /**

2.    Create a thread.

3.    */

4.    externDECLSPEC SDL_Thread *SDLCALL

5.    SDL_CreateThread(SDL_ThreadFunctionfn, const char *name, void *data,

6.    pfnSDL_CurrentBeginThreadpfnBeginThread,

7.    pfnSDL_CurrentEndThreadpfnEndThread);


來自 <https://www.cnblogs.com/findman/p/6050589.html>

ID

引數

說明

1

SDL_ThreadFunction fn

執行緒所呼叫的函式

2

const char *name 

執行緒的名稱

3

void *data 

執行緒所傳入的資料

4

pfnSDL_CurrentBeginThread pfnBeginThread 

開始執行緒

5

pfnSDL_CurrentEndThread pfnEndThread 

結束執行緒

 

來自 <https://www.cnblogs.com/findman/p/6050589.html>