1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 //#define LOG_NDEBUG 0 18 #define LOG_TAG "ToneGenerator" 19 20 #include <math.h> 21 #include <utils/Log.h> 22 #include <cutils/properties.h> 23 #include "media/ToneGenerator.h" 24 25 26 namespace android { 27 28 29 // Descriptors for all available tones (See ToneGenerator::ToneDescriptor class declaration for details) 30 const ToneGenerator::ToneDescriptor ToneGenerator::sToneDescriptors[] = { 31 { .segments = { { .duration = ToneGenerator::TONEGEN_INF, .waveFreq = { 1336, 941, 0 }, 0, 0}, 32 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 33 .repeatCnt = ToneGenerator::TONEGEN_INF, 34 .repeatSegment = 0 }, // TONE_DTMF_0 35 { .segments = { { .duration = ToneGenerator::TONEGEN_INF, .waveFreq = { 1209, 697, 0 }, 0, 0 }, 36 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 37 .repeatCnt = ToneGenerator::TONEGEN_INF, 38 .repeatSegment = 0 }, // TONE_DTMF_1 39 { .segments = { { .duration = ToneGenerator::TONEGEN_INF, .waveFreq = { 1336, 697, 0 }, 0, 0 }, 40 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 41 .repeatCnt = ToneGenerator::TONEGEN_INF, 42 .repeatSegment = 0 }, // TONE_DTMF_2 43 { .segments = { { .duration = ToneGenerator::TONEGEN_INF, .waveFreq = { 1477, 697, 0 }, 0, 0 }, 44 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 45 .repeatCnt = ToneGenerator::TONEGEN_INF, 46 .repeatSegment = 0 }, // TONE_DTMF_3 47 { .segments = { { .duration = ToneGenerator::TONEGEN_INF, .waveFreq = { 1209, 770, 0 }, 0, 0 }, 48 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 49 .repeatCnt = ToneGenerator::TONEGEN_INF, 50 .repeatSegment = 0 }, // TONE_DTMF_4 51 { .segments = { { .duration = ToneGenerator::TONEGEN_INF, .waveFreq = { 1336, 770, 0 }, 0, 0 }, 52 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 53 .repeatCnt = ToneGenerator::TONEGEN_INF, 54 .repeatSegment = 0 }, // TONE_DTMF_5 55 { .segments = { { .duration = ToneGenerator::TONEGEN_INF, .waveFreq = { 1477, 770, 0 }, 0, 0 }, 56 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 57 .repeatCnt = ToneGenerator::TONEGEN_INF, 58 .repeatSegment = 0 }, // TONE_DTMF_6 59 { .segments = { { .duration = ToneGenerator::TONEGEN_INF, .waveFreq = { 1209, 852, 0 }, 0, 0 }, 60 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 61 .repeatCnt = ToneGenerator::TONEGEN_INF, 62 .repeatSegment = 0 }, // TONE_DTMF_7 63 { .segments = { { .duration = ToneGenerator::TONEGEN_INF, .waveFreq = { 1336, 852, 0 }, 0, 0 }, 64 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 65 .repeatCnt = ToneGenerator::TONEGEN_INF, 66 .repeatSegment = 0 }, // TONE_DTMF_8 67 { .segments = { { .duration = ToneGenerator::TONEGEN_INF, .waveFreq = { 1477, 852, 0 }, 0, 0 }, 68 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 69 .repeatCnt = ToneGenerator::TONEGEN_INF, 70 .repeatSegment = 0 }, // TONE_DTMF_9 71 { .segments = { { .duration = ToneGenerator::TONEGEN_INF, .waveFreq = { 1209, 941, 0 }, 0, 0 }, 72 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 73 .repeatCnt = ToneGenerator::TONEGEN_INF, 74 .repeatSegment = 0 }, // TONE_DTMF_S 75 { .segments = { { .duration = ToneGenerator::TONEGEN_INF, .waveFreq = { 1477, 941, 0 }, 0, 0 }, 76 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 77 .repeatCnt = ToneGenerator::TONEGEN_INF, 78 .repeatSegment = 0 }, // TONE_DTMF_P 79 { .segments = { { .duration = ToneGenerator::TONEGEN_INF, .waveFreq = { 1633, 697, 0 }, 0, 0 }, 80 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 81 .repeatCnt = ToneGenerator::TONEGEN_INF, 82 .repeatSegment = 0 }, // TONE_DTMF_A 83 { .segments = { { .duration = ToneGenerator::TONEGEN_INF, .waveFreq = { 1633, 770, 0 }, 0, 0 }, 84 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 85 .repeatCnt = ToneGenerator::TONEGEN_INF, 86 .repeatSegment = 0 }, // TONE_DTMF_B 87 { .segments = { { .duration = ToneGenerator::TONEGEN_INF, .waveFreq = { 1633, 852, 0 }, 0, 0 }, 88 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 89 .repeatCnt = ToneGenerator::TONEGEN_INF, 90 .repeatSegment = 0 }, // TONE_DTMF_C 91 { .segments = { { .duration = ToneGenerator::TONEGEN_INF, .waveFreq = { 1633, 941, 0 }, 0, 0 }, 92 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 93 .repeatCnt = ToneGenerator::TONEGEN_INF, 94 .repeatSegment = 0 }, // TONE_DTMF_D 95 { .segments = { { .duration = ToneGenerator::TONEGEN_INF, .waveFreq = { 425, 0 }, 0, 0 }, 96 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 97 .repeatCnt = ToneGenerator::TONEGEN_INF, 98 .repeatSegment = 0 }, // TONE_SUP_DIAL 99 { .segments = { { .duration = 500 , .waveFreq = { 425, 0 }, 0, 0}, 100 { .duration = 500, .waveFreq = { 0 }, 0, 0}, 101 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 102 .repeatCnt = ToneGenerator::TONEGEN_INF, 103 .repeatSegment = 0 }, // TONE_SUP_BUSY 104 { .segments = { { .duration = 200, .waveFreq = { 425, 0 }, 0, 0 }, 105 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 106 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 107 .repeatCnt = ToneGenerator::TONEGEN_INF, 108 .repeatSegment = 0 }, // TONE_SUP_CONGESTION 109 { .segments = { { .duration = 200, .waveFreq = { 425, 0 }, 0, 0 }, 110 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 111 .repeatCnt = 0, 112 .repeatSegment = 0 }, // TONE_SUP_RADIO_ACK 113 { .segments = { { .duration = 200, .waveFreq = { 425, 0 }, 0, 0}, 114 { .duration = 200, .waveFreq = { 0 }, 0, 0}, 115 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 116 .repeatCnt = 2, 117 .repeatSegment = 0 }, // TONE_SUP_RADIO_NOTAVAIL 118 { .segments = { { .duration = 330, .waveFreq = { 950, 1400, 1800, 0 }, 0, 0}, 119 { .duration = 1000, .waveFreq = { 0 }, 0, 0}, 120 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 121 .repeatCnt = ToneGenerator::TONEGEN_INF, 122 .repeatSegment = 0 }, // TONE_SUP_ERROR 123 { .segments = { { .duration = 200, .waveFreq = { 425, 0 }, 0, 0 }, 124 { .duration = 600, .waveFreq = { 0 }, 0, 0 }, 125 { .duration = 200, .waveFreq = { 425, 0 }, 0, 0 }, 126 { .duration = 3000, .waveFreq = { 0 }, 0, 0 }, 127 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 128 .repeatCnt = ToneGenerator::TONEGEN_INF, 129 .repeatSegment = 0 }, // TONE_SUP_CALL_WAITING 130 { .segments = { { .duration = 1000, .waveFreq = { 425, 0 }, 0, 0 }, 131 { .duration = 4000, .waveFreq = { 0 }, 0, 0 }, 132 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 133 .repeatCnt = ToneGenerator::TONEGEN_INF, 134 .repeatSegment = 0 }, // TONE_SUP_RINGTONE 135 { .segments = { { .duration = 40, .waveFreq = { 400, 1200, 0 }, 0, 0 }, 136 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 137 .repeatCnt = 0, 138 .repeatSegment = 0 }, // TONE_PROP_BEEP 139 { .segments = { { .duration = 100, .waveFreq = { 1200, 0 }, 0, 0 }, 140 { .duration = 100, .waveFreq = { 0 }, 0, 0 }, 141 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 142 .repeatCnt = 1, 143 .repeatSegment = 0 }, // TONE_PROP_ACK 144 { .segments = { { .duration = 400, .waveFreq = { 300, 400, 500, 0 }, 0, 0 }, 145 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 146 .repeatCnt = 0, 147 .repeatSegment = 0 }, // TONE_PROP_NACK 148 { .segments = { { .duration = 200, .waveFreq = { 400, 1200, 0 }, 0, 0 }, 149 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 150 .repeatCnt = 0, 151 .repeatSegment = 0 }, // TONE_PROP_PROMPT 152 { .segments = { { .duration = 40, .waveFreq = { 400, 1200, 0 }, 0, 0 }, 153 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 154 { .duration = 40, .waveFreq = { 400, 1200, 0 }, 0, 0 }, 155 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 156 .repeatCnt = 0, 157 .repeatSegment = 0 }, // TONE_PROP_BEEP2 158 { .segments = { { .duration = 250, .waveFreq = { 440, 0 }, 0, 0 }, 159 { .duration = 250, .waveFreq = { 620, 0 }, 0, 0 }, 160 { .duration = 0 , .waveFreq = { 0 }, 0, 0 }}, 161 .repeatCnt = ToneGenerator::TONEGEN_INF, 162 .repeatSegment = 0 }, // TONE_SUP_INTERCEPT 163 { .segments = { { .duration = 250, .waveFreq = { 440, 0 }, 0, 0 }, 164 { .duration = 250, .waveFreq = { 620, 0 }, 0, 0 }, 165 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 166 .repeatCnt = 7, 167 .repeatSegment = 0 }, // TONE_SUP_INTERCEPT_ABBREV 168 { .segments = { { .duration = 250, .waveFreq = { 480, 620, 0 }, 0, 0 }, 169 { .duration = 250, .waveFreq = { 0 }, 0, 0 }, 170 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 171 .repeatCnt = 7, 172 .repeatSegment = 0 }, // TONE_SUP_CONGESTION_ABBREV 173 { .segments = { { .duration = 100, .waveFreq = { 350, 440, 0 }, 0, 0 }, 174 { .duration = 100, .waveFreq = { 0 }, 0, 0 }, 175 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 176 .repeatCnt = 2, 177 .repeatSegment = 0 }, // TONE_SUP_CONFIRM 178 { .segments = { { .duration = 100, .waveFreq = { 480, 0 }, 0, 0 }, 179 { .duration = 100, .waveFreq = { 0 }, 0, 0 }, 180 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 181 .repeatCnt = 3, 182 .repeatSegment = 0 }, // TONE_SUP_PIP 183 { .segments = {{ .duration = ToneGenerator::TONEGEN_INF, .waveFreq = { 425, 0 }, 0, 0}, 184 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 185 .repeatCnt = ToneGenerator::TONEGEN_INF, 186 .repeatSegment = 0 }, // TONE_CDMA_DIAL_TONE_LITE 187 { .segments = { { .duration = 2000, .waveFreq = { 440, 480, 0 }, 0, 0 }, 188 { .duration = 4000, .waveFreq = { 0 }, 0, 0 }, 189 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 190 .repeatCnt = ToneGenerator::TONEGEN_INF, 191 .repeatSegment = 0 }, // TONE_CDMA_NETWORK_USA_RINGBACK 192 { .segments = { { .duration = 250, .waveFreq = { 440, 0 }, 0, 0 }, 193 { .duration = 250, .waveFreq = { 620, 0 }, 0, 0 }, 194 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 195 .repeatCnt = ToneGenerator::TONEGEN_INF, 196 .repeatSegment = 0 }, // TONE_CDMA_INTERCEPT 197 { .segments = { { .duration = 250, .waveFreq = { 440, 0 }, 0, 0 }, 198 { .duration = 250, .waveFreq = { 620, 0 }, 0, 0 }, 199 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 200 .repeatCnt = 0, 201 .repeatSegment = 0 }, // TONE_CDMA_ABBR_INTERCEPT 202 { .segments = { { .duration = 250, .waveFreq = { 480, 620, 0 }, 0, 0 }, 203 { .duration = 250, .waveFreq = { 0 }, 0, 0 }, 204 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 205 .repeatCnt = ToneGenerator::TONEGEN_INF, 206 .repeatSegment = 0 }, // TONE_CDMA_REORDER 207 { .segments = { { .duration = 250, .waveFreq = { 480, 620, 0 }, 0, 0 }, 208 { .duration = 250, .waveFreq = { 0 }, 0, 0 }, 209 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 210 .repeatCnt = 7, 211 .repeatSegment = 0 }, // TONE_CDMA_ABBR_REORDER 212 { .segments = { { .duration = 500, .waveFreq = { 480, 620, 0 }, 0, 0 }, 213 { .duration = 500, .waveFreq = { 0 }, 0, 0 }, 214 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 215 .repeatCnt = ToneGenerator::TONEGEN_INF, 216 .repeatSegment = 0 }, // TONE_CDMA_NETWORK_BUSY 217 { .segments = { { .duration = 100, .waveFreq = { 350, 440, 0 }, 0, 0 }, 218 { .duration = 100, .waveFreq = { 0 }, 0, 0 }, 219 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 220 .repeatCnt = 2, 221 .repeatSegment = 0 }, // TONE_CDMA_CONFIRM 222 { .segments = { { .duration = 500, .waveFreq = { 660, 1000, 0 }, 0, 0 }, 223 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 224 .repeatCnt = 0, 225 .repeatSegment = 0 }, // TONE_CDMA_ANSWER 226 { .segments = { { .duration = 300, .waveFreq = { 440, 0 }, 0, 0 }, 227 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 228 .repeatCnt = 0, 229 .repeatSegment = 0 }, // TONE_CDMA_NETWORK_CALLWAITING 230 { .segments = { { .duration = 100, .waveFreq = { 480, 0 }, 0, 0 }, 231 { .duration = 100, .waveFreq = { 0 }, 0, 0 }, 232 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 233 .repeatCnt = 3, 234 .repeatSegment = 0 }, // TONE_CDMA_PIP 235 236 { .segments = { { .duration = 32, .waveFreq = { 2091, 0}, 0, 0 }, 237 { .duration = 64, .waveFreq = { 2556, 0}, 19, 0}, 238 { .duration = 32, .waveFreq = { 2091, 0}, 0, 0}, 239 { .duration = 48, .waveFreq = { 2556, 0}, 0, 0}, 240 { .duration = 4000, .waveFreq = { 0 }, 0, 0}, 241 { .duration = 0, .waveFreq = { 0 }, 0, 0}}, 242 .repeatCnt = 0, 243 .repeatSegment = 0 }, // TONE_CDMA_CALL_SIGNAL_ISDN_NORMAL 244 { .segments = { { .duration = 32, .waveFreq = { 2091, 0}, 0, 0 }, 245 { .duration = 64, .waveFreq = { 2556, 0}, 7, 0 }, 246 { .duration = 32, .waveFreq = { 2091, 0}, 0, 0 }, 247 { .duration = 400, .waveFreq = { 0 }, 0, 0 }, 248 { .duration = 32, .waveFreq = { 2091, 0}, 0, 0 }, 249 { .duration = 64, .waveFreq = { 2556, 0}, 7, 4 }, 250 { .duration = 32, .waveFreq = { 2091, 0}, 0, 0 }, 251 { .duration = 4000, .waveFreq = { 0 }, 0, 0 }, 252 { .duration = 0, .waveFreq = { 0 }, 0, 0 } }, 253 .repeatCnt = 0, 254 .repeatSegment = 0 }, // TONE_CDMA_CALL_SIGNAL_ISDN_INTERGROUP 255 { .segments = { { .duration = 32, .waveFreq = { 2091, 0}, 0, 0 }, 256 { .duration = 64, .waveFreq = { 2556, 0}, 3, 0 }, 257 { .duration = 16, .waveFreq = { 2091, 0}, 0, 0 }, 258 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 259 { .duration = 32, .waveFreq = { 2091, 0}, 0, 0 }, 260 { .duration = 64, .waveFreq = { 2556, 0}, 3, 4 }, 261 { .duration = 16, .waveFreq = { 2091, 0}, 0, 0 }, 262 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 263 { .duration = 0, .waveFreq = { 0 }, 0, 0 } }, 264 .repeatCnt = 0, 265 .repeatSegment = 0 }, // TONE_CDMA_CALL_SIGNAL_ISDN_SP_PRI 266 { .segments = { { .duration = 0, .waveFreq = { 0 }, 0, 0} }, 267 .repeatCnt = 0, 268 .repeatSegment = 0 }, // TONE_CDMA_CALL_SIGNAL_ISDN_PAT3 269 { .segments = { { .duration = 32, .waveFreq = { 2091, 0 }, 0, 0 }, 270 { .duration = 64, .waveFreq = { 2556, 0 }, 4, 0 }, 271 { .duration = 20, .waveFreq = { 2091, 0 }, 0, 0 }, 272 { .duration = 0, .waveFreq = { 0 } , 0, 0 } }, 273 .repeatCnt = 0, 274 .repeatSegment = 0 }, // TONE_CDMA_CALL_SIGNAL_ISDN_PING_RING 275 { .segments = { { .duration = 0, .waveFreq = { 0 }, 0, 0} }, 276 .repeatCnt = 0, 277 .repeatSegment = 0 }, // TONE_CDMA_CALL_SIGNAL_ISDN_PAT5 278 { .segments = { { .duration = 0, .waveFreq = { 0 }, 0, 0} }, 279 .repeatCnt = 0, 280 .repeatSegment = 0 }, // TONE_CDMA_CALL_SIGNAL_ISDN_PAT6 281 { .segments = { { .duration = 0, .waveFreq = { 0 }, 0, 0} }, 282 .repeatCnt = 0, 283 .repeatSegment = 0 }, // TONE_CDMA_CALL_SIGNAL_ISDN_PAT7 284 285 { .segments = { { .duration = 25, .waveFreq = { 3700, 0 }, 0, 0 }, 286 { .duration = 25, .waveFreq = { 4000, 0 }, 39, 0 }, 287 { .duration = 4000, .waveFreq = { 0 }, 0, 0 }, 288 { .duration = 0, .waveFreq = { 0 }, 0, 0 } }, 289 .repeatCnt = ToneGenerator::TONEGEN_INF, 290 .repeatSegment = 0 }, // TONE_CDMA_HIGH_L 291 { .segments = { { .duration = 25, .waveFreq = { 2600, 0 }, 0, 0 }, 292 { .duration = 25, .waveFreq = { 2900, 0 }, 39, 0 }, 293 { .duration = 4000, .waveFreq = { 0 }, 0, 0 }, 294 { .duration = 0, .waveFreq = { 0 }, 0, 0 } }, 295 .repeatCnt = ToneGenerator::TONEGEN_INF, 296 .repeatSegment = 0 }, // TONE_CDMA_MED_L 297 { .segments = { { .duration = 25, .waveFreq = { 1300, 0 }, 0, 0 }, 298 { .duration = 25, .waveFreq = { 1450, 0 }, 39, 0 }, 299 { .duration = 4000, .waveFreq = { 0 }, 0, 0 }, 300 { .duration = 0, .waveFreq = { 0 }, 0, 0 } }, 301 .repeatCnt = ToneGenerator::TONEGEN_INF, 302 .repeatSegment = 0 }, // TONE_CDMA_LOW_L 303 { .segments = { { .duration = 25, .waveFreq = { 3700, 0 }, 0, 0 }, 304 { .duration = 25, .waveFreq = { 4000, 0 }, 15, 0 }, 305 { .duration = 400, .waveFreq = { 0 }, 0, 0 }, 306 { .duration = 0, .waveFreq = { 0 }, 0, 0 } }, 307 .repeatCnt = ToneGenerator::TONEGEN_INF, 308 .repeatSegment = 0 }, // TONE_CDMA_HIGH_SS 309 { .segments = { { .duration = 25, .waveFreq = { 2600, 0 }, 0, 0 }, 310 { .duration = 25, .waveFreq = { 2900, 0 }, 15, 0 }, 311 { .duration = 400, .waveFreq = { 0 }, 0, 0 }, 312 { .duration = 0, .waveFreq = { 0 }, 0, 0 }}, 313 .repeatCnt = ToneGenerator::TONEGEN_INF, 314 .repeatSegment = 0 }, // TONE_CDMA_MED_SS 315 { .segments = { { .duration = 25, .waveFreq = { 1300, 0 }, 0, 0 }, 316 { .duration = 25, .waveFreq = { 1450, 0 }, 15, 0 }, 317 { .duration = 400, .waveFreq = { 0 }, 0, 0 }, 318 { .duration = 0, .waveFreq = { 0 }, 0, 0 }}, 319 .repeatCnt = ToneGenerator::TONEGEN_INF, 320 .repeatSegment = 0 }, // TONE_CDMA_LOW_SS 321 { .segments = { { .duration = 25, .waveFreq = { 3700, 0 }, 0, 0 }, 322 { .duration = 25, .waveFreq = { 4000, 0 }, 7, 0 }, 323 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 324 { .duration = 25, .waveFreq = { 3700, 0 }, 0, 0 }, 325 { .duration = 25, .waveFreq = { 4000, 0 }, 7, 3 }, 326 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 327 { .duration = 25, .waveFreq = { 3700, 0 }, 0, 0 }, 328 { .duration = 25, .waveFreq = { 4000, 0 }, 15, 6 }, 329 { .duration = 4000, .waveFreq = { 0 }, 0, 0 }, 330 { .duration = 0, .waveFreq = { 0 }, 0, 0 }}, 331 .repeatCnt = ToneGenerator::TONEGEN_INF, 332 .repeatSegment = 0 }, // TONE_CDMA_HIGH_SSL 333 { .segments = { { .duration = 25, .waveFreq = { 2600, 0 }, 0, 0 }, 334 { .duration = 25, .waveFreq = { 2900, 0 }, 7, 0 }, 335 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 336 { .duration = 25, .waveFreq = { 2600, 0 }, 0, 0 }, 337 { .duration = 25, .waveFreq = { 2900, 0 }, 7, 3 }, 338 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 339 { .duration = 25, .waveFreq = { 2600, 0 }, 0, 0 }, 340 { .duration = 25, .waveFreq = { 2900, 0 }, 15, 6 }, 341 { .duration = 4000, .waveFreq = { 0 }, 0, 0 }, 342 { .duration = 0, .waveFreq = { 0 }, 0, 0 }}, 343 .repeatCnt = ToneGenerator::TONEGEN_INF, 344 .repeatSegment = 0 }, // TONE_CDMA_MED_SSL 345 { .segments = { { .duration = 25, .waveFreq = { 1300, 0 }, 0, 0 }, 346 { .duration = 25, .waveFreq = { 1450, 0 }, 7, 0 }, 347 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 348 { .duration = 25, .waveFreq = { 1300, 0 }, 0, 0 }, 349 { .duration = 25, .waveFreq = { 1450, 0 }, 7, 3 }, 350 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 351 { .duration = 25, .waveFreq = { 1300, 0 }, 0, 0 }, 352 { .duration = 25, .waveFreq = { 1450, 0 }, 15, 6 }, 353 { .duration = 4000, .waveFreq = { 0 }, 0, 0 }, 354 { .duration = 0, .waveFreq = { 0 }, 0, 0 }}, 355 .repeatCnt = ToneGenerator::TONEGEN_INF, 356 .repeatSegment = 0 }, // TONE_CDMA_LOW_SSL 357 { .segments = { { .duration = 25, .waveFreq = { 3700, 0 }, 0, 0 }, 358 { .duration = 25, .waveFreq = { 4000, 0 }, 19, 0 }, 359 { .duration = 1000, .waveFreq = { 0 }, 0, 0 }, 360 { .duration = 25, .waveFreq = { 3700, 0 }, 0, 0 }, 361 { .duration = 25, .waveFreq = { 4000, 0 }, 19, 3 }, 362 { .duration = 3000, .waveFreq = { 0 }, 0, 0 }, 363 { .duration = 0, .waveFreq = { 0 }, 0, 0 }}, 364 .repeatCnt = ToneGenerator::TONEGEN_INF, 365 .repeatSegment = 0 }, // TONE_CDMA_HIGH_SS_2 366 { .segments = { { .duration = 25, .waveFreq = { 2600, 0 }, 0, 0 }, 367 { .duration = 25, .waveFreq = { 2900, 0 }, 19, 0 }, 368 { .duration = 1000, .waveFreq = { 0 }, 0, 0 }, 369 { .duration = 25, .waveFreq = { 2600, 0 }, 0, 0 }, 370 { .duration = 25, .waveFreq = { 2900, 0 }, 19, 3 }, 371 { .duration = 3000, .waveFreq = { 0 }, 0, 0 }, 372 { .duration = 0, .waveFreq = { 0 }, 0, 0 }}, 373 .repeatCnt = ToneGenerator::TONEGEN_INF, 374 .repeatSegment = 0 }, // TONE_CDMA_MED_SS_2 375 { .segments = { { .duration = 25, .waveFreq = { 1300, 0 }, 0, 0 }, 376 { .duration = 25, .waveFreq = { 1450, 0 }, 19, 0 }, 377 { .duration = 1000, .waveFreq = { 0 }, 0, 0 }, 378 { .duration = 25, .waveFreq = { 1300, 0 }, 0, 0 }, 379 { .duration = 25, .waveFreq = { 1450, 0 }, 19, 3 }, 380 { .duration = 3000, .waveFreq = { 0 }, 0, 0 }, 381 { .duration = 0, .waveFreq = { 0 }, 0, 0 }}, 382 .repeatCnt = ToneGenerator::TONEGEN_INF, 383 .repeatSegment = 0 }, // TONE_CDMA_LOW_SS_2 384 { .segments = { { .duration = 25, .waveFreq = { 3700, 0 }, 0, 0 }, 385 { .duration = 25, .waveFreq = { 4000, 0 }, 9, 0 }, 386 { .duration = 500, .waveFreq = { 0 }, 0, 0 }, 387 { .duration = 25, .waveFreq = { 3700, 0 }, 0, 0 }, 388 { .duration = 25, .waveFreq = { 4000, 0 }, 19, 3 }, 389 { .duration = 500, .waveFreq = { 0 }, 0, 0 }, 390 { .duration = 25, .waveFreq = { 3700, 0 }, 0, 0 }, 391 { .duration = 25, .waveFreq = { 4000, 0 }, 9, 6 }, 392 { .duration = 3000, .waveFreq = { 0 }, 0, 0 }, 393 { .duration = 0, .waveFreq = { 0 }, 0, 0 }}, 394 .repeatCnt = ToneGenerator::TONEGEN_INF, 395 .repeatSegment = 0 }, // TONE_CDMA_HIGH_SLS 396 { .segments = { { .duration = 25, .waveFreq = { 2600, 0 }, 0, 0 }, 397 { .duration = 25, .waveFreq = { 2900, 0 }, 9, 0 }, 398 { .duration = 500, .waveFreq = { 0 }, 0, 0 }, 399 { .duration = 25, .waveFreq = { 2600, 0 }, 0, 0 }, 400 { .duration = 25, .waveFreq = { 2900, 0 }, 19, 3 }, 401 { .duration = 500, .waveFreq = { 0 }, 0, 0 }, 402 { .duration = 25, .waveFreq = { 2600, 0 }, 0, 0 }, 403 { .duration = 25, .waveFreq = { 2900, 0 }, 9, 6 }, 404 { .duration = 3000, .waveFreq = { 0 }, 0, 0 }, 405 { .duration = 0, .waveFreq = { 0 }, 0, 0 }}, 406 .repeatCnt = ToneGenerator::TONEGEN_INF, 407 .repeatSegment = 0 }, // TONE_CDMA_MED_SLS 408 { .segments = { { .duration = 25, .waveFreq = { 1300, 0 }, 0, 0 }, 409 { .duration = 25, .waveFreq = { 1450, 0 }, 9, 0 }, 410 { .duration = 500, .waveFreq = { 0 }, 0, 0 }, 411 { .duration = 25, .waveFreq = { 1300, 0 }, 0, 0 }, 412 { .duration = 25, .waveFreq = { 1450, 0 }, 19, 3 }, 413 { .duration = 500, .waveFreq = { 0 }, 0, 0 }, 414 { .duration = 25, .waveFreq = { 1300, 0 }, 0, 0 }, 415 { .duration = 25, .waveFreq = { 1450, 0 }, 9, 6 }, 416 { .duration = 3000, .waveFreq = { 0 }, 0, 0 }, 417 { .duration = 0, .waveFreq = { 0 }, 0, 0 }}, 418 .repeatCnt = ToneGenerator::TONEGEN_INF, 419 .repeatSegment = 0 }, // TONE_CDMA_LOW_SLS 420 { .segments = { { .duration = 25, .waveFreq = { 3700, 0 }, 0, 0 }, 421 { .duration = 25, .waveFreq = { 4000, 0 }, 9, 0 }, 422 { .duration = 500, .waveFreq = { 0 }, 0, 0 }, 423 { .duration = 25, .waveFreq = { 3700, 0 }, 0, 0 }, 424 { .duration = 25, .waveFreq = { 4000, 0 }, 9, 3 }, 425 { .duration = 500, .waveFreq = { 0 }, 0, 0 }, 426 { .duration = 25, .waveFreq = { 3700, 0 }, 0, 0 }, 427 { .duration = 25, .waveFreq = { 4000, 0 }, 9, 6 }, 428 { .duration = 500, .waveFreq = { 0 }, 0, 0 }, 429 { .duration = 25, .waveFreq = { 3700, 0 }, 0, 0 }, 430 { .duration = 25, .waveFreq = { 4000, 0 }, 9, 9 }, 431 { .duration = 2500, .waveFreq = { 0 }, 0, 0 }, 432 { .duration = 0, .waveFreq = { 0 }, 0, 0 }}, 433 .repeatCnt = ToneGenerator::TONEGEN_INF, 434 .repeatSegment = 0 }, // TONE_CDMA_HIGH_S_X4 435 { .segments = { { .duration = 25, .waveFreq = { 2600, 0 }, 0, 0 }, 436 { .duration = 25, .waveFreq = { 2900, 0 }, 9, 0 }, 437 { .duration = 500, .waveFreq = { 0 }, 0, 0 }, 438 { .duration = 25, .waveFreq = { 2600, 0 }, 0, 0 }, 439 { .duration = 25, .waveFreq = { 2900, 0 }, 9, 3 }, 440 { .duration = 500, .waveFreq = { 0 }, 0, 0 }, 441 { .duration = 25, .waveFreq = { 2600, 0 }, 0, 0 }, 442 { .duration = 25, .waveFreq = { 2900, 0 }, 9, 6 }, 443 { .duration = 500, .waveFreq = { 0 }, 0, 0 }, 444 { .duration = 25, .waveFreq = { 2600, 0 }, 0, 0 }, 445 { .duration = 25, .waveFreq = { 2900, 0 }, 9, 9 }, 446 { .duration = 2500, .waveFreq = { 0 }, 0, 0 }, 447 { .duration = 0, .waveFreq = { 0 }, 0, 0 }}, 448 .repeatCnt = ToneGenerator::TONEGEN_INF, 449 .repeatSegment = 0 }, // TONE_CDMA_MED_S_X4 450 { .segments = { { .duration = 25, .waveFreq = { 1300, 0 }, 0, 0 }, 451 { .duration = 25, .waveFreq = { 1450, 0 }, 9, 0 }, 452 { .duration = 500, .waveFreq = { 0 }, 0, 0 }, 453 { .duration = 25, .waveFreq = { 1300, 0 }, 0, 0 }, 454 { .duration = 25, .waveFreq = { 1450, 0 }, 9, 3 }, 455 { .duration = 500, .waveFreq = { 0 }, 0, 0 }, 456 { .duration = 25, .waveFreq = { 1300, 0 }, 0, 0 }, 457 { .duration = 25, .waveFreq = { 1450, 0 }, 9, 6 }, 458 { .duration = 500, .waveFreq = { 0 }, 0, 0 }, 459 { .duration = 25, .waveFreq = { 1300, 0 }, 0, 0 }, 460 { .duration = 25, .waveFreq = { 1450, 0 }, 9, 9 }, 461 { .duration = 2500, .waveFreq = { 0 }, 0, 0 }, 462 { .duration = 0, .waveFreq = { 0 }, 0, 0 }}, 463 .repeatCnt = ToneGenerator::TONEGEN_INF, 464 .repeatSegment = 0 }, // TONE_CDMA_LOW_S_X4 465 { .segments = { { .duration = 25, .waveFreq = { 3700, 0 }, 0, 0 }, 466 { .duration = 25, .waveFreq = { 4000, 0 }, 19, 0 }, 467 { .duration = 2000, .waveFreq = { 0 }, 0, 0 }, 468 { .duration = 0, .waveFreq = { 0 }, 0, 0 }}, 469 .repeatCnt = ToneGenerator::TONEGEN_INF, 470 .repeatSegment = 0 }, // TONE_CDMA_HIGH_PBX_L 471 { .segments = { { .duration = 25, .waveFreq = { 2600, 0 }, 0, 0 }, 472 { .duration = 25, .waveFreq = { 2900, 0 }, 19, 0 }, 473 { .duration = 2000, .waveFreq = { 0 }, 0, 0 }, 474 { .duration = 0, .waveFreq = { 0 }, 0, 0 }}, 475 .repeatCnt = ToneGenerator::TONEGEN_INF, 476 .repeatSegment = 0 }, // TONE_CDMA_MED_PBX_L 477 { .segments = { { .duration = 25, .waveFreq = { 1300, 0 }, 0, 0 }, 478 { .duration = 25, .waveFreq = { 1450, 0 }, 19, 0 }, 479 { .duration = 2000, .waveFreq = { 0 }, 0, 0 }, 480 { .duration = 0, .waveFreq = { 0 }, 0, 0 }}, 481 .repeatCnt = ToneGenerator::TONEGEN_INF, 482 .repeatSegment = 0 }, // TONE_CDMA_LOW_PBX_L 483 { .segments = { { .duration = 25, .waveFreq = { 3700, 0 }, 0, 0 }, 484 { .duration = 25, .waveFreq = { 4000, 0 }, 7, 0 }, 485 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 486 { .duration = 25, .waveFreq = { 3700, 0 }, 0, 0 }, 487 { .duration = 25, .waveFreq = { 4000, 0 }, 7, 3 }, 488 { .duration = 2000, .waveFreq = { 0 }, 0, 0 }, 489 { .duration = 0, .waveFreq = { 0 }, 0, 0 }}, 490 .repeatCnt = ToneGenerator::TONEGEN_INF, 491 .repeatSegment = 0 }, // TONE_CDMA_HIGH_PBX_SS 492 { .segments = { { .duration = 25, .waveFreq = { 2600, 0 }, 0, 0 }, 493 { .duration = 25, .waveFreq = { 2900, 0 }, 7, 0 }, 494 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 495 { .duration = 25, .waveFreq = { 2600, 0 }, 0, 0 }, 496 { .duration = 25, .waveFreq = { 2900, 0 }, 7, 3 }, 497 { .duration = 2000, .waveFreq = { 0 }, 0, 0 }, 498 { .duration = 0, .waveFreq = { 0 }, 0, 0 }}, 499 .repeatCnt = ToneGenerator::TONEGEN_INF, 500 .repeatSegment = 0 }, // TONE_CDMA_MED_PBX_SS 501 { .segments = { { .duration = 25, .waveFreq = { 1300, 0 }, 0, 0 }, 502 { .duration = 25, .waveFreq = { 1450, 0 }, 7, 0 }, 503 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 504 { .duration = 25, .waveFreq = { 1300, 0 }, 0, 0 }, 505 { .duration = 25, .waveFreq = { 1450, 0 }, 7, 3 }, 506 { .duration = 2000, .waveFreq = { 0 }, 0, 0 }, 507 { .duration = 0, .waveFreq = { 0 }, 0, 0 }}, 508 .repeatCnt = ToneGenerator::TONEGEN_INF, 509 .repeatSegment = 0 }, // TONE_CDMA_LOW_PBX_SS 510 { .segments = { { .duration = 25, .waveFreq = { 3700, 0 }, 0, 0 }, 511 { .duration = 25, .waveFreq = { 4000, 0 }, 7, 0 }, 512 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 513 { .duration = 25, .waveFreq = { 3700, 0 }, 0, 0 }, 514 { .duration = 25, .waveFreq = { 4000, 0 }, 7, 3 }, 515 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 516 { .duration = 25, .waveFreq = { 3700, 0 }, 0, 0 }, 517 { .duration = 25, .waveFreq = { 4000, 0 }, 15, 6 }, 518 { .duration = 1000, .waveFreq = { 0 }, 0, 0 }, 519 { .duration = 0, .waveFreq = { 0 }, 0, 0 }}, 520 .repeatCnt = ToneGenerator::TONEGEN_INF, 521 .repeatSegment = 0 }, // TONE_CDMA_HIGH_PBX_SSL 522 { .segments = { { .duration = 25, .waveFreq = { 2600, 0 }, 0, 0 }, 523 { .duration = 25, .waveFreq = { 2900, 0 }, 7, 0 }, 524 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 525 { .duration = 25, .waveFreq = { 2600, 0 }, 0, 0 }, 526 { .duration = 25, .waveFreq = { 2900, 0 }, 7, 3 }, 527 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 528 { .duration = 25, .waveFreq = { 2600, 0 }, 0, 0 }, 529 { .duration = 25, .waveFreq = { 2900, 0 }, 15, 6 }, 530 { .duration = 1000, .waveFreq = { 0 }, 0, 0 }, 531 { .duration = 0, .waveFreq = { 0 }, 0, 0 }}, 532 .repeatCnt = ToneGenerator::TONEGEN_INF, 533 .repeatSegment = 0 }, // TONE_CDMA_MED_PBX_SSL 534 { .segments = { { .duration = 25, .waveFreq = { 1300, 0 }, 0, 0 }, 535 { .duration = 25, .waveFreq = { 1450, 0 }, 7, 0 }, 536 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 537 { .duration = 25, .waveFreq = { 1300, 0 }, 0, 0 }, 538 { .duration = 25, .waveFreq = { 1450, 0 }, 7, 3 }, 539 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 540 { .duration = 25, .waveFreq = { 1300, 0 }, 0, 0 }, 541 { .duration = 25, .waveFreq = { 1450, 0 }, 15, 6 }, 542 { .duration = 1000, .waveFreq = { 0 }, 0, 0 }, 543 { .duration = 0, .waveFreq = { 0 }, 0, 0 }}, 544 .repeatCnt = ToneGenerator::TONEGEN_INF, 545 .repeatSegment = 0 }, // TONE_CDMA_LOW_PBX_SSL 546 { .segments = { { .duration = 25, .waveFreq = { 3700, 0 }, 0, 0 }, 547 { .duration = 25, .waveFreq = { 4000, 0 }, 7, 0 }, 548 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 549 { .duration = 25, .waveFreq = { 3700, 0 }, 0, 0 }, 550 { .duration = 25, .waveFreq = { 4000, 0 }, 15, 3 }, 551 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 552 { .duration = 25, .waveFreq = { 3700, 0 }, 0, 0 }, 553 { .duration = 25, .waveFreq = { 4000, 0 }, 7, 6 }, 554 { .duration = 1000, .waveFreq = { 0 }, 0, 0 }, 555 { .duration = 0, .waveFreq = { 0 }, 0, 0 }}, 556 .repeatCnt = ToneGenerator::TONEGEN_INF, 557 .repeatSegment = 0 }, // TONE_CDMA_HIGH_PBX_SLS 558 { .segments = { { .duration = 25, .waveFreq = { 2600, 0 }, 0, 0 }, 559 { .duration = 25, .waveFreq = { 2900, 0 }, 7, 0 }, 560 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 561 { .duration = 25, .waveFreq = { 2600, 0 }, 0, 0 }, 562 { .duration = 25, .waveFreq = { 2900, 0 }, 15, 3 }, 563 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 564 { .duration = 25, .waveFreq = { 2600, 0 }, 0, 0 }, 565 { .duration = 25, .waveFreq = { 2900, 0 }, 7, 6 }, 566 { .duration = 1000, .waveFreq = { 0 }, 0, 0 }, 567 { .duration = 0, .waveFreq = { 0 }, 0, 0 }}, 568 .repeatCnt = ToneGenerator::TONEGEN_INF, 569 .repeatSegment = 0 }, // TONE_CDMA_MED_PBX_SLS 570 { .segments = { { .duration = 25, .waveFreq = { 1300, 0 }, 0, 0 }, 571 { .duration = 25, .waveFreq = { 1450, 0 }, 7, 0 }, 572 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 573 { .duration = 25, .waveFreq = { 1300, 0 }, 0, 0 }, 574 { .duration = 25, .waveFreq = { 1450, 0 }, 15, 3 }, 575 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 576 { .duration = 25, .waveFreq = { 1300, 0 }, 0, 0 }, 577 { .duration = 25, .waveFreq = { 1450, 0 }, 7, 6 }, 578 { .duration = 1000, .waveFreq = { 0 }, 0, 0 }, 579 { .duration = 0, .waveFreq = { 0 }, 0, 0 }}, 580 .repeatCnt = ToneGenerator::TONEGEN_INF, 581 .repeatSegment = 0 }, // TONE_CDMA_LOW_PBX_SLS 582 { .segments = { { .duration = 25, .waveFreq = { 3700, 0 }, 0, 0 }, 583 { .duration = 25, .waveFreq = { 4000, 0 }, 7, 0 }, 584 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 585 { .duration = 25, .waveFreq = { 3700, 0 }, 0, 0 }, 586 { .duration = 25, .waveFreq = { 4000, 0 }, 7, 3 }, 587 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 588 { .duration = 25, .waveFreq = { 3700, 0 }, 0, 0 }, 589 { .duration = 25, .waveFreq = { 4000, 0 }, 7, 6 }, 590 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 591 { .duration = 25, .waveFreq = { 3700, 0 }, 0, 0 }, 592 { .duration = 25, .waveFreq = { 4000, 0 }, 7, 9 }, 593 { .duration = 800, .waveFreq = { 0 }, 0, 0 }, 594 { .duration = 0, .waveFreq = { 0 }, 0, 0 }}, 595 .repeatCnt = ToneGenerator::TONEGEN_INF, 596 .repeatSegment = 0 }, // TONE_CDMA_HIGH_PBX_S_X4 597 { .segments = { { .duration = 25, .waveFreq = { 2600, 0 }, 0, 0 }, 598 { .duration = 25, .waveFreq = { 2900, 0 }, 7, 0 }, 599 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 600 { .duration = 25, .waveFreq = { 2600, 0 }, 0, 0 }, 601 { .duration = 25, .waveFreq = { 2900, 0 }, 7, 3 }, 602 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 603 { .duration = 25, .waveFreq = { 2600, 0 }, 0, 0 }, 604 { .duration = 25, .waveFreq = { 2900, 0 }, 7, 6 }, 605 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 606 { .duration = 25, .waveFreq = { 2600, 0 }, 0, 0 }, 607 { .duration = 25, .waveFreq = { 2900, 0 }, 7, 9 }, 608 { .duration = 800, .waveFreq = { 0 }, 0, 0 }, 609 { .duration = 0, .waveFreq = { 0 }, 0, 0 }}, 610 .repeatCnt = ToneGenerator::TONEGEN_INF, 611 .repeatSegment = 0 }, // TONE_CDMA_MED_PBX_S_X4 612 { .segments = { { .duration = 25, .waveFreq = { 1300, 0 }, 0, 0 }, 613 { .duration = 25, .waveFreq = { 1450, 0 }, 7, 0 }, 614 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 615 { .duration = 25, .waveFreq = { 1300, 0 }, 0, 0 }, 616 { .duration = 25, .waveFreq = { 1450, 0 }, 7, 3 }, 617 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 618 { .duration = 25, .waveFreq = { 1300, 0 }, 0, 0 }, 619 { .duration = 25, .waveFreq = { 1450, 0 }, 7, 6 }, 620 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 621 { .duration = 25, .waveFreq = { 1300, 0 }, 0, 0 }, 622 { .duration = 25, .waveFreq = { 1450, 0 }, 7, 9 }, 623 { .duration = 800, .waveFreq = { 0 }, 0, 0 }, 624 { .duration = 0, .waveFreq = { 0 }, 0, 0 }}, 625 .repeatCnt = ToneGenerator::TONEGEN_INF, 626 .repeatSegment = 0 }, // TONE_CDMA_LOW_PBX_S_X4 627 628 { .segments = { { .duration = 62, .waveFreq = { 1109, 0 }, 0, 0 }, 629 { .duration = 62, .waveFreq = { 784, 0 }, 0, 0 }, 630 { .duration = 62, .waveFreq = { 740, 0 }, 0, 0 }, 631 { .duration = 62, .waveFreq = { 622, 0 }, 0, 0 }, 632 { .duration = 62, .waveFreq = { 1109, 0 }, 0, 0 }, 633 { .duration = 0, .waveFreq = { 0 }, 0, 0 } }, 634 .repeatCnt = 0, 635 .repeatSegment = 0 }, // TONE_CDMA_ALERT_NETWORK_LITE 636 { .segments = { { .duration = 62, .waveFreq = { 1245, 0 }, 0, 0 }, 637 { .duration = 62, .waveFreq = { 659, 0 }, 2, 0 }, 638 { .duration = 62, .waveFreq = { 1245, 0 }, 0, 0 }, 639 { .duration = 0, .waveFreq = { 0 }, 0, 0 } }, 640 .repeatCnt = 0, 641 .repeatSegment = 0 }, // TONE_CDMA_ALERT_AUTOREDIAL_LITE 642 { .segments = { { .duration = 400, .waveFreq = { 1150, 770, 0 }, 0, 0 }, 643 { .duration = 0, .waveFreq = { 0 }, 0, 0 } }, 644 .repeatCnt = 0, 645 .repeatSegment = 0 }, // TONE_CDMA_ONE_MIN_BEEP 646 { .segments = { { .duration = 120, .waveFreq = { 941, 1477, 0 }, 0, 0 }, 647 { .duration = 0, .waveFreq = { 0 }, 0, 0 } }, 648 .repeatCnt = 0, 649 .repeatSegment = 0 }, // TONE_CDMA_KEYPAD_VOLUME_KEY_LITE 650 { .segments = { { .duration = 375, .waveFreq = { 587, 0 }, 0, 0 }, 651 { .duration = 125, .waveFreq = { 1175, 0 }, 0, 0 }, 652 { .duration = 0, .waveFreq = { 0 }, 0, 0 } }, 653 .repeatCnt = 0, 654 .repeatSegment = 0 }, // TONE_CDMA_PRESSHOLDKEY_LITE 655 { .segments = { { .duration = 62, .waveFreq = { 587, 0 }, 0, 0 }, 656 { .duration = 62, .waveFreq = { 784, 0 }, 0, 0 }, 657 { .duration = 62, .waveFreq = { 831, 0 }, 0, 0 }, 658 { .duration = 62, .waveFreq = { 784, 0 }, 0, 0 }, 659 { .duration = 62, .waveFreq = { 1109, 0 }, 0, 0 }, 660 { .duration = 62, .waveFreq = { 784, 0 }, 0, 0 }, 661 { .duration = 62, .waveFreq = { 831, 0 }, 0, 0 }, 662 { .duration = 62, .waveFreq = { 784, 0 }, 0, 0 }, 663 { .duration = 0, .waveFreq = { 0 }, 0, 0 } }, 664 .repeatCnt = 0, 665 .repeatSegment = 0 }, // TONE_CDMA_ALERT_INCALL_LITE 666 { .segments = { { .duration = 125, .waveFreq = { 941, 0 }, 0, 0 }, 667 { .duration = 10, .waveFreq = { 0 }, 2, 0 }, 668 { .duration = 4990, .waveFreq = { 0 }, 0, 0 }, 669 { .duration = 0, .waveFreq = { 0 }, 0, 0 } }, 670 .repeatCnt = ToneGenerator::TONEGEN_INF, 671 .repeatSegment = 0 }, // TONE_CDMA_EMERGENCY_RINGBACK 672 { .segments = { { .duration = 125, .waveFreq = { 1319, 0 }, 0, 0 }, 673 { .duration = 125, .waveFreq = { 0 }, 0, 0 }, 674 { .duration = 0, .waveFreq = { 0 }, 0, 0 } }, 675 .repeatCnt = 2, 676 .repeatSegment = 0 }, // TONE_CDMA_ALERT_CALL_GUARD 677 { .segments = { { .duration = 125, .waveFreq = { 1047, 0 }, 0, 0 }, 678 { .duration = 125, .waveFreq = { 370, 0 }, 0, 0 }, 679 { .duration = 0, .waveFreq = { 0 }, 0, 0 } }, 680 .repeatCnt = 0, 681 .repeatSegment = 0 }, // TONE_CDMA_SOFT_ERROR_LITE 682 { .segments = { { .duration = 125, .waveFreq = { 1480, 0 }, 0, 0 }, 683 { .duration = 125, .waveFreq = { 1397, 0 }, 0, 0 }, 684 { .duration = 125, .waveFreq = { 784, 0 }, 0, 0 }, 685 { .duration = 0, .waveFreq = { 0 }, 0, 0 } }, 686 .repeatCnt = 0, 687 .repeatSegment = 0 }, // TONE_CDMA_CALLDROP_LITE 688 689 { .segments = { { .duration = 500, .waveFreq = { 425, 0 }, 0, 0 }, 690 { .duration = 500, .waveFreq = { 0 }, 0, 0 }, 691 { .duration = 0, .waveFreq = { 0 }, 0, 0 }}, 692 .repeatCnt = 0, 693 .repeatSegment = 0 }, // TONE_CDMA_NETWORK_BUSY_ONE_SHOT 694 { .segments = { { .duration = 400, .waveFreq = { 1150, 770 }, 0, 0 }, 695 { .duration = 0, .waveFreq = { 0 }, 0, 0 }}, 696 .repeatCnt = 0, 697 .repeatSegment = 0 }, // TONE_CDMA_ABBR_ALERT 698 { .segments = { { .duration = 0, .waveFreq = { 0 }, 0, 0 }}, 699 .repeatCnt = 0, 700 .repeatSegment = 0 }, // TONE_CDMA_SIGNAL_OFF 701 702 { .segments = { { .duration = ToneGenerator::TONEGEN_INF, .waveFreq = { 350, 440, 0 }, 0, 0 }, 703 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 704 .repeatCnt = ToneGenerator::TONEGEN_INF, 705 .repeatSegment = 0 }, // TONE_ANSI_DIAL 706 { .segments = { { .duration = 500, .waveFreq = { 480, 620, 0 }, 0, 0 }, 707 { .duration = 500, .waveFreq = { 0 }, 0, 0 }, 708 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 709 .repeatCnt = ToneGenerator::TONEGEN_INF, 710 .repeatSegment = 0 }, // TONE_ANSI_BUSY 711 { .segments = { { .duration = 250, .waveFreq = { 480, 620, 0 }, 0, 0 }, 712 { .duration = 250, .waveFreq = { 0 }, 0, 0 }, 713 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 714 .repeatCnt = ToneGenerator::TONEGEN_INF, 715 .repeatSegment = 0 }, // TONE_ANSI_CONGESTION 716 { .segments = { { .duration = 300, .waveFreq = { 440, 0 }, 0, 0 }, 717 { .duration = 9700, .waveFreq = { 0 }, 0, 0 }, 718 { .duration = 100, .waveFreq = { 440, 0 }, 0, 0 }, 719 { .duration = 100, .waveFreq = { 0 }, 0, 0 }, 720 { .duration = 100, .waveFreq = { 440, 0 }, 0, 0 }, 721 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 722 .repeatCnt = ToneGenerator::TONEGEN_INF, 723 .repeatSegment = 1 }, // TONE_ANSI_CALL_WAITING 724 { .segments = { { .duration = 2000, .waveFreq = { 440, 480, 0 }, 0, 0 }, 725 { .duration = 4000, .waveFreq = { 0 }, 0, 0 }, 726 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 727 .repeatCnt = ToneGenerator::TONEGEN_INF, 728 .repeatSegment = 0 }, // TONE_ANSI_RINGTONE 729 { .segments = { { .duration = ToneGenerator::TONEGEN_INF, .waveFreq = { 400, 0 }, 0, 0 }, 730 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 731 .repeatCnt = ToneGenerator::TONEGEN_INF, 732 .repeatSegment = 0 }, // TONE_JAPAN_DIAL 733 { .segments = { { .duration = 500, .waveFreq = { 400, 0 }, 0, 0 }, 734 { .duration = 500, .waveFreq = { 0 }, 0, 0 }, 735 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 736 .repeatCnt = ToneGenerator::TONEGEN_INF, 737 .repeatSegment = 0 }, // TONE_JAPAN_BUSY 738 { .segments = { { .duration = 1000, .waveFreq = { 400, 0 }, 0, 0 }, 739 { .duration = 2000, .waveFreq = { 0 }, 0, 0 }, 740 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 741 .repeatCnt = ToneGenerator::TONEGEN_INF, 742 .repeatSegment = 0 }, // TONE_JAPAN_RADIO_ACK 743 { .segments = { { .duration = 375, .waveFreq = { 400, 0 }, 0, 0 }, 744 { .duration = 375, .waveFreq = { 0 }, 0, 0 }, 745 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 746 .repeatCnt = ToneGenerator::TONEGEN_INF, 747 .repeatSegment = 0 }, // TONE_GB_BUSY 748 { .segments = { { .duration = 400, .waveFreq = { 400, 0 }, 0, 0 }, 749 { .duration = 350, .waveFreq = { 0 }, 0, 0 }, 750 { .duration = 225, .waveFreq = { 400, 0 }, 0, 0 }, 751 { .duration = 525, .waveFreq = { 0 }, 0, 0 }, 752 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 753 .repeatCnt = ToneGenerator::TONEGEN_INF, 754 .repeatSegment = 0 }, // TONE_GB_CONGESTION 755 { .segments = { { .duration = 400, .waveFreq = { 400, 450, 0 }, 0, 0 }, 756 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 757 { .duration = 400, .waveFreq = { 400, 450, 0 }, 0, 0 }, 758 { .duration = 2000, .waveFreq = { 0 }, 0, 0}, 759 { .duration = 0, .waveFreq = { 0 }, 0, 0}}, 760 .repeatCnt = ToneGenerator::TONEGEN_INF, 761 .repeatSegment = 0 }, // TONE_GB_RINGTONE 762 { .segments = { { .duration = ToneGenerator::TONEGEN_INF, .waveFreq = { 400, 425, 450, 0 }, 0, 0 }, 763 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 764 .repeatCnt = ToneGenerator::TONEGEN_INF, 765 .repeatSegment = 0 }, // TONE_AUSTRALIA_DIAL 766 { .segments = { { .duration = 400, .waveFreq = { 400, 450, 0 }, 0, 0 }, 767 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 768 { .duration = 400, .waveFreq = { 400, 450, 0 }, 0, 0 }, 769 { .duration = 2000, .waveFreq = { 0 }, 0, 0}, 770 { .duration = 0, .waveFreq = { 0 }, 0, 0}}, 771 .repeatCnt = ToneGenerator::TONEGEN_INF, 772 .repeatSegment = 0 }, // TONE_AUSTRALIA_RINGTONE 773 { .segments = { { .duration = 375, .waveFreq = { 425, 0 }, 0, 0 }, 774 { .duration = 375, .waveFreq = { 0 }, 0, 0 }, 775 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 776 .repeatCnt = ToneGenerator::TONEGEN_INF, 777 .repeatSegment = 0 }, // TONE_AUSTRALIA_BUSY 778 { .segments = { { .duration = 200, .waveFreq = { 425, 0 }, 0, 0 }, 779 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 780 { .duration = 200, .waveFreq = { 425, 0 }, 0, 0 }, 781 { .duration = 4400, .waveFreq = { 0 }, 0, 0 }, 782 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 783 .repeatCnt = ToneGenerator::TONEGEN_INF, 784 .repeatSegment = 0 }, // TONE_AUSTRALIA_CALL_WAITING 785 { .segments = { { .duration = 375, .waveFreq = { 425, 0 }, 0, 0 }, 786 { .duration = 375, .waveFreq = { 0 }, 0, 0 }, 787 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 788 .repeatCnt = ToneGenerator::TONEGEN_INF, 789 .repeatSegment = 0 }, // TONE_AUSTRALIA_CONGESTION 790 { .segments = { { .duration = 750, .waveFreq = { 425, 0 }, 0, 0 }, 791 { .duration = 750, .waveFreq = { 0 }, 0, 0 }, 792 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 793 .repeatCnt = ToneGenerator::TONEGEN_INF, 794 .repeatSegment = 0 }, // TONE_SG_BUSY 795 { .segments = { { .duration = 400, .waveFreq = { 401, 425, 449, 0 }, 0, 0 }, 796 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 797 { .duration = 400, .waveFreq = { 401, 425, 449, 0 }, 0, 0 }, 798 { .duration = 2000, .waveFreq = { 0 }, 0, 0 }, 799 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 800 .repeatCnt = ToneGenerator::TONEGEN_INF, 801 .repeatSegment = 0 }, // TONE_SG_RINGTONE 802 { .segments = { { .duration = 500, .waveFreq = { 480, 620, 0 }, 0, 0 }, 803 { .duration = 500, .waveFreq = { 0 }, 0, 0 }, 804 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 805 .repeatCnt = ToneGenerator::TONEGEN_INF, 806 .repeatSegment = 0 }, // TONE_HK_BUSY 807 { .segments = { { .duration = 400, .waveFreq = { 440, 480, 0 }, 0, 0 }, 808 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 809 { .duration = 400, .waveFreq = { 440, 480, 0 }, 0, 0 }, 810 { .duration = 3000, .waveFreq = { 0 }, 0, 0 }, 811 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 812 .repeatCnt = ToneGenerator::TONEGEN_INF, 813 .repeatSegment = 0 }, // TONE_HK_RINGTONE 814 { .segments = { { .duration = 400, .waveFreq = { 400, 450, 0 }, 0, 0 }, 815 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 816 { .duration = 400, .waveFreq = { 400, 450, 0 }, 0, 0 }, 817 { .duration = 2000, .waveFreq = { 0 }, 0, 0}, 818 { .duration = 0, .waveFreq = { 0 }, 0, 0}}, 819 .repeatCnt = ToneGenerator::TONEGEN_INF, 820 .repeatSegment = 0 }, // TONE_IE_RINGTONE 821 { .segments = { { .duration = 180, .waveFreq = { 425, 0 }, 0, 0 }, 822 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 823 { .duration = 200, .waveFreq = { 425, 0 }, 0, 0 }, 824 { .duration = 4500, .waveFreq = { 0 }, 0, 0 }, 825 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 826 .repeatCnt = ToneGenerator::TONEGEN_INF, 827 .repeatSegment = 0 }, // TONE_IE_CALL_WAITING 828 { .segments = { { .duration = ToneGenerator::TONEGEN_INF, .waveFreq = { 375, 400, 425, 0 }, 0, 0 }, 829 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 830 .repeatCnt = ToneGenerator::TONEGEN_INF, 831 .repeatSegment = 0 }, // TONE_INDIA_DIAL 832 { .segments = { { .duration = 750, .waveFreq = { 400, 0 }, 0, 0 }, 833 { .duration = 750, .waveFreq = { 0 }, 0, 0 }, 834 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 835 .repeatCnt = ToneGenerator::TONEGEN_INF, 836 .repeatSegment = 0 }, // TONE_INDIA_BUSY 837 { .segments = { { .duration = 250, .waveFreq = { 400, 0 }, 0, 0 }, 838 { .duration = 250, .waveFreq = { 0 }, 0, 0 }, 839 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 840 .repeatCnt = ToneGenerator::TONEGEN_INF, 841 .repeatSegment = 0 }, // TONE_INDIA_CONGESTION 842 { .segments = { { .duration = 200, .waveFreq = { 400, 0 }, 0, 0 }, 843 { .duration = 100, .waveFreq = { 0 }, 0, 0 }, 844 { .duration = 200, .waveFreq = { 400, 0 }, 0, 0 }, 845 { .duration = 7500, .waveFreq = { 0 }, 0, 0 }, 846 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 847 .repeatCnt = ToneGenerator::TONEGEN_INF, 848 .repeatSegment = 0 }, // TONE_INDIA_CALL_WAITING 849 { .segments = { { .duration = 400, .waveFreq = { 375, 400, 425, 0 }, 0, 0 }, 850 { .duration = 200, .waveFreq = { 0 }, 0, 0 }, 851 { .duration = 400, .waveFreq = { 375, 400, 425, 0 }, 0, 0 }, 852 { .duration = 2000, .waveFreq = { 0 }, 0, 0 }, 853 { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, 854 .repeatCnt = ToneGenerator::TONEGEN_INF, 855 .repeatSegment = 0 }, // TONE_INDIA_RINGTONE 856 }; 857 858 // Used by ToneGenerator::getToneForRegion() to convert user specified supervisory tone type 859 // to actual tone for current region. 860 const unsigned char /*tone_type*/ ToneGenerator::sToneMappingTable[NUM_REGIONS-1][NUM_SUP_TONES] = { 861 { // ANSI 862 TONE_ANSI_DIAL, // TONE_SUP_DIAL 863 TONE_ANSI_BUSY, // TONE_SUP_BUSY 864 TONE_ANSI_CONGESTION, // TONE_SUP_CONGESTION 865 TONE_SUP_RADIO_ACK, // TONE_SUP_RADIO_ACK 866 TONE_SUP_RADIO_NOTAVAIL, // TONE_SUP_RADIO_NOTAVAIL 867 TONE_SUP_ERROR, // TONE_SUP_ERROR 868 TONE_ANSI_CALL_WAITING, // TONE_SUP_CALL_WAITING 869 TONE_ANSI_RINGTONE // TONE_SUP_RINGTONE 870 }, 871 { // JAPAN 872 TONE_JAPAN_DIAL, // TONE_SUP_DIAL 873 TONE_JAPAN_BUSY, // TONE_SUP_BUSY 874 TONE_SUP_CONGESTION, // TONE_SUP_CONGESTION 875 TONE_JAPAN_RADIO_ACK, // TONE_SUP_RADIO_ACK 876 TONE_SUP_RADIO_NOTAVAIL, // TONE_SUP_RADIO_NOTAVAIL 877 TONE_SUP_ERROR, // TONE_SUP_ERROR 878 TONE_SUP_CALL_WAITING, // TONE_SUP_CALL_WAITING 879 TONE_SUP_RINGTONE // TONE_SUP_RINGTONE 880 }, 881 { // GB 882 TONE_ANSI_DIAL, // TONE_SUP_DIAL 883 TONE_GB_BUSY, // TONE_SUP_BUSY 884 TONE_GB_CONGESTION, // TONE_SUP_CONGESTION 885 TONE_SUP_RADIO_ACK, // TONE_SUP_RADIO_ACK 886 TONE_SUP_RADIO_NOTAVAIL, // TONE_SUP_RADIO_NOTAVAIL 887 TONE_SUP_ERROR, // TONE_SUP_ERROR 888 TONE_SUP_CALL_WAITING, // TONE_SUP_CALL_WAITING 889 TONE_GB_RINGTONE // TONE_SUP_RINGTONE 890 }, 891 { // AUSTRALIA 892 TONE_AUSTRALIA_DIAL, // TONE_SUP_DIAL 893 TONE_AUSTRALIA_BUSY, // TONE_SUP_BUSY 894 TONE_AUSTRALIA_CONGESTION, // TONE_SUP_CONGESTION 895 TONE_SUP_RADIO_ACK, // TONE_SUP_RADIO_ACK 896 TONE_SUP_RADIO_NOTAVAIL, // TONE_SUP_RADIO_NOTAVAIL 897 TONE_SUP_ERROR, // TONE_SUP_ERROR 898 TONE_AUSTRALIA_CALL_WAITING,// TONE_SUP_CALL_WAITING 899 TONE_AUSTRALIA_RINGTONE // TONE_SUP_RINGTONE 900 }, 901 { // SINGAPORE 902 TONE_SUP_DIAL, // TONE_SUP_DIAL 903 TONE_SG_BUSY, // TONE_SUP_BUSY 904 TONE_SUP_CONGESTION, // TONE_SUP_CONGESTION 905 TONE_SUP_RADIO_ACK, // TONE_SUP_RADIO_ACK 906 TONE_SUP_RADIO_NOTAVAIL, // TONE_SUP_RADIO_NOTAVAIL 907 TONE_SUP_ERROR, // TONE_SUP_ERROR 908 TONE_SUP_CALL_WAITING, // TONE_SUP_CALL_WAITING 909 TONE_SG_RINGTONE // TONE_SUP_RINGTONE 910 }, 911 { // HONGKONG 912 TONE_SUP_DIAL, // TONE_SUP_DIAL 913 TONE_HK_BUSY, // TONE_SUP_BUSY 914 TONE_SUP_CONGESTION, // TONE_SUP_CONGESTION 915 TONE_SUP_RADIO_ACK, // TONE_SUP_RADIO_ACK 916 TONE_SUP_RADIO_NOTAVAIL, // TONE_SUP_RADIO_NOTAVAIL 917 TONE_SUP_ERROR, // TONE_SUP_ERROR 918 TONE_SUP_CALL_WAITING, // TONE_SUP_CALL_WAITING 919 TONE_HK_RINGTONE // TONE_SUP_RINGTONE 920 }, 921 { // IRELAND 922 TONE_SUP_DIAL, // TONE_SUP_DIAL 923 TONE_SUP_BUSY, // TONE_SUP_BUSY 924 TONE_SUP_CONGESTION, // TONE_SUP_CONGESTION 925 TONE_SUP_RADIO_ACK, // TONE_SUP_RADIO_ACK 926 TONE_SUP_RADIO_NOTAVAIL, // TONE_SUP_RADIO_NOTAVAIL 927 TONE_SUP_ERROR, // TONE_SUP_ERROR 928 TONE_IE_CALL_WAITING, // TONE_SUP_CALL_WAITING 929 TONE_IE_RINGTONE // TONE_SUP_RINGTONE 930 }, 931 { // INDIA 932 TONE_INDIA_DIAL, // TONE_SUP_DIAL 933 TONE_INDIA_BUSY, // TONE_SUP_BUSY 934 TONE_INDIA_CONGESTION, // TONE_SUP_CONGESTION 935 TONE_SUP_RADIO_ACK, // TONE_SUP_RADIO_ACK 936 TONE_SUP_RADIO_NOTAVAIL, // TONE_SUP_RADIO_NOTAVAIL 937 TONE_SUP_ERROR, // TONE_SUP_ERROR 938 TONE_INDIA_CALL_WAITING, // TONE_SUP_CALL_WAITING 939 TONE_INDIA_RINGTONE // TONE_SUP_RINGTONE 940 } 941 }; 942 943 944 //////////////////////////////////////////////////////////////////////////////// 945 // ToneGenerator class Implementation 946 //////////////////////////////////////////////////////////////////////////////// 947 948 949 //---------------------------------- public methods ---------------------------- 950 951 952 //////////////////////////////////////////////////////////////////////////////// 953 // 954 // Method: ToneGenerator::ToneGenerator() 955 // 956 // Description: Constructor. Initializes the tone sequencer, intantiates required sine wave 957 // generators, instantiates output audio track. 958 // 959 // Input: 960 // streamType: Type of stream used for tone playback 961 // volume: volume applied to tone (0.0 to 1.0) 962 // 963 // Output: 964 // none 965 // 966 //////////////////////////////////////////////////////////////////////////////// 967 ToneGenerator::ToneGenerator(audio_stream_type_t streamType, float volume, bool threadCanCallJava) { 968 969 ALOGV("ToneGenerator constructor: streamType=%d, volume=%f", streamType, volume); 970 971 mState = TONE_IDLE; 972 973 if (AudioSystem::getOutputSamplingRate(&mSamplingRate, streamType) != NO_ERROR) { 974 ALOGE("Unable to marshal AudioFlinger"); 975 return; 976 } 977 mThreadCanCallJava = threadCanCallJava; 978 mStreamType = streamType; 979 mVolume = volume; 980 mpToneDesc = NULL; 981 mpNewToneDesc = NULL; 982 // Generate tone by chunks of 20 ms to keep cadencing precision 983 mProcessSize = (mSamplingRate * 20) / 1000; 984 985 char value[PROPERTY_VALUE_MAX]; 986 if (property_get("gsm.operator.iso-country", value, "") == 0) { 987 property_get("gsm.sim.operator.iso-country", value, ""); 988 } 989 // If dual sim device has two SIM cards inserted and is not registerd to any network, 990 // "," is set to "gsm.operator.iso-country" prop. 991 // In this case, "gsm.sim.operator.iso-country" prop should be used. 992 if (strlen(value) == 1 && strstr(value, ",") != NULL) { 993 property_get("gsm.sim.operator.iso-country", value, ""); 994 } 995 996 if (strstr(value, "us") != NULL || 997 strstr(value, "ca") != NULL) { 998 mRegion = ANSI; 999 } else if (strstr(value, "jp") != NULL) { 1000 mRegion = JAPAN; 1001 } else if (strstr(value, "gb") != NULL) { 1002 mRegion = GB; 1003 } else if (strstr(value, "au") != NULL) { 1004 mRegion = AUSTRALIA; 1005 } else if (strstr(value, "sg") != NULL) { 1006 mRegion = SINGAPORE; 1007 } else if (strstr(value, "hk") != NULL) { 1008 mRegion = HONGKONG; 1009 } else if (strstr(value, "ie") != NULL) { 1010 mRegion = IRELAND; 1011 } else if (strstr(value, "in") != NULL) { 1012 mRegion = INDIA; 1013 } else { 1014 mRegion = CEPT; 1015 } 1016 1017 if (initAudioTrack()) { 1018 ALOGV("ToneGenerator INIT OK, time: %d", (unsigned int)(systemTime()/1000000)); 1019 } else { 1020 ALOGV("!!!ToneGenerator INIT FAILED!!!"); 1021 } 1022 } 1023 1024 1025 1026 1027 //////////////////////////////////////////////////////////////////////////////// 1028 // 1029 // Method: ToneGenerator::~ToneGenerator() 1030 // 1031 // Description: Destructor. Stop sound playback and delete audio track if 1032 // needed and delete sine wave generators. 1033 // 1034 // Input: 1035 // none 1036 // 1037 // Output: 1038 // none 1039 // 1040 //////////////////////////////////////////////////////////////////////////////// 1041 ToneGenerator::~ToneGenerator() { 1042 ALOGV("ToneGenerator destructor"); 1043 1044 if (mpAudioTrack != 0) { 1045 stopTone(); 1046 ALOGV("Delete Track: %p", mpAudioTrack.get()); 1047 mpAudioTrack.clear(); 1048 } 1049 clearWaveGens(); 1050 } 1051 1052 //////////////////////////////////////////////////////////////////////////////// 1053 // 1054 // Method: ToneGenerator::startTone() 1055 // 1056 // Description: Starts tone playback. 1057 // 1058 // Input: 1059 // toneType: Type of tone generated (values in enum tone_type) 1060 // durationMs: The tone duration in milliseconds. If the tone is limited in time by definition, 1061 // the actual duration will be the minimum of durationMs and the defined tone duration. 1062 // Ommiting or setting durationMs to -1 does not limit tone duration. 1063 // 1064 // Output: 1065 // none 1066 // 1067 //////////////////////////////////////////////////////////////////////////////// 1068 bool ToneGenerator::startTone(tone_type toneType, int durationMs) { 1069 bool lResult = false; 1070 status_t lStatus; 1071 1072 if (toneType >= NUM_TONES) 1073 return lResult; 1074 1075 toneType = getToneForRegion(toneType); 1076 if (toneType == TONE_CDMA_SIGNAL_OFF) { 1077 return true; 1078 } 1079 1080 if (mState == TONE_IDLE) { 1081 ALOGV("startTone: try to re-init AudioTrack"); 1082 if (!initAudioTrack()) { 1083 return lResult; 1084 } 1085 } 1086 1087 ALOGV("startTone toneType %d", toneType); 1088 1089 mLock.lock(); 1090 1091 // Get descriptor for requested tone 1092 mpNewToneDesc = &sToneDescriptors[toneType]; 1093 1094 mDurationMs = durationMs; 1095 1096 if (mState == TONE_STOPPED) { 1097 ALOGV("Start waiting for previous tone to stop"); 1098 lStatus = mWaitCbkCond.waitRelative(mLock, seconds(3)); 1099 if (lStatus != NO_ERROR) { 1100 ALOGE("--- start wait for stop timed out, status %d", lStatus); 1101 mState = TONE_IDLE; 1102 mLock.unlock(); 1103 return lResult; 1104 } 1105 } 1106 1107 if (mState == TONE_INIT) { 1108 if (prepareWave()) { 1109 ALOGV("Immediate start, time %d", (unsigned int)(systemTime()/1000000)); 1110 lResult = true; 1111 mState = TONE_STARTING; 1112 if (clock_gettime(CLOCK_MONOTONIC, &mStartTime) != 0) { 1113 mStartTime.tv_sec = 0; 1114 } 1115 mLock.unlock(); 1116 mpAudioTrack->start(); 1117 mLock.lock(); 1118 if (mState == TONE_STARTING) { 1119 ALOGV("Wait for start callback"); 1120 lStatus = mWaitCbkCond.waitRelative(mLock, seconds(3)); 1121 if (lStatus != NO_ERROR) { 1122 ALOGE("--- Immediate start timed out, status %d", lStatus); 1123 mState = TONE_IDLE; 1124 lResult = false; 1125 } 1126 } 1127 } else { 1128 mState = TONE_IDLE; 1129 } 1130 } else { 1131 ALOGV("Delayed start"); 1132 mState = TONE_RESTARTING; 1133 mStartTime.tv_sec = 0; 1134 lStatus = mWaitCbkCond.waitRelative(mLock, seconds(3)); 1135 if (lStatus == NO_ERROR) { 1136 if (mState != TONE_IDLE) { 1137 lResult = true; 1138 } 1139 ALOGV("cond received"); 1140 } else { 1141 ALOGE("--- Delayed start timed out, status %d", lStatus); 1142 mState = TONE_IDLE; 1143 } 1144 } 1145 mLock.unlock(); 1146 1147 ALOGV_IF(lResult, "Tone started, time %d", (unsigned int)(systemTime()/1000000)); 1148 ALOGW_IF(!lResult, "Tone start failed!!!, time %d", (unsigned int)(systemTime()/1000000)); 1149 1150 return lResult; 1151 } 1152 1153 //////////////////////////////////////////////////////////////////////////////// 1154 // 1155 // Method: ToneGenerator::stopTone() 1156 // 1157 // Description: Stops tone playback. 1158 // 1159 // Input: 1160 // none 1161 // 1162 // Output: 1163 // none 1164 // 1165 //////////////////////////////////////////////////////////////////////////////// 1166 void ToneGenerator::stopTone() { 1167 ALOGV("stopTone"); 1168 1169 mLock.lock(); 1170 if (mState != TONE_IDLE && mState != TONE_INIT) { 1171 if (mState == TONE_PLAYING || mState == TONE_STARTING || mState == TONE_RESTARTING) { 1172 struct timespec stopTime; 1173 // If the start time is valid, make sure that the number of audio samples produced 1174 // corresponds at least to the time between the start and stop commands. 1175 // This is needed in case of cold start of the output stream. 1176 if ((mStartTime.tv_sec != 0) && (clock_gettime(CLOCK_MONOTONIC, &stopTime) == 0)) { 1177 time_t sec = stopTime.tv_sec - mStartTime.tv_sec; 1178 auto nsec = stopTime.tv_nsec - mStartTime.tv_nsec; 1179 if (nsec < 0) { 1180 --sec; 1181 nsec += 1000000000; 1182 } 1183 1184 if ((sec + 1) > ((time_t)(INT_MAX / mSamplingRate))) { 1185 mMaxSmp = sec * mSamplingRate; 1186 } else { 1187 // mSamplingRate is always > 1000 1188 sec = sec * 1000 + nsec / 1000000; // duration in milliseconds 1189 mMaxSmp = (unsigned int)(((int64_t)sec * mSamplingRate) / 1000); 1190 } 1191 ALOGV("stopTone() forcing mMaxSmp to %d, total for far %d", mMaxSmp, mTotalSmp); 1192 } else { 1193 mState = TONE_STOPPING; 1194 } 1195 } 1196 ALOGV("waiting cond"); 1197 status_t lStatus = mWaitCbkCond.waitRelative(mLock, seconds(3)); 1198 if (lStatus == NO_ERROR) { 1199 // If the tone was restarted exit now before calling clearWaveGens(); 1200 if (mState != TONE_INIT) { 1201 mLock.unlock(); 1202 return; 1203 } 1204 ALOGV("track stop complete, time %d", (unsigned int)(systemTime()/1000000)); 1205 } else { 1206 ALOGE("--- Stop timed out"); 1207 mState = TONE_IDLE; 1208 mpAudioTrack->stop(); 1209 } 1210 clearWaveGens(); 1211 } 1212 1213 mLock.unlock(); 1214 } 1215 1216 //---------------------------------- private methods --------------------------- 1217 1218 1219 1220 1221 //////////////////////////////////////////////////////////////////////////////// 1222 // 1223 // Method: ToneGenerator::initAudioTrack() 1224 // 1225 // Description: Allocates and configures AudioTrack used for PCM output. 1226 // 1227 // Input: 1228 // none 1229 // 1230 // Output: 1231 // none 1232 // 1233 //////////////////////////////////////////////////////////////////////////////// 1234 bool ToneGenerator::initAudioTrack() { 1235 // Open audio track in mono, PCM 16bit, default sampling rate. 1236 mpAudioTrack = new AudioTrack(); 1237 ALOGV("AudioTrack(%p) created", mpAudioTrack.get()); 1238 1239 audio_attributes_t attr; 1240 audio_stream_type_t streamType = mStreamType; 1241 if (mStreamType == AUDIO_STREAM_VOICE_CALL) { 1242 streamType = AUDIO_STREAM_DTMF; 1243 } 1244 attr = AudioSystem::streamTypeToAttributes(streamType); 1245 1246 const size_t frameCount = mProcessSize; 1247 status_t status = mpAudioTrack->set( 1248 AUDIO_STREAM_DEFAULT, 1249 0, // sampleRate 1250 AUDIO_FORMAT_PCM_16_BIT, 1251 AUDIO_CHANNEL_OUT_MONO, 1252 frameCount, 1253 AUDIO_OUTPUT_FLAG_FAST, 1254 audioCallback, 1255 this, // user 1256 0, // notificationFrames 1257 0, // sharedBuffer 1258 mThreadCanCallJava, 1259 AUDIO_SESSION_ALLOCATE, 1260 AudioTrack::TRANSFER_CALLBACK, 1261 nullptr, 1262 AUDIO_UID_INVALID, 1263 -1, 1264 &attr); 1265 // Set caller name so it can be logged in destructor. 1266 // MediaMetricsConstants.h: AMEDIAMETRICS_PROP_CALLERNAME_VALUE_TONEGENERATOR 1267 mpAudioTrack->setCallerName("tonegenerator"); 1268 if (status != NO_ERROR) { 1269 ALOGE("AudioTrack(%p) set failed with error %d", mpAudioTrack.get(), status); 1270 mpAudioTrack.clear(); 1271 return false; 1272 } 1273 1274 mpAudioTrack->setVolume(mVolume); 1275 mState = TONE_INIT; 1276 return true; 1277 } 1278 1279 //////////////////////////////////////////////////////////////////////////////// 1280 // 1281 // Method: ToneGenerator::audioCallback() 1282 // 1283 // Description: AudioTrack callback implementation. Generates a block of 1284 // PCM samples 1285 // and manages tone generator sequencer: tones pulses, tone duration... 1286 // 1287 // Input: 1288 // user reference (pointer to our ToneGenerator) 1289 // info audio buffer descriptor 1290 // 1291 // Output: 1292 // returned value: always true. 1293 // 1294 //////////////////////////////////////////////////////////////////////////////// 1295 void ToneGenerator::audioCallback(int event, void* user, void *info) { 1296 1297 if (event != AudioTrack::EVENT_MORE_DATA) return; 1298 1299 AudioTrack::Buffer *buffer = static_cast<AudioTrack::Buffer *>(info); 1300 ToneGenerator *lpToneGen = static_cast<ToneGenerator *>(user); 1301 int16_t *lpOut = buffer->i16; 1302 unsigned int lNumSmp = buffer->size/sizeof(int16_t); 1303 const ToneDescriptor *lpToneDesc = lpToneGen->mpToneDesc; 1304 1305 if (buffer->size == 0) return; 1306 1307 1308 // Clear output buffer: WaveGenerator accumulates into lpOut buffer 1309 memset(lpOut, 0, buffer->size); 1310 1311 while (lNumSmp) { 1312 unsigned int lReqSmp = lNumSmp < lpToneGen->mProcessSize*2 ? lNumSmp : lpToneGen->mProcessSize; 1313 unsigned int lGenSmp; 1314 unsigned int lWaveCmd = WaveGenerator::WAVEGEN_CONT; 1315 bool lSignal = false; 1316 1317 lpToneGen->mLock.lock(); 1318 1319 1320 // Update pcm frame count and end time (current time at the end of this process) 1321 lpToneGen->mTotalSmp += lReqSmp; 1322 1323 // Update tone gen state machine and select wave gen command 1324 switch (lpToneGen->mState) { 1325 case TONE_PLAYING: 1326 lWaveCmd = WaveGenerator::WAVEGEN_CONT; 1327 break; 1328 case TONE_STARTING: 1329 ALOGV("Starting Cbk"); 1330 1331 lWaveCmd = WaveGenerator::WAVEGEN_START; 1332 break; 1333 case TONE_STOPPING: 1334 case TONE_RESTARTING: 1335 ALOGV("Stop/restart Cbk"); 1336 1337 lWaveCmd = WaveGenerator::WAVEGEN_STOP; 1338 lpToneGen->mNextSegSmp = TONEGEN_INF; // forced to skip state machine management below 1339 break; 1340 case TONE_STOPPED: 1341 ALOGV("Stopped Cbk"); 1342 goto audioCallback_EndLoop; 1343 default: 1344 ALOGV("Extra Cbk"); 1345 goto audioCallback_EndLoop; 1346 } 1347 1348 // Exit if tone sequence is over 1349 if (lpToneDesc->segments[lpToneGen->mCurSegment].duration == 0 || 1350 lpToneGen->mTotalSmp > lpToneGen->mMaxSmp) { 1351 if (lpToneGen->mState == TONE_PLAYING) { 1352 lpToneGen->mState = TONE_STOPPING; 1353 } 1354 if (lpToneDesc->segments[lpToneGen->mCurSegment].duration == 0) { 1355 goto audioCallback_EndLoop; 1356 } 1357 // fade out before stopping if maximum duration reached 1358 lWaveCmd = WaveGenerator::WAVEGEN_STOP; 1359 lpToneGen->mNextSegSmp = TONEGEN_INF; // forced to skip state machine management below 1360 } 1361 1362 if (lpToneGen->mTotalSmp > lpToneGen->mNextSegSmp) { 1363 // Time to go to next sequence segment 1364 1365 ALOGV("End Segment, time: %d", (unsigned int)(systemTime()/1000000)); 1366 1367 lGenSmp = lReqSmp; 1368 1369 // If segment, ON -> OFF transition : ramp volume down 1370 if (lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[0] != 0) { 1371 lWaveCmd = WaveGenerator::WAVEGEN_STOP; 1372 unsigned int lFreqIdx = 0; 1373 uint16_t lFrequency = lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[lFreqIdx]; 1374 1375 while (lFrequency != 0) { 1376 WaveGenerator *lpWaveGen = lpToneGen->mWaveGens.valueFor(lFrequency); 1377 lpWaveGen->getSamples(lpOut, lGenSmp, lWaveCmd); 1378 lFrequency = lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[++lFreqIdx]; 1379 } 1380 ALOGV("ON->OFF, lGenSmp: %d, lReqSmp: %d", lGenSmp, lReqSmp); 1381 } 1382 1383 // check if we need to loop and loop for the reqd times 1384 if (lpToneDesc->segments[lpToneGen->mCurSegment].loopCnt) { 1385 if (lpToneGen->mLoopCounter < lpToneDesc->segments[lpToneGen->mCurSegment].loopCnt) { 1386 ALOGV ("in if loop loopCnt(%d) loopctr(%d), CurSeg(%d)", 1387 lpToneDesc->segments[lpToneGen->mCurSegment].loopCnt, 1388 lpToneGen->mLoopCounter, 1389 lpToneGen->mCurSegment); 1390 lpToneGen->mCurSegment = lpToneDesc->segments[lpToneGen->mCurSegment].loopIndx; 1391 ++lpToneGen->mLoopCounter; 1392 } else { 1393 // completed loop. go to next segment 1394 lpToneGen->mLoopCounter = 0; 1395 lpToneGen->mCurSegment++; 1396 ALOGV ("in else loop loopCnt(%d) loopctr(%d), CurSeg(%d)", 1397 lpToneDesc->segments[lpToneGen->mCurSegment].loopCnt, 1398 lpToneGen->mLoopCounter, 1399 lpToneGen->mCurSegment); 1400 } 1401 } else { 1402 lpToneGen->mCurSegment++; 1403 ALOGV ("Goto next seg loopCnt(%d) loopctr(%d), CurSeg(%d)", 1404 lpToneDesc->segments[lpToneGen->mCurSegment].loopCnt, 1405 lpToneGen->mLoopCounter, 1406 lpToneGen->mCurSegment); 1407 1408 } 1409 1410 // Handle loop if last segment reached 1411 if (lpToneDesc->segments[lpToneGen->mCurSegment].duration == 0) { 1412 ALOGV("Last Seg: %d", lpToneGen->mCurSegment); 1413 1414 // Pre increment loop count and restart if total count not reached. Stop sequence otherwise 1415 if (++lpToneGen->mCurCount <= lpToneDesc->repeatCnt) { 1416 ALOGV("Repeating Count: %d", lpToneGen->mCurCount); 1417 1418 lpToneGen->mCurSegment = lpToneDesc->repeatSegment; 1419 if (lpToneDesc->segments[lpToneDesc->repeatSegment].waveFreq[0] != 0) { 1420 lWaveCmd = WaveGenerator::WAVEGEN_START; 1421 } 1422 1423 ALOGV("New segment %d, Next Time: %lld", lpToneGen->mCurSegment, 1424 ((long long)(lpToneGen->mNextSegSmp)*1000)/lpToneGen->mSamplingRate); 1425 1426 1427 } else { 1428 lGenSmp = 0; 1429 ALOGV("End repeat, time: %d", (unsigned int)(systemTime()/1000000)); 1430 } 1431 } else { 1432 ALOGV("New segment %d, Next Time: %lld", lpToneGen->mCurSegment, 1433 ((long long)(lpToneGen->mNextSegSmp)*1000)/lpToneGen->mSamplingRate); 1434 1435 if (lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[0] != 0) { 1436 // If next segment is not silent, OFF -> ON transition : reset wave generator 1437 lWaveCmd = WaveGenerator::WAVEGEN_START; 1438 1439 ALOGV("OFF->ON, lGenSmp: %d, lReqSmp: %d", lGenSmp, lReqSmp); 1440 } else { 1441 lGenSmp = 0; 1442 } 1443 } 1444 1445 // Update next segment transition position. No harm to do it also for last segment as lpToneGen->mNextSegSmp won't be used any more 1446 lpToneGen->mNextSegSmp 1447 += (lpToneDesc->segments[lpToneGen->mCurSegment].duration * lpToneGen->mSamplingRate) / 1000; 1448 1449 } else { 1450 // Inside a segment keep tone ON or OFF 1451 if (lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[0] == 0) { 1452 lGenSmp = 0; // If odd segment, tone is currently OFF 1453 } else { 1454 lGenSmp = lReqSmp; // If event segment, tone is currently ON 1455 } 1456 } 1457 1458 if (lGenSmp) { 1459 // If samples must be generated, call all active wave generators and acumulate waves in lpOut 1460 unsigned int lFreqIdx = 0; 1461 uint16_t lFrequency = lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[lFreqIdx]; 1462 1463 while (lFrequency != 0) { 1464 WaveGenerator *lpWaveGen = lpToneGen->mWaveGens.valueFor(lFrequency); 1465 lpWaveGen->getSamples(lpOut, lGenSmp, lWaveCmd); 1466 lFrequency = lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[++lFreqIdx]; 1467 } 1468 } 1469 1470 lNumSmp -= lReqSmp; 1471 lpOut += lReqSmp; 1472 1473 audioCallback_EndLoop: 1474 1475 switch (lpToneGen->mState) { 1476 case TONE_RESTARTING: 1477 ALOGV("Cbk restarting track"); 1478 if (lpToneGen->prepareWave()) { 1479 lpToneGen->mState = TONE_STARTING; 1480 if (clock_gettime(CLOCK_MONOTONIC, &lpToneGen->mStartTime) != 0) { 1481 lpToneGen->mStartTime.tv_sec = 0; 1482 } 1483 // must reload lpToneDesc as prepareWave() may change mpToneDesc 1484 lpToneDesc = lpToneGen->mpToneDesc; 1485 } else { 1486 ALOGW("Cbk restarting prepareWave() failed"); 1487 lpToneGen->mState = TONE_IDLE; 1488 lpToneGen->mpAudioTrack->stop(); 1489 // Force loop exit 1490 lNumSmp = 0; 1491 } 1492 lSignal = true; 1493 break; 1494 case TONE_STOPPING: 1495 ALOGV("Cbk Stopping"); 1496 lpToneGen->mState = TONE_STOPPED; 1497 // Force loop exit 1498 lNumSmp = 0; 1499 break; 1500 case TONE_STOPPED: 1501 lpToneGen->mState = TONE_INIT; 1502 ALOGV("Cbk Stopped track"); 1503 lpToneGen->mpAudioTrack->stop(); 1504 // Force loop exit 1505 lNumSmp = 0; 1506 buffer->size = 0; 1507 lSignal = true; 1508 break; 1509 case TONE_STARTING: 1510 ALOGV("Cbk starting track"); 1511 lpToneGen->mState = TONE_PLAYING; 1512 lSignal = true; 1513 break; 1514 case TONE_PLAYING: 1515 break; 1516 default: 1517 // Force loop exit 1518 lNumSmp = 0; 1519 buffer->size = 0; 1520 break; 1521 } 1522 1523 if (lSignal) 1524 lpToneGen->mWaitCbkCond.broadcast(); 1525 lpToneGen->mLock.unlock(); 1526 } 1527 } 1528 1529 1530 //////////////////////////////////////////////////////////////////////////////// 1531 // 1532 // Method: ToneGenerator::prepareWave() 1533 // 1534 // Description: Prepare wave generators and reset tone sequencer state machine. 1535 // mpNewToneDesc must have been initialized before calling this function. 1536 // Input: 1537 // none 1538 // 1539 // Output: 1540 // returned value: true if wave generators have been created, false otherwise 1541 // 1542 //////////////////////////////////////////////////////////////////////////////// 1543 bool ToneGenerator::prepareWave() { 1544 unsigned int segmentIdx = 0; 1545 1546 if (mpNewToneDesc == NULL) { 1547 return false; 1548 } 1549 1550 // Remove existing wave generators if any 1551 clearWaveGens(); 1552 1553 mpToneDesc = mpNewToneDesc; 1554 1555 if (mDurationMs == -1) { 1556 mMaxSmp = TONEGEN_INF; 1557 } else { 1558 if (mDurationMs > (int)(TONEGEN_INF / mSamplingRate)) { 1559 mMaxSmp = (mDurationMs / 1000) * mSamplingRate; 1560 } else { 1561 mMaxSmp = (mDurationMs * mSamplingRate) / 1000; 1562 } 1563 ALOGV("prepareWave, duration limited to %d ms", mDurationMs); 1564 } 1565 1566 while (mpToneDesc->segments[segmentIdx].duration) { 1567 // Get total number of sine waves: needed to adapt sine wave gain. 1568 unsigned int lNumWaves = numWaves(segmentIdx); 1569 unsigned int freqIdx = 0; 1570 unsigned int frequency = mpToneDesc->segments[segmentIdx].waveFreq[freqIdx]; 1571 while (frequency) { 1572 // Instantiate a wave generator if ot already done for this frequency 1573 if (mWaveGens.indexOfKey(frequency) == NAME_NOT_FOUND) { 1574 ToneGenerator::WaveGenerator *lpWaveGen = 1575 new ToneGenerator::WaveGenerator(mSamplingRate, 1576 frequency, 1577 TONEGEN_GAIN/lNumWaves); 1578 mWaveGens.add(frequency, lpWaveGen); 1579 } 1580 frequency = mpNewToneDesc->segments[segmentIdx].waveFreq[++freqIdx]; 1581 } 1582 segmentIdx++; 1583 } 1584 1585 // Initialize tone sequencer 1586 mTotalSmp = 0; 1587 mCurSegment = 0; 1588 mCurCount = 0; 1589 mLoopCounter = 0; 1590 if (mpToneDesc->segments[0].duration == TONEGEN_INF) { 1591 mNextSegSmp = TONEGEN_INF; 1592 } else{ 1593 mNextSegSmp = (mpToneDesc->segments[0].duration * mSamplingRate) / 1000; 1594 } 1595 1596 return true; 1597 } 1598 1599 1600 //////////////////////////////////////////////////////////////////////////////// 1601 // 1602 // Method: ToneGenerator::numWaves() 1603 // 1604 // Description: Count number of sine waves needed to generate a tone segment (e.g 2 for DTMF). 1605 // 1606 // Input: 1607 // segmentIdx tone segment index 1608 // 1609 // Output: 1610 // returned value: nummber of sine waves 1611 // 1612 //////////////////////////////////////////////////////////////////////////////// 1613 unsigned int ToneGenerator::numWaves(unsigned int segmentIdx) { 1614 unsigned int lCnt = 0; 1615 1616 if (mpToneDesc->segments[segmentIdx].duration) { 1617 while (mpToneDesc->segments[segmentIdx].waveFreq[lCnt]) { 1618 lCnt++; 1619 } 1620 lCnt++; 1621 } 1622 1623 return lCnt; 1624 } 1625 1626 1627 //////////////////////////////////////////////////////////////////////////////// 1628 // 1629 // Method: ToneGenerator::clearWaveGens() 1630 // 1631 // Description: Removes all wave generators. 1632 // 1633 // Input: 1634 // none 1635 // 1636 // Output: 1637 // none 1638 // 1639 //////////////////////////////////////////////////////////////////////////////// 1640 void ToneGenerator::clearWaveGens() { 1641 ALOGV("Clearing mWaveGens:"); 1642 1643 for (size_t lIdx = 0; lIdx < mWaveGens.size(); lIdx++) { 1644 delete mWaveGens.valueAt(lIdx); 1645 } 1646 mWaveGens.clear(); 1647 } 1648 1649 //////////////////////////////////////////////////////////////////////////////// 1650 // 1651 // Method: ToneGenerator::getToneForRegion() 1652 // 1653 // Description: Get correct ringtone type according to current region. 1654 // The corrected ring tone type is the tone descriptor index in sToneDescriptors[]. 1655 // 1656 // Input: 1657 // none 1658 // 1659 // Output: 1660 // none 1661 // 1662 //////////////////////////////////////////////////////////////////////////////// 1663 ToneGenerator::tone_type ToneGenerator::getToneForRegion(tone_type toneType) { 1664 tone_type regionTone; 1665 1666 if (mRegion == CEPT || toneType < FIRST_SUP_TONE || toneType > LAST_SUP_TONE) { 1667 regionTone = toneType; 1668 } else { 1669 regionTone = (tone_type) sToneMappingTable[mRegion][toneType - FIRST_SUP_TONE]; 1670 } 1671 1672 ALOGV("getToneForRegion, tone %d, region %d, regionTone %d", toneType, mRegion, regionTone); 1673 1674 return regionTone; 1675 } 1676 1677 1678 //////////////////////////////////////////////////////////////////////////////// 1679 // WaveGenerator::WaveGenerator class Implementation 1680 //////////////////////////////////////////////////////////////////////////////// 1681 1682 //---------------------------------- public methods ---------------------------- 1683 1684 //////////////////////////////////////////////////////////////////////////////// 1685 // 1686 // Method: WaveGenerator::WaveGenerator() 1687 // 1688 // Description: Constructor. 1689 // 1690 // Input: 1691 // samplingRate: Output sampling rate in Hz 1692 // frequency: Frequency of the sine wave to generate in Hz 1693 // volume: volume (0.0 to 1.0) 1694 // 1695 // Output: 1696 // none 1697 // 1698 //////////////////////////////////////////////////////////////////////////////// 1699 ToneGenerator::WaveGenerator::WaveGenerator(uint32_t samplingRate, 1700 uint16_t frequency, float volume) { 1701 double d0; 1702 double F_div_Fs; // frequency / samplingRate 1703 1704 F_div_Fs = frequency / (double)samplingRate; 1705 d0 = - (float)GEN_AMP * sin(2 * M_PI * F_div_Fs); 1706 mS2_0 = (int16_t)d0; 1707 mS1 = 0; 1708 mS2 = mS2_0; 1709 1710 mAmplitude_Q15 = (int16_t)(32767. * 32767. * volume / GEN_AMP); 1711 // take some margin for amplitude fluctuation 1712 if (mAmplitude_Q15 > 32500) 1713 mAmplitude_Q15 = 32500; 1714 1715 d0 = 32768.0 * cos(2 * M_PI * F_div_Fs); // Q14*2*cos() 1716 if (d0 > 32767) 1717 d0 = 32767; 1718 mA1_Q14 = (int16_t) d0; 1719 1720 ALOGV("WaveGenerator init, mA1_Q14: %d, mS2_0: %d, mAmplitude_Q15: %d", 1721 mA1_Q14, mS2_0, mAmplitude_Q15); 1722 } 1723 1724 //////////////////////////////////////////////////////////////////////////////// 1725 // 1726 // Method: WaveGenerator::~WaveGenerator() 1727 // 1728 // Description: Destructor. 1729 // 1730 // Input: 1731 // none 1732 // 1733 // Output: 1734 // none 1735 // 1736 //////////////////////////////////////////////////////////////////////////////// 1737 ToneGenerator::WaveGenerator::~WaveGenerator() { 1738 } 1739 1740 //////////////////////////////////////////////////////////////////////////////// 1741 // 1742 // Method: WaveGenerator::getSamples() 1743 // 1744 // Description: Generates count samples of a sine wave and accumulates 1745 // result in outBuffer. 1746 // 1747 // Input: 1748 // outBuffer: Output buffer where to accumulate samples. 1749 // count: number of samples to produce. 1750 // command: special action requested (see enum gen_command). 1751 // 1752 // Output: 1753 // none 1754 // 1755 //////////////////////////////////////////////////////////////////////////////// 1756 void ToneGenerator::WaveGenerator::getSamples(int16_t *outBuffer, 1757 unsigned int count, unsigned int command) { 1758 long lS1, lS2; 1759 long lA1, lAmplitude; 1760 long Sample; // current sample 1761 1762 // init local 1763 if (command == WAVEGEN_START) { 1764 lS1 = (long)0; 1765 lS2 = (long)mS2_0; 1766 } else { 1767 lS1 = mS1; 1768 lS2 = mS2; 1769 } 1770 lA1 = (long)mA1_Q14; 1771 lAmplitude = (long)mAmplitude_Q15; 1772 1773 if (command == WAVEGEN_STOP) { 1774 lAmplitude <<= 16; 1775 if (count == 0) { 1776 return; 1777 } 1778 long dec = lAmplitude/count; 1779 // loop generation 1780 while (count) { 1781 count--; 1782 Sample = ((lA1 * lS1) >> S_Q14) - lS2; 1783 // shift delay 1784 lS2 = lS1; 1785 lS1 = Sample; 1786 Sample = ((lAmplitude>>16) * Sample) >> S_Q15; 1787 *(outBuffer++) += (int16_t)Sample; // put result in buffer 1788 lAmplitude -= dec; 1789 } 1790 } else { 1791 // loop generation 1792 while (count) { 1793 count--; 1794 Sample = ((lA1 * lS1) >> S_Q14) - lS2; 1795 // shift delay 1796 lS2 = lS1; 1797 lS1 = Sample; 1798 Sample = (lAmplitude * Sample) >> S_Q15; 1799 *(outBuffer++) += (int16_t)Sample; // put result in buffer 1800 } 1801 } 1802 1803 // save status 1804 mS1 = lS1; 1805 mS2 = lS2; 1806 } 1807 1808 } // end namespace android 1809