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