• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/neteq/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.
DtmfToneGenerator()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.
Init(int fs,int event,int attenuation)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.
Reset()147 void DtmfToneGenerator::Reset() {
148   initialized_ = false;
149 }
150 
151 // Generate num_samples of DTMF signal and write to |output|.
Generate(size_t num_samples,AudioMultiVector * output)152 int DtmfToneGenerator::Generate(size_t num_samples,
153                                 AudioMultiVector* output) {
154   if (!initialized_) {
155     return kNotInitialized;
156   }
157 
158   if (!output) {
159     return kParameterError;
160   }
161 
162   output->AssertSize(num_samples);
163   for (size_t i = 0; i < num_samples; ++i) {
164     // Use recursion formula y[n] = a * y[n - 1] - y[n - 2].
165     int16_t temp_val_low = ((coeff1_ * sample_history1_[1] + 8192) >> 14)
166         - sample_history1_[0];
167     int16_t temp_val_high = ((coeff2_ * sample_history2_[1] + 8192) >> 14)
168         - sample_history2_[0];
169 
170     // Update recursion memory.
171     sample_history1_[0] = sample_history1_[1];
172     sample_history1_[1] = temp_val_low;
173     sample_history2_[0] = sample_history2_[1];
174     sample_history2_[1] = temp_val_high;
175 
176     // Attenuate the low frequency tone 3 dB.
177     int32_t temp_val = kAmpMultiplier * temp_val_low + (temp_val_high << 15);
178     // Normalize the signal to Q14 with proper rounding.
179     temp_val = (temp_val + 16384) >> 15;
180     // Scale the signal to correct volume.
181     (*output)[0][i] =
182         static_cast<int16_t>((temp_val * amplitude_ + 8192) >> 14);
183   }
184   // Copy first channel to all other channels.
185   for (size_t channel = 1; channel < output->Channels(); ++channel) {
186     output->CopyChannel(0, channel);
187   }
188 
189   return static_cast<int>(num_samples);
190 }
191 
initialized() const192 bool DtmfToneGenerator::initialized() const {
193   return initialized_;
194 }
195 
196 }  // namespace webrtc
197