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