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