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