#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. jquery datatables api

    原文地址 学习可参考:http://www.guoxk.com/node/jquery-datatables http://yuemeiqing2008-163-com.iteye.com/blog/ ...

  2. 将对象转为json,加入到HttpResponseMessage中

    需要引用程序集: System.Net.Http System.Web System.Web.Extensions Code: using System; using System.Collectio ...

  3. Bad Hair Day

    /* Some of Farmer John's N cows (1 ≤ N ≤ 80,000) are having a bad hair day! Since each cow is self-c ...

  4. 03 解析库之Beautifulsoup模块

    Beautifulsoup模块   一 介绍 Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式 ...

  5. 别人家的PS系列又来了!!!

    又到了“别人的PS”系列的日常感叹了,大家请边看推文边组织语言准备留言,用点新鲜词,不要再说什么给跪了,献上膝盖之类的,争取换点词. 好了,废话不多说,开始正文,先看几则简单的PS作品: 这两组作品出 ...

  6. tp5允许跨域

    header("Access-Control-Allow-Origin: *"); 放在命名空间之后

  7. 2. Get the codes from GIT

    Clone the code from git.

  8. centos6.8下redis的安装和配置

    centos6.8下redis的安装和配置 下载.安装 在redis官网可以获取到最新版本的redis 进入/usr/local/目录,执行如下命令 wget http://download.redi ...

  9. 2018.09.29 bzoj3675: [Apio2014]序列分割(斜率优化dp)

    传送门 斜率优化dp经典题目. 首先需要证明只要选择的K个断点是相同的,那么得到的答案也是相同的. 根据分治的思想,我们只需要证明有两个断点时成立,就能推出K个断点时成立. 我们设两个断点分成的三段连 ...

  10. 2018.09.12 poj3621Sightseeing Cows(01分数规划+spfa判环)

    传送门 01分数规划板题啊. 发现就是一个最优比率环. 这个直接二分+spfa判负环就行了. 代码: #include<iostream> #include<cstdio> # ...