/*

*

*这里使用了transcode-1.1.7对wav文件进行解码。然后使用opensl es进行播放

*

*/


//用到的变量和结构体

WAV wav; //wav文件指针
SLObjectItf engineObject; //引擎对象
SLEngineItf engineInterface; //引擎接口
SLObjectItf outputMixObject; //混音器
SLObjectItf audioPlayerObject; //播放器对象
SLAndroidSimpleBufferQueueItf andioPlayerBufferQueueItf; //缓冲器队列接口
SLPlayItf audioPlayInterface; //播放接口 unsigned char *buffer; //缓冲区
size_t bufferSize; //缓冲区大小 //上下文
struct PlayerContext{
WAV wav;
unsigned char *buffer;
size_t bufferSize; PlayerContext(WAV wav,
unsigned char *buffer,
size_t bufferSize){
this->wav = wav;
this->buffer = buffer;
this->bufferSize = bufferSize;
}
};
//实现对象
void RealizeObject(SLObjectItf object){
//非异步(堵塞)
(*object)->Realize(object,SL_BOOLEAN_FALSE);
}

详细实现流程:

1.打开文件

WAV wav = OpenWaveFile(env,jFileName);
//打开文件
WAV OpenWaveFile(JNIEnv *env,jstring jFileName){
const char *cFileName = env->GetStringUTFChars(jFileName,JNI_FALSE);
WAVError err;
WAV wav = wav_open(cFileName,WAV_READ,&err); LOGI("%d",wav_get_bitrate(wav));
env->ReleaseStringUTFChars(jFileName,cFileName);
if(wav == 0){
LOGE("%s",wav_strerror(err));
}
return wav;
}

2.创建OpenSL ES引擎

//OpenSL ES在Android平台下默认是线程安全的,这样设置是为了为了兼容其它平台
SLEngineOption options[] = {
{(SLuint32)SL_ENGINEOPTION_THREADSAFE, (SLuint32)SL_BOOLEAN_TRUE}
};
slCreateEngine(&engineObject,ARRAY_LEN(engineObject),options,0,0,0); //没有接口 //实例化对象
//对象创建之后。处于未实例化状态,对象尽管存在但未分配不论什么资源,使用前先实例化(使用完之后destroy)
RealizeObject(engineObject);

3.获取引擎接口

(*engineObject)->GetInterface(engineObject,SL_IID_ENGINE,&engineInterface);

4.创建输出混音器

(*engineInterface)->CreateOutputMix(engineInterface,&outputMixObject,0,0,0); //没有接口
//实例化混音器
RealizeObject(outputMixObject);

5.创建缓冲区保存读取到的音频数据库

//缓冲区的大小
bufferSize = wav_get_channels(wav) * wav_get_rate(wav) * wav_get_bits(wav);
buffer = new unsigned char[bufferSize];

6.创建带有缓冲区队列的音频播放器

CreateBufferQueueAudioPlayer(wav,engineInterface,outputMixObject,audioPlayerObject);
//实例化音频播放器
RealizeObject(audioPlayerObject);

CreateBufferQueueAudioPlayer.cpp

extern "C" {
#include "wavlib.h"
}
#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>
#include <android/log.h> #define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
//创建音频播放对象
void CreateBufferQueueAudioPlayer(
WAV wav,
SLEngineItf engineEngine,
SLObjectItf outputMixObject,
SLObjectItf &audioPlayerObject){ // Android针对数据源的简单缓冲区队列定位器
SLDataLocator_AndroidSimpleBufferQueue dataSourceLocator = {
SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, // 定位器类型
1 // 缓冲区数
}; // PCM数据源格式
SLDataFormat_PCM dataSourceFormat = {
SL_DATAFORMAT_PCM, // 格式类型
wav_get_channels(wav), // 通道数
wav_get_rate(wav) * 1000, // 毫赫兹/秒的样本数
wav_get_bits(wav), // 每一个样本的位数
wav_get_bits(wav), // 容器大小
SL_SPEAKER_FRONT_CENTER, // 通道屏蔽
SL_BYTEORDER_LITTLEENDIAN // 字节顺序
}; // 数据源是含有PCM格式的简单缓冲区队列
SLDataSource dataSource = {
&dataSourceLocator, // 数据定位器
&dataSourceFormat // 数据格式
}; // 针对数据接收器的输出混合定位器
SLDataLocator_OutputMix dataSinkLocator = {
SL_DATALOCATOR_OUTPUTMIX, // 定位器类型
outputMixObject // 输出混合
}; // 数据定位器是一个输出混合
SLDataSink dataSink = {
&dataSinkLocator, // 定位器
0 // 格式
}; // 须要的接口
SLInterfaceID interfaceIds[] = {
SL_IID_BUFFERQUEUE
}; // 须要的接口,假设所须要的接口不要用。请求将失败
SLboolean requiredInterfaces[] = {
SL_BOOLEAN_TRUE // for SL_IID_BUFFERQUEUE
}; // 创建音频播放器对象
SLresult result = (*engineEngine)->CreateAudioPlayer(
engineEngine,
&audioPlayerObject,
&dataSource,
&dataSink,
ARRAY_LEN(interfaceIds),
interfaceIds,
requiredInterfaces);
}

posted on
2017-08-07 11:22 
lxjshuju 
阅读(...) 
评论(...) 
编辑 
收藏

Android音视频学习第7章:使用OpenSL ES进行音频解码的更多相关文章

  1. Android 音视频深入 十四 FFmpeg与OpenSL ES 播放mp3音乐,能暂停(附源码下载)

    项目地址https://github.com/979451341/FFmpegOpenslES 这次说的是FFmpeg解码mp3,数据给OpenSL ES播放,并且能够暂停. 1.创建引擎 slCre ...

  2. 堪称教科书级别的Android音视频入门进阶学习手册,开源分享!

    概述 随着整个互联网的崛起,数据传递的形式也在不断升级变化,总的流行趋势如下: 纯文本的短信,QQ -> 空间,微博,朋友圈的图片文字结合 -> 微信语音 -> 各大直播软件 -&g ...

  3. Android 音视频开发学习思路

    Android 音视频开发这块目前的确没有比较系统的教程或者书籍,网上的博客文章也都是比较零散的.只能通过一点点的学习和积累把这块的知识串联积累起来. 初级入门篇: Android 音视频开发(一) ...

  4. Android 音视频深入 七 学习之路的总结和资料分享

    说个实话一开始我对基于Android如何开发音视频很迷茫,甚至对音视频开发都不是很明白,我看了Android 音视频开发入门指南 http://blog.51cto.com/ticktick/1956 ...

  5. android音视频点/直播模块开发

      音视频 版权声明:本文为博主原创文章,未经博主允许不得转载. 前言 随着音视频领域的火热,在很多领域(教育,游戏,娱乐,体育,跑步,餐饮,音乐等)尝试做音视频直播/点播功能,那么作为开发一个小白, ...

  6. Android 音视频开发(一) : 通过三种方式绘制图片

    版权声明:转载请说明出处:http://www.cnblogs.com/renhui/p/7456956.html 在 Android 音视频开发学习思路 里面,我们写到了,想要逐步入门音视频开发,就 ...

  7. Android 音视频开发(六): MediaCodec API 详解

    在学习了Android 音视频的基本的相关知识,并整理了相关的API之后,我们应该对基本的音视频有一定的轮廓了. 下面开始接触一个Android音视频中相当重要的一个API: MediaCodec.通 ...

  8. Android 音视频开发(七): 音视频录制流程总结

    在前面我们学习和使用了AudioRecord.AudioTrack.Camera.MediaExtractor.MediaMuxer API.MediaCodec. 学习和使用了上述的API之后,相信 ...

  9. Android音视频点/直播模块开发实践总结-zz

    随着音视频领域的火热,在很多领域(教育,游戏,娱乐,体育,跑步,餐饮,音乐等)尝试做音视频直播/点播功能.那么作为开发一个小白,如何快速学习音视频基础知识,了解音视频编解码的传输协议,编解码方式,以及 ...

随机推荐

  1. Think in Java(二):初始化与清理

    1. 区分重载方法: 參数顺序的不同能够区分两个方法,只是,普通情况下千万别这么做.由于这会使代码难以维护不能通过返回值类型来区分重载方法:由于假设我直接调用f(), 此时java不知道应该调用那一个 ...

  2. 【转载】正则过滤所有html标签,只留文字的方法。

    public static string Html2Text(string htmlStr) { if (String.IsNullOrEmpty(htmlStr)) { return "& ...

  3. UML建模学习3:UML基本构造块之关系

    今天我们来看UML基本构造块的还有一个要素--关系. UML中有表示基本图示符号之间的关系,它们是:依赖(dependency).泛化(generalization,也有的称继承).实 现(reali ...

  4. WinForm下的键盘事件(KeyPress、KeyDown)及如何处理不响应键盘事件

    KeyDown事件用来处理功能键:F1 F2 F3... keyPress事件用来处理字符比如说:A B C... 1 2 3... 注:处理该事件时,需要先将窗体的 KeyPreview=true; ...

  5. js获取当前域名的方法

    一.获取当前域名 1.方法一 var domain = document.domain; 2.方法二 var domain = window.location.host; 但是获取到的domain在线 ...

  6. CSS之千变万化的Div

    厂址:http://www.cnblogs.com/yunfeifei/p/4671930.html 一.div和css3在一起 .box1 { width: 100px; height: 100px ...

  7. autoHotKey 一些脚本积累

    新建test.ahk,然后运行即可. #InstallKeybdHook #Persistent Hotstring("EndChars", "`n") ; 设 ...

  8. Nginx an upstream response is buffered to a temporary file,nginx502错误

    1.错误日志:warn:an upstream response is buffered to a temporary file 解决办法:增加fastcgi_buffers 8 4K;     fa ...

  9. iOS开发-iOS 10 由于权限问题导致崩溃的那些坑

     iOS开发-iOS 10 由于权限问题导致崩溃的那些坑 6月份的WWDC大会结束有一段时间了,相信很多开发者也是在努力工作的闲时用着Xcode8 Beta版学习着新的特性吧. 使用Xcode8写自己 ...

  10. 基于jdom 的 xmluti

    package cn.com.do1.wechat.common; import org.jdom.Attribute; import org.jdom.Document; import org.jd ...