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