• 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 <cstdio>
17 #include <cstdlib>
18 #include <cstring>
19 #include <securec.h>
20 #include <iostream>
21 #include <unistd.h>
22 #include <OpenSLES.h>
23 #include <OpenSLES_OpenHarmony.h>
24 #include <OpenSLES_Platform.h>
25 #include "audio_info.h"
26 #include "audio_log.h"
27 
28 using namespace std;
29 
30 static void BufferQueueCallback(SLOHBufferQueueItf bufferQueueItf, void *pContext, SLuint32 size);
31 
32 static void CaptureOption(void);
33 
34 static void OperationTime(uint64_t time);
35 
36 static void CaptureStart(SLRecordItf recordItf, SLOHBufferQueueItf bufferQueueItf, FILE *wavFile);
37 
38 static void CapturePause(SLRecordItf recordItf);
39 
40 static void CaptureStop(SLRecordItf recordItf);
41 
42 static void OpenSLESCaptureTest();
43 
44 const int PARAMETERS = 8;
45 FILE *wavFile_ = nullptr;
46 SLObjectItf engineObject = nullptr;
47 SLRecordItf  recordItf;
48 SLOHBufferQueueItf bufferQueueItf;
49 SLObjectItf pcmCapturerObject = nullptr;
50 struct timespec tv1 = {0};
51 struct timespec tv2 = {0};
52 
main(int argc,char * argv[])53 int main(int argc, char *argv[])
54 {
55     AUDIO_INFO_LOG("OpenSL ES capture test in");
56     if (argc > PARAMETERS) {
57         AUDIO_ERR_LOG("Incorrect number(%{public}d) of parameters", argc);
58         return -1;
59     }
60 
61     int opt = 0;
62     string filePath = "/data/test.pcm";
63     wavFile_ = fopen(filePath.c_str(), "wb");
64     if (wavFile_ == nullptr) {
65         AUDIO_INFO_LOG("OpenSL ES capture: Unable to open file");
66         return -1;
67     }
68 
69     OpenSLESCaptureTest();
70     while ((opt = getopt(argc, argv, "s:p:S")) != -1) {
71         switch (opt) {
72             case 's':
73                 CaptureOption();
74                 break;
75             case 'p':
76                 CapturePause(recordItf);
77                 break;
78             case 'S':
79             default:
80                 CaptureStop(recordItf);
81                 break;
82         }
83     }
84 }
85 
CaptureOption(void)86 static void CaptureOption(void)
87 {
88     AUDIO_INFO_LOG("Enter CaptureOption.");
89     uint64_t totalTime = strtoull(optarg, nullptr, 10);
90     CaptureStart(recordItf, bufferQueueItf, wavFile_);
91     OperationTime(totalTime);
92 }
93 
OpenSLESCaptureTest()94 static void OpenSLESCaptureTest()
95 {
96     AUDIO_INFO_LOG("Enter OpenSLESCaptureTest");
97     engineObject = nullptr;
98     SLEngineItf engineItf = nullptr;
99 
100     slCreateEngine(&engineObject, 0, nullptr, 0, nullptr, nullptr);
101     (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
102     (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineItf);
103 
104     SLDataLocator_IODevice io_device = {
105         SL_DATALOCATOR_IODEVICE,
106         SL_IODEVICE_AUDIOINPUT,
107         SL_DEFAULTDEVICEID_AUDIOINPUT,
108         NULL
109     };
110 
111     SLDataSource audioSource = {
112         &io_device,
113         NULL
114     };
115 
116     SLDataLocator_BufferQueue buffer_queue = {
117         SL_DATALOCATOR_BUFFERQUEUE,
118         3
119     };
120 
121     SLDataFormat_PCM format_pcm = {
122         SL_DATAFORMAT_PCM,
123         OHOS::AudioStandard::AudioChannel::MONO,
124         OHOS::AudioStandard::AudioSamplingRate::SAMPLE_RATE_44100,
125         SL_PCMSAMPLEFORMAT_FIXED_16,
126         0,
127         0,
128         0
129     };
130     SLDataSink audioSink = {
131         &buffer_queue,
132         &format_pcm
133     };
134 
135     (*engineItf)->CreateAudioRecorder(engineItf, &pcmCapturerObject,
136         &audioSource, &audioSink, 0, nullptr, nullptr);
137     (*pcmCapturerObject)->Realize(pcmCapturerObject, SL_BOOLEAN_FALSE);
138 
139     (*pcmCapturerObject)->GetInterface(pcmCapturerObject, SL_IID_RECORD, &recordItf);
140     (*pcmCapturerObject)->GetInterface(pcmCapturerObject, SL_IID_OH_BUFFERQUEUE, &bufferQueueItf);
141     (*bufferQueueItf)->RegisterCallback(bufferQueueItf, BufferQueueCallback, wavFile_);
142 
143     return;
144 }
145 
BufferQueueCallback(SLOHBufferQueueItf bufferQueueItf,void * pContext,SLuint32 size)146 static void BufferQueueCallback(SLOHBufferQueueItf bufferQueueItf, void *pContext, SLuint32 size)
147 {
148     AUDIO_INFO_LOG("Enter BufferQueueCallback");
149     FILE *wavFile = (FILE *)pContext;
150     if (wavFile != nullptr) {
151         SLuint8 *buffer = nullptr;
152         SLuint32 pSize = 0;
153         (*bufferQueueItf)->GetBuffer(bufferQueueItf, &buffer, pSize);
154         if (buffer != nullptr) {
155             AUDIO_INFO_LOG("BufferQueueCallback, length, pSize:%{public}lu, size: %{public}lu.",
156                            pSize, size);
157             fwrite(buffer, 1, pSize, wavFile);
158             (*bufferQueueItf)->Enqueue(bufferQueueItf, buffer, size);
159         } else {
160             AUDIO_INFO_LOG("BufferQueueCallback, buffer is null or pSize: %{public}lu, size: %{public}lu.",
161                            pSize, size);
162         }
163     }
164 
165     return;
166 }
167 
CaptureStart(SLRecordItf recordItf,SLOHBufferQueueItf bufferQueueItf,FILE * wavFile)168 static void CaptureStart(SLRecordItf recordItf, SLOHBufferQueueItf bufferQueueItf, FILE *wavFile)
169 {
170     AUDIO_INFO_LOG("Enter CaptureStart");
171     (*recordItf)->SetRecordState(recordItf, SL_RECORDSTATE_RECORDING);
172     if (wavFile != nullptr) {
173         SLuint8* buffer = nullptr;
174         SLuint32 pSize = 0;
175         (*bufferQueueItf)->GetBuffer(bufferQueueItf, &buffer, pSize);
176         if (buffer != nullptr) {
177             AUDIO_INFO_LOG("CaptureStart, enqueue buffer length: %{public}lu.", pSize);
178             fwrite(buffer, 1, pSize, wavFile);
179             (*bufferQueueItf)->Enqueue(bufferQueueItf, buffer, pSize);
180         } else {
181             AUDIO_INFO_LOG("CaptureStart, buffer is null or pSize: %{public}lu.", pSize);
182         }
183     }
184 
185     return;
186 }
187 
CapturePause(SLRecordItf recordItf)188 static void CapturePause(SLRecordItf recordItf)
189 {
190     AUDIO_INFO_LOG("Enter CapturePause");
191     uint64_t totalTime = strtoull(optarg, nullptr, 10);
192     (*recordItf)->SetRecordState(recordItf, SL_RECORDSTATE_PAUSED);
193     OperationTime(totalTime);
194 
195     return;
196 }
197 
CaptureStop(SLRecordItf recordItf)198 static void CaptureStop(SLRecordItf recordItf)
199 {
200     AUDIO_INFO_LOG("Enter CaptureStop");
201     fflush(wavFile_);
202     (*recordItf)->SetRecordState(recordItf, SL_RECORDSTATE_STOPPED);
203     (*pcmCapturerObject)->Destroy(pcmCapturerObject);
204     fclose(wavFile_);
205     wavFile_ = nullptr;
206     return;
207 }
208 
OperationTime(uint64_t time)209 static void OperationTime(uint64_t time)
210 {
211     uint64_t usecTimes = 1000000000;
212     time *= usecTimes;
213     clock_gettime(CLOCK_REALTIME, &tv1);
214     clock_gettime(CLOCK_REALTIME, &tv2);
215     while (((tv2.tv_sec * usecTimes + tv2.tv_nsec) - (tv1.tv_sec * usecTimes + tv1.tv_nsec)) <= time) {
216         sleep(1);
217         clock_gettime(CLOCK_REALTIME, &tv2);
218     }
219 
220     return;
221 }
222