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