首页 > 编程知识 正文

空间数据主要用于描述,winamp主要用于播放mp3文件

时间:2023-05-06 20:50:19 阅读:276841 作者:1223

资料:
https://github.com/googlesamples/android-ndk

里面找到

https://github.com/googlesamples/android-ndk/tree/master/native-audio

里面是google 的模板代码

sd 香蕉蜜粉目录有一个output.pcm 的数据

java 的代码

public class MainActivity extends AppCompatActivity { static { System.loadLibrary("native-lib"); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public native void palypcm(String url); public void play(View view) { String path = "/mnt/sdcard/output.pcm"; palypcm(path); }}

OpenSL ES 播放pcm的代码

#include <jni.h>#include <string>extern "C"{#include <SLES/OpenSLES.h>#include <SLES/OpenSLES_Android.h>}#include <android/log.h>#define LOGI(FORMAT,...) __android_log_print(ANDROID_LOG_INFO,"jniLib",FORMAT,##__VA_ARGS__);#define LOGE(FORMAT,...) __android_log_print(ANDROID_LOG_ERROR,"jniLib",FORMAT,##__VA_ARGS__);// 引擎接口SLObjectItf engineObject = NULL;SLEngineItf engineEngine = NULL;//混音器SLObjectItf outputMixObject = NULL;SLEnvironmentalReverbItf outputMixEnvironmentalReverb = NULL;SLEnvironmentalReverbSettings reverbSettings = SL_I3DL2_ENVIRONMENT_PRESET_STONECORRIDOR;//pcmSLObjectItf pcmPlayerObject = NULL;SLPlayItf pcmPlayerPlay = NULL;SLVolumeItf pcmPlayerVolume = NULL;//缓冲器队列接口SLAndroidSimpleBufferQueueItf pcmBufferQueue;FILE *pcmFile;void *buffer;uint8_t *out_buffer;void getPcmData(void **pcm){ //是否读到结尾 while(!feof(pcmFile)) { /** * size_t fread( void *buffer, size_t size, size_t count, FILE *stream ) buffer 是读取的数据存放的内存的指针(可以是数组,也可以是新开辟的空间,buffer就是一个索引) size 是每次读取的字节数 count 是读取次数 strean 是要读取的文件的指针 例如 从文件fp里读取100个字节 可用以下语句 fread(buffer,100,1,fp) fread(buffer,50,2,fp) fread(buffer,1,100,fp) */ fread(out_buffer, 44100 * 2 * 2, 1, pcmFile); if(out_buffer == NULL) { LOGI("%s", "read end"); break; } else{ LOGI("%s", "reading"); } *pcm = out_buffer; break; }}void pcmBufferCallBack(SLAndroidSimpleBufferQueueItf bf, void * context){ //assert(NULL == context); getPcmData(&buffer); // for streaming playback, replace this test by logic to find and fill the next buffer if (NULL != buffer) { SLresult result; // enqueue another buffer result = (*pcmBufferQueue)->Enqueue(pcmBufferQueue, buffer, 44100 * 2 * 2); // the most likely other result is SL_RESULT_BUFFER_INSUFFICIENT, // which for this code example would indicate a programming error }}extern "C"JNIEXPORT void JNICALLJava_com_example_androidopenslaudio_MainActivity_palypcm(JNIEnv *env, jobject instance, jstring url_) { const char *url = env->GetStringUTFChars(url_, 0); // TODO //读取pcm文件 pcmFile = fopen(url, "r"); if(pcmFile == NULL) { LOGE("%s", "fopen file error"); return; } out_buffer = (uint8_t *) malloc(44100 * 2 * 2); SLresult result; //第一步------------------------------------------ // 创建引擎对象 slCreateEngine(&engineObject, 0, 0, 0, 0, 0); (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE); (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine); //第二步------------------------------------------- // 创建混音器 const SLInterfaceID mids[1] = {SL_IID_ENVIRONMENTALREVERB}; const SLboolean mreq[1] = {SL_BOOLEAN_FALSE}; result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 1, mids, mreq); (void)result; result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE); (void)result; result = (*outputMixObject)->GetInterface(outputMixObject, SL_IID_ENVIRONMENTALREVERB, &outputMixEnvironmentalReverb); if (SL_RESULT_SUCCESS == result) { result = (*outputMixEnvironmentalReverb)->SetEnvironmentalReverbProperties( outputMixEnvironmentalReverb, &reverbSettings); (void)result; } SLDataLocator_OutputMix outputMix = {SL_DATALOCATOR_OUTPUTMIX, outputMixObject}; // 第三步-------------------------------------------- // 创建播放器 SLDataLocator_AndroidSimpleBufferQueue android_queue={SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,2}; SLDataFormat_PCM pcm={ SL_DATAFORMAT_PCM,//播放pcm格式的数据 2,//2个声道(立体声) SL_SAMPLINGRATE_44_1,//44100hz的频率 SL_PCMSAMPLEFORMAT_FIXED_16,//位数 16位 SL_PCMSAMPLEFORMAT_FIXED_16,//和位数一致就行 SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT,//立体声(前左前右) SL_BYTEORDER_LITTLEENDIAN//结束标志 }; SLDataSource slDataSource = {&android_queue, &pcm}; SLDataSink audioSnk = {&outputMix, NULL}; const SLInterfaceID ids[3] = {SL_IID_BUFFERQUEUE, SL_IID_EFFECTSEND, SL_IID_VOLUME}; const SLboolean req[3] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE}; result = (*engineEngine)->CreateAudioPlayer(engineEngine, &pcmPlayerObject, &slDataSource, &audioSnk, 3, ids, req); // 初始化播放器 (*pcmPlayerObject)->Realize(pcmPlayerObject, SL_BOOLEAN_FALSE); //得到接口后调用 获取Player接口 (*pcmPlayerObject)->GetInterface(pcmPlayerObject, SL_IID_PLAY, &pcmPlayerPlay); //第四步--------------------------------------- // 创建缓冲区和回调函数 (*pcmPlayerObject)->GetInterface(pcmPlayerObject, SL_IID_BUFFERQUEUE, &pcmBufferQueue); //缓冲接口回调 (*pcmBufferQueue)->RegisterCallback(pcmBufferQueue, pcmBufferCallBack, NULL); //获取音量接口 (*pcmPlayerObject)->GetInterface(pcmPlayerObject, SL_IID_VOLUME, &pcmPlayerVolume); //第五步---------------------------------------- // 设置播放状态 (*pcmPlayerPlay)->SetPlayState(pcmPlayerPlay, SL_PLAYSTATE_PLAYING); //第六步---------------------------------------- // 主动调用回调函数开始工作 pcmBufferCallBack(pcmBufferQueue, NULL); env->ReleaseStringUTFChars(url_, url);}

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。