SDL2文章列表git
SDL2入門github
SDL2事件處理bash
SDL2紋理渲染函數
原本計劃寫FFmpeg+SDL2視頻播放,可是發現要說的內容有點多,因此仍是先從簡單的音頻數據播放開始,一步一步來。post
int SDLCALL SDL_OpenAudio(SDL_AudioSpec * desired, SDL_AudioSpec * obtained);
// desired:指望的參數。
// obtained:實際音頻設備的參數,通常狀況下設置爲NULL便可。
複製代碼
//在這個結構體中包含了音頻的各類參數
typedef struct SDL_AudioSpec {
int freq; /**< 音頻採樣率*/
SDL_AudioFormat format; /**< 音頻數據格式 */
Uint8 channels; /**< 聲道數: 1 單聲道, 2 立體聲 */
Uint8 silence; /**< 設置靜音的值*/
Uint16 samples; /**< 音頻緩衝區中的採樣個數,要求必須是2的n次*/
Uint16 padding; /**< 考慮到兼容性的一個參數*/
Uint32 size; /**< 音頻緩衝區的大小,以字節爲單位*/
SDL_AudioCallback callback; /**< 填充音頻緩衝區的回調函數 */
void *userdata; /**< 用戶自定義的數據 */
} SDL_AudioSpec;
複製代碼
當音頻設備須要更多數據的時候會調用該回調函數。ui
// userdata:SDL_AudioSpec結構中的用戶自定義數據,通常狀況下能夠不用。
// stream:該指針指向須要填充的音頻緩衝區。
// len:音頻緩衝區的大小(以字節爲單位)。
void (SDLCALL * SDL_AudioCallback) (void *userdata,
Uint8 *stream,
int len);
複製代碼
// 當pause_on設置爲0的時候便可開始播放音頻數據。設置爲1的時候,將會播放靜音的值。
void SDLCALL SDL_PauseAudio(int pause_on) 複製代碼
#include <stdio.h>
#include <tchar.h>
#include <SDL_types.h>
#include "SDL.h"
static Uint8 *audio_chunk;
static Uint32 audio_len;
static Uint8 *audio_pos;
int pcm_buffer_size = 4096;
//回調函數,音頻設備須要更多數據的時候會調用該回調函數
void read_audio_data(void *udata, Uint8 *stream, int len) {
SDL_memset(stream, 0, len);
if (audio_len == 0)
return;
len = (len > audio_len ? audio_len : len);
SDL_MixAudio(stream, audio_pos, len, SDL_MIX_MAXVOLUME);
audio_pos += len;
audio_len -= len;
}
int WinMain(int argc, char *argv[]) {
if (SDL_Init(SDL_INIT_AUDIO | SDL_INIT_TIMER)) {
printf("Could not initialize SDL - %s\n", SDL_GetError());
return -1;
}
SDL_AudioSpec spec;
spec.freq = 44100;//根據你錄製的PCM採樣率決定
spec.format = AUDIO_S16SYS;
spec.channels = 1; //單聲道
spec.silence = 0;
spec.samples = 1024;
spec.callback = read_audio_data;
spec.userdata = NULL;
if (SDL_OpenAudio(&spec, NULL) < 0) {
printf("can't open audio.\n");
return -1;
}
FILE *fp = fopen("C:\\Users\\lenovo\\Desktop\\1111111.pcm", "rb+");
if (fp == NULL) {
printf("cannot open this file\n");
return -1;
}
char *pcm_buffer = (char *) malloc(pcm_buffer_size);
//播放
SDL_PauseAudio(0);
while (1) {
if (fread(pcm_buffer, 1, pcm_buffer_size, fp) != pcm_buffer_size) { //從文件中讀取數據,剩下的就交給音頻設備去完成了,它播放完一段數據後會執行回調函數,獲取等多的數據
break;
}
audio_chunk = (Uint8 *) pcm_buffer;
audio_len = pcm_buffer_size; //長度爲讀出數據長度,在read_audio_data中作減法
audio_pos = audio_chunk;
while (audio_len > 0) //判斷是否播放完畢
SDL_Delay(1);
}
free(pcm_buffer);
SDL_Quit();
return 0;
}
複製代碼
OK!第一步完成,能正常播放出聲音了。this
想要錄製PCM本身試一下?能夠試試用這個Android音視頻(五) OpenSL ES錄製、播放音頻(帶源碼)錄製一段。spa