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