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