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