开发者社区> usher.yue> 正文

SDL2.0例子代码分析---循环播放wav loopwav

简介: SDL2.0中循环播放一段声音文件 ,并且添加上注释。 /* 加载并且循环播放一个WAV文件*/ /* loopwaves.c is much more robust in handling WAVE files -- This is only for simple WAVEs */ #include "SDL_config.
+关注继续查看

SDL2.0中循环播放一段声音文件 ,并且添加上注释。

/*  加载并且循环播放一个WAV文件*/

/* loopwaves.c is much more robust in handling WAVE files --
	This is only for simple WAVEs
	*/
#include "SDL_config.h"

#include <stdio.h>
#include <stdlib.h>

#if HAVE_SIGNAL_H
#include <signal.h>
#endif

#include "SDL.h"
#include "SDL_audio.h"

//sdl 播放缓冲区定义
struct
{
	SDL_AudioSpec spec;
	Uint8 *sound;               /*指向声音数据指针 */
	Uint32 soundlen;            /* Length of wave data */
	int soundpos;               /* Current play position */
} wave;


/* 调用这个函数退出SDL子系统 */
static void
quit(int rc)
{
	SDL_Quit();
	exit(rc);
}


void SDLCALL
fillerup(void *unused, Uint8 * stream, int len)
{
	Uint8 *waveptr;
	int waveleft;

	/*设置当前声音指针
	声音指针+当前播放的位置
	*/
	waveptr = wave.sound + wave.soundpos;
	//剩余声音数据   声音数据长度-当前播放的位置 
	waveleft = wave.soundlen - wave.soundpos;

	/* 如果剩余数据<需要的长度 */
	while (waveleft <= len)
	{
		//拷贝剩余数据到音频缓冲区
		SDL_memcpy(stream, waveptr, waveleft);
		//音频缓冲区stream指针后移
		stream += waveleft;
		//len=len-waveleft
		len -= waveleft;
		//拷贝玩剩余数据
		//waveptr指向 声音数据开头  
		waveptr = wave.sound;
		//长度等于len 
		waveleft = wave.soundlen;
		//位置等于len
		wave.soundpos = 0;
	}
	//重新拷贝内存到 音频设备缓冲区  
	//也就是循环播放
	SDL_memcpy(stream, waveptr, len);  
	//当前播放的位置 +=len
	wave.soundpos += len;
}

static int done = 0;
//退出信号 
void
poked(int sig)
{
	done = 1;
}

int
main(int argc, char *argv[])
{
	int i;
	char filename[4096];

	/* Enable standard application logging */
	SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);

	/* 初始化SDL音频库 */
	if (SDL_Init(SDL_INIT_AUDIO) < 0) {
		SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
		return (1);
	}

	//拷贝文件名字 到 filename 缓冲区
	if (argc >= 1) {
		SDL_strlcpy(filename, argv[1], sizeof(filename));
	}
	else {
		SDL_strlcpy(filename, "D:\\vs2010_pro\\ffmpeg_test\\Output\\audio.aac", sizeof(filename));
	}
	/* 加载声音文件到内存 */
	if (SDL_LoadWAV(filename, &wave.spec, &wave.sound, &wave.soundlen) == NULL) {
		SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", argv[1], SDL_GetError());
		quit(1);
	}
	//音频回调 在回调函数中填充音频缓冲区 需求的大小的数据 
	wave.spec.callback = fillerup;
#if HAVE_SIGNAL_H
	/* Set the signals */
#ifdef SIGHUP
	signal(SIGHUP, poked);
#endif
	signal(SIGINT, poked);
#ifdef SIGQUIT
	signal(SIGQUIT, poked);
#endif
	signal(SIGTERM, poked);
#endif /* HAVE_SIGNAL_H */

	/* Show the list of available drivers */
	SDL_Log("Available audio drivers:");
	//打印电脑上的所有音频驱动
	for (i = 0; i < SDL_GetNumAudioDrivers(); ++i) {
		SDL_Log("%i: %s", i, SDL_GetAudioDriver(i));
	}

	/*初始化音频设备  并且打开 因为我们输出的wav有头部信息所有 我们不需要设置参数*/
	if (SDL_OpenAudio(&wave.spec, NULL) < 0) {
		SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open audio: %s\n", SDL_GetError());
		SDL_FreeWAV(wave.sound);
		quit(2);
	}

	//打印当前音频设备
	SDL_Log("Using audio driver: %s\n", SDL_GetCurrentAudioDriver());

	/*开始播放声音  这个时候 SDL以异步线程的方式不停的回调 来取数据  */
	SDL_PauseAudio(0);
	//如果当前正在播放 那么 主线程 Delay 1s 
	//或者有退出信号 那么退出
	while (!done && (SDL_GetAudioStatus() == SDL_AUDIO_PLAYING))
		SDL_Delay(1000);

	/* 关闭音频 */
	SDL_CloseAudio();
	//释放分配的声音数据内存
	SDL_FreeWAV(wave.sound); 
   //退出程序 和SDL
	SDL_Quit();
	return (0);
}



版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Qt | 播放音频文件 QMediaplayer
QMediaplayer的使用方法以及遇到的问题。
202 0
SDL开发笔记(二):音频基础介绍、使用SDL播放音频
SDL开发笔记(二):音频基础介绍、使用SDL播放音频
251 0
FFmpeg开发笔记(六):ffmpeg解码视频并使用SDL同步时间显示播放
FFmpeg开发笔记(六):ffmpeg解码视频并使用SDL同步时间显示播放
279 0
SDL开发笔记(三):使用SDL渲染窗口颜色和图片
SDL开发笔记(三):使用SDL渲染窗口颜色和图片
317 0
QT使用QSound类播放WAV文件
QT使用QSound类播放WAV文件
124 0
使用QT播放音频文件的几种方法:QSound、QSoundEffect、QMediaPlayer
使用QT播放音频文件的几种方法:QSound、QSoundEffect、QMediaPlayer
573 0
Qt 播放音频文件
Qt播放音频文件的方法有好多中,简单介绍几种 不过一下几种方式都需要在Qt工程文件中添加
138 0
ffplay源码分析7-播放控制
ffplay是FFmpeg工程自带的简单播放器,使用FFmpeg提供的解码器和SDL库进行视频播放。
89 0
100行代码实现最简单的基于FFMPEG+SDL的视频播放器(SDL1.x)【转】
转自:http://blog.csdn.net/leixiaohua1020/article/details/8652605 版权声明:本文为博主原创文章,未经博主允许不得转载。   目录(?)[-] 简介 流程图 simplest_ffmpeg_player标准版代码 ...
1632 0
+关注
usher.yue
算法相关技术专家
文章
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载