blob: 075b8ad46bea1823fb78a9376001c3bb06bd20bf [file] [log] [blame]
ekm030249d2015-06-15 13:02:24 -07001/*
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
ekmdb4fecf2015-06-22 17:49:08 -070011//
12// Specifies helper classes for intelligibility enhancement.
13//
14
ekm030249d2015-06-15 13:02:24 -070015#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_INTELLIGIBILITY_INTELLIGIBILITY_UTILS_H_
16#define WEBRTC_MODULES_AUDIO_PROCESSING_INTELLIGIBILITY_INTELLIGIBILITY_UTILS_H_
17
18#include <complex>
19
ekmdb4fecf2015-06-22 17:49:08 -070020#include "webrtc/base/scoped_ptr.h"
ekm030249d2015-06-15 13:02:24 -070021
22namespace webrtc {
23
24namespace intelligibility {
25
26// Internal helper for computing the variances of a stream of arrays.
27// The result is an array of variances per position: the i-th variance
28// is the variance of the stream of data on the i-th positions in the
29// input arrays.
30// There are four methods of computation:
31// * kStepInfinite computes variances from the beginning onwards
32// * kStepDecaying uses a recursive exponential decay formula with a
33// settable forgetting factor
34// * kStepWindowed computes variances within a moving window
35// * kStepBlocked is similar to kStepWindowed, but history is kept
36// as a rolling window of blocks: multiple input elements are used for
37// one block and the history then consists of the variances of these blocks
38// with the same effect as kStepWindowed, but less storage, so the window
39// can be longer
40class VarianceArray {
41 public:
42 enum StepType {
43 kStepInfinite = 0,
44 kStepDecaying,
45 kStepWindowed,
46 kStepBlocked
47 };
48
49 // Construct an instance for the given input array length (|freqs|) and
50 // computation algorithm (|type|), with the appropriate parameters.
51 // |window_size| is the number of samples for kStepWindowed and
52 // the number of blocks for kStepBlocked. |decay| is the forgetting factor
53 // for kStepDecaying.
54 VarianceArray(int freqs, StepType type, int window_size, float decay);
55
56 // Add a new data point to the series and compute the new variances.
57 // TODO(bercic) |skip_fudge| is a flag for kStepWindowed and kStepDecaying,
58 // whether they should skip adding some small dummy values to the input
59 // to prevent problems with all-zero inputs. Can probably be removed.
60 void Step(const std::complex<float>* data, bool skip_fudge = false) {
61 (this->*step_func_)(data, skip_fudge);
62 }
63 // Reset variances to zero and forget all history.
64 void Clear();
65 // Scale the input data by |scale|. Effectively multiply variances
66 // by |scale^2|.
67 void ApplyScale(float scale);
68
69 // The current set of variances.
ekmdb4fecf2015-06-22 17:49:08 -070070 const float* variance() const { return variance_.get(); }
ekm030249d2015-06-15 13:02:24 -070071
72 // The mean value of the current set of variances.
ekmdb4fecf2015-06-22 17:49:08 -070073 float array_mean() const { return array_mean_; }
ekm030249d2015-06-15 13:02:24 -070074
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
ekmdb4fecf2015-06-22 17:49:08 -070081 // TODO(ekmeyerson): Switch the following running means
82 // and histories from rtc::scoped_ptr to std::vector.
83
ekm030249d2015-06-15 13:02:24 -070084 // The current average X and X^2.
ekmdb4fecf2015-06-22 17:49:08 -070085 rtc::scoped_ptr<std::complex<float>[]> running_mean_;
86 rtc::scoped_ptr<std::complex<float>[]> running_mean_sq_;
ekm030249d2015-06-15 13:02:24 -070087
88 // Average X and X^2 for the current block in kStepBlocked.
ekmdb4fecf2015-06-22 17:49:08 -070089 rtc::scoped_ptr<std::complex<float>[]> sub_running_mean_;
90 rtc::scoped_ptr<std::complex<float>[]> sub_running_mean_sq_;
ekm030249d2015-06-15 13:02:24 -070091
92 // Sample history for the rolling window in kStepWindowed and block-wise
93 // histories for kStepBlocked.
ekmdb4fecf2015-06-22 17:49:08 -070094 rtc::scoped_ptr<rtc::scoped_ptr<std::complex<float>[]>[]> history_;
95 rtc::scoped_ptr<rtc::scoped_ptr<std::complex<float>[]>[]> subhistory_;
96 rtc::scoped_ptr<rtc::scoped_ptr<std::complex<float>[]>[]> subhistory_sq_;
ekm030249d2015-06-15 13:02:24 -070097
98 // The current set of variances and sums for Welford's algorithm.
ekmdb4fecf2015-06-22 17:49:08 -070099 rtc::scoped_ptr<float[]> variance_;
100 rtc::scoped_ptr<float[]> conj_sum_;
ekm030249d2015-06-15 13:02:24 -0700101
102 const int freqs_;
103 const int window_size_;
104 const float decay_;
105 int history_cursor_;
106 int count_;
107 float array_mean_;
108 void (VarianceArray::*step_func_)(const std::complex<float>*, bool);
109};
110
111// Helper class for smoothing gain changes. On each applicatiion step, the
112// currently used gains are changed towards a set of settable target gains,
113// constrained by a limit on the magnitude of the changes.
114class GainApplier {
115 public:
116 GainApplier(int freqs, float change_limit);
117
118 // Copy |in_block| to |out_block|, multiplied by the current set of gains,
119 // and step the current set of gains towards the target set.
120 void Apply(const std::complex<float>* in_block,
121 std::complex<float>* out_block);
122
123 // Return the current target gain set. Modify this array to set the targets.
ekmdb4fecf2015-06-22 17:49:08 -0700124 float* target() const { return target_.get(); }
ekm030249d2015-06-15 13:02:24 -0700125
126 private:
127 const int freqs_;
128 const float change_limit_;
ekmdb4fecf2015-06-22 17:49:08 -0700129 rtc::scoped_ptr<float[]> target_;
130 rtc::scoped_ptr<float[]> current_;
ekm030249d2015-06-15 13:02:24 -0700131};
132
133} // namespace intelligibility
134
135} // namespace webrtc
136
137#endif // WEBRTC_MODULES_AUDIO_PROCESSING_INTELLIGIBILITY_INTELLIGIBILITY_UTILS_H_