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