sdl主要用图形界面显示及播放声音,本人刚刚接触sdl,写了个简单的入门程序,实现播放声音文件,现分享一下当做个笔记。
// sound2.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
extern "C"
{
//SDL
#include "sdl/SDL.h"
#include "sdl/SDL_thread.h"
#pragma comment(lib, "lib\\SDL2main.lib")
#pragma comment(lib, "lib\\SDL2.lib")
};
#include <iostream>
using namespace std;
#define SOUND_DATA_LEN 409600//samples*channel*2byte=4096的倍数
//音频数据结构
typedef struct SoundData
{
Uint8 buffer[SOUND_DATA_LEN];//数据缓存
Uint8 *position;//缓存当前播放指针
Uint32 length;//待播放的缓存长度
}SoundData;
//SDL 2.0
//播放回调
void fill_audio(void *udata, Uint8 *stream, int len)
{
SoundData* sd = (SoundData*)udata;
SDL_memset(stream, 0, len);
//缓存数据已播放完毕
if(sd->length <= 0)
{
return;
}
//缓存中能播放最大的长度
len = len > sd->length ?sd->length : len;
//将数据混合至声卡设备
SDL_MixAudio(stream, sd->position, len, SDL_MIX_MAXVOLUME);
sd->position += len;//当前播放位置更新
sd->length -= len;//缓存剩余长度更新
}
int _tmain(int argc, _TCHAR* argv[])
{
char *file_name = "Sweety - 樱花草.wav";//只支持.wav文件
//声音缓存结构
SoundData sd;
//步骤(1)设置音频信息
//SDL 2.0 Support for multiple windows
SDL_AudioSpec wanted_spec;
wanted_spec.freq = 44100;//44.1KHz采样率
wanted_spec.format = AUDIO_S16SYS;//采样数据格式
wanted_spec.channels = 2;//2声道
wanted_spec.silence = 0;//静音时大小
wanted_spec.samples = 1024;//每次播放长度1024*2channels*2byte
wanted_spec.callback = fill_audio;//设置播放回调函数
wanted_spec.userdata = &sd;//传递数据给回调函数
//步骤(2)打开音频设备
if (SDL_OpenAudio(&wanted_spec, NULL)<0)
{
printf("can't open audio.\n");
goto end;
}
FILE* file = fopen(file_name, "rb");
if(!file)
{
cout<<"无法打开声音文件:"<<file_name<<endl;
goto end;
}
int count = 0;//文件帧数
int len = 0;//能读文件数据长度
//步骤(3)开始播放
SDL_PauseAudio(0);
//循环读文件数据至缓存
while(len = fread(sd.buffer, 1, SOUND_DATA_LEN, file))
{
sd.length = len;//Audio buffer length
sd.position = sd.buffer;
//存存数据未播放完等待
while(sd.length>0)
{
SDL_Delay(1);
}
printf("文件帧:%03d\n", count++);
}
end:
fclose(file);
//步骤(4)退出
SDL_Quit();
system("pause");
return 0;
}