OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright (c) 2014 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 WEBRTC_MODULES_AUDIO_PROCESSING_INTELLIGIBILITY_INTELLIGIBILITY_UTILS_H_ |
| 12 #define WEBRTC_MODULES_AUDIO_PROCESSING_INTELLIGIBILITY_INTELLIGIBILITY_UTILS_H_ |
| 13 |
| 14 #include <complex> |
| 15 |
| 16 #include "webrtc/system_wrappers/interface/scoped_ptr.h" |
| 17 |
| 18 namespace webrtc { |
| 19 |
| 20 namespace intelligibility { |
| 21 |
| 22 // Internal helper for computing the variances of a stream of arrays. |
| 23 // The result is an array of variances per position: the i-th variance |
| 24 // is the variance of the stream of data on the i-th positions in the |
| 25 // input arrays. |
| 26 // There are four methods of computation: |
| 27 // * kStepInfinite computes variances from the beginning onwards |
| 28 // * kStepDecaying uses a recursive exponential decay formula with a |
| 29 // settable forgetting factor |
| 30 // * kStepWindowed computes variances within a moving window |
| 31 // * kStepBlocked is similar to kStepWindowed, but history is kept |
| 32 // as a rolling window of blocks: multiple input elements are used for |
| 33 // one block and the history then consists of the variances of these blocks |
| 34 // with the same effect as kStepWindowed, but less storage, so the window |
| 35 // can be longer |
| 36 class VarianceArray { |
| 37 public: |
| 38 enum StepType { |
| 39 kStepInfinite = 0, |
| 40 kStepDecaying, |
| 41 kStepWindowed, |
| 42 kStepBlocked |
| 43 }; |
| 44 |
| 45 // Construct an instance for the given input array length (|freqs|) and |
| 46 // computation algorithm (|type|), with the appropriate parameters. |
| 47 // |window_size| is the number of samples for kStepWindowed and |
| 48 // the number of blocks for kStepBlocked. |decay| is the forgetting factor |
| 49 // for kStepDecaying. |
| 50 VarianceArray(int freqs, StepType type, int window_size, float decay); |
| 51 |
| 52 // Add a new data point to the series and compute the new variances. |
| 53 // TODO(bercic) |skip_fudge| is a flag for kStepWindowed and kStepDecaying, |
| 54 // whether they should skip adding some small dummy values to the input |
| 55 // to prevent problems with all-zero inputs. Can probably be removed. |
| 56 void Step(const std::complex<float>* data, bool skip_fudge = false) { |
| 57 (this->*step_func_)(data, skip_fudge); |
| 58 } |
| 59 // Reset variances to zero and forget all history. |
| 60 void Clear(); |
| 61 // Scale the input data by |scale|. Effectively multiply variances |
| 62 // by |scale^2|. |
| 63 void ApplyScale(float scale); |
| 64 |
| 65 // The current set of variances. |
| 66 const float* variance() const { |
| 67 return variance_.get(); |
| 68 } |
| 69 |
| 70 // The mean value of the current set of variances. |
| 71 float array_mean() const { |
| 72 return array_mean_; |
| 73 } |
| 74 |
| 75 private: |
| 76 void InfiniteStep(const std::complex<float>* data, bool dummy); |
| 77 void DecayStep(const std::complex<float>* data, bool dummy); |
| 78 void WindowedStep(const std::complex<float>* data, bool dummy); |
| 79 void BlockedStep(const std::complex<float>* data, bool dummy); |
| 80 |
| 81 // The current average X and X^2. |
| 82 scoped_ptr<std::complex<float>[]> running_mean_; |
| 83 scoped_ptr<std::complex<float>[]> running_mean_sq_; |
| 84 |
| 85 // Average X and X^2 for the current block in kStepBlocked. |
| 86 scoped_ptr<std::complex<float>[]> sub_running_mean_; |
| 87 scoped_ptr<std::complex<float>[]> sub_running_mean_sq_; |
| 88 |
| 89 // Sample history for the rolling window in kStepWindowed and block-wise |
| 90 // histories for kStepBlocked. |
| 91 scoped_ptr<scoped_ptr<std::complex<float>[]>[]> history_; |
| 92 scoped_ptr<scoped_ptr<std::complex<float>[]>[]> subhistory_; |
| 93 scoped_ptr<scoped_ptr<std::complex<float>[]>[]> subhistory_sq_; |
| 94 |
| 95 // The current set of variances and sums for Welford's algorithm. |
| 96 scoped_ptr<float[]> variance_; |
| 97 scoped_ptr<float[]> conj_sum_; |
| 98 |
| 99 const int freqs_; |
| 100 const int window_size_; |
| 101 const float decay_; |
| 102 int history_cursor_; |
| 103 int count_; |
| 104 float array_mean_; |
| 105 void (VarianceArray::*step_func_)(const std::complex<float>*, bool); |
| 106 }; |
| 107 |
| 108 // Helper class for smoothing gain changes. On each applicatiion step, the |
| 109 // currently used gains are changed towards a set of settable target gains, |
| 110 // constrained by a limit on the magnitude of the changes. |
| 111 class GainApplier { |
| 112 public: |
| 113 GainApplier(int freqs, float change_limit); |
| 114 |
| 115 // Copy |in_block| to |out_block|, multiplied by the current set of gains, |
| 116 // and step the current set of gains towards the target set. |
| 117 void Apply(const std::complex<float>* in_block, |
| 118 std::complex<float>* out_block); |
| 119 |
| 120 // Return the current target gain set. Modify this array to set the targets. |
| 121 float* target() const { |
| 122 return target_.get(); |
| 123 } |
| 124 |
| 125 private: |
| 126 const int freqs_; |
| 127 const float change_limit_; |
| 128 scoped_ptr<float[]> target_; |
| 129 scoped_ptr<float[]> current_; |
| 130 }; |
| 131 |
| 132 } // namespace intelligibility |
| 133 |
| 134 } // namespace webrtc |
| 135 |
| 136 #endif // WEBRTC_MODULES_AUDIO_PROCESSING_INTELLIGIBILITY_INTELLIGIBILITY_UTILS
_H_ |
| 137 |
OLD | NEW |