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