#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. oracle使用 merge 更新或插入数据

    OracleCC++C#  总结下.使用merge比传统的先判断再选择插入或更新快很多. 1)主要功能 提供有条件地更新和插入数据到数据库表中 如果该行存在,执行一个UPDATE操作,如果是一个新行, ...

  2. 解压查看二进制rpm包的方法

    详细参考: man cpio 具体方法: rpm2cpio qt5-qtbase-5.6.0-13.fc21.x86_64.rpm | cpio -dium 执行后可在当前目录查看 安装目录  etc ...

  3. memcached centos启动笔记

    root情况下命令行输入 apt-get install memcached 自动安装 不熟悉的情况下 可能找不到改程序所在目录 使用 find / -name memcached 从根目录开始寻找 ...

  4. android textview settext卡顿深层次原因

    最近在公司项目里面发现listview里面的textview在调用settext函数的时候非常耗时,当时都有点不敢相信,这是因为如果你把textview设置成wrap_content,则每次调用set ...

  5. chrome,opera..通过file协议浏览html代码时,发送的ajax请求本地文件,会报跨域错误

    XMLHttpRequest cannot loadfile:///E:/webs/extJS/ext-3.3.0/examples/csdn/combobox.txt?_dc=14147389739 ...

  6. 20155232 2016-2017-3 《Java程序设计》第9周学习总结

    20155232 2016-2017-3 <Java程序设计>第9周学习总结 教材学习内容总结 第16章 JDBC(Java DataBase Connectivity)即java数据库连 ...

  7. 657. Judge Route Circle

    static int wing=[]() { std::ios::sync_with_stdio(false); cin.tie(NULL); ; }(); class Solution { publ ...

  8. 2018.09.01 poj3071Football(概率dp+二进制找规律)

    传送门 概率dp简单题. 设f[i][j]表示前i轮j获胜的概率. 如果j,k能够刚好在第i轮相遇,找规律可以发现j,k满足: (j−1)>>(i−1)" role=" ...

  9. 2018.07.18 [NOI2018]归程(return)(kruskal重构树)

    传送门 新鲜出炉的noi2018试题. 下面讲讲这题的解法: 首先要学习一个叫做kruskal重构树的东东. 听名字就知道跟kruskal算法有关,没错,原来的kruskal算法就是用并查集实现的,但 ...

  10. 2018.07.06 POJ 1459 Power Network(多源多汇最大流)

    Power Network Time Limit: 2000MS Memory Limit: 32768K Description A power network consists of nodes ...