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