• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <OpenSLES.h>
17 #include <OpenSLES_OpenHarmony.h>
18 #include <OpenSLES_Platform.h>
19 #include "media_log.h"
20 #include <iostream>
21 #include "pcm2wav.h"
22 #include <unistd.h>
23 
24 using namespace std;
25 
26 static void BuqqerQueueCallback (SLOHBufferQueueItf bufferQueueItf, void *pContext, SLuint32 size);
27 
28 static void PlayerStart (SLPlayItf playItf, SLOHBufferQueueItf bufferQueueItf, FILE *wavFile);
29 
30 static void PlayerStop (SLPlayItf playItf, SLOHBufferQueueItf bufferQueueItf);
31 
32 static void OpenSlTest();
33 
34 static void OpenSlTestConcurrent();
35 
36 FILE *wavFile_ = nullptr;
37 FILE *wavFile1_ = nullptr;
38 FILE *wavFile2_ = nullptr;
39 wav_hdr wavHeader_;
40 wav_hdr wavHeader1_;
41 wav_hdr wavHeader2_;
42 SLObjectItf engineObject = nullptr;
43 SLObjectItf outputMixObject = nullptr;
44 SLPlayItf playItf;
45 SLPlayItf playItf1;
46 SLPlayItf playItf2;
47 SLVolumeItf volumeItf1;
48 SLVolumeItf volumeItf2;
49 SLOHBufferQueueItf bufferQueueItf;
50 SLOHBufferQueueItf bufferQueueItf1;
51 SLOHBufferQueueItf bufferQueueItf2;
52 SLObjectItf pcmPlayerObject = nullptr;
53 SLObjectItf pcmPlayerObject1 = nullptr;
54 SLObjectItf pcmPlayerObject2 = nullptr;
55 
main(int argc,char * argv[])56 int main(int argc, char *argv[])
57 {
58     if (argc == 4) {
59         size_t headerSize = sizeof(wav_hdr);
60         char *inputPath = argv[1];
61         char path[PATH_MAX + 1] = {0x00};
62         if ((strlen(inputPath) > PATH_MAX) || (realpath(inputPath, path) == nullptr)) {
63             MEDIA_ERR_LOG("Invalid path");
64             return -1;
65         }
66         wavFile1_ = fopen(path, "rb");
67         if (wavFile1_ == nullptr) {
68             MEDIA_INFO_LOG("AudioRendererTest: Unable to open wave file");
69             return -1;
70         }
71         fread(&wavHeader1_, 1, headerSize, wavFile1_);
72 
73         headerSize = sizeof(wav_hdr);
74         inputPath = argv[2];
75         if ((strlen(inputPath) > PATH_MAX) || (realpath(inputPath, path) == nullptr)) {
76             MEDIA_ERR_LOG("Invalid path");
77             return -1;
78         }
79         wavFile2_ = fopen(path, "rb");
80         if (wavFile2_ == nullptr) {
81             MEDIA_INFO_LOG("AudioRendererTest: Unable to open wave file");
82             return -1;
83         }
84         fread(&wavHeader2_, 1, headerSize, wavFile2_);
85 
86         OpenSlTestConcurrent();
87 
88         while (!feof(wavFile1_) || !feof(wavFile2_)) {
89             sleep(1);
90         }
91 
92         PlayerStop(playItf1, bufferQueueItf1);
93         PlayerStop(playItf2, bufferQueueItf2);
94         (*pcmPlayerObject1)->Destroy(pcmPlayerObject1);
95         (*pcmPlayerObject2)->Destroy(pcmPlayerObject2);
96         (*engineObject)->Destroy(engineObject);
97         (*outputMixObject)->Destroy(outputMixObject);
98         return 0;
99     } else {
100         if (argc < 2) {
101             return -1;
102         }
103         size_t headerSize = sizeof(wav_hdr);
104         char *inputPath = argv[1];
105         char path[PATH_MAX + 1] = {0x00};
106         if ((strlen(inputPath) > PATH_MAX) || (realpath(inputPath, path) == nullptr)) {
107             MEDIA_ERR_LOG("Invalid path");
108             return -1;
109         }
110         wavFile_ = fopen(path, "rb");
111         if (wavFile_ == nullptr) {
112             MEDIA_INFO_LOG("AudioRendererTest: Unable to open wave file");
113             return -1;
114         }
115         fread(&wavHeader_, 1, headerSize, wavFile_);
116 
117         OpenSlTest();
118 
119         while (!feof(wavFile_)) {
120             sleep(1);
121         }
122         PlayerStop(playItf, bufferQueueItf);
123         (*pcmPlayerObject)->Destroy(pcmPlayerObject);
124 
125         if (argc < 3) {
126             return 0;
127         }
128         char *inputPath2 = argv[2];
129         char path2[PATH_MAX + 1] = {0x00};
130         if ((strlen(inputPath2) > PATH_MAX) || (realpath(inputPath2, path2) == nullptr)) {
131             MEDIA_ERR_LOG("Invalid path");
132             return -1;
133         }
134         wavFile_ = fopen(path2, "rb");
135         if (wavFile_ == nullptr) {
136             MEDIA_INFO_LOG("AudioRendererTest: Unable to open wave file");
137             return -1;
138         }
139         fread(&wavHeader_, 1, headerSize, wavFile_);
140 
141         OpenSlTest();
142 
143         while (!feof(wavFile_)) {
144             sleep(1);
145         }
146         PlayerStop(playItf, bufferQueueItf);
147         (*pcmPlayerObject)->Destroy(pcmPlayerObject);
148         return 0;
149     }
150 }
151 
OpenSlTest()152 static void OpenSlTest()
153 {
154     MEDIA_INFO_LOG("OpenSlTest");
155     engineObject = nullptr;
156     SLEngineItf engineEngine = nullptr;
157     SLresult result;
158     result = slCreateEngine(&engineObject, 0, nullptr, 0, nullptr, nullptr);
159     result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
160     result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
161 
162     outputMixObject = nullptr;
163     result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, nullptr, nullptr);
164     (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
165 
166     SLDataLocator_OutputMix slOutputMix = {SL_DATALOCATOR_OUTPUTMIX, outputMixObject};
167     SLDataSink slSink = {&slOutputMix, nullptr};
168     SLDataLocator_BufferQueue slBufferQueue = {
169         SL_DATALOCATOR_BUFFERQUEUE,
170         0
171     };
172     SLDataFormat_PCM pcmFormat = {
173         SL_DATAFORMAT_PCM,
174         wavHeader_.NumOfChan,
175         wavHeader_.SamplesPerSec * 1000,
176         wavHeader_.bitsPerSample,
177         0,
178         0,
179         0
180     };
181     SLDataSource slSource = {&slBufferQueue, &pcmFormat};
182     result = (*engineEngine)->CreateAudioPlayer(engineEngine, &pcmPlayerObject, &slSource, &slSink, 3, nullptr, nullptr);
183     (*pcmPlayerObject)->Realize(pcmPlayerObject, SL_BOOLEAN_FALSE);
184 
185     (*pcmPlayerObject)->GetInterface(pcmPlayerObject, SL_IID_PLAY, &playItf);
186     SLVolumeItf volumeItf;
187     (*pcmPlayerObject)->GetInterface(pcmPlayerObject, SL_IID_VOLUME, &volumeItf);
188     SLmillibel pLevel = 0;
189     (*volumeItf)->GetVolumeLevel(volumeItf, &pLevel);
190     (*pcmPlayerObject)->GetInterface(pcmPlayerObject, SL_IID_OH_BUFFERQUEUE, &bufferQueueItf);
191     (*bufferQueueItf)->RegisterCallback(bufferQueueItf, BuqqerQueueCallback, wavFile_);
192 
193     PlayerStart(playItf, bufferQueueItf, wavFile_);
194 }
195 
OpenSlTestConcurrent()196 static void OpenSlTestConcurrent()
197 {
198     MEDIA_INFO_LOG("OpenSlTestConcurrent");
199     engineObject = nullptr;
200     SLEngineItf engineEngine = nullptr;
201     SLresult result;
202 
203     result = slCreateEngine(&engineObject, 0, nullptr, 0, nullptr, nullptr);
204     result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
205     result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
206 
207     outputMixObject = nullptr;
208     result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, nullptr, nullptr);
209     (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
210 
211     SLDataLocator_OutputMix slOutputMix = {SL_DATALOCATOR_OUTPUTMIX, outputMixObject};
212     SLDataSink slSink = {&slOutputMix, nullptr};
213     SLDataLocator_BufferQueue slBufferQueue = {
214         SL_DATALOCATOR_BUFFERQUEUE,
215         0
216     };
217     SLDataFormat_PCM pcmFormat1 = {
218         SL_DATAFORMAT_PCM,
219         wavHeader1_.NumOfChan,
220         wavHeader1_.SamplesPerSec * 1000,
221         wavHeader1_.bitsPerSample,
222         0,
223         0,
224         0
225     };
226     SLDataFormat_PCM pcmFormat2 = {
227         SL_DATAFORMAT_PCM,
228         wavHeader2_.NumOfChan,
229         wavHeader2_.SamplesPerSec * 1000,
230         wavHeader2_.bitsPerSample,
231         0,
232         0,
233         0
234     };
235     SLDataSource slSource1 = {&slBufferQueue, &pcmFormat1};
236     SLDataSource slSource2 = {&slBufferQueue, &pcmFormat2};
237 
238     result = (*engineEngine)->CreateAudioPlayer(engineEngine, &pcmPlayerObject1, &slSource1, &slSink, 3, nullptr, nullptr);
239     (*pcmPlayerObject1)->Realize(pcmPlayerObject1, SL_BOOLEAN_FALSE);
240 
241     result = (*engineEngine)->CreateAudioPlayer(engineEngine, &pcmPlayerObject2, &slSource2, &slSink, 3, nullptr, nullptr);
242     (*pcmPlayerObject2)->Realize(pcmPlayerObject2, SL_BOOLEAN_FALSE);
243 
244     (*pcmPlayerObject1)->GetInterface(pcmPlayerObject1, SL_IID_PLAY, &playItf1);
245     (*pcmPlayerObject2)->GetInterface(pcmPlayerObject2, SL_IID_PLAY, &playItf2);
246     (*pcmPlayerObject1)->GetInterface(pcmPlayerObject1, SL_IID_VOLUME, &volumeItf1);
247 
248     SLmillibel level1 = 0;
249     (*volumeItf1)->GetMaxVolumeLevel(volumeItf1, &level1);
250     SLmillibel temp = 2;
251     level1 = (SLmillibel) (level1 / temp);
252     (*volumeItf1)->SetVolumeLevel(volumeItf1, level1);
253     (*pcmPlayerObject2)->GetInterface(pcmPlayerObject2, SL_IID_VOLUME, &volumeItf2);
254     SLmillibel level2 = 0;
255     (*volumeItf2)->GetMaxVolumeLevel(volumeItf2, &level2);
256     temp = 15;
257     level2 = (SLmillibel) (level2 / temp);
258     (*volumeItf2)->SetVolumeLevel(volumeItf2, level2);
259 
260     (*pcmPlayerObject1)->GetInterface(pcmPlayerObject1, SL_IID_OH_BUFFERQUEUE, &bufferQueueItf1);
261     (*pcmPlayerObject2)->GetInterface(pcmPlayerObject2, SL_IID_OH_BUFFERQUEUE, &bufferQueueItf2);
262     (*bufferQueueItf1)->RegisterCallback(bufferQueueItf1, BuqqerQueueCallback, wavFile1_);
263     (*bufferQueueItf2)->RegisterCallback(bufferQueueItf2, BuqqerQueueCallback, wavFile2_);
264     PlayerStart(playItf1, bufferQueueItf1, wavFile1_);
265     PlayerStart(playItf2, bufferQueueItf2, wavFile2_);
266 }
267 
BuqqerQueueCallback(SLOHBufferQueueItf bufferQueueItf,void * pContext,SLuint32 size)268 static void BuqqerQueueCallback (SLOHBufferQueueItf bufferQueueItf, void *pContext, SLuint32 size)
269 {
270     FILE *wavFile = (FILE *)pContext;
271     if (!feof(wavFile)) {
272         SLuint8 *buffer = nullptr;
273         SLuint32 pSize = 0;
274         (*bufferQueueItf)->GetBuffer(bufferQueueItf, &buffer, pSize);
275         fread(buffer, 1, size, wavFile);
276         (*bufferQueueItf)->Enqueue(bufferQueueItf, buffer, size);
277     }
278     return;
279 }
280 
PlayerStart(SLPlayItf playItf,SLOHBufferQueueItf bufferQueueItf,FILE * wavFile)281 static void PlayerStart (SLPlayItf playItf, SLOHBufferQueueItf bufferQueueItf, FILE *wavFile)
282 {
283     MEDIA_INFO_LOG("PlayerStart");
284     (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_PLAYING);
285     if (!feof(wavFile)) {
286         SLuint8* buffer = nullptr;
287         SLuint32 pSize = 0;
288         (*bufferQueueItf)->GetBuffer(bufferQueueItf, &buffer, pSize);
289         fread(buffer, 1, pSize, wavFile);
290         (*bufferQueueItf)->Enqueue(bufferQueueItf, buffer, pSize);
291     }
292     return;
293 }
294 
PlayerStop(SLPlayItf playItf,SLOHBufferQueueItf bufferQueueItf)295 static void PlayerStop (SLPlayItf playItf, SLOHBufferQueueItf bufferQueueItf)
296 {
297     MEDIA_INFO_LOG("PlayerStop");
298     (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_STOPPED);
299     return;
300 }
301 
302