dtmf_tone_generator.cc (8728B)
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 "modules/audio_coding/neteq/dtmf_tone_generator.h" 32 33 #include <cstddef> 34 #include <cstdint> 35 #include <iterator> 36 37 #include "modules/audio_coding/neteq/audio_multi_vector.h" 38 #include "modules/audio_coding/neteq/audio_vector.h" 39 #include "rtc_base/checks.h" 40 41 namespace webrtc { 42 43 // The filter coefficient a = 2*cos(2*pi*f/fs) for the low frequency tone, for 44 // sample rates fs = {8000, 16000, 32000, 48000} Hz, and events 0 through 15. 45 // Values are in Q14. 46 const int DtmfToneGenerator::kCoeff1[4][16] = { 47 {24219, 27980, 27980, 27980, 26956, 26956, 26956, 25701, 25701, 25701, 48 24219, 24219, 27980, 26956, 25701, 24219}, 49 {30556, 31548, 31548, 31548, 31281, 31281, 31281, 30951, 30951, 30951, 50 30556, 30556, 31548, 31281, 30951, 30556}, 51 {32210, 32462, 32462, 32462, 32394, 32394, 32394, 32311, 32311, 32311, 52 32210, 32210, 32462, 32394, 32311, 32210}, 53 {32520, 32632, 32632, 32632, 32602, 32602, 32602, 32564, 32564, 32564, 54 32520, 32520, 32632, 32602, 32564, 32520}}; 55 56 // The filter coefficient a = 2*cos(2*pi*f/fs) for the high frequency tone, for 57 // sample rates fs = {8000, 16000, 32000, 48000} Hz, and events 0 through 15. 58 // Values are in Q14. 59 const int DtmfToneGenerator::kCoeff2[4][16] = { 60 {16325, 19073, 16325, 13085, 19073, 16325, 13085, 19073, 16325, 13085, 61 19073, 13085, 9315, 9315, 9315, 9315}, 62 {28361, 29144, 28361, 27409, 29144, 28361, 27409, 29144, 28361, 27409, 63 29144, 27409, 26258, 26258, 26258, 26258}, 64 {31647, 31849, 31647, 31400, 31849, 31647, 31400, 31849, 31647, 31400, 65 31849, 31400, 31098, 31098, 31098, 31098}, 66 {32268, 32359, 32268, 32157, 32359, 32268, 32157, 32359, 32268, 32157, 67 32359, 32157, 32022, 32022, 32022, 32022}}; 68 69 // The initialization value x[-2] = sin(2*pi*f/fs) for the low frequency tone, 70 // for sample rates fs = {8000, 16000, 32000, 48000} Hz, and events 0-15. 71 // Values are in Q14. 72 const int DtmfToneGenerator::kInitValue1[4][16] = { 73 {11036, 8528, 8528, 8528, 9315, 9315, 9315, 10163, 10163, 10163, 11036, 74 11036, 8528, 9315, 10163, 11036}, 75 {5918, 4429, 4429, 4429, 4879, 4879, 4879, 5380, 5380, 5380, 5918, 5918, 76 4429, 4879, 5380, 5918}, 77 {3010, 2235, 2235, 2235, 2468, 2468, 2468, 2728, 2728, 2728, 3010, 3010, 78 2235, 2468, 2728, 3010}, 79 {2013, 1493, 1493, 1493, 1649, 1649, 1649, 1823, 1823, 1823, 2013, 2013, 80 1493, 1649, 1823, 2013}}; 81 82 // The initialization value x[-2] = sin(2*pi*f/fs) for the high frequency tone, 83 // for sample rates fs = {8000, 16000, 32000, 48000} Hz, and events 0-15. 84 // Values are in Q14. 85 const int DtmfToneGenerator::kInitValue2[4][16] = { 86 {14206, 13323, 14206, 15021, 13323, 14206, 15021, 13323, 14206, 15021, 87 13323, 15021, 15708, 15708, 15708, 15708}, 88 {8207, 7490, 8207, 8979, 7490, 8207, 8979, 7490, 8207, 8979, 7490, 8979, 89 9801, 9801, 9801, 9801}, 90 {4249, 3853, 4249, 4685, 3853, 4249, 4685, 3853, 4249, 4685, 3853, 4685, 91 5164, 5164, 5164, 5164}, 92 {2851, 2582, 2851, 3148, 2582, 2851, 3148, 2582, 2851, 3148, 2582, 3148, 93 3476, 3476, 3476, 3476}}; 94 95 // Amplitude multipliers for volume values 0 through 63, corresponding to 96 // 0 dBm0 through -63 dBm0. Values are in Q14. 97 // for a in range(0, 64): 98 // print round(16141.0 * 10**(-float(a)/20)) 99 const int DtmfToneGenerator::kAmplitude[64] = { 100 16141, 14386, 12821, 11427, 10184, 9077, 8090, 7210, 6426, 5727, 5104, 101 4549, 4054, 3614, 3221, 2870, 2558, 2280, 2032, 1811, 1614, 1439, 102 1282, 1143, 1018, 908, 809, 721, 643, 573, 510, 455, 405, 103 361, 322, 287, 256, 228, 203, 181, 161, 144, 128, 114, 104 102, 91, 81, 72, 64, 57, 51, 45, 41, 36, 32, 105 29, 26, 23, 20, 18, 16, 14, 13, 11}; 106 107 // Constructor. 108 DtmfToneGenerator::DtmfToneGenerator() 109 : initialized_(false), coeff1_(0), coeff2_(0), amplitude_(0) {} 110 111 // Initialize the DTMF generator with sample rate fs Hz (8000, 16000, 32000, 112 // 48000), event (0-15) and attenuation (0-36 dB). 113 // Returns 0 on success, otherwise an error code. 114 int DtmfToneGenerator::Init(int fs, int event, int attenuation) { 115 initialized_ = false; 116 size_t fs_index; 117 if (fs == 8000) { 118 fs_index = 0; 119 } else if (fs == 16000) { 120 fs_index = 1; 121 } else if (fs == 32000) { 122 fs_index = 2; 123 } else if (fs == 48000) { 124 fs_index = 3; 125 } else { 126 RTC_DCHECK_NOTREACHED(); 127 fs_index = 1; // Default to 8000 Hz. 128 } 129 130 if (event < 0 || event > 15) { 131 return kParameterError; // Invalid event number. 132 } 133 134 if (attenuation < 0 || attenuation > 63) { 135 return kParameterError; // Invalid attenuation. 136 } 137 138 // Look up oscillator coefficient for low and high frequencies. 139 RTC_DCHECK_LE(0, fs_index); 140 RTC_DCHECK_GT(std::size(kCoeff1), fs_index); 141 RTC_DCHECK_GT(std::size(kCoeff2), fs_index); 142 RTC_DCHECK_LE(0, event); 143 RTC_DCHECK_GT(std::ssize(kCoeff1[fs_index]), event); 144 RTC_DCHECK_GT(std::ssize(kCoeff2[fs_index]), event); 145 coeff1_ = kCoeff1[fs_index][event]; 146 coeff2_ = kCoeff2[fs_index][event]; 147 148 // Look up amplitude multiplier. 149 RTC_DCHECK_LE(0, attenuation); 150 RTC_DCHECK_GT(std::ssize(kAmplitude), attenuation); 151 amplitude_ = kAmplitude[attenuation]; 152 153 // Initialize sample history. 154 RTC_DCHECK_LE(0, fs_index); 155 RTC_DCHECK_GT(std::size(kInitValue1), fs_index); 156 RTC_DCHECK_GT(std::size(kInitValue2), fs_index); 157 RTC_DCHECK_LE(0, event); 158 RTC_DCHECK_GT(std::ssize(kInitValue1[fs_index]), event); 159 RTC_DCHECK_GT(std::ssize(kInitValue2[fs_index]), event); 160 sample_history1_[0] = kInitValue1[fs_index][event]; 161 sample_history1_[1] = 0; 162 sample_history2_[0] = kInitValue2[fs_index][event]; 163 sample_history2_[1] = 0; 164 165 initialized_ = true; 166 return 0; 167 } 168 169 // Reset tone generator to uninitialized state. 170 void DtmfToneGenerator::Reset() { 171 initialized_ = false; 172 } 173 174 // Generate num_samples of DTMF signal and write to `output`. 175 int DtmfToneGenerator::Generate(size_t num_samples, AudioMultiVector* output) { 176 if (!initialized_) { 177 return kNotInitialized; 178 } 179 180 if (!output) { 181 return kParameterError; 182 } 183 184 output->AssertSize(num_samples); 185 for (size_t i = 0; i < num_samples; ++i) { 186 // Use recursion formula y[n] = a * y[n - 1] - y[n - 2]. 187 int16_t temp_val_low = 188 ((coeff1_ * sample_history1_[1] + 8192) >> 14) - sample_history1_[0]; 189 int16_t temp_val_high = 190 ((coeff2_ * sample_history2_[1] + 8192) >> 14) - sample_history2_[0]; 191 192 // Update recursion memory. 193 sample_history1_[0] = sample_history1_[1]; 194 sample_history1_[1] = temp_val_low; 195 sample_history2_[0] = sample_history2_[1]; 196 sample_history2_[1] = temp_val_high; 197 198 // Attenuate the low frequency tone 3 dB. 199 int32_t temp_val = 200 kAmpMultiplier * temp_val_low + temp_val_high * (1 << 15); 201 // Normalize the signal to Q14 with proper rounding. 202 temp_val = (temp_val + 16384) >> 15; 203 // Scale the signal to correct volume. 204 (*output)[0][i] = 205 static_cast<int16_t>((temp_val * amplitude_ + 8192) >> 14); 206 } 207 // Copy first channel to all other channels. 208 for (size_t channel = 1; channel < output->Channels(); ++channel) { 209 output->CopyChannel(0, channel); 210 } 211 212 return static_cast<int>(num_samples); 213 } 214 215 bool DtmfToneGenerator::initialized() const { 216 return initialized_; 217 } 218 219 } // namespace webrtc