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 "audio_errors.h"
21 #include "foundation/ability/ability_runtime/interfaces/kits/native/appkit/ability_runtime/context/application_context.h"
22 #include "nweb_log.h"
23
24 namespace OHOS::NWeb {
25 const std::unordered_map<AudioAdapterSamplingRate, AudioSamplingRate> SAMPLING_RATE_MAP = {
26 {AudioAdapterSamplingRate::SAMPLE_RATE_8000, AudioSamplingRate::SAMPLE_RATE_8000},
27 {AudioAdapterSamplingRate::SAMPLE_RATE_11025, AudioSamplingRate::SAMPLE_RATE_11025},
28 {AudioAdapterSamplingRate::SAMPLE_RATE_12000, AudioSamplingRate::SAMPLE_RATE_12000},
29 {AudioAdapterSamplingRate::SAMPLE_RATE_16000, AudioSamplingRate::SAMPLE_RATE_16000},
30 {AudioAdapterSamplingRate::SAMPLE_RATE_22050, AudioSamplingRate::SAMPLE_RATE_22050},
31 {AudioAdapterSamplingRate::SAMPLE_RATE_24000, AudioSamplingRate::SAMPLE_RATE_24000},
32 {AudioAdapterSamplingRate::SAMPLE_RATE_32000, AudioSamplingRate::SAMPLE_RATE_32000},
33 {AudioAdapterSamplingRate::SAMPLE_RATE_44100, AudioSamplingRate::SAMPLE_RATE_44100},
34 {AudioAdapterSamplingRate::SAMPLE_RATE_48000, AudioSamplingRate::SAMPLE_RATE_48000},
35 {AudioAdapterSamplingRate::SAMPLE_RATE_64000, AudioSamplingRate::SAMPLE_RATE_64000},
36 {AudioAdapterSamplingRate::SAMPLE_RATE_96000, AudioSamplingRate::SAMPLE_RATE_96000},
37 };
38
39 const std::unordered_map<AudioAdapterEncodingType, AudioEncodingType> ENCODING_TYPE_MAP = {
40 {AudioAdapterEncodingType::ENCODING_PCM, AudioEncodingType::ENCODING_PCM},
41 {AudioAdapterEncodingType::ENCODING_INVALID, AudioEncodingType::ENCODING_INVALID}
42 };
43
44 const std::unordered_map<AudioAdapterSampleFormat, AudioSampleFormat> SAMPLE_FORMAT_MAP = {
45 {AudioAdapterSampleFormat::SAMPLE_U8, AudioSampleFormat::SAMPLE_U8},
46 {AudioAdapterSampleFormat::SAMPLE_S16LE, AudioSampleFormat::SAMPLE_S16LE},
47 {AudioAdapterSampleFormat::SAMPLE_S24LE, AudioSampleFormat::SAMPLE_S24LE},
48 {AudioAdapterSampleFormat::SAMPLE_S32LE, AudioSampleFormat::SAMPLE_S32LE},
49 {AudioAdapterSampleFormat::SAMPLE_F32LE, AudioSampleFormat::SAMPLE_F32LE},
50 };
51
52 const std::unordered_map<AudioAdapterChannel, AudioChannel> AUDIO_CHANNEL_MAP = {
53 {AudioAdapterChannel::MONO, AudioChannel::MONO},
54 {AudioAdapterChannel::STEREO, AudioChannel::STEREO},
55 {AudioAdapterChannel::CHANNEL_3, AudioChannel::CHANNEL_3},
56 {AudioAdapterChannel::CHANNEL_4, AudioChannel::CHANNEL_4},
57 {AudioAdapterChannel::CHANNEL_5, AudioChannel::CHANNEL_5},
58 {AudioAdapterChannel::CHANNEL_6, AudioChannel::CHANNEL_6},
59 {AudioAdapterChannel::CHANNEL_7, AudioChannel::CHANNEL_7},
60 {AudioAdapterChannel::CHANNEL_8, AudioChannel::CHANNEL_8},
61 };
62
63 const std::unordered_map<AudioAdapterContentType, ContentType> CONTENT_TYPE_MAP = {
64 {AudioAdapterContentType::CONTENT_TYPE_UNKNOWN, ContentType::CONTENT_TYPE_UNKNOWN},
65 {AudioAdapterContentType::CONTENT_TYPE_SPEECH, ContentType::CONTENT_TYPE_SPEECH},
66 {AudioAdapterContentType::CONTENT_TYPE_MUSIC, ContentType::CONTENT_TYPE_MUSIC},
67 {AudioAdapterContentType::CONTENT_TYPE_MOVIE, ContentType::CONTENT_TYPE_MOVIE},
68 {AudioAdapterContentType::CONTENT_TYPE_SONIFICATION, ContentType::CONTENT_TYPE_SONIFICATION},
69 {AudioAdapterContentType::CONTENT_TYPE_RINGTONE, ContentType::CONTENT_TYPE_RINGTONE},
70 };
71
72 const std::unordered_map<AudioAdapterStreamUsage, StreamUsage> STREAM_USAGE_MAP = {
73 {AudioAdapterStreamUsage::STREAM_USAGE_UNKNOWN, StreamUsage::STREAM_USAGE_UNKNOWN},
74 {AudioAdapterStreamUsage::STREAM_USAGE_MEDIA, StreamUsage::STREAM_USAGE_MEDIA},
75 {AudioAdapterStreamUsage::STREAM_USAGE_VOICE_COMMUNICATION, StreamUsage::STREAM_USAGE_VOICE_COMMUNICATION},
76 {AudioAdapterStreamUsage::STREAM_USAGE_VOICE_ASSISTANT, StreamUsage::STREAM_USAGE_VOICE_ASSISTANT},
77 {AudioAdapterStreamUsage::STREAM_USAGE_NOTIFICATION_RINGTONE, StreamUsage::STREAM_USAGE_NOTIFICATION_RINGTONE},
78 };
79
AudioRendererWriteCallbackImpl(std::shared_ptr<AudioRendererWriteCallbackAdapter> callback)80 AudioRendererWriteCallbackImpl::AudioRendererWriteCallbackImpl(
81 std::shared_ptr<AudioRendererWriteCallbackAdapter> callback) : callback_(callback) {}
82
OnWriteData(size_t length)83 void AudioRendererWriteCallbackImpl::OnWriteData(size_t length)
84 {
85 if (callback_) {
86 callback_->OnWriteData(length);
87 }
88 }
89
Create(const AudioAdapterRendererOptions & rendererOptions,std::string cachePath)90 int32_t AudioRendererAdapterImpl::Create(const AudioAdapterRendererOptions &rendererOptions,
91 std::string cachePath)
92 {
93 std::string audioCachePath = cachePath;
94 if (audioCachePath.empty()) {
95 std::shared_ptr<AbilityRuntime::ApplicationContext> context =
96 AbilityRuntime::ApplicationContext::GetApplicationContext();
97 if (!context) {
98 WVLOG_E("application context get failed");
99 return AUDIO_ERROR;
100 }
101 audioCachePath = context->GetCacheDir();
102 if (audioCachePath.empty()) {
103 WVLOG_E("application cache path get failed");
104 return AUDIO_ERROR;
105 }
106 }
107
108 AudioRendererOptions audioOptions;
109 audioOptions.streamInfo.samplingRate = GetAudioSamplingRate(rendererOptions.samplingRate);
110 audioOptions.streamInfo.encoding = GetAudioEncodingType(rendererOptions.encoding);
111 audioOptions.streamInfo.format = GetAudioSampleFormat(rendererOptions.format);
112 audioOptions.streamInfo.channels = GetAudioChannel(rendererOptions.channels);
113 audioOptions.rendererInfo.contentType = GetAudioContentType(rendererOptions.contentType);
114 audioOptions.rendererInfo.streamUsage = GetAudioStreamUsage(rendererOptions.streamUsage);
115 audioOptions.rendererInfo.rendererFlags = rendererOptions.rendererFlags;
116
117 audio_renderer_ = AudioRenderer::Create(audioCachePath, audioOptions);
118 if (audio_renderer_ == nullptr) {
119 WVLOG_E("audio rendderer create failed");
120 return AUDIO_NULL_ERROR;
121 }
122 return AUDIO_OK;
123 }
124
Start()125 bool AudioRendererAdapterImpl::Start()
126 {
127 if (audio_renderer_ == nullptr) {
128 WVLOG_E("audio rendderer is nullptr");
129 return false;
130 }
131 return audio_renderer_->Start();
132 }
133
Stop()134 bool AudioRendererAdapterImpl::Stop()
135 {
136 if (audio_renderer_ == nullptr) {
137 WVLOG_E("audio rendderer is nullptr");
138 return false;
139 }
140 return audio_renderer_->Stop();
141 }
142
Release()143 bool AudioRendererAdapterImpl::Release()
144 {
145 if (audio_renderer_ == nullptr) {
146 WVLOG_E("audio rendderer is nullptr");
147 return false;
148 }
149 return audio_renderer_->Release();
150 }
151
Write(uint8_t * buffer,size_t bufferSize)152 int32_t AudioRendererAdapterImpl::Write(uint8_t *buffer, size_t bufferSize)
153 {
154 if (audio_renderer_ == nullptr) {
155 WVLOG_E("audio rendderer is nullptr");
156 return AUDIO_NULL_ERROR;
157 }
158 return audio_renderer_->Write(buffer, bufferSize);
159 }
160
GetLatency(uint64_t & latency) const161 int32_t AudioRendererAdapterImpl::GetLatency(uint64_t &latency) const
162 {
163 if (audio_renderer_ == nullptr) {
164 WVLOG_E("audio rendderer is nullptr");
165 return AUDIO_NULL_ERROR;
166 }
167 return audio_renderer_->GetLatency(latency);
168 }
169
SetVolume(float volume) const170 int32_t AudioRendererAdapterImpl::SetVolume(float volume) const
171 {
172 if (audio_renderer_ == nullptr) {
173 WVLOG_E("audio rendderer is nullptr");
174 return AUDIO_NULL_ERROR;
175 }
176 return audio_renderer_->SetVolume(volume);
177 }
178
GetVolume() const179 float AudioRendererAdapterImpl::GetVolume() const
180 {
181 if (audio_renderer_ == nullptr) {
182 WVLOG_E("audio rendderer is nullptr");
183 return AUDIO_NULL_ERROR;
184 }
185 return audio_renderer_->GetVolume();
186 }
187
Enqueue(const BufferDescAdapter & bufDesc)188 int32_t AudioRendererAdapterImpl::Enqueue(const BufferDescAdapter& bufDesc)
189 {
190 if (audio_renderer_ == nullptr) {
191 WVLOG_E("audio renderer is nullptr");
192 return AUDIO_NULL_ERROR;
193 }
194 BufferDesc bufInfo;
195 bufInfo.buffer = bufDesc.buffer;
196 bufInfo.bufLength = bufDesc.bufLength;
197 bufInfo.dataLength = bufDesc.dataLength;
198 int32_t ret = audio_renderer_->Enqueue(bufInfo);
199 if (ret != AudioStandard::SUCCESS) {
200 WVLOG_E("audio renderer enqueue faild");
201 return AUDIO_ERROR;
202 }
203 return AUDIO_OK;
204 }
205
GetBufferDesc(BufferDescAdapter & bufDesc)206 int32_t AudioRendererAdapterImpl::GetBufferDesc(BufferDescAdapter& bufDesc)
207 {
208 if (audio_renderer_ == nullptr) {
209 WVLOG_E("audio renderer is nullptr");
210 return AUDIO_NULL_ERROR;
211 }
212 BufferDesc bufInfo;
213 int32_t ret = audio_renderer_->GetBufferDesc(bufInfo);
214 if (ret != AudioStandard::SUCCESS) {
215 WVLOG_E("audio renderer get buffer desc faild");
216 return AUDIO_ERROR;
217 }
218 bufDesc.buffer = bufInfo.buffer;
219 bufDesc.bufLength = bufInfo.bufLength;
220 bufDesc.dataLength = bufInfo.dataLength;
221 return AUDIO_OK;
222 }
223
SetAudioRendererWriteCallbackAdapter(const std::shared_ptr<AudioRendererWriteCallbackAdapter> & callback)224 int32_t AudioRendererAdapterImpl::SetAudioRendererWriteCallbackAdapter(
225 const std::shared_ptr<AudioRendererWriteCallbackAdapter>& callback)
226 {
227 if (callback == nullptr) {
228 WVLOG_E("audio renderer write callback is nullptr");
229 return AUDIO_NULL_ERROR;
230 }
231 callback_ = std::make_shared<AudioRendererWriteCallbackImpl>(callback);
232 if (audio_renderer_ == nullptr) {
233 WVLOG_E("audio renderer is nullptr");
234 return AUDIO_NULL_ERROR;
235 }
236 int32_t ret = audio_renderer_->SetRenderMode(RENDER_MODE_CALLBACK);
237 if (ret != AudioStandard::SUCCESS) {
238 WVLOG_E("audio renderer set render mode faild");
239 return AUDIO_ERROR;
240 }
241 ret = audio_renderer_->SetRendererWriteCallback(callback_);
242 if (ret != AudioStandard::SUCCESS) {
243 WVLOG_E("audio renderer set renderer write callback faild");
244 return AUDIO_ERROR;
245 }
246 return AUDIO_OK;
247 }
248
GetAudioSamplingRate(AudioAdapterSamplingRate samplingRate)249 AudioSamplingRate AudioRendererAdapterImpl::GetAudioSamplingRate(AudioAdapterSamplingRate samplingRate)
250 {
251 auto item = SAMPLING_RATE_MAP.find(samplingRate);
252 if (item == SAMPLING_RATE_MAP.end()) {
253 WVLOG_E("audio sampling rate not found");
254 return AudioSamplingRate::SAMPLE_RATE_44100;
255 }
256 return item->second;
257 }
258
GetAudioEncodingType(AudioAdapterEncodingType encodingType)259 AudioEncodingType AudioRendererAdapterImpl::GetAudioEncodingType(AudioAdapterEncodingType encodingType)
260 {
261 auto item = ENCODING_TYPE_MAP.find(encodingType);
262 if (item == ENCODING_TYPE_MAP.end()) {
263 WVLOG_E("audio encoding type not found");
264 return AudioEncodingType::ENCODING_INVALID;
265 }
266 return item->second;
267 }
268
GetAudioSampleFormat(AudioAdapterSampleFormat sampleFormat)269 AudioSampleFormat AudioRendererAdapterImpl::GetAudioSampleFormat(AudioAdapterSampleFormat sampleFormat)
270 {
271 auto item = SAMPLE_FORMAT_MAP.find(sampleFormat);
272 if (item == SAMPLE_FORMAT_MAP.end()) {
273 WVLOG_E("audio sample format not found");
274 return AudioSampleFormat::INVALID_WIDTH;
275 }
276 return item->second;
277 }
278
GetAudioChannel(AudioAdapterChannel channel)279 AudioChannel AudioRendererAdapterImpl::GetAudioChannel(AudioAdapterChannel channel)
280 {
281 auto item = AUDIO_CHANNEL_MAP.find(channel);
282 if (item == AUDIO_CHANNEL_MAP.end()) {
283 WVLOG_E("audio channel not found");
284 return AudioChannel::STEREO;
285 }
286 return item->second;
287 }
288
GetAudioContentType(AudioAdapterContentType contentType)289 ContentType AudioRendererAdapterImpl::GetAudioContentType(AudioAdapterContentType contentType)
290 {
291 auto item = CONTENT_TYPE_MAP.find(contentType);
292 if (item == CONTENT_TYPE_MAP.end()) {
293 WVLOG_E("audio content type not found");
294 return ContentType::CONTENT_TYPE_MUSIC;
295 }
296 return item->second;
297 }
298
GetAudioStreamUsage(AudioAdapterStreamUsage streamUsage)299 StreamUsage AudioRendererAdapterImpl::GetAudioStreamUsage(AudioAdapterStreamUsage streamUsage)
300 {
301 auto item = STREAM_USAGE_MAP.find(streamUsage);
302 if (item == STREAM_USAGE_MAP.end()) {
303 WVLOG_E("audio stream usage not found");
304 return StreamUsage::STREAM_USAGE_MEDIA;
305 }
306 return item->second;
307 }
308 } // namespace OHOS::NWeb