• 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     if (IsUseTonePlayer(currentToneDescriptor_)) {
50         TELEPHONY_LOGI("currentToneDescriptor = %{public}d", currentToneDescriptor_);
51         if (!InitTonePlayer()) {
52             return TELEPHONY_ERROR;
53         }
54         std::thread play([&]() {
55             pthread_setname_np(pthread_self(), TONE_PLAY_THREAD);
56             tonePlayer_->StartTone();
57         });
58         play.detach();
59     } else {
60         AudioPlay audioPlay = &AudioPlayer::Play;
61         if (audioPlayer_ == nullptr) {
62             TELEPHONY_LOGE("audioPlayer_ is nullptr");
63             return TELEPHONY_ERR_LOCAL_PTR_NULL;
64         }
65         std::thread play(audioPlay, audioPlayer_, GetToneDescriptorPath(currentToneDescriptor_),
66             AudioStandard::AudioStreamType::STREAM_MUSIC, PlayerType::TYPE_TONE);
67         pthread_setname_np(play.native_handle(), TONE_PLAY_THREAD);
68         play.detach();
69     }
70     return TELEPHONY_SUCCESS;
71 }
72 
Stop()73 int32_t Tone::Stop()
74 {
75     std::lock_guard<std::mutex> lock(mutex_);
76     if (currentToneDescriptor_ == TONE_UNKNOWN) {
77         TELEPHONY_LOGE("tone descriptor unknown");
78         return CALL_ERR_AUDIO_UNKNOWN_TONE;
79     }
80     if (IsUseTonePlayer(currentToneDescriptor_)) {
81         if (tonePlayer_ != nullptr) {
82             tonePlayer_->StopTone();
83             tonePlayer_->Release();
84         }
85     } else {
86         if (audioPlayer_ == nullptr) {
87             TELEPHONY_LOGE("audioPlayer_ is nullptr");
88             return TELEPHONY_ERR_LOCAL_PTR_NULL;
89         }
90         audioPlayer_->SetStop(PlayerType::TYPE_TONE, true);
91     }
92     return TELEPHONY_SUCCESS;
93 }
94 
InitTonePlayer()95 bool Tone::InitTonePlayer()
96 {
97     using namespace OHOS::AudioStandard;
98     if (tonePlayer_ == nullptr) {
99         StreamUsage streamUsage = GetStreamUsageByToneType(currentToneDescriptor_);
100         AudioRendererInfo rendererInfo = {};
101         rendererInfo.contentType = ContentType::CONTENT_TYPE_UNKNOWN;
102         rendererInfo.streamUsage = streamUsage;
103         rendererInfo.rendererFlags = 0;
104         tonePlayer_ = TonePlayer::Create(rendererInfo);
105         if (tonePlayer_ == nullptr) {
106             return false;
107         }
108         ToneType toneType = ConvertToneDescriptorToToneType(currentToneDescriptor_);
109         if (!tonePlayer_->LoadTone(toneType)) {
110             return false;
111         }
112     }
113     return true;
114 }
115 
ConvertDigitToTone(char digit)116 ToneDescriptor Tone::ConvertDigitToTone(char digit)
117 {
118     ToneDescriptor dtmf = ToneDescriptor::TONE_UNKNOWN;
119     switch (digit) {
120         case '0':
121             dtmf = ToneDescriptor::TONE_DTMF_CHAR_0;
122             break;
123         case '1':
124             dtmf = ToneDescriptor::TONE_DTMF_CHAR_1;
125             break;
126         case '2':
127             dtmf = ToneDescriptor::TONE_DTMF_CHAR_2;
128             break;
129         case '3':
130             dtmf = ToneDescriptor::TONE_DTMF_CHAR_3;
131             break;
132         case '4':
133             dtmf = ToneDescriptor::TONE_DTMF_CHAR_4;
134             break;
135         case '5':
136             dtmf = ToneDescriptor::TONE_DTMF_CHAR_5;
137             break;
138         case '6':
139             dtmf = ToneDescriptor::TONE_DTMF_CHAR_6;
140             break;
141         case '7':
142             dtmf = ToneDescriptor::TONE_DTMF_CHAR_7;
143             break;
144         case '8':
145             dtmf = ToneDescriptor::TONE_DTMF_CHAR_8;
146             break;
147         case '9':
148             dtmf = ToneDescriptor::TONE_DTMF_CHAR_9;
149             break;
150         case '*':
151             dtmf = ToneDescriptor::TONE_DTMF_CHAR_P;
152             break;
153         case '#':
154             dtmf = ToneDescriptor::TONE_DTMF_CHAR_W;
155             break;
156         default:
157             break;
158     }
159     return dtmf;
160 }
161 
ConvertToneDescriptorToToneType(ToneDescriptor tone)162 AudioStandard::ToneType Tone::ConvertToneDescriptorToToneType(ToneDescriptor tone)
163 {
164     using namespace OHOS::AudioStandard;
165     ToneType tonType = ToneType::NUM_TONES;
166     switch (tone) {
167         case ToneDescriptor::TONE_DTMF_CHAR_0:
168             tonType = ToneType::TONE_TYPE_DIAL_0;
169             break;
170         case ToneDescriptor::TONE_DTMF_CHAR_1:
171             tonType = ToneType::TONE_TYPE_DIAL_1;
172             break;
173         case ToneDescriptor::TONE_DTMF_CHAR_2:
174             tonType = ToneType::TONE_TYPE_DIAL_2;
175             break;
176         case ToneDescriptor::TONE_DTMF_CHAR_3:
177             tonType = ToneType::TONE_TYPE_DIAL_3;
178             break;
179         case ToneDescriptor::TONE_DTMF_CHAR_4:
180             tonType = ToneType::TONE_TYPE_DIAL_4;
181             break;
182         case ToneDescriptor::TONE_DTMF_CHAR_5:
183             tonType = ToneType::TONE_TYPE_DIAL_5;
184             break;
185         case ToneDescriptor::TONE_DTMF_CHAR_6:
186             tonType = ToneType::TONE_TYPE_DIAL_6;
187             break;
188         case ToneDescriptor::TONE_DTMF_CHAR_7:
189             tonType = ToneType::TONE_TYPE_DIAL_7;
190             break;
191         case ToneDescriptor::TONE_DTMF_CHAR_8:
192             tonType = ToneType::TONE_TYPE_DIAL_8;
193             break;
194         case ToneDescriptor::TONE_DTMF_CHAR_9:
195             tonType = ToneType::TONE_TYPE_DIAL_9;
196             break;
197         case ToneDescriptor::TONE_DTMF_CHAR_P:
198             tonType = ToneType::TONE_TYPE_DIAL_S;
199             break;
200         case ToneDescriptor::TONE_DTMF_CHAR_W:
201             tonType = ToneType::TONE_TYPE_DIAL_P;
202             break;
203         default:
204             tonType = ConvertCallToneDescriptorToToneType(tone);
205             break;
206     }
207     return tonType;
208 }
209 
ConvertCallToneDescriptorToToneType(ToneDescriptor tone)210 AudioStandard::ToneType Tone::ConvertCallToneDescriptorToToneType(ToneDescriptor tone)
211 {
212     using namespace OHOS::AudioStandard;
213     ToneType tonType = ToneType::NUM_TONES;
214     switch (tone) {
215         case ToneDescriptor::TONE_RINGBACK:
216             tonType = ToneType::TONE_TYPE_COMMON_SUPERVISORY_RINGTONE;
217             break;
218         case ToneDescriptor::TONE_WAITING:
219             tonType = ToneType::TONE_TYPE_COMMON_SUPERVISORY_CALL_WAITING;
220             break;
221         default:
222             break;
223     }
224     return tonType;
225 }
226 
GetStreamUsageByToneType(ToneDescriptor descriptor)227 AudioStandard::StreamUsage Tone::GetStreamUsageByToneType(ToneDescriptor descriptor)
228 {
229     AudioStandard::StreamUsage streamUsage = AudioStandard::StreamUsage::STREAM_USAGE_UNKNOWN;
230     switch (descriptor) {
231         case ToneDescriptor::TONE_DTMF_CHAR_0:
232         case ToneDescriptor::TONE_DTMF_CHAR_1:
233         case ToneDescriptor::TONE_DTMF_CHAR_2:
234         case ToneDescriptor::TONE_DTMF_CHAR_3:
235         case ToneDescriptor::TONE_DTMF_CHAR_4:
236         case ToneDescriptor::TONE_DTMF_CHAR_5:
237         case ToneDescriptor::TONE_DTMF_CHAR_6:
238         case ToneDescriptor::TONE_DTMF_CHAR_7:
239         case ToneDescriptor::TONE_DTMF_CHAR_8:
240         case ToneDescriptor::TONE_DTMF_CHAR_9:
241         case ToneDescriptor::TONE_DTMF_CHAR_P:
242         case ToneDescriptor::TONE_DTMF_CHAR_W:
243             streamUsage = AudioStandard::StreamUsage::STREAM_USAGE_DTMF;
244             break;
245         case ToneDescriptor::TONE_RINGBACK:
246         case ToneDescriptor::TONE_WAITING:
247             streamUsage = AudioStandard::StreamUsage::STREAM_USAGE_VOICE_COMMUNICATION;
248             break;
249         default:
250             break;
251     }
252     return streamUsage;
253 }
254 
IsUseTonePlayer(ToneDescriptor tone)255 bool Tone::IsUseTonePlayer(ToneDescriptor tone)
256 {
257     bool ret = false;
258     switch (tone) {
259         case ToneDescriptor::TONE_DTMF_CHAR_0:
260         case ToneDescriptor::TONE_DTMF_CHAR_1:
261         case ToneDescriptor::TONE_DTMF_CHAR_2:
262         case ToneDescriptor::TONE_DTMF_CHAR_3:
263         case ToneDescriptor::TONE_DTMF_CHAR_4:
264         case ToneDescriptor::TONE_DTMF_CHAR_5:
265         case ToneDescriptor::TONE_DTMF_CHAR_6:
266         case ToneDescriptor::TONE_DTMF_CHAR_7:
267         case ToneDescriptor::TONE_DTMF_CHAR_8:
268         case ToneDescriptor::TONE_DTMF_CHAR_9:
269         case ToneDescriptor::TONE_DTMF_CHAR_P:
270         case ToneDescriptor::TONE_DTMF_CHAR_W:
271             ret = true;
272             break;
273         case ToneDescriptor::TONE_RINGBACK:
274         case ToneDescriptor::TONE_WAITING:
275             ret = true;
276             break;
277         default:
278             break;
279     }
280     return ret;
281 }
282 
GetToneDescriptorPath(ToneDescriptor tone)283 std::string Tone::GetToneDescriptorPath(ToneDescriptor tone)
284 {
285 #ifdef ABILITY_AUDIO_SUPPORT
286     return DelayedSingleton<AudioProxy>::GetInstance()->GetToneDescriptorPath(tone);
287 #endif
288     return DelayedSingleton<AudioProxy>::GetInstance()->GetDefaultTonePath();
289 }
290 
ReleaseRenderer()291 void Tone::ReleaseRenderer()
292 {
293     if (audioPlayer_ == nullptr) {
294         TELEPHONY_LOGE("audioPlayer_ is nullptr");
295         return;
296     }
297     audioPlayer_->ReleaseRenderer();
298 }
299 } // namespace Telephony
300 } // namespace OHOS
301