首先看源碼:緩存
typedef struct SDL_AudioSpec { int freq; /**< DSP frequency -- samples per second */ Uint16 format; /**< Audio data format */ Uint8 channels; /**< Number of channels: 1 mono, 2 stereo */ Uint8 silence; /**< Audio buffer silence value (calculated) */ Uint16 samples; /**< Audio buffer size in samples (power of 2) */ Uint16 padding; /**< Necessary for some compile environments */ Uint32 size; /**< Audio buffer size in bytes (calculated) */ /** * This function is called when the audio device needs more data. * * @param[out] stream A pointer to the audio data buffer * @param[in] len The length of the audio buffer in bytes. * * Once the callback returns, the buffer will no longer be valid. * Stereo samples are stored in a LRLRLR ordering. */ void (SDLCALL *callback)(void *userdata, Uint8 *stream, int len); void *userdata; } SDL_AudioSpec;
SDL_AudioSpec結構體是用來描述某些音頻數據的格式。 結構體中的變量都會被SDL_OpenAudio()函數用到,想要用SDL處理音頻數據,必須搞懂這些基礎的東西。函數
freq 指定了每秒向音頻設備發送的sample數。經常使用的值爲:11025,22050,44100。值越高質量越好。ui
format 指定了每一個sample元素的大小和類型。可能取值以下:指針
AUDIO_U8code |
unsigned 8-bit samples.orm |
AUDIO_S8回調函數 |
signed 8-bit samples.源碼 |
AUDIO_U16 or AUDIO_U16LSBit |
並不是全部硬件都支持(unsigned 16-bit little-endian)io |
AUDIO_S16 or AUDIO_S16LSB |
並不是全部硬件都支持 (signed 16-bit little-endian) |
AUDIO_U16MSB |
並不是全部硬件都支持 (unsigned 16-bit big-endian) |
AUDIO_S16MSB |
並不是全部硬件都支持 (signed 16-bit big-endian) |
int32 support |
|
AUDIO_S32 or AUDIO_S32LSB |
32-bit integer samples |
AUDIO_S32MSB |
as above, but big-endian byte order |
float32 support |
|
AUDIO_F32 or AUDIO_F32LSB |
32-bit floating point samples |
AUDIO_F32MSB |
as above, but big-endian byte order |
本地音頻字節序 | |
AUDIO_U16SYS |
AUDIO_U16LSB or AUDIO_U16MSB 取決於硬件CPU字節序 |
AUDIO_S16SYS |
AUDIO_S16LSB or AUDIO_S16MSB 取決於硬件CPU字節序 |
AUDIO_S32SYS |
AUDIO_S32LSB or AUDIO_S32MSB 取決於硬件CPU字節序 |
AUDIO_F32SYS |
AUDIO_F32LSB or AUDIO_F32MSB 取決於硬件CPU字節序 |
channels 指定了聲音的通道數:1(單聲道)2(立體聲)。
samples 這個值表示音頻緩存區的大小(以sample計)。一個sample是一段大小爲 format * channels 的音頻數據。
size 這個值表示音頻緩存區的大小(以byte計)。
silence 設置靜音的值。
padding 考慮到兼容性的一個參數。
callback 是獲取音頻數據後的回調函數,能夠做解碼獲取的音頻碼流及輸出到設備的操做。例如:
void audio_callback(void *userdata, Uint8 *stream, int len){ AVCodecContext *aCodecCtx = (AVCodecContext *) userdata; int len1, audio_size; static uint8_t audio_buf[(MAX_AUDIO_FRAME_SIZE * 3) / 2]; static unsigned int audio_buf_size = 0; static unsigned int audio_buf_index = 0; SDL_memset(stream, 0, len); printf("audio_callback len=%d \n", len); //向設備發送長度爲len的數據 while(len > 0){ //緩衝區中無數據 if(audio_buf_index >= audio_buf_size){ //從packet中解碼數據 audio_size = audio_decode_frame(aCodecCtx, audio_buf, audio_buf_size); printf("audio_decode_frame finish audio_size=%d \n", audio_size); if(audio_size < 0){//沒有解碼到數據或者出錯,填充0 audio_buf_size = 1024; memset(audio_buf, 0, audio_buf_size); }else{ audio_buf_size = audio_size; } audio_buf_index = 0; } len1 = audio_buf_size - audio_buf_index; if(len1 > len) len1 = len; SDL_MixAudio(stream, audio_buf + audio_buf_index, len, SDL_MIX_MAXVOLUME); len -= len1; stream += len1; audio_buf_index += len1; } }
關於callback的參數:
userdata |
程序特定的參數,保存在SDL_AudioSpec結構體中 |
stream |
指向緩存區的指針,這個緩存區將被這個回調函數填滿 |
len |
上面緩存區的大小(字節數) |