| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. | 2  *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. | 
| 3  * | 3  * | 
| 4  *  Use of this source code is governed by a BSD-style license | 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 | 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 | 6  *  tree. An additional intellectual property rights grant can be found | 
| 7  *  in the file PATENTS.  All contributing project authors may | 7  *  in the file PATENTS.  All contributing project authors may | 
| 8  *  be found in the AUTHORS file in the root of the source tree. | 8  *  be found in the AUTHORS file in the root of the source tree. | 
| 9  */ | 9  */ | 
| 10 | 10 | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
| 33 } | 33 } | 
| 34 | 34 | 
| 35 float AddDitherIfZero(float value) { | 35 float AddDitherIfZero(float value) { | 
| 36   return value == 0.f ? std::rand() * 0.01f / RAND_MAX : value; | 36   return value == 0.f ? std::rand() * 0.01f / RAND_MAX : value; | 
| 37 } | 37 } | 
| 38 | 38 | 
| 39 complex<float> zerofudge(complex<float> c) { | 39 complex<float> zerofudge(complex<float> c) { | 
| 40   return complex<float>(AddDitherIfZero(c.real()), AddDitherIfZero(c.imag())); | 40   return complex<float>(AddDitherIfZero(c.real()), AddDitherIfZero(c.imag())); | 
| 41 } | 41 } | 
| 42 | 42 | 
| 43 complex<float> NewMean(complex<float> mean, complex<float> data, int count) { | 43 complex<float> NewMean(complex<float> mean, complex<float> data, size_t count) { | 
| 44   return mean + (data - mean) / static_cast<float>(count); | 44   return mean + (data - mean) / static_cast<float>(count); | 
| 45 } | 45 } | 
| 46 | 46 | 
| 47 void AddToMean(complex<float> data, int count, complex<float>* mean) { | 47 void AddToMean(complex<float> data, size_t count, complex<float>* mean) { | 
| 48   (*mean) = NewMean(*mean, data, count); | 48   (*mean) = NewMean(*mean, data, count); | 
| 49 } | 49 } | 
| 50 | 50 | 
| 51 | 51 | 
| 52 static const int kWindowBlockSize = 10; | 52 static const size_t kWindowBlockSize = 10; | 
| 53 | 53 | 
| 54 VarianceArray::VarianceArray(int freqs, | 54 VarianceArray::VarianceArray(size_t freqs, | 
| 55                              StepType type, | 55                              StepType type, | 
| 56                              int window_size, | 56                              size_t window_size, | 
| 57                              float decay) | 57                              float decay) | 
| 58     : running_mean_(new complex<float>[freqs]()), | 58     : running_mean_(new complex<float>[freqs]()), | 
| 59       running_mean_sq_(new complex<float>[freqs]()), | 59       running_mean_sq_(new complex<float>[freqs]()), | 
| 60       sub_running_mean_(new complex<float>[freqs]()), | 60       sub_running_mean_(new complex<float>[freqs]()), | 
| 61       sub_running_mean_sq_(new complex<float>[freqs]()), | 61       sub_running_mean_sq_(new complex<float>[freqs]()), | 
| 62       variance_(new float[freqs]()), | 62       variance_(new float[freqs]()), | 
| 63       conj_sum_(new float[freqs]()), | 63       conj_sum_(new float[freqs]()), | 
| 64       freqs_(freqs), | 64       freqs_(freqs), | 
| 65       window_size_(window_size), | 65       window_size_(window_size), | 
| 66       decay_(decay), | 66       decay_(decay), | 
| 67       history_cursor_(0), | 67       history_cursor_(0), | 
| 68       count_(0), | 68       count_(0), | 
| 69       array_mean_(0.0f), | 69       array_mean_(0.0f), | 
| 70       buffer_full_(false) { | 70       buffer_full_(false) { | 
| 71   history_.reset(new rtc::scoped_ptr<complex<float>[]>[freqs_]()); | 71   history_.reset(new rtc::scoped_ptr<complex<float>[]>[freqs_]()); | 
| 72   for (int i = 0; i < freqs_; ++i) { | 72   for (size_t i = 0; i < freqs_; ++i) { | 
| 73     history_[i].reset(new complex<float>[window_size_]()); | 73     history_[i].reset(new complex<float>[window_size_]()); | 
| 74   } | 74   } | 
| 75   subhistory_.reset(new rtc::scoped_ptr<complex<float>[]>[freqs_]()); | 75   subhistory_.reset(new rtc::scoped_ptr<complex<float>[]>[freqs_]()); | 
| 76   for (int i = 0; i < freqs_; ++i) { | 76   for (size_t i = 0; i < freqs_; ++i) { | 
| 77     subhistory_[i].reset(new complex<float>[window_size_]()); | 77     subhistory_[i].reset(new complex<float>[window_size_]()); | 
| 78   } | 78   } | 
| 79   subhistory_sq_.reset(new rtc::scoped_ptr<complex<float>[]>[freqs_]()); | 79   subhistory_sq_.reset(new rtc::scoped_ptr<complex<float>[]>[freqs_]()); | 
| 80   for (int i = 0; i < freqs_; ++i) { | 80   for (size_t i = 0; i < freqs_; ++i) { | 
| 81     subhistory_sq_[i].reset(new complex<float>[window_size_]()); | 81     subhistory_sq_[i].reset(new complex<float>[window_size_]()); | 
| 82   } | 82   } | 
| 83   switch (type) { | 83   switch (type) { | 
| 84     case kStepInfinite: | 84     case kStepInfinite: | 
| 85       step_func_ = &VarianceArray::InfiniteStep; | 85       step_func_ = &VarianceArray::InfiniteStep; | 
| 86       break; | 86       break; | 
| 87     case kStepDecaying: | 87     case kStepDecaying: | 
| 88       step_func_ = &VarianceArray::DecayStep; | 88       step_func_ = &VarianceArray::DecayStep; | 
| 89       break; | 89       break; | 
| 90     case kStepWindowed: | 90     case kStepWindowed: | 
| 91       step_func_ = &VarianceArray::WindowedStep; | 91       step_func_ = &VarianceArray::WindowedStep; | 
| 92       break; | 92       break; | 
| 93     case kStepBlocked: | 93     case kStepBlocked: | 
| 94       step_func_ = &VarianceArray::BlockedStep; | 94       step_func_ = &VarianceArray::BlockedStep; | 
| 95       break; | 95       break; | 
| 96     case kStepBlockBasedMovingAverage: | 96     case kStepBlockBasedMovingAverage: | 
| 97       step_func_ = &VarianceArray::BlockBasedMovingAverage; | 97       step_func_ = &VarianceArray::BlockBasedMovingAverage; | 
| 98       break; | 98       break; | 
| 99   } | 99   } | 
| 100 } | 100 } | 
| 101 | 101 | 
| 102 // Compute the variance with Welford's algorithm, adding some fudge to | 102 // Compute the variance with Welford's algorithm, adding some fudge to | 
| 103 // the input in case of all-zeroes. | 103 // the input in case of all-zeroes. | 
| 104 void VarianceArray::InfiniteStep(const complex<float>* data, bool skip_fudge) { | 104 void VarianceArray::InfiniteStep(const complex<float>* data, bool skip_fudge) { | 
| 105   array_mean_ = 0.0f; | 105   array_mean_ = 0.0f; | 
| 106   ++count_; | 106   ++count_; | 
| 107   for (int i = 0; i < freqs_; ++i) { | 107   for (size_t i = 0; i < freqs_; ++i) { | 
| 108     complex<float> sample = data[i]; | 108     complex<float> sample = data[i]; | 
| 109     if (!skip_fudge) { | 109     if (!skip_fudge) { | 
| 110       sample = zerofudge(sample); | 110       sample = zerofudge(sample); | 
| 111     } | 111     } | 
| 112     if (count_ == 1) { | 112     if (count_ == 1) { | 
| 113       running_mean_[i] = sample; | 113       running_mean_[i] = sample; | 
| 114       variance_[i] = 0.0f; | 114       variance_[i] = 0.0f; | 
| 115     } else { | 115     } else { | 
| 116       float old_sum = conj_sum_[i]; | 116       float old_sum = conj_sum_[i]; | 
| 117       complex<float> old_mean = running_mean_[i]; | 117       complex<float> old_mean = running_mean_[i]; | 
| 118       running_mean_[i] = | 118       running_mean_[i] = | 
| 119           old_mean + (sample - old_mean) / static_cast<float>(count_); | 119           old_mean + (sample - old_mean) / static_cast<float>(count_); | 
| 120       conj_sum_[i] = | 120       conj_sum_[i] = | 
| 121           (old_sum + std::conj(sample - old_mean) * (sample - running_mean_[i])) | 121           (old_sum + std::conj(sample - old_mean) * (sample - running_mean_[i])) | 
| 122               .real(); | 122               .real(); | 
| 123       variance_[i] = | 123       variance_[i] = | 
| 124           conj_sum_[i] / (count_ - 1); | 124           conj_sum_[i] / (count_ - 1); | 
| 125     } | 125     } | 
| 126     array_mean_ += (variance_[i] - array_mean_) / (i + 1); | 126     array_mean_ += (variance_[i] - array_mean_) / (i + 1); | 
| 127   } | 127   } | 
| 128 } | 128 } | 
| 129 | 129 | 
| 130 // Compute the variance from the beginning, with exponential decaying of the | 130 // Compute the variance from the beginning, with exponential decaying of the | 
| 131 // series data. | 131 // series data. | 
| 132 void VarianceArray::DecayStep(const complex<float>* data, bool /*dummy*/) { | 132 void VarianceArray::DecayStep(const complex<float>* data, bool /*dummy*/) { | 
| 133   array_mean_ = 0.0f; | 133   array_mean_ = 0.0f; | 
| 134   ++count_; | 134   ++count_; | 
| 135   for (int i = 0; i < freqs_; ++i) { | 135   for (size_t i = 0; i < freqs_; ++i) { | 
| 136     complex<float> sample = data[i]; | 136     complex<float> sample = data[i]; | 
| 137     sample = zerofudge(sample); | 137     sample = zerofudge(sample); | 
| 138 | 138 | 
| 139     if (count_ == 1) { | 139     if (count_ == 1) { | 
| 140       running_mean_[i] = sample; | 140       running_mean_[i] = sample; | 
| 141       running_mean_sq_[i] = sample * std::conj(sample); | 141       running_mean_sq_[i] = sample * std::conj(sample); | 
| 142       variance_[i] = 0.0f; | 142       variance_[i] = 0.0f; | 
| 143     } else { | 143     } else { | 
| 144       complex<float> prev = running_mean_[i]; | 144       complex<float> prev = running_mean_[i]; | 
| 145       complex<float> prev2 = running_mean_sq_[i]; | 145       complex<float> prev2 = running_mean_sq_[i]; | 
| 146       running_mean_[i] = decay_ * prev + (1.0f - decay_) * sample; | 146       running_mean_[i] = decay_ * prev + (1.0f - decay_) * sample; | 
| 147       running_mean_sq_[i] = | 147       running_mean_sq_[i] = | 
| 148           decay_ * prev2 + (1.0f - decay_) * sample * std::conj(sample); | 148           decay_ * prev2 + (1.0f - decay_) * sample * std::conj(sample); | 
| 149       variance_[i] = (running_mean_sq_[i] - | 149       variance_[i] = (running_mean_sq_[i] - | 
| 150                       running_mean_[i] * std::conj(running_mean_[i])).real(); | 150                       running_mean_[i] * std::conj(running_mean_[i])).real(); | 
| 151     } | 151     } | 
| 152 | 152 | 
| 153     array_mean_ += (variance_[i] - array_mean_) / (i + 1); | 153     array_mean_ += (variance_[i] - array_mean_) / (i + 1); | 
| 154   } | 154   } | 
| 155 } | 155 } | 
| 156 | 156 | 
| 157 // Windowed variance computation. On each step, the variances for the | 157 // Windowed variance computation. On each step, the variances for the | 
| 158 // window are recomputed from scratch, using Welford's algorithm. | 158 // window are recomputed from scratch, using Welford's algorithm. | 
| 159 void VarianceArray::WindowedStep(const complex<float>* data, bool /*dummy*/) { | 159 void VarianceArray::WindowedStep(const complex<float>* data, bool /*dummy*/) { | 
| 160   int num = min(count_ + 1, window_size_); | 160   size_t num = min(count_ + 1, window_size_); | 
| 161   array_mean_ = 0.0f; | 161   array_mean_ = 0.0f; | 
| 162   for (int i = 0; i < freqs_; ++i) { | 162   for (size_t i = 0; i < freqs_; ++i) { | 
| 163     complex<float> mean; | 163     complex<float> mean; | 
| 164     float conj_sum = 0.0f; | 164     float conj_sum = 0.0f; | 
| 165 | 165 | 
| 166     history_[i][history_cursor_] = data[i]; | 166     history_[i][history_cursor_] = data[i]; | 
| 167 | 167 | 
| 168     mean = history_[i][history_cursor_]; | 168     mean = history_[i][history_cursor_]; | 
| 169     variance_[i] = 0.0f; | 169     variance_[i] = 0.0f; | 
| 170     for (int j = 1; j < num; ++j) { | 170     for (size_t j = 1; j < num; ++j) { | 
| 171       complex<float> sample = | 171       complex<float> sample = | 
| 172           zerofudge(history_[i][(history_cursor_ + j) % window_size_]); | 172           zerofudge(history_[i][(history_cursor_ + j) % window_size_]); | 
| 173       sample = history_[i][(history_cursor_ + j) % window_size_]; | 173       sample = history_[i][(history_cursor_ + j) % window_size_]; | 
| 174       float old_sum = conj_sum; | 174       float old_sum = conj_sum; | 
| 175       complex<float> old_mean = mean; | 175       complex<float> old_mean = mean; | 
| 176 | 176 | 
| 177       mean = old_mean + (sample - old_mean) / static_cast<float>(j + 1); | 177       mean = old_mean + (sample - old_mean) / static_cast<float>(j + 1); | 
| 178       conj_sum = | 178       conj_sum = | 
| 179           (old_sum + std::conj(sample - old_mean) * (sample - mean)).real(); | 179           (old_sum + std::conj(sample - old_mean) * (sample - mean)).real(); | 
| 180       variance_[i] = conj_sum / (j); | 180       variance_[i] = conj_sum / (j); | 
| 181     } | 181     } | 
| 182     array_mean_ += (variance_[i] - array_mean_) / (i + 1); | 182     array_mean_ += (variance_[i] - array_mean_) / (i + 1); | 
| 183   } | 183   } | 
| 184   history_cursor_ = (history_cursor_ + 1) % window_size_; | 184   history_cursor_ = (history_cursor_ + 1) % window_size_; | 
| 185   ++count_; | 185   ++count_; | 
| 186 } | 186 } | 
| 187 | 187 | 
| 188 // Variance with a window of blocks. Within each block, the variances are | 188 // Variance with a window of blocks. Within each block, the variances are | 
| 189 // recomputed from scratch at every stp, using |Var(X) = E(X^2) - E^2(X)|. | 189 // recomputed from scratch at every stp, using |Var(X) = E(X^2) - E^2(X)|. | 
| 190 // Once a block is filled with kWindowBlockSize samples, it is added to the | 190 // Once a block is filled with kWindowBlockSize samples, it is added to the | 
| 191 // history window and a new block is started. The variances for the window | 191 // history window and a new block is started. The variances for the window | 
| 192 // are recomputed from scratch at each of these transitions. | 192 // are recomputed from scratch at each of these transitions. | 
| 193 void VarianceArray::BlockedStep(const complex<float>* data, bool /*dummy*/) { | 193 void VarianceArray::BlockedStep(const complex<float>* data, bool /*dummy*/) { | 
| 194   int blocks = min(window_size_, history_cursor_ + 1); | 194   size_t blocks = min(window_size_, history_cursor_ + 1); | 
| 195   for (int i = 0; i < freqs_; ++i) { | 195   for (size_t i = 0; i < freqs_; ++i) { | 
| 196     AddToMean(data[i], count_ + 1, &sub_running_mean_[i]); | 196     AddToMean(data[i], count_ + 1, &sub_running_mean_[i]); | 
| 197     AddToMean(data[i] * std::conj(data[i]), count_ + 1, | 197     AddToMean(data[i] * std::conj(data[i]), count_ + 1, | 
| 198               &sub_running_mean_sq_[i]); | 198               &sub_running_mean_sq_[i]); | 
| 199     subhistory_[i][history_cursor_ % window_size_] = sub_running_mean_[i]; | 199     subhistory_[i][history_cursor_ % window_size_] = sub_running_mean_[i]; | 
| 200     subhistory_sq_[i][history_cursor_ % window_size_] = sub_running_mean_sq_[i]; | 200     subhistory_sq_[i][history_cursor_ % window_size_] = sub_running_mean_sq_[i]; | 
| 201 | 201 | 
| 202     variance_[i] = | 202     variance_[i] = | 
| 203         (NewMean(running_mean_sq_[i], sub_running_mean_sq_[i], blocks) - | 203         (NewMean(running_mean_sq_[i], sub_running_mean_sq_[i], blocks) - | 
| 204          NewMean(running_mean_[i], sub_running_mean_[i], blocks) * | 204          NewMean(running_mean_[i], sub_running_mean_[i], blocks) * | 
| 205              std::conj(NewMean(running_mean_[i], sub_running_mean_[i], blocks))) | 205              std::conj(NewMean(running_mean_[i], sub_running_mean_[i], blocks))) | 
| 206             .real(); | 206             .real(); | 
| 207     if (count_ == kWindowBlockSize - 1) { | 207     if (count_ == kWindowBlockSize - 1) { | 
| 208       sub_running_mean_[i] = complex<float>(0.0f, 0.0f); | 208       sub_running_mean_[i] = complex<float>(0.0f, 0.0f); | 
| 209       sub_running_mean_sq_[i] = complex<float>(0.0f, 0.0f); | 209       sub_running_mean_sq_[i] = complex<float>(0.0f, 0.0f); | 
| 210       running_mean_[i] = complex<float>(0.0f, 0.0f); | 210       running_mean_[i] = complex<float>(0.0f, 0.0f); | 
| 211       running_mean_sq_[i] = complex<float>(0.0f, 0.0f); | 211       running_mean_sq_[i] = complex<float>(0.0f, 0.0f); | 
| 212       for (int j = 0; j < min(window_size_, history_cursor_); ++j) { | 212       for (size_t j = 0; j < min(window_size_, history_cursor_); ++j) { | 
| 213         AddToMean(subhistory_[i][j], j + 1, &running_mean_[i]); | 213         AddToMean(subhistory_[i][j], j + 1, &running_mean_[i]); | 
| 214         AddToMean(subhistory_sq_[i][j], j + 1, &running_mean_sq_[i]); | 214         AddToMean(subhistory_sq_[i][j], j + 1, &running_mean_sq_[i]); | 
| 215       } | 215       } | 
| 216       ++history_cursor_; | 216       ++history_cursor_; | 
| 217     } | 217     } | 
| 218   } | 218   } | 
| 219   ++count_; | 219   ++count_; | 
| 220   if (count_ == kWindowBlockSize) { | 220   if (count_ == kWindowBlockSize) { | 
| 221     count_ = 0; | 221     count_ = 0; | 
| 222   } | 222   } | 
| 223 } | 223 } | 
| 224 | 224 | 
| 225 // Recomputes variances for each window from scratch based on previous window. | 225 // Recomputes variances for each window from scratch based on previous window. | 
| 226 void VarianceArray::BlockBasedMovingAverage(const std::complex<float>* data, | 226 void VarianceArray::BlockBasedMovingAverage(const std::complex<float>* data, | 
| 227                                             bool /*dummy*/) { | 227                                             bool /*dummy*/) { | 
| 228   // TODO(ekmeyerson) To mitigate potential divergence, add counter so that | 228   // TODO(ekmeyerson) To mitigate potential divergence, add counter so that | 
| 229   // after every so often sums are computed scratch by summing over all | 229   // after every so often sums are computed scratch by summing over all | 
| 230   // elements instead of subtracting oldest and adding newest. | 230   // elements instead of subtracting oldest and adding newest. | 
| 231   for (int i = 0; i < freqs_; ++i) { | 231   for (size_t i = 0; i < freqs_; ++i) { | 
| 232     sub_running_mean_[i] += data[i]; | 232     sub_running_mean_[i] += data[i]; | 
| 233     sub_running_mean_sq_[i] += data[i] * std::conj(data[i]); | 233     sub_running_mean_sq_[i] += data[i] * std::conj(data[i]); | 
| 234   } | 234   } | 
| 235   ++count_; | 235   ++count_; | 
| 236 | 236 | 
| 237   // TODO(ekmeyerson) Make kWindowBlockSize nonconstant to allow | 237   // TODO(ekmeyerson) Make kWindowBlockSize nonconstant to allow | 
| 238   // experimentation with different block size,window size pairs. | 238   // experimentation with different block size,window size pairs. | 
| 239   if (count_ >= kWindowBlockSize) { | 239   if (count_ >= kWindowBlockSize) { | 
| 240     count_ = 0; | 240     count_ = 0; | 
| 241 | 241 | 
| 242     for (int i = 0; i < freqs_; ++i) { | 242     for (size_t i = 0; i < freqs_; ++i) { | 
| 243       running_mean_[i] -= subhistory_[i][history_cursor_]; | 243       running_mean_[i] -= subhistory_[i][history_cursor_]; | 
| 244       running_mean_sq_[i] -= subhistory_sq_[i][history_cursor_]; | 244       running_mean_sq_[i] -= subhistory_sq_[i][history_cursor_]; | 
| 245 | 245 | 
| 246       float scale = 1.f / kWindowBlockSize; | 246       float scale = 1.f / kWindowBlockSize; | 
| 247       subhistory_[i][history_cursor_] = sub_running_mean_[i] * scale; | 247       subhistory_[i][history_cursor_] = sub_running_mean_[i] * scale; | 
| 248       subhistory_sq_[i][history_cursor_] = sub_running_mean_sq_[i] * scale; | 248       subhistory_sq_[i][history_cursor_] = sub_running_mean_sq_[i] * scale; | 
| 249 | 249 | 
| 250       sub_running_mean_[i] = std::complex<float>(0.0f, 0.0f); | 250       sub_running_mean_[i] = std::complex<float>(0.0f, 0.0f); | 
| 251       sub_running_mean_sq_[i] = std::complex<float>(0.0f, 0.0f); | 251       sub_running_mean_sq_[i] = std::complex<float>(0.0f, 0.0f); | 
| 252 | 252 | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
| 272   memset(running_mean_sq_.get(), 0, sizeof(*running_mean_sq_.get()) * freqs_); | 272   memset(running_mean_sq_.get(), 0, sizeof(*running_mean_sq_.get()) * freqs_); | 
| 273   memset(variance_.get(), 0, sizeof(*variance_.get()) * freqs_); | 273   memset(variance_.get(), 0, sizeof(*variance_.get()) * freqs_); | 
| 274   memset(conj_sum_.get(), 0, sizeof(*conj_sum_.get()) * freqs_); | 274   memset(conj_sum_.get(), 0, sizeof(*conj_sum_.get()) * freqs_); | 
| 275   history_cursor_ = 0; | 275   history_cursor_ = 0; | 
| 276   count_ = 0; | 276   count_ = 0; | 
| 277   array_mean_ = 0.0f; | 277   array_mean_ = 0.0f; | 
| 278 } | 278 } | 
| 279 | 279 | 
| 280 void VarianceArray::ApplyScale(float scale) { | 280 void VarianceArray::ApplyScale(float scale) { | 
| 281   array_mean_ = 0.0f; | 281   array_mean_ = 0.0f; | 
| 282   for (int i = 0; i < freqs_; ++i) { | 282   for (size_t i = 0; i < freqs_; ++i) { | 
| 283     variance_[i] *= scale * scale; | 283     variance_[i] *= scale * scale; | 
| 284     array_mean_ += (variance_[i] - array_mean_) / (i + 1); | 284     array_mean_ += (variance_[i] - array_mean_) / (i + 1); | 
| 285   } | 285   } | 
| 286 } | 286 } | 
| 287 | 287 | 
| 288 GainApplier::GainApplier(int freqs, float change_limit) | 288 GainApplier::GainApplier(size_t freqs, float change_limit) | 
| 289     : freqs_(freqs), | 289     : freqs_(freqs), | 
| 290       change_limit_(change_limit), | 290       change_limit_(change_limit), | 
| 291       target_(new float[freqs]()), | 291       target_(new float[freqs]()), | 
| 292       current_(new float[freqs]()) { | 292       current_(new float[freqs]()) { | 
| 293   for (int i = 0; i < freqs; ++i) { | 293   for (size_t i = 0; i < freqs; ++i) { | 
| 294     target_[i] = 1.0f; | 294     target_[i] = 1.0f; | 
| 295     current_[i] = 1.0f; | 295     current_[i] = 1.0f; | 
| 296   } | 296   } | 
| 297 } | 297 } | 
| 298 | 298 | 
| 299 void GainApplier::Apply(const complex<float>* in_block, | 299 void GainApplier::Apply(const complex<float>* in_block, | 
| 300                         complex<float>* out_block) { | 300                         complex<float>* out_block) { | 
| 301   for (int i = 0; i < freqs_; ++i) { | 301   for (size_t i = 0; i < freqs_; ++i) { | 
| 302     float factor = sqrtf(fabsf(current_[i])); | 302     float factor = sqrtf(fabsf(current_[i])); | 
| 303     if (!std::isnormal(factor)) { | 303     if (!std::isnormal(factor)) { | 
| 304       factor = 1.0f; | 304       factor = 1.0f; | 
| 305     } | 305     } | 
| 306     out_block[i] = factor * in_block[i]; | 306     out_block[i] = factor * in_block[i]; | 
| 307     current_[i] = UpdateFactor(target_[i], current_[i], change_limit_); | 307     current_[i] = UpdateFactor(target_[i], current_[i], change_limit_); | 
| 308   } | 308   } | 
| 309 } | 309 } | 
| 310 | 310 | 
| 311 }  // namespace intelligibility | 311 }  // namespace intelligibility | 
| 312 | 312 | 
| 313 }  // namespace webrtc | 313 }  // namespace webrtc | 
| OLD | NEW | 
|---|