OpenSL的使用
#include <jni.h> 
#include <string> 
#include <SLES/OpenSLES.h> 
#include <SLES/OpenSLES_Android.h> 
#include <android/log.h> 
#define LOGD(FORMAT,...) __android_log_print(ANDROID_LOG_ERROR,"ywl5320",FORMAT,##__VA_ARGS__); 
 
//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/test.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_aplay_testopensl_MainActivity_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 配置音频信息 
    //数据定位器 就是定位要播放声音数据的存放位置,分为4种:内存位置,输入/输出设备位置,缓冲区队列位置,和midi缓冲区队列位置。
    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); 
 
    return env->NewStringUTF(hello.c_str()); 
}
OpenSL的使用的更多相关文章
- Android IOS WebRTC 音视频开发总结(十六)-- 音频设备操作之opensl与jni
		本节主要分享视频通话中android和ios上操作音频设备的方式,如调解音量大小,启用扬声器(本系列文章转载请说明出处,博客园RTC.Blacker). 先看看webrtc中处理音频设备代码的目录结构 ... 
- [工作记录] Android OpenSL ES: references & AAC related
		AAC V.S. MP3 http://en.wikipedia.org/wiki/Advanced_Audio_Coding#AAC.27s_improvements_over_MP3 AAC pa ... 
- Android OpenSL ES 开发:Android OpenSL 介绍和开发流程说明
		一.Android OpenSL ES 介绍 OpenSL ES (Open Sound Library for Embedded Systems)是无授权费.跨平台.针对嵌入式系统精心优化的硬件音频 ... 
- Android OpenSL ES 开发:使用 OpenSL 播放 PCM 数据
		OpenSL ES 是基于NDK也就是c语言的底层开发音频的公开API,通过使用它能够做到标准化, 高性能,低响应时间的音频功能实现方法. 这次是使用OpenSL ES来做一个音乐播放器,它能够播放m ... 
- Android OpenSL ES 开发:Android OpenSL 录制 PCM 音频数据
		一.实现说明 OpenSL ES的录音要比播放简单一些,在创建好引擎后,再创建好录音接口基本就可以录音了.在这里我们做的是流式录音,所以需要用至少2个buffer来缓存录制好的PCM数据,这里我们可以 ... 
- Android OpenSL ES 开发:OpenSL ES利用SoundTouch实现PCM音频的变速和变调
		缘由 OpenSL ES 学习到现在已经知道 OpenSL ES 不仅能播放和录制PCM音频数据,还能改变声音大小.设置左声道或右声道播放.还能变速播放,可谓是播放音频的王者.但是变速有一点不好的就是 ... 
- Android 音视频深入 十四  FFmpeg与OpenSL ES 播放mp3音乐,能暂停(附源码下载)
		项目地址https://github.com/979451341/FFmpegOpenslES 这次说的是FFmpeg解码mp3,数据给OpenSL ES播放,并且能够暂停. 1.创建引擎 slCre ... 
- Android 音视频深入 十三 OpenSL ES 制作音乐播放器,能暂停和调整音量(附源码下载)
		项目地址https://github.com/979451341/OpenSLAudio OpenSL ES 是基于NDK也就是c语言的底层开发音频的公开API,通过使用它能够做到标准化, 高性能,低 ... 
- OpenSL ES 查询设备支持的SL Profiles
		opensl es 提供了三种类型:分别是 SL_PROFILES_PHONE(手机):SL_PROFILES_MUSIC(音乐); SL_PROFILES_GAME (游戏). 如果你使用的手机的开 ... 
- Android音视频学习第7章:使用OpenSL ES进行音频解码
		/* * *这里使用了transcode-1.1.7对wav文件进行解码.然后使用opensl es进行播放 * */ //用到的变量和结构体 WAV wav; //wav文件指针 SLObjectI ... 
随机推荐
- php 下 html5 XHR2 + FormData + File API 上传文件
			FormData的作用: FormData对象可以帮助我们自动的打包表单数据,通过XMLHttpRequest的send()方法来提交表单.当然FormData也可以动态的append数据.FormD ... 
- Spring框架的AOP技术(注解方式)
			1. 步骤一:创建JavaWEB项目,引入具体的开发的jar包 * 先引入Spring框架开发的基本开发包 * 再引入Spring框架的AOP的开发包 * spring的传统AOP的开发的包 * sp ... 
- jetty 8.0 add filter example
			http://zyn010101.iteye.com/blog/1679798 package com.cicc.gaf.sso.server;import java.io.IOException;i ... 
- MVC,MVP,MVVM区别联系
			本质上都是MVC,MVC在不同技术中的应用衍生出MVP,MVVM MVC:b/s MVP:c/s,尤其winform MVVM:wpf http://www.codeproject.com/Artic ... 
- spring boot2.03 spring cloud Finchley.RELEASE遇到的问题
			1.spring cloud bus 本地不能更新 原因是@RefreshScope注解要加在需要更新的controller上 2.No instances found of configserver ... 
- Mint UI 之 Swipe 组件
			#为什么不显示内容? 一定要指定 mt-swipe 元素的宽和高. <mt-swipe :auto="4000" class="swipe"> &l ... 
- cxf  soap  rest webservice  spring
			1. 导入 jar 包 2. 编写接口 3. 编写实现 4. 配置spring 配置文件 5. 配置web.xml servlet 6. 访问 package com.diancai.test; im ... 
- 按条件设置gridcontrol 单元格属性
			等价代码设置:(注意这里使用都是FieldName, 即绑定对象的字段名) var cn = new StyleFormatCondition(FormatConditionEnum.Expressi ... 
- 如何在Linux中统计一个进程的线程数(转)
			方法一: /proc proc 伪文件系统,它驻留在 /proc 目录,这是最简单的方法来查看任何活动进程的线程数. /proc 目录以可读文本文件形式输出,提供现有进程和系统硬件相关的信息如 CPU ... 
- C和指针小结(C/C++程序设计)
			C和指针 相关基础知识:内存的分配(谭浩强版) 1.整型变量的地址与浮点型/字符型变量的地址区别?(整型变量/浮点型变量的区别是什么) 2.int *p,指向整型数据的指针变量. 3.通过指针变量访问 ... 
