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