Add empty 3 band splitting filter API
This is only an empty API that will never be used. For now is 48kHz not supported in AudioProcessing. For that it needs to be added in InitializeLocked. But before the 3 band filter bank needs to be populated. BUG=webrtc:3146 R=bjornv@webrtc.org, kwiberg@webrtc.org Review URL: https://webrtc-codereview.appspot.com/30139004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@7715 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
2656bf813f
commit
087da13fe8
@ -20,7 +20,8 @@ namespace {
|
|||||||
enum {
|
enum {
|
||||||
kSamplesPer8kHzChannel = 80,
|
kSamplesPer8kHzChannel = 80,
|
||||||
kSamplesPer16kHzChannel = 160,
|
kSamplesPer16kHzChannel = 160,
|
||||||
kSamplesPer32kHzChannel = 320
|
kSamplesPer32kHzChannel = 320,
|
||||||
|
kSamplesPer48kHzChannel = 480
|
||||||
};
|
};
|
||||||
|
|
||||||
bool HasKeyboardChannel(AudioProcessing::ChannelLayout layout) {
|
bool HasKeyboardChannel(AudioProcessing::ChannelLayout layout) {
|
||||||
@ -171,13 +172,18 @@ AudioBuffer::AudioBuffer(int input_samples_per_channel,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (proc_samples_per_channel_ == kSamplesPer32kHzChannel) {
|
if (proc_samples_per_channel_ == kSamplesPer32kHzChannel ||
|
||||||
|
proc_samples_per_channel_ == kSamplesPer48kHzChannel) {
|
||||||
samples_per_split_channel_ = kSamplesPer16kHzChannel;
|
samples_per_split_channel_ = kSamplesPer16kHzChannel;
|
||||||
split_channels_low_.reset(new IFChannelBuffer(samples_per_split_channel_,
|
split_channels_low_.reset(new IFChannelBuffer(samples_per_split_channel_,
|
||||||
num_proc_channels_));
|
num_proc_channels_));
|
||||||
split_channels_high_.reset(new IFChannelBuffer(samples_per_split_channel_,
|
split_channels_high_.reset(new IFChannelBuffer(samples_per_split_channel_,
|
||||||
num_proc_channels_));
|
num_proc_channels_));
|
||||||
splitting_filter_.reset(new SplittingFilter(num_proc_channels_));
|
splitting_filter_.reset(new SplittingFilter(num_proc_channels_));
|
||||||
|
if (proc_samples_per_channel_ == kSamplesPer48kHzChannel) {
|
||||||
|
split_channels_super_high_.reset(
|
||||||
|
new IFChannelBuffer(samples_per_split_channel_, num_proc_channels_));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -391,6 +397,18 @@ float* const* AudioBuffer::high_pass_split_channels_f() {
|
|||||||
: NULL;
|
: NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const float* const* AudioBuffer::super_high_pass_split_channels_f() const {
|
||||||
|
return split_channels_super_high_.get()
|
||||||
|
? split_channels_super_high_->fbuf_const()->channels()
|
||||||
|
: NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
float* const* AudioBuffer::super_high_pass_split_channels_f() {
|
||||||
|
return split_channels_super_high_.get()
|
||||||
|
? split_channels_super_high_->fbuf()->channels()
|
||||||
|
: NULL;
|
||||||
|
}
|
||||||
|
|
||||||
const int16_t* AudioBuffer::mixed_low_pass_data() {
|
const int16_t* AudioBuffer::mixed_low_pass_data() {
|
||||||
// Currently only mixing stereo to mono is supported.
|
// Currently only mixing stereo to mono is supported.
|
||||||
assert(num_proc_channels_ == 1 || num_proc_channels_ == 2);
|
assert(num_proc_channels_ == 1 || num_proc_channels_ == 2);
|
||||||
@ -513,15 +531,29 @@ void AudioBuffer::CopyLowPassToReference() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AudioBuffer::SplitIntoFrequencyBands() {
|
void AudioBuffer::SplitIntoFrequencyBands() {
|
||||||
splitting_filter_->TwoBandsAnalysis(
|
if (samples_per_channel() == kSamplesPer32kHzChannel) {
|
||||||
channels(), samples_per_channel(), num_proc_channels_,
|
splitting_filter_->TwoBandsAnalysis(
|
||||||
low_pass_split_channels(), high_pass_split_channels());
|
channels(), samples_per_channel(), num_proc_channels_,
|
||||||
|
low_pass_split_channels(), high_pass_split_channels());
|
||||||
|
} else if (samples_per_channel() == kSamplesPer48kHzChannel) {
|
||||||
|
splitting_filter_->ThreeBandsAnalysis(
|
||||||
|
channels_f(), samples_per_channel(), num_proc_channels_,
|
||||||
|
low_pass_split_channels_f(), high_pass_split_channels_f(),
|
||||||
|
super_high_pass_split_channels_f());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioBuffer::MergeFrequencyBands() {
|
void AudioBuffer::MergeFrequencyBands() {
|
||||||
splitting_filter_->TwoBandsSynthesis(
|
if (samples_per_channel() == kSamplesPer32kHzChannel) {
|
||||||
low_pass_split_channels(), high_pass_split_channels(),
|
splitting_filter_->TwoBandsSynthesis(
|
||||||
samples_per_split_channel(), num_proc_channels_, channels());
|
low_pass_split_channels(), high_pass_split_channels(),
|
||||||
|
samples_per_split_channel(), num_proc_channels_, channels());
|
||||||
|
} else if (samples_per_channel() == kSamplesPer48kHzChannel) {
|
||||||
|
splitting_filter_->ThreeBandsSynthesis(
|
||||||
|
low_pass_split_channels_f(), high_pass_split_channels_f(),
|
||||||
|
super_high_pass_split_channels_f(), samples_per_split_channel(),
|
||||||
|
num_proc_channels_, channels_f());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
@ -78,6 +78,8 @@ class AudioBuffer {
|
|||||||
const float* const* low_pass_split_channels_f() const;
|
const float* const* low_pass_split_channels_f() const;
|
||||||
float* const* high_pass_split_channels_f();
|
float* const* high_pass_split_channels_f();
|
||||||
const float* const* high_pass_split_channels_f() const;
|
const float* const* high_pass_split_channels_f() const;
|
||||||
|
float* const* super_high_pass_split_channels_f();
|
||||||
|
const float* const* super_high_pass_split_channels_f() const;
|
||||||
|
|
||||||
const float* keyboard_data() const;
|
const float* keyboard_data() const;
|
||||||
|
|
||||||
@ -122,6 +124,7 @@ class AudioBuffer {
|
|||||||
scoped_ptr<IFChannelBuffer> channels_;
|
scoped_ptr<IFChannelBuffer> channels_;
|
||||||
scoped_ptr<IFChannelBuffer> split_channels_low_;
|
scoped_ptr<IFChannelBuffer> split_channels_low_;
|
||||||
scoped_ptr<IFChannelBuffer> split_channels_high_;
|
scoped_ptr<IFChannelBuffer> split_channels_high_;
|
||||||
|
scoped_ptr<IFChannelBuffer> split_channels_super_high_;
|
||||||
scoped_ptr<SplittingFilter> splitting_filter_;
|
scoped_ptr<SplittingFilter> splitting_filter_;
|
||||||
scoped_ptr<ChannelBuffer<int16_t> > mixed_low_pass_channels_;
|
scoped_ptr<ChannelBuffer<int16_t> > mixed_low_pass_channels_;
|
||||||
scoped_ptr<ChannelBuffer<int16_t> > low_pass_reference_channels_;
|
scoped_ptr<ChannelBuffer<int16_t> > low_pass_reference_channels_;
|
||||||
|
@ -262,7 +262,8 @@ int AudioProcessingImpl::InitializeLocked(int input_sample_rate_hz,
|
|||||||
// demonstrated to work well for AEC in most practical scenarios.
|
// demonstrated to work well for AEC in most practical scenarios.
|
||||||
rev_proc_format_.set(rev_proc_rate, 1);
|
rev_proc_format_.set(rev_proc_rate, 1);
|
||||||
|
|
||||||
if (fwd_proc_format_.rate() == kSampleRate32kHz) {
|
if (fwd_proc_format_.rate() == kSampleRate32kHz ||
|
||||||
|
fwd_proc_format_.rate() == kSampleRate48kHz) {
|
||||||
split_rate_ = kSampleRate16kHz;
|
split_rate_ = kSampleRate16kHz;
|
||||||
} else {
|
} else {
|
||||||
split_rate_ = fwd_proc_format_.rate();
|
split_rate_ = fwd_proc_format_.rate();
|
||||||
@ -404,7 +405,8 @@ int AudioProcessingImpl::ProcessStream(AudioFrame* frame) {
|
|||||||
// Must be a native rate.
|
// Must be a native rate.
|
||||||
if (frame->sample_rate_hz_ != kSampleRate8kHz &&
|
if (frame->sample_rate_hz_ != kSampleRate8kHz &&
|
||||||
frame->sample_rate_hz_ != kSampleRate16kHz &&
|
frame->sample_rate_hz_ != kSampleRate16kHz &&
|
||||||
frame->sample_rate_hz_ != kSampleRate32kHz) {
|
frame->sample_rate_hz_ != kSampleRate32kHz &&
|
||||||
|
frame->sample_rate_hz_ != kSampleRate48kHz) {
|
||||||
return kBadSampleRateError;
|
return kBadSampleRateError;
|
||||||
}
|
}
|
||||||
if (echo_control_mobile_->is_enabled() &&
|
if (echo_control_mobile_->is_enabled() &&
|
||||||
@ -540,7 +542,8 @@ int AudioProcessingImpl::AnalyzeReverseStream(AudioFrame* frame) {
|
|||||||
// Must be a native rate.
|
// Must be a native rate.
|
||||||
if (frame->sample_rate_hz_ != kSampleRate8kHz &&
|
if (frame->sample_rate_hz_ != kSampleRate8kHz &&
|
||||||
frame->sample_rate_hz_ != kSampleRate16kHz &&
|
frame->sample_rate_hz_ != kSampleRate16kHz &&
|
||||||
frame->sample_rate_hz_ != kSampleRate32kHz) {
|
frame->sample_rate_hz_ != kSampleRate32kHz &&
|
||||||
|
frame->sample_rate_hz_ != kSampleRate48kHz) {
|
||||||
return kBadSampleRateError;
|
return kBadSampleRateError;
|
||||||
}
|
}
|
||||||
// This interface does not tolerate different forward and reverse rates.
|
// This interface does not tolerate different forward and reverse rates.
|
||||||
@ -775,14 +778,16 @@ bool AudioProcessingImpl::output_copy_needed(bool is_data_processed) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool AudioProcessingImpl::synthesis_needed(bool is_data_processed) const {
|
bool AudioProcessingImpl::synthesis_needed(bool is_data_processed) const {
|
||||||
return (is_data_processed && fwd_proc_format_.rate() == kSampleRate32kHz);
|
return (is_data_processed && (fwd_proc_format_.rate() == kSampleRate32kHz ||
|
||||||
|
fwd_proc_format_.rate() == kSampleRate48kHz));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AudioProcessingImpl::analysis_needed(bool is_data_processed) const {
|
bool AudioProcessingImpl::analysis_needed(bool is_data_processed) const {
|
||||||
if (!is_data_processed && !voice_detection_->is_enabled()) {
|
if (!is_data_processed && !voice_detection_->is_enabled()) {
|
||||||
// Only level_estimator_ is enabled.
|
// Only level_estimator_ is enabled.
|
||||||
return false;
|
return false;
|
||||||
} else if (fwd_proc_format_.rate() == kSampleRate32kHz) {
|
} else if (fwd_proc_format_.rate() == kSampleRate32kHz ||
|
||||||
|
fwd_proc_format_.rate() == kSampleRate48kHz) {
|
||||||
// Something besides level_estimator_ is enabled, and we have super-wb.
|
// Something besides level_estimator_ is enabled, and we have super-wb.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -380,7 +380,8 @@ class AudioProcessing {
|
|||||||
enum NativeRate {
|
enum NativeRate {
|
||||||
kSampleRate8kHz = 8000,
|
kSampleRate8kHz = 8000,
|
||||||
kSampleRate16kHz = 16000,
|
kSampleRate16kHz = 16000,
|
||||||
kSampleRate32kHz = 32000
|
kSampleRate32kHz = 32000,
|
||||||
|
kSampleRate48kHz = 48000
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int kChunkSizeMs = 10;
|
static const int kChunkSizeMs = 10;
|
||||||
|
@ -46,4 +46,20 @@ void SplittingFilter::TwoBandsSynthesis(const int16_t* const* low_band,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SplittingFilter::ThreeBandsAnalysis(const float* const* in_data,
|
||||||
|
int in_data_length,
|
||||||
|
int channels,
|
||||||
|
float* const* low_band,
|
||||||
|
float* const* high_band,
|
||||||
|
float* const* super_high_band) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void SplittingFilter::ThreeBandsSynthesis(const float* const* low_band,
|
||||||
|
const float* const* high_band,
|
||||||
|
const float* const* super_high_band,
|
||||||
|
int band_length,
|
||||||
|
int channels,
|
||||||
|
float* const* out_data) {
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
@ -47,6 +47,18 @@ class SplittingFilter {
|
|||||||
int band_length,
|
int band_length,
|
||||||
int channels,
|
int channels,
|
||||||
int16_t* const* out_data);
|
int16_t* const* out_data);
|
||||||
|
void ThreeBandsAnalysis(const float* const* in_data,
|
||||||
|
int in_data_length,
|
||||||
|
int channels,
|
||||||
|
float* const* low_band,
|
||||||
|
float* const* high_band,
|
||||||
|
float* const* super_high_band);
|
||||||
|
void ThreeBandsSynthesis(const float* const* low_band,
|
||||||
|
const float* const* high_band,
|
||||||
|
const float* const* super_high_band,
|
||||||
|
int band_length,
|
||||||
|
int channels,
|
||||||
|
float* const* out_data);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int channels_;
|
int channels_;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user