• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 "tone.h"
17 
18 #include <thread>
19 
20 #include "telephony_log_wrapper.h"
21 
22 namespace OHOS {
23 namespace Telephony {
24 using AudioPlay = int32_t (AudioPlayer::*)(const std::string &, AudioStandard::AudioStreamType, PlayerType);
25 
Tone()26 Tone::Tone() : audioPlayer_(new (std::nothrow) AudioPlayer()) {}
27 
Tone(ToneDescriptor tone)28 Tone::Tone(ToneDescriptor tone) : audioPlayer_(new (std::nothrow) AudioPlayer())
29 {
30     currentToneDescriptor_ = tone;
31 }
32 
~Tone()33 Tone::~Tone()
34 {
35     if (audioPlayer_ != nullptr) {
36         delete audioPlayer_;
37         audioPlayer_ = nullptr;
38     }
39 }
40 
Init()41 void Tone::Init() {}
42 
Play()43 int32_t Tone::Play()
44 {
45     if (currentToneDescriptor_ == TONE_UNKNOWN) {
46         TELEPHONY_LOGE("tone descriptor unknown");
47         return CALL_ERR_AUDIO_UNKNOWN_TONE;
48     }
49     PlayerType playerType = PlayerType::TYPE_TONE;
50     if (IsDtmf(currentToneDescriptor_)) {
51         playerType = PlayerType::TYPE_DTMF;
52         if (!InitTonePlayer()) {
53             return TELEPHONY_ERROR;
54         }
55         std::thread play([&]() {
56             pthread_setname_np(pthread_self(), TONE_PLAY_THREAD);
57             dtmfTonePlayer_->StartTone();
58         });
59         play.detach();
60     } else {
61         AudioPlay audioPlay = &AudioPlayer::Play;
62         if (audioPlayer_ == nullptr) {
63             TELEPHONY_LOGE("audioPlayer_ is nullptr");
64             return TELEPHONY_ERR_LOCAL_PTR_NULL;
65         }
66         std::thread play(audioPlay, audioPlayer_,
67             GetToneDescriptorPath(currentToneDescriptor_), AudioStandard::AudioStreamType::STREAM_MUSIC, playerType);
68         pthread_setname_np(play.native_handle(), TONE_PLAY_THREAD);
69         play.detach();
70     }
71     return TELEPHONY_SUCCESS;
72 }
73 
Stop()74 int32_t Tone::Stop()
75 {
76     std::lock_guard<std::mutex> lock(mutex_);
77     if (currentToneDescriptor_ == TONE_UNKNOWN) {
78         TELEPHONY_LOGE("tone descriptor unknown");
79         return CALL_ERR_AUDIO_UNKNOWN_TONE;
80     }
81     PlayerType playerType = PlayerType::TYPE_TONE;
82     if (IsDtmf(currentToneDescriptor_)) {
83         playerType = PlayerType::TYPE_DTMF;
84         if (InitTonePlayer()) {
85             dtmfTonePlayer_->StopTone();
86             dtmfTonePlayer_->Release();
87         }
88     } else {
89         if (audioPlayer_ == nullptr) {
90             TELEPHONY_LOGE("audioPlayer_ is nullptr");
91             return TELEPHONY_ERR_LOCAL_PTR_NULL;
92         }
93         audioPlayer_->SetStop(playerType, true);
94     }
95     return TELEPHONY_SUCCESS;
96 }
97 
InitTonePlayer()98 bool Tone::InitTonePlayer()
99 {
100     using namespace OHOS::AudioStandard;
101     if (dtmfTonePlayer_ == nullptr) {
102         AudioRendererInfo rendererInfo = {};
103         rendererInfo.contentType = ContentType::CONTENT_TYPE_UNKNOWN;
104         rendererInfo.streamUsage = StreamUsage::STREAM_USAGE_DTMF;
105         rendererInfo.rendererFlags = 0;
106         dtmfTonePlayer_ = TonePlayer::Create(rendererInfo);
107         if (dtmfTonePlayer_ == nullptr) {
108             return false;
109         }
110         ToneType dtmfType = ConvertToneDescriptorToToneType(currentToneDescriptor_);
111         if (!dtmfTonePlayer_->LoadTone(dtmfType)) {
112             return false;
113         }
114     }
115     return true;
116 }
117 
ConvertDigitToTone(char digit)118 ToneDescriptor Tone::ConvertDigitToTone(char digit)
119 {
120     ToneDescriptor dtmf = ToneDescriptor::TONE_UNKNOWN;
121     switch (digit) {
122         case '0':
123             dtmf = ToneDescriptor::TONE_DTMF_CHAR_0;
124             break;
125         case '1':
126             dtmf = ToneDescriptor::TONE_DTMF_CHAR_1;
127             break;
128         case '2':
129             dtmf = ToneDescriptor::TONE_DTMF_CHAR_2;
130             break;
131         case '3':
132             dtmf = ToneDescriptor::TONE_DTMF_CHAR_3;
133             break;
134         case '4':
135             dtmf = ToneDescriptor::TONE_DTMF_CHAR_4;
136             break;
137         case '5':
138             dtmf = ToneDescriptor::TONE_DTMF_CHAR_5;
139             break;
140         case '6':
141             dtmf = ToneDescriptor::TONE_DTMF_CHAR_6;
142             break;
143         case '7':
144             dtmf = ToneDescriptor::TONE_DTMF_CHAR_7;
145             break;
146         case '8':
147             dtmf = ToneDescriptor::TONE_DTMF_CHAR_8;
148             break;
149         case '9':
150             dtmf = ToneDescriptor::TONE_DTMF_CHAR_9;
151             break;
152         case '*':
153             dtmf = ToneDescriptor::TONE_DTMF_CHAR_P;
154             break;
155         case '#':
156             dtmf = ToneDescriptor::TONE_DTMF_CHAR_W;
157             break;
158         default:
159             break;
160     }
161     return dtmf;
162 }
163 
ConvertToneDescriptorToToneType(ToneDescriptor tone)164 AudioStandard::ToneType Tone::ConvertToneDescriptorToToneType(ToneDescriptor tone)
165 {
166     using namespace OHOS::AudioStandard;
167     ToneType dtmf = ToneType::NUM_TONES;
168     switch (tone) {
169         case ToneDescriptor::TONE_DTMF_CHAR_0:
170             dtmf = ToneType::TONE_TYPE_DIAL_0;
171             break;
172         case ToneDescriptor::TONE_DTMF_CHAR_1:
173             dtmf = ToneType::TONE_TYPE_DIAL_1;
174             break;
175         case ToneDescriptor::TONE_DTMF_CHAR_2:
176             dtmf = ToneType::TONE_TYPE_DIAL_2;
177             break;
178         case ToneDescriptor::TONE_DTMF_CHAR_3:
179             dtmf = ToneType::TONE_TYPE_DIAL_3;
180             break;
181         case ToneDescriptor::TONE_DTMF_CHAR_4:
182             dtmf = ToneType::TONE_TYPE_DIAL_4;
183             break;
184         case ToneDescriptor::TONE_DTMF_CHAR_5:
185             dtmf = ToneType::TONE_TYPE_DIAL_5;
186             break;
187         case ToneDescriptor::TONE_DTMF_CHAR_6:
188             dtmf = ToneType::TONE_TYPE_DIAL_6;
189             break;
190         case ToneDescriptor::TONE_DTMF_CHAR_7:
191             dtmf = ToneType::TONE_TYPE_DIAL_7;
192             break;
193         case ToneDescriptor::TONE_DTMF_CHAR_8:
194             dtmf = ToneType::TONE_TYPE_DIAL_8;
195             break;
196         case ToneDescriptor::TONE_DTMF_CHAR_9:
197             dtmf = ToneType::TONE_TYPE_DIAL_9;
198             break;
199         case ToneDescriptor::TONE_DTMF_CHAR_P:
200             dtmf = ToneType::TONE_TYPE_DIAL_S;
201             break;
202         case ToneDescriptor::TONE_DTMF_CHAR_W:
203             dtmf = ToneType::TONE_TYPE_DIAL_P;
204             break;
205         default:
206             break;
207     }
208     return dtmf;
209 }
210 
IsDtmf(ToneDescriptor tone)211 bool Tone::IsDtmf(ToneDescriptor tone)
212 {
213     bool ret = false;
214     switch (tone) {
215         case ToneDescriptor::TONE_DTMF_CHAR_0:
216         case ToneDescriptor::TONE_DTMF_CHAR_1:
217         case ToneDescriptor::TONE_DTMF_CHAR_2:
218         case ToneDescriptor::TONE_DTMF_CHAR_3:
219         case ToneDescriptor::TONE_DTMF_CHAR_4:
220         case ToneDescriptor::TONE_DTMF_CHAR_5:
221         case ToneDescriptor::TONE_DTMF_CHAR_6:
222         case ToneDescriptor::TONE_DTMF_CHAR_7:
223         case ToneDescriptor::TONE_DTMF_CHAR_8:
224         case ToneDescriptor::TONE_DTMF_CHAR_9:
225         case ToneDescriptor::TONE_DTMF_CHAR_P:
226         case ToneDescriptor::TONE_DTMF_CHAR_W:
227             ret = true;
228             break;
229         default:
230             break;
231     }
232     return ret;
233 }
234 
GetToneDescriptorPath(ToneDescriptor tone)235 std::string Tone::GetToneDescriptorPath(ToneDescriptor tone)
236 {
237 #ifdef ABILITY_AUDIO_SUPPORT
238     return DelayedSingleton<AudioProxy>::GetInstance()->GetToneDescriptorPath(tone);
239 #endif
240     return DelayedSingleton<AudioProxy>::GetInstance()->GetDefaultTonePath();
241 }
242 
ReleaseRenderer()243 void Tone::ReleaseRenderer()
244 {
245     if (audioPlayer_ == nullptr) {
246         TELEPHONY_LOGE("audioPlayer_ is nullptr");
247         return;
248     }
249     audioPlayer_->ReleaseRenderer();
250 }
251 } // namespace Telephony
252 } // namespace OHOS