#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;
}
我这里只是将官网给出的例子添加了注释,方便大家理解