• 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 #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