Reparent Nonlinear beamformer under beamforming interface.

R=aluebs@webrtc.org, andrew@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/41269004

Cr-Commit-Position: refs/heads/master@{#8862}
This commit is contained in:
Michael Graczyk
2015-03-25 16:37:27 -07:00
parent bf395c1fc0
commit dfa36058c9
14 changed files with 85 additions and 36 deletions

View File

@ -13,7 +13,6 @@
#include <complex>
#include "webrtc/base/checks.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/common_audio/blocker.h"
#include "webrtc/common_audio/real_fourier.h"

View File

@ -72,6 +72,7 @@ source_set("audio_processing") {
"audio_buffer.h",
"audio_processing_impl.cc",
"audio_processing_impl.h",
"beamformer/beamformer.h",
"beamformer/complex_matrix.h",
"beamformer/covariance_matrix_generator.cc",
"beamformer/covariance_matrix_generator.h",

View File

@ -82,6 +82,7 @@
'audio_buffer.h',
'audio_processing_impl.cc',
'audio_processing_impl.h',
'beamformer/beamformer.h',
'beamformer/complex_matrix.h',
'beamformer/covariance_matrix_generator.cc',
'beamformer/covariance_matrix_generator.h',

View File

@ -14,11 +14,11 @@
#include "webrtc/base/platform_file.h"
#include "webrtc/common_audio/include/audio_util.h"
#include "webrtc/common_audio/channel_buffer.h"
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
#include "webrtc/modules/audio_processing/agc/agc_manager_direct.h"
#include "webrtc/modules/audio_processing/audio_buffer.h"
#include "webrtc/modules/audio_processing/beamformer/nonlinear_beamformer.h"
#include "webrtc/common_audio/channel_buffer.h"
#include "webrtc/modules/audio_processing/common.h"
#include "webrtc/modules/audio_processing/echo_cancellation_impl.h"
#include "webrtc/modules/audio_processing/echo_control_mobile_impl.h"
@ -134,7 +134,7 @@ AudioProcessing* AudioProcessing::Create(const Config& config) {
}
AudioProcessing* AudioProcessing::Create(const Config& config,
NonlinearBeamformer* beamformer) {
Beamformer<float>* beamformer) {
AudioProcessingImpl* apm = new AudioProcessingImpl(config, beamformer);
if (apm->Initialize() != kNoError) {
delete apm;
@ -148,7 +148,7 @@ AudioProcessingImpl::AudioProcessingImpl(const Config& config)
: AudioProcessingImpl(config, nullptr) {}
AudioProcessingImpl::AudioProcessingImpl(const Config& config,
NonlinearBeamformer* beamformer)
Beamformer<float>* beamformer)
: echo_cancellation_(NULL),
echo_control_mobile_(NULL),
gain_control_(NULL),
@ -600,7 +600,7 @@ int AudioProcessingImpl::ProcessStreamLocked() {
}
if (beamformer_enabled_) {
beamformer_->ProcessChunk(ca->split_data_f(), ca->split_data_f());
beamformer_->ProcessChunk(*ca->split_data_f(), ca->split_data_f());
ca->set_num_channels(1);
}

View File

@ -11,19 +11,21 @@
#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_AUDIO_PROCESSING_IMPL_H_
#define WEBRTC_MODULES_AUDIO_PROCESSING_AUDIO_PROCESSING_IMPL_H_
#include "webrtc/modules/audio_processing/include/audio_processing.h"
#include <list>
#include <string>
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/base/thread_annotations.h"
#include "webrtc/modules/audio_processing/include/audio_processing.h"
namespace webrtc {
class AgcManagerDirect;
class AudioBuffer;
class NonlinearBeamformer;
template<typename T>
class Beamformer;
class CriticalSectionWrapper;
class EchoCancellationImpl;
class EchoControlMobileImpl;
@ -86,8 +88,9 @@ class AudioFormat : public AudioRate {
class AudioProcessingImpl : public AudioProcessing {
public:
explicit AudioProcessingImpl(const Config& config);
// Only for testing.
AudioProcessingImpl(const Config& config, NonlinearBeamformer* beamformer);
// AudioProcessingImpl takes ownership of beamformer.
AudioProcessingImpl(const Config& config, Beamformer<float>* beamformer);
virtual ~AudioProcessingImpl();
// AudioProcessing methods.
@ -218,7 +221,7 @@ class AudioProcessingImpl : public AudioProcessing {
bool transient_suppressor_enabled_;
rtc::scoped_ptr<TransientSuppressor> transient_suppressor_;
const bool beamformer_enabled_;
rtc::scoped_ptr<NonlinearBeamformer> beamformer_;
rtc::scoped_ptr<Beamformer<float>> beamformer_;
const std::vector<Point> array_geometry_;
const bool supports_48kHz_;

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2015 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 WEBRTC_MODULES_AUDIO_PROCESSING_BEAMFORMER_BEAMFORMER_H_
#define WEBRTC_MODULES_AUDIO_PROCESSING_BEAMFORMER_BEAMFORMER_H_
#include "webrtc/common_audio/channel_buffer.h"
namespace webrtc {
template<typename T>
class Beamformer {
public:
virtual ~Beamformer() {}
// Process one time-domain chunk of audio. The audio is expected to be split
// into frequency bands inside the ChannelBuffer. The number of frames and
// channels must correspond to the constructor parameters. The same
// ChannelBuffer can be passed in as |input| and |output|.
virtual void ProcessChunk(const ChannelBuffer<T>& input,
ChannelBuffer<T>* output) = 0;
// Sample rate corresponds to the lower band.
// Needs to be called before the the Beamformer can be used.
virtual void Initialize(int chunk_size_ms, int sample_rate_hz) = 0;
// Returns true if the current data contains the target signal.
// Which signals are considered "targets" is implementation dependent.
virtual bool is_target_present() = 0;
};
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_PROCESSING_BEAMFORMER_BEAMFORMER_H_

View File

@ -15,7 +15,6 @@
#include "webrtc/base/checks.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/common_audio/channel_buffer.h"
#include "webrtc/modules/audio_processing/beamformer/matrix.h"
namespace webrtc {

View File

@ -12,13 +12,13 @@
#define WEBRTC_MODULES_AUDIO_PROCESSING_BEAMFORMER_MATRIX_H_
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include "webrtc/base/checks.h"
#include "webrtc/base/constructormagic.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/common_audio/channel_buffer.h"
namespace {

View File

@ -19,6 +19,4 @@ MockNonlinearBeamformer::MockNonlinearBeamformer(
: NonlinearBeamformer(array_geometry) {
}
MockNonlinearBeamformer::~MockNonlinearBeamformer() {}
} // namespace webrtc

View File

@ -21,10 +21,9 @@ namespace webrtc {
class MockNonlinearBeamformer : public NonlinearBeamformer {
public:
explicit MockNonlinearBeamformer(const std::vector<Point>& array_geometry);
~MockNonlinearBeamformer() override;
MOCK_METHOD2(Initialize, void(int chunk_size_ms, int sample_rate_hz));
MOCK_METHOD2(ProcessChunk, void(const ChannelBuffer<float>* input,
MOCK_METHOD2(ProcessChunk, void(const ChannelBuffer<float>& input,
ChannelBuffer<float>* output));
MOCK_METHOD0(is_target_present, bool());
};

View File

@ -293,32 +293,32 @@ void NonlinearBeamformer::InitInterfCovMats() {
}
}
void NonlinearBeamformer::ProcessChunk(const ChannelBuffer<float>* input,
void NonlinearBeamformer::ProcessChunk(const ChannelBuffer<float>& input,
ChannelBuffer<float>* output) {
DCHECK_EQ(input->num_channels(), num_input_channels_);
DCHECK_EQ(input->num_frames_per_band(), chunk_length_);
DCHECK_EQ(input.num_channels(), num_input_channels_);
DCHECK_EQ(input.num_frames_per_band(), chunk_length_);
float old_high_pass_mask = high_pass_postfilter_mask_;
lapped_transform_->ProcessChunk(input->channels(0), output->channels(0));
lapped_transform_->ProcessChunk(input.channels(0), output->channels(0));
// Ramp up/down for smoothing. 1 mask per 10ms results in audible
// discontinuities.
const float ramp_increment =
(high_pass_postfilter_mask_ - old_high_pass_mask) /
input->num_frames_per_band();
input.num_frames_per_band();
// Apply delay and sum and post-filter in the time domain. WARNING: only works
// because delay-and-sum is not frequency dependent.
for (int i = 1; i < input->num_bands(); ++i) {
for (int i = 1; i < input.num_bands(); ++i) {
float smoothed_mask = old_high_pass_mask;
for (int j = 0; j < input->num_frames_per_band(); ++j) {
for (int j = 0; j < input.num_frames_per_band(); ++j) {
smoothed_mask += ramp_increment;
// Applying the delay and sum (at zero degrees, this is equivalent to
// averaging).
float sum = 0.f;
for (int k = 0; k < input->num_channels(); ++k) {
sum += input->channels(i)[k][j];
for (int k = 0; k < input.num_channels(); ++k) {
sum += input.channels(i)[k][j];
}
output->channels(i)[0][j] = sum / input->num_channels() * smoothed_mask;
output->channels(i)[0][j] = sum / input.num_channels() * smoothed_mask;
}
}
}

View File

@ -14,8 +14,10 @@
#include <vector>
#include "webrtc/common_audio/lapped_transform.h"
#include "webrtc/modules/audio_processing/beamformer/complex_matrix.h"
#include "webrtc/common_audio/channel_buffer.h"
#include "webrtc/modules/audio_processing/beamformer/array_util.h"
#include "webrtc/modules/audio_processing/beamformer/beamformer.h"
#include "webrtc/modules/audio_processing/beamformer/complex_matrix.h"
namespace webrtc {
@ -27,7 +29,9 @@ namespace webrtc {
// Beamforming Postprocessor" by Bastiaan Kleijn.
//
// TODO: Target angle assumed to be 0. Parameterize target angle.
class NonlinearBeamformer : public LappedTransform::Callback {
class NonlinearBeamformer
: public Beamformer<float>,
public LappedTransform::Callback {
public:
// At the moment it only accepts uniform linear microphone arrays. Using the
// first microphone as a reference position [0, 0, 0] is a natural choice.
@ -35,19 +39,20 @@ class NonlinearBeamformer : public LappedTransform::Callback {
// Sample rate corresponds to the lower band.
// Needs to be called before the NonlinearBeamformer can be used.
virtual void Initialize(int chunk_size_ms, int sample_rate_hz);
void Initialize(int chunk_size_ms, int sample_rate_hz) override;
// Process one time-domain chunk of audio. The audio is expected to be split
// into frequency bands inside the ChannelBuffer. The number of frames and
// channels must correspond to the constructor parameters. The same
// ChannelBuffer can be passed in as |input| and |output|.
virtual void ProcessChunk(const ChannelBuffer<float>* input,
ChannelBuffer<float>* output);
void ProcessChunk(const ChannelBuffer<float>& input,
ChannelBuffer<float>* output) override;
// After processing each block |is_target_present_| is set to true if the
// target signal es present and to false otherwise. This methods can be called
// to know if the data is target signal or interference and process it
// accordingly.
virtual bool is_target_present() { return is_target_present_; }
bool is_target_present() override { return is_target_present_; }
protected:
// Process one frequency-domain block of audio. This is where the fun

View File

@ -72,7 +72,7 @@ int main(int argc, char* argv[]) {
break;
}
bf.ProcessChunk(&captured_audio_cb, &captured_audio_cb);
bf.ProcessChunk(captured_audio_cb, &captured_audio_cb);
webrtc::PcmWriteFromFloat(
write_file, kChunkSize, 1, captured_audio_cb.channels());
}

View File

@ -25,7 +25,10 @@ struct AecCore;
namespace webrtc {
class AudioFrame;
class NonlinearBeamformer;
template<typename T>
class Beamformer;
class EchoCancellation;
class EchoControlMobile;
class GainControl;
@ -202,7 +205,7 @@ class AudioProcessing {
static AudioProcessing* Create(const Config& config);
// Only for testing.
static AudioProcessing* Create(const Config& config,
NonlinearBeamformer* beamformer);
Beamformer<float>* beamformer);
virtual ~AudioProcessing() {}
// Initializes internal states, while retaining all user settings. This