• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     int32_t type = (rendererOptions.streamUsage == AudioAdapterStreamUsage::STREAM_USAGE_VOICE_COMMUNICATION) ?
169         OHOS::AVSession::AVSession::SESSION_TYPE_VOICE_CALL : OHOS::AVSession::AVSession::SESSION_TYPE_AUDIO;
170     avsession_ = AVSessionManager::GetInstance().CreateSession(elementName.GetBundleName(), type, elementName);
171     if (avsession_ == nullptr) {
172         WVLOG_E("audio renderer create avsession failed");
173         return AUDIO_NULL_ERROR;
174     }
175     return AUDIO_OK;
176 }
177 
Start()178 bool AudioRendererAdapterImpl::Start()
179 {
180     if (audio_renderer_ == nullptr) {
181         WVLOG_E("audio rendderer is nullptr");
182         return false;
183     }
184     return audio_renderer_->Start();
185 }
186 
Pause()187 bool AudioRendererAdapterImpl::Pause()
188 {
189     if (audio_renderer_ == nullptr) {
190         WVLOG_E("audio rendderer is nullptr");
191         return false;
192     }
193     return audio_renderer_->Pause();
194 }
195 
Stop()196 bool AudioRendererAdapterImpl::Stop()
197 {
198     if (audio_renderer_ == nullptr) {
199         WVLOG_E("audio rendderer is nullptr");
200         return false;
201     }
202     return audio_renderer_->Stop();
203 }
204 
Release()205 bool AudioRendererAdapterImpl::Release()
206 {
207     if (audio_renderer_ == nullptr) {
208         WVLOG_E("audio rendderer is nullptr");
209         return false;
210     }
211     return audio_renderer_->Release();
212 }
213 
Write(uint8_t * buffer,size_t bufferSize)214 int32_t AudioRendererAdapterImpl::Write(uint8_t *buffer, size_t bufferSize)
215 {
216     if (audio_renderer_ == nullptr) {
217         WVLOG_E("audio rendderer is nullptr");
218         return AUDIO_NULL_ERROR;
219     }
220     return audio_renderer_->Write(buffer, bufferSize);
221 }
222 
GetLatency(uint64_t & latency) const223 int32_t AudioRendererAdapterImpl::GetLatency(uint64_t &latency) const
224 {
225     if (audio_renderer_ == nullptr) {
226         WVLOG_E("audio rendderer is nullptr");
227         return AUDIO_NULL_ERROR;
228     }
229     return audio_renderer_->GetLatency(latency);
230 }
231 
SetVolume(float volume) const232 int32_t AudioRendererAdapterImpl::SetVolume(float volume) const
233 {
234     if (audio_renderer_ == nullptr) {
235         WVLOG_E("audio rendderer is nullptr");
236         return AUDIO_NULL_ERROR;
237     }
238     return audio_renderer_->SetVolume(volume);
239 }
240 
GetVolume() const241 float AudioRendererAdapterImpl::GetVolume() const
242 {
243     if (audio_renderer_ == nullptr) {
244         WVLOG_E("audio rendderer is nullptr");
245         return AUDIO_NULL_ERROR;
246     }
247     return audio_renderer_->GetVolume();
248 }
249 
SetAudioRendererCallback(const std::shared_ptr<AudioRendererCallbackAdapter> & callback)250 int32_t AudioRendererAdapterImpl::SetAudioRendererCallback(
251     const std::shared_ptr<AudioRendererCallbackAdapter> &callback)
252 {
253     if (callback == nullptr) {
254         WVLOG_E("set audio manager interrupt callback is nullptr");
255         return AUDIO_NULL_ERROR;
256     }
257     callback_ = std::make_shared<AudioRendererCallbackImpl>(callback);
258 
259     if (audio_renderer_ == nullptr) {
260         WVLOG_E("audio rendderer is nullptr");
261         return AUDIO_NULL_ERROR;
262     }
263     int32_t ret = audio_renderer_->SetRendererCallback(callback_);
264     if (ret != AudioStandard::SUCCESS) {
265         WVLOG_E("audio renderer set callback failed, code: %{public}d", ret);
266         return AUDIO_ERROR;
267     }
268     return AUDIO_OK;
269 }
270 
SetInterruptMode(bool audioExclusive)271 void AudioRendererAdapterImpl::SetInterruptMode(bool audioExclusive)
272 {
273     if (audio_renderer_ == nullptr) {
274         WVLOG_E("audio rendderer is nullptr");
275         return;
276     }
277     InterruptMode interruptMode = audioExclusive
278                                 ? InterruptMode::INDEPENDENT_MODE
279                                 : InterruptMode::SHARE_MODE;
280     WVLOG_D("AudioRendererAdapterImpl::SetInterruptMode audioExclusive: %{public}d", audioExclusive);
281     audio_renderer_->SetInterruptMode(interruptMode);
282 }
283 
IsRendererStateRunning()284 bool AudioRendererAdapterImpl::IsRendererStateRunning()
285 {
286     return audio_renderer_->GetStatus() == OHOS::AudioStandard::RendererState::RENDERER_RUNNING;
287 }
288 
GetAudioSamplingRate(AudioAdapterSamplingRate samplingRate)289 AudioSamplingRate AudioRendererAdapterImpl::GetAudioSamplingRate(AudioAdapterSamplingRate samplingRate)
290 {
291     auto item = SAMPLING_RATE_MAP.find(samplingRate);
292     if (item == SAMPLING_RATE_MAP.end()) {
293         WVLOG_E("audio sampling rate not found");
294         return AudioSamplingRate::SAMPLE_RATE_44100;
295     }
296     return item->second;
297 }
298 
GetAudioEncodingType(AudioAdapterEncodingType encodingType)299 AudioEncodingType AudioRendererAdapterImpl::GetAudioEncodingType(AudioAdapterEncodingType encodingType)
300 {
301     auto item = ENCODING_TYPE_MAP.find(encodingType);
302     if (item == ENCODING_TYPE_MAP.end()) {
303         WVLOG_E("audio encoding type not found");
304         return AudioEncodingType::ENCODING_INVALID;
305     }
306     return item->second;
307 }
308 
GetAudioSampleFormat(AudioAdapterSampleFormat sampleFormat)309 AudioSampleFormat AudioRendererAdapterImpl::GetAudioSampleFormat(AudioAdapterSampleFormat sampleFormat)
310 {
311     auto item = SAMPLE_FORMAT_MAP.find(sampleFormat);
312     if (item == SAMPLE_FORMAT_MAP.end()) {
313         WVLOG_E("audio sample format not found");
314         return AudioSampleFormat::INVALID_WIDTH;
315     }
316     return item->second;
317 }
318 
GetAudioChannel(AudioAdapterChannel channel)319 AudioChannel AudioRendererAdapterImpl::GetAudioChannel(AudioAdapterChannel channel)
320 {
321     auto item = AUDIO_CHANNEL_MAP.find(channel);
322     if (item == AUDIO_CHANNEL_MAP.end()) {
323         WVLOG_E("audio channel not found");
324         return AudioChannel::STEREO;
325     }
326     return item->second;
327 }
328 
GetAudioContentType(AudioAdapterContentType contentType)329 ContentType AudioRendererAdapterImpl::GetAudioContentType(AudioAdapterContentType contentType)
330 {
331     auto item = CONTENT_TYPE_MAP.find(contentType);
332     if (item == CONTENT_TYPE_MAP.end()) {
333         WVLOG_E("audio content type not found");
334         return ContentType::CONTENT_TYPE_MUSIC;
335     }
336     return item->second;
337 }
338 
GetAudioStreamUsage(AudioAdapterStreamUsage streamUsage)339 StreamUsage AudioRendererAdapterImpl::GetAudioStreamUsage(AudioAdapterStreamUsage streamUsage)
340 {
341     auto item = STREAM_USAGE_MAP.find(streamUsage);
342     if (item == STREAM_USAGE_MAP.end()) {
343         WVLOG_E("audio stream usage not found");
344         return StreamUsage::STREAM_USAGE_MEDIA;
345     }
346     return item->second;
347 }
348 }  // namespace OHOS::NWeb