ToneGenerator.cpp revision 1ab85ec401801ef9a9184650d0f5a1639b45eeb9
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
26namespace android {
27
28
29// Descriptors for all available tones (See ToneGenerator::ToneDescriptor class declaration for details)
30const 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.
750const 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////////////////////////////////////////////////////////////////////////////////
797ToneGenerator::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////////////////////////////////////////////////////////////////////////////////
850ToneGenerator::~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////////////////////////////////////////////////////////////////////////////////
876bool 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////////////////////////////////////////////////////////////////////////////////
974void 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////////////////////////////////////////////////////////////////////////////////
1043bool 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                      0,    // sessionId
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
1074initAudioTrack_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////////////////////////////////////////////////////////////////////////////////
1101void 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
1277audioCallback_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////////////////////////////////////////////////////////////////////////////////
1347bool 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////////////////////////////////////////////////////////////////////////////////
1417unsigned 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////////////////////////////////////////////////////////////////////////////////
1444void 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////////////////////////////////////////////////////////////////////////////////
1467ToneGenerator::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////////////////////////////////////////////////////////////////////////////////
1503ToneGenerator::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////////////////////////////////////////////////////////////////////////////////
1541ToneGenerator::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////////////////////////////////////////////////////////////////////////////////
1560void 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