opensl es初始化代码

  1 const double amplitude = 0.5;
  2 //const double sampleRate = 44100.0;
  3 const double sampleRate = 48000.0;
  4 const int samplesPerBuffer = 1024;
  5 double frequency = 440.0;
  6 // 生成正弦波样本的缓冲区
  7 short buffer[2][samplesPerBuffer];
  8 int currentBuffer = 0;
  9 
 10 SLObjectItf engineObject;
 11 SLEngineItf engineEngine;
 12 
 13 // 播放器
 14 SLObjectItf playerObj;
 15 SLPlayItf playerPlay;
 16 
 17 SLAndroidSimpleBufferQueueItf playerBufferQueue;
 18 
 19 // 新增前向声明
 20 void bufferQueueCallback(SLAndroidSimpleBufferQueueItf bq, void *context);
 21 double generateSineWave(short* outputBuffer, int numSamples,
 22                         double currentPhase, double freq,
 23                         double amp, double sRate);
 24 double gentran(short* outputBuffer, int numSamples,double currentPhase, double freq,double amp, double sRate);
 25 double gensaw(short* outputBuffer, int numSamples,double currentPhase, double freq,double amp, double sRate);
 26 double gensquare(short* outputBuffer, int numSamples,double currentPhase, double freq,double amp, double sRate);
 27 
 28 typedef struct CallbackContext {
 29     double currentPhase;   // 当前相位
 30     short* pcmBuffer;      // 音频缓冲区
 31 } CallbackContext;
 32 CallbackContext *ctx = nullptr;
 33 extern "C"
 34 JNIEXPORT void JNICALL
 35 Java_com_xsh_opensltest_SlInstrumentTest_initEngine(JNIEnv *env, jobject thiz)
 36 {
 37     // 创建引擎
 38     SLresult result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
 39     if(result !=SL_RESULT_SUCCESS)
 40     {
 41         __android_log_print(ANDROID_LOG_ERROR, "OpenSLES", "slCreateEngine failed");
 42     }
 43     SLresult engineRealize = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
 44     if(engineRealize !=SL_RESULT_SUCCESS)
 45     {
 46         __android_log_print(ANDROID_LOG_ERROR, "OpenSLES", "engineRealize failed");
 47     }
 48     SLresult engineInterFace = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
 49     if(engineInterFace !=SL_RESULT_SUCCESS)
 50     {
 51         __android_log_print(ANDROID_LOG_ERROR, "OpenSLES", "engineInterFace failed");
 52     }
 53     // 创建混音器
 54     SLObjectItf outputMixObject;
 55     SLresult outputMix = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, NULL, NULL);
 56     if(outputMix !=SL_RESULT_SUCCESS)
 57     {
 58         __android_log_print(ANDROID_LOG_ERROR, "OpenSLES", "CreateOutputMix failed");
 59     }
 60     SLresult outputMixRealize = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
 61     if(outputMixRealize !=SL_RESULT_SUCCESS)
 62     {
 63         __android_log_print(ANDROID_LOG_ERROR, "OpenSLES", "outputMixRealize failed");
 64     }
 65 
 66     // 配置音频参数
 67     // 定义 PCM 参数
 68     SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {
 69             SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,
 70             2 // 缓冲区数量
 71     };
 72 
 73     SLDataFormat_PCM format_pcm = {
 74             SL_DATAFORMAT_PCM,
 75             2,                  // 声道数2 对应 SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT,
 76             SL_SAMPLINGRATE_48, // 采样率 44100Hz
 77             SL_PCMSAMPLEFORMAT_FIXED_16, // 16位采样
 78             SL_PCMSAMPLEFORMAT_FIXED_16,
 79             //SL_SPEAKER_FRONT_CENTER,
 80             SL_SPEAKER_FRONT_LEFT|SL_SPEAKER_FRONT_RIGHT,
 81             SL_BYTEORDER_LITTLEENDIAN
 82     };
 83 
 84     SLDataSource audioSrc = {&loc_bufq, &format_pcm};
 85 
 86     SLDataLocator_OutputMix loc_outmix = {
 87         SL_DATALOCATOR_OUTPUTMIX,
 88         outputMixObject
 89     };
 90     SLDataSink audioSnk = {&loc_outmix, NULL};
 91 
 92     const SLInterfaceID ids[1] = {SL_IID_BUFFERQUEUE};
 93     const SLboolean req[1] = {SL_BOOLEAN_TRUE};
 94     //创建播放器
 95     SLresult resultAudioPlayer = (*engineEngine)->CreateAudioPlayer(
 96         engineEngine,
 97         &playerObj,// 改成engineObject试试 Error:createAudioPlayer failed
 98         &audioSrc,
 99         &audioSnk,
100         1, ids, req
101     );
102     if(resultAudioPlayer!=SL_RESULT_SUCCESS)
103     {
104         __android_log_print(ANDROID_LOG_ERROR, "OpenSLES", "createAudioPlayer failed");
105     }
106     // 可能要改下面的代码
107     (*playerObj)->Realize(playerObj, SL_BOOLEAN_FALSE);
108     (*playerObj)->GetInterface(playerObj, SL_IID_PLAY, &playerPlay);
109     SLresult  getBufferQueueResult = (*playerObj)->GetInterface(playerObj, SL_IID_BUFFERQUEUE, &playerBufferQueue);
110     if(getBufferQueueResult!=SL_RESULT_SUCCESS){
111         __android_log_print(ANDROID_LOG_ERROR, "OpenSLES", "GetInterface(BUFFERQUEUE) failed: %d", getBufferQueueResult);
112     }
113     ctx = new CallbackContext ();
114     ctx->currentPhase = 0.0;
115     ctx->pcmBuffer = new short[samplesPerBuffer];// 分配缓冲区内存
116     SLresult  regResult = (*playerBufferQueue)->RegisterCallback(playerBufferQueue, bufferQueueCallback, ctx);
117     if(regResult!=SL_RESULT_SUCCESS)
118     {
119         __android_log_print(ANDROID_LOG_ERROR, "OpenSLES", "RegisterCallback failed: %d", regResult);
120     }
121     bufferQueueCallback(playerBufferQueue, ctx); // 第一次填充
122     bufferQueueCallback(playerBufferQueue, ctx); // 第二次填充
123     //SLresult playResult = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PLAYING);
124     /*if (playResult != SL_RESULT_SUCCESS) {
125         __android_log_print(ANDROID_LOG_ERROR, "OpenSLES", "SetPlayState failed: %d", playResult);
126     }*/
127 }
128 
129 // 缓冲队列回调函数
130 void bufferQueueCallback(SLAndroidSimpleBufferQueueItf bq, void *context)
131 {
132     CallbackContext *ctx = (CallbackContext*)context;
133     if(currenWaveType == WaveType::SINE)
134     {
135         ctx->currentPhase = generateSineWave(ctx->pcmBuffer,samplesPerBuffer,ctx->currentPhase,frequency,amplitude,sampleRate);
136     }
137     else if(currenWaveType == WaveType::SAWTOOTH)
138     {
139         ctx->currentPhase = gensaw(ctx->pcmBuffer,samplesPerBuffer,ctx->currentPhase,frequency,amplitude,sampleRate);
140     }
141     /*ctx->currentPhase = generateSineWave(
142             ctx->pcmBuffer,
143             samplesPerBuffer,
144             ctx->currentPhase,
145             frequency,
146             amplitude,
147             sampleRate
148             );*/
149     SLresult  r = (*bq)->Enqueue(bq,ctx->pcmBuffer,sizeof(short)*samplesPerBuffer);
150     if(r !=SL_RESULT_SUCCESS)
151     {
152         __android_log_print(ANDROID_LOG_ERROR,"OpenSLES","Enqueue failed: ");
153         __android_log_print(ANDROID_LOG_ERROR,"OpenSLES","%d", r);
154     }
155 }

 

posted on 2025-05-27 08:24  小沙盒工作室  阅读(16)  评论(0)    收藏  举报