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