blob: c85534e9b7fe502f029cb7441dc50a29553cc396 [file] [log] [blame]
henrik.lundin@webrtc.org9a400812013-01-29 12:09:21 +00001/*
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
35namespace 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.
40const 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.
53const 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.
66const 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.
79const 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.
91const 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.
97DtmfToneGenerator::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.
107int 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.
147void DtmfToneGenerator::Reset() {
148 initialized_ = false;
149}
150
151// Generate num_samples of DTMF signal and write to |output|.
152int DtmfToneGenerator::Generate(int num_samples,
henrik.lundin@webrtc.org0e9c3992013-09-30 20:38:44 +0000153 AudioMultiVector* output) {
henrik.lundin@webrtc.org9a400812013-01-29 12:09:21 +0000154 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