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