ToneGenerator.cpp revision 4afdfa7fd7e9fe59fb298ef2ac252686e68bc73a
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//#define LOG_NDEBUG 0 1889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#define LOG_TAG "ToneGenerator" 1989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <utils/threads.h> 2089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 2189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <stdio.h> 2289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <math.h> 2389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <utils/Log.h> 2489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <sys/resource.h> 2589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <utils/RefBase.h> 2689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <utils/Timers.h> 270b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent#include <cutils/properties.h> 2889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "media/ToneGenerator.h" 2989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 300b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent 3189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectnamespace android { 3289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 330b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent 3489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Descriptors for all available tones (See ToneGenerator::ToneDescriptor class declaration for details) 350b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurentconst ToneGenerator::ToneDescriptor ToneGenerator::sToneDescriptors[] = { 360b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: {{ duration: ToneGenerator::TONEGEN_INF, waveFreq: { 1336, 941, 0 }}, 370b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 380b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: ToneGenerator::TONEGEN_INF, 390b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_DTMF_0 400b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: ToneGenerator::TONEGEN_INF, waveFreq: { 1209, 697, 0 } }, 410b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 420b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: ToneGenerator::TONEGEN_INF, 430b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_DTMF_1 440b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: ToneGenerator::TONEGEN_INF, waveFreq: { 1336, 697, 0 } }, 450b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 460b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: ToneGenerator::TONEGEN_INF, 470b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_DTMF_2 480b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: ToneGenerator::TONEGEN_INF, waveFreq: { 1477, 697, 0 } }, 490b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 500b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: ToneGenerator::TONEGEN_INF, 510b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_DTMF_3 520b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: ToneGenerator::TONEGEN_INF, waveFreq: { 1209, 770, 0 } }, 530b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 540b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: ToneGenerator::TONEGEN_INF, 550b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_DTMF_4 560b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: ToneGenerator::TONEGEN_INF, waveFreq: { 1336, 770, 0 } }, 570b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 580b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: ToneGenerator::TONEGEN_INF, 590b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_DTMF_5 600b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: ToneGenerator::TONEGEN_INF, waveFreq: { 1477, 770, 0 } }, 610b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 620b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: ToneGenerator::TONEGEN_INF, 630b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_DTMF_6 640b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: ToneGenerator::TONEGEN_INF, waveFreq: { 1209, 852, 0 } }, 650b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 660b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: ToneGenerator::TONEGEN_INF, 670b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_DTMF_7 680b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: ToneGenerator::TONEGEN_INF, waveFreq: { 1336, 852, 0 } }, 690b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 700b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: ToneGenerator::TONEGEN_INF, 710b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_DTMF_8 720b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: ToneGenerator::TONEGEN_INF, waveFreq: { 1477, 852, 0 } }, 730b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 740b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: ToneGenerator::TONEGEN_INF, 750b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_DTMF_9 760b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: ToneGenerator::TONEGEN_INF, waveFreq: { 1209, 941, 0 } }, 770b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 780b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: ToneGenerator::TONEGEN_INF, 790b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_DTMF_S 800b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: ToneGenerator::TONEGEN_INF, waveFreq: { 1477, 941, 0 } }, 810b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 820b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: ToneGenerator::TONEGEN_INF, 830b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_DTMF_P 840b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: ToneGenerator::TONEGEN_INF, waveFreq: { 1633, 697, 0 } }, 850b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 860b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: ToneGenerator::TONEGEN_INF, 870b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_DTMF_A 880b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: ToneGenerator::TONEGEN_INF, waveFreq: { 1633, 770, 0 } }, 890b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 900b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: ToneGenerator::TONEGEN_INF, 910b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_DTMF_B 920b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: ToneGenerator::TONEGEN_INF, waveFreq: { 1633, 852, 0 } }, 930b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 940b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: ToneGenerator::TONEGEN_INF, 950b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_DTMF_C 960b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: ToneGenerator::TONEGEN_INF, waveFreq: { 1633, 941, 0 } }, 970b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 980b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: ToneGenerator::TONEGEN_INF, 990b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_DTMF_D 1000b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: ToneGenerator::TONEGEN_INF, waveFreq: { 425, 0 } }, 1010b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 1020b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: ToneGenerator::TONEGEN_INF, 1030b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_SUP_DIAL 1040b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: 500 , waveFreq: { 425, 0 }}, 1050b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 500, waveFreq: { 0 }}, 1060b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 1070b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: ToneGenerator::TONEGEN_INF, 1080b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_SUP_BUSY 1090b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: 200, waveFreq: { 425, 0 } }, 1100b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 200, waveFreq: { 0 } }, 1110b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 1120b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: ToneGenerator::TONEGEN_INF, 1130b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_SUP_CONGESTION 1140b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: 200, waveFreq: { 425, 0 } }, 1150b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 1160b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: 0, 1170b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_SUP_RADIO_ACK 1180b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: 200, waveFreq: { 425, 0 }}, 1190b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 200, waveFreq: { 0 }}, 1200b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 1210b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: 2, 1220b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_SUP_RADIO_NOTAVAIL 1230b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: 330, waveFreq: { 950, 1400, 1800, 0 }}, 1240b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 1000, waveFreq: { 0 } }, 1250b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 1260b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: ToneGenerator::TONEGEN_INF, 1270b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_SUP_ERROR 1280b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: 200, waveFreq: { 425, 0 } }, 1290b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 600, waveFreq: { 0 } }, 1300b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 200, waveFreq: { 425, 0 } }, 1310b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 3000, waveFreq: { 0 } }, 1320b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 1330b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: ToneGenerator::TONEGEN_INF, 1340b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_SUP_CALL_WAITING 1350b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: 1000, waveFreq: { 425, 0 } }, 1360b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 4000, waveFreq: { 0 } }, 1370b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 1380b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: ToneGenerator::TONEGEN_INF, 1390b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_SUP_RINGTONE 1400b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: 40, waveFreq: { 400, 1200, 0 } }, 1410b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 1420b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: 0, 1430b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_PROP_BEEP 1440b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: 100, waveFreq: { 1200, 0 } }, 1450b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 100, waveFreq: { 0 } }, 1460b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 1470b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: 1, 1480b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_PROP_ACK 1490b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: 400, waveFreq: { 300, 400, 500, 0 } }, 1500b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 1510b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: 0, 1520b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_PROP_NACK 1530b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: 200, waveFreq: { 400, 1200, 0 } }, 1540b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 1550b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: 0, 1560b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_PROP_PROMPT 1570b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: 40, waveFreq: { 400, 1200, 0 } }, 1580b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 200, waveFreq: { 0 } }, 1590b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 40, waveFreq: { 400, 1200, 0 } }, 1600b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 1610b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: 0, 1620b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_PROP_BEEP2 1630b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: 250, waveFreq: { 440, 0 } }, 1640b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 250, waveFreq: { 620, 0 } }, 1650b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 1660b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: ToneGenerator::TONEGEN_INF, 1670b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_SUP_INTERCEPT 1680b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: 250, waveFreq: { 440, 0 } }, 1690b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 250, waveFreq: { 620, 0 } }, 1700b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 1710b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: 7, 1720b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_SUP_INTERCEPT_ABBREV 1730b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: 250, waveFreq: { 480, 620, 0 } }, 1740b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 250, waveFreq: { 0 } }, 1750b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 1760b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: 7, 1770b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_SUP_CONGESTION_ABBREV 1780b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: 100, waveFreq: { 350, 440, 0 } }, 1790b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 100, waveFreq: { 0 } }, 1800b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 1810b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: 2, 1820b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_SUP_CONFIRM 1830b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: 100, waveFreq: { 480, 0 } }, 1840b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 100, waveFreq: { 0 } }, 1850b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 1860b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: 3, 1870b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_SUP_PIP 1880b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: ToneGenerator::TONEGEN_INF, waveFreq: { 350, 440, 0 } }, 1890b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 1900b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: ToneGenerator::TONEGEN_INF, 1910b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_ANSI_DIAL 1920b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: 500, waveFreq: { 480, 620, 0 } }, 1930b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 500, waveFreq: { 0 } }, 1940b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 1950b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: ToneGenerator::TONEGEN_INF, 1960b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_ANSI_BUSY 1970b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: 250, waveFreq: { 480, 620, 0 } }, 1980b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 250, waveFreq: { 0 } }, 1990b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 2000b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: ToneGenerator::TONEGEN_INF, 2010b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_ANSI_CONGESTION 2020b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: 300, waveFreq: { 440, 0 } }, 2030b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 9700, waveFreq: { 0 } }, 2040b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 100, waveFreq: { 440, 0 } }, 2050b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 100, waveFreq: { 0 } }, 2060b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 100, waveFreq: { 440, 0 } }, 2070b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 2080b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: ToneGenerator::TONEGEN_INF, 2090b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 1 }, // TONE_ANSI_CALL_WAITING 2100b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: 2000, waveFreq: { 440, 480, 0 } }, 2110b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 4000, waveFreq: { 0 } }, 2120b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 2130b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: ToneGenerator::TONEGEN_INF, 2140b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_ANSI_RINGTONE 2150b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: ToneGenerator::TONEGEN_INF, waveFreq: { 400, 0 } }, 2160b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 2170b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: ToneGenerator::TONEGEN_INF, 2180b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_JAPAN_DIAL 2190b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: 500, waveFreq: { 400, 0 } }, 2200b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 500, waveFreq: { 0 } }, 2210b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 2220b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: ToneGenerator::TONEGEN_INF, 2230b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_JAPAN_BUSY 2240b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { segments: { { duration: 1000, waveFreq: { 400, 0 } }, 2250b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 2000, waveFreq: { 0 } }, 2260b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { duration: 0 , waveFreq: { 0 }}}, 2270b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatCnt: ToneGenerator::TONEGEN_INF, 2280b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent repeatSegment: 0 }, // TONE_JAPAN_RADIO_ACK 2290b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent}; 2300b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent 2310b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent// Used by ToneGenerator::getToneForRegion() to convert user specified supervisory tone type 2320b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent// to actual tone for current region. 2330b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurentconst unsigned char ToneGenerator::sToneMappingTable[NUM_REGIONS-1][NUM_SUP_TONES] = { 2340b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { // ANSI 2350b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent TONE_ANSI_DIAL, // TONE_SUP_DIAL 2360b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent TONE_ANSI_BUSY, // TONE_SUP_BUSY 2370b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent TONE_ANSI_CONGESTION, // TONE_SUP_CONGESTION 2380b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent TONE_SUP_RADIO_ACK, // TONE_SUP_RADIO_ACK 2390b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent TONE_SUP_RADIO_NOTAVAIL, // TONE_SUP_RADIO_NOTAVAIL 2400b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent TONE_SUP_ERROR, // TONE_SUP_ERROR 2410b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent TONE_ANSI_CALL_WAITING, // TONE_SUP_CALL_WAITING 2420b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent TONE_ANSI_RINGTONE // TONE_SUP_RINGTONE 2430b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent }, 2440b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent { // JAPAN 2450b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent TONE_JAPAN_DIAL, // TONE_SUP_DIAL 2460b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent TONE_JAPAN_BUSY, // TONE_SUP_BUSY 2470b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent TONE_SUP_CONGESTION, // TONE_SUP_CONGESTION 2480b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent TONE_JAPAN_RADIO_ACK, // TONE_SUP_RADIO_ACK 2490b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent TONE_SUP_RADIO_NOTAVAIL, // TONE_SUP_RADIO_NOTAVAIL 2500b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent TONE_SUP_ERROR, // TONE_SUP_ERROR 2510b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent TONE_SUP_CALL_WAITING, // TONE_SUP_CALL_WAITING 2520b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent TONE_SUP_RINGTONE // TONE_SUP_RINGTONE 2530b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent } 2540b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent}; 2550b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent 25689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 25789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//////////////////////////////////////////////////////////////////////////////// 25889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ToneGenerator class Implementation 25989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//////////////////////////////////////////////////////////////////////////////// 26089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 26189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 26289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//---------------------------------- public methods ---------------------------- 26389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 26489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 26589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//////////////////////////////////////////////////////////////////////////////// 26689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 26789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Method: ToneGenerator::ToneGenerator() 26889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 26989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Description: Constructor. Initializes the tone sequencer, intantiates required sine wave 27089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// generators, instantiates output audio track. 27189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 27289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Input: 27389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// toneType: Type of tone generated (values in enum tone_type) 27489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// streamType: Type of stream used for tone playback (enum AudioTrack::stream_type) 27589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// volume: volume applied to tone (0.0 to 1.0) 27689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 27789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Output: 27889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// none 27989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 28089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//////////////////////////////////////////////////////////////////////////////// 28189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectToneGenerator::ToneGenerator(int streamType, float volume) { 28289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 28389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("ToneGenerator constructor: streamType=%d, volume=%f\n", streamType, volume); 28489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 28589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mState = TONE_IDLE; 28689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 28789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (AudioSystem::getOutputSamplingRate(&mSamplingRate, streamType) != NO_ERROR) { 28889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGE("Unable to marshal AudioFlinger"); 28989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return; 29089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 29189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mStreamType = streamType; 29289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mVolume = volume; 29389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mpAudioTrack = 0; 29489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mpToneDesc = 0; 29589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mpNewToneDesc = 0; 29689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Generate tone by chunks of 20 ms to keep cadencing precision 29789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mProcessSize = (mSamplingRate * 20) / 1000; 29889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 2990b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent char value[PROPERTY_VALUE_MAX]; 3000b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent property_get("gsm.operator.iso-country", value, ""); 3010b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent if (strcmp(value,"us") == 0 || 3020b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent strcmp(value,"ca") == 0) { 3030b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent mRegion = ANSI; 3040b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent } else if (strcmp(value,"jp") == 0) { 3050b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent mRegion = JAPAN; 3060b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent } else { 3070b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent mRegion = CEPT; 3080b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent } 3090b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent 31089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (initAudioTrack()) { 31189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("ToneGenerator INIT OK, time: %d\n", (unsigned int)(systemTime()/1000000)); 31289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 31389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("!!!ToneGenerator INIT FAILED!!!\n"); 31489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 31589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 31689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 31789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 31889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 31989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 32089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//////////////////////////////////////////////////////////////////////////////// 32189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 32289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Method: ToneGenerator::~ToneGenerator() 32389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 32489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Description: Destructor. Stop sound playback and delete audio track if 32589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// needed and delete sine wave generators. 32689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 32789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Input: 32889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// none 32989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 33089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Output: 33189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// none 33289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 33389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//////////////////////////////////////////////////////////////////////////////// 33489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectToneGenerator::~ToneGenerator() { 33589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("ToneGenerator destructor\n"); 33689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 33789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mpAudioTrack) { 33889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project stopTone(); 33989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("Delete Track: %p\n", mpAudioTrack); 34089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project delete mpAudioTrack; 34189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 34289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 34389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 34489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//////////////////////////////////////////////////////////////////////////////// 34589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 34689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Method: ToneGenerator::startTone() 34789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 34889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Description: Starts tone playback. 34989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 35089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Input: 35189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// none 35289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 35389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Output: 35489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// none 35589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 35689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//////////////////////////////////////////////////////////////////////////////// 35789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectbool ToneGenerator::startTone(int toneType) { 35889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project bool lResult = false; 35989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 3604afdfa7fd7e9fe59fb298ef2ac252686e68bc73aDave Sparks if ((toneType < 0) || (toneType >= NUM_TONES)) 36189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return lResult; 36289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 36389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mState == TONE_IDLE) { 36489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("startTone: try to re-init AudioTrack"); 36589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (!initAudioTrack()) { 36689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return lResult; 36789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 36889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 36989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 37089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("startTone\n"); 37189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 37289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mLock.lock(); 37389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 37489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Get descriptor for requested tone 3750b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent toneType = getToneForRegion(toneType); 3760b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent mpNewToneDesc = &sToneDescriptors[toneType]; 37789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 37889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mState == TONE_INIT) { 37989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (prepareWave()) { 38089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("Immediate start, time %d\n", (unsigned int)(systemTime()/1000000)); 38189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lResult = true; 38289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mState = TONE_STARTING; 38389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mLock.unlock(); 38489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mpAudioTrack->start(); 38589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mLock.lock(); 38689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mState == TONE_STARTING) { 38789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("Wait for start callback"); 3888365529381f6284f2d59dcc38e26f73adeec9c67The Android Open Source Project status_t lStatus = mWaitCbkCond.waitRelative(mLock, seconds(1)); 3898365529381f6284f2d59dcc38e26f73adeec9c67The Android Open Source Project if (lStatus != NO_ERROR) { 3908365529381f6284f2d59dcc38e26f73adeec9c67The Android Open Source Project LOGE("--- Immediate start timed out, status %d", lStatus); 39189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mState = TONE_IDLE; 39289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lResult = false; 39389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 39489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 39589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 39689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mState == TONE_IDLE; 39789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 39889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 39989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("Delayed start\n"); 40089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 40189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mState = TONE_RESTARTING; 4028365529381f6284f2d59dcc38e26f73adeec9c67The Android Open Source Project status_t lStatus = mWaitCbkCond.waitRelative(mLock, seconds(1)); 4038365529381f6284f2d59dcc38e26f73adeec9c67The Android Open Source Project if (lStatus == NO_ERROR) { 40489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mState != TONE_IDLE) { 40589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lResult = true; 40689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 40789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("cond received"); 40889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 4098365529381f6284f2d59dcc38e26f73adeec9c67The Android Open Source Project LOGE("--- Delayed start timed out, status %d", lStatus); 41089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mState = TONE_IDLE; 41189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 41289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 41389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mLock.unlock(); 41489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 41589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV_IF(lResult, "Tone started, time %d\n", (unsigned int)(systemTime()/1000000)); 41689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGW_IF(!lResult, "Tone start failed!!!, time %d\n", (unsigned int)(systemTime()/1000000)); 41789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 41889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return lResult; 41989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 42089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 42189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//////////////////////////////////////////////////////////////////////////////// 42289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 42389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Method: ToneGenerator::stopTone() 42489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 42589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Description: Stops tone playback. 42689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 42789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Input: 42889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// none 42989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 43089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Output: 43189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// none 43289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 43389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//////////////////////////////////////////////////////////////////////////////// 43489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectvoid ToneGenerator::stopTone() { 43589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("stopTone"); 43689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 43789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mLock.lock(); 43889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mState == TONE_PLAYING || mState == TONE_STARTING || mState == TONE_RESTARTING) { 43989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mState = TONE_STOPPING; 44089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("waiting cond"); 44189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project status_t lStatus = mWaitCbkCond.waitRelative(mLock, seconds(1)); 44289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (lStatus == NO_ERROR) { 44389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("track stop complete, time %d", (unsigned int)(systemTime()/1000000)); 44489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 44589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGE("--- Stop timed out"); 44689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mState = TONE_IDLE; 44789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mpAudioTrack->stop(); 44889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 44989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 45089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 45189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project clearWaveGens(); 45289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 45389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mLock.unlock(); 45489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 45589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 45689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//---------------------------------- private methods --------------------------- 45789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 45889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 45989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 46089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 46189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//////////////////////////////////////////////////////////////////////////////// 46289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 46389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Method: ToneGenerator::initAudioTrack() 46489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 46589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Description: Allocates and configures AudioTrack used for PCM output. 46689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 46789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Input: 46889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// none 46989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 47089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Output: 47189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// none 47289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 47389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//////////////////////////////////////////////////////////////////////////////// 47489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectbool ToneGenerator::initAudioTrack() { 47589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 47689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mpAudioTrack) { 47789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project delete mpAudioTrack; 47889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mpAudioTrack = 0; 47989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 48089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 48189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Open audio track in mono, PCM 16bit, default sampling rate, default buffer size 48289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mpAudioTrack 48389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project = new AudioTrack(mStreamType, 0, AudioSystem::PCM_16_BIT, 1, 0, 0, audioCallback, this, 0); 48489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 48589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mpAudioTrack == 0) { 48689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGE("AudioTrack allocation failed"); 48789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project goto initAudioTrack_exit; 48889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 48989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("Create Track: %p\n", mpAudioTrack); 49089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 49189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mpAudioTrack->initCheck() != NO_ERROR) { 49289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGE("AudioTrack->initCheck failed"); 49389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project goto initAudioTrack_exit; 49489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 49589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 49689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mpAudioTrack->setVolume(mVolume, mVolume); 49789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 49889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mState = TONE_INIT; 49989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 50089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return true; 50189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 50289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectinitAudioTrack_exit: 50389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 50489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Cleanup 50589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mpAudioTrack) { 50689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("Delete Track I: %p\n", mpAudioTrack); 50789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project delete mpAudioTrack; 50889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mpAudioTrack = 0; 50989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 51089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 51189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return false; 51289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 51389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 51489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 51589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//////////////////////////////////////////////////////////////////////////////// 51689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 51789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Method: ToneGenerator::audioCallback() 51889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 51989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Description: AudioTrack callback implementation. Generates a block of 52089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// PCM samples 52189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// and manages tone generator sequencer: tones pulses, tone duration... 52289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 52389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Input: 52489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// user reference (pointer to our ToneGenerator) 52589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// info audio buffer descriptor 52689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 52789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Output: 52889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// returned value: always true. 52989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 53089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//////////////////////////////////////////////////////////////////////////////// 53189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectvoid ToneGenerator::audioCallback(int event, void* user, void *info) { 53289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 53389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (event != AudioTrack::EVENT_MORE_DATA) return; 53489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 53589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project const AudioTrack::Buffer *buffer = static_cast<const AudioTrack::Buffer *>(info); 53689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ToneGenerator *lpToneGen = static_cast<ToneGenerator *>(user); 53789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project short *lpOut = buffer->i16; 53889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project unsigned int lNumSmp = buffer->size/sizeof(short); 5390b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent const ToneDescriptor *lpToneDesc = lpToneGen->mpToneDesc; 54089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 54189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (buffer->size == 0) return; 54289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 54389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 54489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Clear output buffer: WaveGenerator accumulates into lpOut buffer 54589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project memset(lpOut, 0, buffer->size); 54689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 54789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project while (lNumSmp) { 54889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project unsigned int lReqSmp = lNumSmp < lpToneGen->mProcessSize*2 ? lNumSmp : lpToneGen->mProcessSize; 54989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project unsigned int lGenSmp; 55089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project unsigned int lWaveCmd = WaveGenerator::WAVEGEN_CONT; 55189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project bool lSignal = false; 55289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 55389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lpToneGen->mLock.lock(); 55489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 55589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Update pcm frame count and end time (current time at the end of this process) 55689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lpToneGen->mTotalSmp += lReqSmp; 55789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 55889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Update tone gen state machine and select wave gen command 55989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project switch (lpToneGen->mState) { 56089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case TONE_PLAYING: 56189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lWaveCmd = WaveGenerator::WAVEGEN_CONT; 56289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 56389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case TONE_STARTING: 56489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("Starting Cbk"); 56589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 56689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lWaveCmd = WaveGenerator::WAVEGEN_START; 56789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 56889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case TONE_STOPPING: 56989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case TONE_RESTARTING: 57089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("Stop/restart Cbk"); 57189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 57289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lWaveCmd = WaveGenerator::WAVEGEN_STOP; 57389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lpToneGen->mNextSegSmp = TONEGEN_INF; // forced to skip state machine management below 57489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 57589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project default: 57689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("Extra Cbk"); 5778365529381f6284f2d59dcc38e26f73adeec9c67The Android Open Source Project // Force loop exit 5788365529381f6284f2d59dcc38e26f73adeec9c67The Android Open Source Project lNumSmp = 0; 57989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project goto audioCallback_EndLoop; 58089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 58189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 58289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 58389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Exit if tone sequence is over 5840b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent if (lpToneDesc->segments[lpToneGen->mCurSegment].duration == 0) { 58589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (lpToneGen->mState == TONE_PLAYING) { 58689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lpToneGen->mState = TONE_STOPPING; 58789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 58889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project goto audioCallback_EndLoop; 58989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 59089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 59189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (lpToneGen->mTotalSmp > lpToneGen->mNextSegSmp) { 59289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Time to go to next sequence segment 59389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 59489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("End Segment, time: %d\n", (unsigned int)(systemTime()/1000000)); 59589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 59689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lGenSmp = lReqSmp; 5970b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent 5980b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent // If segment, ON -> OFF transition : ramp volume down 5990b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent if (lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[0] != 0) { 60089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lWaveCmd = WaveGenerator::WAVEGEN_STOP; 6010b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent unsigned int lFreqIdx = 0; 6020b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent unsigned short lFrequency = lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[lFreqIdx]; 6030b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent 6040b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent while (lFrequency != 0) { 6050b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent WaveGenerator *lpWaveGen = lpToneGen->mWaveGens.valueFor(lFrequency); 6060b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent lpWaveGen->getSamples(lpOut, lGenSmp, lWaveCmd); 6070b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent lFrequency = lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[++lFreqIdx]; 6080b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent } 60989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("ON->OFF, lGenSmp: %d, lReqSmp: %d\n", lGenSmp, lReqSmp); 61089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 6110b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent 6120b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent // Go to next segment 6130b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent lpToneGen->mCurSegment++; 6140b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent 6150b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent // Handle loop if last segment reached 6160b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent if (lpToneDesc->segments[lpToneGen->mCurSegment].duration == 0) { 61789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("Last Seg: %d\n", lpToneGen->mCurSegment); 61889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 61989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Pre increment loop count and restart if total count not reached. Stop sequence otherwise 6200b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent if (++lpToneGen->mCurCount <= lpToneDesc->repeatCnt) { 62189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("Repeating Count: %d\n", lpToneGen->mCurCount); 62289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 6230b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent lpToneGen->mCurSegment = lpToneDesc->repeatSegment; 6240b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent if (lpToneDesc->segments[lpToneDesc->repeatSegment].waveFreq[0] != 0) { 6250b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent lWaveCmd = WaveGenerator::WAVEGEN_START; 6260b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent } 62789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 62889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("New segment %d, Next Time: %d\n", lpToneGen->mCurSegment, 62989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project (lpToneGen->mNextSegSmp*1000)/lpToneGen->mSamplingRate); 63089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 63189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 6320b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent lGenSmp = 0; 63389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("End repeat, time: %d\n", (unsigned int)(systemTime()/1000000)); 63489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 63589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 63689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("New segment %d, Next Time: %d\n", lpToneGen->mCurSegment, 63789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project (lpToneGen->mNextSegSmp*1000)/lpToneGen->mSamplingRate); 6380b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent if (lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[0] != 0) { 6390b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent // If next segment is not silent, OFF -> ON transition : reset wave generator 6400b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent lWaveCmd = WaveGenerator::WAVEGEN_START; 6410b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent 6420b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent LOGV("OFF->ON, lGenSmp: %d, lReqSmp: %d\n", lGenSmp, lReqSmp); 6430b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent } else { 6440b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent lGenSmp = 0; 6450b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent } 64689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 64789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 64889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Update next segment transition position. No harm to do it also for last segment as lpToneGen->mNextSegSmp won't be used any more 64989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lpToneGen->mNextSegSmp 6500b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent += (lpToneDesc->segments[lpToneGen->mCurSegment].duration * lpToneGen->mSamplingRate) / 1000; 65189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 65289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 65389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Inside a segment keep tone ON or OFF 6540b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent if (lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[0] == 0) { 65589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lGenSmp = 0; // If odd segment, tone is currently OFF 65689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 65789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lGenSmp = lReqSmp; // If event segment, tone is currently ON 65889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 65989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 66089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 66189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (lGenSmp) { 66289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // If samples must be generated, call all active wave generators and acumulate waves in lpOut 6630b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent unsigned int lFreqIdx = 0; 6640b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent unsigned short lFrequency = lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[lFreqIdx]; 66589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 6660b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent while (lFrequency != 0) { 6670b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent WaveGenerator *lpWaveGen = lpToneGen->mWaveGens.valueFor(lFrequency); 66889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lpWaveGen->getSamples(lpOut, lGenSmp, lWaveCmd); 6690b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent lFrequency = lpToneDesc->segments[lpToneGen->mCurSegment].waveFreq[++lFreqIdx]; 67089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 67189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 67289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 67389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lNumSmp -= lReqSmp; 67489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lpOut += lReqSmp; 67589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 67689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectaudioCallback_EndLoop: 67789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 67889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project switch (lpToneGen->mState) { 67989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case TONE_RESTARTING: 68089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("Cbk restarting track\n"); 68189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (lpToneGen->prepareWave()) { 68289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lpToneGen->mState = TONE_STARTING; 68389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 68489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGW("Cbk restarting prepareWave() failed\n"); 68589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lpToneGen->mState = TONE_IDLE; 68689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lpToneGen->mpAudioTrack->stop(); 68789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Force loop exit 68889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lNumSmp = 0; 68989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 69089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lSignal = true; 69189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 69289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case TONE_STOPPING: 69389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lpToneGen->mState = TONE_INIT; 69489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("Cbk Stopping track\n"); 69589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lSignal = true; 69689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lpToneGen->mpAudioTrack->stop(); 69789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 69889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Force loop exit 69989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lNumSmp = 0; 70089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 70189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case TONE_STARTING: 70289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("Cbk starting track\n"); 70389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lpToneGen->mState = TONE_PLAYING; 70489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lSignal = true; 70589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 70689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project default: 70789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 70889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 70989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 71089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (lSignal) 71189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lpToneGen->mWaitCbkCond.signal(); 71289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lpToneGen->mLock.unlock(); 71389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 71489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 71589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 71689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 71789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//////////////////////////////////////////////////////////////////////////////// 71889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 71989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Method: ToneGenerator::prepareWave() 72089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 72189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Description: Prepare wave generators and reset tone sequencer state machine. 7220b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent// mpNewToneDesc must have been initialized before calling this function. 72389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Input: 72489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// none 72589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 72689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Output: 72789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// returned value: true if wave generators have been created, false otherwise 72889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 72989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//////////////////////////////////////////////////////////////////////////////// 73089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectbool ToneGenerator::prepareWave() { 7310b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent unsigned int segmentIdx = 0; 73289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 73389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (!mpNewToneDesc) { 73489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return false; 73589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 7360b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent 73789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Remove existing wave generators if any 73889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project clearWaveGens(); 73989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 74089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mpToneDesc = mpNewToneDesc; 74189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 7420b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent while (mpToneDesc->segments[segmentIdx].duration) { 7430b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent // Get total number of sine waves: needed to adapt sine wave gain. 7440b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent unsigned int lNumWaves = numWaves(segmentIdx); 7450b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent unsigned int freqIdx = 0; 7460b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent unsigned int frequency = mpToneDesc->segments[segmentIdx].waveFreq[freqIdx]; 7470b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent while (frequency) { 7480b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent // Instantiate a wave generator if ot already done for this frequency 7490b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent if (mWaveGens.indexOfKey(frequency) == NAME_NOT_FOUND) { 7500b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent ToneGenerator::WaveGenerator *lpWaveGen = 7510b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent new ToneGenerator::WaveGenerator((unsigned short)mSamplingRate, 7520b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent frequency, 7530b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent TONEGEN_GAIN/lNumWaves); 7540b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent if (lpWaveGen == 0) { 7550b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent goto prepareWave_exit; 7560b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent } 7570b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent mWaveGens.add(frequency, lpWaveGen); 7580b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent } 7590b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent frequency = mpNewToneDesc->segments[segmentIdx].waveFreq[++freqIdx]; 76089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 7610b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent segmentIdx++; 76289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 76389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 76489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Initialize tone sequencer 76589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mTotalSmp = 0; 76689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mCurSegment = 0; 76789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mCurCount = 0; 7680b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent if (mpToneDesc->segments[0].duration == TONEGEN_INF) { 7690b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent mNextSegSmp = TONEGEN_INF; 7700b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent } else{ 7710b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent mNextSegSmp = (mpToneDesc->segments[0].duration * mSamplingRate) / 1000; 7720b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent } 77389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 77489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return true; 77589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 77689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectprepareWave_exit: 77789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 77889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project clearWaveGens(); 77989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 78089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return false; 78189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 78289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 78389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 78489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//////////////////////////////////////////////////////////////////////////////// 78589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 78689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Method: ToneGenerator::numWaves() 78789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 7880b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent// Description: Count number of sine waves needed to generate a tone segment (e.g 2 for DTMF). 78989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 79089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Input: 7910b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent// segmentIdx tone segment index 79289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 79389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Output: 79489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// returned value: nummber of sine waves 79589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 79689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//////////////////////////////////////////////////////////////////////////////// 7970b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurentunsigned int ToneGenerator::numWaves(unsigned int segmentIdx) { 79889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project unsigned int lCnt = 0; 79989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 8000b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent if (mpToneDesc->segments[segmentIdx].duration) { 8010b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent while (mpToneDesc->segments[segmentIdx].waveFreq[lCnt]) { 8020b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent lCnt++; 8030b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent } 80489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lCnt++; 80589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 80689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 80789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return lCnt; 80889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 80989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 81089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 81189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//////////////////////////////////////////////////////////////////////////////// 81289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 81389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Method: ToneGenerator::clearWaveGens() 81489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 81589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Description: Removes all wave generators. 81689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 81789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Input: 81889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// none 81989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 82089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Output: 82189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// none 82289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 82389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//////////////////////////////////////////////////////////////////////////////// 82489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectvoid ToneGenerator::clearWaveGens() { 82589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("Clearing mWaveGens:"); 82689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 8270b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent for (size_t lIdx = 0; lIdx < mWaveGens.size(); lIdx++) { 8280b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent delete mWaveGens.valueAt(lIdx); 82989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 8300b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent mWaveGens.clear(); 8310b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent} 8320b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent 8330b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent//////////////////////////////////////////////////////////////////////////////// 8340b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent// 8350b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent// Method: ToneGenerator::getToneForRegion() 8360b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent// 8370b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent// Description: Get correct ringtone type according to current region. 8380b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent// The corrected ring tone type is the tone descriptor index in sToneDescriptors[]. 8390b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent// 8400b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent// Input: 8410b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent// none 8420b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent// 8430b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent// Output: 8440b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent// none 8450b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent// 8460b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent//////////////////////////////////////////////////////////////////////////////// 8470b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurentint ToneGenerator::getToneForRegion(int toneType) { 8480b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent int regionTone; 8490b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent 8500b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent if (mRegion == CEPT || toneType < FIRST_SUP_TONE || toneType > LAST_SUP_TONE) { 8510b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent regionTone = toneType; 8520b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent } else { 8530b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent regionTone = sToneMappingTable[mRegion][toneType - FIRST_SUP_TONE]; 8540b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent } 8550b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent 8560b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent LOGV("getToneForRegion, tone %d, region %d, regionTone %d", toneType, mRegion, regionTone); 8570b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent 8580b62e242d112d46e9357242b0a4e11c720c98ca0Eric Laurent return regionTone; 85989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 86089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 86189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 86289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//////////////////////////////////////////////////////////////////////////////// 86389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// WaveGenerator::WaveGenerator class Implementation 86489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//////////////////////////////////////////////////////////////////////////////// 86589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 86689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//---------------------------------- public methods ---------------------------- 86789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 86889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//////////////////////////////////////////////////////////////////////////////// 86989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 87089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Method: WaveGenerator::WaveGenerator() 87189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 87289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Description: Constructor. 87389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 87489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Input: 87589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// samplingRate: Output sampling rate in Hz 87689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// frequency: Frequency of the sine wave to generate in Hz 87789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// volume: volume (0.0 to 1.0) 87889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 87989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Output: 88089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// none 88189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 88289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//////////////////////////////////////////////////////////////////////////////// 88389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectToneGenerator::WaveGenerator::WaveGenerator(unsigned short samplingRate, 88489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project unsigned short frequency, float volume) { 88589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project double d0; 88689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project double F_div_Fs; // frequency / samplingRate 88789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 88889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project F_div_Fs = frequency / (double)samplingRate; 88989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project d0 = - (float)GEN_AMP * sin(2 * M_PI * F_div_Fs); 89089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mS2_0 = (short)d0; 89189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mS1 = 0; 89289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mS2 = mS2_0; 89389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 89489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mAmplitude_Q15 = (short)(32767. * 32767. * volume / GEN_AMP); 89589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // take some margin for amplitude fluctuation 89689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mAmplitude_Q15 > 32500) 89789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mAmplitude_Q15 = 32500; 89889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 89989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project d0 = 32768.0 * cos(2 * M_PI * F_div_Fs); // Q14*2*cos() 90089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (d0 > 32767) 90189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project d0 = 32767; 90289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mA1_Q14 = (short) d0; 90389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 90489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGV("WaveGenerator init, mA1_Q14: %d, mS2_0: %d, mAmplitude_Q15: %d\n", 90589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mA1_Q14, mS2_0, mAmplitude_Q15); 90689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 90789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 90889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//////////////////////////////////////////////////////////////////////////////// 90989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 91089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Method: WaveGenerator::~WaveGenerator() 91189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 91289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Description: Destructor. 91389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 91489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Input: 91589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// none 91689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 91789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Output: 91889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// none 91989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 92089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//////////////////////////////////////////////////////////////////////////////// 92189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectToneGenerator::WaveGenerator::~WaveGenerator() { 92289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 92389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 92489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//////////////////////////////////////////////////////////////////////////////// 92589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 92689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Method: WaveGenerator::getSamples() 92789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 92889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Description: Generates count samples of a sine wave and accumulates 92989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// result in outBuffer. 93089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 93189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Input: 93289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// outBuffer: Output buffer where to accumulate samples. 93389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// count: number of samples to produce. 93489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// command: special action requested (see enum gen_command). 93589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 93689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Output: 93789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// none 93889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// 93989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//////////////////////////////////////////////////////////////////////////////// 94089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectvoid ToneGenerator::WaveGenerator::getSamples(short *outBuffer, 94189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project unsigned int count, unsigned int command) { 94289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project long lS1, lS2; 94389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project long lA1, lAmplitude; 94489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project long Sample; // current sample 94589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 94689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // init local 94789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (command == WAVEGEN_START) { 94889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lS1 = (long)0; 94989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lS2 = (long)mS2_0; 95089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 95189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lS1 = (long)mS1; 95289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lS2 = (long)mS2; 95389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 95489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lA1 = (long)mA1_Q14; 95589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lAmplitude = (long)mAmplitude_Q15; 95689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 95789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (command == WAVEGEN_STOP) { 95889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lAmplitude <<= 16; 95989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (count == 0) { 96089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return; 96189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 96289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project long dec = lAmplitude/count; 96389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // loop generation 96489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project while (count--) { 96589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Sample = ((lA1 * lS1) >> S_Q14) - lS2; 96689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // shift delay 96789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lS2 = lS1; 96889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lS1 = Sample; 96989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Sample = ((lAmplitude>>16) * Sample) >> S_Q15; 97089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *(outBuffer++) += (short)Sample; // put result in buffer 97189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lAmplitude -= dec; 97289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 97389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 97489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // loop generation 97589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project while (count--) { 97689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Sample = ((lA1 * lS1) >> S_Q14) - lS2; 97789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // shift delay 97889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lS2 = lS1; 97989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lS1 = Sample; 98089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Sample = (lAmplitude * Sample) >> S_Q15; 98189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *(outBuffer++) += (short)Sample; // put result in buffer 98289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 98389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 98489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 98589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // save status 98689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mS1 = (short)lS1; 98789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mS2 = (short)lS2; 98889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 98989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 99089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} // end namespace android 99189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 992