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 #ifndef MODULES_AUDIO_CODING_NETEQ_DSP_HELPER_H_ 12 #define MODULES_AUDIO_CODING_NETEQ_DSP_HELPER_H_ 13 14 #include <stdint.h> 15 #include <string.h> 16 17 #include "modules/audio_coding/neteq/audio_multi_vector.h" 18 #include "modules/audio_coding/neteq/audio_vector.h" 19 #include "rtc_base/constructor_magic.h" 20 21 namespace webrtc { 22 23 // This class contains various signal processing functions, all implemented as 24 // static methods. 25 class DspHelper { 26 public: 27 // Filter coefficients used when downsampling from the indicated sample rates 28 // (8, 16, 32, 48 kHz) to 4 kHz. Coefficients are in Q12. 29 static const int16_t kDownsample8kHzTbl[3]; 30 static const int16_t kDownsample16kHzTbl[5]; 31 static const int16_t kDownsample32kHzTbl[7]; 32 static const int16_t kDownsample48kHzTbl[7]; 33 34 // Constants used to mute and unmute over 5 samples. The coefficients are 35 // in Q15. 36 static const int kMuteFactorStart8kHz = 27307; 37 static const int kMuteFactorIncrement8kHz = -5461; 38 static const int kUnmuteFactorStart8kHz = 5461; 39 static const int kUnmuteFactorIncrement8kHz = 5461; 40 static const int kMuteFactorStart16kHz = 29789; 41 static const int kMuteFactorIncrement16kHz = -2979; 42 static const int kUnmuteFactorStart16kHz = 2979; 43 static const int kUnmuteFactorIncrement16kHz = 2979; 44 static const int kMuteFactorStart32kHz = 31208; 45 static const int kMuteFactorIncrement32kHz = -1560; 46 static const int kUnmuteFactorStart32kHz = 1560; 47 static const int kUnmuteFactorIncrement32kHz = 1560; 48 static const int kMuteFactorStart48kHz = 31711; 49 static const int kMuteFactorIncrement48kHz = -1057; 50 static const int kUnmuteFactorStart48kHz = 1057; 51 static const int kUnmuteFactorIncrement48kHz = 1057; 52 53 // Multiplies the signal with a gradually changing factor. 54 // The first sample is multiplied with |factor| (in Q14). For each sample, 55 // |factor| is increased (additive) by the |increment| (in Q20), which can 56 // be negative. Returns the scale factor after the last increment. 57 static int RampSignal(const int16_t* input, 58 size_t length, 59 int factor, 60 int increment, 61 int16_t* output); 62 63 // Same as above, but with the samples of |signal| being modified in-place. 64 static int RampSignal(int16_t* signal, 65 size_t length, 66 int factor, 67 int increment); 68 69 // Same as above, but processes |length| samples from |signal|, starting at 70 // |start_index|. 71 static int RampSignal(AudioVector* signal, 72 size_t start_index, 73 size_t length, 74 int factor, 75 int increment); 76 77 // Same as above, but for an AudioMultiVector. 78 static int RampSignal(AudioMultiVector* signal, 79 size_t start_index, 80 size_t length, 81 int factor, 82 int increment); 83 84 // Peak detection with parabolic fit. Looks for |num_peaks| maxima in |data|, 85 // having length |data_length| and sample rate multiplier |fs_mult|. The peak 86 // locations and values are written to the arrays |peak_index| and 87 // |peak_value|, respectively. Both arrays must hold at least |num_peaks| 88 // elements. 89 static void PeakDetection(int16_t* data, 90 size_t data_length, 91 size_t num_peaks, 92 int fs_mult, 93 size_t* peak_index, 94 int16_t* peak_value); 95 96 // Estimates the height and location of a maximum. The three values in the 97 // array |signal_points| are used as basis for a parabolic fit, which is then 98 // used to find the maximum in an interpolated signal. The |signal_points| are 99 // assumed to be from a 4 kHz signal, while the maximum, written to 100 // |peak_index| and |peak_value| is given in the full sample rate, as 101 // indicated by the sample rate multiplier |fs_mult|. 102 static void ParabolicFit(int16_t* signal_points, 103 int fs_mult, 104 size_t* peak_index, 105 int16_t* peak_value); 106 107 // Calculates the sum-abs-diff for |signal| when compared to a displaced 108 // version of itself. Returns the displacement lag that results in the minimum 109 // distortion. The resulting distortion is written to |distortion_value|. 110 // The values of |min_lag| and |max_lag| are boundaries for the search. 111 static size_t MinDistortion(const int16_t* signal, 112 size_t min_lag, 113 size_t max_lag, 114 size_t length, 115 int32_t* distortion_value); 116 117 // Mixes |length| samples from |input1| and |input2| together and writes the 118 // result to |output|. The gain for |input1| starts at |mix_factor| (Q14) and 119 // is decreased by |factor_decrement| (Q14) for each sample. The gain for 120 // |input2| is the complement 16384 - mix_factor. 121 static void CrossFade(const int16_t* input1, 122 const int16_t* input2, 123 size_t length, 124 int16_t* mix_factor, 125 int16_t factor_decrement, 126 int16_t* output); 127 128 // Scales |input| with an increasing gain. Applies |factor| (Q14) to the first 129 // sample and increases the gain by |increment| (Q20) for each sample. The 130 // result is written to |output|. |length| samples are processed. 131 static void UnmuteSignal(const int16_t* input, 132 size_t length, 133 int16_t* factor, 134 int increment, 135 int16_t* output); 136 137 // Starts at unity gain and gradually fades out |signal|. For each sample, 138 // the gain is reduced by |mute_slope| (Q14). |length| samples are processed. 139 static void MuteSignal(int16_t* signal, int mute_slope, size_t length); 140 141 // Downsamples |input| from |sample_rate_hz| to 4 kHz sample rate. The input 142 // has |input_length| samples, and the method will write |output_length| 143 // samples to |output|. Compensates for the phase delay of the downsampling 144 // filters if |compensate_delay| is true. Returns -1 if the input is too short 145 // to produce |output_length| samples, otherwise 0. 146 static int DownsampleTo4kHz(const int16_t* input, 147 size_t input_length, 148 size_t output_length, 149 int input_rate_hz, 150 bool compensate_delay, 151 int16_t* output); 152 153 private: 154 // Table of constants used in method DspHelper::ParabolicFit(). 155 static const int16_t kParabolaCoefficients[17][3]; 156 157 RTC_DISALLOW_COPY_AND_ASSIGN(DspHelper); 158 }; 159 160 } // namespace webrtc 161 #endif // MODULES_AUDIO_CODING_NETEQ_DSP_HELPER_H_ 162