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_renderer_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 const std::unordered_map<AudioAdapterSamplingRate, AudioSamplingRate> SAMPLING_RATE_MAP = {
27 { AudioAdapterSamplingRate::SAMPLE_RATE_8000, AudioSamplingRate::SAMPLE_RATE_8000 },
28 { AudioAdapterSamplingRate::SAMPLE_RATE_11025, AudioSamplingRate::SAMPLE_RATE_11025 },
29 { AudioAdapterSamplingRate::SAMPLE_RATE_12000, AudioSamplingRate::SAMPLE_RATE_12000 },
30 { AudioAdapterSamplingRate::SAMPLE_RATE_16000, AudioSamplingRate::SAMPLE_RATE_16000 },
31 { AudioAdapterSamplingRate::SAMPLE_RATE_22050, AudioSamplingRate::SAMPLE_RATE_22050 },
32 { AudioAdapterSamplingRate::SAMPLE_RATE_24000, AudioSamplingRate::SAMPLE_RATE_24000 },
33 { AudioAdapterSamplingRate::SAMPLE_RATE_32000, AudioSamplingRate::SAMPLE_RATE_32000 },
34 { AudioAdapterSamplingRate::SAMPLE_RATE_44100, AudioSamplingRate::SAMPLE_RATE_44100 },
35 { AudioAdapterSamplingRate::SAMPLE_RATE_48000, AudioSamplingRate::SAMPLE_RATE_48000 },
36 { AudioAdapterSamplingRate::SAMPLE_RATE_64000, AudioSamplingRate::SAMPLE_RATE_64000 },
37 { AudioAdapterSamplingRate::SAMPLE_RATE_96000, AudioSamplingRate::SAMPLE_RATE_96000 },
38 };
39
40 const std::unordered_map<AudioAdapterEncodingType, AudioEncodingType> ENCODING_TYPE_MAP = {
41 { AudioAdapterEncodingType::ENCODING_PCM, AudioEncodingType::ENCODING_PCM },
42 { AudioAdapterEncodingType::ENCODING_INVALID, AudioEncodingType::ENCODING_INVALID }
43 };
44
45 const std::unordered_map<AudioAdapterSampleFormat, AudioSampleFormat> SAMPLE_FORMAT_MAP = {
46 { AudioAdapterSampleFormat::SAMPLE_U8, AudioSampleFormat::SAMPLE_U8 },
47 { AudioAdapterSampleFormat::SAMPLE_S16LE, AudioSampleFormat::SAMPLE_S16LE },
48 { AudioAdapterSampleFormat::SAMPLE_S24LE, AudioSampleFormat::SAMPLE_S24LE },
49 { AudioAdapterSampleFormat::SAMPLE_S32LE, AudioSampleFormat::SAMPLE_S32LE },
50 { AudioAdapterSampleFormat::SAMPLE_F32LE, AudioSampleFormat::SAMPLE_F32LE },
51 };
52
53 const std::unordered_map<AudioAdapterChannel, AudioChannel> AUDIO_CHANNEL_MAP = {
54 { AudioAdapterChannel::MONO, AudioChannel::MONO },
55 { AudioAdapterChannel::STEREO, AudioChannel::STEREO },
56 { AudioAdapterChannel::CHANNEL_3, AudioChannel::CHANNEL_3 },
57 { AudioAdapterChannel::CHANNEL_4, AudioChannel::CHANNEL_4 },
58 { AudioAdapterChannel::CHANNEL_5, AudioChannel::CHANNEL_5 },
59 { AudioAdapterChannel::CHANNEL_6, AudioChannel::CHANNEL_6 },
60 { AudioAdapterChannel::CHANNEL_7, AudioChannel::CHANNEL_7 },
61 { AudioAdapterChannel::CHANNEL_8, AudioChannel::CHANNEL_8 },
62 };
63
64 const std::unordered_map<AudioAdapterContentType, ContentType> CONTENT_TYPE_MAP = {
65 { AudioAdapterContentType::CONTENT_TYPE_UNKNOWN, ContentType::CONTENT_TYPE_UNKNOWN },
66 { AudioAdapterContentType::CONTENT_TYPE_SPEECH, ContentType::CONTENT_TYPE_SPEECH },
67 { AudioAdapterContentType::CONTENT_TYPE_MUSIC, ContentType::CONTENT_TYPE_MUSIC },
68 { AudioAdapterContentType::CONTENT_TYPE_MOVIE, ContentType::CONTENT_TYPE_MOVIE },
69 { AudioAdapterContentType::CONTENT_TYPE_SONIFICATION, ContentType::CONTENT_TYPE_SONIFICATION },
70 { AudioAdapterContentType::CONTENT_TYPE_RINGTONE, ContentType::CONTENT_TYPE_RINGTONE },
71 };
72
73 const std::unordered_map<AudioAdapterStreamUsage, StreamUsage> STREAM_USAGE_MAP = {
74 { AudioAdapterStreamUsage::STREAM_USAGE_UNKNOWN, StreamUsage::STREAM_USAGE_UNKNOWN },
75 { AudioAdapterStreamUsage::STREAM_USAGE_MEDIA, StreamUsage::STREAM_USAGE_MEDIA },
76 { AudioAdapterStreamUsage::STREAM_USAGE_VOICE_COMMUNICATION, StreamUsage::STREAM_USAGE_VIDEO_COMMUNICATION },
77 { AudioAdapterStreamUsage::STREAM_USAGE_VOICE_ASSISTANT, StreamUsage::STREAM_USAGE_VOICE_ASSISTANT },
78 { AudioAdapterStreamUsage::STREAM_USAGE_NOTIFICATION_RINGTONE, StreamUsage::STREAM_USAGE_NOTIFICATION_RINGTONE },
79 };
80
81 const std::unordered_map<AudioStreamDeviceChangeReason, AudioAdapterDeviceChangeReason> CHANGE_REASON_MAP = {
82 { AudioStreamDeviceChangeReason::UNKNOWN, AudioAdapterDeviceChangeReason::UNKNOWN },
83 { AudioStreamDeviceChangeReason::NEW_DEVICE_AVAILABLE, AudioAdapterDeviceChangeReason::NEW_DEVICE_AVAILABLE },
84 { AudioStreamDeviceChangeReason::OLD_DEVICE_UNAVALIABLE, AudioAdapterDeviceChangeReason::OLD_DEVICE_UNAVALIABLE },
85 { AudioStreamDeviceChangeReason::OVERRODE, AudioAdapterDeviceChangeReason::OVERRODE },
86 };
AudioRendererCallbackImpl(std::shared_ptr<AudioRendererCallbackAdapter> cb)87 AudioRendererCallbackImpl::AudioRendererCallbackImpl(std::shared_ptr<AudioRendererCallbackAdapter> cb) : cb_(cb) {};
88
OnInterrupt(const InterruptEvent& interruptEvent)89 void AudioRendererCallbackImpl::OnInterrupt(const InterruptEvent& interruptEvent)
90 {
91 if (!cb_) {
92 return;
93 }
94 switch (interruptEvent.hintType) {
95 case InterruptHint::INTERRUPT_HINT_PAUSE:
96 cb_->OnSuspend();
97 break;
98 case InterruptHint::INTERRUPT_HINT_STOP:
99 cb_->OnSuspend();
100 break;
101 case InterruptHint::INTERRUPT_HINT_RESUME:
102 cb_->OnResume();
103 break;
104 default:
105 WVLOG_E("audio renderer interrupt hint not foud, code: %{public}d", interruptEvent.hintType);
106 break;
107 }
108 }
109
OnStateChange(const RendererState state, const StateChangeCmdType cmdType)110 void AudioRendererCallbackImpl::OnStateChange(const RendererState state, const StateChangeCmdType cmdType) {}
GetChangeReason(AudioStreamDeviceChangeReason reason)111 AudioAdapterDeviceChangeReason AudioOutputChangeCallbackImpl::GetChangeReason(AudioStreamDeviceChangeReason reason)
112 {
113 auto item = CHANGE_REASON_MAP.find(reason);
114 if (item == CHANGE_REASON_MAP.end()) {
115 WVLOG_E("device change reason not found");
116 return AudioAdapterDeviceChangeReason::UNKNOWN;
117 }
118 return item->second;
119 }
120
AudioOutputChangeCallbackImpl(std::shared_ptr<AudioOutputChangeCallbackAdapter> cb)121 AudioOutputChangeCallbackImpl::AudioOutputChangeCallbackImpl(std::shared_ptr<AudioOutputChangeCallbackAdapter> cb)
122 : cb_(cb) {};
OnOutputDeviceChange( const DeviceInfo& deviceInfo, const AudioStreamDeviceChangeReason reason)123 void AudioOutputChangeCallbackImpl::OnOutputDeviceChange(
124 const DeviceInfo& deviceInfo, const AudioStreamDeviceChangeReason reason)
125 {
126 if (!cb_) {
127 return;
128 }
129 AudioAdapterDeviceChangeReason reasonAdapter = GetChangeReason(reason);
130 WVLOG_I("OnOutputDeviceChange reason: %{public}d", (int32_t)reasonAdapter);
131 cb_->OnOutputDeviceChange((int32_t)reasonAdapter);
132 }
133
Create( const std::shared_ptr<AudioRendererOptionsAdapter> rendererOptions, std::string cachePath)134 int32_t AudioRendererAdapterImpl::Create(
135 const std::shared_ptr<AudioRendererOptionsAdapter> rendererOptions, std::string cachePath)
136 {
137 std::string audioCachePath = cachePath;
138 std::shared_ptr<AbilityRuntime::ApplicationContext> context =
139 AbilityRuntime::ApplicationContext::GetApplicationContext();
140 if (!context) {
141 WVLOG_E("application context get failed");
142 return AUDIO_ERROR;
143 }
144 if (audioCachePath.empty()) {
145 audioCachePath = context->GetCacheDir();
146 if (audioCachePath.empty()) {
147 WVLOG_E("application cache path get failed");
148 return AUDIO_ERROR;
149 }
150 }
151 if (!rendererOptions) {
152 WVLOG_E("rendererOptions is nullptr");
153 return AUDIO_ERROR;
154 }
155
156 AudioRendererOptions audioOptions;
157 TransformToAudioRendererOptions(audioOptions, rendererOptions);
158 audio_renderer_ = AudioRenderer::Create(audioCachePath, audioOptions);
159 if (audio_renderer_ == nullptr) {
160 WVLOG_E("audio rendderer create failed");
161 return AUDIO_NULL_ERROR;
162 }
163 audio_renderer_->SetOffloadAllowed(false);
164 return AUDIO_OK;
165 }
166
Start()167 bool AudioRendererAdapterImpl::Start()
168 {
169 if (audio_renderer_ == nullptr) {
170 WVLOG_E("audio rendderer is nullptr");
171 return false;
172 }
173 return audio_renderer_->Start();
174 }
175
Pause()176 bool AudioRendererAdapterImpl::Pause()
177 {
178 if (audio_renderer_ == nullptr) {
179 WVLOG_E("audio rendderer is nullptr");
180 return false;
181 }
182 return audio_renderer_->Pause();
183 }
184
Stop()185 bool AudioRendererAdapterImpl::Stop()
186 {
187 if (audio_renderer_ == nullptr) {
188 WVLOG_E("audio rendderer is nullptr");
189 return false;
190 }
191 return audio_renderer_->Stop();
192 }
193
Release()194 bool AudioRendererAdapterImpl::Release()
195 {
196 if (audio_renderer_ == nullptr) {
197 WVLOG_E("audio rendderer is nullptr");
198 return false;
199 }
200 return audio_renderer_->Release();
201 }
202
Write(uint8_t* buffer, size_t bufferSize)203 int32_t AudioRendererAdapterImpl::Write(uint8_t* buffer, size_t bufferSize)
204 {
205 if (audio_renderer_ == nullptr) {
206 WVLOG_E("audio rendderer is nullptr");
207 return AUDIO_NULL_ERROR;
208 }
209 return audio_renderer_->Write(buffer, bufferSize);
210 }
211
GetLatency(uint64_t& latency)212 int32_t AudioRendererAdapterImpl::GetLatency(uint64_t& latency)
213 {
214 if (audio_renderer_ == nullptr) {
215 WVLOG_E("audio rendderer is nullptr");
216 return AUDIO_NULL_ERROR;
217 }
218 return audio_renderer_->GetLatency(latency);
219 }
220
SetVolume(float volume)221 int32_t AudioRendererAdapterImpl::SetVolume(float volume)
222 {
223 if (audio_renderer_ == nullptr) {
224 WVLOG_E("audio rendderer is nullptr");
225 return AUDIO_NULL_ERROR;
226 }
227 return audio_renderer_->SetVolume(volume);
228 }
229
GetVolume()230 float AudioRendererAdapterImpl::GetVolume()
231 {
232 if (audio_renderer_ == nullptr) {
233 WVLOG_E("audio rendderer is nullptr");
234 return AUDIO_NULL_ERROR;
235 }
236 return audio_renderer_->GetVolume();
237 }
238
SetAudioRendererCallback( const std::shared_ptr<AudioRendererCallbackAdapter>& callback)239 int32_t AudioRendererAdapterImpl::SetAudioRendererCallback(
240 const std::shared_ptr<AudioRendererCallbackAdapter>& callback)
241 {
242 if (callback == nullptr) {
243 WVLOG_E("set audio manager interrupt callback is nullptr");
244 return AUDIO_NULL_ERROR;
245 }
246 callback_ = std::make_shared<AudioRendererCallbackImpl>(callback);
247
248 if (audio_renderer_ == nullptr) {
249 WVLOG_E("audio rendderer is nullptr");
250 return AUDIO_NULL_ERROR;
251 }
252 int32_t ret = audio_renderer_->SetRendererCallback(callback_);
253 if (ret != AudioStandard::SUCCESS) {
254 WVLOG_E("audio renderer set callback failed, code: %{public}d", ret);
255 return AUDIO_ERROR;
256 }
257 return AUDIO_OK;
258 }
259
SetAudioOutputChangeCallback( const std::shared_ptr<AudioOutputChangeCallbackAdapter>& callback)260 int32_t AudioRendererAdapterImpl::SetAudioOutputChangeCallback(
261 const std::shared_ptr<AudioOutputChangeCallbackAdapter>& callback)
262 {
263 WVLOG_I("AudioRendererAdapterImpl::SetAudioOutputChangeCallback");
264 if (callback == nullptr) {
265 WVLOG_E("set audio manager interrupt callback is nullptr");
266 return AUDIO_NULL_ERROR;
267 }
268 ouputChangeCallback_ = std::make_shared<AudioOutputChangeCallbackImpl>(callback);
269 if (audio_renderer_ == nullptr) {
270 WVLOG_E("audio rendderer is nullptr");
271 return AUDIO_NULL_ERROR;
272 }
273 int32_t ret = audio_renderer_->RegisterOutputDeviceChangeWithInfoCallback(ouputChangeCallback_);
274 if (ret != AudioStandard::SUCCESS) {
275 WVLOG_E("audio renderer set output device change callback failed, code: %{public}d", ret);
276 return AUDIO_ERROR;
277 }
278 return AUDIO_OK;
279 }
280
SetInterruptMode(bool audioExclusive)281 void AudioRendererAdapterImpl::SetInterruptMode(bool audioExclusive)
282 {
283 if (audio_renderer_ == nullptr) {
284 WVLOG_E("audio rendderer is nullptr");
285 return;
286 }
287 InterruptMode interruptMode = audioExclusive ? InterruptMode::INDEPENDENT_MODE : InterruptMode::SHARE_MODE;
288 WVLOG_D("AudioRendererAdapterImpl::SetInterruptMode audioExclusive: %{public}d", audioExclusive);
289 audio_renderer_->SetInterruptMode(interruptMode);
290 }
291
SetAudioSilentMode(bool isSilentMode)292 void AudioRendererAdapterImpl::SetAudioSilentMode(bool isSilentMode)
293 {
294 if (audio_renderer_ == nullptr) {
295 WVLOG_E("audio rendderer is nullptr");
296 return;
297 }
298 audio_renderer_->SetSilentModeAndMixWithOthers(isSilentMode);
299 WVLOG_D("AudioRendererAdapterImpl::SetAudioSilentMode isSilentMode: %{public}d", isSilentMode);
300 }
301
IsRendererStateRunning()302 bool AudioRendererAdapterImpl::IsRendererStateRunning()
303 {
304 if (audio_renderer_ == nullptr) {
305 WVLOG_E("audio rendderer is nullptr");
306 return false;
307 }
308 return audio_renderer_->GetStatus() == OHOS::AudioStandard::RendererState::RENDERER_RUNNING;
309 }
310
GetAudioSamplingRate(AudioAdapterSamplingRate samplingRate)311 AudioSamplingRate AudioRendererAdapterImpl::GetAudioSamplingRate(AudioAdapterSamplingRate samplingRate)
312 {
313 auto item = SAMPLING_RATE_MAP.find(samplingRate);
314 if (item == SAMPLING_RATE_MAP.end()) {
315 WVLOG_E("audio sampling rate not found");
316 return AudioSamplingRate::SAMPLE_RATE_44100;
317 }
318 return item->second;
319 }
320
GetAudioEncodingType(AudioAdapterEncodingType encodingType)321 AudioEncodingType AudioRendererAdapterImpl::GetAudioEncodingType(AudioAdapterEncodingType encodingType)
322 {
323 auto item = ENCODING_TYPE_MAP.find(encodingType);
324 if (item == ENCODING_TYPE_MAP.end()) {
325 WVLOG_E("audio encoding type not found");
326 return AudioEncodingType::ENCODING_INVALID;
327 }
328 return item->second;
329 }
330
GetAudioSampleFormat(AudioAdapterSampleFormat sampleFormat)331 AudioSampleFormat AudioRendererAdapterImpl::GetAudioSampleFormat(AudioAdapterSampleFormat sampleFormat)
332 {
333 auto item = SAMPLE_FORMAT_MAP.find(sampleFormat);
334 if (item == SAMPLE_FORMAT_MAP.end()) {
335 WVLOG_E("audio sample format not found");
336 return AudioSampleFormat::INVALID_WIDTH;
337 }
338 return item->second;
339 }
340
GetAudioChannel(AudioAdapterChannel channel)341 AudioChannel AudioRendererAdapterImpl::GetAudioChannel(AudioAdapterChannel channel)
342 {
343 auto item = AUDIO_CHANNEL_MAP.find(channel);
344 if (item == AUDIO_CHANNEL_MAP.end()) {
345 WVLOG_E("audio channel not found");
346 return AudioChannel::STEREO;
347 }
348 return item->second;
349 }
350
GetAudioContentType(AudioAdapterContentType contentType)351 ContentType AudioRendererAdapterImpl::GetAudioContentType(AudioAdapterContentType contentType)
352 {
353 auto item = CONTENT_TYPE_MAP.find(contentType);
354 if (item == CONTENT_TYPE_MAP.end()) {
355 WVLOG_E("audio content type not found");
356 return ContentType::CONTENT_TYPE_MUSIC;
357 }
358 return item->second;
359 }
360
GetAudioStreamUsage(AudioAdapterStreamUsage streamUsage)361 StreamUsage AudioRendererAdapterImpl::GetAudioStreamUsage(AudioAdapterStreamUsage streamUsage)
362 {
363 auto item = STREAM_USAGE_MAP.find(streamUsage);
364 if (item == STREAM_USAGE_MAP.end()) {
365 WVLOG_E("audio stream usage not found");
366 return StreamUsage::STREAM_USAGE_MEDIA;
367 }
368 return item->second;
369 }
370
TransformToAudioRendererOptions( AudioRendererOptions& out, const std::shared_ptr<AudioRendererOptionsAdapter>& in)371 void AudioRendererAdapterImpl::TransformToAudioRendererOptions(
372 AudioRendererOptions& out, const std::shared_ptr<AudioRendererOptionsAdapter>& in)
373 {
374 out.streamInfo.samplingRate = GetAudioSamplingRate(in->GetSamplingRate());
375 out.streamInfo.encoding = GetAudioEncodingType(in->GetEncodingType());
376 out.streamInfo.format = GetAudioSampleFormat(in->GetSampleFormat());
377 out.streamInfo.channels = GetAudioChannel(in->GetChannel());
378 out.rendererInfo.contentType = GetAudioContentType(in->GetContentType());
379 out.rendererInfo.streamUsage = GetAudioStreamUsage(in->GetStreamUsage());
380 out.rendererInfo.rendererFlags = in->GetRenderFlags();
381 }
382
383 } // namespace OHOS::NWeb
384