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.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);
}
时间: 2024-08-30 03:09:28

SDL2.0例子代码分析---循环播放wav loopwav的相关文章

SDL2.0例子代码分析-----CheckKeys Project

SDL简介 SDL(Simple DirectMedia Layer)是一套开放源代码的跨平台多媒体开发库,使用C语言写成.SDL提供了数种控制图像.声音.输出入的函数,让开发者只要用相同或是相似的代码就可以开发出跨多个平台(Linux.Windows.Mac OS X等)的应用软件.目前SDL多用于开发游戏.模拟器.媒体播放器等多媒体应用领域. SDL1.2和SDL2的差别 SDK1.2和SDL2.1系列的API接口变动的不小,当然功能也大大增强,支持多线程窗口. 具体的change 请看 h

(原创)cocos2d-x 3.0 示例代码分析1:AppDelegate

星月最近在用3.0做类似刀塔游戏,第一次用3.0,之前一直只是查查资料,最近发现做一些特定行为需要对3.0一些新的特性了解.所以趁这个机会,把3.0的测试代码过一遍,同时增加注释,希望能对大家有帮助~ 因为项目原因,所以不定期更新~~(小白:借口,继续找借口!) 星月倾心贡献~~~ // AppDelegate.cpp /**************************************************************************** Copyright (

apollo2.0 radar代码分析

从apollo2.0的代码上看,百度是想做lidar和radar融合的先看传感器输出数据定义class SensorRawFrame{public:SensorType sensortype;double timestamp;Eigen::Matrix4d pose;};// lidar输出数据定义,用的是Velodyne的产品,包含了一块点云,pcl库格式class Velodyne的产品RawFrame : public SensorRawFrame {public:VelodyneRawF

基于&lt;最简单的基于FFMPEG+SDL的视频播放器 ver2 (采用SDL2.0)&gt;的一些个人总结

最近因为项目接近收尾阶段,所以变的没有之前那么忙了,所以最近重新拿起了之前的一些FFMPEG和SDL的相关流媒体播放器的例子在看. 同时自己也用FFMPEG2.01,SDL2.01结合MFC以及网上罗列的一些资料,打算打造一款自己的简易播放器. 最先开始是阅读了<An ffmpeg and SDL Tutorial>以及来源与(http://blog.csdn.net/love4mario/article/details/17652355)中的中文资料,同时认真对tutorial01-08中的

(转)基于FFPMEG2.0版本的ffplay代码分析

ref:http://zzhhui.blog.sohu.com/304810230.html 背景说明 FFmpeg是一个开源,免费,跨平台的视频和音频流方案,它提供了一套完整的录制.转换以及流化音视频的解决方案.而ffplay是有ffmpeg官方提供的一个基于ffmpeg的简单播放器.学习ffplay对于播放器流程.ffmpeg的调用等等是一个非常好的例子.本文就是对ffplay的一个基本的流程剖析,很多细节内容还需要继续钻研. 注:本文师基于ffmpeg-2.0版本进行分析,具体代码行还请对

最简单的基于FFMPEG+SDL的音频播放器 ver2 (采用SDL2.0)

简介 之前做过一个简单的音频播放器:<最简单的基于FFMPEG+SDL的音频播放器>,采用的是SDL1.2.前两天刚把原先做的<最简单的基于FFMPEG+SDL的视频播放器>更新采用了SDL2.0,于是顺手也把音频播放器更新成为SDL2.0. SourceForge项目主页:https://sourceforge.net/projects/simplestffmpegaudioplayer/ 完整工程下载地址:http://download.csdn.net/detail/leix

Android4.0图库Gallery2代码分析(二) 数据管理和数据加载

Android4.0图库Gallery2代码分析(二) 数据管理和数据加载 2012-09-07 11:19 8152人阅读 评论(12) 收藏 举报 代码分析android相册优化工作 Android4.0图库Gallery2代码分析(二) 数据管理和数据加载 一 图库数据管理 Gallery2的数据管理 DataManager(职责:管理数据源)- MediaSource(职责:管理数据集) - MediaSet(职责:管理数据项).DataManager中初始化所有的数据源(LocalSo

演示基于SDL2.0+FFmpeg的播放器

SDL是一个跨平台的渲染组件,目前已经推出到2.0.3版本,支持Win/Linux/OSX/Android.网上很多介绍大多是基于SDL1.2版本的,与2.0版本有一定的差别,本文演示如何用SDL2.0版本播放视频(仅视频). SDL下载网站:http://libsdl.org 参考网址:http://blog.csdn.net/dawdo222/article/details/8692834 上代码: // 演示如何用SDL2进行播放 //可参考http://blog.csdn.net/daw

Lua1.0 代码分析 table.c

转载出处:http://my.oschina.net/xhan/blog/307961 table.c 代码分析 全局符号,常量,字符串,关联数组,文件列表的定义. 全局符号: 初始有 5 个基本的符号,Lua 预设的函数和库函数都注册在里面. 常量: 初始的几个常量是 Lua 中 type 的名字. 字符串表,关联数组表,文件列表 所有的这些在 table.c 中定义的这些数组可以认为是 Lua 的全局注册表空间,Lua 的环境. 函数分析 ? 1 2 3 4 5 6 7 8 9 10 11