前面几篇关于SDL的文章介绍的是以画面为主,这里介绍下SDL中针对音频播放提供的机制,以及如何应用。

对于音频而言,有几个概念需要事先了解下,采样率、声道数、量化位数,如果你不清楚的话,麻烦先了解下这几本参数的概念。

常用的采样率有8kHz(语音、电话)、48kHz(电视),声道数常用的是双声道或5.1声道,量化位数8bit或16bit。

SDL提供了音频设备、音频输入/输出的控制机制。

比较常规的做法是先创建音频设备,然后按照你的实际需求进行音频输入输出。

由于音频处理相对简单,这里仅在一个cpp中实现所有wav播放的功能。

工程创建

为了演示期间,我们在vs10中创建控制台程序,并包含SDL头文件和库的路径。,工程名为3_wav_play。我从网上下了一个wav音频,名字为“congtouzailai.wav”。(音量比较大的,播放的时候注意下)

wav文件加载

SDL提供了SDL_LoadWAV函数,用于加载wav文件,加载的代码如下:

    SDL_AudioSpec wav_spec;
Uint32 wav_length;
Uint8 *wav_buffer; /* Load the WAV */
if (SDL_LoadWAV("congtouzailai.wav", &wav_spec, &wav_buffer, &wav_length) == NULL)
{
fprintf(stderr, "Could not open test.wav: %s\n", SDL_GetError());
return -;
}

函数调用成功之后,就可以获得wav文件中的音频参数,比如采样率、声道数、量化位数等,其中原始的音频数据(PCM)存储在wav_buffer中,长度为wav_length。

创建回调参数上下文

struct AudioPlayContext
{
Uint8 * data; // pcm buffer
int offset; // current read pos
int data_len; // left data length
bool is_exit; // is audio play buffer empty?
};

提供这个参数,只是为了提供数据从主函数到回调函数传递参数的机制。

创建音频设备

    AudioPlayContext context;
context.data = wav_buffer;
context.offset = ;
context.data_len = wav_length;
context.is_exit = false; // open audio device
SDL_AudioSpec want, have; want = wav_spec;
want.callback = MyAudioCallback; // you wrote this function elsewhere.
want.userdata = &context; if (SDL_OpenAudio(&want, &have) < )
{
printf("Failed to open audio: %s\n", SDL_GetError());
return -;
} if (have.format != want.format)
printf("We didn't get Float32 audio format.\n");

这里最主要的结构体SDL_AudioSpec的初始化,这里的回调函数MyAudioCallback,提供了向播放设备写入音频数据的方式。

播放音频数据

在主线程中,我们启动播放,并等待当前wav文件播放完成。代码如下

    SDL_PauseAudio();  // start audio playing.
// wait for the end
while(!context.is_exit)
{
SDL_Delay();
}

在回调函数中我们需要将数据填充到音频设备的播放缓冲中,并设置是否播放完成的标志位,代码如下

void MyAudioCallback(void* userdata, Uint8* stream, int len)
{
AudioPlayContext * context = reinterpret_cast<AudioPlayContext *>(userdata);
int copy_len = __min(len, context->data_len);
memcpy(stream, context->data+context->offset, copy_len);
context->data_len -= copy_len;
context->offset += copy_len;
if (context->data_len <= )
{
context->is_exit = true;
} if (copy_len < len)
{
memset(stream+copy_len, , len-copy_len);
}
}

反初始化操作

程序退出时,别忘记释放wav文件加载时的数据。

    SDL_CloseAudio();
/* Do stuff with the WAV data, and then... */
SDL_FreeWAV(wav_buffer);
SDL_Quit();

上面几个合并在一起就是最简单的wav文件播放器。

相关代码可以从我的git下载,url如下:https://git.oschina.net/Tocy/SampleCode.git,位于TocySDL2VisualTutorial目录下。

Beginning SDL 2.0(6) 音频渲染及wav播放的更多相关文章

  1. Beginning SDL 2.0(4) YUV加载及渲染

    本文主要内容是基于的“Beginning SDL 2.0(3) SDL介绍及BMP渲染”(以下简称BS3)基础上,将BMP加载及渲染修改为YUV420或I420的原始视频格式.阅读完本部分内容相信你可 ...

  2. Beginning SDL 2.0(3) SDL介绍及BMP渲染

    SDL是一个跨平台的多媒体库.为了实现跨平台,SDL提供了一个简单的界面库抽象,比如提供了SDL_Window用于表示窗口句柄,SDL_Surface.SDL_Texture.SDL_Renderer ...

  3. Beginning SDL 2.0(5) 基于MFC和SDL的YuvPlayer

    本文是在“Beginning SDL 2.0(4) YUV加载及渲染”(以下简称BS4)基础上做的功能完善,如果你对之间介绍的内容了解不多,麻烦先阅读之前的内容. 本文主要介绍如何完成一个基于MFC和 ...

  4. Beginning SDL 2.0(2) TwinklebearDev SDL 2.0 Tutorial

    本文整理并简要介绍了TwinklebearDev SDL 2.0 Tutorial相关内容(以下简称TDSDLTutorial). 这是作为我学习并了解SDL2.0功能一篇学习总结. TDSDLTut ...

  5. Beginning SDL 2.0(1) SDL功能简介

    原文链接为 http://wiki.libsdl.org/Introduction. 由于近期整理音视频可视化的技术,发现好久不更新的SDL发布了2.0版本,以前也没有过于关注,这里准备尝试下.了解S ...

  6. Android下基于PCM的音频渲染

    环境准备 请按照我之前的文章-Android下基于SDL的位图渲染,安装必要的开发环境. 实践篇 这里主要参考Beginning SDL 2.0(6) 音频渲染及wav播放,只不过将源从WAV文件改成 ...

  7. (转)在SDL工程中让SDL_ttf渲染汉字

    有时候在关于SDL的博文中看到一些评论,说SDL对中文的支持不佳,因为当程序涉及中文时总是输出乱码. 照我个人观点,这里面很多都是误解.下面就根据我在windows下使用SDL的情况,说说我的观点. ...

  8. vue2.0 之文本渲染-v-html、v-text

    vue2.0 之文本渲染-v-html.v-text 1.index.html代码 <!DOCTYPE html> <html> <head> <meta c ...

  9. COCOS2DX 3.0 优化提升渲染速度 Auto-batching

    COCOS2DX 3.0 优化提升渲染速度 Auto-batching 近期在看COCOS2DX 3.0的Auto-batching合批与Auto Culling动态缩减功能以下就来细致看看吧:整合好 ...

随机推荐

  1. iOS presentedViewController和presentingViewController的区别

    当我们用present进行界面跳转时,会涉及到一个传向关系. 比如:A -> B    界面A跳转界面B A.presentedViewControlle = B B.presentingVie ...

  2. 第一次使用Mac

    Mac禁用掉默认输入法 搜狗输入法已经包含中文.英文输入法了,其余输入法可以删除掉.按ctrol键的时候本来应该是搜狗输入法中英文切换,结果却是搜狗输入法和ABC输入法之间互相切换. 打开键盘偏好设置 ...

  3. NSOperation, NSOperationQueue 原理探析

    通过GNUstep的Foundation来尝试探索下NSOperation,NSOperationQueue 示例程序 写一个简单的程序 - (void)viewDidLoad { [super vi ...

  4. build high performance server 转载

    http://blog.ci123.com/wobushizhanghua/entry/246311 先后查看了haproxy,l7sw和lighttpd的 相关源码,无一例外,他们一致认为多路复用是 ...

  5. 自动化部署必备技能—定制化RPM包[转载]

    回顾下安装软件的三种方式: 1.编译安装软件,优点是可以定制化安装目录.按需开启功能等,缺点是需要查找并实验出适合的编译参数,诸如MySQL之类的软件编译耗时过长. 2.yum安装软件,优点是全自动化 ...

  6. 如何利用 Visual Studio 自定义项目或工程模板(转载)

    在开发项目的时候,由其是商业性质的大型项目时,往往需要在每个代码文件上都加上一段关于版权.开发人员的信息,并且名称空间上都需要带有公司的标志.这个时候,是选择在开发的时候手动添加还是自动生成呢? 我们 ...

  7. 【转】Tesla Autopilot

    Tesla Autopilot 以下内容是<Tesla Model S的设计失误>一文中新加入的小节.由于写作时间相距太远,而且由于它的时效性,现在也把它单独提出来,独立成文. 两个月前, ...

  8. python packages prebuild for windows

    python  prebuild / precompiled packages for windows  by uci edu   在python windows环境下作业,有时候会碰上一些无厘头的问 ...

  9. Groovy 学习手册(2)

    二. 工具 1. 控制台 groovyConsole: Groovy 控制台是一个非常易于使用和简单的轻量级的编辑器.你可以在里面做很多事情. 在编辑器里面可以书写代码,Windows 下,按下Ctr ...

  10. java环境变量设置与java查看安装路径

    把jdk安装到计算机中之后,我们来进行设置使java环境能够使用. 首先右键点我的电脑.打开属性.然后选择“高级”里面的“环境变量”,在新的打开界面中的系统变量需要设置三个属性“JAVA_HOME”. ...