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 "dspeaker_client.h"
17
18 #include "daudio_constants.h"
19 #include "daudio_hisysevent.h"
20 #include "daudio_util.h"
21 #include "daudio_sink_manager.h"
22
23 #undef DH_LOG_TAG
24 #define DH_LOG_TAG "DSpeakerClient"
25
26 namespace OHOS {
27 namespace DistributedHardware {
~DSpeakerClient()28 DSpeakerClient::~DSpeakerClient()
29 {
30 DHLOGD("Release speaker client.");
31 }
32
OnEngineTransEvent(const AVTransEvent & event)33 void DSpeakerClient::OnEngineTransEvent(const AVTransEvent &event)
34 {
35 if (event.type == EventType::EVENT_START_SUCCESS) {
36 OnStateChange(DATA_OPENED);
37 } else if ((event.type == EventType::EVENT_STOP_SUCCESS) ||
38 (event.type == EventType::EVENT_CHANNEL_CLOSED) ||
39 (event.type == EventType::EVENT_START_FAIL)) {
40 OnStateChange(DATA_CLOSED);
41 }
42 }
43
OnEngineTransMessage(const std::shared_ptr<AVTransMessage> & message)44 void DSpeakerClient::OnEngineTransMessage(const std::shared_ptr<AVTransMessage> &message)
45 {
46 if (message == nullptr) {
47 DHLOGE("The parameter is nullptr");
48 return;
49 }
50 DAudioSinkManager::GetInstance().HandleDAudioNotify(message->dstDevId_, message->dstDevId_,
51 static_cast<int32_t>(message->type_), message->content_);
52 }
53
OnEngineTransDataAvailable(const std::shared_ptr<AudioData> & audioData)54 void DSpeakerClient::OnEngineTransDataAvailable(const std::shared_ptr<AudioData> &audioData)
55 {
56 DHLOGE("On Engine Data available");
57 OnDecodeTransDataDone(audioData);
58 }
59
InitReceiverEngine(IAVEngineProvider * providerPtr)60 int32_t DSpeakerClient::InitReceiverEngine(IAVEngineProvider *providerPtr)
61 {
62 DHLOGI("InitReceiverEngine enter.");
63 if (speakerTrans_ == nullptr) {
64 speakerTrans_ = std::make_shared<AVTransReceiverTransport>(devId_, shared_from_this());
65 }
66 int32_t ret = speakerTrans_->InitEngine(providerPtr);
67 if (ret != DH_SUCCESS) {
68 DHLOGE("Spk client initialize av receiver adapter failed.");
69 return ERR_DH_AUDIO_TRANS_NULL_VALUE;
70 }
71 return DH_SUCCESS;
72 }
73
CreateAudioRenderer(const AudioParam & param)74 int32_t DSpeakerClient::CreateAudioRenderer(const AudioParam ¶m)
75 {
76 DHLOGD("Set up spk client: {sampleRate: %d, bitFormat: %d, channelMask: %d," +
77 "frameSize: %d, contentType: %d, renderFlags: %d, streamUsage: %d}.",
78 param.comParam.sampleRate, param.comParam.bitFormat, param.comParam.channelMask, param.comParam.frameSize,
79 param.renderOpts.contentType, param.renderOpts.renderFlags, param.renderOpts.streamUsage);
80 audioParam_ = param;
81 AudioStandard::AudioRendererOptions rendererOptions = {
82 {
83 static_cast<AudioStandard::AudioSamplingRate>(audioParam_.comParam.sampleRate),
84 AudioStandard::AudioEncodingType::ENCODING_PCM,
85 static_cast<AudioStandard::AudioSampleFormat>(audioParam_.comParam.bitFormat),
86 static_cast<AudioStandard::AudioChannel>(audioParam_.comParam.channelMask),
87 },
88 {
89 static_cast<AudioStandard::ContentType>(audioParam_.renderOpts.contentType),
90 static_cast<AudioStandard::StreamUsage>(audioParam_.renderOpts.streamUsage),
91 audioParam_.renderOpts.renderFlags == MMAP_MODE ? AudioStandard::STREAM_FLAG_FAST : 0,
92 }
93 };
94 std::lock_guard<std::mutex> lck(devMtx_);
95 audioRenderer_ = AudioStandard::AudioRenderer::Create(rendererOptions);
96 if (audioRenderer_ == nullptr) {
97 DHLOGE("Audio renderer create failed.");
98 return ERR_DH_AUDIO_CLIENT_CREATE_RENDER_FAILED;
99 }
100 audioRenderer_ ->SetRendererCallback(shared_from_this());
101 if (audioParam_.renderOpts.renderFlags != MMAP_MODE) {
102 return DH_SUCCESS;
103 }
104 int32_t ret = audioRenderer_->SetRendererWriteCallback(shared_from_this());
105 if (ret != DH_SUCCESS) {
106 DHLOGE("Client save write callback failed.");
107 return ERR_DH_AUDIO_CLIENT_CREATE_RENDER_FAILED;
108 }
109 return DH_SUCCESS;
110 }
111
OnWriteData(size_t length)112 void DSpeakerClient::OnWriteData(size_t length)
113 {
114 AudioStandard::BufferDesc bufDesc;
115 if (audioRenderer_ == nullptr) {
116 DHLOGE("AudioRenderer is nullptr.");
117 return;
118 }
119 int32_t ret = audioRenderer_->GetBufferDesc(bufDesc);
120 if (ret != DH_SUCCESS || bufDesc.buffer == nullptr || bufDesc.bufLength == 0) {
121 DHLOGE("Get buffer desc failed.");
122 return;
123 }
124 std::shared_ptr<AudioData> audioData = nullptr;
125 {
126 std::unique_lock<std::mutex> spkLck(dataQueueMtx_);
127 dataQueueCond_.wait_for(spkLck, std::chrono::milliseconds(REQUEST_DATA_WAIT),
128 [this]() { return !dataQueue_.empty(); });
129 if (dataQueue_.empty()) {
130 return;
131 }
132 audioData = dataQueue_.front();
133 dataQueue_.pop();
134 DHLOGD("Pop spk data, dataQueue size: %d.", dataQueue_.size());
135 }
136 if (audioData->Capacity() != bufDesc.bufLength) {
137 DHLOGE("Audio data length is not equal to buflength. datalength: %d, bufLength: %d",
138 audioData->Capacity(), bufDesc.bufLength);
139 }
140 if (memcpy_s(bufDesc.buffer, bufDesc.bufLength, audioData->Data(), audioData->Capacity()) != EOK) {
141 DHLOGE("Copy audio data failed.");
142 }
143 audioRenderer_->Enqueue(bufDesc);
144 }
145
SetUp(const AudioParam & param)146 int32_t DSpeakerClient::SetUp(const AudioParam ¶m)
147 {
148 int32_t ret = CreateAudioRenderer(param);
149 if (ret != DH_SUCCESS) {
150 DHLOGE("Set up failed, Create Audio renderer failed.");
151 return ret;
152 }
153 if (speakerTrans_ == nullptr) {
154 DHLOGE("Speaker trans should be init by dev.");
155 return ERR_DH_AUDIO_NULLPTR;
156 }
157 ret = speakerTrans_->SetUp(audioParam_, audioParam_, shared_from_this(), CAP_SPK);
158 if (ret != DH_SUCCESS) {
159 DHLOGE("Speaker trans setup failed.");
160 return ret;
161 }
162 ret = speakerTrans_->Start();
163 if (ret != DH_SUCCESS) {
164 DHLOGE("Speaker trans start failed.");
165 return ret;
166 }
167 auto pid = getpid();
168 ret = AudioStandard::AudioSystemManager::GetInstance()->RegisterVolumeKeyEventCallback(pid, shared_from_this());
169 if (ret != DH_SUCCESS) {
170 DHLOGE("Failed to register volume key event callback.");
171 return ret;
172 }
173 clientStatus_ = AudioStatus::STATUS_READY;
174 return DH_SUCCESS;
175 }
176
Release()177 int32_t DSpeakerClient::Release()
178 {
179 DHLOGI("Release spk client.");
180 std::lock_guard<std::mutex> lck(devMtx_);
181 if (clientStatus_ != AudioStatus::STATUS_READY && clientStatus_ != AudioStatus::STATUS_STOP) {
182 DHLOGE("Speaker status %d is wrong.", (int32_t)clientStatus_);
183 return ERR_DH_AUDIO_SA_STATUS_ERR;
184 }
185 bool isSucess = true;
186 if (speakerTrans_ != nullptr) {
187 if (speakerTrans_->Stop() != DH_SUCCESS) {
188 DHLOGE("Speaker trans stop failed.");
189 isSucess = false;
190 }
191 if (speakerTrans_->Release() != DH_SUCCESS) {
192 DHLOGE("Speaker trans release failed.");
193 isSucess = false;
194 }
195 speakerTrans_ = nullptr;
196 }
197
198 int32_t ret = AudioStandard::AudioSystemManager::GetInstance()->UnregisterVolumeKeyEventCallback(getpid());
199 if (ret != DH_SUCCESS) {
200 DHLOGE("Failed to unregister volume key event callback, error code %d.", ret);
201 isSucess = false;
202 }
203 if (audioRenderer_ != nullptr && !audioRenderer_->Release()) {
204 DHLOGE("Audio renderer release failed.");
205 isSucess = false;
206 audioRenderer_ = nullptr;
207 }
208 clientStatus_ = AudioStatus::STATUS_IDLE;
209 return isSucess ? DH_SUCCESS : ERR_DH_AUDIO_CLIENT_RENDER_RELEASE_FAILED;
210 }
211
StartRender()212 int32_t DSpeakerClient::StartRender()
213 {
214 DHLOGI("Start spk client.");
215 std::lock_guard<std::mutex> lck(devMtx_);
216 if (audioRenderer_ == nullptr || clientStatus_ != AudioStatus::STATUS_READY) {
217 DHLOGE("Audio renderer init failed or spk status wrong, status: %d.", (int32_t)clientStatus_);
218 DAudioHisysevent::GetInstance().SysEventWriteFault(DAUDIO_OPT_FAIL, ERR_DH_AUDIO_SA_STATUS_ERR,
219 "daudio renderer init failed or spk status wrong.");
220 return ERR_DH_AUDIO_SA_STATUS_ERR;
221 }
222 if (!audioRenderer_->Start()) {
223 DHLOGE("Audio renderer start failed.");
224 DAudioHisysevent::GetInstance().SysEventWriteFault(DAUDIO_OPT_FAIL, ERR_DH_AUDIO_CLIENT_RENDER_STARTUP_FAILURE,
225 "daudio renderer start failed.");
226 return ERR_DH_AUDIO_CLIENT_RENDER_STARTUP_FAILURE;
227 }
228 if (audioParam_.renderOpts.renderFlags != MMAP_MODE) {
229 isRenderReady_.store(true);
230 renderDataThread_ = std::thread(&DSpeakerClient::PlayThreadRunning, this);
231 }
232 clientStatus_ = AudioStatus::STATUS_START;
233 return DH_SUCCESS;
234 }
235
StopRender()236 int32_t DSpeakerClient::StopRender()
237 {
238 DHLOGI("Stop spk client.");
239 std::lock_guard<std::mutex> lck(devMtx_);
240 if (clientStatus_ != AudioStatus::STATUS_START || !isRenderReady_.load()) {
241 DHLOGE("Renderer is not start or spk status wrong, status: %d.", (int32_t)clientStatus_);
242 DAudioHisysevent::GetInstance().SysEventWriteFault(DAUDIO_OPT_FAIL, ERR_DH_AUDIO_SA_STATUS_ERR,
243 "daudio renderer is not start or spk status wrong.");
244 return ERR_DH_AUDIO_SA_STATUS_ERR;
245 }
246 if (audioRenderer_ == nullptr) {
247 DHLOGE("Audio renderer is nullptr.");
248 DAudioHisysevent::GetInstance().SysEventWriteFault(DAUDIO_OPT_FAIL, ERR_DH_AUDIO_CLIENT_RENDER_OR_TRANS_IS_NULL,
249 "daudio renderer is nullptr.");
250 return ERR_DH_AUDIO_CLIENT_RENDER_OR_TRANS_IS_NULL;
251 }
252
253 FlushJitterQueue();
254 if (audioParam_.renderOpts.renderFlags != MMAP_MODE) {
255 isRenderReady_.store(false);
256 if (renderDataThread_.joinable()) {
257 renderDataThread_.join();
258 }
259 }
260
261 if (!audioRenderer_->Stop()) {
262 DHLOGE("Audio renderer stop failed");
263 DAudioHisysevent::GetInstance().SysEventWriteFault(DAUDIO_OPT_FAIL, ERR_DH_AUDIO_CLIENT_RENDER_STOP_FAILED,
264 "daudio renderer stop failed.");
265 return ERR_DH_AUDIO_CLIENT_RENDER_STOP_FAILED;
266 }
267 clientStatus_ = AudioStatus::STATUS_STOP;
268 return DH_SUCCESS;
269 }
270
PlayThreadRunning()271 void DSpeakerClient::PlayThreadRunning()
272 {
273 DHLOGD("Start the renderer thread.");
274 if (pthread_setname_np(pthread_self(), RENDERTHREAD) != DH_SUCCESS) {
275 DHLOGE("Render data thread setname failed.");
276 }
277
278 FillJitterQueue();
279 while (audioRenderer_ != nullptr && isRenderReady_.load()) {
280 std::shared_ptr<AudioData> audioData = nullptr;
281 {
282 std::unique_lock<std::mutex> spkLck(dataQueueMtx_);
283 dataQueueCond_.wait_for(spkLck, std::chrono::milliseconds(REQUEST_DATA_WAIT),
284 [this]() { return !dataQueue_.empty(); });
285 if (dataQueue_.empty()) {
286 continue;
287 }
288 audioData = dataQueue_.front();
289 dataQueue_.pop();
290 DHLOGD("Pop spk data, dataqueue size: %d.", dataQueue_.size());
291 }
292
293 int32_t writeOffSet = 0;
294 while (writeOffSet < static_cast<int32_t>(audioData->Capacity())) {
295 int32_t writeLen = audioRenderer_->Write(audioData->Data() + writeOffSet,
296 static_cast<int32_t>(audioData->Capacity()) - writeOffSet);
297 DHLOGD("Write audio render, write len: %d, raw len: %d, offset: %d", writeLen, audioData->Capacity(),
298 writeOffSet);
299 if (writeLen < 0) {
300 break;
301 }
302 writeOffSet += writeLen;
303 }
304 }
305 }
306
FillJitterQueue()307 void DSpeakerClient::FillJitterQueue()
308 {
309 while (isRenderReady_.load()) {
310 {
311 std::lock_guard<std::mutex> lock(dataQueueMtx_);
312 if (dataQueue_.size() >= DATA_QUEUE_SIZE) {
313 break;
314 }
315 }
316 usleep(SLEEP_TIME);
317 }
318 }
319
FlushJitterQueue()320 void DSpeakerClient::FlushJitterQueue()
321 {
322 while (true) {
323 {
324 std::lock_guard<std::mutex> lock(dataQueueMtx_);
325 if (dataQueue_.empty()) {
326 break;
327 }
328 }
329 usleep(SLEEP_TIME);
330 }
331 }
332
OnDecodeTransDataDone(const std::shared_ptr<AudioData> & audioData)333 int32_t DSpeakerClient::OnDecodeTransDataDone(const std::shared_ptr<AudioData> &audioData)
334 {
335 DHLOGI("Write stream buffer.");
336 if (audioData == nullptr) {
337 DHLOGE("The parameter is empty.");
338 return ERR_DH_AUDIO_CLIENT_PARAM_IS_NULL;
339 }
340 std::lock_guard<std::mutex> lock(dataQueueMtx_);
341 while (dataQueue_.size() > DATA_QUEUE_MAX_SIZE) {
342 DHLOGD("Data queue overflow.");
343 dataQueue_.pop();
344 }
345 dataQueue_.push(audioData);
346 dataQueueCond_.notify_all();
347 DHLOGI("Push new spk data, buf len: %d.", dataQueue_.size());
348 return DH_SUCCESS;
349 }
350
OnStateChange(const AudioEventType type)351 int32_t DSpeakerClient::OnStateChange(const AudioEventType type)
352 {
353 DHLOGD("On state change. type: %d", type);
354 AudioEvent event;
355 switch (type) {
356 case AudioEventType::DATA_OPENED: {
357 event.type = AudioEventType::SPEAKER_OPENED;
358 event.content = GetVolumeLevel();
359 break;
360 }
361 case AudioEventType::DATA_CLOSED: {
362 event.type = AudioEventType::SPEAKER_CLOSED;
363 break;
364 }
365 default:
366 DHLOGE("Invalid parameter type: %d.", type);
367 return ERR_DH_AUDIO_CLIENT_STATE_IS_INVALID;
368 }
369
370 std::shared_ptr<IAudioEventCallback> cbObj = eventCallback_.lock();
371 if (cbObj == nullptr) {
372 DHLOGE("Event callback is nullptr.");
373 return ERR_DH_AUDIO_CLIENT_EVENT_CALLBACK_IS_NULL;
374 }
375 cbObj->NotifyEvent(event);
376 return DH_SUCCESS;
377 }
378
GetVolumeLevel()379 string DSpeakerClient::GetVolumeLevel()
380 {
381 DHLOGD("Get the volume level.");
382 std::stringstream ss;
383 AudioStandard::AudioStreamType streamType = AudioStandard::AudioStreamType::STREAM_DEFAULT;
384 auto volumeType = static_cast<AudioStandard::AudioVolumeType>(1);
385 int32_t volumeLevel = AudioStandard::AudioSystemManager::GetInstance()->GetVolume(volumeType);
386 int32_t maxVolumeLevel = AudioStandard::AudioSystemManager::GetInstance()->GetMaxVolume(volumeType);
387 int32_t minVolumeLevel = AudioStandard::AudioSystemManager::GetInstance()->GetMinVolume(volumeType);
388 bool isUpdateUi = false;
389 ss << "FIRST_VOLUME_CHANAGE;"
390 << "AUDIO_STREAM_TYPE=" << streamType << ";"
391 << "VOLUME_LEVEL=" << volumeLevel << ";"
392 << "IS_UPDATEUI=" << isUpdateUi << ";"
393 << "MAX_VOLUME_LEVEL=" << maxVolumeLevel << ";"
394 << "MIN_VOLUME_LEVEL=" << minVolumeLevel << ";";
395 std::string str = ss.str();
396 DHLOGD("Get the volume level result, event: %s.", str.c_str());
397 return str;
398 }
399
OnVolumeKeyEvent(AudioStandard::VolumeEvent volumeEvent)400 void DSpeakerClient::OnVolumeKeyEvent(AudioStandard::VolumeEvent volumeEvent)
401 {
402 DHLOGD("Volume change event.");
403 std::shared_ptr<IAudioEventCallback> cbObj = eventCallback_.lock();
404 if (cbObj == nullptr) {
405 DHLOGE("Event callback is nullptr.");
406 return;
407 }
408 std::stringstream ss;
409 ss << "VOLUME_CHANAGE;"
410 << "AUDIO_STREAM_TYPE=" << volumeEvent.volumeType << ";"
411 << "VOLUME_LEVEL=" << volumeEvent.volume << ";"
412 << "IS_UPDATEUI=" << volumeEvent.updateUi << ";"
413 << "VOLUME_GROUP_ID=" << volumeEvent.volumeGroupId << ";";
414 std::string str = ss.str();
415 DHLOGD("Volume change notification result, event: %s.", str.c_str());
416
417 AudioEvent audioEvent(VOLUME_CHANGE, str);
418 cbObj->NotifyEvent(audioEvent);
419 }
420
OnInterrupt(const AudioStandard::InterruptEvent & interruptEvent)421 void DSpeakerClient::OnInterrupt(const AudioStandard::InterruptEvent &interruptEvent)
422 {
423 DHLOGD("Audio focus interrupt event.");
424 std::shared_ptr<IAudioEventCallback> cbObj = eventCallback_.lock();
425 if (cbObj == nullptr) {
426 DHLOGE("Event callback is nullptr.");
427 return;
428 }
429 std::stringstream ss;
430 ss << "INTERRUPT_EVENT;"
431 << "EVENT_TYPE=" << interruptEvent.eventType << ";"
432 << "FORCE_TYPE=" << interruptEvent.forceType << ";"
433 << "HINT_TYPE=" << interruptEvent.hintType << ";";
434 std::string str = ss.str();
435 DHLOGD("Audio focus oninterrupt notification result, event: %s.", str.c_str());
436
437 AudioEvent audioEvent(AUDIO_FOCUS_CHANGE, str);
438 cbObj->NotifyEvent(audioEvent);
439 }
440
OnStateChange(const AudioStandard::RendererState state,const AudioStandard::StateChangeCmdType cmdType)441 void DSpeakerClient::OnStateChange(const AudioStandard::RendererState state,
442 const AudioStandard::StateChangeCmdType __attribute__((unused)) cmdType)
443 {
444 DHLOGD("On render state change. state: %d", state);
445 std::shared_ptr<IAudioEventCallback> cbObj = eventCallback_.lock();
446 if (cbObj == nullptr) {
447 DHLOGE("Event callback is nullptr.");
448 return;
449 }
450 std::stringstream ss;
451 ss << "RENDER_STATE_CHANGE_EVENT;"
452 << "STATE=" << state << ";";
453 std::string str = ss.str();
454 DHLOGD("Audio render state changes notification result, event: %s.", str.c_str());
455
456 AudioEvent audioEvent(AUDIO_RENDER_STATE_CHANGE, str);
457 cbObj->NotifyEvent(audioEvent);
458 }
459
SetAudioParameters(const AudioEvent & event)460 int32_t DSpeakerClient::SetAudioParameters(const AudioEvent &event)
461 {
462 DHLOGD("Set the volume, arg: %s.", event.content.c_str());
463
464 int32_t audioVolumeType;
465 int32_t ret = GetAudioParamInt(event.content, AUDIO_VOLUME_TYPE, audioVolumeType);
466 if (ret != DH_SUCCESS) {
467 DHLOGE("Get audio volume type failed.");
468 return ret;
469 }
470 auto volumeType = static_cast<AudioStandard::AudioVolumeType>(audioVolumeType);
471 DHLOGD("Audio volume type, volumeType = %d.", volumeType);
472 if (event.type != VOLUME_SET) {
473 DHLOGE("Invalid parameter.");
474 return ERR_DH_AUDIO_CLIENT_INVALID_VOLUME_PARAMETER;
475 }
476
477 int32_t audioVolumeLevel;
478 ret = GetAudioParamInt(event.content, VOLUME_LEVEL, audioVolumeLevel);
479 if (ret != DH_SUCCESS) {
480 DHLOGE("Get audio volume level failed.");
481 return ret;
482 }
483 DHLOGD("volume level = %d.", audioVolumeLevel);
484 ret = AudioStandard::AudioSystemManager::GetInstance()->SetVolume(volumeType, audioVolumeLevel);
485 if (ret != DH_SUCCESS) {
486 DHLOGE("Voloume set failed.");
487 return ERR_DH_AUDIO_CLIENT_SET_VOLUME_FAILED;
488 }
489 return DH_SUCCESS;
490 }
491
SetMute(const AudioEvent & event)492 int32_t DSpeakerClient::SetMute(const AudioEvent &event)
493 {
494 DHLOGD("Set mute, arg: %s.", event.content.c_str());
495 int32_t audioVolumeType;
496 int32_t ret = GetAudioParamInt(event.content, AUDIO_VOLUME_TYPE, audioVolumeType);
497 if (ret != DH_SUCCESS) {
498 DHLOGE("Get audio volume type failed.");
499 return ret;
500 }
501
502 bool muteStatus = false;
503 ret = GetAudioParamBool(event.content, STREAM_MUTE_STATUS, muteStatus);
504 if (ret != DH_SUCCESS) {
505 DHLOGE("Get mute status failed.");
506 return ret;
507 }
508
509 auto volumeType = static_cast<AudioStandard::AudioVolumeType>(audioVolumeType);
510 DHLOGD("Audio volume type, volumeType = %d.", volumeType);
511 if (event.type != VOLUME_MUTE_SET) {
512 DHLOGE("Invalid parameter.");
513 return ERR_DH_AUDIO_CLIENT_INVALID_VOLUME_PARAMETER;
514 }
515 ret = AudioStandard::AudioSystemManager::GetInstance()->SetMute(volumeType, muteStatus);
516 if (ret != DH_SUCCESS) {
517 DHLOGE("Mute set failed.");
518 return ERR_DH_AUDIO_CLIENT_SET_MUTE_FAILED;
519 }
520 return DH_SUCCESS;
521 }
522
Pause()523 void DSpeakerClient::Pause()
524 {
525 DHLOGI("Pause and flush");
526 FlushJitterQueue();
527 if (audioParam_.renderOpts.renderFlags != MMAP_MODE) {
528 isRenderReady_.store(false);
529 if (renderDataThread_.joinable()) {
530 renderDataThread_.join();
531 }
532 }
533
534 if (speakerTrans_ == nullptr || speakerTrans_->Pause() != DH_SUCCESS) {
535 DHLOGE("Speaker trans Pause failed.");
536 }
537 if (audioRenderer_ != nullptr) {
538 audioRenderer_->Flush();
539 }
540 clientStatus_ = AudioStatus::STATUS_START;
541 isRenderReady_.store(true);
542 }
543
ReStart()544 void DSpeakerClient::ReStart()
545 {
546 DHLOGI("ReStart");
547 if (speakerTrans_ == nullptr || speakerTrans_->Restart(audioParam_, audioParam_) != DH_SUCCESS) {
548 DHLOGE("Speaker trans Restart failed.");
549 }
550 if (audioParam_.renderOpts.renderFlags != MMAP_MODE) {
551 isRenderReady_.store(true);
552 renderDataThread_ = std::thread(&DSpeakerClient::PlayThreadRunning, this);
553 }
554 clientStatus_ = AudioStatus::STATUS_START;
555 }
556
SendMessage(uint32_t type,std::string content,std::string dstDevId)557 int32_t DSpeakerClient::SendMessage(uint32_t type, std::string content, std::string dstDevId)
558 {
559 DHLOGI("Send message to remote.");
560 if (type != static_cast<uint32_t>(NOTIFY_OPEN_SPEAKER_RESULT) &&
561 type != static_cast<uint32_t>(NOTIFY_CLOSE_SPEAKER_RESULT) &&
562 type != static_cast<uint32_t>(VOLUME_CHANGE) &&
563 type != static_cast<uint32_t>(AUDIO_FOCUS_CHANGE) &&
564 type != static_cast<uint32_t>(AUDIO_RENDER_STATE_CHANGE)) {
565 DHLOGE("event type is not NOTIFY_OPEN_SPK or NOTIFY_CLOSE_SPK. type:%u", type);
566 return ERR_DH_AUDIO_NULLPTR;
567 }
568 if (speakerTrans_ == nullptr) {
569 DHLOGE("speaker trans is null.");
570 return ERR_DH_AUDIO_NULLPTR;
571 }
572 speakerTrans_->SendMessage(type, content, dstDevId);
573 return DH_SUCCESS;
574 }
575
PlayStatusChange(const std::string & args)576 void DSpeakerClient::PlayStatusChange(const std::string &args)
577 {
578 DHLOGD("Play status change, args: %s.", args.c_str());
579 if (args == AUDIO_EVENT_RESTART) {
580 ReStart();
581 } else if (args == AUDIO_EVENT_PAUSE) {
582 Pause();
583 } else {
584 DHLOGE("Play status error.");
585 }
586 }
587
SetAttrs(const std::string & devId,const std::shared_ptr<IAudioEventCallback> & callback)588 void DSpeakerClient::SetAttrs(const std::string &devId, const std::shared_ptr<IAudioEventCallback> &callback)
589 {
590 DHLOGE("Set attrs, not support yet.");
591 }
592 } // DistributedHardware
593 } // OHOS
594