Surface the noise estimate of the NS to be used by other components

R=henrik.lundin@webrtc.org, turaj@webrtc.org

Review URL: https://codereview.webrtc.org/1654443004 .

Cr-Commit-Position: refs/heads/master@{#11541}
diff --git a/webrtc/modules/audio_processing/include/audio_processing.h b/webrtc/modules/audio_processing/include/audio_processing.h
index bf3565d..138259c 100644
--- a/webrtc/modules/audio_processing/include/audio_processing.h
+++ b/webrtc/modules/audio_processing/include/audio_processing.h
@@ -915,6 +915,9 @@
   // which |kUnsupportedFunctionError| is returned.
   virtual float speech_probability() const = 0;
 
+  // Returns the noise estimate per frequency bin averaged over all channels.
+  virtual std::vector<float> NoiseEstimate() = 0;
+
  protected:
   virtual ~NoiseSuppression() {}
 };
diff --git a/webrtc/modules/audio_processing/include/mock_audio_processing.h b/webrtc/modules/audio_processing/include/mock_audio_processing.h
index 3a7e308..363e99a 100644
--- a/webrtc/modules/audio_processing/include/mock_audio_processing.h
+++ b/webrtc/modules/audio_processing/include/mock_audio_processing.h
@@ -140,6 +140,7 @@
       Level());
   MOCK_CONST_METHOD0(speech_probability,
       float());
+  MOCK_METHOD0(NoiseEstimate, std::vector<float>());
 };
 
 class MockVoiceDetection : public VoiceDetection {
diff --git a/webrtc/modules/audio_processing/noise_suppression_impl.cc b/webrtc/modules/audio_processing/noise_suppression_impl.cc
index de7e856..400e8e4 100644
--- a/webrtc/modules/audio_processing/noise_suppression_impl.cc
+++ b/webrtc/modules/audio_processing/noise_suppression_impl.cc
@@ -172,4 +172,30 @@
   return AudioProcessing::kUnsupportedFunctionError;
 #endif
 }
+
+std::vector<float> NoiseSuppressionImpl::NoiseEstimate() {
+  rtc::CritScope cs(crit_);
+  std::vector<float> noise_estimate;
+#if defined(WEBRTC_NS_FLOAT)
+  noise_estimate.assign(WebRtcNs_num_freq(), 0.f);
+  for (auto& suppressor : suppressors_) {
+    const float* noise = WebRtcNs_noise_estimate(suppressor->state());
+    for (size_t i = 0; i < noise_estimate.size(); ++i) {
+      noise_estimate[i] += noise[i] / suppressors_.size();
+    }
+  }
+#elif defined(WEBRTC_NS_FIXED)
+  const float kNormalizationFactor = 1.f / (1 << 8);
+  noise_estimate.assign(WebRtcNsx_num_freq(), 0.f);
+  for (auto& suppressor : suppressors_) {
+    const uint32_t* noise = WebRtcNsx_noise_estimate(suppressor->state());
+    for (size_t i = 0; i < noise_estimate.size(); ++i) {
+      noise_estimate[i] += kNormalizationFactor *
+          static_cast<float>(noise[i]) / suppressors_.size();
+    }
+  }
+#endif
+  return noise_estimate;
+}
+
 }  // namespace webrtc
diff --git a/webrtc/modules/audio_processing/noise_suppression_impl.h b/webrtc/modules/audio_processing/noise_suppression_impl.h
index debbc61..47fe815 100644
--- a/webrtc/modules/audio_processing/noise_suppression_impl.h
+++ b/webrtc/modules/audio_processing/noise_suppression_impl.h
@@ -11,6 +11,8 @@
 #ifndef WEBRTC_MODULES_AUDIO_PROCESSING_NOISE_SUPPRESSION_IMPL_H_
 #define WEBRTC_MODULES_AUDIO_PROCESSING_NOISE_SUPPRESSION_IMPL_H_
 
+#include <vector>
+
 #include "webrtc/base/constructormagic.h"
 #include "webrtc/base/criticalsection.h"
 #include "webrtc/base/scoped_ptr.h"
@@ -36,6 +38,7 @@
   int set_level(Level level) override;
   Level level() const override;
   float speech_probability() const override;
+  std::vector<float> NoiseEstimate() override;
 
  private:
   class Suppressor;
diff --git a/webrtc/modules/audio_processing/ns/noise_suppression.c b/webrtc/modules/audio_processing/ns/noise_suppression.c
index dd05e0a..8b6f45f 100644
--- a/webrtc/modules/audio_processing/ns/noise_suppression.c
+++ b/webrtc/modules/audio_processing/ns/noise_suppression.c
@@ -57,3 +57,15 @@
   }
   return self->priorSpeechProb;
 }
+
+const float* WebRtcNs_noise_estimate(const NsHandle* handle) {
+  const NoiseSuppressionC* self = (const NoiseSuppressionC*)handle;
+  if (handle == NULL || self->initFlag == 0) {
+    return NULL;
+  }
+  return self->noise;
+}
+
+size_t WebRtcNs_num_freq() {
+  return HALF_ANAL_BLOCKL;
+}
diff --git a/webrtc/modules/audio_processing/ns/noise_suppression.h b/webrtc/modules/audio_processing/ns/noise_suppression.h
index 8018118..41cad4e 100644
--- a/webrtc/modules/audio_processing/ns/noise_suppression.h
+++ b/webrtc/modules/audio_processing/ns/noise_suppression.h
@@ -109,6 +109,25 @@
  */
 float WebRtcNs_prior_speech_probability(NsHandle* handle);
 
+/* Returns a pointer to the noise estimate per frequency bin. The number of
+ * frequency bins can be provided using WebRtcNs_num_freq().
+ *
+ * Input
+ *      - handle        : Noise suppression instance.
+ *
+ * Return value         : Pointer to the noise estimate per frequency bin.
+ *                        Returns NULL if the input is a NULL pointer or an
+ *                        uninitialized instance.
+ */
+const float* WebRtcNs_noise_estimate(const NsHandle* handle);
+
+/* Returns the number of frequency bins, which is the length of the noise
+ * estimate for example.
+ *
+ * Return value         : Number of frequency bins.
+ */
+size_t WebRtcNs_num_freq();
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/webrtc/modules/audio_processing/ns/noise_suppression_x.c b/webrtc/modules/audio_processing/ns/noise_suppression_x.c
index 0a5ba13..efe8a5b 100644
--- a/webrtc/modules/audio_processing/ns/noise_suppression_x.c
+++ b/webrtc/modules/audio_processing/ns/noise_suppression_x.c
@@ -44,3 +44,15 @@
   WebRtcNsx_ProcessCore((NoiseSuppressionFixedC*)nsxInst, speechFrame,
                         num_bands, outFrame);
 }
+
+const uint32_t* WebRtcNsx_noise_estimate(const NsxHandle* nsxInst) {
+  const NoiseSuppressionFixedC* self = (const NoiseSuppressionFixedC*)nsxInst;
+  if (nsxInst == NULL || self->initFlag == 0) {
+    return NULL;
+  }
+  return self->prevNoiseU32;
+}
+
+size_t WebRtcNsx_num_freq() {
+  return HALF_ANAL_BLOCKL;
+}
diff --git a/webrtc/modules/audio_processing/ns/noise_suppression_x.h b/webrtc/modules/audio_processing/ns/noise_suppression_x.h
index 02b44cc..7a5fc42 100644
--- a/webrtc/modules/audio_processing/ns/noise_suppression_x.h
+++ b/webrtc/modules/audio_processing/ns/noise_suppression_x.h
@@ -11,6 +11,8 @@
 #ifndef WEBRTC_MODULES_AUDIO_PROCESSING_NS_NOISE_SUPPRESSION_X_H_
 #define WEBRTC_MODULES_AUDIO_PROCESSING_NS_NOISE_SUPPRESSION_X_H_
 
+#include <stddef.h>
+
 #include "webrtc/typedefs.h"
 
 typedef struct NsxHandleT NsxHandle;
@@ -81,6 +83,25 @@
                        int num_bands,
                        short* const* outFrame);
 
+/* Returns a pointer to the noise estimate per frequency bin. The number of
+ * frequency bins can be provided using WebRtcNsx_num_freq().
+ *
+ * Input
+ *      - nsxInst       : NSx instance. Needs to be initiated before call.
+ *
+ * Return value         : Pointer to the noise estimate per frequency bin.
+ *                        Returns NULL if the input is a NULL pointer or an
+ *                        uninitialized instance.
+ */
+const uint32_t* WebRtcNsx_noise_estimate(const NsxHandle* nsxInst);
+
+/* Returns the number of frequency bins, which is the length of the noise
+ * estimate for example.
+ *
+ * Return value         : Number of frequency bins.
+ */
+size_t WebRtcNsx_num_freq();
+
 #ifdef __cplusplus
 }
 #endif