#include <jni.h>
#include <string>
#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h> //1 创建引擎
static SLObjectItf engineSL = NULL;
SLEngineItf CreateSL()
{
SLresult re;
SLEngineItf en;
re = slCreateEngine(&engineSL,0,0,0,0,0);
if(re != SL_RESULT_SUCCESS) return NULL;
re = (*engineSL)->Realize(engineSL,SL_BOOLEAN_FALSE);
if(re != SL_RESULT_SUCCESS) return NULL;
re = (*engineSL)->GetInterface(engineSL,SL_IID_ENGINE,&en);
if(re != SL_RESULT_SUCCESS) return NULL;
return en;
} void PcmCall(SLAndroidSimpleBufferQueueItf bf,void *contex)
{
LOGD("PcmCall");
static FILE *fp = NULL;
static char *buf = NULL;
if(!buf)
{
buf = new char[1024*1024];
}
if(!fp)
{
fp = fopen("/sdcard/shape.pcm","rb");
}
if(!fp)return;
if(feof(fp) == 0)
{
int len = fread(buf,1,1024,fp);
if(len > 0)
(*bf)->Enqueue(bf,buf,len);
} }
 
extern "C"
JNIEXPORT jstring JNICALL
Java_com_example_user_player_Play_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
std::string hello = "Hello from C++"; //1 创建引擎
SLEngineItf eng = CreateSL();
if(eng){
LOGD("CreateSL success! ");
}else{
LOGD("CreateSL failed! ");
} //2 创建混音器
SLObjectItf mix = NULL;
SLresult re = 0;
re = (*eng)->CreateOutputMix(eng,&mix,0,0,0);
if(re !=SL_RESULT_SUCCESS )
{
LOGD("SL_RESULT_SUCCESS failed!");
}
re = (*mix)->Realize(mix,SL_BOOLEAN_FALSE);
if(re !=SL_RESULT_SUCCESS )
{
LOGD("(*mix)->Realize failed!");
}
SLDataLocator_OutputMix outmix = {SL_DATALOCATOR_OUTPUTMIX,mix};
SLDataSink audioSink= {&outmix,0}; //3 配置音频信息
//缓冲队列
SLDataLocator_AndroidSimpleBufferQueue que = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,10};
//音频格式
SLDataFormat_PCM pcm = {
SL_DATAFORMAT_PCM,
2,// 声道数
SL_SAMPLINGRATE_44_1,
SL_PCMSAMPLEFORMAT_FIXED_16,
SL_PCMSAMPLEFORMAT_FIXED_16,
SL_SPEAKER_FRONT_LEFT|SL_SPEAKER_FRONT_RIGHT,
SL_BYTEORDER_LITTLEENDIAN //字节序,小端
};
SLDataSource ds = {&que,&pcm}; //4 创建播放器
SLObjectItf player = NULL;
SLPlayItf iplayer = NULL;
SLAndroidSimpleBufferQueueItf pcmQue = NULL;
const SLInterfaceID ids[] = {SL_IID_BUFFERQUEUE};
const SLboolean req[] = {SL_BOOLEAN_TRUE};
re = (*eng)->CreateAudioPlayer(eng,&player,&ds,&audioSink,sizeof(ids)/sizeof(SLInterfaceID),ids,req);
if(re !=SL_RESULT_SUCCESS )
{
LOGD("CreateAudioPlayer failed!");
} else{
LOGD("CreateAudioPlayer success!");
}
(*player)->Realize(player,SL_BOOLEAN_FALSE);
//获取player接口
re = (*player)->GetInterface(player,SL_IID_PLAY,&iplayer);
if(re !=SL_RESULT_SUCCESS )
{
LOGD("GetInterface SL_IID_PLAY failed!");
}
re = (*player)->GetInterface(player,SL_IID_BUFFERQUEUE,&pcmQue);
if(re !=SL_RESULT_SUCCESS )
{
LOGD("GetInterface SL_IID_BUFFERQUEUE failed!");
} //设置回调函数,播放队列空调用
(*pcmQue)->RegisterCallback(pcmQue,PcmCall,0); //设置为播放状态
(*iplayer)->SetPlayState(iplayer,SL_PLAYSTATE_PLAYING); //启动队列回调
(*pcmQue)->Enqueue(pcmQue,"",1); 错误的代码:
//1.创建引擎
SLEngineItf eng = CreateSL(); //2.创建输出设备
SLObjectItf mix = NULL;
(*eng)->CreateOutputMix(eng , &mix ,0 ,0 ,0);
//实例化mix
(*mix)->Realize(mix , SL_BOOLEAN_FALSE);
//配置输出设备
SLDataLocator_OutputMix outMix = {SL_DATALOCATOR_OUTPUTMIX , mix};
SLDataSink audioSink = {&outMix , 0};
//配置PCM格式信息
//缓冲格式
SLDataLocator_AndroidSimpleBufferQueue queue = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE
, 10};
//音频格式
SLDataFormat_PCM pcm = {
SL_DATAFORMAT_PCM,
2,
SL_SAMPLINGRATE_44_1,
SL_PCMSAMPLEFORMAT_FIXED_16,
SL_PCMSAMPLEFORMAT_FIXED_16,
SL_SPEAKER_FRONT_RIGHT | SL_SPEAKER_FRONT_LEFT, //SL_SPEAKER_BACK_RIGHT,
SL_BYTEORDER_LITTLEENDIAN //字节序,小断------还有大段 }; SLDataSource ds = {&queue , &pcm}; //创建播放器
SLObjectItf player = NULL;
SLPlayItf iplayer = NULL ;
const SLInterfaceID ids[] = {SL_IID_BUFFERQUEUE};
const SLboolean req[] = {SL_BOOLEAN_TRUE};
(*eng)->CreateAudioPlayer(eng,&player,&ds,&audioSink,sizeof(ids)/sizeof(SLInterfaceID),ids,req); //如果只用player接口就不用传其他
//实例化播放器 //参数,因为调用到内部类的接口,
(*player)->Realize(player ,SL_BOOLEAN_FALSE); //所以必须传入其他参数
//获取接口
(*player)->GetInterface(player, SL_IID_PLAY, &iplayer); //获取队列的接口
SLAndroidSimpleBufferQueueItf pcmQue = NULL;
(*player)->GetInterface(player, SL_IID_BUFFERQUEUE, &pcmQue); //设置回调函数
(*pcmQue)->RegisterCallback(pcmQue, PcmCall, 0); //设置播放状态
(*iplayer)->SetPlayState(iplayer , SL_PLAYSTATE_PLAYING); //启动队列回调
(*pcmQue)->Enqueue(pcmQue , " ",1);
												

OpenSL的代码编写的更多相关文章

  1. 使用Spring注解来简化ssh框架的代码编写

     目的:主要是通过使用Spring注解的方式来简化ssh框架的代码编写. 首先:我们浏览一下原始的applicationContext.xml文件中的部分配置. <bean id="m ...

  2. VS开发中的代码编写小技巧——避免重复代码编写的几种方法

    上一篇文章中程序员的幸福生活--有你的日子,每天都是情人节,收到了大家的很多好评.鼓励和祝福,非常感动,真诚的谢谢大家.也希望每个朋友都能保持一个积极向上的心态,去迎接丰富多彩的人生. 在开发过程中, ...

  3. IOS 推送-配置与代码编写

    IOS 推送配置与代码编写 这里介绍IOS的推送,本文章已经在IOS6/7/8上都能运行OK,按照道理IOS9应该没问题. 大纲: 1.文章前提 2.推送介绍 3.推送文件账号设置 4.推送证书介绍 ...

  4. .NET代码编写规范 整理

    .NET代码编写规范 整理 .NET代码编写规范 - [ASP.NET] 2009-02-26 | Tag: 版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明 http://lensp ...

  5. 纯javascript代码编写计算器程序

    今天来分享一下用纯javascript代码编写的一个计算器程序,很多行业都能用到这个程序,例如做装修预算.贷款利率等等. 首先来看一下完成后的效果: 具体代码如下:(关注我的博客,及时获取最新WEB前 ...

  6. 如何优雅的代码编写 AutoLayout

    概述 使用 Objective-C 纯代码编写 AutoLayout,看 AutoLayout 的字面理解就是自动布局,听起来好像蛮屌的样子.说白了就是适配:适应.兼容各种不同的情况,包括不同版本的操 ...

  7. 小代码编写神器:LINQPad 使用入门

    原文:小代码编写神器:LINQPad 使用入门 一:概述 1:想查看程序运行结果,又不想启动 VS 怎么办? 2:想测试下自己的 C# 能力,不使用 VS 的智能感知,怎么办? 那么,我们有一个选择, ...

  8. 使用python制作ArcGIS插件(2)代码编写

    使用python制作ArcGIS插件(2)代码编写 by 李远祥 上一章节已经介绍了如何去搭建AddIn的界面,接下来要实现具体的功能,则到了具体的编程环节.由于使用的是python语言进行编程,则开 ...

  9. 代码编写规范说明书(c#.net与asp.net)

    代码编写规范说明书(c#.net与asp.net) 目 录1 目的2 范围3 注释规范3.1 概述3.2 自建代码文件注释3.3 模块(类)注释3.4 类属性注释3.5 方法注释3.6 代码间注释4 ...

随机推荐

  1. VINS-mono详细解读

    VINS-mono详细解读 极品巧克力 前言 Vins-mono是香港科技大学开源的一个VIO算法,https://github.com/HKUST-Aerial-Robotics/VINS-Mono ...

  2. discuz回贴通知插件实现-用户状态设置

    1.获取用户提交数据 discuz通过$_GET来获取全部数据,包括($_GET,$_POST). else if($_GET['pluginop'] == 'set') { //获取用户提交数据 $ ...

  3. 【每日更新】【SQL实用大杂烩】

    11.分页1. select * from (select top 2 * from( select top 3 * from t_table order by field1) a order by  ...

  4. HDOJ1242 Rescue(营救) 搜索

    Rescue Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  5. springcloud-eureka简单实现

    请参考 spring+cloud为服务实战 第三章 一.创建Eureka服务 1.使用Idea创建一个项目 结构如下: 2.pom.xml配置: <?xml version="1.0& ...

  6. * 结束Activity

    public class MainActivity extends Activity   {       @Override       public void onCreate(Bundle sav ...

  7. Python中的replace方法

    replace 方法:返回根据正则表达式进行文字替换后的字符串的复制. stringObj.replace(rgExp, replaceText) 参数 stringObj必选项.要执行该替换的 St ...

  8. (回文串 Manacher)吉哥系列故事——完美队形II -- hdu -- 4513

    http://acm.hdu.edu.cn/showproblem.php?pid=4513 吉哥系列故事——完美队形II Time Limit: 3000/1000 MS (Java/Others) ...

  9. Codeforces805 C. Find Amir 2017-05-05 08:41 140人阅读 评论(0) 收藏

    C. Find Amir time limit per test 1 second memory limit per test 256 megabytes input standard input o ...

  10. delphi 手机振动 IOS Android

    delphi 手机振动 IOS Android delphi  手机振动 IOS Android 振动 https://community.embarcadero.com/blogs/entry/ho ...