tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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