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