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 }