Android音视频学习第7章:使用OpenSL ES进行音频解码
/*
*
*这里使用了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);
}
Android音视频学习第7章:使用OpenSL ES进行音频解码的更多相关文章
- Android 音视频深入 十四 FFmpeg与OpenSL ES 播放mp3音乐,能暂停(附源码下载)
项目地址https://github.com/979451341/FFmpegOpenslES 这次说的是FFmpeg解码mp3,数据给OpenSL ES播放,并且能够暂停. 1.创建引擎 slCre ...
- 堪称教科书级别的Android音视频入门进阶学习手册,开源分享!
概述 随着整个互联网的崛起,数据传递的形式也在不断升级变化,总的流行趋势如下: 纯文本的短信,QQ -> 空间,微博,朋友圈的图片文字结合 -> 微信语音 -> 各大直播软件 -&g ...
- Android 音视频开发学习思路
Android 音视频开发这块目前的确没有比较系统的教程或者书籍,网上的博客文章也都是比较零散的.只能通过一点点的学习和积累把这块的知识串联积累起来. 初级入门篇: Android 音视频开发(一) ...
- Android 音视频深入 七 学习之路的总结和资料分享
说个实话一开始我对基于Android如何开发音视频很迷茫,甚至对音视频开发都不是很明白,我看了Android 音视频开发入门指南 http://blog.51cto.com/ticktick/1956 ...
- android音视频点/直播模块开发
音视频 版权声明:本文为博主原创文章,未经博主允许不得转载. 前言 随着音视频领域的火热,在很多领域(教育,游戏,娱乐,体育,跑步,餐饮,音乐等)尝试做音视频直播/点播功能,那么作为开发一个小白, ...
- Android 音视频开发(一) : 通过三种方式绘制图片
版权声明:转载请说明出处:http://www.cnblogs.com/renhui/p/7456956.html 在 Android 音视频开发学习思路 里面,我们写到了,想要逐步入门音视频开发,就 ...
- Android 音视频开发(六): MediaCodec API 详解
在学习了Android 音视频的基本的相关知识,并整理了相关的API之后,我们应该对基本的音视频有一定的轮廓了. 下面开始接触一个Android音视频中相当重要的一个API: MediaCodec.通 ...
- Android 音视频开发(七): 音视频录制流程总结
在前面我们学习和使用了AudioRecord.AudioTrack.Camera.MediaExtractor.MediaMuxer API.MediaCodec. 学习和使用了上述的API之后,相信 ...
- Android音视频点/直播模块开发实践总结-zz
随着音视频领域的火热,在很多领域(教育,游戏,娱乐,体育,跑步,餐饮,音乐等)尝试做音视频直播/点播功能.那么作为开发一个小白,如何快速学习音视频基础知识,了解音视频编解码的传输协议,编解码方式,以及 ...
随机推荐
- Overlapped I/O模型深入分析(转)
随笔 - 262 文章 - 0 评论 - 531 博客园 首页 新随笔 联系 管理 订阅 Overlapped I/O模型深入分析(转) 简述: Overlapped I/O也 ...
- C++ bool和string转换
直接贴代码吧.用g++能够编译.測试ok #include <iostream> #include <sstream> using namespace std; int mai ...
- 在spring+springMvc+mabatis框架下集成swagger
我是在ssm框架下集成swagger的,具体的ssm搭建可以看这篇博文: Intellij Idea下搭建基于Spring+SpringMvc+MyBatis的WebApi接口架构 本项目的GitHu ...
- C语言错误处理方法、C++异常处理方法(throw, try, catch)简介
一.C语言错误处理方法 1.返回值(if … else语句判断错误) 2.errno(linux 系统调用) 3.goto语句(函数内局部跳转) 4.setjmp.longjmp(Do not use ...
- C# BackgroundWorker的Bug???
废话不多说,上代码: public partial class Form1 : Form { BackgroundWorker _bgWorker; int count; public Form1() ...
- ARM开发工具软件命令具体解释---嵌入式回归第三篇
先从bootloader開始,由于临时眼下这些都会是裸机程序相关. 本人这里是VMwarm10.0上安装的红帽linux虚拟机.从以下的截图中能够看出 裸机开发流程: 这里先做第三步(第一步第二步已提 ...
- Atitit. 最佳实践 QA----降低cpu占有率--cpu占用太高怎么办
Atitit. 最佳实践 QA----降低cpu占有率--cpu占用太高怎么办 跟个磁盘队列长度雅十,一到李80%走不行兰.... 1. 寻找线程too 多的.关闭... Taskman>> ...
- video标签常用属性及说明
video标签常用属性(在标签内部使用) video常用API属性及方法(API属性是供JS调用的,不在video标签元素中直接使用)
- 信号处理函数(2)-sigismember()
定义: int sigismember(const sigset_t *set,int signum); 表头文件: #include<signal.h> 说明: sigismem ...
- ngBind {{}} ngBindTemplate
1.首先我们最常使用的一个绑定表达式的指令是ngBind,比如在一个div标签中我们可以这样使用: <div ng-bind="vm.info"></div> ...