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
随着音视频领域的火热,在很多领域(教育,游戏,娱乐,体育,跑步,餐饮,音乐等)尝试做音视频直播/点播功能.那么作为开发一个小白,如何快速学习音视频基础知识,了解音视频编解码的传输协议,编解码方式,以及 ...
随机推荐
- redhat6.2 系统中文环境改成英文环境
暂时变为英文:export LANG=en_US.UTF-8 可以保证你暂时安装oracle没有问题,不出现框框.但是,要说彻底改为英语环境下的时候,用下面: export LANG=en_US就是改 ...
- jquery 获取html <img /> 位置时出错问题
如图所示,这样端口小图片都是通过jquery html()方法设置的(参数html就是画整个图片的html字符串),如图: 但是出现图片没有完全渲染完的问题,如图: 从图中可以看出在代码运行到断点的时 ...
- ML 与 DM 工具 Weka 的使用
1.关于Weka Weka 的全名是怀卡托智能分析环境(Waikato Environment for Knowledge Analysis),是一款免费的.非商业化(与之对应的是SPSS公司商业数据 ...
- 如何让iOS模拟器也能测试蓝牙4.0程序?
买一个CSR蓝牙4.0 USB适配器,插在Mac上 在终端输入sudo nvram bluetoothHostControllerSwitchBehavior="never" 重启 ...
- 基于Redis构建10万+终端级的高性能部标JT808协议的Gps网关服务器(转)
原文地址:http://www.jt808.com/?p=1282 在开发一个大规模的部标GPS监控平台的时候,就算我们花费再多的时间设计和规划,我们也并不能准确的预测出自己未来的车载终端接入量有多大 ...
- C++ 基类指针和子类指针相互赋值
首先,给出基类animal和子类fish [cpp] view plaincopy //======================================================== ...
- Android 利用fastjson进行json解析
package com.example.FastJson.util; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.Typ ...
- Python中模拟C# Linq的一些操作
闲来无事时积累的一些Linq函数,有时间就更新. 需要注意python版本如果低于3.0不支持lambda,只能单独写函数传参,比较麻烦 1.FirstOrDefault: def FirstOrDe ...
- verilog gtkwave
gtkwave,开源波形显示软件 来自 bluesky1 博客.http://blog.sina.com.cn/s/blog_566ca6330100c0t3.html~type=v5_one& ...
- [elk]logstash统计api访问失败率
处理原始日志 日志从moogoo导出来的 { "mobile" : "13612345678", "isp" : "中国移动_广东 ...