Update to current webrtc library
This is from the upstream library commit id 3326535126e435f1ba647885ce43a8f0f3d317eb, corresponding to Chromium 88.0.4290.1.
This commit is contained in:
@ -8,11 +8,11 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_COMMON_AUDIO_RESAMPLER_INCLUDE_PUSH_RESAMPLER_H_
|
||||
#define WEBRTC_COMMON_AUDIO_RESAMPLER_INCLUDE_PUSH_RESAMPLER_H_
|
||||
#ifndef COMMON_AUDIO_RESAMPLER_INCLUDE_PUSH_RESAMPLER_H_
|
||||
#define COMMON_AUDIO_RESAMPLER_INCLUDE_PUSH_RESAMPLER_H_
|
||||
|
||||
#include "webrtc/base/scoped_ptr.h"
|
||||
#include "webrtc/typedefs.h"
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -28,25 +28,32 @@ class PushResampler {
|
||||
|
||||
// Must be called whenever the parameters change. Free to be called at any
|
||||
// time as it is a no-op if parameters have not changed since the last call.
|
||||
int InitializeIfNeeded(int src_sample_rate_hz, int dst_sample_rate_hz,
|
||||
int num_channels);
|
||||
int InitializeIfNeeded(int src_sample_rate_hz,
|
||||
int dst_sample_rate_hz,
|
||||
size_t num_channels);
|
||||
|
||||
// Returns the total number of samples provided in destination (e.g. 32 kHz,
|
||||
// 2 channel audio gives 640 samples).
|
||||
int Resample(const T* src, size_t src_length, T* dst, size_t dst_capacity);
|
||||
|
||||
private:
|
||||
rtc::scoped_ptr<PushSincResampler> sinc_resampler_;
|
||||
rtc::scoped_ptr<PushSincResampler> sinc_resampler_right_;
|
||||
int src_sample_rate_hz_;
|
||||
int dst_sample_rate_hz_;
|
||||
int num_channels_;
|
||||
rtc::scoped_ptr<T[]> src_left_;
|
||||
rtc::scoped_ptr<T[]> src_right_;
|
||||
rtc::scoped_ptr<T[]> dst_left_;
|
||||
rtc::scoped_ptr<T[]> dst_right_;
|
||||
};
|
||||
size_t num_channels_;
|
||||
// Vector that is needed to provide the proper inputs and outputs to the
|
||||
// interleave/de-interleave methods used in Resample. This needs to be
|
||||
// heap-allocated on the state to support an arbitrary number of channels
|
||||
// without doing run-time heap-allocations in the Resample method.
|
||||
std::vector<T*> channel_data_array_;
|
||||
|
||||
struct ChannelResampler {
|
||||
std::unique_ptr<PushSincResampler> resampler;
|
||||
std::vector<T> source;
|
||||
std::vector<T> destination;
|
||||
};
|
||||
|
||||
std::vector<ChannelResampler> channel_resamplers_;
|
||||
};
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // WEBRTC_COMMON_AUDIO_RESAMPLER_INCLUDE_PUSH_RESAMPLER_H_
|
||||
#endif // COMMON_AUDIO_RESAMPLER_INCLUDE_PUSH_RESAMPLER_H_
|
||||
|
@ -8,88 +8,92 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* A wrapper for resampling a numerous amount of sampling combinations.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_RESAMPLER_RESAMPLER_H_
|
||||
#define WEBRTC_RESAMPLER_RESAMPLER_H_
|
||||
#ifndef COMMON_AUDIO_RESAMPLER_INCLUDE_RESAMPLER_H_
|
||||
#define COMMON_AUDIO_RESAMPLER_INCLUDE_RESAMPLER_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "webrtc/typedefs.h"
|
||||
#include <stdint.h>
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// All methods return 0 on success and -1 on failure.
|
||||
class Resampler
|
||||
{
|
||||
class Resampler {
|
||||
public:
|
||||
Resampler();
|
||||
Resampler(int inFreq, int outFreq, size_t num_channels);
|
||||
~Resampler();
|
||||
|
||||
public:
|
||||
Resampler();
|
||||
Resampler(int inFreq, int outFreq, int num_channels);
|
||||
~Resampler();
|
||||
// Reset all states
|
||||
int Reset(int inFreq, int outFreq, size_t num_channels);
|
||||
|
||||
// Reset all states
|
||||
int Reset(int inFreq, int outFreq, int num_channels);
|
||||
// Reset all states if any parameter has changed
|
||||
int ResetIfNeeded(int inFreq, int outFreq, size_t num_channels);
|
||||
|
||||
// Reset all states if any parameter has changed
|
||||
int ResetIfNeeded(int inFreq, int outFreq, int num_channels);
|
||||
// Resample samplesIn to samplesOut.
|
||||
int Push(const int16_t* samplesIn,
|
||||
size_t lengthIn,
|
||||
int16_t* samplesOut,
|
||||
size_t maxLen,
|
||||
size_t& outLen); // NOLINT: to avoid changing APIs
|
||||
|
||||
// Resample samplesIn to samplesOut.
|
||||
int Push(const int16_t* samplesIn, size_t lengthIn, int16_t* samplesOut,
|
||||
size_t maxLen, size_t &outLen);
|
||||
private:
|
||||
enum ResamplerMode {
|
||||
kResamplerMode1To1,
|
||||
kResamplerMode1To2,
|
||||
kResamplerMode1To3,
|
||||
kResamplerMode1To4,
|
||||
kResamplerMode1To6,
|
||||
kResamplerMode1To12,
|
||||
kResamplerMode2To3,
|
||||
kResamplerMode2To11,
|
||||
kResamplerMode4To11,
|
||||
kResamplerMode8To11,
|
||||
kResamplerMode11To16,
|
||||
kResamplerMode11To32,
|
||||
kResamplerMode2To1,
|
||||
kResamplerMode3To1,
|
||||
kResamplerMode4To1,
|
||||
kResamplerMode6To1,
|
||||
kResamplerMode12To1,
|
||||
kResamplerMode3To2,
|
||||
kResamplerMode11To2,
|
||||
kResamplerMode11To4,
|
||||
kResamplerMode11To8
|
||||
};
|
||||
|
||||
private:
|
||||
enum ResamplerMode
|
||||
{
|
||||
kResamplerMode1To1,
|
||||
kResamplerMode1To2,
|
||||
kResamplerMode1To3,
|
||||
kResamplerMode1To4,
|
||||
kResamplerMode1To6,
|
||||
kResamplerMode1To12,
|
||||
kResamplerMode2To3,
|
||||
kResamplerMode2To11,
|
||||
kResamplerMode4To11,
|
||||
kResamplerMode8To11,
|
||||
kResamplerMode11To16,
|
||||
kResamplerMode11To32,
|
||||
kResamplerMode2To1,
|
||||
kResamplerMode3To1,
|
||||
kResamplerMode4To1,
|
||||
kResamplerMode6To1,
|
||||
kResamplerMode12To1,
|
||||
kResamplerMode3To2,
|
||||
kResamplerMode11To2,
|
||||
kResamplerMode11To4,
|
||||
kResamplerMode11To8
|
||||
};
|
||||
// Computes the resampler mode for a given sampling frequency pair.
|
||||
// Returns -1 for unsupported frequency pairs.
|
||||
static int ComputeResamplerMode(int in_freq_hz,
|
||||
int out_freq_hz,
|
||||
ResamplerMode* mode);
|
||||
|
||||
// Generic pointers since we don't know what states we'll need
|
||||
void* state1_;
|
||||
void* state2_;
|
||||
void* state3_;
|
||||
// Generic pointers since we don't know what states we'll need
|
||||
void* state1_;
|
||||
void* state2_;
|
||||
void* state3_;
|
||||
|
||||
// Storage if needed
|
||||
int16_t* in_buffer_;
|
||||
int16_t* out_buffer_;
|
||||
size_t in_buffer_size_;
|
||||
size_t out_buffer_size_;
|
||||
size_t in_buffer_size_max_;
|
||||
size_t out_buffer_size_max_;
|
||||
// Storage if needed
|
||||
int16_t* in_buffer_;
|
||||
int16_t* out_buffer_;
|
||||
size_t in_buffer_size_;
|
||||
size_t out_buffer_size_;
|
||||
size_t in_buffer_size_max_;
|
||||
size_t out_buffer_size_max_;
|
||||
|
||||
int my_in_frequency_khz_;
|
||||
int my_out_frequency_khz_;
|
||||
ResamplerMode my_mode_;
|
||||
int num_channels_;
|
||||
int my_in_frequency_khz_;
|
||||
int my_out_frequency_khz_;
|
||||
ResamplerMode my_mode_;
|
||||
size_t num_channels_;
|
||||
|
||||
// Extra instance for stereo
|
||||
Resampler* slave_left_;
|
||||
Resampler* slave_right_;
|
||||
// Extra instance for stereo
|
||||
Resampler* helper_left_;
|
||||
Resampler* helper_right_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // WEBRTC_RESAMPLER_RESAMPLER_H_
|
||||
#endif // COMMON_AUDIO_RESAMPLER_INCLUDE_RESAMPLER_H_
|
||||
|
@ -8,40 +8,78 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "webrtc/common_audio/resampler/include/push_resampler.h"
|
||||
#include "common_audio/resampler/include/push_resampler.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "webrtc/common_audio/include/audio_util.h"
|
||||
#include "webrtc/common_audio/resampler/include/resampler.h"
|
||||
#include "webrtc/common_audio/resampler/push_sinc_resampler.h"
|
||||
#include <memory>
|
||||
|
||||
#include "common_audio/include/audio_util.h"
|
||||
#include "common_audio/resampler/push_sinc_resampler.h"
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace {
|
||||
// These checks were factored out into a non-templatized function
|
||||
// due to problems with clang on Windows in debug builds.
|
||||
// For some reason having the DCHECKs inline in the template code
|
||||
// caused the compiler to generate code that threw off the linker.
|
||||
// TODO(tommi): Re-enable when we've figured out what the problem is.
|
||||
// http://crbug.com/615050
|
||||
void CheckValidInitParams(int src_sample_rate_hz,
|
||||
int dst_sample_rate_hz,
|
||||
size_t num_channels) {
|
||||
// The below checks are temporarily disabled on WEBRTC_WIN due to problems
|
||||
// with clang debug builds.
|
||||
#if !defined(WEBRTC_WIN) && defined(__clang__)
|
||||
RTC_DCHECK_GT(src_sample_rate_hz, 0);
|
||||
RTC_DCHECK_GT(dst_sample_rate_hz, 0);
|
||||
RTC_DCHECK_GT(num_channels, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CheckExpectedBufferSizes(size_t src_length,
|
||||
size_t dst_capacity,
|
||||
size_t num_channels,
|
||||
int src_sample_rate,
|
||||
int dst_sample_rate) {
|
||||
// The below checks are temporarily disabled on WEBRTC_WIN due to problems
|
||||
// with clang debug builds.
|
||||
// TODO(tommi): Re-enable when we've figured out what the problem is.
|
||||
// http://crbug.com/615050
|
||||
#if !defined(WEBRTC_WIN) && defined(__clang__)
|
||||
const size_t src_size_10ms = src_sample_rate * num_channels / 100;
|
||||
const size_t dst_size_10ms = dst_sample_rate * num_channels / 100;
|
||||
RTC_DCHECK_EQ(src_length, src_size_10ms);
|
||||
RTC_DCHECK_GE(dst_capacity, dst_size_10ms);
|
||||
#endif
|
||||
}
|
||||
} // namespace
|
||||
|
||||
template <typename T>
|
||||
PushResampler<T>::PushResampler()
|
||||
: src_sample_rate_hz_(0),
|
||||
dst_sample_rate_hz_(0),
|
||||
num_channels_(0) {
|
||||
}
|
||||
: src_sample_rate_hz_(0), dst_sample_rate_hz_(0), num_channels_(0) {}
|
||||
|
||||
template <typename T>
|
||||
PushResampler<T>::~PushResampler() {
|
||||
}
|
||||
PushResampler<T>::~PushResampler() {}
|
||||
|
||||
template <typename T>
|
||||
int PushResampler<T>::InitializeIfNeeded(int src_sample_rate_hz,
|
||||
int dst_sample_rate_hz,
|
||||
int num_channels) {
|
||||
size_t num_channels) {
|
||||
CheckValidInitParams(src_sample_rate_hz, dst_sample_rate_hz, num_channels);
|
||||
|
||||
if (src_sample_rate_hz == src_sample_rate_hz_ &&
|
||||
dst_sample_rate_hz == dst_sample_rate_hz_ &&
|
||||
num_channels == num_channels_)
|
||||
num_channels == num_channels_) {
|
||||
// No-op if settings haven't changed.
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (src_sample_rate_hz <= 0 || dst_sample_rate_hz <= 0 ||
|
||||
num_channels <= 0 || num_channels > 2)
|
||||
if (src_sample_rate_hz <= 0 || dst_sample_rate_hz <= 0 || num_channels <= 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
src_sample_rate_hz_ = src_sample_rate_hz;
|
||||
dst_sample_rate_hz_ = dst_sample_rate_hz;
|
||||
@ -51,29 +89,28 @@ int PushResampler<T>::InitializeIfNeeded(int src_sample_rate_hz,
|
||||
static_cast<size_t>(src_sample_rate_hz / 100);
|
||||
const size_t dst_size_10ms_mono =
|
||||
static_cast<size_t>(dst_sample_rate_hz / 100);
|
||||
sinc_resampler_.reset(new PushSincResampler(src_size_10ms_mono,
|
||||
dst_size_10ms_mono));
|
||||
if (num_channels_ == 2) {
|
||||
src_left_.reset(new T[src_size_10ms_mono]);
|
||||
src_right_.reset(new T[src_size_10ms_mono]);
|
||||
dst_left_.reset(new T[dst_size_10ms_mono]);
|
||||
dst_right_.reset(new T[dst_size_10ms_mono]);
|
||||
sinc_resampler_right_.reset(new PushSincResampler(src_size_10ms_mono,
|
||||
dst_size_10ms_mono));
|
||||
channel_resamplers_.clear();
|
||||
for (size_t i = 0; i < num_channels; ++i) {
|
||||
channel_resamplers_.push_back(ChannelResampler());
|
||||
auto channel_resampler = channel_resamplers_.rbegin();
|
||||
channel_resampler->resampler = std::make_unique<PushSincResampler>(
|
||||
src_size_10ms_mono, dst_size_10ms_mono);
|
||||
channel_resampler->source.resize(src_size_10ms_mono);
|
||||
channel_resampler->destination.resize(dst_size_10ms_mono);
|
||||
}
|
||||
|
||||
channel_data_array_.resize(num_channels_);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
int PushResampler<T>::Resample(const T* src, size_t src_length, T* dst,
|
||||
int PushResampler<T>::Resample(const T* src,
|
||||
size_t src_length,
|
||||
T* dst,
|
||||
size_t dst_capacity) {
|
||||
const size_t src_size_10ms =
|
||||
static_cast<size_t>(src_sample_rate_hz_ * num_channels_ / 100);
|
||||
const size_t dst_size_10ms =
|
||||
static_cast<size_t>(dst_sample_rate_hz_ * num_channels_ / 100);
|
||||
if (src_length != src_size_10ms || dst_capacity < dst_size_10ms)
|
||||
return -1;
|
||||
CheckExpectedBufferSizes(src_length, dst_capacity, num_channels_,
|
||||
src_sample_rate_hz_, dst_sample_rate_hz_);
|
||||
|
||||
if (src_sample_rate_hz_ == dst_sample_rate_hz_) {
|
||||
// The old resampler provides this memcpy facility in the case of matching
|
||||
@ -81,26 +118,30 @@ int PushResampler<T>::Resample(const T* src, size_t src_length, T* dst,
|
||||
memcpy(dst, src, src_length * sizeof(T));
|
||||
return static_cast<int>(src_length);
|
||||
}
|
||||
if (num_channels_ == 2) {
|
||||
const size_t src_length_mono = src_length / num_channels_;
|
||||
const size_t dst_capacity_mono = dst_capacity / num_channels_;
|
||||
T* deinterleaved[] = {src_left_.get(), src_right_.get()};
|
||||
Deinterleave(src, src_length_mono, num_channels_, deinterleaved);
|
||||
|
||||
size_t dst_length_mono =
|
||||
sinc_resampler_->Resample(src_left_.get(), src_length_mono,
|
||||
dst_left_.get(), dst_capacity_mono);
|
||||
sinc_resampler_right_->Resample(src_right_.get(), src_length_mono,
|
||||
dst_right_.get(), dst_capacity_mono);
|
||||
const size_t src_length_mono = src_length / num_channels_;
|
||||
const size_t dst_capacity_mono = dst_capacity / num_channels_;
|
||||
|
||||
deinterleaved[0] = dst_left_.get();
|
||||
deinterleaved[1] = dst_right_.get();
|
||||
Interleave(deinterleaved, dst_length_mono, num_channels_, dst);
|
||||
return static_cast<int>(dst_length_mono * num_channels_);
|
||||
} else {
|
||||
return static_cast<int>(
|
||||
sinc_resampler_->Resample(src, src_length, dst, dst_capacity));
|
||||
for (size_t ch = 0; ch < num_channels_; ++ch) {
|
||||
channel_data_array_[ch] = channel_resamplers_[ch].source.data();
|
||||
}
|
||||
|
||||
Deinterleave(src, src_length_mono, num_channels_, channel_data_array_.data());
|
||||
|
||||
size_t dst_length_mono = 0;
|
||||
|
||||
for (auto& resampler : channel_resamplers_) {
|
||||
dst_length_mono = resampler.resampler->Resample(
|
||||
resampler.source.data(), src_length_mono, resampler.destination.data(),
|
||||
dst_capacity_mono);
|
||||
}
|
||||
|
||||
for (size_t ch = 0; ch < num_channels_; ++ch) {
|
||||
channel_data_array_[ch] = channel_resamplers_[ch].destination.data();
|
||||
}
|
||||
|
||||
Interleave(channel_data_array_.data(), dst_length_mono, num_channels_, dst);
|
||||
return static_cast<int>(dst_length_mono * num_channels_);
|
||||
}
|
||||
|
||||
// Explictly generate required instantiations.
|
||||
|
@ -8,12 +8,12 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "webrtc/common_audio/resampler/push_sinc_resampler.h"
|
||||
#include "common_audio/resampler/push_sinc_resampler.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "webrtc/base/checks.h"
|
||||
#include "webrtc/common_audio/include/audio_util.h"
|
||||
#include "common_audio/include/audio_util.h"
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -28,8 +28,7 @@ PushSincResampler::PushSincResampler(size_t source_frames,
|
||||
first_pass_(true),
|
||||
source_available_(0) {}
|
||||
|
||||
PushSincResampler::~PushSincResampler() {
|
||||
}
|
||||
PushSincResampler::~PushSincResampler() {}
|
||||
|
||||
size_t PushSincResampler::Resample(const int16_t* source,
|
||||
size_t source_length,
|
||||
|
@ -8,13 +8,16 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_COMMON_AUDIO_RESAMPLER_PUSH_SINC_RESAMPLER_H_
|
||||
#define WEBRTC_COMMON_AUDIO_RESAMPLER_PUSH_SINC_RESAMPLER_H_
|
||||
#ifndef COMMON_AUDIO_RESAMPLER_PUSH_SINC_RESAMPLER_H_
|
||||
#define COMMON_AUDIO_RESAMPLER_PUSH_SINC_RESAMPLER_H_
|
||||
|
||||
#include "webrtc/base/constructormagic.h"
|
||||
#include "webrtc/base/scoped_ptr.h"
|
||||
#include "webrtc/common_audio/resampler/sinc_resampler.h"
|
||||
#include "webrtc/typedefs.h"
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "common_audio/resampler/sinc_resampler.h"
|
||||
#include "rtc_base/constructor_magic.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -35,8 +38,10 @@ class PushSincResampler : public SincResamplerCallback {
|
||||
// at least as large as |destination_frames|. Returns the number of samples
|
||||
// provided in destination (for convenience, since this will always be equal
|
||||
// to |destination_frames|).
|
||||
size_t Resample(const int16_t* source, size_t source_frames,
|
||||
int16_t* destination, size_t destination_capacity);
|
||||
size_t Resample(const int16_t* source,
|
||||
size_t source_frames,
|
||||
int16_t* destination,
|
||||
size_t destination_capacity);
|
||||
size_t Resample(const float* source,
|
||||
size_t source_frames,
|
||||
float* destination,
|
||||
@ -56,8 +61,8 @@ class PushSincResampler : public SincResamplerCallback {
|
||||
friend class PushSincResamplerTest;
|
||||
SincResampler* get_resampler_for_testing() { return resampler_.get(); }
|
||||
|
||||
rtc::scoped_ptr<SincResampler> resampler_;
|
||||
rtc::scoped_ptr<float[]> float_buffer_;
|
||||
std::unique_ptr<SincResampler> resampler_;
|
||||
std::unique_ptr<float[]> float_buffer_;
|
||||
const float* source_ptr_;
|
||||
const int16_t* source_ptr_int_;
|
||||
const size_t destination_frames_;
|
||||
@ -73,4 +78,4 @@ class PushSincResampler : public SincResamplerCallback {
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // WEBRTC_COMMON_AUDIO_RESAMPLER_PUSH_SINC_RESAMPLER_H_
|
||||
#endif // COMMON_AUDIO_RESAMPLER_PUSH_SINC_RESAMPLER_H_
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -85,16 +85,17 @@
|
||||
// MSVC++ requires this to be set before any other includes to get M_PI.
|
||||
#define _USE_MATH_DEFINES
|
||||
|
||||
#include "webrtc/common_audio/resampler/sinc_resampler.h"
|
||||
#include "common_audio/resampler/sinc_resampler.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include "webrtc/system_wrappers/include/cpu_features_wrapper.h"
|
||||
#include "webrtc/typedefs.h"
|
||||
#include "rtc_base/checks.h"
|
||||
#include "rtc_base/system/arch.h"
|
||||
#include "system_wrappers/include/cpu_features_wrapper.h" // kSSE2, WebRtc_G...
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -118,35 +119,25 @@ double SincScaleFactor(double io_ratio) {
|
||||
|
||||
} // namespace
|
||||
|
||||
// If we know the minimum architecture at compile time, avoid CPU detection.
|
||||
#if defined(WEBRTC_ARCH_X86_FAMILY)
|
||||
#if defined(__SSE2__)
|
||||
#define CONVOLVE_FUNC Convolve_SSE
|
||||
void SincResampler::InitializeCPUSpecificFeatures() {}
|
||||
#else
|
||||
// x86 CPU detection required. Function will be set by
|
||||
// InitializeCPUSpecificFeatures().
|
||||
// TODO(dalecurtis): Once Chrome moves to an SSE baseline this can be removed.
|
||||
#define CONVOLVE_FUNC convolve_proc_
|
||||
const size_t SincResampler::kKernelSize;
|
||||
|
||||
// If we know the minimum architecture at compile time, avoid CPU detection.
|
||||
void SincResampler::InitializeCPUSpecificFeatures() {
|
||||
convolve_proc_ = WebRtc_GetCPUInfo(kSSE2) ? Convolve_SSE : Convolve_C;
|
||||
}
|
||||
#endif
|
||||
#elif defined(WEBRTC_HAS_NEON)
|
||||
#define CONVOLVE_FUNC Convolve_NEON
|
||||
void SincResampler::InitializeCPUSpecificFeatures() {}
|
||||
#elif defined(WEBRTC_DETECT_NEON)
|
||||
#define CONVOLVE_FUNC convolve_proc_
|
||||
void SincResampler::InitializeCPUSpecificFeatures() {
|
||||
convolve_proc_ = WebRtc_GetCPUFeaturesARM() & kCPUFeatureNEON ?
|
||||
Convolve_NEON : Convolve_C;
|
||||
}
|
||||
#if defined(WEBRTC_HAS_NEON)
|
||||
convolve_proc_ = Convolve_NEON;
|
||||
#elif defined(WEBRTC_ARCH_X86_FAMILY)
|
||||
// Using AVX2 instead of SSE2 when AVX2 supported.
|
||||
if (GetCPUInfo(kAVX2))
|
||||
convolve_proc_ = Convolve_AVX2;
|
||||
else if (GetCPUInfo(kSSE2))
|
||||
convolve_proc_ = Convolve_SSE;
|
||||
else
|
||||
convolve_proc_ = Convolve_C;
|
||||
#else
|
||||
// Unknown architecture.
|
||||
#define CONVOLVE_FUNC Convolve_C
|
||||
void SincResampler::InitializeCPUSpecificFeatures() {}
|
||||
// Unknown architecture.
|
||||
convolve_proc_ = Convolve_C;
|
||||
#endif
|
||||
}
|
||||
|
||||
SincResampler::SincResampler(double io_sample_rate_ratio,
|
||||
size_t request_frames,
|
||||
@ -155,27 +146,23 @@ SincResampler::SincResampler(double io_sample_rate_ratio,
|
||||
read_cb_(read_cb),
|
||||
request_frames_(request_frames),
|
||||
input_buffer_size_(request_frames_ + kKernelSize),
|
||||
// Create input buffers with a 16-byte alignment for SSE optimizations.
|
||||
// Create input buffers with a 32-byte alignment for SIMD optimizations.
|
||||
kernel_storage_(static_cast<float*>(
|
||||
AlignedMalloc(sizeof(float) * kKernelStorageSize, 16))),
|
||||
AlignedMalloc(sizeof(float) * kKernelStorageSize, 32))),
|
||||
kernel_pre_sinc_storage_(static_cast<float*>(
|
||||
AlignedMalloc(sizeof(float) * kKernelStorageSize, 16))),
|
||||
AlignedMalloc(sizeof(float) * kKernelStorageSize, 32))),
|
||||
kernel_window_storage_(static_cast<float*>(
|
||||
AlignedMalloc(sizeof(float) * kKernelStorageSize, 16))),
|
||||
AlignedMalloc(sizeof(float) * kKernelStorageSize, 32))),
|
||||
input_buffer_(static_cast<float*>(
|
||||
AlignedMalloc(sizeof(float) * input_buffer_size_, 16))),
|
||||
#if defined(WEBRTC_CPU_DETECTION)
|
||||
convolve_proc_(NULL),
|
||||
#endif
|
||||
AlignedMalloc(sizeof(float) * input_buffer_size_, 32))),
|
||||
convolve_proc_(nullptr),
|
||||
r1_(input_buffer_.get()),
|
||||
r2_(input_buffer_.get() + kKernelSize / 2) {
|
||||
#if defined(WEBRTC_CPU_DETECTION)
|
||||
InitializeCPUSpecificFeatures();
|
||||
assert(convolve_proc_);
|
||||
#endif
|
||||
assert(request_frames_ > 0);
|
||||
RTC_DCHECK(convolve_proc_);
|
||||
RTC_DCHECK_GT(request_frames_, 0);
|
||||
Flush();
|
||||
assert(block_size_ > kKernelSize);
|
||||
RTC_DCHECK_GT(block_size_, kKernelSize);
|
||||
|
||||
memset(kernel_storage_.get(), 0,
|
||||
sizeof(*kernel_storage_.get()) * kKernelStorageSize);
|
||||
@ -198,11 +185,11 @@ void SincResampler::UpdateRegions(bool second_load) {
|
||||
block_size_ = r4_ - r2_;
|
||||
|
||||
// r1_ at the beginning of the buffer.
|
||||
assert(r1_ == input_buffer_.get());
|
||||
RTC_DCHECK_EQ(r1_, input_buffer_.get());
|
||||
// r1_ left of r2_, r4_ left of r3_ and size correct.
|
||||
assert(r2_ - r1_ == r4_ - r3_);
|
||||
RTC_DCHECK_EQ(r2_ - r1_, r4_ - r3_);
|
||||
// r2_ left of r3.
|
||||
assert(r2_ < r3_);
|
||||
RTC_DCHECK_LT(r2_, r3_);
|
||||
}
|
||||
|
||||
void SincResampler::InitializeKernel() {
|
||||
@ -221,23 +208,23 @@ void SincResampler::InitializeKernel() {
|
||||
|
||||
for (size_t i = 0; i < kKernelSize; ++i) {
|
||||
const size_t idx = i + offset_idx * kKernelSize;
|
||||
const float pre_sinc = static_cast<float>(M_PI *
|
||||
(static_cast<int>(i) - static_cast<int>(kKernelSize / 2) -
|
||||
subsample_offset));
|
||||
const float pre_sinc = static_cast<float>(
|
||||
M_PI * (static_cast<int>(i) - static_cast<int>(kKernelSize / 2) -
|
||||
subsample_offset));
|
||||
kernel_pre_sinc_storage_[idx] = pre_sinc;
|
||||
|
||||
// Compute Blackman window, matching the offset of the sinc().
|
||||
const float x = (i - subsample_offset) / kKernelSize;
|
||||
const float window = static_cast<float>(kA0 - kA1 * cos(2.0 * M_PI * x) +
|
||||
kA2 * cos(4.0 * M_PI * x));
|
||||
kA2 * cos(4.0 * M_PI * x));
|
||||
kernel_window_storage_[idx] = window;
|
||||
|
||||
// Compute the sinc with offset, then window the sinc() function and store
|
||||
// at the correct offset.
|
||||
kernel_storage_[idx] = static_cast<float>(window *
|
||||
((pre_sinc == 0) ?
|
||||
sinc_scale_factor :
|
||||
(sin(sinc_scale_factor * pre_sinc) / pre_sinc)));
|
||||
kernel_storage_[idx] = static_cast<float>(
|
||||
window * ((pre_sinc == 0)
|
||||
? sinc_scale_factor
|
||||
: (sin(sinc_scale_factor * pre_sinc) / pre_sinc)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -259,10 +246,10 @@ void SincResampler::SetRatio(double io_sample_rate_ratio) {
|
||||
const float window = kernel_window_storage_[idx];
|
||||
const float pre_sinc = kernel_pre_sinc_storage_[idx];
|
||||
|
||||
kernel_storage_[idx] = static_cast<float>(window *
|
||||
((pre_sinc == 0) ?
|
||||
sinc_scale_factor :
|
||||
(sin(sinc_scale_factor * pre_sinc) / pre_sinc)));
|
||||
kernel_storage_[idx] = static_cast<float>(
|
||||
window * ((pre_sinc == 0)
|
||||
? sinc_scale_factor
|
||||
: (sin(sinc_scale_factor * pre_sinc) / pre_sinc)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -289,7 +276,7 @@ void SincResampler::Resample(size_t frames, float* destination) {
|
||||
for (int i = static_cast<int>(
|
||||
ceil((block_size_ - virtual_source_idx_) / current_io_ratio));
|
||||
i > 0; --i) {
|
||||
assert(virtual_source_idx_ < block_size_);
|
||||
RTC_DCHECK_LT(virtual_source_idx_, block_size_);
|
||||
|
||||
// |virtual_source_idx_| lies in between two kernel offsets so figure out
|
||||
// what they are.
|
||||
@ -305,10 +292,10 @@ void SincResampler::Resample(size_t frames, float* destination) {
|
||||
const float* const k1 = kernel_ptr + offset_idx * kKernelSize;
|
||||
const float* const k2 = k1 + kKernelSize;
|
||||
|
||||
// Ensure |k1|, |k2| are 16-byte aligned for SIMD usage. Should always be
|
||||
// true so long as kKernelSize is a multiple of 16.
|
||||
assert(0u == (reinterpret_cast<uintptr_t>(k1) & 0x0F));
|
||||
assert(0u == (reinterpret_cast<uintptr_t>(k2) & 0x0F));
|
||||
// Ensure |k1|, |k2| are 32-byte aligned for SIMD usage. Should always be
|
||||
// true so long as kKernelSize is a multiple of 32.
|
||||
RTC_DCHECK_EQ(0, reinterpret_cast<uintptr_t>(k1) % 32);
|
||||
RTC_DCHECK_EQ(0, reinterpret_cast<uintptr_t>(k2) % 32);
|
||||
|
||||
// Initialize input pointer based on quantized |virtual_source_idx_|.
|
||||
const float* const input_ptr = r1_ + source_idx;
|
||||
@ -316,8 +303,8 @@ void SincResampler::Resample(size_t frames, float* destination) {
|
||||
// Figure out how much to weight each kernel's "convolution".
|
||||
const double kernel_interpolation_factor =
|
||||
virtual_offset_idx - offset_idx;
|
||||
*destination++ = CONVOLVE_FUNC(
|
||||
input_ptr, k1, k2, kernel_interpolation_factor);
|
||||
*destination++ =
|
||||
convolve_proc_(input_ptr, k1, k2, kernel_interpolation_factor);
|
||||
|
||||
// Advance the virtual index.
|
||||
virtual_source_idx_ += current_io_ratio;
|
||||
@ -356,7 +343,8 @@ void SincResampler::Flush() {
|
||||
UpdateRegions(false);
|
||||
}
|
||||
|
||||
float SincResampler::Convolve_C(const float* input_ptr, const float* k1,
|
||||
float SincResampler::Convolve_C(const float* input_ptr,
|
||||
const float* k1,
|
||||
const float* k2,
|
||||
double kernel_interpolation_factor) {
|
||||
float sum1 = 0;
|
||||
@ -372,7 +360,7 @@ float SincResampler::Convolve_C(const float* input_ptr, const float* k1,
|
||||
|
||||
// Linearly interpolate the two "convolutions".
|
||||
return static_cast<float>((1.0 - kernel_interpolation_factor) * sum1 +
|
||||
kernel_interpolation_factor * sum2);
|
||||
kernel_interpolation_factor * sum2);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
@ -11,16 +11,17 @@
|
||||
// Modified from the Chromium original here:
|
||||
// src/media/base/sinc_resampler.h
|
||||
|
||||
#ifndef WEBRTC_COMMON_AUDIO_RESAMPLER_SINC_RESAMPLER_H_
|
||||
#define WEBRTC_COMMON_AUDIO_RESAMPLER_SINC_RESAMPLER_H_
|
||||
#ifndef COMMON_AUDIO_RESAMPLER_SINC_RESAMPLER_H_
|
||||
#define COMMON_AUDIO_RESAMPLER_SINC_RESAMPLER_H_
|
||||
|
||||
#include "webrtc/base/constructormagic.h"
|
||||
#include "webrtc/base/scoped_ptr.h"
|
||||
#include "webrtc/system_wrappers/include/aligned_malloc.h"
|
||||
#ifndef WEBRTC_AUDIO_PROCESSING_ONLY_BUILD
|
||||
#include "webrtc/test/testsupport/gtest_prod_util.h"
|
||||
#endif
|
||||
#include "webrtc/typedefs.h"
|
||||
#include <stddef.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "rtc_base/constructor_magic.h"
|
||||
#include "rtc_base/gtest_prod_util.h"
|
||||
#include "rtc_base/memory/aligned_malloc.h"
|
||||
#include "rtc_base/system/arch.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -87,10 +88,8 @@ class SincResampler {
|
||||
float* get_kernel_for_testing() { return kernel_storage_.get(); }
|
||||
|
||||
private:
|
||||
#ifndef WEBRTC_AUDIO_PROCESSING_ONLY_BUILD
|
||||
FRIEND_TEST_ALL_PREFIXES(SincResamplerTest, Convolve);
|
||||
FRIEND_TEST_ALL_PREFIXES(SincResamplerTest, ConvolveBenchmark);
|
||||
#endif
|
||||
|
||||
void InitializeKernel();
|
||||
void UpdateRegions(bool second_load);
|
||||
@ -104,14 +103,22 @@ class SincResampler {
|
||||
// Compute convolution of |k1| and |k2| over |input_ptr|, resultant sums are
|
||||
// linearly interpolated using |kernel_interpolation_factor|. On x86 and ARM
|
||||
// the underlying implementation is chosen at run time.
|
||||
static float Convolve_C(const float* input_ptr, const float* k1,
|
||||
const float* k2, double kernel_interpolation_factor);
|
||||
static float Convolve_C(const float* input_ptr,
|
||||
const float* k1,
|
||||
const float* k2,
|
||||
double kernel_interpolation_factor);
|
||||
#if defined(WEBRTC_ARCH_X86_FAMILY)
|
||||
static float Convolve_SSE(const float* input_ptr, const float* k1,
|
||||
static float Convolve_SSE(const float* input_ptr,
|
||||
const float* k1,
|
||||
const float* k2,
|
||||
double kernel_interpolation_factor);
|
||||
#elif defined(WEBRTC_DETECT_NEON) || defined(WEBRTC_HAS_NEON)
|
||||
static float Convolve_NEON(const float* input_ptr, const float* k1,
|
||||
static float Convolve_AVX2(const float* input_ptr,
|
||||
const float* k1,
|
||||
const float* k2,
|
||||
double kernel_interpolation_factor);
|
||||
#elif defined(WEBRTC_HAS_NEON)
|
||||
static float Convolve_NEON(const float* input_ptr,
|
||||
const float* k1,
|
||||
const float* k2,
|
||||
double kernel_interpolation_factor);
|
||||
#endif
|
||||
@ -141,22 +148,22 @@ class SincResampler {
|
||||
// Contains kKernelOffsetCount kernels back-to-back, each of size kKernelSize.
|
||||
// The kernel offsets are sub-sample shifts of a windowed sinc shifted from
|
||||
// 0.0 to 1.0 sample.
|
||||
rtc::scoped_ptr<float[], AlignedFreeDeleter> kernel_storage_;
|
||||
rtc::scoped_ptr<float[], AlignedFreeDeleter> kernel_pre_sinc_storage_;
|
||||
rtc::scoped_ptr<float[], AlignedFreeDeleter> kernel_window_storage_;
|
||||
std::unique_ptr<float[], AlignedFreeDeleter> kernel_storage_;
|
||||
std::unique_ptr<float[], AlignedFreeDeleter> kernel_pre_sinc_storage_;
|
||||
std::unique_ptr<float[], AlignedFreeDeleter> kernel_window_storage_;
|
||||
|
||||
// Data from the source is copied into this buffer for each processing pass.
|
||||
rtc::scoped_ptr<float[], AlignedFreeDeleter> input_buffer_;
|
||||
std::unique_ptr<float[], AlignedFreeDeleter> input_buffer_;
|
||||
|
||||
// Stores the runtime selection of which Convolve function to use.
|
||||
// TODO(ajm): Move to using a global static which must only be initialized
|
||||
// once by the user. We're not doing this initially, because we don't have
|
||||
// e.g. a LazyInstance helper in webrtc.
|
||||
#if defined(WEBRTC_CPU_DETECTION)
|
||||
typedef float (*ConvolveProc)(const float*, const float*, const float*,
|
||||
// Stores the runtime selection of which Convolve function to use.
|
||||
// TODO(ajm): Move to using a global static which must only be initialized
|
||||
// once by the user. We're not doing this initially, because we don't have
|
||||
// e.g. a LazyInstance helper in webrtc.
|
||||
typedef float (*ConvolveProc)(const float*,
|
||||
const float*,
|
||||
const float*,
|
||||
double);
|
||||
ConvolveProc convolve_proc_;
|
||||
#endif
|
||||
|
||||
// Pointers to the various regions inside |input_buffer_|. See the diagram at
|
||||
// the top of the .cc file for more information.
|
||||
@ -171,4 +178,4 @@ class SincResampler {
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // WEBRTC_COMMON_AUDIO_RESAMPLER_SINC_RESAMPLER_H_
|
||||
#endif // COMMON_AUDIO_RESAMPLER_SINC_RESAMPLER_H_
|
||||
|
66
webrtc/common_audio/resampler/sinc_resampler_avx2.cc
Normal file
66
webrtc/common_audio/resampler/sinc_resampler_avx2.cc
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2020 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.
|
||||
*/
|
||||
|
||||
#include <immintrin.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <xmmintrin.h>
|
||||
|
||||
#include "common_audio/resampler/sinc_resampler.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
float SincResampler::Convolve_AVX2(const float* input_ptr,
|
||||
const float* k1,
|
||||
const float* k2,
|
||||
double kernel_interpolation_factor) {
|
||||
__m256 m_input;
|
||||
__m256 m_sums1 = _mm256_setzero_ps();
|
||||
__m256 m_sums2 = _mm256_setzero_ps();
|
||||
|
||||
// Based on |input_ptr| alignment, we need to use loadu or load. Unrolling
|
||||
// these loops has not been tested or benchmarked.
|
||||
bool aligned_input = (reinterpret_cast<uintptr_t>(input_ptr) & 0x1F) == 0;
|
||||
if (!aligned_input) {
|
||||
for (size_t i = 0; i < kKernelSize; i += 8) {
|
||||
m_input = _mm256_loadu_ps(input_ptr + i);
|
||||
m_sums1 = _mm256_fmadd_ps(m_input, _mm256_load_ps(k1 + i), m_sums1);
|
||||
m_sums2 = _mm256_fmadd_ps(m_input, _mm256_load_ps(k2 + i), m_sums2);
|
||||
}
|
||||
} else {
|
||||
for (size_t i = 0; i < kKernelSize; i += 8) {
|
||||
m_input = _mm256_load_ps(input_ptr + i);
|
||||
m_sums1 = _mm256_fmadd_ps(m_input, _mm256_load_ps(k1 + i), m_sums1);
|
||||
m_sums2 = _mm256_fmadd_ps(m_input, _mm256_load_ps(k2 + i), m_sums2);
|
||||
}
|
||||
}
|
||||
|
||||
// Linearly interpolate the two "convolutions".
|
||||
__m128 m128_sums1 = _mm_add_ps(_mm256_extractf128_ps(m_sums1, 0),
|
||||
_mm256_extractf128_ps(m_sums1, 1));
|
||||
__m128 m128_sums2 = _mm_add_ps(_mm256_extractf128_ps(m_sums2, 0),
|
||||
_mm256_extractf128_ps(m_sums2, 1));
|
||||
m128_sums1 = _mm_mul_ps(
|
||||
m128_sums1,
|
||||
_mm_set_ps1(static_cast<float>(1.0 - kernel_interpolation_factor)));
|
||||
m128_sums2 = _mm_mul_ps(
|
||||
m128_sums2, _mm_set_ps1(static_cast<float>(kernel_interpolation_factor)));
|
||||
m128_sums1 = _mm_add_ps(m128_sums1, m128_sums2);
|
||||
|
||||
// Sum components together.
|
||||
float result;
|
||||
m128_sums2 = _mm_add_ps(_mm_movehl_ps(m128_sums1, m128_sums1), m128_sums1);
|
||||
_mm_store_ss(&result, _mm_add_ss(m128_sums2,
|
||||
_mm_shuffle_ps(m128_sums2, m128_sums2, 1)));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
@ -11,13 +11,14 @@
|
||||
// Modified from the Chromium original:
|
||||
// src/media/base/sinc_resampler.cc
|
||||
|
||||
#include "webrtc/common_audio/resampler/sinc_resampler.h"
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
#include "common_audio/resampler/sinc_resampler.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
float SincResampler::Convolve_NEON(const float* input_ptr, const float* k1,
|
||||
float SincResampler::Convolve_NEON(const float* input_ptr,
|
||||
const float* k1,
|
||||
const float* k2,
|
||||
double kernel_interpolation_factor) {
|
||||
float32x4_t m_input;
|
||||
@ -25,7 +26,7 @@ float SincResampler::Convolve_NEON(const float* input_ptr, const float* k1,
|
||||
float32x4_t m_sums2 = vmovq_n_f32(0);
|
||||
|
||||
const float* upper = input_ptr + kKernelSize;
|
||||
for (; input_ptr < upper; ) {
|
||||
for (; input_ptr < upper;) {
|
||||
m_input = vld1q_f32(input_ptr);
|
||||
input_ptr += 4;
|
||||
m_sums1 = vmlaq_f32(m_sums1, m_input, vld1q_f32(k1));
|
||||
|
@ -11,13 +11,16 @@
|
||||
// Modified from the Chromium original:
|
||||
// src/media/base/simd/sinc_resampler_sse.cc
|
||||
|
||||
#include "webrtc/common_audio/resampler/sinc_resampler.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <xmmintrin.h>
|
||||
|
||||
#include "common_audio/resampler/sinc_resampler.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
float SincResampler::Convolve_SSE(const float* input_ptr, const float* k1,
|
||||
float SincResampler::Convolve_SSE(const float* input_ptr,
|
||||
const float* k1,
|
||||
const float* k2,
|
||||
double kernel_interpolation_factor) {
|
||||
__m128 m_input;
|
||||
@ -41,17 +44,18 @@ float SincResampler::Convolve_SSE(const float* input_ptr, const float* k1,
|
||||
}
|
||||
|
||||
// Linearly interpolate the two "convolutions".
|
||||
m_sums1 = _mm_mul_ps(m_sums1, _mm_set_ps1(
|
||||
static_cast<float>(1.0 - kernel_interpolation_factor)));
|
||||
m_sums2 = _mm_mul_ps(m_sums2, _mm_set_ps1(
|
||||
static_cast<float>(kernel_interpolation_factor)));
|
||||
m_sums1 = _mm_mul_ps(
|
||||
m_sums1,
|
||||
_mm_set_ps1(static_cast<float>(1.0 - kernel_interpolation_factor)));
|
||||
m_sums2 = _mm_mul_ps(
|
||||
m_sums2, _mm_set_ps1(static_cast<float>(kernel_interpolation_factor)));
|
||||
m_sums1 = _mm_add_ps(m_sums1, m_sums2);
|
||||
|
||||
// Sum components together.
|
||||
float result;
|
||||
m_sums2 = _mm_add_ps(_mm_movehl_ps(m_sums1, m_sums1), m_sums1);
|
||||
_mm_store_ss(&result, _mm_add_ss(m_sums2, _mm_shuffle_ps(
|
||||
m_sums2, m_sums2, 1)));
|
||||
_mm_store_ss(&result,
|
||||
_mm_add_ss(m_sums2, _mm_shuffle_ps(m_sums2, m_sums2, 1)));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
// MSVC++ requires this to be set before any other includes to get M_PI.
|
||||
#define _USE_MATH_DEFINES
|
||||
|
||||
#include "webrtc/common_audio/resampler/sinusoidal_linear_chirp_source.h"
|
||||
#include "common_audio/resampler/sinusoidal_linear_chirp_source.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
@ -43,8 +43,7 @@ void SinusoidalLinearChirpSource::Run(size_t frames, float* destination) {
|
||||
} else {
|
||||
// Sinusoidal linear chirp.
|
||||
double t = (current_index_ - delay_samples_) / sample_rate_;
|
||||
destination[i] =
|
||||
sin(2 * M_PI * (kMinFrequency * t + (k_ / 2) * t * t));
|
||||
destination[i] = sin(2 * M_PI * (kMinFrequency * t + (k_ / 2) * t * t));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -52,7 +51,7 @@ void SinusoidalLinearChirpSource::Run(size_t frames, float* destination) {
|
||||
|
||||
double SinusoidalLinearChirpSource::Frequency(size_t position) {
|
||||
return kMinFrequency + (position - delay_samples_) *
|
||||
(max_frequency_ - kMinFrequency) / total_samples_;
|
||||
(max_frequency_ - kMinFrequency) / total_samples_;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
@ -11,11 +11,11 @@
|
||||
// Modified from the Chromium original here:
|
||||
// src/media/base/sinc_resampler_unittest.cc
|
||||
|
||||
#ifndef WEBRTC_COMMON_AUDIO_RESAMPLER_SINUSOIDAL_LINEAR_CHIRP_SOURCE_H_
|
||||
#define WEBRTC_COMMON_AUDIO_RESAMPLER_SINUSOIDAL_LINEAR_CHIRP_SOURCE_H_
|
||||
#ifndef COMMON_AUDIO_RESAMPLER_SINUSOIDAL_LINEAR_CHIRP_SOURCE_H_
|
||||
#define COMMON_AUDIO_RESAMPLER_SINUSOIDAL_LINEAR_CHIRP_SOURCE_H_
|
||||
|
||||
#include "webrtc/base/constructormagic.h"
|
||||
#include "webrtc/common_audio/resampler/sinc_resampler.h"
|
||||
#include "common_audio/resampler/sinc_resampler.h"
|
||||
#include "rtc_base/constructor_magic.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -26,19 +26,19 @@ class SinusoidalLinearChirpSource : public SincResamplerCallback {
|
||||
public:
|
||||
// |delay_samples| can be used to insert a fractional sample delay into the
|
||||
// source. It will produce zeros until non-negative time is reached.
|
||||
SinusoidalLinearChirpSource(int sample_rate, size_t samples,
|
||||
double max_frequency, double delay_samples);
|
||||
SinusoidalLinearChirpSource(int sample_rate,
|
||||
size_t samples,
|
||||
double max_frequency,
|
||||
double delay_samples);
|
||||
|
||||
virtual ~SinusoidalLinearChirpSource() {}
|
||||
~SinusoidalLinearChirpSource() override {}
|
||||
|
||||
void Run(size_t frames, float* destination) override;
|
||||
|
||||
double Frequency(size_t position);
|
||||
|
||||
private:
|
||||
enum {
|
||||
kMinFrequency = 5
|
||||
};
|
||||
enum { kMinFrequency = 5 };
|
||||
|
||||
int sample_rate_;
|
||||
size_t total_samples_;
|
||||
@ -52,4 +52,4 @@ class SinusoidalLinearChirpSource : public SincResamplerCallback {
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // WEBRTC_COMMON_AUDIO_RESAMPLER_SINUSOIDAL_LINEAR_CHIRP_SOURCE_H_
|
||||
#endif // COMMON_AUDIO_RESAMPLER_SINUSOIDAL_LINEAR_CHIRP_SOURCE_H_
|
||||
|
Reference in New Issue
Block a user