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 "audio_capturer_adapter_impl.h"
17
18 #include <unordered_map>
19
20 #include "application_context.h"
21 #include "audio_errors.h"
22 #include "nweb_log.h"
23
24 namespace OHOS::NWeb {
25
26 std::unordered_set<AudioCapturerAdapterImpl*> AudioCapturerAdapterImpl::audioCapturerAdapterSet_ = {};
27
28 constexpr int64_t NANOSECONDS_PER_SECOND = 1000000000;
29
30 const std::unordered_map<AudioAdapterSamplingRate, AudioSamplingRate> SAMPLING_RATE_MAP = {
31 {AudioAdapterSamplingRate::SAMPLE_RATE_8000, AudioSamplingRate::SAMPLE_RATE_8000},
32 {AudioAdapterSamplingRate::SAMPLE_RATE_11025, AudioSamplingRate::SAMPLE_RATE_11025},
33 {AudioAdapterSamplingRate::SAMPLE_RATE_12000, AudioSamplingRate::SAMPLE_RATE_12000},
34 {AudioAdapterSamplingRate::SAMPLE_RATE_16000, AudioSamplingRate::SAMPLE_RATE_16000},
35 {AudioAdapterSamplingRate::SAMPLE_RATE_22050, AudioSamplingRate::SAMPLE_RATE_22050},
36 {AudioAdapterSamplingRate::SAMPLE_RATE_24000, AudioSamplingRate::SAMPLE_RATE_24000},
37 {AudioAdapterSamplingRate::SAMPLE_RATE_32000, AudioSamplingRate::SAMPLE_RATE_32000},
38 {AudioAdapterSamplingRate::SAMPLE_RATE_44100, AudioSamplingRate::SAMPLE_RATE_44100},
39 {AudioAdapterSamplingRate::SAMPLE_RATE_48000, AudioSamplingRate::SAMPLE_RATE_48000},
40 {AudioAdapterSamplingRate::SAMPLE_RATE_64000, AudioSamplingRate::SAMPLE_RATE_64000},
41 {AudioAdapterSamplingRate::SAMPLE_RATE_96000, AudioSamplingRate::SAMPLE_RATE_96000},
42 };
43
44 const std::unordered_map<AudioAdapterEncodingType, AudioEncodingType> ENCODING_TYPE_MAP = {
45 {AudioAdapterEncodingType::ENCODING_PCM, AudioEncodingType::ENCODING_PCM},
46 {AudioAdapterEncodingType::ENCODING_INVALID, AudioEncodingType::ENCODING_INVALID}
47 };
48
49 const std::unordered_map<AudioAdapterSampleFormat, AudioSampleFormat> SAMPLE_FORMAT_MAP = {
50 {AudioAdapterSampleFormat::SAMPLE_U8, AudioSampleFormat::SAMPLE_U8},
51 {AudioAdapterSampleFormat::SAMPLE_S16LE, AudioSampleFormat::SAMPLE_S16LE},
52 {AudioAdapterSampleFormat::SAMPLE_S24LE, AudioSampleFormat::SAMPLE_S24LE},
53 {AudioAdapterSampleFormat::SAMPLE_S32LE, AudioSampleFormat::SAMPLE_S32LE},
54 {AudioAdapterSampleFormat::SAMPLE_F32LE, AudioSampleFormat::SAMPLE_F32LE},
55 };
56
57 const std::unordered_map<AudioAdapterChannel, AudioChannel> AUDIO_CHANNEL_MAP = {
58 {AudioAdapterChannel::MONO, AudioChannel::MONO},
59 {AudioAdapterChannel::STEREO, AudioChannel::STEREO},
60 {AudioAdapterChannel::CHANNEL_3, AudioChannel::CHANNEL_3},
61 {AudioAdapterChannel::CHANNEL_4, AudioChannel::CHANNEL_4},
62 {AudioAdapterChannel::CHANNEL_5, AudioChannel::CHANNEL_5},
63 {AudioAdapterChannel::CHANNEL_6, AudioChannel::CHANNEL_6},
64 {AudioAdapterChannel::CHANNEL_7, AudioChannel::CHANNEL_7},
65 {AudioAdapterChannel::CHANNEL_8, AudioChannel::CHANNEL_8},
66 };
67
68 const std::unordered_map<AudioAdapterSourceType, SourceType> SOURCE_TYPE_MAP = {
69 {AudioAdapterSourceType::SOURCE_TYPE_INVALID, SourceType::SOURCE_TYPE_INVALID},
70 {AudioAdapterSourceType::SOURCE_TYPE_MIC, SourceType::SOURCE_TYPE_MIC},
71 {AudioAdapterSourceType::SOURCE_TYPE_VOICE_RECOGNITION, SourceType::SOURCE_TYPE_VOICE_RECOGNITION},
72 {AudioAdapterSourceType::SOURCE_TYPE_VOICE_COMMUNICATION, SourceType::SOURCE_TYPE_VOICE_COMMUNICATION},
73 {AudioAdapterSourceType::SOURCE_TYPE_ULTRASONIC, SourceType::SOURCE_TYPE_ULTRASONIC},
74 };
75
AudioCapturerReadCallbackImpl(std::shared_ptr<AudioCapturerReadCallbackAdapter> cb)76 AudioCapturerReadCallbackImpl::AudioCapturerReadCallbackImpl(
77 std::shared_ptr<AudioCapturerReadCallbackAdapter> cb) : cb_(cb) {};
78
OnReadData(size_t length)79 void AudioCapturerReadCallbackImpl::OnReadData(size_t length)
80 {
81 if (!cb_) {
82 WVLOG_E("Get AudioCapturerReadCallbackAdapter failed.");
83 return;
84 }
85 cb_->OnReadData(length);
86 }
87
Create(const AudioAdapterCapturerOptions & capturerOptions,std::string cachePath)88 int32_t AudioCapturerAdapterImpl::Create(const AudioAdapterCapturerOptions &capturerOptions,
89 std::string cachePath)
90 {
91 std::string audioCachePath = cachePath;
92 if (audioCachePath.empty()) {
93 std::shared_ptr<AbilityRuntime::ApplicationContext> context =
94 AbilityRuntime::ApplicationContext::GetApplicationContext();
95 if (!context) {
96 WVLOG_E("application context get failed");
97 return AUDIO_ERROR;
98 }
99 audioCachePath = context->GetCacheDir();
100 if (audioCachePath.empty()) {
101 WVLOG_E("application cache path get failed");
102 return AUDIO_ERROR;
103 }
104 }
105
106 AudioCapturerOptions options;
107 options.streamInfo.samplingRate = GetAudioSamplingRate(capturerOptions.samplingRate);
108 options.streamInfo.encoding = GetAudioEncodingType(capturerOptions.encoding);
109 options.streamInfo.format = GetAudioSampleFormat(capturerOptions.format);
110 options.streamInfo.channels = GetAudioChannel(capturerOptions.channels);
111 options.capturerInfo.sourceType = GetAudioSourceType(capturerOptions.sourceType);
112 options.capturerInfo.capturerFlags = capturerOptions.capturerFlags;
113
114 audio_capturer_ = AudioCapturer::Create(options, audioCachePath);
115 if (audio_capturer_ == nullptr) {
116 WVLOG_E("audio capturer create failed");
117 return AUDIO_NULL_ERROR;
118 }
119 audio_capturer_->SetCaptureMode(AudioCaptureMode::CAPTURE_MODE_CALLBACK);
120 return AUDIO_OK;
121 }
122
Start()123 bool AudioCapturerAdapterImpl::Start()
124 {
125 if (audio_capturer_ == nullptr) {
126 WVLOG_E("audio capturer is nullptr");
127 return false;
128 }
129 std::unordered_set<AudioCapturerAdapterImpl*> capturers;
130 for (auto capturer : audioCapturerAdapterSet_) {
131 if (capturer != nullptr) {
132 capturers.insert(capturer);
133 }
134 }
135 for (auto capturerToStop : capturers) {
136 if (capturerToStop != nullptr) {
137 WVLOG_I("audio capturer is interrupting other capturer");
138 capturerToStop->Stop();
139 }
140 }
141 audioCapturerAdapterSet_.insert(this);
142 return audio_capturer_->Start();
143 }
144
Stop()145 bool AudioCapturerAdapterImpl::Stop()
146 {
147 if (audio_capturer_ == nullptr) {
148 WVLOG_E("audio capturer is nullptr");
149 return false;
150 }
151 audioCapturerAdapterSet_.erase(this);
152 return audio_capturer_->Stop();
153 }
154
Release()155 bool AudioCapturerAdapterImpl::Release()
156 {
157 if (audio_capturer_ == nullptr) {
158 WVLOG_E("audio capturer is nullptr");
159 return false;
160 }
161 return audio_capturer_->Release();
162 }
163
SetCapturerReadCallback(const std::shared_ptr<AudioCapturerReadCallbackAdapter> & callback)164 int32_t AudioCapturerAdapterImpl::SetCapturerReadCallback(
165 const std::shared_ptr<AudioCapturerReadCallbackAdapter> &callback)
166 {
167 if (audio_capturer_ == nullptr) {
168 WVLOG_E("audio capturer is nullptr");
169 return AUDIO_NULL_ERROR;
170 }
171 auto capturerReadCallback = std::make_shared<AudioCapturerReadCallbackImpl>(callback);
172 if (capturerReadCallback == nullptr) {
173 WVLOG_E("audio capturerReadCallback is nullptr");
174 return AUDIO_NULL_ERROR;
175 }
176 return audio_capturer_->SetCapturerReadCallback(capturerReadCallback);
177 }
178
GetBufferDesc(BufferDescAdapter & bufferDesc)179 int32_t AudioCapturerAdapterImpl::GetBufferDesc(BufferDescAdapter &bufferDesc)
180 {
181 if (audio_capturer_ == nullptr) {
182 WVLOG_E("audio capturer is nullptr");
183 return AUDIO_NULL_ERROR;
184 }
185 BufferDesc bufDesc;
186 audio_capturer_->GetBufferDesc(bufDesc);
187 bufferDesc.buffer = bufDesc.buffer;
188 bufferDesc.bufLength = bufDesc.bufLength;
189 bufferDesc.dataLength = bufDesc.dataLength;
190 return 0;
191 }
192
Enqueue(const BufferDescAdapter & bufferDesc) const193 int32_t AudioCapturerAdapterImpl::Enqueue(const BufferDescAdapter &bufferDesc) const
194 {
195 if (audio_capturer_ == nullptr) {
196 WVLOG_E("audio capturer is nullptr");
197 return AUDIO_NULL_ERROR;
198 }
199 BufferDesc bufDesc;
200 bufDesc.buffer = bufferDesc.buffer;
201 bufDesc.bufLength = bufferDesc.bufLength;
202 bufDesc.dataLength = bufferDesc.dataLength;
203 return audio_capturer_->Enqueue(bufDesc);
204 }
205
GetFrameCount(uint32_t & frameCount) const206 int32_t AudioCapturerAdapterImpl::GetFrameCount(uint32_t &frameCount) const
207 {
208 if (audio_capturer_ == nullptr) {
209 WVLOG_E("audio capturer is nullptr");
210 return AUDIO_NULL_ERROR;
211 }
212 return audio_capturer_->GetFrameCount(frameCount);
213 }
214
GetAudioTime()215 int64_t AudioCapturerAdapterImpl::GetAudioTime()
216 {
217 if (audio_capturer_ == nullptr) {
218 WVLOG_E("audio capturer is nullptr");
219 return AUDIO_NULL_ERROR;
220 }
221 Timestamp timeStamp;
222 audio_capturer_->GetAudioTime(timeStamp, Timestamp::Timestampbase::MONOTONIC);
223 return timeStamp.time.tv_sec * NANOSECONDS_PER_SECOND + timeStamp.time.tv_nsec;
224 }
225
GetAudioSamplingRate(AudioAdapterSamplingRate samplingRate)226 AudioSamplingRate AudioCapturerAdapterImpl::GetAudioSamplingRate(AudioAdapterSamplingRate samplingRate)
227 {
228 auto item = SAMPLING_RATE_MAP.find(samplingRate);
229 if (item == SAMPLING_RATE_MAP.end()) {
230 WVLOG_E("audio sampling rate not found");
231 return AudioSamplingRate::SAMPLE_RATE_44100;
232 }
233 return item->second;
234 }
235
GetAudioEncodingType(AudioAdapterEncodingType encodingType)236 AudioEncodingType AudioCapturerAdapterImpl::GetAudioEncodingType(AudioAdapterEncodingType encodingType)
237 {
238 auto item = ENCODING_TYPE_MAP.find(encodingType);
239 if (item == ENCODING_TYPE_MAP.end()) {
240 WVLOG_E("audio encoding type not found");
241 return AudioEncodingType::ENCODING_INVALID;
242 }
243 return item->second;
244 }
245
GetAudioSampleFormat(AudioAdapterSampleFormat sampleFormat)246 AudioSampleFormat AudioCapturerAdapterImpl::GetAudioSampleFormat(AudioAdapterSampleFormat sampleFormat)
247 {
248 auto item = SAMPLE_FORMAT_MAP.find(sampleFormat);
249 if (item == SAMPLE_FORMAT_MAP.end()) {
250 WVLOG_E("audio sample format not found");
251 return AudioSampleFormat::INVALID_WIDTH;
252 }
253 return item->second;
254 }
255
GetAudioChannel(AudioAdapterChannel channel)256 AudioChannel AudioCapturerAdapterImpl::GetAudioChannel(AudioAdapterChannel channel)
257 {
258 auto item = AUDIO_CHANNEL_MAP.find(channel);
259 if (item == AUDIO_CHANNEL_MAP.end()) {
260 WVLOG_E("audio channel not found");
261 return AudioChannel::STEREO;
262 }
263 return item->second;
264 }
265
GetAudioSourceType(AudioAdapterSourceType sourceType)266 SourceType AudioCapturerAdapterImpl::GetAudioSourceType(AudioAdapterSourceType sourceType)
267 {
268 auto item = SOURCE_TYPE_MAP.find(sourceType);
269 if (item == SOURCE_TYPE_MAP.end()) {
270 WVLOG_E("audio source type not found");
271 return SourceType::SOURCE_TYPE_VOICE_RECOGNITION;
272 }
273 return item->second;
274 }
275 } // namespace OHOS::NWeb