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 
    744 
    745 
    746 };
    747 
    748 // Used by ToneGenerator::getToneForRegion() to convert user specified supervisory tone type
    749 // to actual tone for current region.
    750 const unsigned char /*tone_type*/ ToneGenerator::sToneMappingTable[NUM_REGIONS-1][NUM_SUP_TONES] = {
    751         {   // ANSI
    752             TONE_ANSI_DIAL,             // TONE_SUP_DIAL
    753             TONE_ANSI_BUSY,             // TONE_SUP_BUSY
    754             TONE_ANSI_CONGESTION,       // TONE_SUP_CONGESTION
    755             TONE_SUP_RADIO_ACK,         // TONE_SUP_RADIO_ACK
    756             TONE_SUP_RADIO_NOTAVAIL,    // TONE_SUP_RADIO_NOTAVAIL
    757             TONE_SUP_ERROR,             // TONE_SUP_ERROR
    758             TONE_ANSI_CALL_WAITING,     // TONE_SUP_CALL_WAITING
    759             TONE_ANSI_RINGTONE          // TONE_SUP_RINGTONE
    760         },
    761         {   // JAPAN
    762             TONE_JAPAN_DIAL,             // TONE_SUP_DIAL
    763             TONE_JAPAN_BUSY,             // TONE_SUP_BUSY
    764             TONE_SUP_CONGESTION,         // TONE_SUP_CONGESTION
    765             TONE_JAPAN_RADIO_ACK,        // TONE_SUP_RADIO_ACK
    766             TONE_SUP_RADIO_NOTAVAIL,     // TONE_SUP_RADIO_NOTAVAIL
    767             TONE_SUP_ERROR,              // TONE_SUP_ERROR
    768             TONE_SUP_CALL_WAITING,       // TONE_SUP_CALL_WAITING
    769             TONE_SUP_RINGTONE            // TONE_SUP_RINGTONE
    770         }
    771 };
    772 
    773 
    774 ////////////////////////////////////////////////////////////////////////////////
    775 //                           ToneGenerator class Implementation
    776 ////////////////////////////////////////////////////////////////////////////////
    777 
    778 
    779 //---------------------------------- public methods ----------------------------
    780 
    781 
    782 ////////////////////////////////////////////////////////////////////////////////
    783 //
    784 //    Method:        ToneGenerator::ToneGenerator()
    785 //
    786 //    Description:    Constructor. Initializes the tone sequencer, intantiates required sine wave
    787 //        generators, instantiates output audio track.
    788 //
    789 //    Input:
    790 //        streamType:        Type of stream used for tone playback
    791 //        volume:            volume applied to tone (0.0 to 1.0)
    792 //
    793 //    Output:
    794 //        none
    795 //
    796 ////////////////////////////////////////////////////////////////////////////////
    797 ToneGenerator::ToneGenerator(audio_stream_type_t streamType, float volume, bool threadCanCallJava) {
    798 
    799     ALOGV("ToneGenerator constructor: streamType=%d, volume=%f", streamType, volume);
    800 
    801     mState = TONE_IDLE;
    802 
    803     if (AudioSystem::getOutputSamplingRate(&mSamplingRate, streamType) != NO_ERROR) {
    804         ALOGE("Unable to marshal AudioFlinger");
    805         return;
    806     }
    807     mThreadCanCallJava = threadCanCallJava;
    808     mStreamType = streamType;
    809     mVolume = volume;
    810     mpToneDesc = NULL;
    811     mpNewToneDesc = NULL;
    812     // Generate tone by chunks of 20 ms to keep cadencing precision
    813     mProcessSize = (mSamplingRate * 20) / 1000;
    814 
    815     char value[PROPERTY_VALUE_MAX];
    816     property_get("gsm.operator.iso-country", value, "");
    817     if (strcmp(value,"us") == 0 ||
    818         strcmp(value,"ca") == 0) {
    819         mRegion = ANSI;
    820     } else if (strcmp(value,"jp") == 0) {
    821         mRegion = JAPAN;
    822     } else {
    823         mRegion = CEPT;
    824     }
    825 
    826     if (initAudioTrack()) {
    827         ALOGV("ToneGenerator INIT OK, time: %d", (unsigned int)(systemTime()/1000000));
    828     } else {
    829         ALOGV("!!!ToneGenerator INIT FAILED!!!");
    830     }
    831 }
    832 
    833 
    834 
    835 
    836 ////////////////////////////////////////////////////////////////////////////////
    837 //
    838 //    Method:        ToneGenerator::~ToneGenerator()
    839 //
    840 //    Description:    Destructor. Stop sound playback and delete audio track if
    841 //      needed and delete sine wave generators.
    842 //
    843 //    Input:
    844 //        none
    845 //
    846 //    Output:
    847 //        none
    848 //
    849 ////////////////////////////////////////////////////////////////////////////////
    850 ToneGenerator::~ToneGenerator() {
    851     ALOGV("ToneGenerator destructor");
    852 
    853     if (mpAudioTrack != 0) {
    854         stopTone();
    855         ALOGV("Delete Track: %p", mpAudioTrack.get());
    856         mpAudioTrack.clear();
    857     }
    858 }
    859 
    860 ////////////////////////////////////////////////////////////////////////////////
    861 //
    862 //    Method:        ToneGenerator::startTone()
    863 //
    864 //    Description:    Starts tone playback.
    865 //
    866 //    Input:
    867 //        toneType:        Type of tone generated (values in enum tone_type)
    868 //        durationMs:      The tone duration in milliseconds. If the tone is limited in time by definition,
    869 //              the actual duration will be the minimum of durationMs and the defined tone duration.
    870 //              Ommiting or setting durationMs to -1 does not limit tone duration.
    871 //
    872 //    Output:
    873 //        none
    874 //
    875 ////////////////////////////////////////////////////////////////////////////////
    876 bool ToneGenerator::startTone(tone_type toneType, int durationMs) {
    877     bool lResult = false;
    878     status_t lStatus;
    879 
    880     if ((toneType < 0) || (toneType >= NUM_TONES))
    881         return lResult;
    882 
    883     toneType = getToneForRegion(toneType);
    884     if (toneType == TONE_CDMA_SIGNAL_OFF) {
    885         return true;
    886     }
    887 
    888     if (mState == TONE_IDLE) {
    889         ALOGV("startTone: try to re-init AudioTrack");
    890         if (!initAudioTrack()) {
    891             return lResult;
    892         }
    893     }
    894 
    895     ALOGV("startTone");
    896 
    897     mLock.lock();
    898 
    899     // Get descriptor for requested tone
    900     mpNewToneDesc = &sToneDescriptors[toneType];
    901 
    902     mDurationMs = durationMs;
    903 
    904     if (mState == TONE_STOPPED) {
    905         ALOGV("Start waiting for previous tone to stop");
    906         lStatus = mWaitCbkCond.waitRelative(mLock, seconds(3));
    907         if (lStatus != NO_ERROR) {
    908             ALOGE("--- start wait for stop timed out, status %d", lStatus);
    909             mState = TONE_IDLE;
    910             mLock.unlock();
    911             return lResult;
    912         }
    913     }
    914 
    915     if (mState == TONE_INIT) {
    916         if (prepareWave()) {
    917             ALOGV("Immediate start, time %d", (unsigned int)(systemTime()/1000000));
    918             lResult = true;
    919             mState = TONE_STARTING;
    920             if (clock_gettime(CLOCK_MONOTONIC, &mStartTime) != 0) {
    921                 mStartTime.tv_sec = 0;
    922             }
    923             mLock.unlock();
    924             mpAudioTrack->start();
    925             mLock.lock();
    926             if (mState == TONE_STARTING) {
    927                 ALOGV("Wait for start callback");
    928                 lStatus = mWaitCbkCond.waitRelative(mLock, seconds(3));
    929                 if (lStatus != NO_ERROR) {
    930                     ALOGE("--- Immediate start timed out, status %d", lStatus);
    931                     mState = TONE_IDLE;
    932                     lResult = false;
    933                 }
    934             }
    935         } else {
    936             mState = TONE_IDLE;
    937         }
    938     } else {
    939         ALOGV("Delayed start");
    940         mState = TONE_RESTARTING;
    941         mStartTime.tv_sec = 0;
    942         lStatus = mWaitCbkCond.waitRelative(mLock, seconds(3));
    943         if (lStatus == NO_ERROR) {
    944             if (mState != TONE_IDLE) {
    945                 lResult = true;
    946             }
    947             ALOGV("cond received");
    948         } else {
    949             ALOGE("--- Delayed start timed out, status %d", lStatus);
    950             mState = TONE_IDLE;
    951         }
    952     }
    953     mLock.unlock();
    954 
    955     ALOGV_IF(lResult, "Tone started, time %d", (unsigned int)(systemTime()/1000000));
    956     ALOGW_IF(!lResult, "Tone start failed!!!, time %d", (unsigned int)(systemTime()/1000000));
    957 
    958     return lResult;
    959 }
    960 
    961 ////////////////////////////////////////////////////////////////////////////////
    962 //
    963 //    Method:        ToneGenerator::stopTone()
    964 //
    965 //    Description:    Stops tone playback.
    966 //
    967 //    Input:
    968 //        none
    969 //
    970 //    Output:
    971 //        none
    972 //
    973 ////////////////////////////////////////////////////////////////////////////////
    974 void ToneGenerator::stopTone() {
    975     ALOGV("stopTone");
    976 
    977     mLock.lock();
    978     if (mState != TONE_IDLE && mState != TONE_INIT) {
    979         if (mState == TONE_PLAYING || mState == TONE_STARTING || mState == TONE_RESTARTING) {
    980             struct timespec stopTime;
    981             // If the start time is valid, make sure that the number of audio samples produced
    982             // corresponds at least to the time between the start and stop commands.
    983             // This is needed in case of cold start of the output stream.
    984             if ((mStartTime.tv_sec != 0) && (clock_gettime(CLOCK_MONOTONIC, &stopTime) == 0)) {
    985                 time_t sec = stopTime.tv_sec - mStartTime.tv_sec;
    986                 long nsec = stopTime.tv_nsec - mStartTime.tv_nsec;
    987                 long durationMs;
    988                 if (nsec < 0) {
    989                     --sec;
    990                     nsec += 1000000000;
    991                 }
    992 
    993                 if ((sec + 1) > ((long)(INT_MAX / mSamplingRate))) {
    994                     mMaxSmp = sec * mSamplingRate;
    995                 } else {
    996                     // mSamplingRate is always > 1000
    997                     sec = sec * 1000 + nsec / 1000000; // duration in milliseconds
    998                     mMaxSmp = (unsigned int)(((int64_t)sec * mSamplingRate) / 1000);
    999                 }
   1000                 ALOGV("stopTone() forcing mMaxSmp to %d, total for far %d", mMaxSmp,  mTotalSmp);
   1001             } else {
   1002                 mState = TONE_STOPPING;
   1003             }
   1004         }
   1005         ALOGV("waiting cond");
   1006         status_t lStatus = mWaitCbkCond.waitRelative(mLock, seconds(3));
   1007         if (lStatus == NO_ERROR) {
   1008             // If the tone was restarted exit now before calling clearWaveGens();
   1009             if (mState != TONE_INIT) {
   1010                 mLock.unlock();
   1011                 return;
   1012             }
   1013             ALOGV("track stop complete, time %d", (unsigned int)(systemTime()/1000000));
   1014         } else {
   1015             ALOGE("--- Stop timed out");
   1016             mState = TONE_IDLE;
   1017             mpAudioTrack->stop();
   1018         }
   1019         clearWaveGens();
   1020     }
   1021 
   1022     mLock.unlock();
   1023 }
   1024 
   1025 //---------------------------------- private methods ---------------------------
   1026 
   1027 
   1028 
   1029 
   1030 ////////////////////////////////////////////////////////////////////////////////
   1031 //
   1032 //    Method:        ToneGenerator::initAudioTrack()
   1033 //
   1034 //    Description:    Allocates and configures AudioTrack used for PCM output.
   1035 //
   1036 //    Input:
   1037 //        none
   1038 //
   1039 //    Output:
   1040 //        none
   1041 //
   1042 ////////////////////////////////////////////////////////////////////////////////
   1043 bool ToneGenerator::initAudioTrack() {
   1044 
   1045     // Open audio track in mono, PCM 16bit, default sampling rate, default buffer size
   1046     mpAudioTrack = new AudioTrack();
   1047     ALOGV("Create Track: %p", mpAudioTrack.get());
   1048 
   1049     mpAudioTrack->set(mStreamType,
   1050                       0,    // sampleRate
   1051                       AUDIO_FORMAT_PCM_16_BIT,
   1052                       AUDIO_CHANNEL_OUT_MONO,
   1053                       0,    // frameCount
   1054                       AUDIO_OUTPUT_FLAG_FAST,
   1055                       audioCallback,
   1056                       this, // user
   1057                       0,    // notificationFrames
   1058                       0,    // sharedBuffer
   1059                       mThreadCanCallJava,
   1060                       AUDIO_SESSION_ALLOCATE,
   1061                       AudioTrack::TRANSFER_CALLBACK);
   1062 
   1063     if (mpAudioTrack->initCheck() != NO_ERROR) {
   1064         ALOGE("AudioTrack->initCheck failed");
   1065         goto initAudioTrack_exit;
   1066     }
   1067 
   1068     mpAudioTrack->setVolume(mVolume);
   1069 
   1070     mState = TONE_INIT;
   1071 
   1072     return true;
   1073 
   1074 initAudioTrack_exit:
   1075 
   1076     ALOGV("Init failed: %p", mpAudioTrack.get());
   1077 
   1078     // Cleanup
   1079     mpAudioTrack.clear();
   1080 
   1081     return false;
   1082 }
   1083 
   1084 
   1085 ////////////////////////////////////////////////////////////////////////////////
   1086 //
   1087 //    Method:        ToneGenerator::audioCallback()
   1088 //
   1089 //    Description:    AudioTrack callback implementation. Generates a block of
   1090 //        PCM samples
   1091 //        and manages tone generator sequencer: tones pulses, tone duration...
   1092 //
   1093 //    Input:
   1094 //        user    reference (pointer to our ToneGenerator)
   1095 //        info    audio buffer descriptor
   1096 //
   1097 //    Output:
   1098 //        returned value: always true.
   1099 //
   1100 ////////////////////////////////////////////////////////////////////////////////
   1101 void ToneGenerator::audioCallback(int event, void* user, void *info) {
   1102 
   1103     if (event != AudioTrack::EVENT_MORE_DATA) return;
   1104 
   1105     AudioTrack::Buffer *buffer = static_cast<AudioTrack::Buffer *>(info);
   1106     ToneGenerator *lpToneGen = static_cast<ToneGenerator *>(user);
   1107     short *lpOut = buffer->i16;
   1108     unsigned int lNumSmp = buffer->size/sizeof(short);
   1109     const ToneDescriptor *lpToneDesc = lpToneGen->mpToneDesc;
   1110 
   1111     if (buffer->size == 0) return;
   1112 
   1113 
   1114     // Clear output buffer: WaveGenerator accumulates into lpOut buffer
   1115     memset(lpOut, 0, buffer->size);
   1116 
   1117     while (lNumSmp) {
   1118         unsigned int lReqSmp = lNumSmp < lpToneGen->mProcessSize*2 ? lNumSmp : lpToneGen->mProcessSize;
   1119         unsigned int lGenSmp;
   1120         unsigned int lWaveCmd = WaveGenerator::WAVEGEN_CONT;
   1121         bool lSignal = false;
   1122 
   1123         lpToneGen->mLock.lock();
   1124 
   1125 
   1126         // Update pcm frame count and end time (current time at the end of this process)
   1127         lpToneGen->mTotalSmp += lReqSmp;
   1128 
   1129         // Update tone gen state machine and select wave gen command
   1130         switch (lpToneGen->mState) {
   1131         case TONE_PLAYING:
   1132             lWaveCmd = WaveGenerator::WAVEGEN_CONT;
   1133             break;
   1134         case TONE_STARTING:
   1135             ALOGV("Starting Cbk");
   1136 
   1137             lWaveCmd = WaveGenerator::WAVEGEN_START;
   1138             break;
   1139         case TONE_STOPPING:
   1140         case TONE_RESTARTING:
   1141             ALOGV("Stop/restart Cbk");
   1142 
   1143             lWaveCmd = WaveGenerator::WAVEGEN_STOP;
   1144             lpToneGen->mNextSegSmp = TONEGEN_INF; // forced to skip state machine management below
   1145             break;
   1146         case TONE_STOPPED:
   1147             ALOGV("Stopped Cbk");
   1148             goto audioCallback_EndLoop;
   1149         default:
   1150             ALOGV("Extra Cbk");
   1151             goto audioCallback_EndLoop;
   1152         }
   1153 
   1154         // Exit if tone sequence is over
   1155         if (lpToneDesc->segments[lpToneGen->mCurSegment].duration == 0 ||
   1156             lpToneGen->mTotalSmp > lpToneGen->mMaxSmp) {
   1157             if (lpToneGen->mState == TONE_PLAYING) {
   1158                 lpToneGen->mState = TONE_STOPPING;
   1159             }
   1160             if (lpToneDesc->segments[lpToneGen->mCurSegment].duration == 0) {
   1161                 goto audioCallback_EndLoop;
   1162             }
   1163             // fade out before stopping if maximum duration reached
   1164             lWaveCmd = WaveGenerator::WAVEGEN_STOP;
   1165             lpToneGen->mNextSegSmp = TONEGEN_INF; // forced to skip state machine management below
   1166         }
   1167 
   1168         if (lpToneGen->mTotalSmp > lpToneGen->mNextSegSmp) {
   1169             // Time to go to next sequence segment
   1170 
   1171             ALOGV("End Segment, time: %d", (unsigned int)(systemTime()/1000000));
   1172 
   1173             lGenSmp = lReqSmp;
   1174 
   1175             // If segment,  ON -> OFF transition : ramp volume down
   1176             if (lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[0] != 0) {
   1177                 lWaveCmd = WaveGenerator::WAVEGEN_STOP;
   1178                 unsigned int lFreqIdx = 0;
   1179                 unsigned short lFrequency = lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[lFreqIdx];
   1180 
   1181                 while (lFrequency != 0) {
   1182                     WaveGenerator *lpWaveGen = lpToneGen->mWaveGens.valueFor(lFrequency);
   1183                     lpWaveGen->getSamples(lpOut, lGenSmp, lWaveCmd);
   1184                     lFrequency = lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[++lFreqIdx];
   1185                 }
   1186                 ALOGV("ON->OFF, lGenSmp: %d, lReqSmp: %d", lGenSmp, lReqSmp);
   1187             }
   1188 
   1189             // check if we need to loop and loop for the reqd times
   1190             if (lpToneDesc->segments[lpToneGen->mCurSegment].loopCnt) {
   1191                 if (lpToneGen->mLoopCounter < lpToneDesc->segments[lpToneGen->mCurSegment].loopCnt) {
   1192                     ALOGV ("in if loop loopCnt(%d) loopctr(%d), CurSeg(%d)",
   1193                           lpToneDesc->segments[lpToneGen->mCurSegment].loopCnt,
   1194                           lpToneGen->mLoopCounter,
   1195                           lpToneGen->mCurSegment);
   1196                     lpToneGen->mCurSegment = lpToneDesc->segments[lpToneGen->mCurSegment].loopIndx;
   1197                     ++lpToneGen->mLoopCounter;
   1198                 } else {
   1199                     // completed loop. go to next segment
   1200                     lpToneGen->mLoopCounter = 0;
   1201                     lpToneGen->mCurSegment++;
   1202                     ALOGV ("in else loop loopCnt(%d) loopctr(%d), CurSeg(%d)",
   1203                           lpToneDesc->segments[lpToneGen->mCurSegment].loopCnt,
   1204                           lpToneGen->mLoopCounter,
   1205                           lpToneGen->mCurSegment);
   1206                 }
   1207             } else {
   1208                 lpToneGen->mCurSegment++;
   1209                 ALOGV ("Goto next seg loopCnt(%d) loopctr(%d), CurSeg(%d)",
   1210                       lpToneDesc->segments[lpToneGen->mCurSegment].loopCnt,
   1211                       lpToneGen->mLoopCounter,
   1212                       lpToneGen->mCurSegment);
   1213 
   1214             }
   1215 
   1216             // Handle loop if last segment reached
   1217             if (lpToneDesc->segments[lpToneGen->mCurSegment].duration == 0) {
   1218                 ALOGV("Last Seg: %d", lpToneGen->mCurSegment);
   1219 
   1220                 // Pre increment loop count and restart if total count not reached. Stop sequence otherwise
   1221                 if (++lpToneGen->mCurCount <= lpToneDesc->repeatCnt) {
   1222                     ALOGV("Repeating Count: %d", lpToneGen->mCurCount);
   1223 
   1224                     lpToneGen->mCurSegment = lpToneDesc->repeatSegment;
   1225                     if (lpToneDesc->segments[lpToneDesc->repeatSegment].waveFreq[0] != 0) {
   1226                         lWaveCmd = WaveGenerator::WAVEGEN_START;
   1227                     }
   1228 
   1229                     ALOGV("New segment %d, Next Time: %d", lpToneGen->mCurSegment,
   1230                             (lpToneGen->mNextSegSmp*1000)/lpToneGen->mSamplingRate);
   1231 
   1232                 } else {
   1233                     lGenSmp = 0;
   1234                     ALOGV("End repeat, time: %d", (unsigned int)(systemTime()/1000000));
   1235                 }
   1236             } else {
   1237                 ALOGV("New segment %d, Next Time: %d", lpToneGen->mCurSegment,
   1238                         (lpToneGen->mNextSegSmp*1000)/lpToneGen->mSamplingRate);
   1239                 if (lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[0] != 0) {
   1240                     // If next segment is not silent,  OFF -> ON transition : reset wave generator
   1241                     lWaveCmd = WaveGenerator::WAVEGEN_START;
   1242 
   1243                     ALOGV("OFF->ON, lGenSmp: %d, lReqSmp: %d", lGenSmp, lReqSmp);
   1244                 } else {
   1245                     lGenSmp = 0;
   1246                 }
   1247             }
   1248 
   1249             // Update next segment transition position. No harm to do it also for last segment as lpToneGen->mNextSegSmp won't be used any more
   1250             lpToneGen->mNextSegSmp
   1251                     += (lpToneDesc->segments[lpToneGen->mCurSegment].duration * lpToneGen->mSamplingRate) / 1000;
   1252 
   1253         } else {
   1254             // Inside a segment keep tone ON or OFF
   1255             if (lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[0] == 0) {
   1256                 lGenSmp = 0;  // If odd segment, tone is currently OFF
   1257             } else {
   1258                 lGenSmp = lReqSmp;  // If event segment, tone is currently ON
   1259             }
   1260         }
   1261 
   1262         if (lGenSmp) {
   1263             // If samples must be generated, call all active wave generators and acumulate waves in lpOut
   1264             unsigned int lFreqIdx = 0;
   1265             unsigned short lFrequency = lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[lFreqIdx];
   1266 
   1267             while (lFrequency != 0) {
   1268                 WaveGenerator *lpWaveGen = lpToneGen->mWaveGens.valueFor(lFrequency);
   1269                 lpWaveGen->getSamples(lpOut, lGenSmp, lWaveCmd);
   1270                 lFrequency = lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[++lFreqIdx];
   1271             }
   1272         }
   1273 
   1274         lNumSmp -= lReqSmp;
   1275         lpOut += lReqSmp;
   1276 
   1277 audioCallback_EndLoop:
   1278 
   1279         switch (lpToneGen->mState) {
   1280         case TONE_RESTARTING:
   1281             ALOGV("Cbk restarting track");
   1282             if (lpToneGen->prepareWave()) {
   1283                 lpToneGen->mState = TONE_STARTING;
   1284                 if (clock_gettime(CLOCK_MONOTONIC, &lpToneGen->mStartTime) != 0) {
   1285                     lpToneGen->mStartTime.tv_sec = 0;
   1286                 }
   1287                 // must reload lpToneDesc as prepareWave() may change mpToneDesc
   1288                 lpToneDesc = lpToneGen->mpToneDesc;
   1289             } else {
   1290                 ALOGW("Cbk restarting prepareWave() failed");
   1291                 lpToneGen->mState = TONE_IDLE;
   1292                 lpToneGen->mpAudioTrack->stop();
   1293                 // Force loop exit
   1294                 lNumSmp = 0;
   1295             }
   1296             lSignal = true;
   1297             break;
   1298         case TONE_STOPPING:
   1299             ALOGV("Cbk Stopping");
   1300             lpToneGen->mState = TONE_STOPPED;
   1301             // Force loop exit
   1302             lNumSmp = 0;
   1303             break;
   1304         case TONE_STOPPED:
   1305             lpToneGen->mState = TONE_INIT;
   1306             ALOGV("Cbk Stopped track");
   1307             lpToneGen->mpAudioTrack->stop();
   1308             // Force loop exit
   1309             lNumSmp = 0;
   1310             buffer->size = 0;
   1311             lSignal = true;
   1312             break;
   1313         case TONE_STARTING:
   1314             ALOGV("Cbk starting track");
   1315             lpToneGen->mState = TONE_PLAYING;
   1316             lSignal = true;
   1317             break;
   1318         case TONE_PLAYING:
   1319             break;
   1320         default:
   1321             // Force loop exit
   1322             lNumSmp = 0;
   1323             buffer->size = 0;
   1324             break;
   1325         }
   1326 
   1327         if (lSignal)
   1328             lpToneGen->mWaitCbkCond.broadcast();
   1329         lpToneGen->mLock.unlock();
   1330     }
   1331 }
   1332 
   1333 
   1334 ////////////////////////////////////////////////////////////////////////////////
   1335 //
   1336 //    Method:        ToneGenerator::prepareWave()
   1337 //
   1338 //    Description:    Prepare wave generators and reset tone sequencer state machine.
   1339 //      mpNewToneDesc must have been initialized before calling this function.
   1340 //    Input:
   1341 //        none
   1342 //
   1343 //    Output:
   1344 //        returned value:   true if wave generators have been created, false otherwise
   1345 //
   1346 ////////////////////////////////////////////////////////////////////////////////
   1347 bool ToneGenerator::prepareWave() {
   1348     unsigned int segmentIdx = 0;
   1349 
   1350     if (mpNewToneDesc == NULL) {
   1351         return false;
   1352     }
   1353 
   1354     // Remove existing wave generators if any
   1355     clearWaveGens();
   1356 
   1357     mpToneDesc = mpNewToneDesc;
   1358 
   1359     if (mDurationMs == -1) {
   1360         mMaxSmp = TONEGEN_INF;
   1361     } else {
   1362         if (mDurationMs > (int)(TONEGEN_INF / mSamplingRate)) {
   1363             mMaxSmp = (mDurationMs / 1000) * mSamplingRate;
   1364         } else {
   1365             mMaxSmp = (mDurationMs * mSamplingRate) / 1000;
   1366         }
   1367         ALOGV("prepareWave, duration limited to %d ms", mDurationMs);
   1368     }
   1369 
   1370     while (mpToneDesc->segments[segmentIdx].duration) {
   1371         // Get total number of sine waves: needed to adapt sine wave gain.
   1372         unsigned int lNumWaves = numWaves(segmentIdx);
   1373         unsigned int freqIdx = 0;
   1374         unsigned int frequency = mpToneDesc->segments[segmentIdx].waveFreq[freqIdx];
   1375         while (frequency) {
   1376             // Instantiate a wave generator if  ot already done for this frequency
   1377             if (mWaveGens.indexOfKey(frequency) == NAME_NOT_FOUND) {
   1378                 ToneGenerator::WaveGenerator *lpWaveGen =
   1379                         new ToneGenerator::WaveGenerator((unsigned short)mSamplingRate,
   1380                                 frequency,
   1381                                 TONEGEN_GAIN/lNumWaves);
   1382                 mWaveGens.add(frequency, lpWaveGen);
   1383             }
   1384             frequency = mpNewToneDesc->segments[segmentIdx].waveFreq[++freqIdx];
   1385         }
   1386         segmentIdx++;
   1387     }
   1388 
   1389     // Initialize tone sequencer
   1390     mTotalSmp = 0;
   1391     mCurSegment = 0;
   1392     mCurCount = 0;
   1393     mLoopCounter = 0;
   1394     if (mpToneDesc->segments[0].duration == TONEGEN_INF) {
   1395         mNextSegSmp = TONEGEN_INF;
   1396     } else{
   1397         mNextSegSmp = (mpToneDesc->segments[0].duration * mSamplingRate) / 1000;
   1398     }
   1399 
   1400     return true;
   1401 }
   1402 
   1403 
   1404 ////////////////////////////////////////////////////////////////////////////////
   1405 //
   1406 //    Method:        ToneGenerator::numWaves()
   1407 //
   1408 //    Description:    Count number of sine waves needed to generate a tone segment (e.g 2 for DTMF).
   1409 //
   1410 //    Input:
   1411 //        segmentIdx        tone segment index
   1412 //
   1413 //    Output:
   1414 //        returned value:    nummber of sine waves
   1415 //
   1416 ////////////////////////////////////////////////////////////////////////////////
   1417 unsigned int ToneGenerator::numWaves(unsigned int segmentIdx) {
   1418     unsigned int lCnt = 0;
   1419 
   1420     if (mpToneDesc->segments[segmentIdx].duration) {
   1421         while (mpToneDesc->segments[segmentIdx].waveFreq[lCnt]) {
   1422             lCnt++;
   1423         }
   1424         lCnt++;
   1425     }
   1426 
   1427     return lCnt;
   1428 }
   1429 
   1430 
   1431 ////////////////////////////////////////////////////////////////////////////////
   1432 //
   1433 //    Method:        ToneGenerator::clearWaveGens()
   1434 //
   1435 //    Description:    Removes all wave generators.
   1436 //
   1437 //    Input:
   1438 //        none
   1439 //
   1440 //    Output:
   1441 //        none
   1442 //
   1443 ////////////////////////////////////////////////////////////////////////////////
   1444 void ToneGenerator::clearWaveGens() {
   1445     ALOGV("Clearing mWaveGens:");
   1446 
   1447     for (size_t lIdx = 0; lIdx < mWaveGens.size(); lIdx++) {
   1448         delete mWaveGens.valueAt(lIdx);
   1449     }
   1450     mWaveGens.clear();
   1451 }
   1452 
   1453 ////////////////////////////////////////////////////////////////////////////////
   1454 //
   1455 //    Method:       ToneGenerator::getToneForRegion()
   1456 //
   1457 //    Description:  Get correct ringtone type according to current region.
   1458 //      The corrected ring tone type is the tone descriptor index in sToneDescriptors[].
   1459 //
   1460 //    Input:
   1461 //        none
   1462 //
   1463 //    Output:
   1464 //        none
   1465 //
   1466 ////////////////////////////////////////////////////////////////////////////////
   1467 ToneGenerator::tone_type ToneGenerator::getToneForRegion(tone_type toneType) {
   1468     tone_type regionTone;
   1469 
   1470     if (mRegion == CEPT || toneType < FIRST_SUP_TONE || toneType > LAST_SUP_TONE) {
   1471         regionTone = toneType;
   1472     } else {
   1473         regionTone = (tone_type) sToneMappingTable[mRegion][toneType - FIRST_SUP_TONE];
   1474     }
   1475 
   1476     ALOGV("getToneForRegion, tone %d, region %d, regionTone %d", toneType, mRegion, regionTone);
   1477 
   1478     return regionTone;
   1479 }
   1480 
   1481 
   1482 ////////////////////////////////////////////////////////////////////////////////
   1483 //                WaveGenerator::WaveGenerator class    Implementation
   1484 ////////////////////////////////////////////////////////////////////////////////
   1485 
   1486 //---------------------------------- public methods ----------------------------
   1487 
   1488 ////////////////////////////////////////////////////////////////////////////////
   1489 //
   1490 //    Method:        WaveGenerator::WaveGenerator()
   1491 //
   1492 //    Description:    Constructor.
   1493 //
   1494 //    Input:
   1495 //        samplingRate:    Output sampling rate in Hz
   1496 //        frequency:       Frequency of the sine wave to generate in Hz
   1497 //        volume:          volume (0.0 to 1.0)
   1498 //
   1499 //    Output:
   1500 //        none
   1501 //
   1502 ////////////////////////////////////////////////////////////////////////////////
   1503 ToneGenerator::WaveGenerator::WaveGenerator(unsigned short samplingRate,
   1504         unsigned short frequency, float volume) {
   1505     double d0;
   1506     double F_div_Fs;  // frequency / samplingRate
   1507 
   1508     F_div_Fs = frequency / (double)samplingRate;
   1509     d0 = - (float)GEN_AMP * sin(2 * M_PI * F_div_Fs);
   1510     mS2_0 = (short)d0;
   1511     mS1 = 0;
   1512     mS2 = mS2_0;
   1513 
   1514     mAmplitude_Q15 = (short)(32767. * 32767. * volume / GEN_AMP);
   1515     // take some margin for amplitude fluctuation
   1516     if (mAmplitude_Q15 > 32500)
   1517         mAmplitude_Q15 = 32500;
   1518 
   1519     d0 = 32768.0 * cos(2 * M_PI * F_div_Fs);  // Q14*2*cos()
   1520     if (d0 > 32767)
   1521         d0 = 32767;
   1522     mA1_Q14 = (short) d0;
   1523 
   1524     ALOGV("WaveGenerator init, mA1_Q14: %d, mS2_0: %d, mAmplitude_Q15: %d",
   1525             mA1_Q14, mS2_0, mAmplitude_Q15);
   1526 }
   1527 
   1528 ////////////////////////////////////////////////////////////////////////////////
   1529 //
   1530 //    Method:        WaveGenerator::~WaveGenerator()
   1531 //
   1532 //    Description:    Destructor.
   1533 //
   1534 //    Input:
   1535 //        none
   1536 //
   1537 //    Output:
   1538 //        none
   1539 //
   1540 ////////////////////////////////////////////////////////////////////////////////
   1541 ToneGenerator::WaveGenerator::~WaveGenerator() {
   1542 }
   1543 
   1544 ////////////////////////////////////////////////////////////////////////////////
   1545 //
   1546 //    Method:        WaveGenerator::getSamples()
   1547 //
   1548 //    Description:    Generates count samples of a sine wave and accumulates
   1549 //        result in outBuffer.
   1550 //
   1551 //    Input:
   1552 //        outBuffer:      Output buffer where to accumulate samples.
   1553 //        count:          number of samples to produce.
   1554 //        command:        special action requested (see enum gen_command).
   1555 //
   1556 //    Output:
   1557 //        none
   1558 //
   1559 ////////////////////////////////////////////////////////////////////////////////
   1560 void ToneGenerator::WaveGenerator::getSamples(short *outBuffer,
   1561         unsigned int count, unsigned int command) {
   1562     long lS1, lS2;
   1563     long lA1, lAmplitude;
   1564     long Sample;  // current sample
   1565 
   1566     // init local
   1567     if (command == WAVEGEN_START) {
   1568         lS1 = (long)0;
   1569         lS2 = (long)mS2_0;
   1570     } else {
   1571         lS1 = (long)mS1;
   1572         lS2 = (long)mS2;
   1573     }
   1574     lA1 = (long)mA1_Q14;
   1575     lAmplitude = (long)mAmplitude_Q15;
   1576 
   1577     if (command == WAVEGEN_STOP) {
   1578         lAmplitude <<= 16;
   1579         if (count == 0) {
   1580             return;
   1581         }
   1582         long dec = lAmplitude/count;
   1583         // loop generation
   1584         while (count--) {
   1585             Sample = ((lA1 * lS1) >> S_Q14) - lS2;
   1586             // shift delay
   1587             lS2 = lS1;
   1588             lS1 = Sample;
   1589             Sample = ((lAmplitude>>16) * Sample) >> S_Q15;
   1590             *(outBuffer++) += (short)Sample;  // put result in buffer
   1591             lAmplitude -= dec;
   1592         }
   1593     } else {
   1594         // loop generation
   1595         while (count--) {
   1596             Sample = ((lA1 * lS1) >> S_Q14) - lS2;
   1597             // shift delay
   1598             lS2 = lS1;
   1599             lS1 = Sample;
   1600             Sample = (lAmplitude * Sample) >> S_Q15;
   1601             *(outBuffer++) += (short)Sample;  // put result in buffer
   1602         }
   1603     }
   1604 
   1605     // save status
   1606     mS1 = (short)lS1;
   1607     mS2 = (short)lS2;
   1608 }
   1609 
   1610 }  // end namespace android
   1611