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