1 /*
2 * Copyright (c) 2022-2024 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_render_interface_impl.h"
17
18 #include <hdf_base.h>
19 #include <unistd.h>
20 #include "sys/time.h"
21
22 #include "cJSON.h"
23 #include "daudio_constants.h"
24 #include "daudio_events.h"
25 #include "daudio_log.h"
26 #include "daudio_utils.h"
27
28 #undef DH_LOG_TAG
29 #define DH_LOG_TAG "AudioRenderInterfaceImpl"
30
31 using namespace OHOS::DistributedHardware;
32 namespace OHOS {
33 namespace HDI {
34 namespace DistributedAudio {
35 namespace Audio {
36 namespace V1_0 {
AudioRenderInterfaceImpl(const std::string & adpName,const AudioDeviceDescriptor & desc,const AudioSampleAttributes & attrs,const sptr<IDAudioCallback> & callback,uint32_t renderId)37 AudioRenderInterfaceImpl::AudioRenderInterfaceImpl(const std::string &adpName, const AudioDeviceDescriptor &desc,
38 const AudioSampleAttributes &attrs, const sptr<IDAudioCallback> &callback, uint32_t renderId)
39 : adapterName_(adpName), devDesc_(desc),
40 devAttrs_(attrs), renderId_(renderId), audioExtCallback_(callback)
41 {
42 devAttrs_.frameSize = CalculateFrameSize(attrs.sampleRate, attrs.channelCount, attrs.format,
43 AUDIO_NORMAL_INTERVAL, false);
44 DHLOGD("Distributed audio render constructed, period(%{public}d), frameSize(%{public}d).",
45 attrs.period, devAttrs_.frameSize);
46 }
47
~AudioRenderInterfaceImpl()48 AudioRenderInterfaceImpl::~AudioRenderInterfaceImpl()
49 {
50 DHLOGD("Distributed audio render destructed, id(%{public}d).", devDesc_.pins);
51 }
52
GetLatency(uint32_t & ms)53 int32_t AudioRenderInterfaceImpl::GetLatency(uint32_t &ms)
54 {
55 DHLOGI("Get render device latency, not support yet.");
56 ms = 0;
57 return HDF_SUCCESS;
58 }
59
GetFadeRate(uint32_t currentIndex,const uint32_t durationIndex)60 float AudioRenderInterfaceImpl::GetFadeRate(uint32_t currentIndex, const uint32_t durationIndex)
61 {
62 if (currentIndex > durationIndex || durationIndex == 0) {
63 return 1.0f;
64 }
65
66 float fadeRate = static_cast<float>(currentIndex) / durationIndex * DAUDIO_FADE_NORMALIZATION_FACTOR;
67 if (fadeRate < 1) {
68 return pow(fadeRate, DAUDIO_FADE_POWER_NUM) / DAUDIO_FADE_NORMALIZATION_FACTOR;
69 }
70 return -pow(fadeRate - DAUDIO_FADE_MAXIMUM_VALUE, DAUDIO_FADE_POWER_NUM) /
71 DAUDIO_FADE_NORMALIZATION_FACTOR + 1;
72 }
73
FadeInProcess(const uint32_t durationFrame,int8_t * frameData,const size_t frameLength)74 int32_t AudioRenderInterfaceImpl::FadeInProcess(const uint32_t durationFrame,
75 int8_t *frameData, const size_t frameLength)
76 {
77 if (frameLength > RENDER_MAX_FRAME_SIZE) {
78 DHLOGE("The frameLength is over max length.");
79 return HDF_ERR_INVALID_PARAM;
80 }
81 int16_t* frame = reinterpret_cast<int16_t *>(frameData);
82 const size_t newFrameLength = frameLength / 2;
83
84 for (size_t k = 0; k < newFrameLength; ++k) {
85 float rate = GetFadeRate(currentFrame_ * newFrameLength + k, durationFrame * newFrameLength);
86 frame[k] = currentFrame_ == durationFrame - 1 ? frame[k] : static_cast<int16_t>(rate * frame[k]);
87 }
88 if (currentFrame_ < durationFrame - 1) {
89 DHLOGD("Fade-in frame[currentFrame: %{public}d].", currentFrame_);
90 }
91 ++currentFrame_;
92 currentFrame_ = currentFrame_ >= durationFrame ? durationFrame - 1 : currentFrame_;
93
94 return HDF_SUCCESS;
95 }
96
RenderFrame(const std::vector<int8_t> & frame,uint64_t & replyBytes)97 int32_t AudioRenderInterfaceImpl::RenderFrame(const std::vector<int8_t> &frame, uint64_t &replyBytes)
98 {
99 DHLOGD("Render frame[sampleRate: %{public}u, channelCount: %{public}u, format: %{public}d, frameSize: %{public}u].",
100 devAttrs_.sampleRate, devAttrs_.channelCount, devAttrs_.format, devAttrs_.frameSize);
101
102 int64_t startTime = GetNowTimeUs();
103 std::lock_guard<std::mutex> renderLck(renderMtx_);
104 if (renderStatus_ != RENDER_STATUS_START) {
105 DHLOGE("Render status wrong, return false.");
106 return HDF_FAILURE;
107 }
108
109 AudioParameter param = { devAttrs_.format, devAttrs_.channelCount, devAttrs_.sampleRate, 0,
110 devAttrs_.frameSize, devAttrs_.type};
111 AudioData data = { param, frame };
112 #ifdef DUMP_RENDER_FILE
113 if (dumpFlag_) {
114 SaveFile(HDF_RENDER_FILENAME, reinterpret_cast<uint8_t*>(data.data.data()), frame.size());
115 }
116 #endif
117 if (enableFade_ && (currentFrame_ < DURATION_FRAMES_MINUS)) {
118 FadeInProcess(DURATION_FRAMES, data.data.data(), frame.size());
119 }
120 if (audioExtCallback_ == nullptr) {
121 DHLOGE("Callback is nullptr.");
122 return HDF_FAILURE;
123 }
124 int32_t ret = audioExtCallback_->WriteStreamData(renderId_, data);
125 if (ret != HDF_SUCCESS) {
126 DHLOGE("Write stream data failed.");
127 return HDF_FAILURE;
128 }
129
130 ++frameIndex_;
131 DHLOGD("Render audio frame success.");
132 int64_t endTime = GetNowTimeUs();
133 if (IsOutDurationRange(startTime, endTime, lastRenderStartTime_)) {
134 DHLOGE("This time render frame spend: %" PRId64" us, The interval of this time and the last time: %" PRId64
135 " us", endTime - startTime, startTime - lastRenderStartTime_);
136 }
137 lastRenderStartTime_ = startTime;
138 return HDF_SUCCESS;
139 }
140
GetRenderPosition(uint64_t & frames,AudioTimeStamp & time)141 int32_t AudioRenderInterfaceImpl::GetRenderPosition(uint64_t &frames, AudioTimeStamp &time)
142 {
143 DHLOGI("Get render position, not support yet.");
144 (void)frames;
145 (void)time;
146 return HDF_SUCCESS;
147 }
148
SetRenderSpeed(float speed)149 int32_t AudioRenderInterfaceImpl::SetRenderSpeed(float speed)
150 {
151 DHLOGI("Set render speed, control render speed is not support yet.");
152 renderSpeed_ = speed;
153 return HDF_SUCCESS;
154 }
155
GetRenderSpeed(float & speed)156 int32_t AudioRenderInterfaceImpl::GetRenderSpeed(float &speed)
157 {
158 DHLOGI("Get render speed, control render speed is not support yet.");
159 speed = renderSpeed_;
160 return HDF_SUCCESS;
161 }
162
SetChannelMode(AudioChannelMode mode)163 int32_t AudioRenderInterfaceImpl::SetChannelMode(AudioChannelMode mode)
164 {
165 DHLOGI("Set channel mode, control channel mode is not support yet.");
166 channelMode_ = mode;
167 return HDF_SUCCESS;
168 }
169
GetChannelMode(AudioChannelMode & mode)170 int32_t AudioRenderInterfaceImpl::GetChannelMode(AudioChannelMode &mode)
171 {
172 DHLOGI("Get channel mode, control channel mode is not support yet.");
173 mode = channelMode_;
174 return HDF_SUCCESS;
175 }
176
RegCallback(const sptr<IAudioCallback> & audioCallback,int8_t cookie)177 int32_t AudioRenderInterfaceImpl::RegCallback(const sptr<IAudioCallback> &audioCallback, int8_t cookie)
178 {
179 DHLOGI("Register render callback.");
180 (void)cookie;
181 renderCallback_ = audioCallback;
182 return HDF_SUCCESS;
183 }
184
DrainBuffer(AudioDrainNotifyType & type)185 int32_t AudioRenderInterfaceImpl::DrainBuffer(AudioDrainNotifyType &type)
186 {
187 DHLOGI("Drain audio buffer, not support yet.");
188 (void)type;
189 return HDF_SUCCESS;
190 }
191
IsSupportsDrain(bool & support)192 int32_t AudioRenderInterfaceImpl::IsSupportsDrain(bool &support)
193 {
194 DHLOGI("Check whether drain is supported, not support yet.");
195 (void)support;
196 return HDF_SUCCESS;
197 }
198
Start()199 int32_t AudioRenderInterfaceImpl::Start()
200 {
201 DHLOGI("Start render.");
202 if (firstOpenFlag_) {
203 firstOpenFlag_ = false;
204 } else {
205 cJSON *jParam = cJSON_CreateObject();
206 if (jParam == nullptr) {
207 DHLOGE("Failed to create cJSON object.");
208 return HDF_FAILURE;
209 }
210 cJSON_AddStringToObject(jParam, KEY_DH_ID, std::to_string(devDesc_.pins).c_str());
211 cJSON_AddStringToObject(jParam, "ChangeType", HDF_EVENT_RESTART.c_str());
212 char *jsonData = cJSON_PrintUnformatted(jParam);
213 if (jsonData == nullptr) {
214 DHLOGE("Failed to create JSON data.");
215 cJSON_Delete(jParam);
216 return HDF_FAILURE;
217 }
218 std::string content(jsonData);
219 cJSON_Delete(jParam);
220 cJSON_free(jsonData);
221 DAudioEvent event = { HDF_AUDIO_EVENT_CHANGE_PLAY_STATUS, content};
222 if (audioExtCallback_ == nullptr) {
223 DHLOGE("Callback is nullptr.");
224 return HDF_FAILURE;
225 }
226 int32_t ret = audioExtCallback_->NotifyEvent(renderId_, event);
227 if (ret != HDF_SUCCESS) {
228 DHLOGE("Restart failed.");
229 }
230 }
231 std::lock_guard<std::mutex> renderLck(renderMtx_);
232 renderStatus_ = RENDER_STATUS_START;
233 currentFrame_ = CUR_FRAME_INIT_VALUE;
234 frameIndex_ = 0;
235 return HDF_SUCCESS;
236 }
237
Stop()238 int32_t AudioRenderInterfaceImpl::Stop()
239 {
240 DHLOGI("Stop render.");
241 cJSON *jParam = cJSON_CreateObject();
242 if (jParam == nullptr) {
243 DHLOGE("Failed to create cJSON object.");
244 return HDF_FAILURE;
245 }
246 cJSON_AddStringToObject(jParam, KEY_DH_ID, std::to_string(devDesc_.pins).c_str());
247 cJSON_AddStringToObject(jParam, "ChangeType", HDF_EVENT_PAUSE.c_str());
248 char *jsonData = cJSON_PrintUnformatted(jParam);
249 if (jsonData == nullptr) {
250 DHLOGE("Failed to create JSON data.");
251 cJSON_Delete(jParam);
252 return HDF_FAILURE;
253 }
254 std::string content(jsonData);
255 cJSON_Delete(jParam);
256 cJSON_free(jsonData);
257 DAudioEvent event = { HDF_AUDIO_EVENT_CHANGE_PLAY_STATUS, content};
258 if (audioExtCallback_ == nullptr) {
259 DHLOGE("Callback is nullptr.");
260 return HDF_FAILURE;
261 }
262 int32_t ret = audioExtCallback_->NotifyEvent(renderId_, event);
263 if (ret != HDF_SUCCESS) {
264 DHLOGE("Pause and clear cache streams failed.");
265 }
266 std::lock_guard<std::mutex> renderLck(renderMtx_);
267 renderStatus_ = RENDER_STATUS_STOP;
268 return HDF_SUCCESS;
269 }
270
Pause()271 int32_t AudioRenderInterfaceImpl::Pause()
272 {
273 DHLOGI("Pause render.");
274 std::lock_guard<std::mutex> renderLck(renderMtx_);
275 renderStatus_ = RENDER_STATUS_PAUSE;
276 return HDF_SUCCESS;
277 }
278
Resume()279 int32_t AudioRenderInterfaceImpl::Resume()
280 {
281 return HDF_SUCCESS;
282 }
283
Flush()284 int32_t AudioRenderInterfaceImpl::Flush()
285 {
286 return HDF_SUCCESS;
287 }
288
TurnStandbyMode()289 int32_t AudioRenderInterfaceImpl::TurnStandbyMode()
290 {
291 DHLOGI("Turn stand by mode, not support yet.");
292 return HDF_SUCCESS;
293 }
294
AudioDevDump(int32_t range,int32_t fd)295 int32_t AudioRenderInterfaceImpl::AudioDevDump(int32_t range, int32_t fd)
296 {
297 DHLOGI("Dump audio info, not support yet.");
298 (void)range;
299 (void)fd;
300 return HDF_SUCCESS;
301 }
302
IsSupportsPauseAndResume(bool & supportPause,bool & supportResume)303 int32_t AudioRenderInterfaceImpl::IsSupportsPauseAndResume(bool &supportPause, bool &supportResume)
304 {
305 DHLOGI("Check whether pause and resume is supported, not support yet.");
306 (void)supportPause;
307 (void)supportResume;
308 return HDF_SUCCESS;
309 }
310
CheckSceneCapability(const AudioSceneDescriptor & scene,bool & supported)311 int32_t AudioRenderInterfaceImpl::CheckSceneCapability(const AudioSceneDescriptor &scene, bool &supported)
312 {
313 DHLOGI("Check scene capability.");
314 (void)scene;
315 (void)supported;
316 return HDF_SUCCESS;
317 }
318
SelectScene(const AudioSceneDescriptor & scene)319 int32_t AudioRenderInterfaceImpl::SelectScene(const AudioSceneDescriptor &scene)
320 {
321 DHLOGI("Select audio scene, not support yet.");
322 (void)scene;
323 return HDF_SUCCESS;
324 }
325
SetMute(bool mute)326 int32_t AudioRenderInterfaceImpl::SetMute(bool mute)
327 {
328 DHLOGI("Set mute, not support yet.");
329 (void)mute;
330 return HDF_SUCCESS;
331 }
332
GetMute(bool & mute)333 int32_t AudioRenderInterfaceImpl::GetMute(bool &mute)
334 {
335 DHLOGI("Get mute, not support yet.");
336 (void)mute;
337 return HDF_SUCCESS;
338 }
339
SetVolume(float volume)340 int32_t AudioRenderInterfaceImpl::SetVolume(float volume)
341 {
342 DHLOGI("Can not set vol not by this interface.");
343 (void)volume;
344 return HDF_SUCCESS;
345 }
346
GetVolume(float & volume)347 int32_t AudioRenderInterfaceImpl::GetVolume(float &volume)
348 {
349 DHLOGI("Can not get vol not by this interface.");
350 (void)volume;
351 return HDF_SUCCESS;
352 }
353
GetGainThreshold(float & min,float & max)354 int32_t AudioRenderInterfaceImpl::GetGainThreshold(float &min, float &max)
355 {
356 DHLOGI("Get gain threshold, not support yet.");
357 min = 0;
358 max = 0;
359 return HDF_SUCCESS;
360 }
361
SetGain(float gain)362 int32_t AudioRenderInterfaceImpl::SetGain(float gain)
363 {
364 DHLOGI("Set gain, not support yet.");
365 (void)gain;
366 return HDF_SUCCESS;
367 }
368
GetGain(float & gain)369 int32_t AudioRenderInterfaceImpl::GetGain(float &gain)
370 {
371 DHLOGI("Get gain, not support yet.");
372 gain = 1.0;
373 return HDF_SUCCESS;
374 }
375
GetFrameSize(uint64_t & size)376 int32_t AudioRenderInterfaceImpl::GetFrameSize(uint64_t &size)
377 {
378 (void)size;
379 return HDF_SUCCESS;
380 }
381
GetFrameCount(uint64_t & count)382 int32_t AudioRenderInterfaceImpl::GetFrameCount(uint64_t &count)
383 {
384 (void)count;
385 return HDF_SUCCESS;
386 }
387
SetSampleAttributes(const AudioSampleAttributes & attrs)388 int32_t AudioRenderInterfaceImpl::SetSampleAttributes(const AudioSampleAttributes &attrs)
389 {
390 DHLOGI("Set sample attributes.");
391 devAttrs_ = attrs;
392 return HDF_SUCCESS;
393 }
394
GetSampleAttributes(AudioSampleAttributes & attrs)395 int32_t AudioRenderInterfaceImpl::GetSampleAttributes(AudioSampleAttributes &attrs)
396 {
397 DHLOGI("Get sample attributes.");
398 attrs = devAttrs_;
399 return HDF_SUCCESS;
400 }
401
GetCurrentChannelId(uint32_t & channelId)402 int32_t AudioRenderInterfaceImpl::GetCurrentChannelId(uint32_t &channelId)
403 {
404 DHLOGI("Get current channel id, not support yet.");
405 (void)channelId;
406 return HDF_SUCCESS;
407 }
408
SetExtraParams(const std::string & keyValueList)409 int32_t AudioRenderInterfaceImpl::SetExtraParams(const std::string &keyValueList)
410 {
411 DHLOGI("Set extra parameters, not support yet.");
412 (void)keyValueList;
413 return HDF_SUCCESS;
414 }
415
GetExtraParams(std::string & keyValueList)416 int32_t AudioRenderInterfaceImpl::GetExtraParams(std::string &keyValueList)
417 {
418 DHLOGI("Get extra parameters, not support yet.");
419 (void)keyValueList;
420 return HDF_SUCCESS;
421 }
422
ReqMmapBuffer(int32_t reqSize,AudioMmapBufferDescriptor & desc)423 int32_t AudioRenderInterfaceImpl::ReqMmapBuffer(int32_t reqSize, AudioMmapBufferDescriptor &desc)
424 {
425 DHLOGI("Request mmap buffer, not support yet.");
426 (void)reqSize;
427 (void)desc;
428 return HDF_SUCCESS;
429 }
430
GetMmapPosition(uint64_t & frames,AudioTimeStamp & time)431 int32_t AudioRenderInterfaceImpl::GetMmapPosition(uint64_t &frames, AudioTimeStamp &time)
432 {
433 DHLOGI("Get mmap position, not support yet.");
434 (void)frames;
435 (void)time;
436 return HDF_SUCCESS;
437 }
438
AddAudioEffect(uint64_t effectid)439 int32_t AudioRenderInterfaceImpl::AddAudioEffect(uint64_t effectid)
440 {
441 DHLOGI("Add audio effect, not support yet.");
442 (void)effectid;
443 return HDF_SUCCESS;
444 }
445
RemoveAudioEffect(uint64_t effectid)446 int32_t AudioRenderInterfaceImpl::RemoveAudioEffect(uint64_t effectid)
447 {
448 DHLOGI("Remove audio effect, not support yet.");
449 (void)effectid;
450 return HDF_SUCCESS;
451 }
452
GetFrameBufferSize(uint64_t & bufferSize)453 int32_t AudioRenderInterfaceImpl::GetFrameBufferSize(uint64_t &bufferSize)
454 {
455 DHLOGI("Get frame buffer size, not support yet.");
456 (void)bufferSize;
457 return HDF_SUCCESS;
458 }
459
GetRenderDesc()460 const AudioDeviceDescriptor &AudioRenderInterfaceImpl::GetRenderDesc()
461 {
462 return devDesc_;
463 }
464
SetVolumeInner(const uint32_t vol)465 void AudioRenderInterfaceImpl::SetVolumeInner(const uint32_t vol)
466 {
467 std::lock_guard<std::mutex> volLck(volMtx_);
468 vol_ = vol;
469 }
470
SetVolumeRangeInner(const uint32_t volMax,const uint32_t volMin)471 void AudioRenderInterfaceImpl::SetVolumeRangeInner(const uint32_t volMax, const uint32_t volMin)
472 {
473 std::lock_guard<std::mutex> volLck(volMtx_);
474 volMin_ = volMin;
475 volMax_ = volMax;
476 }
477
GetVolumeInner()478 uint32_t AudioRenderInterfaceImpl::GetVolumeInner()
479 {
480 std::lock_guard<std::mutex> volLck(volMtx_);
481 return vol_;
482 }
483
GetMaxVolumeInner()484 uint32_t AudioRenderInterfaceImpl::GetMaxVolumeInner()
485 {
486 std::lock_guard<std::mutex> volLck(volMtx_);
487 return volMax_;
488 }
489
GetMinVolumeInner()490 uint32_t AudioRenderInterfaceImpl::GetMinVolumeInner()
491 {
492 std::lock_guard<std::mutex> volLck(volMtx_);
493 return volMin_;
494 }
495
SetAttrs(const std::string & adpName,const AudioDeviceDescriptor & desc,const AudioSampleAttributes & attrs,const sptr<IDAudioCallback> & callback,const int32_t dhId)496 void AudioRenderInterfaceImpl::SetAttrs(const std::string &adpName, const AudioDeviceDescriptor &desc,
497 const AudioSampleAttributes &attrs, const sptr<IDAudioCallback> &callback, const int32_t dhId)
498 {
499 DHLOGI("Set attrs, not support yet.");
500 }
501
SetDumpFlagInner()502 void AudioRenderInterfaceImpl::SetDumpFlagInner()
503 {
504 dumpFlag_ = true;
505 }
506 } // V1_0
507 } // Audio
508 } // Distributedaudio
509 } // HDI
510 } // OHOS
511