SDL输出音频的简单使用

        sdl作为一个强大的跨平台多媒体库,音频播放是线性连续的,调用相对简单,其后端是通过一个音频回调函数不断向音频设备输出buf,以下是所涉及的接口:

SDL_Init(SDL_INIT_AUDIO):初始化音频设备。

SDL_OpenAudio(SDL_AudioSpec * desired, SDL_AudioSpec * obtained):这个函数用于设置音频设备的参数,并准备音频设备以便进行音频播放。
desired:这是一个指向 SDL_AudioSpec 结构体的指针,该结构体包含了开发者希望的音频设备参数。这些参数包括音频的采样率、音频格式、通道数、缓冲区大小等。
obtained:这也是一个指向 SDL_AudioSpec 结构体的指针,但是它是用于输出实际获得的音频设备参数的。当 SDL_OpenAudio() 成功返回后,这个结构体将被填充为音频设备实际支持的参数。

SDL_PauseAudio(0):用于暂停或恢复音频播放。

SDL_CloseAudio():关闭音频子系统。

SDL_Quit():完全退出 SDL 库。

        其中,比较重要的是desired中参数的配置和回调函数的实现:

SDL_AudioSpec spec;
spec.freq;				    //音频一秒采样率
spec.channels;		        //音频通道数
spec.format;		        //音频样本类型
spec.silence;		        //静音
spec.samples;			    //缓冲区大小
spec.callback;              //回调函数
spec.userdata;              //传入回调函数的数据

         sdl中的音频回调函数接口声明是固定,我们可以自己实现函数内部,只要将播放的音频数据赋值给stream即可,以下是一个简易的音频回调函数实现:

void AudioPlayer::Callback(void* userdata,unsigned char* stream, int len)
{
	SDL_memset(stream, 0, len);
    //userdata转成ifstream便于数据传输
    auto ifs = (ifstream*)userdata;
    ifs->read((char*)stream, len);
    if (ifs->gcount() <= 0)
    {
	    SDL_PauseAudio(1);
    }
    cout << "CallBack" << endl;
}

以下是一个简单的dome:

#include<iostream>
#include<fstream>
extern"C"
{
	#include<SDL.h>
}
#pragma comment(lib,"SDL2.lib")

using namespace std;

void CallBack(void* userdata, Uint8* stream, int len);

#undef main
int main()
{
	ifstream ifs("48000_2_s16le.pcm",ios::binary);
	if (!ifs)
	{
		return -1;
	}

	if (SDL_Init(SDL_INIT_AUDIO) < 0)
	{
		return -1;
	}

	SDL_AudioSpec spec;
	spec.freq = 48000;			//一秒的采样率
	spec.channels = 2;			//通道数,双声道
	spec.samples = 1024;		//设置缓冲区大小为 1024 个音频帧
	spec.format = AUDIO_S16SYS;	//系统原生的 16 位音频格式
	spec.silence = 0;			//不静音
	spec.userdata =&ifs;		//将文件句柄传入回调函数,便于取数据
	spec.callback = CallBack;	//音频回调函数

	if (SDL_OpenAudio(&spec, nullptr) < 0)
	{
		return -1;
	}
	
	//播放音频
	SDL_PauseAudio(0);

	//阻塞等音频播放完
	getchar();

	SDL_CloseAudio();
	ifs.close();
	return 0;
}

void CallBack(void* userdata, Uint8* stream,int len)
{
	SDL_memset(stream, 0, len);
	//userdata转成ifstream便于数据传输
	auto ifs = (ifstream*)userdata;
	ifs->read((char*)stream, len);
	if (ifs->gcount() <= 0)
	{
		SDL_PauseAudio(1);
	}
	cout << "CallBack" << endl;
}

        喜欢的朋友可以给个赞和关注,谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值