• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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