189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project/*
289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *
489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * you may not use this file except in compliance with the License.
689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * You may obtain a copy of the License at
789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *
889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *
1089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
1189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
1289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * See the License for the specific language governing permissions and
1489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * limitations under the License.
1589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project */
1689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
1789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#ifndef ANDROID_TONEGENERATOR_H_
1889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#define ANDROID_TONEGENERATOR_H_
1989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
2089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <utils/RefBase.h>
210b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent#include <utils/KeyedVector.h>
2289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <utils/threads.h>
2389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <media/AudioSystem.h>
2489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <media/AudioTrack.h>
2589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
2689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectnamespace android {
2789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
2889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectclass ToneGenerator {
2989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectpublic:
3089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
3189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // List of all available tones
3289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // This enum must be kept consistant with constants in ToneGenerator JAVA class
3389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    enum tone_type {
3489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // DTMF tones  ITU-T Recommendation Q.23
3589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        TONE_DTMF_0 = 0,  // 0 key: 1336Hz, 941Hz
3689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        TONE_DTMF_1,  // 1 key: 1209Hz, 697Hz
3789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        TONE_DTMF_2,  // 2 key: 1336Hz, 697Hz
3889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        TONE_DTMF_3,  // 3 key: 1477Hz, 697Hz
3989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        TONE_DTMF_4,  // 4 key: 1209Hz, 770Hz
4089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        TONE_DTMF_5,  // 5 key: 1336Hz, 770Hz
4189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        TONE_DTMF_6,  // 6 key: 1477Hz, 770Hz
4289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        TONE_DTMF_7,  // 7 key: 1209Hz, 852Hz
4389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        TONE_DTMF_8,  // 8 key: 1336Hz, 852Hz
4489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        TONE_DTMF_9,  // 9 key: 1477Hz, 852Hz
4589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        TONE_DTMF_S,  // * key: 1209Hz, 941Hz
4689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        TONE_DTMF_P,  // # key: 1477Hz, 941Hz
4789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        TONE_DTMF_A,  // A key: 1633Hz, 697Hz
4889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        TONE_DTMF_B,  // B key: 1633Hz, 770Hz
4989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        TONE_DTMF_C,  // C key: 1633Hz, 852Hz
5089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        TONE_DTMF_D,  // D key: 1633Hz, 941Hz
5189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // Call supervisory tones:  3GPP TS 22.001 (CEPT)
520b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent        TONE_SUP_DIAL,  // Dial tone: CEPT: 425Hz, continuous
530b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent        FIRST_SUP_TONE = TONE_SUP_DIAL,
540b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent        TONE_SUP_BUSY,  // Busy tone, CEPT: 425Hz, 500ms ON, 500ms OFF...
550b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent        TONE_SUP_CONGESTION,  // Congestion tone CEPT, JAPAN: 425Hz, 200ms ON, 200ms OFF...
560b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent        TONE_SUP_RADIO_ACK,  // Radio path acknowlegment, CEPT, ANSI: 425Hz, 200ms ON
5789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        TONE_SUP_RADIO_NOTAVAIL,  // Radio path not available: 425Hz, 200ms ON, 200 OFF 3 bursts
5889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        TONE_SUP_ERROR,  // Error/Special info:  950Hz+1400Hz+1800Hz, 330ms ON, 1s OFF...
590b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent        TONE_SUP_CALL_WAITING,  // Call Waiting CEPT,JAPAN:  425Hz, 200ms ON, 600ms OFF, 200ms ON, 3s OFF...
600b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent        TONE_SUP_RINGTONE,  // Ring Tone CEPT, JAPAN:  425Hz, 1s ON, 4s OFF...
610b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent        LAST_SUP_TONE = TONE_SUP_RINGTONE,
6289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // Proprietary tones:  3GPP TS 31.111
6389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        TONE_PROP_BEEP,  // General beep: 400Hz+1200Hz, 35ms ON
6489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        TONE_PROP_ACK,  // Positive Acknowlgement: 1200Hz, 100ms ON, 100ms OFF 2 bursts
650b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent        TONE_PROP_NACK,  // Negative Acknowlgement: 300Hz+400Hz+500Hz, 400ms ON
6689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        TONE_PROP_PROMPT,  // Prompt tone: 400Hz+1200Hz, 200ms ON
6789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        TONE_PROP_BEEP2,  // General double beep: 400Hz+1200Hz, 35ms ON, 200ms OFF, 35ms on
680b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent        // Additional call supervisory tones: specified by IS-95 only
690b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent        TONE_SUP_INTERCEPT, // Intercept tone: alternating 440 Hz and 620 Hz tones, each on for 250 ms.
700b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent        TONE_SUP_INTERCEPT_ABBREV, // Abbreviated intercept: intercept tone limited to 4 seconds
710b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent        TONE_SUP_CONGESTION_ABBREV, // Abbreviated congestion: congestion tone limited to 4 seconds
720b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent        TONE_SUP_CONFIRM, // Confirm tone: a 350 Hz tone added to a 440 Hz tone repeated 3 times in a 100 ms on, 100 ms off cycle.
730b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent        TONE_SUP_PIP, // Pip tone: four bursts of 480 Hz tone (0.1 s on, 0.1 s off).
745e0a3043af16bc71a4211ee00dc00724de6623a7David Krause
755e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        // CDMA Tones
765e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_DIAL_TONE_LITE,
775e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_NETWORK_USA_RINGBACK,
785e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_INTERCEPT,
795e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_ABBR_INTERCEPT,
805e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_REORDER,
815e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_ABBR_REORDER,
825e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_NETWORK_BUSY,
835e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_CONFIRM,
845e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_ANSWER,
855e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_NETWORK_CALLWAITING,
865e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_PIP,
875e0a3043af16bc71a4211ee00dc00724de6623a7David Krause
885e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        // ISDN
895e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_CALL_SIGNAL_ISDN_NORMAL,  // ISDN Alert Normal
905e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_CALL_SIGNAL_ISDN_INTERGROUP, // ISDN Intergroup
915e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_CALL_SIGNAL_ISDN_SP_PRI, // ISDN SP PRI
925e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_CALL_SIGNAL_ISDN_PAT3,  // ISDN Alert PAT3
935e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_CALL_SIGNAL_ISDN_PING_RING, // ISDN Alert PING RING
945e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_CALL_SIGNAL_ISDN_PAT5,  // ISDN Alert PAT5
955e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_CALL_SIGNAL_ISDN_PAT6,  // ISDN Alert PAT6
965e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_CALL_SIGNAL_ISDN_PAT7,  // ISDN Alert PAT7
975e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        // ISDN end
985e0a3043af16bc71a4211ee00dc00724de6623a7David Krause
995e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        // IS54
1005e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_HIGH_L,  // IS54 High Pitch Long
1015e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_MED_L, // IS54 Med Pitch Long
1025e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_LOW_L, // IS54 Low Pitch Long
1035e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_HIGH_SS, // IS54 High Pitch Short Short
1045e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_MED_SS, // IS54 Medium Pitch Short Short
1055e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_LOW_SS, // IS54 Low Pitch Short Short
1065e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_HIGH_SSL, // IS54 High Pitch Short Short Long
1075e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_MED_SSL, // IS54 Medium  Pitch Short Short Long
1085e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_LOW_SSL, // IS54 Low  Pitch Short Short Long
1095e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_HIGH_SS_2, // IS54 High Pitch Short Short 2
1105e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_MED_SS_2, // IS54 Med Pitch Short Short 2
1115e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_LOW_SS_2, // IS54 Low  Pitch Short Short 2
1125e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_HIGH_SLS, // IS54 High Pitch Short Long Short
1135e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_MED_SLS, // IS54 Med Pitch Short Long Short
1145e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_LOW_SLS, // IS54 Low Pitch Short Long Short
1155e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_HIGH_S_X4, // IS54 High Pitch Short Short Short Short
1165e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_MED_S_X4, // IS54 Med Pitch Short Short Short Short
1175e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_LOW_S_X4, // IS54 Low Pitch Short Short Short Short
1185e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_HIGH_PBX_L, // PBX High Pitch Long
1195e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_MED_PBX_L, // PBX Med Pitch Long
1205e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_LOW_PBX_L, // PBX Low  Pitch Long
1215e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_HIGH_PBX_SS, // PBX High Short Short
1225e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_MED_PBX_SS, // PBX Med Short Short
1235e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_LOW_PBX_SS, // PBX Low  Short Short
1245e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_HIGH_PBX_SSL, // PBX High Short Short Long
1255e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_MED_PBX_SSL, // PBX Med Short Short Long
1265e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_LOW_PBX_SSL,  // PBX Low Short Short Long
1275e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_HIGH_PBX_SLS, // PBX High  SLS
1285e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_MED_PBX_SLS,  // PBX Med SLS
1295e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_LOW_PBX_SLS, // PBX Low SLS
1305e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_HIGH_PBX_S_X4, // PBX High SSSS
1315e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_MED_PBX_S_X4, // PBX Med SSSS
1325e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_LOW_PBX_S_X4, // PBX LOW SSSS
1335e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        //IS54 end
1345e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        // proprietary
1355e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_ALERT_NETWORK_LITE,
1365e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_ALERT_AUTOREDIAL_LITE,
1375e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_ONE_MIN_BEEP,
1385e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_KEYPAD_VOLUME_KEY_LITE,
1395e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_PRESSHOLDKEY_LITE,
1405e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_ALERT_INCALL_LITE,
1415e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_EMERGENCY_RINGBACK,
1425e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_ALERT_CALL_GUARD,
1435e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_SOFT_ERROR_LITE,
1445e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_CALLDROP_LITE,
1455e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        // proprietary end
1465e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_NETWORK_BUSY_ONE_SHOT,
1475e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_ABBR_ALERT,
1485e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        TONE_CDMA_SIGNAL_OFF,
1495e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        //CDMA end
1500b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent        NUM_TONES,
1510b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent        NUM_SUP_TONES = LAST_SUP_TONE-FIRST_SUP_TONE+1
15289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    };
15389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
154fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kasten    ToneGenerator(audio_stream_type_t streamType, float volume, bool threadCanCallJava = false);
15589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    ~ToneGenerator();
15689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
1573d2f877c1cb4e4ae4ddde7f57f4353de9341f11bGlenn Kasten    bool startTone(tone_type toneType, int durationMs = -1);
15889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    void stopTone();
15989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
16089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    bool isInited() { return (mState == TONE_IDLE)?false:true;}
16189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
162a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    // returns the audio session this ToneGenerator belongs to or 0 if an error occured.
163a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    int getSessionId() { return (mpAudioTrack == NULL) ? 0 : mpAudioTrack->getSessionId(); }
164a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
16589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectprivate:
16689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
16789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    enum tone_state {
16889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        TONE_IDLE,  // ToneGenerator is being initialized or initialization failed
16989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        TONE_INIT,  // ToneGenerator has been successfully initialized and is not playing
17089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        TONE_STARTING,  // ToneGenerator is starting playing
17189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        TONE_PLAYING,  // ToneGenerator is playing
17289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        TONE_STOPPING,  // ToneGenerator is stoping
173824b6a4a67166c3937400702944f659bd0d5d386Eric Laurent        TONE_STOPPED,  // ToneGenerator is stopped: the AudioTrack will be stopped
174824b6a4a67166c3937400702944f659bd0d5d386Eric Laurent        TONE_RESTARTING  // A start request was received in active state (playing or stopping)
17589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    };
17689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
1770b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent
1780b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent    // Region specific tones.
1790b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent    // These supervisory tones are different depending on the region (USA/CANADA, JAPAN, rest of the world).
1800b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent    // When a tone in the range [FIRST_SUP_TONE, LAST_SUP_TONE] is requested, the region is determined
1810b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent    // from system property gsm.operator.iso-country and the proper tone descriptor is selected with the
1820b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent    // help of sToneMappingTable[]
1830b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent    enum regional_tone_type {
1840b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent        // ANSI supervisory tones
1850b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent        TONE_ANSI_DIAL = NUM_TONES, // Dial tone: a continuous 350 Hz + 440 Hz tone.
1860b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent        TONE_ANSI_BUSY,             // Busy tone on:  a 480 Hz + 620 Hz tone repeated in a 500 ms on, 500 ms off cycle.
1870b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent        TONE_ANSI_CONGESTION,       // Network congestion (reorder) tone on:  a 480 Hz + 620 Hz tone repeated in a 250 ms on, 250 ms off cycle.
1880b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent        TONE_ANSI_CALL_WAITING,     // Call waiting tone on: 440 Hz, on for 300 ms, 9,7 s off followed by
1890b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent                                    // (440 Hz, on for 100 ms off for 100 ms, on for 100 ms, 9,7s off and repeated as necessary).
1900b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent        TONE_ANSI_RINGTONE,         // Ring Tone:  a 440 Hz + 480 Hz tone repeated in a 2 s on, 4 s off pattern.
1910b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent        // JAPAN Supervisory tones
1920b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent        TONE_JAPAN_DIAL,            // Dial tone: 400Hz, continuous
1930b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent        TONE_JAPAN_BUSY,            // Busy tone: 400Hz, 500ms ON, 500ms OFF...
1940b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent        TONE_JAPAN_RADIO_ACK,       // Radio path acknowlegment: 400Hz, 1s ON, 2s OFF...
1950b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent        NUM_ALTERNATE_TONES
1960b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent    };
1970b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent
1980b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent    enum region {
1990b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent        ANSI,
2000b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent        JAPAN,
2010b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent        CEPT,
2020b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent        NUM_REGIONS
2030b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent    };
2040b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent
2050b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent    static const unsigned char sToneMappingTable[NUM_REGIONS-1][NUM_SUP_TONES];
2060b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent
2070b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent    static const unsigned int TONEGEN_MAX_WAVES = 3;     // Maximun number of sine waves in a tone segment
2085e0a3043af16bc71a4211ee00dc00724de6623a7David Krause    static const unsigned int TONEGEN_MAX_SEGMENTS = 12;  // Maximun number of segments in a tone descriptor
20989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    static const unsigned int TONEGEN_INF = 0xFFFFFFFF;  // Represents infinite time duration
21089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    static const float TONEGEN_GAIN = 0.9;  // Default gain passed to  WaveGenerator().
21189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
21289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // ToneDescriptor class contains all parameters needed to generate a tone:
2130b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent    //    - The array waveFreq[]:
2140b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent    //         1 for static tone descriptors: contains the frequencies of all individual waves making the multi-tone.
2150b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent    //         2 for active tone descritors: contains the indexes of the WaveGenerator objects in mWaveGens
21689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    //        The number of sine waves varies from 1 to TONEGEN_MAX_WAVES.
21789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    //        The first null value indicates that no more waves are needed.
21889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    //    - The array segments[] is used to generate the tone pulses. A segment is a period of time
21989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    //        during which the tone is ON or OFF.    Segments with even index (starting from 0)
22089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    //        correspond to tone ON state and segments with odd index to OFF state.
22189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    //        The data stored in segments[] is the duration of the corresponding period in ms.
22289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    //        The first segment encountered with a 0 duration    indicates that no more segment follows.
2235e0a3043af16bc71a4211ee00dc00724de6623a7David Krause    //    - loopCnt - Number of times to repeat a sequence of seqments after playing this
2245e0a3043af16bc71a4211ee00dc00724de6623a7David Krause    //    - loopIndx - The segment index to go back and play is loopcnt > 0
22589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    //    - repeatCnt indicates the number of times the sequence described by segments[] array must be repeated.
2260b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent    //        When the tone generator encounters the first 0 duration segment, it will compare repeatCnt to mCurCount.
2270b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent    //        If mCurCount > repeatCnt, the tone is stopped automatically. Otherwise, tone sequence will be
2280b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent    //        restarted from segment repeatSegment.
2290b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent    //    - repeatSegment number of the first repeated segment when repeatCnt is not null
23089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
2310b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent    class ToneSegment {
23289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    public:
2330b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent        unsigned int duration;
23489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        unsigned short waveFreq[TONEGEN_MAX_WAVES+1];
2355e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        unsigned short loopCnt;
2365e0a3043af16bc71a4211ee00dc00724de6623a7David Krause        unsigned short loopIndx;
2370b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent    };
2380b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent
2390b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent    class ToneDescriptor {
2400b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent    public:
2410b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent        ToneSegment segments[TONEGEN_MAX_SEGMENTS+1];
24289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        unsigned long repeatCnt;
2430b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent        unsigned long repeatSegment;
24489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    };
24589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
2460b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent    static const ToneDescriptor sToneDescriptors[];
24789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
24834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    bool mThreadCanCallJava;
24989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    unsigned int mTotalSmp;  // Total number of audio samples played (gives current time)
25089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    unsigned int mNextSegSmp;  // Position of next segment transition expressed in samples
25189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // NOTE: because mTotalSmp, mNextSegSmp are stored on 32 bit, current design will operate properly
25289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // only if tone duration is less than about 27 Hours(@44100Hz sampling rate). If this time is exceeded,
25389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // no crash will occur but tone sequence will show a glitch.
25485fa14d35468acca07ce0085d67b909f673fae07Eric Laurent    unsigned int mMaxSmp;  // Maximum number of audio samples played (maximun tone duration)
255e33e00e931d1381d402484aa5cde67e540e3c82cEric Laurent    int mDurationMs;  // Maximum tone duration in ms
25689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
25789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    unsigned short mCurSegment;  // Current segment index in ToneDescriptor segments[]
25889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    unsigned short mCurCount;  // Current sequence repeat count
25989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    volatile unsigned short mState;  // ToneGenerator state (tone_state)
2600b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent    unsigned short mRegion;
26189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    const ToneDescriptor *mpToneDesc;  // pointer to active tone descriptor
26289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    const ToneDescriptor *mpNewToneDesc;  // pointer to next active tone descriptor
26389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
2645e0a3043af16bc71a4211ee00dc00724de6623a7David Krause    unsigned short mLoopCounter; // Current tone loopback count
2655e0a3043af16bc71a4211ee00dc00724de6623a7David Krause
26689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    int mSamplingRate;  // AudioFlinger Sampling rate
26789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    AudioTrack *mpAudioTrack;  // Pointer to audio track used for playback
26889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    Mutex mLock;  // Mutex to control concurent access to ToneGenerator object from audio callback and application API
26989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    Mutex mCbkCondLock; // Mutex associated to mWaitCbkCond
27089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    Condition mWaitCbkCond; // condition enabling interface to wait for audio callback completion after a change is requested
27189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    float mVolume;  // Volume applied to audio track
272fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kasten    audio_stream_type_t mStreamType; // Audio stream used for output
27389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    unsigned int mProcessSize;  // Size of audio blocks generated at a time by audioCallback() (in PCM frames).
27489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
27589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    bool initAudioTrack();
276d217a8c4632b3e3065f8c2a26b9ce4dc4c97171fGlenn Kasten    static void audioCallback(int event, void* user, void *info);
27789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    bool prepareWave();
2780b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent    unsigned int numWaves(unsigned int segmentIdx);
27989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    void clearWaveGens();
2803d2f877c1cb4e4ae4ddde7f57f4353de9341f11bGlenn Kasten    tone_type getToneForRegion(tone_type toneType);
28189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
28289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // WaveGenerator generates a single sine wave
28389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    class WaveGenerator {
28489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    public:
28589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        enum gen_command {
28689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            WAVEGEN_START,  // Start/restart wave from phase 0
28789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            WAVEGEN_CONT,  // Continue wave from current phase
28889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            WAVEGEN_STOP  // Stop wave on zero crossing
28989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        };
29089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
29189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        WaveGenerator(unsigned short samplingRate, unsigned short frequency,
29289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                float volume);
29389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        ~WaveGenerator();
29489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
29589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        void getSamples(short *outBuffer, unsigned int count,
29689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                unsigned int command);
29789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
29889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    private:
29989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        static const short GEN_AMP = 32000;  // amplitude of generator
30089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        static const short S_Q14 = 14;  // shift for Q14
30189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        static const short S_Q15 = 15;  // shift for Q15
30289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
30389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        short mA1_Q14;  // Q14 coefficient
30489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // delay line of full amplitude generator
30589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        short mS1, mS2;  // delay line S2 oldest
30689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        short mS2_0;  // saved value for reinitialisation
30789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        short mAmplitude_Q15;  // Q15 amplitude
30889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    };
30989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
3100b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent    KeyedVector<unsigned short, WaveGenerator *> mWaveGens;  // list of active wave generators.
31189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project};
31289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
31389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
31489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project;  // namespace android
31589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
31689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#endif /*ANDROID_TONEGENERATOR_H_*/
317