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 <sys/time.h>
17 #include <utility>
18
19 #include <climits>
20 #include <cmath>
21 #include <cfloat>
22 #include "securec.h"
23 #include "audio_log.h"
24 #include "audio_policy_manager.h"
25 #include "tone_player_private.h"
26 #include "audio_utils.h"
27
28 namespace OHOS {
29 namespace AudioStandard {
30 namespace {
31 constexpr int32_t C20MS = 20;
32 constexpr int32_t C1000MS = 1000;
33 constexpr int32_t CMAXWAIT = 3;
34 constexpr int32_t CDOUBLE = 2;
35 constexpr int32_t AMPLITUDE = 16000;
36 constexpr int32_t BIT8 = 8;
37 }
38
39 #ifdef DUMPFILE
40 const char *g_tonePlayerTestFilePath = "/data/local/tmp/toneplayer_test.pcm";
41 #endif // DUMPFILE
42
Create(const AudioRendererInfo & rendererInfo)43 std::shared_ptr<TonePlayer> TonePlayer::Create(const AudioRendererInfo &rendererInfo)
44 {
45 if (!PermissionUtil::VerifySelfPermission()) {
46 AUDIO_ERR_LOG("Create: No system permission");
47 return nullptr;
48 }
49 return std::make_shared <TonePlayerPrivate>("", rendererInfo);
50 }
51
Create(const std::string cachePath,const AudioRendererInfo & rendererInfo)52 std::shared_ptr<TonePlayer> TonePlayer::Create(const std::string cachePath, const AudioRendererInfo &rendererInfo)
53 {
54 if (!PermissionUtil::VerifySelfPermission()) {
55 AUDIO_ERR_LOG("Create: No system permission");
56 return nullptr;
57 }
58 return std::make_shared <TonePlayerPrivate>(cachePath, rendererInfo);
59 }
60
TonePlayerPrivate(const std::string cachePath,const AudioRendererInfo & rendereInfo)61 TonePlayerPrivate::TonePlayerPrivate(const std::string cachePath, const AudioRendererInfo &rendereInfo)
62 {
63 tonePlayerState_ = TONE_PLAYER_IDLE;
64 rendererOptions.streamInfo.encoding = AudioEncodingType::ENCODING_PCM;
65 rendererOptions.streamInfo.samplingRate = SAMPLE_RATE_44100;
66 rendererOptions.streamInfo.format = SAMPLE_S16LE;
67 rendererOptions.streamInfo.channels = MONO;
68
69 // contentType::CONTENT_TYPE_MUSIC;
70 rendererOptions.rendererInfo.contentType = rendereInfo.contentType;
71
72 // streamUsage::STREAM_USAGE_MEDIA;
73 rendererOptions.rendererInfo.streamUsage = rendereInfo.streamUsage;
74 rendererOptions.rendererInfo.rendererFlags = rendereInfo.rendererFlags;
75 supportedTones_ = AudioPolicyManager::GetInstance().GetSupportedTones();
76 volume_ = TRACK_VOLUME;
77 toneInfo_ = NULL;
78 initialToneInfo_ = NULL;
79 toneDataGenLoop_ = nullptr;
80 samplingRate_ = rendererOptions.streamInfo.samplingRate;
81 if (!cachePath.empty()) {
82 AUDIO_INFO_LOG("copy application cache path");
83 cachePath_.assign(cachePath);
84 }
85 AUDIO_DEBUG_LOG("TonePlayerPrivate constructor: volume=%{public}f, size=%{public}zu",
86 volume_, supportedTones_.size());
87 #ifdef DUMPFILE
88 pfd_ = nullptr;
89 #endif // DUMPFILE
90 }
91
92 TonePlayer::~TonePlayer() = default;
93
~TonePlayerPrivate()94 TonePlayerPrivate::~TonePlayerPrivate()
95 {
96 AUDIO_INFO_LOG("TonePlayerPrivate destructor");
97 if (audioRenderer_ != nullptr) {
98 StopTone();
99 mutexLock_.lock();
100 if (audioRenderer_ != nullptr) {
101 audioRenderer_->Clear();
102 } else {
103 AUDIO_ERR_LOG("~TonePlayerPrivate audioRenderer_ is null");
104 }
105 mutexLock_.unlock();
106 }
107 if (toneDataGenLoop_ && toneDataGenLoop_->joinable()) {
108 toneDataGenLoop_->join();
109 }
110 audioRenderer_ = nullptr;
111 }
112
LoadEventStateHandler()113 bool TonePlayerPrivate::LoadEventStateHandler()
114 {
115 AUDIO_INFO_LOG("TonePlayerPrivate::LoadEventStateHandler start");
116 bool result = true;
117 if (audioRenderer_ != nullptr) {
118 result = StopTone();
119 mutexLock_.lock();
120 if (audioRenderer_ != nullptr) {
121 if (audioRenderer_->Clear() != 0) {
122 result = false;
123 }
124 } else {
125 AUDIO_ERR_LOG("LoadEventStateHandler audioRenderer_ is null");
126 }
127 mutexLock_.unlock();
128 tonePlayerState_ = TONE_PLAYER_IDLE;
129 audioRenderer_ = nullptr;
130 }
131 if (tonePlayerState_ == TONE_PLAYER_IDLE) {
132 AUDIO_DEBUG_LOG("Load Init AudioRenderer");
133 if ((audioRenderer_ == nullptr) && (!InitAudioRenderer())) {
134 AUDIO_ERR_LOG("LoadEventStateHandler InitAudioRenderer fail");
135 return false;
136 }
137 tonePlayerState_ = TONE_PLAYER_INIT;
138 }
139 if (InitToneWaveInfo() == false) {
140 AUDIO_ERR_LOG("Wave Initialization Failed");
141 tonePlayerState_ = TONE_PLAYER_IDLE;
142 return false;
143 }
144 tonePlayerState_ = TONE_PLAYER_STARTING;
145 toneDataState_ = TONE_DATA_LOADING;
146 if (toneDataGenLoop_ == nullptr) {
147 toneDataGenLoop_ = std::make_unique<std::thread>(&TonePlayerPrivate::AudioToneDataThreadFunc, this);
148 }
149 return result;
150 }
151
PlayEventStateHandler()152 bool TonePlayerPrivate::PlayEventStateHandler()
153 {
154 bool result = true;
155 status_t retStatus;
156 mutexLock_.unlock();
157 mutexLock_.lock();
158 if (audioRenderer_ != nullptr) {
159 result = audioRenderer_->Start();
160 } else {
161 AUDIO_ERR_LOG("PlayEventStateHandler audioRenderer_ is null");
162 }
163 mutexLock_.unlock();
164 mutexLock_.lock();
165 if (tonePlayerState_ == TONE_PLAYER_STARTING) {
166 mutexLock_.unlock();
167 std::unique_lock<std::mutex> lock(cbkCondLock_);
168 playWait_ = true;
169 retStatus = waitAudioCbkCond_.wait_for(lock, std::chrono::seconds(CMAXWAIT));
170 playWait_ = false;
171 AUDIO_DEBUG_LOG("Immediate start got notified, status %{public}d", retStatus);
172 mutexLock_.lock();
173 if (retStatus == std::cv_status::timeout) {
174 AUDIO_ERR_LOG("Immediate start timed out, status %{public}d", retStatus);
175 return false;
176 }
177 }
178 playWait_ = false;
179 return result;
180 }
181
TonePlayerStateHandler(int16_t event)182 bool TonePlayerPrivate::TonePlayerStateHandler(int16_t event)
183 {
184 AUDIO_INFO_LOG("TonePlayerPrivate HandlePlayerState");
185 switch (event) {
186 case PLAYER_EVENT_LOAD:
187 if (LoadEventStateHandler() == false) {
188 return false;
189 }
190 break;
191 case PLAYER_EVENT_PLAY:
192 if (PlayEventStateHandler() == false) {
193 tonePlayerState_ = TONE_PLAYER_IDLE;
194 return false;
195 }
196 AUDIO_DEBUG_LOG("PLAYER_EVENT tonePlayerState_ %{public}d", tonePlayerState_);
197 break;
198 case PLAYER_EVENT_STOP:
199 StopEventStateHandler();
200 break;
201 }
202 return true;
203 }
204
LoadTone(ToneType toneType)205 bool TonePlayerPrivate::LoadTone(ToneType toneType)
206 {
207 AUDIO_INFO_LOG("LoadTone type: %{public}d, tonePlayerState_ %{public}d", toneType, tonePlayerState_);
208 bool result = false;
209 if (!PermissionUtil::VerifySelfPermission()) {
210 AUDIO_ERR_LOG("LoadTone: No system permission");
211 return false;
212 }
213 if (toneType >= NUM_TONES) {
214 return result;
215 }
216 mutexLock_.lock();
217 if (tonePlayerState_ != TONE_PLAYER_IDLE && tonePlayerState_ != TONE_PLAYER_INIT) {
218 mutexLock_.unlock();
219 return result;
220 }
221
222 if (std::find(supportedTones_.begin(), supportedTones_.end(), (int32_t)toneType) == supportedTones_.end()) {
223 mutexLock_.unlock();
224 return result;
225 }
226
227 // Get descriptor for requested tone
228 initialToneInfo_ = AudioPolicyManager::GetInstance().GetToneConfig(toneType);
229 if (initialToneInfo_->segmentCnt == 0) {
230 AUDIO_ERR_LOG("LoadTone failed, calling GetToneConfig returned invalid");
231 mutexLock_.unlock();
232 return result;
233 }
234 result = TonePlayerStateHandler(PLAYER_EVENT_LOAD);
235 mutexLock_.unlock();
236 #ifdef DUMPFILE
237 pfd_ = fopen(g_tonePlayerTestFilePath, "wb+");
238 if (pfd_ == nullptr) {
239 AUDIO_ERR_LOG("Error opening pcm test file!");
240 }
241 #endif // DUMPFILE
242 return result;
243 }
244
StartTone()245 bool TonePlayerPrivate::StartTone()
246 {
247 AUDIO_INFO_LOG("STARTTONE tonePlayerState_ %{public}d", tonePlayerState_);
248 bool retVal = false;
249 mutexLock_.lock();
250 if (tonePlayerState_ == TONE_PLAYER_IDLE || tonePlayerState_ == TONE_PLAYER_INIT) {
251 if (LoadEventStateHandler() == false) {
252 mutexLock_.unlock();
253 return false;
254 }
255 }
256 retVal = TonePlayerStateHandler(PLAYER_EVENT_PLAY);
257 mutexLock_.unlock();
258 return retVal;
259 }
260
Release()261 bool TonePlayerPrivate::Release()
262 {
263 bool retVal = true;
264 if (audioRenderer_ != nullptr) {
265 retVal = StopTone();
266 mutexLock_.lock();
267 if (audioRenderer_ != nullptr) {
268 if (audioRenderer_->Clear() != 0) {
269 retVal = false;
270 }
271 } else {
272 AUDIO_ERR_LOG("Release audioRenderer_ is null");
273 }
274 mutexLock_.unlock();
275 tonePlayerState_ = TONE_PLAYER_IDLE;
276 }
277 audioRenderer_ = nullptr;
278 return retVal;
279 }
280
StopTone()281 bool TonePlayerPrivate::StopTone()
282 {
283 AUDIO_INFO_LOG("StopTone tonePlayerState_ %{public}d", tonePlayerState_);
284 bool retVal = true;
285 mutexLock_.lock();
286 if (tonePlayerState_ == TONE_PLAYER_IDLE || tonePlayerState_ == TONE_PLAYER_INIT) {
287 AUDIO_INFO_LOG("-stop tone End");
288 mutexLock_.unlock();
289 return retVal;
290 } else if (tonePlayerState_ == TONE_PLAYER_STOPPED) {
291 AUDIO_INFO_LOG("tone is End");
292 mutexLock_.unlock();
293 return retVal;
294 }
295
296 retVal = TonePlayerStateHandler(PLAYER_EVENT_STOP);
297 mutexLock_.unlock();
298 mutexLock_.lock();
299 if (audioRenderer_ != nullptr) {
300 retVal = audioRenderer_->Stop();
301 } else {
302 AUDIO_ERR_LOG("StopTone audioRenderer_ is null");
303 }
304 mutexLock_.unlock();
305 #ifdef DUMPFILE
306 if (pfd_) {
307 fclose(pfd_);
308 pfd_ = nullptr;
309 }
310 #endif // DUMPFILE
311 return retVal;
312 }
313
StopEventStateHandler()314 void TonePlayerPrivate::StopEventStateHandler()
315 {
316 if (tonePlayerState_ == TONE_PLAYER_PLAYING || tonePlayerState_ == TONE_PLAYER_STARTING) {
317 tonePlayerState_ = TONE_PLAYER_STOPPING;
318 }
319 AUDIO_DEBUG_LOG("WAITING wait_for cond");
320 mutexLock_.unlock();
321 waitToneDataCond_.notify_all();
322 mutexLock_.lock();
323 }
324
InitAudioRenderer()325 bool TonePlayerPrivate::InitAudioRenderer()
326 {
327 processSize_ = (rendererOptions.streamInfo.samplingRate * C20MS) / C1000MS;
328 if (!cachePath_.empty()) {
329 audioRenderer_ = AudioRenderer::Create(cachePath_, rendererOptions);
330 } else {
331 audioRenderer_ = AudioRenderer::Create(rendererOptions);
332 }
333 if (audioRenderer_ == nullptr) {
334 AUDIO_ERR_LOG("initAudioRenderer: Renderer create failed");
335 return false;
336 }
337
338 AUDIO_DEBUG_LOG("initAudioRenderer: Playback renderer created");
339 if (audioRenderer_->SetRenderMode(RENDER_MODE_CALLBACK)) {
340 AUDIO_ERR_LOG("initAudioRenderer: SetRenderMode failed");
341 return false;
342 }
343 AUDIO_DEBUG_LOG("initAudioRenderer: SetRenderMode Sucessful");
344 if (audioRenderer_->SetRendererWriteCallback(shared_from_this())) {
345 AUDIO_ERR_LOG("initAudioRenderer: SetRendererWriteCallback failed");
346 return false;
347 }
348 AUDIO_DEBUG_LOG("initAudioRenderer: SetRendererWriteCallback Sucessful");
349 if (audioRenderer_->SetRendererCallback(shared_from_this())) {
350 AUDIO_ERR_LOG("initAudioRenderer: SetRendererCallbackfailed");
351 return false;
352 }
353
354 AUDIO_DEBUG_LOG("initAudioRenderer: SetRendererCallback Sucessful");
355 audioRenderer_->SetVolume(volume_);
356 AUDIO_INFO_LOG("initAudioRenderer: SetVolume Sucessful");
357 return true;
358 }
359
OnInterrupt(const InterruptEvent & interruptEvent)360 void TonePlayerPrivate::OnInterrupt(const InterruptEvent &interruptEvent)
361 {
362 AUDIO_INFO_LOG("OnInterrupt eventType: %{public}d", interruptEvent.eventType);
363 }
364
OnWriteData(size_t length)365 void TonePlayerPrivate::OnWriteData(size_t length)
366 {
367 AUDIO_DEBUG_LOG("OnWriteData Cbk: %{public}zu", length);
368 AudioToneRendererCallback();
369 }
370
OnStateChange(const RendererState state,const StateChangeCmdType cmdType)371 void TonePlayerPrivate::OnStateChange(const RendererState state,
372 const StateChangeCmdType __attribute__((unused)) cmdType)
373 {
374 AUDIO_INFO_LOG("OnStateChange Cbk: %{public}d not calling", state);
375 if (state == RENDERER_RUNNING || state == RENDERER_STOPPED) {
376 AUDIO_INFO_LOG("OnStateChange state: %{public}d", state);
377 }
378 }
379
CheckToneStopped()380 bool TonePlayerPrivate::CheckToneStopped()
381 {
382 AUDIO_DEBUG_LOG("CheckToneStopped state: %{public}d tot: %{public}d max: %{public}d not calling",
383 tonePlayerState_, totalSample_, maxSample_);
384 std::shared_ptr<ToneInfo> toneDesc = toneInfo_;
385 if (tonePlayerState_ == TONE_PLAYER_STOPPED) {
386 return true;
387 }
388 if (toneDesc->segments[currSegment_].duration == 0 ||
389 totalSample_ > maxSample_ || tonePlayerState_ == TONE_PLAYER_STOPPING) {
390 if (tonePlayerState_ == TONE_PLAYER_PLAYING) {
391 tonePlayerState_ = TONE_PLAYER_STOPPING;
392 AUDIO_DEBUG_LOG("Audicallback move playing to stoping");
393 }
394 return true;
395 }
396 return false;
397 }
398
CheckToneStarted(uint32_t reqSample,int8_t * audioBuffer)399 bool TonePlayerPrivate::CheckToneStarted(uint32_t reqSample, int8_t *audioBuffer)
400 {
401 std::shared_ptr<ToneInfo> toneDesc = toneInfo_;
402 if (tonePlayerState_ == TONE_PLAYER_STARTING) {
403 tonePlayerState_ = TONE_PLAYER_PLAYING;
404 AUDIO_DEBUG_LOG("Audicallback move to playing");
405 if (toneDesc->segments[currSegment_].duration != 0) {
406 sampleCount_ = 0;
407 GetSamples(toneDesc->segments[currSegment_].waveFreq, audioBuffer, reqSample);
408 }
409 AUDIO_DEBUG_LOG("CheckToneStarted GenerateStartWave to currseg: %{public}d ", currSegment_);
410 return true;
411 }
412 return false;
413 }
414
GetCurrentSegmentUpdated(std::shared_ptr<ToneInfo> toneDesc)415 void TonePlayerPrivate::GetCurrentSegmentUpdated(std::shared_ptr<ToneInfo> toneDesc)
416 {
417 if (toneDesc->segments[currSegment_].loopCnt) {
418 if (loopCounter_ < toneDesc->segments[currSegment_].loopCnt) {
419 currSegment_ = toneDesc->segments[currSegment_].loopIndx;
420 ++loopCounter_;
421 } else {
422 // completed loop. go to next segment
423 loopCounter_ = 0;
424 currSegment_++;
425 }
426 } else {
427 // no looping required , go to next segment
428 currSegment_++;
429 }
430 AUDIO_INFO_LOG("GetCurrentSegmentUpdated loopCounter_: %{public}d, currSegment_: %{public}d",
431 loopCounter_, currSegment_);
432 }
433
CheckToneContinuity()434 bool TonePlayerPrivate::CheckToneContinuity()
435 {
436 AUDIO_INFO_LOG("CheckToneContinuity Entry loopCounter_: %{public}d, currSegment_: %{public}d",
437 loopCounter_, currSegment_);
438 bool retVal = false;
439 std::shared_ptr<ToneInfo> toneDesc = toneInfo_;
440 GetCurrentSegmentUpdated(toneDesc);
441
442 // Handle loop if last segment reached
443 if (toneDesc->segments[currSegment_].duration == 0) {
444 AUDIO_DEBUG_LOG("Last Seg: %{public}d", currSegment_);
445 if (currCount_ < toneDesc->repeatCnt) {
446 currSegment_ = toneDesc->repeatSegment;
447 ++currCount_;
448 retVal = true;
449 } else {
450 retVal = false;
451 }
452 } else {
453 retVal = true;
454 }
455 AUDIO_DEBUG_LOG("CheckToneContinuity End loopCounter_: %{public}d, currSegment_: %{public}d currCount_: %{public}d",
456 loopCounter_, currSegment_, currCount_);
457 return retVal;
458 }
459
ContinueToneplay(uint32_t reqSample,int8_t * audioBuffer)460 bool TonePlayerPrivate::ContinueToneplay(uint32_t reqSample, int8_t *audioBuffer)
461 {
462 std::shared_ptr<ToneInfo> toneDesc = toneInfo_;
463 if (tonePlayerState_ != TONE_PLAYER_PLAYING) {
464 return false;
465 }
466 if (playWait_) {
467 waitAudioCbkCond_.notify_all();
468 AUDIO_INFO_LOG("tonePlayerState_ is TONE_PLAYER_PLAYING waitAudioCbkCond_ notify_all");
469 }
470 if (totalSample_ <= nextSegSample_) {
471 if (toneDesc->segments[currSegment_].duration != 0) {
472 GetSamples(toneDesc->segments[currSegment_].waveFreq, audioBuffer, reqSample);
473 }
474 return true;
475 }
476 AUDIO_DEBUG_LOG(" Current Seg Last minute Playing Tone");
477
478 if (CheckToneContinuity()) {
479 if (toneDesc->segments[currSegment_].duration != 0) {
480 sampleCount_ = 0;
481 GetSamples(toneDesc->segments[currSegment_].waveFreq, audioBuffer, reqSample);
482 }
483 }
484 nextSegSample_
485 += (toneDesc->segments[currSegment_].duration * samplingRate_) / C1000MS;
486 AUDIO_INFO_LOG("ContinueToneplay nextSegSample_: %{public}d", nextSegSample_);
487 return true;
488 }
489
AudioToneRendererCallback()490 void TonePlayerPrivate::AudioToneRendererCallback()
491 {
492 std::unique_lock<std::mutex> lock(dataCondLock_);
493 if (toneDataState_ == TONE_DATA_LOADED) {
494 AUDIO_DEBUG_LOG("Notifing Data AudioToneRendererCallback");
495 waitToneDataCond_.notify_all();
496 }
497 if (toneDataState_ == TONE_DATA_LOADING) {
498 toneDataState_ = TONE_DATA_REQUESTED;
499 waitToneDataCond_.wait_for(lock, std::chrono::seconds(CMAXWAIT));
500 }
501 AUDIO_INFO_LOG("AudioToneRendererCallback Exited");
502 }
503
AudioToneSequenceGen(BufferDesc & bufDesc)504 bool TonePlayerPrivate::AudioToneSequenceGen(BufferDesc &bufDesc)
505 {
506 int8_t *audioBuffer = (int8_t *)bufDesc.buffer;
507 uint32_t totalBufAvailable = bufDesc.bufLength / sizeof(int16_t);
508 bool retVal = true;
509 while (totalBufAvailable) {
510 uint32_t reqSamples = totalBufAvailable < processSize_ * CDOUBLE ? totalBufAvailable : processSize_;
511 bool lSignal = false;
512 AUDIO_DEBUG_LOG("AudioToneDataThreadFunc, lReqSmp: %{public}d totalBufAvailable: %{public}d",
513 reqSamples, totalBufAvailable);
514 mutexLock_.lock();
515 // Update pcm frame count and end time (current time at the end of this process)
516 totalSample_ += reqSamples;
517 if (CheckToneStopped()) {
518 if (tonePlayerState_ == TONE_PLAYER_STOPPING) {
519 tonePlayerState_ = TONE_PLAYER_STOPPED;
520 mutexLock_.unlock();
521 break;
522 }
523 if (tonePlayerState_ == TONE_PLAYER_STOPPED) {
524 tonePlayerState_ = TONE_PLAYER_INIT;
525 totalBufAvailable = 0;
526 bufDesc.dataLength = 0;
527 AUDIO_DEBUG_LOG("Notifing all the STOP");
528 mutexLock_.unlock();
529 waitAudioCbkCond_.notify_all();
530 mutexLock_.lock();
531 if (audioRenderer_ != nullptr) {
532 retVal = audioRenderer_->Stop();
533 } else {
534 AUDIO_ERR_LOG("AudioToneSequenceGen audioRenderer_ is null");
535 }
536 mutexLock_.unlock();
537 return false;
538 }
539 } else if (CheckToneStarted(reqSamples, audioBuffer)) {
540 bufDesc.dataLength += reqSamples * sizeof(int16_t);
541 lSignal = true;
542 } else {
543 if (ContinueToneplay(reqSamples, audioBuffer)) {
544 bufDesc.dataLength += reqSamples * sizeof(int16_t);
545 }
546 }
547 totalBufAvailable -= reqSamples;
548 audioBuffer += reqSamples * sizeof(int16_t);
549 mutexLock_.unlock();
550 if (lSignal) {
551 AUDIO_INFO_LOG("Notifing all the start");
552 waitAudioCbkCond_.notify_all();
553 }
554 }
555 return retVal;
556 }
557
AudioToneDataThreadFunc()558 void TonePlayerPrivate::AudioToneDataThreadFunc()
559 {
560 while (true) {
561 std::unique_lock<std::mutex> lock(dataCondLock_);
562 if (toneDataState_ == TONE_DATA_LOADING) {
563 toneDataState_ = TONE_DATA_LOADED;
564 waitToneDataCond_.wait_for(lock, std::chrono::seconds(CMAXWAIT));
565 }
566
567 BufferDesc bufDesc = {};
568 mutexLock_.lock();
569 if (audioRenderer_ != nullptr) {
570 audioRenderer_->GetBufferDesc(bufDesc);
571 } else {
572 AUDIO_ERR_LOG("AudioToneDataThreadFunc audioRenderer_ is null");
573 }
574 mutexLock_.unlock();
575 std::shared_ptr<ToneInfo> lpToneDesc = toneInfo_;
576 bufDesc.dataLength = 0;
577 AUDIO_DEBUG_LOG("AudioToneDataThreadFunc, tonePlayerState_: %{public}d", tonePlayerState_);
578 if (bufDesc.bufLength == 0) {
579 AUDIO_DEBUG_LOG("notify bufDesc bufLength is 0");
580 waitAudioCbkCond_.notify_all();
581 return;
582 }
583
584 // Clear output buffer: WaveGenerator accumulates into audioBuffer buffer
585 memset_s(bufDesc.buffer, bufDesc.bufLength, 0, bufDesc.bufLength);
586 if (AudioToneSequenceGen(bufDesc) == false) {
587 return;
588 }
589 AUDIO_INFO_LOG("Exiting the AudioToneDataThreadFunc: %{public}zu,tonePlayerState_: %{public}d",
590 bufDesc.dataLength, tonePlayerState_);
591 if (bufDesc.dataLength) {
592 #ifdef DUMPFILE
593 size_t writeResult = fwrite((void*)bufDesc.buffer, 1, bufDesc.dataLength, pfd_);
594 if (writeResult != bufDesc.dataLength) {
595 AUDIO_ERR_LOG("Failed to write the file.");
596 }
597 #endif // DUMPFILE
598 mutexLock_.lock();
599 if (tonePlayerState_ == TONE_PLAYER_STOPPED) {
600 AUDIO_INFO_LOG("Notifing tone player STOP");
601 tonePlayerState_ = TONE_PLAYER_INIT;
602 mutexLock_.unlock();
603 waitAudioCbkCond_.notify_all();
604 return;
605 }
606 mutexLock_.unlock();
607 mutexLock_.lock();
608 if (audioRenderer_ != nullptr) {
609 audioRenderer_->Enqueue(bufDesc);
610 } else {
611 AUDIO_ERR_LOG("AudioToneDataThreadFunc Enqueue audioRenderer_ is null");
612 }
613 mutexLock_.unlock();
614 if (toneDataState_ == TONE_DATA_REQUESTED) {
615 AUDIO_INFO_LOG("Notifing Data AudioToneDataThreadFunc");
616 waitToneDataCond_.notify_all();
617 }
618 toneDataState_ = TONE_DATA_LOADING;
619 }
620 }
621 }
622
InitToneWaveInfo()623 bool TonePlayerPrivate::InitToneWaveInfo()
624 {
625 AUDIO_INFO_LOG("InitToneWaveInfo, Entered");
626 if (initialToneInfo_ == NULL) {
627 return false;
628 }
629 toneInfo_ = initialToneInfo_;
630 maxSample_ = TONEINFO_INF;
631
632 // Initialize tone sequencer
633 totalSample_ = 0;
634 currSegment_ = 0;
635 currCount_ = 0;
636 loopCounter_ = 0;
637 if (toneInfo_->segments[0].duration == TONEINFO_INF) {
638 nextSegSample_ = TONEINFO_INF;
639 } else {
640 nextSegSample_ = (toneInfo_->segments[0].duration * samplingRate_) / C1000MS;
641 }
642 AUDIO_DEBUG_LOG("Prepare wave, nextSegSample_: %{public}d", nextSegSample_);
643 return true;
644 }
645
GetSamples(uint16_t * freqs,int8_t * buffer,uint32_t reqSamples)646 int32_t TonePlayerPrivate::GetSamples(uint16_t *freqs, int8_t *buffer, uint32_t reqSamples)
647 {
648 uint32_t index;
649 uint8_t *data;
650 uint16_t freqVal;
651 float pi = 3.1428f;
652 for (uint32_t i = 0; i <= TONEINFO_MAX_WAVES; i++) {
653 if (freqs[i] == 0) {
654 break;
655 }
656 freqVal = freqs[i];
657 AUDIO_DEBUG_LOG("GetSamples Freq: %{public}d sampleCount_: %{public}d", freqVal, sampleCount_);
658 index = sampleCount_;
659 data = (uint8_t*)buffer;
660 double factor = freqVal * 2 * pi / samplingRate_; // 2 is a parameter in the sine wave formula
661 for (uint32_t idx = 0; idx < reqSamples; idx++) {
662 int16_t sample = AMPLITUDE * sin(factor * index);
663 uint32_t result;
664 if (i == 0) {
665 result = (sample & 0xFF);
666 *data = result & 0xFF;
667 data++;
668 *data = ((sample & 0xFF00) >> BIT8);
669 data++;
670 } else {
671 result = *data + (sample & 0xFF);
672 *data = result & 0xFF;
673 data++;
674 *data += (result >> BIT8) + ((sample & 0xFF00) >> BIT8);
675 data++;
676 }
677 index++;
678 }
679 }
680 sampleCount_ += reqSamples;
681 return 0;
682 }
683 } // end namespace AudioStandard
684 } // end OHOS
685