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 744 745 746 }; 747 748 // Used by ToneGenerator::getToneForRegion() to convert user specified supervisory tone type 749 // to actual tone for current region. 750 const unsigned char /*tone_type*/ ToneGenerator::sToneMappingTable[NUM_REGIONS-1][NUM_SUP_TONES] = { 751 { // ANSI 752 TONE_ANSI_DIAL, // TONE_SUP_DIAL 753 TONE_ANSI_BUSY, // TONE_SUP_BUSY 754 TONE_ANSI_CONGESTION, // TONE_SUP_CONGESTION 755 TONE_SUP_RADIO_ACK, // TONE_SUP_RADIO_ACK 756 TONE_SUP_RADIO_NOTAVAIL, // TONE_SUP_RADIO_NOTAVAIL 757 TONE_SUP_ERROR, // TONE_SUP_ERROR 758 TONE_ANSI_CALL_WAITING, // TONE_SUP_CALL_WAITING 759 TONE_ANSI_RINGTONE // TONE_SUP_RINGTONE 760 }, 761 { // JAPAN 762 TONE_JAPAN_DIAL, // TONE_SUP_DIAL 763 TONE_JAPAN_BUSY, // TONE_SUP_BUSY 764 TONE_SUP_CONGESTION, // TONE_SUP_CONGESTION 765 TONE_JAPAN_RADIO_ACK, // TONE_SUP_RADIO_ACK 766 TONE_SUP_RADIO_NOTAVAIL, // TONE_SUP_RADIO_NOTAVAIL 767 TONE_SUP_ERROR, // TONE_SUP_ERROR 768 TONE_SUP_CALL_WAITING, // TONE_SUP_CALL_WAITING 769 TONE_SUP_RINGTONE // TONE_SUP_RINGTONE 770 } 771 }; 772 773 774 //////////////////////////////////////////////////////////////////////////////// 775 // ToneGenerator class Implementation 776 //////////////////////////////////////////////////////////////////////////////// 777 778 779 //---------------------------------- public methods ---------------------------- 780 781 782 //////////////////////////////////////////////////////////////////////////////// 783 // 784 // Method: ToneGenerator::ToneGenerator() 785 // 786 // Description: Constructor. Initializes the tone sequencer, intantiates required sine wave 787 // generators, instantiates output audio track. 788 // 789 // Input: 790 // streamType: Type of stream used for tone playback 791 // volume: volume applied to tone (0.0 to 1.0) 792 // 793 // Output: 794 // none 795 // 796 //////////////////////////////////////////////////////////////////////////////// 797 ToneGenerator::ToneGenerator(audio_stream_type_t streamType, float volume, bool threadCanCallJava) { 798 799 ALOGV("ToneGenerator constructor: streamType=%d, volume=%f", streamType, volume); 800 801 mState = TONE_IDLE; 802 803 if (AudioSystem::getOutputSamplingRate(&mSamplingRate, streamType) != NO_ERROR) { 804 ALOGE("Unable to marshal AudioFlinger"); 805 return; 806 } 807 mThreadCanCallJava = threadCanCallJava; 808 mStreamType = streamType; 809 mVolume = volume; 810 mpToneDesc = NULL; 811 mpNewToneDesc = NULL; 812 // Generate tone by chunks of 20 ms to keep cadencing precision 813 mProcessSize = (mSamplingRate * 20) / 1000; 814 815 char value[PROPERTY_VALUE_MAX]; 816 property_get("gsm.operator.iso-country", value, ""); 817 if (strcmp(value,"us") == 0 || 818 strcmp(value,"ca") == 0) { 819 mRegion = ANSI; 820 } else if (strcmp(value,"jp") == 0) { 821 mRegion = JAPAN; 822 } else { 823 mRegion = CEPT; 824 } 825 826 if (initAudioTrack()) { 827 ALOGV("ToneGenerator INIT OK, time: %d", (unsigned int)(systemTime()/1000000)); 828 } else { 829 ALOGV("!!!ToneGenerator INIT FAILED!!!"); 830 } 831 } 832 833 834 835 836 //////////////////////////////////////////////////////////////////////////////// 837 // 838 // Method: ToneGenerator::~ToneGenerator() 839 // 840 // Description: Destructor. Stop sound playback and delete audio track if 841 // needed and delete sine wave generators. 842 // 843 // Input: 844 // none 845 // 846 // Output: 847 // none 848 // 849 //////////////////////////////////////////////////////////////////////////////// 850 ToneGenerator::~ToneGenerator() { 851 ALOGV("ToneGenerator destructor"); 852 853 if (mpAudioTrack != 0) { 854 stopTone(); 855 ALOGV("Delete Track: %p", mpAudioTrack.get()); 856 mpAudioTrack.clear(); 857 } 858 } 859 860 //////////////////////////////////////////////////////////////////////////////// 861 // 862 // Method: ToneGenerator::startTone() 863 // 864 // Description: Starts tone playback. 865 // 866 // Input: 867 // toneType: Type of tone generated (values in enum tone_type) 868 // durationMs: The tone duration in milliseconds. If the tone is limited in time by definition, 869 // the actual duration will be the minimum of durationMs and the defined tone duration. 870 // Ommiting or setting durationMs to -1 does not limit tone duration. 871 // 872 // Output: 873 // none 874 // 875 //////////////////////////////////////////////////////////////////////////////// 876 bool ToneGenerator::startTone(tone_type toneType, int durationMs) { 877 bool lResult = false; 878 status_t lStatus; 879 880 if ((toneType < 0) || (toneType >= NUM_TONES)) 881 return lResult; 882 883 toneType = getToneForRegion(toneType); 884 if (toneType == TONE_CDMA_SIGNAL_OFF) { 885 return true; 886 } 887 888 if (mState == TONE_IDLE) { 889 ALOGV("startTone: try to re-init AudioTrack"); 890 if (!initAudioTrack()) { 891 return lResult; 892 } 893 } 894 895 ALOGV("startTone"); 896 897 mLock.lock(); 898 899 // Get descriptor for requested tone 900 mpNewToneDesc = &sToneDescriptors[toneType]; 901 902 mDurationMs = durationMs; 903 904 if (mState == TONE_STOPPED) { 905 ALOGV("Start waiting for previous tone to stop"); 906 lStatus = mWaitCbkCond.waitRelative(mLock, seconds(3)); 907 if (lStatus != NO_ERROR) { 908 ALOGE("--- start wait for stop timed out, status %d", lStatus); 909 mState = TONE_IDLE; 910 mLock.unlock(); 911 return lResult; 912 } 913 } 914 915 if (mState == TONE_INIT) { 916 if (prepareWave()) { 917 ALOGV("Immediate start, time %d", (unsigned int)(systemTime()/1000000)); 918 lResult = true; 919 mState = TONE_STARTING; 920 if (clock_gettime(CLOCK_MONOTONIC, &mStartTime) != 0) { 921 mStartTime.tv_sec = 0; 922 } 923 mLock.unlock(); 924 mpAudioTrack->start(); 925 mLock.lock(); 926 if (mState == TONE_STARTING) { 927 ALOGV("Wait for start callback"); 928 lStatus = mWaitCbkCond.waitRelative(mLock, seconds(3)); 929 if (lStatus != NO_ERROR) { 930 ALOGE("--- Immediate start timed out, status %d", lStatus); 931 mState = TONE_IDLE; 932 lResult = false; 933 } 934 } 935 } else { 936 mState = TONE_IDLE; 937 } 938 } else { 939 ALOGV("Delayed start"); 940 mState = TONE_RESTARTING; 941 mStartTime.tv_sec = 0; 942 lStatus = mWaitCbkCond.waitRelative(mLock, seconds(3)); 943 if (lStatus == NO_ERROR) { 944 if (mState != TONE_IDLE) { 945 lResult = true; 946 } 947 ALOGV("cond received"); 948 } else { 949 ALOGE("--- Delayed start timed out, status %d", lStatus); 950 mState = TONE_IDLE; 951 } 952 } 953 mLock.unlock(); 954 955 ALOGV_IF(lResult, "Tone started, time %d", (unsigned int)(systemTime()/1000000)); 956 ALOGW_IF(!lResult, "Tone start failed!!!, time %d", (unsigned int)(systemTime()/1000000)); 957 958 return lResult; 959 } 960 961 //////////////////////////////////////////////////////////////////////////////// 962 // 963 // Method: ToneGenerator::stopTone() 964 // 965 // Description: Stops tone playback. 966 // 967 // Input: 968 // none 969 // 970 // Output: 971 // none 972 // 973 //////////////////////////////////////////////////////////////////////////////// 974 void ToneGenerator::stopTone() { 975 ALOGV("stopTone"); 976 977 mLock.lock(); 978 if (mState != TONE_IDLE && mState != TONE_INIT) { 979 if (mState == TONE_PLAYING || mState == TONE_STARTING || mState == TONE_RESTARTING) { 980 struct timespec stopTime; 981 // If the start time is valid, make sure that the number of audio samples produced 982 // corresponds at least to the time between the start and stop commands. 983 // This is needed in case of cold start of the output stream. 984 if ((mStartTime.tv_sec != 0) && (clock_gettime(CLOCK_MONOTONIC, &stopTime) == 0)) { 985 time_t sec = stopTime.tv_sec - mStartTime.tv_sec; 986 long nsec = stopTime.tv_nsec - mStartTime.tv_nsec; 987 long durationMs; 988 if (nsec < 0) { 989 --sec; 990 nsec += 1000000000; 991 } 992 993 if ((sec + 1) > ((long)(INT_MAX / mSamplingRate))) { 994 mMaxSmp = sec * mSamplingRate; 995 } else { 996 // mSamplingRate is always > 1000 997 sec = sec * 1000 + nsec / 1000000; // duration in milliseconds 998 mMaxSmp = (unsigned int)(((int64_t)sec * mSamplingRate) / 1000); 999 } 1000 ALOGV("stopTone() forcing mMaxSmp to %d, total for far %d", mMaxSmp, mTotalSmp); 1001 } else { 1002 mState = TONE_STOPPING; 1003 } 1004 } 1005 ALOGV("waiting cond"); 1006 status_t lStatus = mWaitCbkCond.waitRelative(mLock, seconds(3)); 1007 if (lStatus == NO_ERROR) { 1008 // If the tone was restarted exit now before calling clearWaveGens(); 1009 if (mState != TONE_INIT) { 1010 mLock.unlock(); 1011 return; 1012 } 1013 ALOGV("track stop complete, time %d", (unsigned int)(systemTime()/1000000)); 1014 } else { 1015 ALOGE("--- Stop timed out"); 1016 mState = TONE_IDLE; 1017 mpAudioTrack->stop(); 1018 } 1019 clearWaveGens(); 1020 } 1021 1022 mLock.unlock(); 1023 } 1024 1025 //---------------------------------- private methods --------------------------- 1026 1027 1028 1029 1030 //////////////////////////////////////////////////////////////////////////////// 1031 // 1032 // Method: ToneGenerator::initAudioTrack() 1033 // 1034 // Description: Allocates and configures AudioTrack used for PCM output. 1035 // 1036 // Input: 1037 // none 1038 // 1039 // Output: 1040 // none 1041 // 1042 //////////////////////////////////////////////////////////////////////////////// 1043 bool ToneGenerator::initAudioTrack() { 1044 1045 // Open audio track in mono, PCM 16bit, default sampling rate, default buffer size 1046 mpAudioTrack = new AudioTrack(); 1047 ALOGV("Create Track: %p", mpAudioTrack.get()); 1048 1049 mpAudioTrack->set(mStreamType, 1050 0, // sampleRate 1051 AUDIO_FORMAT_PCM_16_BIT, 1052 AUDIO_CHANNEL_OUT_MONO, 1053 0, // frameCount 1054 AUDIO_OUTPUT_FLAG_FAST, 1055 audioCallback, 1056 this, // user 1057 0, // notificationFrames 1058 0, // sharedBuffer 1059 mThreadCanCallJava, 1060 0, // sessionId 1061 AudioTrack::TRANSFER_CALLBACK); 1062 1063 if (mpAudioTrack->initCheck() != NO_ERROR) { 1064 ALOGE("AudioTrack->initCheck failed"); 1065 goto initAudioTrack_exit; 1066 } 1067 1068 mpAudioTrack->setVolume(mVolume); 1069 1070 mState = TONE_INIT; 1071 1072 return true; 1073 1074 initAudioTrack_exit: 1075 1076 ALOGV("Init failed: %p", mpAudioTrack.get()); 1077 1078 // Cleanup 1079 mpAudioTrack.clear(); 1080 1081 return false; 1082 } 1083 1084 1085 //////////////////////////////////////////////////////////////////////////////// 1086 // 1087 // Method: ToneGenerator::audioCallback() 1088 // 1089 // Description: AudioTrack callback implementation. Generates a block of 1090 // PCM samples 1091 // and manages tone generator sequencer: tones pulses, tone duration... 1092 // 1093 // Input: 1094 // user reference (pointer to our ToneGenerator) 1095 // info audio buffer descriptor 1096 // 1097 // Output: 1098 // returned value: always true. 1099 // 1100 //////////////////////////////////////////////////////////////////////////////// 1101 void ToneGenerator::audioCallback(int event, void* user, void *info) { 1102 1103 if (event != AudioTrack::EVENT_MORE_DATA) return; 1104 1105 AudioTrack::Buffer *buffer = static_cast<AudioTrack::Buffer *>(info); 1106 ToneGenerator *lpToneGen = static_cast<ToneGenerator *>(user); 1107 short *lpOut = buffer->i16; 1108 unsigned int lNumSmp = buffer->size/sizeof(short); 1109 const ToneDescriptor *lpToneDesc = lpToneGen->mpToneDesc; 1110 1111 if (buffer->size == 0) return; 1112 1113 1114 // Clear output buffer: WaveGenerator accumulates into lpOut buffer 1115 memset(lpOut, 0, buffer->size); 1116 1117 while (lNumSmp) { 1118 unsigned int lReqSmp = lNumSmp < lpToneGen->mProcessSize*2 ? lNumSmp : lpToneGen->mProcessSize; 1119 unsigned int lGenSmp; 1120 unsigned int lWaveCmd = WaveGenerator::WAVEGEN_CONT; 1121 bool lSignal = false; 1122 1123 lpToneGen->mLock.lock(); 1124 1125 1126 // Update pcm frame count and end time (current time at the end of this process) 1127 lpToneGen->mTotalSmp += lReqSmp; 1128 1129 // Update tone gen state machine and select wave gen command 1130 switch (lpToneGen->mState) { 1131 case TONE_PLAYING: 1132 lWaveCmd = WaveGenerator::WAVEGEN_CONT; 1133 break; 1134 case TONE_STARTING: 1135 ALOGV("Starting Cbk"); 1136 1137 lWaveCmd = WaveGenerator::WAVEGEN_START; 1138 break; 1139 case TONE_STOPPING: 1140 case TONE_RESTARTING: 1141 ALOGV("Stop/restart Cbk"); 1142 1143 lWaveCmd = WaveGenerator::WAVEGEN_STOP; 1144 lpToneGen->mNextSegSmp = TONEGEN_INF; // forced to skip state machine management below 1145 break; 1146 case TONE_STOPPED: 1147 ALOGV("Stopped Cbk"); 1148 goto audioCallback_EndLoop; 1149 default: 1150 ALOGV("Extra Cbk"); 1151 goto audioCallback_EndLoop; 1152 } 1153 1154 // Exit if tone sequence is over 1155 if (lpToneDesc->segments[lpToneGen->mCurSegment].duration == 0 || 1156 lpToneGen->mTotalSmp > lpToneGen->mMaxSmp) { 1157 if (lpToneGen->mState == TONE_PLAYING) { 1158 lpToneGen->mState = TONE_STOPPING; 1159 } 1160 if (lpToneDesc->segments[lpToneGen->mCurSegment].duration == 0) { 1161 goto audioCallback_EndLoop; 1162 } 1163 // fade out before stopping if maximum duration reached 1164 lWaveCmd = WaveGenerator::WAVEGEN_STOP; 1165 lpToneGen->mNextSegSmp = TONEGEN_INF; // forced to skip state machine management below 1166 } 1167 1168 if (lpToneGen->mTotalSmp > lpToneGen->mNextSegSmp) { 1169 // Time to go to next sequence segment 1170 1171 ALOGV("End Segment, time: %d", (unsigned int)(systemTime()/1000000)); 1172 1173 lGenSmp = lReqSmp; 1174 1175 // If segment, ON -> OFF transition : ramp volume down 1176 if (lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[0] != 0) { 1177 lWaveCmd = WaveGenerator::WAVEGEN_STOP; 1178 unsigned int lFreqIdx = 0; 1179 unsigned short lFrequency = lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[lFreqIdx]; 1180 1181 while (lFrequency != 0) { 1182 WaveGenerator *lpWaveGen = lpToneGen->mWaveGens.valueFor(lFrequency); 1183 lpWaveGen->getSamples(lpOut, lGenSmp, lWaveCmd); 1184 lFrequency = lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[++lFreqIdx]; 1185 } 1186 ALOGV("ON->OFF, lGenSmp: %d, lReqSmp: %d", lGenSmp, lReqSmp); 1187 } 1188 1189 // check if we need to loop and loop for the reqd times 1190 if (lpToneDesc->segments[lpToneGen->mCurSegment].loopCnt) { 1191 if (lpToneGen->mLoopCounter < lpToneDesc->segments[lpToneGen->mCurSegment].loopCnt) { 1192 ALOGV ("in if loop loopCnt(%d) loopctr(%d), CurSeg(%d)", 1193 lpToneDesc->segments[lpToneGen->mCurSegment].loopCnt, 1194 lpToneGen->mLoopCounter, 1195 lpToneGen->mCurSegment); 1196 lpToneGen->mCurSegment = lpToneDesc->segments[lpToneGen->mCurSegment].loopIndx; 1197 ++lpToneGen->mLoopCounter; 1198 } else { 1199 // completed loop. go to next segment 1200 lpToneGen->mLoopCounter = 0; 1201 lpToneGen->mCurSegment++; 1202 ALOGV ("in else loop loopCnt(%d) loopctr(%d), CurSeg(%d)", 1203 lpToneDesc->segments[lpToneGen->mCurSegment].loopCnt, 1204 lpToneGen->mLoopCounter, 1205 lpToneGen->mCurSegment); 1206 } 1207 } else { 1208 lpToneGen->mCurSegment++; 1209 ALOGV ("Goto next seg loopCnt(%d) loopctr(%d), CurSeg(%d)", 1210 lpToneDesc->segments[lpToneGen->mCurSegment].loopCnt, 1211 lpToneGen->mLoopCounter, 1212 lpToneGen->mCurSegment); 1213 1214 } 1215 1216 // Handle loop if last segment reached 1217 if (lpToneDesc->segments[lpToneGen->mCurSegment].duration == 0) { 1218 ALOGV("Last Seg: %d", lpToneGen->mCurSegment); 1219 1220 // Pre increment loop count and restart if total count not reached. Stop sequence otherwise 1221 if (++lpToneGen->mCurCount <= lpToneDesc->repeatCnt) { 1222 ALOGV("Repeating Count: %d", lpToneGen->mCurCount); 1223 1224 lpToneGen->mCurSegment = lpToneDesc->repeatSegment; 1225 if (lpToneDesc->segments[lpToneDesc->repeatSegment].waveFreq[0] != 0) { 1226 lWaveCmd = WaveGenerator::WAVEGEN_START; 1227 } 1228 1229 ALOGV("New segment %d, Next Time: %d", lpToneGen->mCurSegment, 1230 (lpToneGen->mNextSegSmp*1000)/lpToneGen->mSamplingRate); 1231 1232 } else { 1233 lGenSmp = 0; 1234 ALOGV("End repeat, time: %d", (unsigned int)(systemTime()/1000000)); 1235 } 1236 } else { 1237 ALOGV("New segment %d, Next Time: %d", lpToneGen->mCurSegment, 1238 (lpToneGen->mNextSegSmp*1000)/lpToneGen->mSamplingRate); 1239 if (lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[0] != 0) { 1240 // If next segment is not silent, OFF -> ON transition : reset wave generator 1241 lWaveCmd = WaveGenerator::WAVEGEN_START; 1242 1243 ALOGV("OFF->ON, lGenSmp: %d, lReqSmp: %d", lGenSmp, lReqSmp); 1244 } else { 1245 lGenSmp = 0; 1246 } 1247 } 1248 1249 // Update next segment transition position. No harm to do it also for last segment as lpToneGen->mNextSegSmp won't be used any more 1250 lpToneGen->mNextSegSmp 1251 += (lpToneDesc->segments[lpToneGen->mCurSegment].duration * lpToneGen->mSamplingRate) / 1000; 1252 1253 } else { 1254 // Inside a segment keep tone ON or OFF 1255 if (lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[0] == 0) { 1256 lGenSmp = 0; // If odd segment, tone is currently OFF 1257 } else { 1258 lGenSmp = lReqSmp; // If event segment, tone is currently ON 1259 } 1260 } 1261 1262 if (lGenSmp) { 1263 // If samples must be generated, call all active wave generators and acumulate waves in lpOut 1264 unsigned int lFreqIdx = 0; 1265 unsigned short lFrequency = lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[lFreqIdx]; 1266 1267 while (lFrequency != 0) { 1268 WaveGenerator *lpWaveGen = lpToneGen->mWaveGens.valueFor(lFrequency); 1269 lpWaveGen->getSamples(lpOut, lGenSmp, lWaveCmd); 1270 lFrequency = lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[++lFreqIdx]; 1271 } 1272 } 1273 1274 lNumSmp -= lReqSmp; 1275 lpOut += lReqSmp; 1276 1277 audioCallback_EndLoop: 1278 1279 switch (lpToneGen->mState) { 1280 case TONE_RESTARTING: 1281 ALOGV("Cbk restarting track"); 1282 if (lpToneGen->prepareWave()) { 1283 lpToneGen->mState = TONE_STARTING; 1284 if (clock_gettime(CLOCK_MONOTONIC, &lpToneGen->mStartTime) != 0) { 1285 lpToneGen->mStartTime.tv_sec = 0; 1286 } 1287 // must reload lpToneDesc as prepareWave() may change mpToneDesc 1288 lpToneDesc = lpToneGen->mpToneDesc; 1289 } else { 1290 ALOGW("Cbk restarting prepareWave() failed"); 1291 lpToneGen->mState = TONE_IDLE; 1292 lpToneGen->mpAudioTrack->stop(); 1293 // Force loop exit 1294 lNumSmp = 0; 1295 } 1296 lSignal = true; 1297 break; 1298 case TONE_STOPPING: 1299 ALOGV("Cbk Stopping"); 1300 lpToneGen->mState = TONE_STOPPED; 1301 // Force loop exit 1302 lNumSmp = 0; 1303 break; 1304 case TONE_STOPPED: 1305 lpToneGen->mState = TONE_INIT; 1306 ALOGV("Cbk Stopped track"); 1307 lpToneGen->mpAudioTrack->stop(); 1308 // Force loop exit 1309 lNumSmp = 0; 1310 buffer->size = 0; 1311 lSignal = true; 1312 break; 1313 case TONE_STARTING: 1314 ALOGV("Cbk starting track"); 1315 lpToneGen->mState = TONE_PLAYING; 1316 lSignal = true; 1317 break; 1318 case TONE_PLAYING: 1319 break; 1320 default: 1321 // Force loop exit 1322 lNumSmp = 0; 1323 buffer->size = 0; 1324 break; 1325 } 1326 1327 if (lSignal) 1328 lpToneGen->mWaitCbkCond.broadcast(); 1329 lpToneGen->mLock.unlock(); 1330 } 1331 } 1332 1333 1334 //////////////////////////////////////////////////////////////////////////////// 1335 // 1336 // Method: ToneGenerator::prepareWave() 1337 // 1338 // Description: Prepare wave generators and reset tone sequencer state machine. 1339 // mpNewToneDesc must have been initialized before calling this function. 1340 // Input: 1341 // none 1342 // 1343 // Output: 1344 // returned value: true if wave generators have been created, false otherwise 1345 // 1346 //////////////////////////////////////////////////////////////////////////////// 1347 bool ToneGenerator::prepareWave() { 1348 unsigned int segmentIdx = 0; 1349 1350 if (mpNewToneDesc == NULL) { 1351 return false; 1352 } 1353 1354 // Remove existing wave generators if any 1355 clearWaveGens(); 1356 1357 mpToneDesc = mpNewToneDesc; 1358 1359 if (mDurationMs == -1) { 1360 mMaxSmp = TONEGEN_INF; 1361 } else { 1362 if (mDurationMs > (int)(TONEGEN_INF / mSamplingRate)) { 1363 mMaxSmp = (mDurationMs / 1000) * mSamplingRate; 1364 } else { 1365 mMaxSmp = (mDurationMs * mSamplingRate) / 1000; 1366 } 1367 ALOGV("prepareWave, duration limited to %d ms", mDurationMs); 1368 } 1369 1370 while (mpToneDesc->segments[segmentIdx].duration) { 1371 // Get total number of sine waves: needed to adapt sine wave gain. 1372 unsigned int lNumWaves = numWaves(segmentIdx); 1373 unsigned int freqIdx = 0; 1374 unsigned int frequency = mpToneDesc->segments[segmentIdx].waveFreq[freqIdx]; 1375 while (frequency) { 1376 // Instantiate a wave generator if ot already done for this frequency 1377 if (mWaveGens.indexOfKey(frequency) == NAME_NOT_FOUND) { 1378 ToneGenerator::WaveGenerator *lpWaveGen = 1379 new ToneGenerator::WaveGenerator((unsigned short)mSamplingRate, 1380 frequency, 1381 TONEGEN_GAIN/lNumWaves); 1382 mWaveGens.add(frequency, lpWaveGen); 1383 } 1384 frequency = mpNewToneDesc->segments[segmentIdx].waveFreq[++freqIdx]; 1385 } 1386 segmentIdx++; 1387 } 1388 1389 // Initialize tone sequencer 1390 mTotalSmp = 0; 1391 mCurSegment = 0; 1392 mCurCount = 0; 1393 mLoopCounter = 0; 1394 if (mpToneDesc->segments[0].duration == TONEGEN_INF) { 1395 mNextSegSmp = TONEGEN_INF; 1396 } else{ 1397 mNextSegSmp = (mpToneDesc->segments[0].duration * mSamplingRate) / 1000; 1398 } 1399 1400 return true; 1401 } 1402 1403 1404 //////////////////////////////////////////////////////////////////////////////// 1405 // 1406 // Method: ToneGenerator::numWaves() 1407 // 1408 // Description: Count number of sine waves needed to generate a tone segment (e.g 2 for DTMF). 1409 // 1410 // Input: 1411 // segmentIdx tone segment index 1412 // 1413 // Output: 1414 // returned value: nummber of sine waves 1415 // 1416 //////////////////////////////////////////////////////////////////////////////// 1417 unsigned int ToneGenerator::numWaves(unsigned int segmentIdx) { 1418 unsigned int lCnt = 0; 1419 1420 if (mpToneDesc->segments[segmentIdx].duration) { 1421 while (mpToneDesc->segments[segmentIdx].waveFreq[lCnt]) { 1422 lCnt++; 1423 } 1424 lCnt++; 1425 } 1426 1427 return lCnt; 1428 } 1429 1430 1431 //////////////////////////////////////////////////////////////////////////////// 1432 // 1433 // Method: ToneGenerator::clearWaveGens() 1434 // 1435 // Description: Removes all wave generators. 1436 // 1437 // Input: 1438 // none 1439 // 1440 // Output: 1441 // none 1442 // 1443 //////////////////////////////////////////////////////////////////////////////// 1444 void ToneGenerator::clearWaveGens() { 1445 ALOGV("Clearing mWaveGens:"); 1446 1447 for (size_t lIdx = 0; lIdx < mWaveGens.size(); lIdx++) { 1448 delete mWaveGens.valueAt(lIdx); 1449 } 1450 mWaveGens.clear(); 1451 } 1452 1453 //////////////////////////////////////////////////////////////////////////////// 1454 // 1455 // Method: ToneGenerator::getToneForRegion() 1456 // 1457 // Description: Get correct ringtone type according to current region. 1458 // The corrected ring tone type is the tone descriptor index in sToneDescriptors[]. 1459 // 1460 // Input: 1461 // none 1462 // 1463 // Output: 1464 // none 1465 // 1466 //////////////////////////////////////////////////////////////////////////////// 1467 ToneGenerator::tone_type ToneGenerator::getToneForRegion(tone_type toneType) { 1468 tone_type regionTone; 1469 1470 if (mRegion == CEPT || toneType < FIRST_SUP_TONE || toneType > LAST_SUP_TONE) { 1471 regionTone = toneType; 1472 } else { 1473 regionTone = (tone_type) sToneMappingTable[mRegion][toneType - FIRST_SUP_TONE]; 1474 } 1475 1476 ALOGV("getToneForRegion, tone %d, region %d, regionTone %d", toneType, mRegion, regionTone); 1477 1478 return regionTone; 1479 } 1480 1481 1482 //////////////////////////////////////////////////////////////////////////////// 1483 // WaveGenerator::WaveGenerator class Implementation 1484 //////////////////////////////////////////////////////////////////////////////// 1485 1486 //---------------------------------- public methods ---------------------------- 1487 1488 //////////////////////////////////////////////////////////////////////////////// 1489 // 1490 // Method: WaveGenerator::WaveGenerator() 1491 // 1492 // Description: Constructor. 1493 // 1494 // Input: 1495 // samplingRate: Output sampling rate in Hz 1496 // frequency: Frequency of the sine wave to generate in Hz 1497 // volume: volume (0.0 to 1.0) 1498 // 1499 // Output: 1500 // none 1501 // 1502 //////////////////////////////////////////////////////////////////////////////// 1503 ToneGenerator::WaveGenerator::WaveGenerator(unsigned short samplingRate, 1504 unsigned short frequency, float volume) { 1505 double d0; 1506 double F_div_Fs; // frequency / samplingRate 1507 1508 F_div_Fs = frequency / (double)samplingRate; 1509 d0 = - (float)GEN_AMP * sin(2 * M_PI * F_div_Fs); 1510 mS2_0 = (short)d0; 1511 mS1 = 0; 1512 mS2 = mS2_0; 1513 1514 mAmplitude_Q15 = (short)(32767. * 32767. * volume / GEN_AMP); 1515 // take some margin for amplitude fluctuation 1516 if (mAmplitude_Q15 > 32500) 1517 mAmplitude_Q15 = 32500; 1518 1519 d0 = 32768.0 * cos(2 * M_PI * F_div_Fs); // Q14*2*cos() 1520 if (d0 > 32767) 1521 d0 = 32767; 1522 mA1_Q14 = (short) d0; 1523 1524 ALOGV("WaveGenerator init, mA1_Q14: %d, mS2_0: %d, mAmplitude_Q15: %d", 1525 mA1_Q14, mS2_0, mAmplitude_Q15); 1526 } 1527 1528 //////////////////////////////////////////////////////////////////////////////// 1529 // 1530 // Method: WaveGenerator::~WaveGenerator() 1531 // 1532 // Description: Destructor. 1533 // 1534 // Input: 1535 // none 1536 // 1537 // Output: 1538 // none 1539 // 1540 //////////////////////////////////////////////////////////////////////////////// 1541 ToneGenerator::WaveGenerator::~WaveGenerator() { 1542 } 1543 1544 //////////////////////////////////////////////////////////////////////////////// 1545 // 1546 // Method: WaveGenerator::getSamples() 1547 // 1548 // Description: Generates count samples of a sine wave and accumulates 1549 // result in outBuffer. 1550 // 1551 // Input: 1552 // outBuffer: Output buffer where to accumulate samples. 1553 // count: number of samples to produce. 1554 // command: special action requested (see enum gen_command). 1555 // 1556 // Output: 1557 // none 1558 // 1559 //////////////////////////////////////////////////////////////////////////////// 1560 void ToneGenerator::WaveGenerator::getSamples(short *outBuffer, 1561 unsigned int count, unsigned int command) { 1562 long lS1, lS2; 1563 long lA1, lAmplitude; 1564 long Sample; // current sample 1565 1566 // init local 1567 if (command == WAVEGEN_START) { 1568 lS1 = (long)0; 1569 lS2 = (long)mS2_0; 1570 } else { 1571 lS1 = (long)mS1; 1572 lS2 = (long)mS2; 1573 } 1574 lA1 = (long)mA1_Q14; 1575 lAmplitude = (long)mAmplitude_Q15; 1576 1577 if (command == WAVEGEN_STOP) { 1578 lAmplitude <<= 16; 1579 if (count == 0) { 1580 return; 1581 } 1582 long dec = lAmplitude/count; 1583 // loop generation 1584 while (count--) { 1585 Sample = ((lA1 * lS1) >> S_Q14) - lS2; 1586 // shift delay 1587 lS2 = lS1; 1588 lS1 = Sample; 1589 Sample = ((lAmplitude>>16) * Sample) >> S_Q15; 1590 *(outBuffer++) += (short)Sample; // put result in buffer 1591 lAmplitude -= dec; 1592 } 1593 } else { 1594 // loop generation 1595 while (count--) { 1596 Sample = ((lA1 * lS1) >> S_Q14) - lS2; 1597 // shift delay 1598 lS2 = lS1; 1599 lS1 = Sample; 1600 Sample = (lAmplitude * Sample) >> S_Q15; 1601 *(outBuffer++) += (short)Sample; // put result in buffer 1602 } 1603 } 1604 1605 // save status 1606 mS1 = (short)lS1; 1607 mS2 = (short)lS2; 1608 } 1609 1610 } // end namespace android 1611