/**
*
* ffmpeg -i file_name.mp3 -acodec pcm_s16le -f s16le -ac 2 -ar 44100 file_name.pcm
* ffmpeg -i xiongmao.flv -vn -c:a pcm_s16le -f s16le -ac 2 -ar 44100 xiongmao.pcm
*
*/
#include <SDL2/SDL.h>
#define PATH_PCM "1.pcm"
#define PCM_BUF_SIZE 4096000
FILE *pcm_fp = NULL;
int isRun = 1;
int pcm_read_len;
char pcm_buf[PCM_BUF_SIZE];
// 回調函數
// 需要len位元組資料寫到指針stream處
// userdata 傳遞過來的參數
void user_feed_pcm(void *userdata, Uint8 *stream, int len)
{
if (!isRun)
{ // 如果程式要退出
return;
}
if (!pcm_fp) // 如果未打開檔案
{
pcm_fp = fopen(PATH_PCM, "r");
if (!pcm_fp) // 如果打開檔案失敗
{
SDL_Log("Failed to open pcm file %s!\n", PATH_PCM);
isRun = 0;
return;
}
}
SDL_memset(stream, 0, len); // 一定要清空!!!!
if ((pcm_read_len = fread(pcm_buf, 1, len, pcm_fp)) < 0) // 如果讀取錯誤
{
SDL_Log("Failed to read pcm file %s!\n", PATH_PCM);
isRun = 0;
return;
}
if (pcm_read_len == 0) // 讀取完畢~
{
isRun = 0;
return;
}
// 将PCM資料拷貝到聲霸卡的緩存區裡
SDL_MixAudio(stream, pcm_buf, pcm_read_len, SDL_MIX_MAXVOLUME / 32); // 破音就除個數
}
int main(int argc, char *argv[])
{
SDL_Init(SDL_INIT_AUDIO);
SDL_AudioSpec spec;
spec.freq = 44100;
spec.channels = 2;
spec.format = AUDIO_S16SYS;
spec.silence = 0;
spec.samples = 1024;
spec.callback = user_feed_pcm; // NULL 就使用 SDL_QueueAudio()來主動填充資料
spec.userdata = NULL;
if (SDL_OpenAudio(&spec, NULL) < 0)
{
SDL_Log("Failed to open audio device!\n");
goto __EXIT;
}
SDL_PauseAudio(0);
while (isRun)
{
SDL_Delay(20);
}
if (pcm_fp)
{
fclose(pcm_fp);
}
SDL_CloseAudio();
__EXIT:
SDL_Quit();
return 0;
}