开发者社区> usher.yue> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

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);
}



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

相关文章
FFmpeg开发笔记(六):ffmpeg解码视频并使用SDL同步时间显示播放
FFmpeg开发笔记(六):ffmpeg解码视频并使用SDL同步时间显示播放
0 0
QT使用QSound类播放WAV文件
QT使用QSound类播放WAV文件
0 0
使用QT播放音频文件的几种方法:QSound、QSoundEffect、QMediaPlayer
使用QT播放音频文件的几种方法:QSound、QSoundEffect、QMediaPlayer
0 0
linux下使用QT调用FFMPEG读取摄像头一帧数据显示到标签控件上
linux下使用QT调用FFMPEG读取摄像头一帧数据显示到标签控件上
0 0
ffplay源码分析7-播放控制
ffplay是FFmpeg工程自带的简单播放器,使用FFmpeg提供的解码器和SDL库进行视频播放。
0 0
vc中播放mp3文件的方法小结
一般播放MP3常见的有两种方法,一种是自己解码,另外一种用系统的库,比如MCI,当然如果可以用控件直接用个控件会更方便。 1.      使用mci   #include #include #include #include #include   #pragma comment(lib,"winmm.
773 0
FFMPEG+SDL2.0流媒体开发3---简易MP4视频播放器,提取MP4的H264视频序列解码并且显示
简介 之前写了一遍提取MP4中的音视频并且解码,这一篇引入SDL2.0来显示解码后的视频序列 实现一个简易的 视频播放器。 我这里用的FFMPEG和SDL2.0都是最新版的 可能网上的资料不是很多,API接口也变了很多,不过大体的思路还是一样的。
943 0
最简单的视音频播放示例9:SDL2播放PCM
本文记录SDL播放音频的技术。在这里使用的版本是SDL2。实际上SDL本身并不提供视音频播放的功能,它只是封装了视音频播放的底层API。在Windows平台下,SDL封装了Direct3D这类的API用于播放视频;封装了DirectSound这类的API用于播放音频。
1041 0
OpenCV x64 vs2010 下打开摄像头录制视频写成avi(代码为转载)
首先参照下面这里进行opencv x64位机器下面的配置 http://wiki.opencv.org.cn/index.php/VC_2010%E4%B8%8B%E5%AE%89%E8%A3%85OpenCV2.4.4   参考到环境变量处的配置之后,文章中所说的x64位机器环境的配置就不是很清晰了,我自己摸索了一些,其实vs2010本身就不是一个64位的编译器。
1012 0
+关注
usher.yue
算法相关技术专家
文章
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载