henrik.lundin@webrtc.org | 9a40081 | 2013-01-29 12:09:21 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
| 3 | * |
| 4 | * Use of this source code is governed by a BSD-style license |
| 5 | * that can be found in the LICENSE file in the root of the source |
| 6 | * tree. An additional intellectual property rights grant can be found |
| 7 | * in the file PATENTS. All contributing project authors may |
| 8 | * be found in the AUTHORS file in the root of the source tree. |
| 9 | */ |
| 10 | |
| 11 | // This class provides a generator for DTMF tones. The tone generation is based |
| 12 | // on a sinusoid recursion. Each sinusoid is generated using a recursion |
| 13 | // formula; x[n] = a * x[n-1] - x[n-2], where the coefficient |
| 14 | // a = 2*cos(2*pi*f/fs). The recursion is started with x[-1] = 0 and |
| 15 | // x[-2] = sin(2*pi*f/fs). (Note that with this initialization, the resulting |
| 16 | // sinusoid gets a "negative" rotation; x[n] = sin(-2*pi*f/fs * n + phi), but |
| 17 | // kept this way due to historical reasons.) |
| 18 | // TODO(hlundin): Change to positive rotation? |
| 19 | // |
| 20 | // Each key on the telephone keypad corresponds to an "event", 0-15. Each event |
| 21 | // is mapped to a tone pair, with a low and a high frequency. There are four |
| 22 | // low and four high frequencies, each corresponding to a row and column, |
| 23 | // respectively, on the keypad as illustrated below. |
| 24 | // |
| 25 | // 1209 Hz 1336 Hz 1477 Hz 1633 Hz |
| 26 | // 697 Hz 1 2 3 12 |
| 27 | // 770 Hz 4 5 6 13 |
| 28 | // 852 Hz 7 8 9 14 |
| 29 | // 941 Hz 10 0 11 15 |
| 30 | |
| 31 | #include "webrtc/modules/audio_coding/neteq4/dtmf_tone_generator.h" |
| 32 | |
| 33 | #include <assert.h> |
| 34 | |
| 35 | namespace webrtc { |
| 36 | |
| 37 | // The filter coefficient a = 2*cos(2*pi*f/fs) for the low frequency tone, for |
| 38 | // sample rates fs = {8000, 16000, 32000, 48000} Hz, and events 0 through 15. |
| 39 | // Values are in Q14. |
| 40 | const int DtmfToneGenerator::kCoeff1[4][16] = { |
| 41 | { 24219, 27980, 27980, 27980, 26956, 26956, 26956, 25701, 25701, 25701, |
| 42 | 24219, 24219, 27980, 26956, 25701, 24219 }, |
| 43 | { 30556, 31548, 31548, 31548, 31281, 31281, 31281, 30951, 30951, 30951, |
| 44 | 30556, 30556, 31548, 31281, 30951, 30556 }, |
| 45 | { 32210, 32462, 32462, 32462, 32394, 32394, 32394, 32311, 32311, 32311, |
| 46 | 32210, 32210, 32462, 32394, 32311, 32210 }, |
| 47 | { 32520, 32632, 32632, 32632, 32602, 32602, 32602, 32564, 32564, 32564, |
| 48 | 32520, 32520, 32632, 32602, 32564, 32520 } }; |
| 49 | |
| 50 | // The filter coefficient a = 2*cos(2*pi*f/fs) for the high frequency tone, for |
| 51 | // sample rates fs = {8000, 16000, 32000, 48000} Hz, and events 0 through 15. |
| 52 | // Values are in Q14. |
| 53 | const int DtmfToneGenerator::kCoeff2[4][16] = { |
| 54 | { 16325, 19073, 16325, 13085, 19073, 16325, 13085, 19073, 16325, 13085, |
| 55 | 19073, 13085, 9315, 9315, 9315, 9315}, |
| 56 | { 28361, 29144, 28361, 27409, 29144, 28361, 27409, 29144, 28361, 27409, |
| 57 | 29144, 27409, 26258, 26258, 26258, 26258}, |
| 58 | { 31647, 31849, 31647, 31400, 31849, 31647, 31400, 31849, 31647, 31400, |
| 59 | 31849, 31400, 31098, 31098, 31098, 31098}, |
| 60 | { 32268, 32359, 32268, 32157, 32359, 32268, 32157, 32359, 32268, 32157, |
| 61 | 32359, 32157, 32022, 32022, 32022, 32022} }; |
| 62 | |
| 63 | // The initialization value x[-2] = sin(2*pi*f/fs) for the low frequency tone, |
| 64 | // for sample rates fs = {8000, 16000, 32000, 48000} Hz, and events 0-15. |
| 65 | // Values are in Q14. |
| 66 | const int DtmfToneGenerator::kInitValue1[4][16] = { |
| 67 | { 11036, 8528, 8528, 8528, 9315, 9315, 9315, 10163, 10163, 10163, 11036, |
| 68 | 11036, 8528, 9315, 10163, 11036}, |
| 69 | { 5918, 4429, 4429, 4429, 4879, 4879, 4879, 5380, 5380, 5380, 5918, 5918, |
| 70 | 4429, 4879, 5380, 5918}, |
| 71 | { 3010, 2235, 2235, 2235, 2468, 2468, 2468, 2728, 2728, 2728, 3010, 3010, |
| 72 | 2235, 2468, 2728, 3010}, |
| 73 | { 2013, 1493, 1493, 1493, 1649, 1649, 1649, 1823, 1823, 1823, 2013, 2013, |
| 74 | 1493, 1649, 1823, 2013 } }; |
| 75 | |
| 76 | // The initialization value x[-2] = sin(2*pi*f/fs) for the high frequency tone, |
| 77 | // for sample rates fs = {8000, 16000, 32000, 48000} Hz, and events 0-15. |
| 78 | // Values are in Q14. |
| 79 | const int DtmfToneGenerator::kInitValue2[4][16] = { |
| 80 | { 14206, 13323, 14206, 15021, 13323, 14206, 15021, 13323, 14206, 15021, |
| 81 | 13323, 15021, 15708, 15708, 15708, 15708}, |
| 82 | { 8207, 7490, 8207, 8979, 7490, 8207, 8979, 7490, 8207, 8979, 7490, 8979, |
| 83 | 9801, 9801, 9801, 9801}, |
| 84 | { 4249, 3853, 4249, 4685, 3853, 4249, 4685, 3853, 4249, 4685, 3853, 4685, |
| 85 | 5164, 5164, 5164, 5164}, |
| 86 | { 2851, 2582, 2851, 3148, 2582, 2851, 3148, 2582, 2851, 3148, 2582, 3148, |
| 87 | 3476, 3476, 3476, 3476} }; |
| 88 | |
| 89 | // Amplitude multipliers for volume values 0 through 36, corresponding to |
| 90 | // 0 dBm0 through -36 dBm0. Values are in Q14. |
| 91 | const int DtmfToneGenerator::kAmplitude[37] = { |
| 92 | 16141, 14386, 12821, 11427, 10184, 9077, 8090, 7210, 6426, 5727, 5104, 4549, |
| 93 | 4054, 3614, 3221, 2870, 2558, 2280, 2032, 1811, 1614, 1439, 1282, 1143, |
| 94 | 1018, 908, 809, 721, 643, 573, 510, 455, 405, 361, 322, 287, 256 }; |
| 95 | |
| 96 | // Constructor. |
| 97 | DtmfToneGenerator::DtmfToneGenerator() |
| 98 | : initialized_(false), |
| 99 | coeff1_(0), |
| 100 | coeff2_(0), |
| 101 | amplitude_(0) { |
| 102 | } |
| 103 | |
| 104 | // Initialize the DTMF generator with sample rate fs Hz (8000, 16000, 32000, |
| 105 | // 48000), event (0-15) and attenuation (0-36 dB). |
| 106 | // Returns 0 on success, otherwise an error code. |
| 107 | int DtmfToneGenerator::Init(int fs, int event, int attenuation) { |
| 108 | initialized_ = false; |
| 109 | int fs_index; |
| 110 | if (fs == 8000) { |
| 111 | fs_index = 0; |
| 112 | } else if (fs == 16000) { |
| 113 | fs_index = 1; |
| 114 | } else if (fs == 32000) { |
| 115 | fs_index = 2; |
| 116 | } else if (fs == 48000) { |
| 117 | fs_index = 3; |
| 118 | } else { |
| 119 | assert(false); |
| 120 | fs_index = 1; // Default to 8000 Hz. |
| 121 | } |
| 122 | |
| 123 | if (event < 0 || event > 15) { |
| 124 | return kParameterError; // Invalid event number. |
| 125 | } |
| 126 | |
| 127 | if (attenuation < 0 || attenuation > 36) { |
| 128 | return kParameterError; // Invalid attenuation. |
| 129 | } |
| 130 | |
| 131 | // Look up oscillator coefficient for low and high frequencies. |
| 132 | coeff1_ = kCoeff1[fs_index][event]; |
| 133 | coeff2_ = kCoeff2[fs_index][event]; |
| 134 | // Look up amplitude multiplier. |
| 135 | amplitude_ = kAmplitude[attenuation]; |
| 136 | // Initialize sample history. |
| 137 | sample_history1_[0] = kInitValue1[fs_index][event]; |
| 138 | sample_history1_[1] = 0; |
| 139 | sample_history2_[0] = kInitValue2[fs_index][event]; |
| 140 | sample_history2_[1] = 0; |
| 141 | |
| 142 | initialized_ = true; |
| 143 | return 0; |
| 144 | } |
| 145 | |
| 146 | // Reset tone generator to uninitialized state. |
| 147 | void DtmfToneGenerator::Reset() { |
| 148 | initialized_ = false; |
| 149 | } |
| 150 | |
| 151 | // Generate num_samples of DTMF signal and write to |output|. |
| 152 | int DtmfToneGenerator::Generate(int num_samples, |
henrik.lundin@webrtc.org | 0e9c399 | 2013-09-30 20:38:44 +0000 | [diff] [blame^] | 153 | AudioMultiVector* output) { |
henrik.lundin@webrtc.org | 9a40081 | 2013-01-29 12:09:21 +0000 | [diff] [blame] | 154 | if (!initialized_) { |
| 155 | return kNotInitialized; |
| 156 | } |
| 157 | |
| 158 | if (num_samples < 0 || !output) { |
| 159 | return kParameterError; |
| 160 | } |
| 161 | assert(output->Channels() == 1); // Not adapted for multi-channel yet. |
| 162 | if (output->Channels() != 1) { |
| 163 | return kStereoNotSupported; |
| 164 | } |
| 165 | |
| 166 | output->AssertSize(num_samples); |
| 167 | for (int i = 0; i < num_samples; ++i) { |
| 168 | // Use recursion formula y[n] = a * y[n - 1] - y[n - 2]. |
| 169 | int16_t temp_val_low = ((coeff1_ * sample_history1_[1] + 8192) >> 14) |
| 170 | - sample_history1_[0]; |
| 171 | int16_t temp_val_high = ((coeff2_ * sample_history2_[1] + 8192) >> 14) |
| 172 | - sample_history2_[0]; |
| 173 | |
| 174 | // Update recursion memory. |
| 175 | sample_history1_[0] = sample_history1_[1]; |
| 176 | sample_history1_[1] = temp_val_low; |
| 177 | sample_history2_[0] = sample_history2_[1]; |
| 178 | sample_history2_[1] = temp_val_high; |
| 179 | |
| 180 | // Attenuate the low frequency tone 3 dB. |
| 181 | int32_t temp_val = kAmpMultiplier * temp_val_low + (temp_val_high << 15); |
| 182 | // Normalize the signal to Q14 with proper rounding. |
| 183 | temp_val = (temp_val + 16384) >> 15; |
| 184 | // Scale the signal to correct volume. |
| 185 | (*output)[0][i] = |
| 186 | static_cast<int16_t>((temp_val * amplitude_ + 8192) >> 14); |
| 187 | } |
| 188 | |
| 189 | return num_samples; |
| 190 | } |
| 191 | |
| 192 | } // namespace webrtc |