SDL教程-002.wav音频文件播放以及混音测试

本文详细介绍使用SDL库进行音频文件播放的方法,包括初始化SDL模块、创建窗口、加载音频、播放音频等步骤。通过具体代码示例,展示如何实现单音频文件播放及混音后播放。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SDL教程-002.wav音频文件播放

单文音频文件播放

#include <iostream>
#include <SDL.h>
#include<stdlib.h>
#include<stdio.h>
#include <SDL_image.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 = "G:\\code\\AudioDemo\\Res\\audios\\test_music.wav";

	//设置显示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));


	/**
	将音频文件加载到内存中
	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;
}

两个音频文件混音后播放代码

混音算法:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值