19a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org/*
29a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
39a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org *
49a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org *  Use of this source code is governed by a BSD-style license
59a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org *  that can be found in the LICENSE file in the root of the source
69a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org *  tree. An additional intellectual property rights grant can be found
79a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org *  in the file PATENTS.  All contributing project authors may
89a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
99a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org */
109a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
11e5abc854f3dc47de16067c2a41476c39b7626722henrik.lundin@webrtc.org#ifndef WEBRTC_MODULES_AUDIO_CODING_NETEQ_BACKGROUND_NOISE_H_
12e5abc854f3dc47de16067c2a41476c39b7626722henrik.lundin@webrtc.org#define WEBRTC_MODULES_AUDIO_CODING_NETEQ_BACKGROUND_NOISE_H_
139a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
143f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org#include <string.h>  // size_t
159a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
16774b3d38a4a0f1a8ec08972a3c543cb5d607ce13henrike@webrtc.org#include "webrtc/base/constructormagic.h"
17e5abc854f3dc47de16067c2a41476c39b7626722henrik.lundin@webrtc.org#include "webrtc/modules/audio_coding/neteq/audio_multi_vector.h"
18e5abc854f3dc47de16067c2a41476c39b7626722henrik.lundin@webrtc.org#include "webrtc/modules/audio_coding/neteq/interface/neteq.h"
199a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org#include "webrtc/system_wrappers/interface/scoped_ptr.h"
209a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org#include "webrtc/typedefs.h"
219a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
229a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.orgnamespace webrtc {
239a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
249a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org// Forward declarations.
259a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.orgclass PostDecodeVad;
269a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
279a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org// This class handles estimation of background noise parameters.
289a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.orgclass BackgroundNoise {
299a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org public:
309a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // TODO(hlundin): For 48 kHz support, increase kMaxLpcOrder to 10.
319a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Will work anyway, but probably sound a little worse.
329a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  static const int kMaxLpcOrder = 8;  // 32000 / 8000 + 4.
339a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
34dd1b19d950158fbb1d7e1792c4db95460d5f8c49pbos@webrtc.org  explicit BackgroundNoise(size_t num_channels);
35dd1b19d950158fbb1d7e1792c4db95460d5f8c49pbos@webrtc.org  virtual ~BackgroundNoise();
369a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
379a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  void Reset();
389a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
399a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Updates the parameter estimates based on the signal currently in the
409a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // |sync_buffer|, and on the latest decision in |vad| if it is running.
410e9c399746f45ceaf46f12b11ba93c09cca0c2bbhenrik.lundin@webrtc.org  void Update(const AudioMultiVector& sync_buffer,
429a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org              const PostDecodeVad& vad);
439a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
449a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Returns |energy_| for |channel|.
459a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  int32_t Energy(size_t channel) const;
469a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
479a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Sets the value of |mute_factor_| for |channel| to |value|.
489a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  void SetMuteFactor(size_t channel, int16_t value);
499a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
509a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Returns |mute_factor_| for |channel|.
519a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  int16_t MuteFactor(size_t channel) const;
529a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
539a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Returns a pointer to |filter_| for |channel|.
549a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  const int16_t* Filter(size_t channel) const;
559a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
569a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Returns a pointer to |filter_state_| for |channel|.
579a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  const int16_t* FilterState(size_t channel) const;
589a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
599a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Copies |length| elements from |input| to the filter state. Will not copy
609a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // more than |kMaxLpcOrder| elements.
619a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  void SetFilterState(size_t channel, const int16_t* input, size_t length);
629a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
639a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Returns |scale_| for |channel|.
649a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  int16_t Scale(size_t channel) const;
659a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
669a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Returns |scale_shift_| for |channel|.
679a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  int16_t ScaleShift(size_t channel) const;
689a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
699a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Accessors.
709a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  bool initialized() const { return initialized_; }
716ca9e7d4a429a9fa69ab41dece14a4dc8c9f9b11turaj@webrtc.org  NetEqBackgroundNoiseMode mode() const { return mode_; }
726ca9e7d4a429a9fa69ab41dece14a4dc8c9f9b11turaj@webrtc.org
736ca9e7d4a429a9fa69ab41dece14a4dc8c9f9b11turaj@webrtc.org  // Sets the mode of the background noise playout for cases when there is long
746ca9e7d4a429a9fa69ab41dece14a4dc8c9f9b11turaj@webrtc.org  // duration of packet loss.
756ca9e7d4a429a9fa69ab41dece14a4dc8c9f9b11turaj@webrtc.org  void set_mode(NetEqBackgroundNoiseMode mode) { mode_ = mode; }
769a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
779a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org private:
789a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  static const int kThresholdIncrement = 229;  // 0.0035 in Q16.
799a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  static const int kVecLen = 256;
809a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  static const int kLogVecLen = 8;  // log2(kVecLen).
819a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  static const int kResidualLength = 64;
829a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  static const int kLogResidualLength = 6;  // log2(kResidualLength)
839a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
849a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  struct ChannelParameters {
859a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    // Constructor.
869a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    ChannelParameters() {
879a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org      Reset();
889a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    }
899a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
909a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    void Reset() {
919a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org      energy = 2500;
929a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org      max_energy = 0;
939a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org      energy_update_threshold = 500000;
949a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org      low_energy_update_threshold = 0;
959a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org      memset(filter_state, 0, sizeof(filter_state));
969a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org      memset(filter, 0, sizeof(filter));
979a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org      filter[0] = 4096;
989a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org      mute_factor = 0,
999a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org      scale = 20000;
1009a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org      scale_shift = 24;
1019a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    }
1029a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
1039a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    int32_t energy;
1049a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    int32_t max_energy;
1059a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    int32_t energy_update_threshold;
1069a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    int32_t low_energy_update_threshold;
1079a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    int16_t filter_state[kMaxLpcOrder];
1089a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    int16_t filter[kMaxLpcOrder + 1];
1099a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    int16_t mute_factor;
1109a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    int16_t scale;
1119a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    int16_t scale_shift;
1129a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  };
1139a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
1149a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  int32_t CalculateAutoCorrelation(const int16_t* signal,
115045e45efeca8776975254550137ec65268aadb54turaj@webrtc.org                                   int length,
1169a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org                                   int32_t* auto_correlation) const;
1179a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
1189a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Increments the energy threshold by a factor 1 + |kThresholdIncrement|.
1199a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  void IncrementEnergyThreshold(size_t channel, int32_t sample_energy);
1209a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
1219a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  // Updates the filter parameters.
1229a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  void SaveParameters(size_t channel,
1239a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org                      const int16_t* lpc_coefficients,
1249a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org                      const int16_t* filter_state,
1259a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org                      int32_t sample_energy,
1269a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org                      int32_t residual_energy);
1279a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
1289a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  size_t num_channels_;
129ba47616ee5a8d8a4d94e160b64b79a56845e291bandrew@webrtc.org  scoped_ptr<ChannelParameters[]> channel_parameters_;
1309a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  bool initialized_;
1316ca9e7d4a429a9fa69ab41dece14a4dc8c9f9b11turaj@webrtc.org  NetEqBackgroundNoiseMode mode_;
1329a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
1339a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org  DISALLOW_COPY_AND_ASSIGN(BackgroundNoise);
1349a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org};
1359a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
1369a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org}  // namespace webrtc
137e5abc854f3dc47de16067c2a41476c39b7626722henrik.lundin@webrtc.org#endif  // WEBRTC_MODULES_AUDIO_CODING_NETEQ_BACKGROUND_NOISE_H_
138