#include "stdafx.h"
#include<stdlib.h>
#include<stdio.h>
#include<SDL.h>
#include<SDL_config.h>
static SDL_AudioSpec spec;
static Uint8 *sound = NULL;
static Uint32 soundlen = 0;
static int posindex = 0;
static Uint32 positions[64];
static void quit(int rc)
{
SDL_Quit();
exit(rc);
}
/*
_pos:userdata的數據
stream:需要填充的流
len:相應stream的大小
簡單來說就是將音頻在內存中的地址複製給stream,SDL會播放stream中對應地址的數據
*/
void SDLCALL fillerup(void *_pos, Uint8 *stream, int len)
{
Uint32 pos = *((Uint32*)_pos);
Uint8 *waveptr;
int waveleft;
/*設置當前聲音指針
聲音指針+當前播放的位置
*/
waveptr = sound + pos;
//剩餘聲音數據 聲音數據長度-當前播放的位置
waveleft = soundlen - pos;
/* 如果剩餘數據<需要的長度 */
while (waveleft <= len)
{
//拷貝剩餘數據到音頻緩衝區
SDL_memcpy(stream,waveptr,waveleft);
//音頻緩衝區stream指針後移
stream += waveleft;
len -= waveleft;
//拷貝玩剩餘數據
//waveptr指向 聲音數據開頭
waveptr = sound;
//長度等於len
waveleft = soundlen;
pos = 0;
}
SDL_memcpy(stream, waveptr, len);
pos += len;
*((Uint32*)_pos) = pos;
}
static int done = 0;
void poked(int sig)
{
done = 1;
}
static void iteration()
{
SDL_Event e;
SDL_AudioDeviceID dev;
//獲取當前等待的事件
while (SDL_PollEvent(&e))
{
if (e.type == SDL_QUIT)
{
done = 1;
}
else if (e.type==SDL_AUDIODEVICEADDED)//音頻添加
{
const char *name = SDL_GetAudioDeviceName(e.adevice.which, 0);
SDL_Log("new %s audio device :%s\n",e.adevice.iscapture?"capture":"output",name);
if (!e.adevice.iscapture)
{
positions[posindex] = 0;
spec.userdata = &positions[posindex++];
spec.callback = fillerup;
dev = SDL_OpenAudioDevice(name, 0, &spec, NULL, 0);
if (!dev)
{
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "can not open '%s':%s\n",name, SDL_GetError());
}
else
{
SDL_Log("opened '%s' as %u \n", name, (unsigned int)dev);
//循環播放音樂
SDL_PauseAudioDevice(dev, 0);
SDL_OpenAudio(&spec,NULL);
}
}
else if (e.type==SDL_AUDIODEVICEREMOVED)//音頻移除
{
dev = (SDL_AudioDeviceID)e.adevice.which;
SDL_Log("%s device %u removed.\n", e.adevice.iscapture ? "capture" : "output", (unsigned int)dev);
//關閉音頻設備
SDL_CloseAudioDevice(dev);
}
}
}
}
/**
音頻播放的步驟
1.初始化SDL模塊,這裏是要播放音樂,所有初始化SDL_INIT_AUDIO和視頻模塊
2.創建窗口
3.加載音頻
4.播放音頻
5.視頻音頻
6.退出SDL
*/
int main(int argc, char* argv[])
{
int i;
char filename[4096];
//設置顯示application 的log信息
SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
//設置sdl要初始化的模塊
if (SDL_Init(SDL_INIT_AUDIO | SDL_INIT_VIDEO)<0)
{
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,"couldn't initialize SDL:%s\n",SDL_GetError());
return 1;
}
//創建窗口
//SDL_MinimizeWindow(SDL_CreateWindow("test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0));
//獲取文件名
if (argc > 1)
{
SDL_strlcpy(filename, argv[1], sizeof(filename));
}
else
{
SDL_strlcpy(filename, "sample.wav", sizeof(filename));
//SDL_strlcpy(filename, "Now.mp3", sizeof(filename));
}
/**
將音頻文件加載到內存中
filename:文件名
spec:音頻的規格
sound:音頻的句柄
soundlen:音頻文件的長度
*/
if (SDL_LoadWAV(filename, &spec, &sound, &soundlen) == NULL)
{
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,"cound't load %s:%s \n",filename,SDL_GetError());
quit(1);
}
SDL_Log("available audio drivers");
//打印音頻設備
for (i = 0; i < SDL_GetNumAudioDrivers(); i++)
{
SDL_Log("%i:%s", i, SDL_GetAudioDriver(i));
}
//查看當前使用的音頻設備
SDL_Log("Using audio driver:%s\n", SDL_GetCurrentAudioDriver());
while (!done)
{
SDL_Delay(100);
iteration();
}
//釋放音頻內存
SDL_FreeWAV(sound);
//退出sdl
SDL_Quit();
system("pause");
return 0;
}
我這裏只是將官網給出的例子添加了註釋,方便大家理解