blob: 8e6d5890a07b3b7414cd89dfe66f625a7b41d03a [file] [log] [blame]
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef MODULES_AUDIO_CODING_NETEQ_BACKGROUND_NOISE_H_
#define MODULES_AUDIO_CODING_NETEQ_BACKGROUND_NOISE_H_
#include <string.h> // size_t
#include <memory>
#include "api/array_view.h"
namespace webrtc {
// Forward declarations.
class AudioMultiVector;
class PostDecodeVad;
// This class handles estimation of background noise parameters.
class BackgroundNoise {
public:
// TODO(hlundin): For 48 kHz support, increase kMaxLpcOrder to 10.
// Will work anyway, but probably sound a little worse.
static constexpr size_t kMaxLpcOrder = 8; // 32000 / 8000 + 4.
explicit BackgroundNoise(size_t num_channels);
virtual ~BackgroundNoise();
BackgroundNoise(const BackgroundNoise&) = delete;
BackgroundNoise& operator=(const BackgroundNoise&) = delete;
void Reset();
// Updates the parameter estimates based on the signal currently in the
// `sync_buffer`, and on the latest decision in `vad` if it is running.
// Returns true if the filter parameters are updated.
bool Update(const AudioMultiVector& sync_buffer, const PostDecodeVad& vad);
// Generates background noise given a random vector and writes the output to
// `buffer`.
void GenerateBackgroundNoise(rtc::ArrayView<const int16_t> random_vector,
size_t channel,
int mute_slope,
bool too_many_expands,
size_t num_noise_samples,
int16_t* buffer);
// Returns `energy_` for `channel`.
int32_t Energy(size_t channel) const;
// Sets the value of `mute_factor_` for `channel` to `value`.
void SetMuteFactor(size_t channel, int16_t value);
// Returns `mute_factor_` for `channel`.
int16_t MuteFactor(size_t channel) const;
// Returns a pointer to `filter_` for `channel`.
const int16_t* Filter(size_t channel) const;
// Returns a pointer to `filter_state_` for `channel`.
const int16_t* FilterState(size_t channel) const;
// Copies `input` to the filter state. Will not copy more than `kMaxLpcOrder`
// elements.
void SetFilterState(size_t channel, rtc::ArrayView<const int16_t> input);
// Returns `scale_` for `channel`.
int16_t Scale(size_t channel) const;
// Returns `scale_shift_` for `channel`.
int16_t ScaleShift(size_t channel) const;
// Accessors.
bool initialized() const { return initialized_; }
private:
static const int kThresholdIncrement = 229; // 0.0035 in Q16.
static const size_t kVecLen = 256;
static const int kLogVecLen = 8; // log2(kVecLen).
static const size_t kResidualLength = 64;
static const int16_t kLogResidualLength = 6; // log2(kResidualLength)
struct ChannelParameters {
// Constructor.
ChannelParameters() { Reset(); }
void Reset() {
energy = 2500;
max_energy = 0;
energy_update_threshold = 500000;
low_energy_update_threshold = 0;
memset(filter_state, 0, sizeof(filter_state));
memset(filter, 0, sizeof(filter));
filter[0] = 4096;
mute_factor = 0;
scale = 20000;
scale_shift = 24;
}
int32_t energy;
int32_t max_energy;
int32_t energy_update_threshold;
int32_t low_energy_update_threshold;
int16_t filter_state[kMaxLpcOrder];
int16_t filter[kMaxLpcOrder + 1];
int16_t mute_factor;
int16_t scale;
int16_t scale_shift;
};
int32_t CalculateAutoCorrelation(const int16_t* signal,
size_t length,
int32_t* auto_correlation) const;
// Increments the energy threshold by a factor 1 + `kThresholdIncrement`.
void IncrementEnergyThreshold(size_t channel, int32_t sample_energy);
// Updates the filter parameters.
void SaveParameters(size_t channel,
const int16_t* lpc_coefficients,
const int16_t* filter_state,
int32_t sample_energy,
int32_t residual_energy);
size_t num_channels_;
std::unique_ptr<ChannelParameters[]> channel_parameters_;
bool initialized_;
};
} // namespace webrtc
#endif // MODULES_AUDIO_CODING_NETEQ_BACKGROUND_NOISE_H_