C++入门 SDL播放PCM文件

一、 参考文章

攻城狮百里
https://blog.csdn.net/weixin_52622200/article/details/131306315

二、 使用FFmpeg将mp3文件转成PCM文件命令

ffmpeg -i xxx.mp3 -f s16le xxx.pcm

三、 main函数

SDL播放PCM原理,SDL播放音频过程中,会不断触发回调函数,我们只要在回调函数中不断将PCM数据拷贝到回调函数指定的地址中即可实现音频播放
main.c

#include <iostream>
#include <fstream>
#include <thread>

extern "C" {
	#include "SDL.h"
}

using namespace std;

//全局数据区,PCM文件内容
char pcmBuffer[100 * 1024 * 1024];
int audioPosition = 0;
int audioLength = 0;

//音频回调函数
void  AudioCallback(void* userdata, Uint8* stream, int length);

int main(int argc,char* argv[])
{
	//SDL初始化
	if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) != 0)
	{
		cout << "sdl init failed" << endl;
	}
	else
	{
		cout << "sdl init succes" << endl;
	}
	
	//创建窗口
	SDL_Window* pWindow = SDL_CreateWindow("sdl播放器", 100, 100, 1600, 900, SDL_WINDOW_RESIZABLE);

	//打开音频设备
	SDL_AudioSpec desired;
	desired.freq = 44100;
	desired.format = AUDIO_S16SYS;
	desired.channels = 2;
	desired.samples = 1024;
	desired.silence = 0;
	desired.callback = AudioCallback;
	SDL_OpenAudio(&desired, NULL);

	//读取PCM文件到内存
	fstream fileStream;
	fileStream.open("D:/myfile/project/ttt/audio/moonlight.pcm", ios::in | ios::binary);
	if (!fileStream.is_open())
	{
		cout << "PCM文件打开失败" << endl;
	}
	fileStream.read(pcmBuffer, 100 * 1024 * 1024);
	int readLength = fileStream.gcount();
	cout << "pcmLength:" << readLength << endl;
	audioLength = readLength;
	fileStream.close();

	//开始播放
	SDL_PauseAudio(0);

	while (true)
	{
		chrono::seconds delay(1);
		this_thread::sleep_for(delay);
	}

	//关闭音频设备
	SDL_CloseAudio();

	return 0;
}

//音频回调函数
void AudioCallback(void* userdata, Uint8* stream, int length)
{
	SDL_memset(stream, 0, length);
	if (audioLength == 0)return;
	length = (length > audioLength ? audioLength : length);
	SDL_MixAudio(stream, (Uint8*)pcmBuffer + audioPosition, length, SDL_MIX_MAXVOLUME);
	audioPosition += length;
	audioLength -= length;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值