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