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