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                 if (nsec < 0) {
    988                     --sec;
    989                     nsec += 1000000000;
    990                 }
    991 
    992                 if ((sec + 1) > ((long)(INT_MAX / mSamplingRate))) {
    993                     mMaxSmp = sec * mSamplingRate;
    994                 } else {
    995                     // mSamplingRate is always > 1000
    996                     sec = sec * 1000 + nsec / 1000000; // duration in milliseconds
    997                     mMaxSmp = (unsigned int)(((int64_t)sec * mSamplingRate) / 1000);
    998                 }
    999                 ALOGV("stopTone() forcing mMaxSmp to %d, total for far %d", mMaxSmp,  mTotalSmp);
   1000             } else {
   1001                 mState = TONE_STOPPING;
   1002             }
   1003         }
   1004         ALOGV("waiting cond");
   1005         status_t lStatus = mWaitCbkCond.waitRelative(mLock, seconds(3));
   1006         if (lStatus == NO_ERROR) {
   1007             // If the tone was restarted exit now before calling clearWaveGens();
   1008             if (mState != TONE_INIT) {
   1009                 mLock.unlock();
   1010                 return;
   1011             }
   1012             ALOGV("track stop complete, time %d", (unsigned int)(systemTime()/1000000));
   1013         } else {
   1014             ALOGE("--- Stop timed out");
   1015             mState = TONE_IDLE;
   1016             mpAudioTrack->stop();
   1017         }
   1018         clearWaveGens();
   1019     }
   1020 
   1021     mLock.unlock();
   1022 }
   1023 
   1024 //---------------------------------- private methods ---------------------------
   1025 
   1026 
   1027 
   1028 
   1029 ////////////////////////////////////////////////////////////////////////////////
   1030 //
   1031 //    Method:        ToneGenerator::initAudioTrack()
   1032 //
   1033 //    Description:    Allocates and configures AudioTrack used for PCM output.
   1034 //
   1035 //    Input:
   1036 //        none
   1037 //
   1038 //    Output:
   1039 //        none
   1040 //
   1041 ////////////////////////////////////////////////////////////////////////////////
   1042 bool ToneGenerator::initAudioTrack() {
   1043 
   1044     // Open audio track in mono, PCM 16bit, default sampling rate, default buffer size
   1045     mpAudioTrack = new AudioTrack();
   1046     ALOGV("Create Track: %p", mpAudioTrack.get());
   1047 
   1048     mpAudioTrack->set(mStreamType,
   1049                       0,    // sampleRate
   1050                       AUDIO_FORMAT_PCM_16_BIT,
   1051                       AUDIO_CHANNEL_OUT_MONO,
   1052                       0,    // frameCount
   1053                       AUDIO_OUTPUT_FLAG_FAST,
   1054                       audioCallback,
   1055                       this, // user
   1056                       0,    // notificationFrames
   1057                       0,    // sharedBuffer
   1058                       mThreadCanCallJava,
   1059                       AUDIO_SESSION_ALLOCATE,
   1060                       AudioTrack::TRANSFER_CALLBACK);
   1061 
   1062     if (mpAudioTrack->initCheck() != NO_ERROR) {
   1063         ALOGE("AudioTrack->initCheck failed");
   1064         goto initAudioTrack_exit;
   1065     }
   1066 
   1067     mpAudioTrack->setVolume(mVolume);
   1068 
   1069     mState = TONE_INIT;
   1070 
   1071     return true;
   1072 
   1073 initAudioTrack_exit:
   1074 
   1075     ALOGV("Init failed: %p", mpAudioTrack.get());
   1076 
   1077     // Cleanup
   1078     mpAudioTrack.clear();
   1079 
   1080     return false;
   1081 }
   1082 
   1083 
   1084 ////////////////////////////////////////////////////////////////////////////////
   1085 //
   1086 //    Method:        ToneGenerator::audioCallback()
   1087 //
   1088 //    Description:    AudioTrack callback implementation. Generates a block of
   1089 //        PCM samples
   1090 //        and manages tone generator sequencer: tones pulses, tone duration...
   1091 //
   1092 //    Input:
   1093 //        user    reference (pointer to our ToneGenerator)
   1094 //        info    audio buffer descriptor
   1095 //
   1096 //    Output:
   1097 //        returned value: always true.
   1098 //
   1099 ////////////////////////////////////////////////////////////////////////////////
   1100 void ToneGenerator::audioCallback(int event, void* user, void *info) {
   1101 
   1102     if (event != AudioTrack::EVENT_MORE_DATA) return;
   1103 
   1104     AudioTrack::Buffer *buffer = static_cast<AudioTrack::Buffer *>(info);
   1105     ToneGenerator *lpToneGen = static_cast<ToneGenerator *>(user);
   1106     short *lpOut = buffer->i16;
   1107     unsigned int lNumSmp = buffer->size/sizeof(short);
   1108     const ToneDescriptor *lpToneDesc = lpToneGen->mpToneDesc;
   1109 
   1110     if (buffer->size == 0) return;
   1111 
   1112 
   1113     // Clear output buffer: WaveGenerator accumulates into lpOut buffer
   1114     memset(lpOut, 0, buffer->size);
   1115 
   1116     while (lNumSmp) {
   1117         unsigned int lReqSmp = lNumSmp < lpToneGen->mProcessSize*2 ? lNumSmp : lpToneGen->mProcessSize;
   1118         unsigned int lGenSmp;
   1119         unsigned int lWaveCmd = WaveGenerator::WAVEGEN_CONT;
   1120         bool lSignal = false;
   1121 
   1122         lpToneGen->mLock.lock();
   1123 
   1124 
   1125         // Update pcm frame count and end time (current time at the end of this process)
   1126         lpToneGen->mTotalSmp += lReqSmp;
   1127 
   1128         // Update tone gen state machine and select wave gen command
   1129         switch (lpToneGen->mState) {
   1130         case TONE_PLAYING:
   1131             lWaveCmd = WaveGenerator::WAVEGEN_CONT;
   1132             break;
   1133         case TONE_STARTING:
   1134             ALOGV("Starting Cbk");
   1135 
   1136             lWaveCmd = WaveGenerator::WAVEGEN_START;
   1137             break;
   1138         case TONE_STOPPING:
   1139         case TONE_RESTARTING:
   1140             ALOGV("Stop/restart Cbk");
   1141 
   1142             lWaveCmd = WaveGenerator::WAVEGEN_STOP;
   1143             lpToneGen->mNextSegSmp = TONEGEN_INF; // forced to skip state machine management below
   1144             break;
   1145         case TONE_STOPPED:
   1146             ALOGV("Stopped Cbk");
   1147             goto audioCallback_EndLoop;
   1148         default:
   1149             ALOGV("Extra Cbk");
   1150             goto audioCallback_EndLoop;
   1151         }
   1152 
   1153         // Exit if tone sequence is over
   1154         if (lpToneDesc->segments[lpToneGen->mCurSegment].duration == 0 ||
   1155             lpToneGen->mTotalSmp > lpToneGen->mMaxSmp) {
   1156             if (lpToneGen->mState == TONE_PLAYING) {
   1157                 lpToneGen->mState = TONE_STOPPING;
   1158             }
   1159             if (lpToneDesc->segments[lpToneGen->mCurSegment].duration == 0) {
   1160                 goto audioCallback_EndLoop;
   1161             }
   1162             // fade out before stopping if maximum duration reached
   1163             lWaveCmd = WaveGenerator::WAVEGEN_STOP;
   1164             lpToneGen->mNextSegSmp = TONEGEN_INF; // forced to skip state machine management below
   1165         }
   1166 
   1167         if (lpToneGen->mTotalSmp > lpToneGen->mNextSegSmp) {
   1168             // Time to go to next sequence segment
   1169 
   1170             ALOGV("End Segment, time: %d", (unsigned int)(systemTime()/1000000));
   1171 
   1172             lGenSmp = lReqSmp;
   1173 
   1174             // If segment,  ON -> OFF transition : ramp volume down
   1175             if (lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[0] != 0) {
   1176                 lWaveCmd = WaveGenerator::WAVEGEN_STOP;
   1177                 unsigned int lFreqIdx = 0;
   1178                 unsigned short lFrequency = lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[lFreqIdx];
   1179 
   1180                 while (lFrequency != 0) {
   1181                     WaveGenerator *lpWaveGen = lpToneGen->mWaveGens.valueFor(lFrequency);
   1182                     lpWaveGen->getSamples(lpOut, lGenSmp, lWaveCmd);
   1183                     lFrequency = lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[++lFreqIdx];
   1184                 }
   1185                 ALOGV("ON->OFF, lGenSmp: %d, lReqSmp: %d", lGenSmp, lReqSmp);
   1186             }
   1187 
   1188             // check if we need to loop and loop for the reqd times
   1189             if (lpToneDesc->segments[lpToneGen->mCurSegment].loopCnt) {
   1190                 if (lpToneGen->mLoopCounter < lpToneDesc->segments[lpToneGen->mCurSegment].loopCnt) {
   1191                     ALOGV ("in if loop loopCnt(%d) loopctr(%d), CurSeg(%d)",
   1192                           lpToneDesc->segments[lpToneGen->mCurSegment].loopCnt,
   1193                           lpToneGen->mLoopCounter,
   1194                           lpToneGen->mCurSegment);
   1195                     lpToneGen->mCurSegment = lpToneDesc->segments[lpToneGen->mCurSegment].loopIndx;
   1196                     ++lpToneGen->mLoopCounter;
   1197                 } else {
   1198                     // completed loop. go to next segment
   1199                     lpToneGen->mLoopCounter = 0;
   1200                     lpToneGen->mCurSegment++;
   1201                     ALOGV ("in else loop loopCnt(%d) loopctr(%d), CurSeg(%d)",
   1202                           lpToneDesc->segments[lpToneGen->mCurSegment].loopCnt,
   1203                           lpToneGen->mLoopCounter,
   1204                           lpToneGen->mCurSegment);
   1205                 }
   1206             } else {
   1207                 lpToneGen->mCurSegment++;
   1208                 ALOGV ("Goto next seg loopCnt(%d) loopctr(%d), CurSeg(%d)",
   1209                       lpToneDesc->segments[lpToneGen->mCurSegment].loopCnt,
   1210                       lpToneGen->mLoopCounter,
   1211                       lpToneGen->mCurSegment);
   1212 
   1213             }
   1214 
   1215             // Handle loop if last segment reached
   1216             if (lpToneDesc->segments[lpToneGen->mCurSegment].duration == 0) {
   1217                 ALOGV("Last Seg: %d", lpToneGen->mCurSegment);
   1218 
   1219                 // Pre increment loop count and restart if total count not reached. Stop sequence otherwise
   1220                 if (++lpToneGen->mCurCount <= lpToneDesc->repeatCnt) {
   1221                     ALOGV("Repeating Count: %d", lpToneGen->mCurCount);
   1222 
   1223                     lpToneGen->mCurSegment = lpToneDesc->repeatSegment;
   1224                     if (lpToneDesc->segments[lpToneDesc->repeatSegment].waveFreq[0] != 0) {
   1225                         lWaveCmd = WaveGenerator::WAVEGEN_START;
   1226                     }
   1227 
   1228                     ALOGV("New segment %d, Next Time: %d", lpToneGen->mCurSegment,
   1229                             (lpToneGen->mNextSegSmp*1000)/lpToneGen->mSamplingRate);
   1230 
   1231                 } else {
   1232                     lGenSmp = 0;
   1233                     ALOGV("End repeat, time: %d", (unsigned int)(systemTime()/1000000));
   1234                 }
   1235             } else {
   1236                 ALOGV("New segment %d, Next Time: %d", lpToneGen->mCurSegment,
   1237                         (lpToneGen->mNextSegSmp*1000)/lpToneGen->mSamplingRate);
   1238                 if (lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[0] != 0) {
   1239                     // If next segment is not silent,  OFF -> ON transition : reset wave generator
   1240                     lWaveCmd = WaveGenerator::WAVEGEN_START;
   1241 
   1242                     ALOGV("OFF->ON, lGenSmp: %d, lReqSmp: %d", lGenSmp, lReqSmp);
   1243                 } else {
   1244                     lGenSmp = 0;
   1245                 }
   1246             }
   1247 
   1248             // Update next segment transition position. No harm to do it also for last segment as lpToneGen->mNextSegSmp won't be used any more
   1249             lpToneGen->mNextSegSmp
   1250                     += (lpToneDesc->segments[lpToneGen->mCurSegment].duration * lpToneGen->mSamplingRate) / 1000;
   1251 
   1252         } else {
   1253             // Inside a segment keep tone ON or OFF
   1254             if (lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[0] == 0) {
   1255                 lGenSmp = 0;  // If odd segment, tone is currently OFF
   1256             } else {
   1257                 lGenSmp = lReqSmp;  // If event segment, tone is currently ON
   1258             }
   1259         }
   1260 
   1261         if (lGenSmp) {
   1262             // If samples must be generated, call all active wave generators and acumulate waves in lpOut
   1263             unsigned int lFreqIdx = 0;
   1264             unsigned short lFrequency = lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[lFreqIdx];
   1265 
   1266             while (lFrequency != 0) {
   1267                 WaveGenerator *lpWaveGen = lpToneGen->mWaveGens.valueFor(lFrequency);
   1268                 lpWaveGen->getSamples(lpOut, lGenSmp, lWaveCmd);
   1269                 lFrequency = lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[++lFreqIdx];
   1270             }
   1271         }
   1272 
   1273         lNumSmp -= lReqSmp;
   1274         lpOut += lReqSmp;
   1275 
   1276 audioCallback_EndLoop:
   1277 
   1278         switch (lpToneGen->mState) {
   1279         case TONE_RESTARTING:
   1280             ALOGV("Cbk restarting track");
   1281             if (lpToneGen->prepareWave()) {
   1282                 lpToneGen->mState = TONE_STARTING;
   1283                 if (clock_gettime(CLOCK_MONOTONIC, &lpToneGen->mStartTime) != 0) {
   1284                     lpToneGen->mStartTime.tv_sec = 0;
   1285                 }
   1286                 // must reload lpToneDesc as prepareWave() may change mpToneDesc
   1287                 lpToneDesc = lpToneGen->mpToneDesc;
   1288             } else {
   1289                 ALOGW("Cbk restarting prepareWave() failed");
   1290                 lpToneGen->mState = TONE_IDLE;
   1291                 lpToneGen->mpAudioTrack->stop();
   1292                 // Force loop exit
   1293                 lNumSmp = 0;
   1294             }
   1295             lSignal = true;
   1296             break;
   1297         case TONE_STOPPING:
   1298             ALOGV("Cbk Stopping");
   1299             lpToneGen->mState = TONE_STOPPED;
   1300             // Force loop exit
   1301             lNumSmp = 0;
   1302             break;
   1303         case TONE_STOPPED:
   1304             lpToneGen->mState = TONE_INIT;
   1305             ALOGV("Cbk Stopped track");
   1306             lpToneGen->mpAudioTrack->stop();
   1307             // Force loop exit
   1308             lNumSmp = 0;
   1309             buffer->size = 0;
   1310             lSignal = true;
   1311             break;
   1312         case TONE_STARTING:
   1313             ALOGV("Cbk starting track");
   1314             lpToneGen->mState = TONE_PLAYING;
   1315             lSignal = true;
   1316             break;
   1317         case TONE_PLAYING:
   1318             break;
   1319         default:
   1320             // Force loop exit
   1321             lNumSmp = 0;
   1322             buffer->size = 0;
   1323             break;
   1324         }
   1325 
   1326         if (lSignal)
   1327             lpToneGen->mWaitCbkCond.broadcast();
   1328         lpToneGen->mLock.unlock();
   1329     }
   1330 }
   1331 
   1332 
   1333 ////////////////////////////////////////////////////////////////////////////////
   1334 //
   1335 //    Method:        ToneGenerator::prepareWave()
   1336 //
   1337 //    Description:    Prepare wave generators and reset tone sequencer state machine.
   1338 //      mpNewToneDesc must have been initialized before calling this function.
   1339 //    Input:
   1340 //        none
   1341 //
   1342 //    Output:
   1343 //        returned value:   true if wave generators have been created, false otherwise
   1344 //
   1345 ////////////////////////////////////////////////////////////////////////////////
   1346 bool ToneGenerator::prepareWave() {
   1347     unsigned int segmentIdx = 0;
   1348 
   1349     if (mpNewToneDesc == NULL) {
   1350         return false;
   1351     }
   1352 
   1353     // Remove existing wave generators if any
   1354     clearWaveGens();
   1355 
   1356     mpToneDesc = mpNewToneDesc;
   1357 
   1358     if (mDurationMs == -1) {
   1359         mMaxSmp = TONEGEN_INF;
   1360     } else {
   1361         if (mDurationMs > (int)(TONEGEN_INF / mSamplingRate)) {
   1362             mMaxSmp = (mDurationMs / 1000) * mSamplingRate;
   1363         } else {
   1364             mMaxSmp = (mDurationMs * mSamplingRate) / 1000;
   1365         }
   1366         ALOGV("prepareWave, duration limited to %d ms", mDurationMs);
   1367     }
   1368 
   1369     while (mpToneDesc->segments[segmentIdx].duration) {
   1370         // Get total number of sine waves: needed to adapt sine wave gain.
   1371         unsigned int lNumWaves = numWaves(segmentIdx);
   1372         unsigned int freqIdx = 0;
   1373         unsigned int frequency = mpToneDesc->segments[segmentIdx].waveFreq[freqIdx];
   1374         while (frequency) {
   1375             // Instantiate a wave generator if  ot already done for this frequency
   1376             if (mWaveGens.indexOfKey(frequency) == NAME_NOT_FOUND) {
   1377                 ToneGenerator::WaveGenerator *lpWaveGen =
   1378                         new ToneGenerator::WaveGenerator((unsigned short)mSamplingRate,
   1379                                 frequency,
   1380                                 TONEGEN_GAIN/lNumWaves);
   1381                 mWaveGens.add(frequency, lpWaveGen);
   1382             }
   1383             frequency = mpNewToneDesc->segments[segmentIdx].waveFreq[++freqIdx];
   1384         }
   1385         segmentIdx++;
   1386     }
   1387 
   1388     // Initialize tone sequencer
   1389     mTotalSmp = 0;
   1390     mCurSegment = 0;
   1391     mCurCount = 0;
   1392     mLoopCounter = 0;
   1393     if (mpToneDesc->segments[0].duration == TONEGEN_INF) {
   1394         mNextSegSmp = TONEGEN_INF;
   1395     } else{
   1396         mNextSegSmp = (mpToneDesc->segments[0].duration * mSamplingRate) / 1000;
   1397     }
   1398 
   1399     return true;
   1400 }
   1401 
   1402 
   1403 ////////////////////////////////////////////////////////////////////////////////
   1404 //
   1405 //    Method:        ToneGenerator::numWaves()
   1406 //
   1407 //    Description:    Count number of sine waves needed to generate a tone segment (e.g 2 for DTMF).
   1408 //
   1409 //    Input:
   1410 //        segmentIdx        tone segment index
   1411 //
   1412 //    Output:
   1413 //        returned value:    nummber of sine waves
   1414 //
   1415 ////////////////////////////////////////////////////////////////////////////////
   1416 unsigned int ToneGenerator::numWaves(unsigned int segmentIdx) {
   1417     unsigned int lCnt = 0;
   1418 
   1419     if (mpToneDesc->segments[segmentIdx].duration) {
   1420         while (mpToneDesc->segments[segmentIdx].waveFreq[lCnt]) {
   1421             lCnt++;
   1422         }
   1423         lCnt++;
   1424     }
   1425 
   1426     return lCnt;
   1427 }
   1428 
   1429 
   1430 ////////////////////////////////////////////////////////////////////////////////
   1431 //
   1432 //    Method:        ToneGenerator::clearWaveGens()
   1433 //
   1434 //    Description:    Removes all wave generators.
   1435 //
   1436 //    Input:
   1437 //        none
   1438 //
   1439 //    Output:
   1440 //        none
   1441 //
   1442 ////////////////////////////////////////////////////////////////////////////////
   1443 void ToneGenerator::clearWaveGens() {
   1444     ALOGV("Clearing mWaveGens:");
   1445 
   1446     for (size_t lIdx = 0; lIdx < mWaveGens.size(); lIdx++) {
   1447         delete mWaveGens.valueAt(lIdx);
   1448     }
   1449     mWaveGens.clear();
   1450 }
   1451 
   1452 ////////////////////////////////////////////////////////////////////////////////
   1453 //
   1454 //    Method:       ToneGenerator::getToneForRegion()
   1455 //
   1456 //    Description:  Get correct ringtone type according to current region.
   1457 //      The corrected ring tone type is the tone descriptor index in sToneDescriptors[].
   1458 //
   1459 //    Input:
   1460 //        none
   1461 //
   1462 //    Output:
   1463 //        none
   1464 //
   1465 ////////////////////////////////////////////////////////////////////////////////
   1466 ToneGenerator::tone_type ToneGenerator::getToneForRegion(tone_type toneType) {
   1467     tone_type regionTone;
   1468 
   1469     if (mRegion == CEPT || toneType < FIRST_SUP_TONE || toneType > LAST_SUP_TONE) {
   1470         regionTone = toneType;
   1471     } else {
   1472         regionTone = (tone_type) sToneMappingTable[mRegion][toneType - FIRST_SUP_TONE];
   1473     }
   1474 
   1475     ALOGV("getToneForRegion, tone %d, region %d, regionTone %d", toneType, mRegion, regionTone);
   1476 
   1477     return regionTone;
   1478 }
   1479 
   1480 
   1481 ////////////////////////////////////////////////////////////////////////////////
   1482 //                WaveGenerator::WaveGenerator class    Implementation
   1483 ////////////////////////////////////////////////////////////////////////////////
   1484 
   1485 //---------------------------------- public methods ----------------------------
   1486 
   1487 ////////////////////////////////////////////////////////////////////////////////
   1488 //
   1489 //    Method:        WaveGenerator::WaveGenerator()
   1490 //
   1491 //    Description:    Constructor.
   1492 //
   1493 //    Input:
   1494 //        samplingRate:    Output sampling rate in Hz
   1495 //        frequency:       Frequency of the sine wave to generate in Hz
   1496 //        volume:          volume (0.0 to 1.0)
   1497 //
   1498 //    Output:
   1499 //        none
   1500 //
   1501 ////////////////////////////////////////////////////////////////////////////////
   1502 ToneGenerator::WaveGenerator::WaveGenerator(unsigned short samplingRate,
   1503         unsigned short frequency, float volume) {
   1504     double d0;
   1505     double F_div_Fs;  // frequency / samplingRate
   1506 
   1507     F_div_Fs = frequency / (double)samplingRate;
   1508     d0 = - (float)GEN_AMP * sin(2 * M_PI * F_div_Fs);
   1509     mS2_0 = (short)d0;
   1510     mS1 = 0;
   1511     mS2 = mS2_0;
   1512 
   1513     mAmplitude_Q15 = (short)(32767. * 32767. * volume / GEN_AMP);
   1514     // take some margin for amplitude fluctuation
   1515     if (mAmplitude_Q15 > 32500)
   1516         mAmplitude_Q15 = 32500;
   1517 
   1518     d0 = 32768.0 * cos(2 * M_PI * F_div_Fs);  // Q14*2*cos()
   1519     if (d0 > 32767)
   1520         d0 = 32767;
   1521     mA1_Q14 = (short) d0;
   1522 
   1523     ALOGV("WaveGenerator init, mA1_Q14: %d, mS2_0: %d, mAmplitude_Q15: %d",
   1524             mA1_Q14, mS2_0, mAmplitude_Q15);
   1525 }
   1526 
   1527 ////////////////////////////////////////////////////////////////////////////////
   1528 //
   1529 //    Method:        WaveGenerator::~WaveGenerator()
   1530 //
   1531 //    Description:    Destructor.
   1532 //
   1533 //    Input:
   1534 //        none
   1535 //
   1536 //    Output:
   1537 //        none
   1538 //
   1539 ////////////////////////////////////////////////////////////////////////////////
   1540 ToneGenerator::WaveGenerator::~WaveGenerator() {
   1541 }
   1542 
   1543 ////////////////////////////////////////////////////////////////////////////////
   1544 //
   1545 //    Method:        WaveGenerator::getSamples()
   1546 //
   1547 //    Description:    Generates count samples of a sine wave and accumulates
   1548 //        result in outBuffer.
   1549 //
   1550 //    Input:
   1551 //        outBuffer:      Output buffer where to accumulate samples.
   1552 //        count:          number of samples to produce.
   1553 //        command:        special action requested (see enum gen_command).
   1554 //
   1555 //    Output:
   1556 //        none
   1557 //
   1558 ////////////////////////////////////////////////////////////////////////////////
   1559 void ToneGenerator::WaveGenerator::getSamples(short *outBuffer,
   1560         unsigned int count, unsigned int command) {
   1561     long lS1, lS2;
   1562     long lA1, lAmplitude;
   1563     long Sample;  // current sample
   1564 
   1565     // init local
   1566     if (command == WAVEGEN_START) {
   1567         lS1 = (long)0;
   1568         lS2 = (long)mS2_0;
   1569     } else {
   1570         lS1 = (long)mS1;
   1571         lS2 = (long)mS2;
   1572     }
   1573     lA1 = (long)mA1_Q14;
   1574     lAmplitude = (long)mAmplitude_Q15;
   1575 
   1576     if (command == WAVEGEN_STOP) {
   1577         lAmplitude <<= 16;
   1578         if (count == 0) {
   1579             return;
   1580         }
   1581         long dec = lAmplitude/count;
   1582         // loop generation
   1583         while (count--) {
   1584             Sample = ((lA1 * lS1) >> S_Q14) - lS2;
   1585             // shift delay
   1586             lS2 = lS1;
   1587             lS1 = Sample;
   1588             Sample = ((lAmplitude>>16) * Sample) >> S_Q15;
   1589             *(outBuffer++) += (short)Sample;  // put result in buffer
   1590             lAmplitude -= dec;
   1591         }
   1592     } else {
   1593         // loop generation
   1594         while (count--) {
   1595             Sample = ((lA1 * lS1) >> S_Q14) - lS2;
   1596             // shift delay
   1597             lS2 = lS1;
   1598             lS1 = Sample;
   1599             Sample = (lAmplitude * Sample) >> S_Q15;
   1600             *(outBuffer++) += (short)Sample;  // put result in buffer
   1601         }
   1602     }
   1603 
   1604     // save status
   1605     mS1 = (short)lS1;
   1606     mS2 = (short)lS2;
   1607 }
   1608 
   1609 }  // end namespace android
   1610