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 <chrono>
17 #include <cstring>
18 #include <dlfcn.h>
19 #include <string>
20 #include <sstream>
21 #include <unistd.h>
22 #include <cinttypes>
23 #include "securec.h"
24 #include "audio_errors.h"
25 #include "audio_log.h"
26 #include "audio_utils.h"
27 #include "remote_audio_renderer_sink.h"
28
29 using namespace std;
30
31 namespace OHOS {
32 namespace AudioStandard {
33 namespace {
34 const int32_t HALF_FACTOR = 2;
35 const float DEFAULT_VOLUME_LEVEL = 1.0f;
36 const uint32_t AUDIO_CHANNELCOUNT = 2;
37 const uint32_t AUDIO_SAMPLE_RATE_48K = 48000;
38 const uint32_t DEEP_BUFFER_RENDER_PERIOD_SIZE = 4096;
39 const uint32_t INT_32_MAX = 0x7fffffff;
40 const uint32_t PCM_8_BIT = 8;
41 const uint32_t PCM_16_BIT = 16;
42 const uint32_t INTERNAL_OUTPUT_STREAM_ID = 0;
43 constexpr int32_t PARAMS_RENDER_STATE_NUM = 2;
44 constexpr int32_t EVENT_DES_SIZE = 60;
45 constexpr int32_t RENDER_STATE_CONTENT_DES_SIZE = 60;
46 #ifdef PRODUCT_M40
47 const uint32_t PARAM_VALUE_LENTH = 20;
48 #endif
49 }
50
51 std::map<std::string, RemoteAudioRendererSink *> RemoteAudioRendererSink::allsinks;
52
RemoteAudioRendererSink(const std::string & deviceNetworkId)53 RemoteAudioRendererSink::RemoteAudioRendererSink(const std::string& deviceNetworkId)
54 : rendererInited_(false), started_(false), paused_(false), leftVolume_(DEFAULT_VOLUME_LEVEL),
55 rightVolume_(DEFAULT_VOLUME_LEVEL), openSpeaker_(-1), audioAdapter_(nullptr),
56 audioRender_(nullptr), callback_(nullptr)
57 {
58 AUDIO_INFO_LOG("Constract.");
59 attr_ = {};
60 this->deviceNetworkId_ = deviceNetworkId;
61 audioManager_ = GetAudioManager();
62 #ifdef DEBUG_DUMP_FILE
63 pfd = nullptr;
64 #endif // DEBUG_DUMP_FILE
65 }
66
~RemoteAudioRendererSink()67 RemoteAudioRendererSink::~RemoteAudioRendererSink()
68 {
69 if (rendererInited_ == true) {
70 RemoteAudioRendererSink::DeInit();
71 } else {
72 AUDIO_INFO_LOG("RemoteAudioRendererSink has already DeInit.");
73 }
74 }
75
GetInstance(const char * deviceNetworkId)76 RemoteAudioRendererSink *RemoteAudioRendererSink::GetInstance(const char *deviceNetworkId)
77 {
78 AUDIO_INFO_LOG("GetInstance.");
79 RemoteAudioRendererSink *audioRenderer_ = nullptr;
80 if (deviceNetworkId == nullptr) {
81 return audioRenderer_;
82 }
83 // check if it is in our map
84 std::string deviceName = deviceNetworkId;
85 if (allsinks.count(deviceName)) {
86 return allsinks[deviceName];
87 } else {
88 audioRenderer_ = new(std::nothrow) RemoteAudioRendererSink(deviceName);
89 AUDIO_DEBUG_LOG("new Daudio device sink:[%{public}s]", deviceNetworkId);
90 allsinks[deviceName] = audioRenderer_;
91 }
92 CHECK_AND_RETURN_RET_LOG((audioRenderer_ != nullptr), nullptr, "null audioRenderer!");
93 return audioRenderer_;
94 }
95
RegisterParameterCallback(AudioSinkCallback * callback)96 void RemoteAudioRendererSink::RegisterParameterCallback(AudioSinkCallback* callback)
97 {
98 AUDIO_INFO_LOG("RemoteAudioRendererSink: register params callback");
99 callback_ = callback;
100 if (paramCallbackRegistered_) {
101 return;
102 }
103 #ifdef PRODUCT_M40
104 // register to adapter
105 ParamCallback adapterCallback = &RemoteAudioRendererSink::ParamEventCallback;
106 if (audioAdapter_ == nullptr) {
107 AUDIO_ERR_LOG("RemoteAudioRendererSink::RegisterParameterCallback audioAdapter_ is null");
108 return;
109 }
110
111 int32_t ret = audioAdapter_->RegExtraParamObserver(audioAdapter_, adapterCallback, this);
112 if (ret != SUCCESS) {
113 AUDIO_ERR_LOG("RemoteAudioRendererSink::RegisterParameterCallback failed, error code: %d", ret);
114 } else {
115 paramCallbackRegistered_ = true;
116 }
117 #endif
118 }
119
SetAudioParameter(const AudioParamKey key,const std::string & condition,const std::string & value)120 void RemoteAudioRendererSink::SetAudioParameter(const AudioParamKey key, const std::string& condition,
121 const std::string& value)
122 {
123 #ifdef PRODUCT_M40
124 AUDIO_INFO_LOG("RemoteAudioRendererSink::SetParameter: key %{public}d, condition: %{public}s, value: %{public}s",
125 key, condition.c_str(), value.c_str());
126 enum AudioExtParamKey hdiKey = AudioExtParamKey(key);
127 if (audioAdapter_ == nullptr) {
128 AUDIO_ERR_LOG("RemoteAudioRendererSink::SetAudioParameter audioAdapter_ is null");
129 return;
130 }
131 int32_t ret = audioAdapter_->SetExtraParams(audioAdapter_, hdiKey, condition.c_str(), value.c_str());
132 if (ret != SUCCESS) {
133 AUDIO_ERR_LOG("RemoteAudioRendererSink::SetAudioParameter failed, error code: %d", ret);
134 }
135 #endif
136 }
137
GetAudioParameter(const AudioParamKey key,const std::string & condition)138 std::string RemoteAudioRendererSink::GetAudioParameter(const AudioParamKey key, const std::string& condition)
139 {
140 #ifdef PRODUCT_M40
141 AUDIO_INFO_LOG("RemoteAudioRendererSink::GetParameter: key %{public}d, condition: %{public}s", key,
142 condition.c_str());
143 enum AudioExtParamKey hdiKey = AudioExtParamKey(key);
144 char value[PARAM_VALUE_LENTH];
145 if (audioAdapter_ == nullptr) {
146 AUDIO_ERR_LOG("RemoteAudioRendererSink::GetAudioParameter audioAdapter_ is null");
147 return "";
148 }
149 int32_t ret = audioAdapter_->GetExtraParams(audioAdapter_, hdiKey, condition.c_str(), value, PARAM_VALUE_LENTH);
150 if (ret !=SUCCESS) {
151 AUDIO_ERR_LOG("AudioRendererSink::GetAudioParameter failed, error code: %d", ret);
152 return "";
153 }
154 return value;
155 #else
156 return "";
157 #endif
158 }
159
ParamEventCallback(AudioExtParamKey key,const char * condition,const char * value,void * reserved,void * cookie)160 int32_t RemoteAudioRendererSink::ParamEventCallback(AudioExtParamKey key, const char* condition, const char* value,
161 void* reserved, void* cookie)
162 {
163 AUDIO_INFO_LOG("RemoteAudioRendererSink::ParamEventCallback:key:%{public}d, condition:%{public}s, value:%{public}s",
164 key, condition, value);
165 RemoteAudioRendererSink* sink = reinterpret_cast<RemoteAudioRendererSink*>(cookie);
166 std::string networkId = sink->GetNetworkId();
167 AudioParamKey audioKey = AudioParamKey(key);
168 // render state change to invalid.
169 if (audioKey == AudioParamKey::RENDER_STATE) {
170 char eventDes[EVENT_DES_SIZE];
171 char contentDes[RENDER_STATE_CONTENT_DES_SIZE];
172 if (sscanf_s(condition, "%[^;];%s", eventDes, EVENT_DES_SIZE, contentDes,
173 RENDER_STATE_CONTENT_DES_SIZE) < PARAMS_RENDER_STATE_NUM) {
174 AUDIO_ERR_LOG("[AudioPolicyServer]: Failed parse condition");
175 return 0;
176 }
177 if (!strcmp(eventDes, "ERR_EVENT")) {
178 AUDIO_INFO_LOG("RemoteAudioRendererSink render state invalid, destroy audioRender");
179 if ((sink->audioRender_ != nullptr) && (sink->audioAdapter_ != nullptr)) {
180 sink->audioAdapter_->DestroyRender(sink->audioAdapter_, sink->audioRender_);
181 }
182 sink->audioRender_ = nullptr;
183 sink->isRenderCreated = false;
184 }
185 }
186 AudioSinkCallback* callback = sink->GetParamCallback();
187 callback->OnAudioParameterChange(networkId, audioKey, condition, value);
188 return 0;
189 }
190
GetNetworkId()191 std::string RemoteAudioRendererSink::GetNetworkId()
192 {
193 return deviceNetworkId_;
194 }
195
GetParamCallback()196 OHOS::AudioStandard::AudioSinkCallback* RemoteAudioRendererSink::GetParamCallback()
197 {
198 return callback_;
199 }
200
DeInit()201 void RemoteAudioRendererSink::DeInit()
202 {
203 AUDIO_INFO_LOG("DeInit.");
204 started_ = false;
205 rendererInited_ = false;
206 if ((audioRender_ != nullptr) && (audioAdapter_ != nullptr)) {
207 audioAdapter_->DestroyRender(audioAdapter_, audioRender_);
208 }
209 audioRender_ = nullptr;
210
211 if ((audioManager_ != nullptr) && (audioAdapter_ != nullptr)) {
212 if (routeHandle_ != -1) {
213 audioAdapter_->ReleaseAudioRoute(audioAdapter_, routeHandle_);
214 }
215 audioManager_->UnloadAdapter(audioManager_, audioAdapter_);
216 }
217 audioAdapter_ = nullptr;
218 audioManager_ = nullptr;
219 #ifdef DEBUG_DUMP_FILE
220 if (pfd) {
221 fclose(pfd);
222 pfd = nullptr;
223 }
224 #endif // DEBUG_DUMP_FILE
225 // remove map recorder.
226 RemoteAudioRendererSink *temp = allsinks[this->deviceNetworkId_];
227 if (temp != nullptr) {
228 delete temp;
229 temp = nullptr;
230 allsinks.erase(this->deviceNetworkId_);
231 }
232 }
233
InitAttrs(struct AudioSampleAttributes & attrs)234 void InitAttrs(struct AudioSampleAttributes &attrs)
235 {
236 /* Initialization of audio parameters for playback */
237 attrs.channelCount = AUDIO_CHANNELCOUNT;
238 attrs.sampleRate = AUDIO_SAMPLE_RATE_48K;
239 attrs.interleaved = 0;
240 attrs.streamId = INTERNAL_OUTPUT_STREAM_ID;
241 attrs.type = AUDIO_IN_MEDIA;
242 attrs.period = DEEP_BUFFER_RENDER_PERIOD_SIZE;
243 attrs.isBigEndian = false;
244 attrs.isSignedData = true;
245 attrs.stopThreshold = INT_32_MAX;
246 attrs.silenceThreshold = 0;
247 }
248
GetAudioManager()249 struct AudioManager *RemoteAudioRendererSink::GetAudioManager()
250 {
251 AUDIO_INFO_LOG("RemoteAudioRendererSink: Initialize audio proxy manager");
252 #ifdef PRODUCT_M40
253 #ifdef __aarch64__
254 char resolvedPath[100] = "/vendor/lib64/libdaudio_client.z.so";
255 #else
256 char resolvedPath[100] = "/vendor/lib/libdaudio_client.z.so";
257 #endif
258 struct AudioManager *(*GetAudioManagerFuncs)() = nullptr;
259
260 void *handle_ = dlopen(resolvedPath, 1);
261 if (handle_ == nullptr) {
262 AUDIO_ERR_LOG("Open so Fail");
263 return nullptr;
264 }
265 AUDIO_INFO_LOG("dlopen successful");
266
267 GetAudioManagerFuncs = (struct AudioManager *(*)())(dlsym(handle_, "GetAudioManagerFuncs"));
268 if (GetAudioManagerFuncs == nullptr) {
269 return nullptr;
270 }
271 AUDIO_INFO_LOG("GetAudioManagerFuncs done");
272
273 struct AudioManager *audioManager = GetAudioManagerFuncs();
274 if (audioManager == nullptr) {
275 return nullptr;
276 }
277 AUDIO_INFO_LOG("daudio manager created");
278 #else
279 struct AudioManager *audioManager = GetAudioManagerFuncs();
280 #endif // PRODUCT_M40
281 return audioManager;
282 }
283
CreateRender(const struct AudioPort & renderPort)284 int32_t RemoteAudioRendererSink::CreateRender(const struct AudioPort &renderPort)
285 {
286 int32_t ret;
287 int64_t start = GetNowTimeMs();
288 struct AudioSampleAttributes param;
289 InitAttrs(param);
290 param.sampleRate = attr_.sampleRate;
291 param.channelCount = attr_.channel;
292 param.format = attr_.format;
293 param.frameSize = PCM_16_BIT * param.channelCount / PCM_8_BIT;
294 param.startThreshold = DEEP_BUFFER_RENDER_PERIOD_SIZE / (param.frameSize);
295 AUDIO_INFO_LOG("RemoteAudioRendererSink Create render format: %{public}d", param.format);
296 struct AudioDeviceDescriptor deviceDesc;
297 deviceDesc.portId = renderPort.portId;
298 deviceDesc.pins = PIN_OUT_SPEAKER;
299 deviceDesc.desc = nullptr;
300 ret = audioAdapter_->CreateRender(audioAdapter_, &deviceDesc, ¶m, &audioRender_);
301 if (ret != 0 || audioRender_ == nullptr) {
302 AUDIO_ERR_LOG("AudioDeviceCreateRender failed");
303 return ERR_NOT_STARTED;
304 }
305
306 isRenderCreated = true;
307 int64_t cost = GetNowTimeMs() - start;
308 AUDIO_INFO_LOG("CreateRender cost[%{public}" PRId64 "]ms", cost);
309
310 return 0;
311 }
312
printRemoteAttr(RemoteAudioSinkAttr attr_)313 inline std::string printRemoteAttr(RemoteAudioSinkAttr attr_)
314 {
315 std::stringstream value;
316 value << "adapterName[" << attr_.adapterName << "] openMicSpeaker[" << attr_.openMicSpeaker << "] ";
317 value << "format[" << static_cast<int32_t>(attr_.format) << "] sampleFmt[" << attr_.sampleFmt << "] ";
318 value << "sampleRate[" << attr_.sampleRate << "] channel[" << attr_.channel << "] ";
319 value << "volume[" << attr_.volume << "] filePath[" << attr_.filePath << "] ";
320 value << "deviceNetworkId[" << attr_.deviceNetworkId << "] device_type[" << attr_.device_type << "]";
321 return value.str();
322 }
323
GetTargetAdapterPort(struct AudioAdapterDescriptor * descs,int32_t size,const char * networkId)324 int32_t RemoteAudioRendererSink::GetTargetAdapterPort(struct AudioAdapterDescriptor *descs, int32_t size,
325 const char *networkId)
326 {
327 int32_t targetIdx = -1;
328 for (int32_t index = 0; index < size; index++) {
329 struct AudioAdapterDescriptor *desc = &descs[index];
330 if (desc == nullptr || desc->adapterName == nullptr) {
331 continue;
332 }
333 if (strcmp(desc->adapterName, networkId)) {
334 AUDIO_INFO_LOG("[%{public}d] is not target adapter", index);
335 continue;
336 }
337 targetIdx = index;
338 for (uint32_t port = 0; port < desc->portNum; port++) {
339 // Only find out the port of out in the sound card
340 if (desc->ports[port].portId == PIN_OUT_SPEAKER) {
341 audioPort_ = desc->ports[port];
342 break;
343 }
344 }
345 }
346 return targetIdx;
347 }
348
Init(RemoteAudioSinkAttr & attr)349 int32_t RemoteAudioRendererSink::Init(RemoteAudioSinkAttr &attr)
350 {
351 AUDIO_INFO_LOG("RemoteAudioRendererSink: Init start.");
352 attr_ = attr;
353 adapterNameCase_ = attr_.adapterName; // Set sound card information
354 openSpeaker_ = attr_.openMicSpeaker;
355
356 if (audioManager_ == nullptr) {
357 AUDIO_ERR_LOG("Init audio manager Fail");
358 return ERR_NOT_STARTED;
359 }
360
361 int32_t size = 0;
362 struct AudioAdapterDescriptor *descs = nullptr;
363 int32_t ret = audioManager_->GetAllAdapters(audioManager_, &descs, &size);
364 if (size == 0 || descs == nullptr || ret != 0) {
365 AUDIO_ERR_LOG("Get adapters Fail");
366 return ERR_NOT_STARTED;
367 }
368 AUDIO_INFO_LOG("Get [%{publid}d]adapters", size);
369 int32_t targetIdx = GetTargetAdapterPort(descs, size, attr_.deviceNetworkId);
370 CHECK_AND_RETURN_RET_LOG((targetIdx >= 0), ERR_NOT_STARTED, "can not find target adapter.");
371
372 struct AudioAdapterDescriptor *desc = &descs[targetIdx];
373
374 if (audioManager_->LoadAdapter(audioManager_, desc, &audioAdapter_) != 0) {
375 AUDIO_ERR_LOG("Load Adapter Fail");
376 return ERR_NOT_STARTED;
377 }
378 if (audioAdapter_ == nullptr) {
379 AUDIO_ERR_LOG("Load audio device failed");
380 return ERR_NOT_STARTED;
381 }
382
383 ret = audioAdapter_->InitAllPorts(audioAdapter_);
384 if (ret != 0) {
385 AUDIO_ERR_LOG("InitAllPorts failed");
386 return ERR_NOT_STARTED;
387 }
388
389 AUDIO_INFO_LOG("RemoteAudioRendererSink: Init end.");
390 rendererInited_ = true;
391
392 #ifdef DEBUG_DUMP_FILE
393 AUDIO_INFO_LOG("dump RemoteAudioSinkAttr:%{public}s", printRemoteAttr(attr_).c_str());
394 std::string fileName = attr_.filePath;
395 std::string filePath = "/data/local/tmp/remote_test_001.pcm";
396 const char *g_audioOutTestFilePath = filePath.c_str();
397 pfd = fopen(g_audioOutTestFilePath, "a+"); // here will not create a file if not exit.
398 AUDIO_ERR_LOG("init dump file[%{public}s]", g_audioOutTestFilePath);
399 if (pfd == nullptr) {
400 AUDIO_ERR_LOG("Error opening remote pcm file[%{public}s]", g_audioOutTestFilePath);
401 }
402 #endif // DEBUG_DUMP_FILE
403
404 return SUCCESS;
405 }
406
RenderFrame(char & data,uint64_t len,uint64_t & writeLen)407 int32_t RemoteAudioRendererSink::RenderFrame(char &data, uint64_t len, uint64_t &writeLen)
408 {
409 int64_t start = GetNowTimeMs();
410 int32_t ret;
411 if (audioRender_ == nullptr) {
412 AUDIO_ERR_LOG("Audio Render Handle is nullptr!");
413 return ERR_INVALID_HANDLE;
414 }
415
416 ret = audioRender_->RenderFrame(audioRender_, static_cast<void*>(&data), len, &writeLen);
417 if (ret != 0) {
418 AUDIO_ERR_LOG("RenderFrame failed ret: %{public}x", ret);
419 return ERR_WRITE_FAILED;
420 }
421 writeLen = len;
422 #ifdef DEBUG_DUMP_FILE
423 if (pfd != nullptr) {
424 size_t writeResult = fwrite((void*)&data, 1, len, pfd);
425 if (writeResult != len) {
426 AUDIO_ERR_LOG("Failed to write the file.");
427 }
428 }
429 #endif // DEBUG_DUMP_FILE
430
431 int64_t cost = GetNowTimeMs() - start;
432 AUDIO_DEBUG_LOG("RenderFrame len[%{public}" PRIu64 "] cost[%{public}" PRId64 "]ms", len, cost);
433 return SUCCESS;
434 }
435
Start(void)436 int32_t RemoteAudioRendererSink::Start(void)
437 {
438 AUDIO_INFO_LOG("Start.");
439 if (!isRenderCreated) {
440 if (CreateRender(audioPort_) != 0) {
441 AUDIO_ERR_LOG("Create render failed, Audio Port: %{public}d", audioPort_.portId);
442 return ERR_NOT_STARTED;
443 }
444 }
445 int32_t ret;
446
447 if (!started_) {
448 ret = audioRender_->control.Start(reinterpret_cast<AudioHandle>(audioRender_));
449 if (!ret) {
450 started_ = true;
451 return SUCCESS;
452 } else {
453 AUDIO_ERR_LOG("RemoteAudioRendererSink::Start failed!");
454 return ERR_NOT_STARTED;
455 }
456 }
457 started_ = true;
458 return SUCCESS;
459 }
460
SetVolume(float left,float right)461 int32_t RemoteAudioRendererSink::SetVolume(float left, float right)
462 {
463 int32_t ret;
464 float volume;
465
466 if (audioRender_ == nullptr) {
467 AUDIO_ERR_LOG("RemoteAudioRendererSink::SetVolume failed audioRender_ null");
468 return ERR_INVALID_HANDLE;
469 }
470
471 leftVolume_ = left;
472 rightVolume_ = right;
473 if ((leftVolume_ == 0) && (rightVolume_ != 0)) {
474 volume = rightVolume_;
475 } else if ((leftVolume_ != 0) && (rightVolume_ == 0)) {
476 volume = leftVolume_;
477 } else {
478 volume = (leftVolume_ + rightVolume_) / HALF_FACTOR;
479 }
480
481 ret = audioRender_->volume.SetVolume(reinterpret_cast<AudioHandle>(audioRender_), volume);
482 if (ret) {
483 AUDIO_ERR_LOG("RemoteAudioRendererSink::Set volume failed!");
484 }
485
486 return ret;
487 }
488
GetVolume(float & left,float & right)489 int32_t RemoteAudioRendererSink::GetVolume(float &left, float &right)
490 {
491 left = leftVolume_;
492 right = rightVolume_;
493 return SUCCESS;
494 }
495
GetLatency(uint32_t * latency)496 int32_t RemoteAudioRendererSink::GetLatency(uint32_t *latency)
497 {
498 if (audioRender_ == nullptr) {
499 AUDIO_ERR_LOG("RemoteAudioRendererSink: GetLatency failed audio render null");
500 return ERR_INVALID_HANDLE;
501 }
502
503 if (!latency) {
504 AUDIO_ERR_LOG("RemoteAudioRendererSink: GetLatency failed latency null");
505 return ERR_INVALID_PARAM;
506 }
507
508 uint32_t hdiLatency;
509 if (audioRender_->GetLatency(audioRender_, &hdiLatency) == 0) {
510 *latency = hdiLatency;
511 return SUCCESS;
512 } else {
513 AUDIO_ERR_LOG("RemoteAudioRendererSink: GetLatency failed.");
514 return ERR_OPERATION_FAILED;
515 }
516 *latency = 21; // 4096 bytes ~ 21ms.
517 return SUCCESS;
518 }
519
GetAudioCategory(AudioScene audioScene)520 static AudioCategory GetAudioCategory(AudioScene audioScene)
521 {
522 AudioCategory audioCategory;
523 switch (audioScene) {
524 case AUDIO_SCENE_DEFAULT:
525 audioCategory = AUDIO_IN_MEDIA;
526 break;
527 case AUDIO_SCENE_RINGING:
528 audioCategory = AUDIO_IN_RINGTONE;
529 break;
530 case AUDIO_SCENE_PHONE_CALL:
531 audioCategory = AUDIO_IN_CALL;
532 break;
533 case AUDIO_SCENE_PHONE_CHAT:
534 audioCategory = AUDIO_IN_COMMUNICATION;
535 break;
536 default:
537 audioCategory = AUDIO_IN_MEDIA;
538 break;
539 }
540 AUDIO_DEBUG_LOG("RemoteAudioRendererSink: Audio category returned is: %{public}d", audioCategory);
541
542 return audioCategory;
543 }
544
SetOutputPortPin(DeviceType outputDevice,AudioRouteNode & sink)545 static int32_t SetOutputPortPin(DeviceType outputDevice, AudioRouteNode &sink)
546 {
547 int32_t ret = SUCCESS;
548
549 switch (outputDevice) {
550 case DEVICE_TYPE_SPEAKER:
551 sink.ext.device.type = PIN_OUT_SPEAKER;
552 sink.ext.device.desc = "pin_out_speaker";
553 break;
554 case DEVICE_TYPE_WIRED_HEADSET:
555 sink.ext.device.type = PIN_OUT_HEADSET;
556 sink.ext.device.desc = "pin_out_headset";
557 break;
558 case DEVICE_TYPE_USB_HEADSET:
559 sink.ext.device.type = PIN_OUT_USB_EXT;
560 sink.ext.device.desc = "pin_out_usb_ext";
561 break;
562 default:
563 ret = ERR_NOT_SUPPORTED;
564 break;
565 }
566
567 return ret;
568 }
569
OpenOutput(DeviceType outputDevice)570 int32_t RemoteAudioRendererSink::OpenOutput(DeviceType outputDevice)
571 {
572 AudioRouteNode source = {};
573 AudioRouteNode sink = {};
574
575 int32_t ret = SetOutputPortPin(outputDevice, sink);
576 if (ret != SUCCESS) {
577 AUDIO_ERR_LOG("RemoteAudioRendererSink: OpenOutput FAILED: %{public}d", ret);
578 return ret;
579 }
580
581 source.portId = 0;
582 source.role = AUDIO_PORT_SOURCE_ROLE;
583 source.type = AUDIO_PORT_MIX_TYPE;
584 source.ext.mix.moduleId = 0;
585 source.ext.mix.streamId = INTERNAL_OUTPUT_STREAM_ID;
586
587 sink.portId = audioPort_.portId;
588 sink.role = AUDIO_PORT_SINK_ROLE;
589 sink.type = AUDIO_PORT_DEVICE_TYPE;
590 sink.ext.device.moduleId = 0;
591
592 AudioRoute route = {
593 .sourcesNum = 1,
594 .sources = &source,
595 .sinksNum = 1,
596 .sinks = &sink,
597 };
598
599 if (audioAdapter_ == nullptr) {
600 AUDIO_ERR_LOG("OpenOutput failed, audioAdapter_ is null");
601 return ERR_INVALID_PARAM;
602 }
603 ret = audioAdapter_->UpdateAudioRoute(audioAdapter_, &route, &routeHandle_);
604 AUDIO_DEBUG_LOG("UpdateAudioRoute returns: %{public}d", ret);
605 if (ret != 0) {
606 AUDIO_ERR_LOG("UpdateAudioRoute failed");
607 return ERR_OPERATION_FAILED;
608 }
609
610 return SUCCESS;
611 }
612
SetAudioScene(AudioScene audioScene)613 int32_t RemoteAudioRendererSink::SetAudioScene(AudioScene audioScene)
614 {
615 AUDIO_INFO_LOG("RemoteAudioRendererSink::SetAudioScene in");
616 CHECK_AND_RETURN_RET_LOG(audioScene >= AUDIO_SCENE_DEFAULT && audioScene <= AUDIO_SCENE_PHONE_CHAT,
617 ERR_INVALID_PARAM, "invalid audioScene");
618 if (audioRender_ == nullptr) {
619 AUDIO_ERR_LOG("RemoteAudioRendererSink::SetAudioScene failed audio render handle is null!");
620 return ERR_INVALID_HANDLE;
621 }
622
623 int32_t ret = OpenOutput(DEVICE_TYPE_SPEAKER);
624 if (ret < 0) {
625 AUDIO_ERR_LOG("RemoteAudioRendererSink: Update route FAILED: %{public}d", ret);
626 }
627 struct AudioSceneDescriptor scene;
628 scene.scene.id = GetAudioCategory(audioScene);
629 scene.desc.pins = PIN_OUT_SPEAKER;
630 if (audioRender_->scene.SelectScene == nullptr) {
631 AUDIO_ERR_LOG("RemoteAudioRendererSink: Select scene nullptr");
632 return ERR_OPERATION_FAILED;
633 }
634
635 AUDIO_INFO_LOG("RemoteAudioRendererSink::SelectScene start");
636 ret = audioRender_->scene.SelectScene((AudioHandle)audioRender_, &scene);
637 AUDIO_INFO_LOG("RemoteAudioRendererSink::SelectScene over");
638 if (ret < 0) {
639 AUDIO_ERR_LOG("RemoteAudioRendererSink: Select scene FAILED: %{public}d", ret);
640 return ERR_OPERATION_FAILED;
641 }
642
643 AUDIO_INFO_LOG("RemoteAudioRendererSink::Select audio scene SUCCESS: %{public}d", audioScene);
644 return SUCCESS;
645 }
646
Stop(void)647 int32_t RemoteAudioRendererSink::Stop(void)
648 {
649 AUDIO_INFO_LOG("Stop.");
650 int32_t ret;
651
652 if (audioRender_ == nullptr) {
653 AUDIO_ERR_LOG("RemoteAudioRendererSink::Stop failed audioRender_ null");
654 return ERR_INVALID_HANDLE;
655 }
656
657 if (started_) {
658 ret = audioRender_->control.Stop(reinterpret_cast<AudioHandle>(audioRender_));
659 if (!ret) {
660 started_ = false;
661 return SUCCESS;
662 } else {
663 AUDIO_ERR_LOG("RemoteAudioRendererSink::Stop failed!");
664 return ERR_OPERATION_FAILED;
665 }
666 }
667 started_ = false;
668 return SUCCESS;
669 }
670
Pause(void)671 int32_t RemoteAudioRendererSink::Pause(void)
672 {
673 AUDIO_INFO_LOG("Pause.");
674 int32_t ret;
675
676 if (audioRender_ == nullptr) {
677 AUDIO_ERR_LOG("RemoteAudioRendererSink::Pause failed audioRender_ null");
678 return ERR_INVALID_HANDLE;
679 }
680
681 if (!started_) {
682 AUDIO_ERR_LOG("RemoteAudioRendererSink::Pause invalid state!");
683 return ERR_OPERATION_FAILED;
684 }
685
686 if (!paused_) {
687 ret = audioRender_->control.Pause(reinterpret_cast<AudioHandle>(audioRender_));
688 if (!ret) {
689 paused_ = true;
690 return SUCCESS;
691 } else {
692 AUDIO_ERR_LOG("RemoteAudioRendererSink::Pause failed!");
693 return ERR_OPERATION_FAILED;
694 }
695 }
696 return SUCCESS;
697 }
698
Resume(void)699 int32_t RemoteAudioRendererSink::Resume(void)
700 {
701 AUDIO_INFO_LOG("Pause.");
702 int32_t ret;
703
704 if (audioRender_ == nullptr) {
705 AUDIO_ERR_LOG("RemoteAudioRendererSink::Resume failed audioRender_ null");
706 return ERR_INVALID_HANDLE;
707 }
708
709 if (!started_) {
710 AUDIO_ERR_LOG("RemoteAudioRendererSink::Resume invalid state!");
711 return ERR_OPERATION_FAILED;
712 }
713
714 if (paused_) {
715 ret = audioRender_->control.Resume(reinterpret_cast<AudioHandle>(audioRender_));
716 if (!ret) {
717 paused_ = false;
718 return SUCCESS;
719 } else {
720 AUDIO_ERR_LOG("RemoteAudioRendererSink::Resume failed!");
721 return ERR_OPERATION_FAILED;
722 }
723 }
724 return SUCCESS;
725 }
726
Reset(void)727 int32_t RemoteAudioRendererSink::Reset(void)
728 {
729 AUDIO_INFO_LOG("Reset.");
730 int32_t ret;
731
732 if (started_ && audioRender_ != nullptr) {
733 ret = audioRender_->control.Flush(reinterpret_cast<AudioHandle>(audioRender_));
734 if (!ret) {
735 return SUCCESS;
736 } else {
737 AUDIO_ERR_LOG("RemoteAudioRendererSink::Reset failed!");
738 return ERR_OPERATION_FAILED;
739 }
740 }
741 return ERR_OPERATION_FAILED;
742 }
743
Flush(void)744 int32_t RemoteAudioRendererSink::Flush(void)
745 {
746 AUDIO_INFO_LOG("Flush.");
747 int32_t ret;
748
749 if (started_ && audioRender_ != nullptr) {
750 ret = audioRender_->control.Flush(reinterpret_cast<AudioHandle>(audioRender_));
751 if (!ret) {
752 return SUCCESS;
753 } else {
754 AUDIO_ERR_LOG("RemoteAudioRendererSink::Flush failed!");
755 return ERR_OPERATION_FAILED;
756 }
757 }
758 return ERR_OPERATION_FAILED;
759 }
760 } // namespace AudioStandard
761 } // namespace OHOS
762
763 #ifdef __cplusplus
764 extern "C" {
765 #endif
766
767 using namespace OHOS::AudioStandard;
768
FillinRemoteAudioRenderSinkWapper(const char * deviceNetworkId,void ** wapper)769 int32_t FillinRemoteAudioRenderSinkWapper(const char *deviceNetworkId, void **wapper)
770 {
771 RemoteAudioRendererSink *instance = RemoteAudioRendererSink::GetInstance(deviceNetworkId);
772 if (instance != nullptr) {
773 *wapper = static_cast<void *>(instance);
774 } else {
775 *wapper = nullptr;
776 }
777
778 return SUCCESS;
779 }
780
RemoteAudioRendererSinkInit(void * wapper,RemoteAudioSinkAttr * attr)781 int32_t RemoteAudioRendererSinkInit(void *wapper, RemoteAudioSinkAttr *attr)
782 {
783 int32_t ret;
784 RemoteAudioRendererSink *audioRendererSink = static_cast<RemoteAudioRendererSink *>(wapper);
785 CHECK_AND_RETURN_RET_LOG(audioRendererSink != nullptr, ERR_INVALID_HANDLE, "null audioRendererSink");
786 if (audioRendererSink->rendererInited_)
787 return SUCCESS;
788
789 ret = audioRendererSink->Init(*attr);
790 return ret;
791 }
792
RemoteAudioRendererSinkDeInit(void * wapper)793 void RemoteAudioRendererSinkDeInit(void *wapper)
794 {
795 RemoteAudioRendererSink *audioRendererSink = static_cast<RemoteAudioRendererSink *>(wapper);
796 CHECK_AND_RETURN_LOG(audioRendererSink != nullptr, "null audioRendererSink");
797 // remove the sink in allsinks.
798 if (audioRendererSink->rendererInited_)
799 audioRendererSink->DeInit();
800 }
801
RemoteAudioRendererSinkStop(void * wapper)802 int32_t RemoteAudioRendererSinkStop(void *wapper)
803 {
804 int32_t ret;
805 RemoteAudioRendererSink *audioRendererSink = static_cast<RemoteAudioRendererSink *>(wapper);
806 CHECK_AND_RETURN_RET_LOG(audioRendererSink != nullptr, ERR_INVALID_HANDLE, "null audioRendererSink");
807 if (!audioRendererSink->rendererInited_)
808 return SUCCESS;
809
810 ret = audioRendererSink->Stop();
811 return ret;
812 }
813
RemoteAudioRendererSinkStart(void * wapper)814 int32_t RemoteAudioRendererSinkStart(void *wapper)
815 {
816 int32_t ret;
817 RemoteAudioRendererSink *audioRendererSink = static_cast<RemoteAudioRendererSink *>(wapper);
818 CHECK_AND_RETURN_RET_LOG(audioRendererSink != nullptr, ERR_INVALID_HANDLE, "null audioRendererSink");
819 if (!audioRendererSink->rendererInited_) {
820 AUDIO_ERR_LOG("audioRenderer Not Inited! Init the renderer first\n");
821 return ERR_NOT_STARTED;
822 }
823
824 ret = audioRendererSink->Start();
825 return ret;
826 }
827
RemoteAudioRendererSinkPause(void * wapper)828 int32_t RemoteAudioRendererSinkPause(void *wapper)
829 {
830 RemoteAudioRendererSink *audioRendererSink = static_cast<RemoteAudioRendererSink *>(wapper);
831 CHECK_AND_RETURN_RET_LOG(audioRendererSink != nullptr, ERR_INVALID_HANDLE, "null audioRendererSink");
832 if (!audioRendererSink->rendererInited_) {
833 AUDIO_ERR_LOG("Renderer pause failed");
834 return ERR_NOT_STARTED;
835 }
836
837 return audioRendererSink->Pause();
838 }
839
RemoteAudioRendererSinkResume(void * wapper)840 int32_t RemoteAudioRendererSinkResume(void *wapper)
841 {
842 RemoteAudioRendererSink *audioRendererSink = static_cast<RemoteAudioRendererSink *>(wapper);
843 CHECK_AND_RETURN_RET_LOG(audioRendererSink != nullptr, ERR_INVALID_HANDLE, "null audioRendererSink");
844 if (!audioRendererSink->rendererInited_) {
845 AUDIO_ERR_LOG("Renderer resume failed");
846 return ERR_NOT_STARTED;
847 }
848
849 return audioRendererSink->Resume();
850 }
851
RemoteAudioRendererRenderFrame(void * wapper,char & data,uint64_t len,uint64_t & writeLen)852 int32_t RemoteAudioRendererRenderFrame(void *wapper, char &data, uint64_t len, uint64_t &writeLen)
853 {
854 int32_t ret;
855 RemoteAudioRendererSink *audioRendererSink = static_cast<RemoteAudioRendererSink *>(wapper);
856 CHECK_AND_RETURN_RET_LOG(audioRendererSink != nullptr, ERR_INVALID_HANDLE, "null audioRendererSink");
857 if (!audioRendererSink->rendererInited_) {
858 AUDIO_ERR_LOG("audioRenderer Not Inited! Init the renderer first\n");
859 return ERR_NOT_STARTED;
860 }
861
862 ret = audioRendererSink->RenderFrame(data, len, writeLen);
863 return ret;
864 }
865
RemoteAudioRendererSinkSetVolume(void * wapper,float left,float right)866 int32_t RemoteAudioRendererSinkSetVolume(void *wapper, float left, float right)
867 {
868 int32_t ret;
869 RemoteAudioRendererSink *audioRendererSink = static_cast<RemoteAudioRendererSink *>(wapper);
870 CHECK_AND_RETURN_RET_LOG(audioRendererSink != nullptr, ERR_INVALID_HANDLE, "null audioRendererSink");
871 if (!audioRendererSink->rendererInited_) {
872 AUDIO_ERR_LOG("audioRenderer Not Inited! Init the renderer first\n");
873 return ERR_NOT_STARTED;
874 }
875
876 ret = audioRendererSink->SetVolume(left, right);
877 return ret;
878 }
879
RemoteAudioRendererSinkGetLatency(void * wapper,uint32_t * latency)880 int32_t RemoteAudioRendererSinkGetLatency(void *wapper, uint32_t *latency)
881 {
882 int32_t ret;
883 RemoteAudioRendererSink *audioRendererSink = static_cast<RemoteAudioRendererSink *>(wapper);
884 CHECK_AND_RETURN_RET_LOG(audioRendererSink != nullptr, ERR_INVALID_HANDLE, "null audioRendererSink");
885 if (!audioRendererSink->rendererInited_) {
886 AUDIO_ERR_LOG("audioRenderer Not Inited! Init the renderer first\n");
887 return ERR_NOT_STARTED;
888 }
889
890 if (!latency) {
891 AUDIO_ERR_LOG("RemoteAudioRendererSinkGetLatency failed latency null");
892 return ERR_INVALID_PARAM;
893 }
894
895 ret = audioRendererSink->GetLatency(latency);
896 return ret;
897 }
898
RemoteAudioRendererSinkGetTransactionId(uint64_t * transactionId)899 int32_t RemoteAudioRendererSinkGetTransactionId(uint64_t *transactionId)
900 {
901 // as we can not get wapper initialized, we dont know which sink address we should return.
902 *transactionId = static_cast<uint16_t>(-1);
903 return SUCCESS;
904 }
905 #ifdef __cplusplus
906 }
907 #endif
908