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