#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的使用的更多相关文章

  1. Android IOS WebRTC 音视频开发总结(十六)-- 音频设备操作之opensl与jni

    本节主要分享视频通话中android和ios上操作音频设备的方式,如调解音量大小,启用扬声器(本系列文章转载请说明出处,博客园RTC.Blacker). 先看看webrtc中处理音频设备代码的目录结构 ...

  2. [工作记录] 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 ...

  3. Android OpenSL ES 开发:Android OpenSL 介绍和开发流程说明

    一.Android OpenSL ES 介绍 OpenSL ES (Open Sound Library for Embedded Systems)是无授权费.跨平台.针对嵌入式系统精心优化的硬件音频 ...

  4. Android OpenSL ES 开发:使用 OpenSL 播放 PCM 数据

    OpenSL ES 是基于NDK也就是c语言的底层开发音频的公开API,通过使用它能够做到标准化, 高性能,低响应时间的音频功能实现方法. 这次是使用OpenSL ES来做一个音乐播放器,它能够播放m ...

  5. Android OpenSL ES 开发:Android OpenSL 录制 PCM 音频数据

    一.实现说明 OpenSL ES的录音要比播放简单一些,在创建好引擎后,再创建好录音接口基本就可以录音了.在这里我们做的是流式录音,所以需要用至少2个buffer来缓存录制好的PCM数据,这里我们可以 ...

  6. Android OpenSL ES 开发:OpenSL ES利用SoundTouch实现PCM音频的变速和变调

    缘由 OpenSL ES 学习到现在已经知道 OpenSL ES 不仅能播放和录制PCM音频数据,还能改变声音大小.设置左声道或右声道播放.还能变速播放,可谓是播放音频的王者.但是变速有一点不好的就是 ...

  7. Android 音视频深入 十四 FFmpeg与OpenSL ES 播放mp3音乐,能暂停(附源码下载)

    项目地址https://github.com/979451341/FFmpegOpenslES 这次说的是FFmpeg解码mp3,数据给OpenSL ES播放,并且能够暂停. 1.创建引擎 slCre ...

  8. Android 音视频深入 十三 OpenSL ES 制作音乐播放器,能暂停和调整音量(附源码下载)

    项目地址https://github.com/979451341/OpenSLAudio OpenSL ES 是基于NDK也就是c语言的底层开发音频的公开API,通过使用它能够做到标准化, 高性能,低 ...

  9. OpenSL ES 查询设备支持的SL Profiles

    opensl es 提供了三种类型:分别是 SL_PROFILES_PHONE(手机):SL_PROFILES_MUSIC(音乐); SL_PROFILES_GAME (游戏). 如果你使用的手机的开 ...

  10. Android音视频学习第7章:使用OpenSL ES进行音频解码

    /* * *这里使用了transcode-1.1.7对wav文件进行解码.然后使用opensl es进行播放 * */ //用到的变量和结构体 WAV wav; //wav文件指针 SLObjectI ...

随机推荐

  1. mybatis框架的架构(图解)

    1. mybatis配置 SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息. mapper.xml文件即sql映射文件,文件中配置了操作数 ...

  2. Java WebService 知识点汇总

    java webservice 获取传入IP axis.jar    servlet.jar MessageContext mMsgContext = MessageContext.getCurren ...

  3. spring mvc leaning

    解读 web.xml文件 <servlet>-----配置前端控制器的servlet <servlet-name>springMVC</servlet-name> ...

  4. ffmpeg 入门教程

    1.在terminal,安装ffmpeg开源库 #brew install ffmpeg 2.新建一个目录first_ffmpeg,并在first_ffmpeg目录下新建ffmpeg目录 3.拷贝/u ...

  5. 怎样完整地离线更新并升级基于 Debian 的操作系统

    不久之前我已经向你展示了如何在任意离线的 Ubuntu 和 Arch Linux 操作系统上安装软件. 今天,我们将会看看如何完整地离线更新并升级基于 Debian 的操作系统. 和之前所述方法的不同 ...

  6. win7安装qt5 纯记录 水文

    去qt官网下载http://www.qt.io/看见download就点进去看看吧 目前的下载地址路径是http://www.qt.io/download-open-source选择Offline I ...

  7. oracle 存储过程应用

    1.查看 SELECT * FROM all_source WHERE type='PROCEDURE' and name=upper('liuyi_prcd'); 2.删除 DROP PROCEDU ...

  8. ubuntu系统中安装RoboMongo

    1.下载RoboMongo RoboMongo官网下载链接.选择好相应版本. 2.解压文件 tar -xzf robomongo--linux-x86_64-.tar.gzcd robomongo-0 ...

  9. 使用PrintWriter out=response.getWriter();输出script脚本时乱码解决

    使用PrintWriter out=response.getWriter();输出script脚本时乱码解决 最近遇到了一个奇怪的事情,仅仅用out.print("<script ty ...

  10. composer 安装扩展失败的决绝方法

    https://getyii.com/topic/32