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