LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/modules/audio_coding/neteq - dtmf_tone_generator.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 71 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 5 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13