aboutsummaryrefslogtreecommitdiff
path: root/webrtc/common_audio
diff options
context:
space:
mode:
Diffstat (limited to 'webrtc/common_audio')
-rw-r--r--webrtc/common_audio/BUILD.gn1
-rw-r--r--webrtc/common_audio/OWNERS1
-rw-r--r--webrtc/common_audio/audio_converter.cc33
-rw-r--r--webrtc/common_audio/audio_converter.h14
-rw-r--r--webrtc/common_audio/audio_converter_unittest.cc38
-rw-r--r--webrtc/common_audio/blocker.cc28
-rw-r--r--webrtc/common_audio/blocker.h16
-rw-r--r--webrtc/common_audio/blocker_unittest.cc115
-rw-r--r--webrtc/common_audio/channel_buffer.cc6
-rw-r--r--webrtc/common_audio/channel_buffer.h20
-rw-r--r--webrtc/common_audio/common_audio.gyp5
-rw-r--r--webrtc/common_audio/include/audio_util.h12
-rw-r--r--webrtc/common_audio/lapped_transform.cc12
-rw-r--r--webrtc/common_audio/lapped_transform.h22
-rw-r--r--webrtc/common_audio/lapped_transform_unittest.cc44
-rw-r--r--webrtc/common_audio/real_fourier.cc2
-rw-r--r--webrtc/common_audio/real_fourier.h2
-rw-r--r--webrtc/common_audio/real_fourier_unittest.cc8
-rw-r--r--webrtc/common_audio/resampler/include/push_resampler.h4
-rw-r--r--webrtc/common_audio/resampler/include/resampler.h8
-rw-r--r--webrtc/common_audio/resampler/push_resampler.cc8
-rw-r--r--webrtc/common_audio/resampler/resampler.cc6
-rw-r--r--webrtc/common_audio/signal_processing/real_fft_unittest.cc1
-rw-r--r--webrtc/common_audio/swap_queue.h210
-rw-r--r--webrtc/common_audio/swap_queue_unittest.cc225
-rw-r--r--webrtc/common_audio/wav_file.cc35
-rw-r--r--webrtc/common_audio/wav_file.h33
-rw-r--r--webrtc/common_audio/wav_file_unittest.cc24
-rw-r--r--webrtc/common_audio/wav_header.cc59
-rw-r--r--webrtc/common_audio/wav_header.h18
-rw-r--r--webrtc/common_audio/wav_header_unittest.cc28
31 files changed, 745 insertions, 293 deletions
diff --git a/webrtc/common_audio/BUILD.gn b/webrtc/common_audio/BUILD.gn
index b01b31816b..b4ec1d71ef 100644
--- a/webrtc/common_audio/BUILD.gn
+++ b/webrtc/common_audio/BUILD.gn
@@ -87,6 +87,7 @@ source_set("common_audio") {
"signal_processing/vector_scaling_operations.c",
"sparse_fir_filter.cc",
"sparse_fir_filter.h",
+ "swap_queue.h",
"vad/include/vad.h",
"vad/include/webrtc_vad.h",
"vad/vad.cc",
diff --git a/webrtc/common_audio/OWNERS b/webrtc/common_audio/OWNERS
index 20f640041e..208a7c5635 100644
--- a/webrtc/common_audio/OWNERS
+++ b/webrtc/common_audio/OWNERS
@@ -1,4 +1,3 @@
-andrew@webrtc.org
henrik.lundin@webrtc.org
jan.skoglund@webrtc.org
kwiberg@webrtc.org
diff --git a/webrtc/common_audio/audio_converter.cc b/webrtc/common_audio/audio_converter.cc
index f1709ae653..9ebfabc286 100644
--- a/webrtc/common_audio/audio_converter.cc
+++ b/webrtc/common_audio/audio_converter.cc
@@ -11,6 +11,7 @@
#include "webrtc/common_audio/audio_converter.h"
#include <cstring>
+#include <utility>
#include "webrtc/base/checks.h"
#include "webrtc/base/safe_conversions.h"
@@ -24,7 +25,7 @@ namespace webrtc {
class CopyConverter : public AudioConverter {
public:
- CopyConverter(int src_channels, size_t src_frames, int dst_channels,
+ CopyConverter(size_t src_channels, size_t src_frames, size_t dst_channels,
size_t dst_frames)
: AudioConverter(src_channels, src_frames, dst_channels, dst_frames) {}
~CopyConverter() override {};
@@ -33,7 +34,7 @@ class CopyConverter : public AudioConverter {
size_t dst_capacity) override {
CheckSizes(src_size, dst_capacity);
if (src != dst) {
- for (int i = 0; i < src_channels(); ++i)
+ for (size_t i = 0; i < src_channels(); ++i)
std::memcpy(dst[i], src[i], dst_frames() * sizeof(*dst[i]));
}
}
@@ -41,7 +42,7 @@ class CopyConverter : public AudioConverter {
class UpmixConverter : public AudioConverter {
public:
- UpmixConverter(int src_channels, size_t src_frames, int dst_channels,
+ UpmixConverter(size_t src_channels, size_t src_frames, size_t dst_channels,
size_t dst_frames)
: AudioConverter(src_channels, src_frames, dst_channels, dst_frames) {}
~UpmixConverter() override {};
@@ -51,7 +52,7 @@ class UpmixConverter : public AudioConverter {
CheckSizes(src_size, dst_capacity);
for (size_t i = 0; i < dst_frames(); ++i) {
const float value = src[0][i];
- for (int j = 0; j < dst_channels(); ++j)
+ for (size_t j = 0; j < dst_channels(); ++j)
dst[j][i] = value;
}
}
@@ -59,7 +60,7 @@ class UpmixConverter : public AudioConverter {
class DownmixConverter : public AudioConverter {
public:
- DownmixConverter(int src_channels, size_t src_frames, int dst_channels,
+ DownmixConverter(size_t src_channels, size_t src_frames, size_t dst_channels,
size_t dst_frames)
: AudioConverter(src_channels, src_frames, dst_channels, dst_frames) {
}
@@ -71,7 +72,7 @@ class DownmixConverter : public AudioConverter {
float* dst_mono = dst[0];
for (size_t i = 0; i < src_frames(); ++i) {
float sum = 0;
- for (int j = 0; j < src_channels(); ++j)
+ for (size_t j = 0; j < src_channels(); ++j)
sum += src[j][i];
dst_mono[i] = sum / src_channels();
}
@@ -80,11 +81,11 @@ class DownmixConverter : public AudioConverter {
class ResampleConverter : public AudioConverter {
public:
- ResampleConverter(int src_channels, size_t src_frames, int dst_channels,
+ ResampleConverter(size_t src_channels, size_t src_frames, size_t dst_channels,
size_t dst_frames)
: AudioConverter(src_channels, src_frames, dst_channels, dst_frames) {
resamplers_.reserve(src_channels);
- for (int i = 0; i < src_channels; ++i)
+ for (size_t i = 0; i < src_channels; ++i)
resamplers_.push_back(new PushSincResampler(src_frames, dst_frames));
}
~ResampleConverter() override {};
@@ -105,7 +106,7 @@ class ResampleConverter : public AudioConverter {
class CompositionConverter : public AudioConverter {
public:
CompositionConverter(ScopedVector<AudioConverter> converters)
- : converters_(converters.Pass()) {
+ : converters_(std::move(converters)) {
RTC_CHECK_GE(converters_.size(), 2u);
// We need an intermediate buffer after every converter.
for (auto it = converters_.begin(); it != converters_.end() - 1; ++it)
@@ -135,9 +136,9 @@ class CompositionConverter : public AudioConverter {
ScopedVector<ChannelBuffer<float>> buffers_;
};
-rtc::scoped_ptr<AudioConverter> AudioConverter::Create(int src_channels,
+rtc::scoped_ptr<AudioConverter> AudioConverter::Create(size_t src_channels,
size_t src_frames,
- int dst_channels,
+ size_t dst_channels,
size_t dst_frames) {
rtc::scoped_ptr<AudioConverter> sp;
if (src_channels > dst_channels) {
@@ -147,7 +148,7 @@ rtc::scoped_ptr<AudioConverter> AudioConverter::Create(int src_channels,
dst_channels, src_frames));
converters.push_back(new ResampleConverter(dst_channels, src_frames,
dst_channels, dst_frames));
- sp.reset(new CompositionConverter(converters.Pass()));
+ sp.reset(new CompositionConverter(std::move(converters)));
} else {
sp.reset(new DownmixConverter(src_channels, src_frames, dst_channels,
dst_frames));
@@ -159,7 +160,7 @@ rtc::scoped_ptr<AudioConverter> AudioConverter::Create(int src_channels,
src_channels, dst_frames));
converters.push_back(new UpmixConverter(src_channels, dst_frames,
dst_channels, dst_frames));
- sp.reset(new CompositionConverter(converters.Pass()));
+ sp.reset(new CompositionConverter(std::move(converters)));
} else {
sp.reset(new UpmixConverter(src_channels, src_frames, dst_channels,
dst_frames));
@@ -172,7 +173,7 @@ rtc::scoped_ptr<AudioConverter> AudioConverter::Create(int src_channels,
dst_frames));
}
- return sp.Pass();
+ return sp;
}
// For CompositionConverter.
@@ -182,8 +183,8 @@ AudioConverter::AudioConverter()
dst_channels_(0),
dst_frames_(0) {}
-AudioConverter::AudioConverter(int src_channels, size_t src_frames,
- int dst_channels, size_t dst_frames)
+AudioConverter::AudioConverter(size_t src_channels, size_t src_frames,
+ size_t dst_channels, size_t dst_frames)
: src_channels_(src_channels),
src_frames_(src_frames),
dst_channels_(dst_channels),
diff --git a/webrtc/common_audio/audio_converter.h b/webrtc/common_audio/audio_converter.h
index 7d1513bc02..c5f08c1d9b 100644
--- a/webrtc/common_audio/audio_converter.h
+++ b/webrtc/common_audio/audio_converter.h
@@ -26,9 +26,9 @@ class AudioConverter {
public:
// Returns a new AudioConverter, which will use the supplied format for its
// lifetime. Caller is responsible for the memory.
- static rtc::scoped_ptr<AudioConverter> Create(int src_channels,
+ static rtc::scoped_ptr<AudioConverter> Create(size_t src_channels,
size_t src_frames,
- int dst_channels,
+ size_t dst_channels,
size_t dst_frames);
virtual ~AudioConverter() {};
@@ -39,23 +39,23 @@ class AudioConverter {
virtual void Convert(const float* const* src, size_t src_size,
float* const* dst, size_t dst_capacity) = 0;
- int src_channels() const { return src_channels_; }
+ size_t src_channels() const { return src_channels_; }
size_t src_frames() const { return src_frames_; }
- int dst_channels() const { return dst_channels_; }
+ size_t dst_channels() const { return dst_channels_; }
size_t dst_frames() const { return dst_frames_; }
protected:
AudioConverter();
- AudioConverter(int src_channels, size_t src_frames, int dst_channels,
+ AudioConverter(size_t src_channels, size_t src_frames, size_t dst_channels,
size_t dst_frames);
// Helper to RTC_CHECK that inputs are correctly sized.
void CheckSizes(size_t src_size, size_t dst_capacity) const;
private:
- const int src_channels_;
+ const size_t src_channels_;
const size_t src_frames_;
- const int dst_channels_;
+ const size_t dst_channels_;
const size_t dst_frames_;
RTC_DISALLOW_COPY_AND_ASSIGN(AudioConverter);
diff --git a/webrtc/common_audio/audio_converter_unittest.cc b/webrtc/common_audio/audio_converter_unittest.cc
index c85b96e285..dace0bdccf 100644
--- a/webrtc/common_audio/audio_converter_unittest.cc
+++ b/webrtc/common_audio/audio_converter_unittest.cc
@@ -13,6 +13,7 @@
#include <vector>
#include "testing/gtest/include/gtest/gtest.h"
+#include "webrtc/base/arraysize.h"
#include "webrtc/base/format_macros.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/common_audio/audio_converter.h"
@@ -24,11 +25,11 @@ namespace webrtc {
typedef rtc::scoped_ptr<ChannelBuffer<float>> ScopedBuffer;
// Sets the signal value to increase by |data| with every sample.
-ScopedBuffer CreateBuffer(const std::vector<float>& data, int frames) {
- const int num_channels = static_cast<int>(data.size());
+ScopedBuffer CreateBuffer(const std::vector<float>& data, size_t frames) {
+ const size_t num_channels = data.size();
ScopedBuffer sb(new ChannelBuffer<float>(frames, num_channels));
- for (int i = 0; i < num_channels; ++i)
- for (int j = 0; j < frames; ++j)
+ for (size_t i = 0; i < num_channels; ++i)
+ for (size_t j = 0; j < frames; ++j)
sb->channels()[i][j] = data[i] * j;
return sb;
}
@@ -56,7 +57,7 @@ float ComputeSNR(const ChannelBuffer<float>& ref,
float mse = 0;
float variance = 0;
float mean = 0;
- for (int i = 0; i < ref.num_channels(); ++i) {
+ for (size_t i = 0; i < ref.num_channels(); ++i) {
for (size_t j = 0; j < ref.num_frames() - delay; ++j) {
float error = ref.channels()[i][j] - test.channels()[i][j + delay];
mse += error * error;
@@ -85,9 +86,9 @@ float ComputeSNR(const ChannelBuffer<float>& ref,
// Sets the source to a linearly increasing signal for which we can easily
// generate a reference. Runs the AudioConverter and ensures the output has
// sufficiently high SNR relative to the reference.
-void RunAudioConverterTest(int src_channels,
+void RunAudioConverterTest(size_t src_channels,
int src_sample_rate_hz,
- int dst_channels,
+ size_t dst_channels,
int dst_sample_rate_hz) {
const float kSrcLeft = 0.0002f;
const float kSrcRight = 0.0001f;
@@ -96,8 +97,8 @@ void RunAudioConverterTest(int src_channels,
const float dst_left = resampling_factor * kSrcLeft;
const float dst_right = resampling_factor * kSrcRight;
const float dst_mono = (dst_left + dst_right) / 2;
- const int src_frames = src_sample_rate_hz / 100;
- const int dst_frames = dst_sample_rate_hz / 100;
+ const size_t src_frames = static_cast<size_t>(src_sample_rate_hz / 100);
+ const size_t dst_frames = static_cast<size_t>(dst_sample_rate_hz / 100);
std::vector<float> src_data(1, kSrcLeft);
if (src_channels == 2)
@@ -127,8 +128,9 @@ void RunAudioConverterTest(int src_channels,
static_cast<size_t>(
PushSincResampler::AlgorithmicDelaySeconds(src_sample_rate_hz) *
dst_sample_rate_hz);
- printf("(%d, %d Hz) -> (%d, %d Hz) ", // SNR reported on the same line later.
- src_channels, src_sample_rate_hz, dst_channels, dst_sample_rate_hz);
+ // SNR reported on the same line later.
+ printf("(%" PRIuS ", %d Hz) -> (%" PRIuS ", %d Hz) ",
+ src_channels, src_sample_rate_hz, dst_channels, dst_sample_rate_hz);
rtc::scoped_ptr<AudioConverter> converter = AudioConverter::Create(
src_channels, src_frames, dst_channels, dst_frames);
@@ -141,13 +143,13 @@ void RunAudioConverterTest(int src_channels,
TEST(AudioConverterTest, ConversionsPassSNRThreshold) {
const int kSampleRates[] = {8000, 16000, 32000, 44100, 48000};
- const int kSampleRatesSize = sizeof(kSampleRates) / sizeof(*kSampleRates);
- const int kChannels[] = {1, 2};
- const int kChannelsSize = sizeof(kChannels) / sizeof(*kChannels);
- for (int src_rate = 0; src_rate < kSampleRatesSize; ++src_rate) {
- for (int dst_rate = 0; dst_rate < kSampleRatesSize; ++dst_rate) {
- for (int src_channel = 0; src_channel < kChannelsSize; ++src_channel) {
- for (int dst_channel = 0; dst_channel < kChannelsSize; ++dst_channel) {
+ const size_t kChannels[] = {1, 2};
+ for (size_t src_rate = 0; src_rate < arraysize(kSampleRates); ++src_rate) {
+ for (size_t dst_rate = 0; dst_rate < arraysize(kSampleRates); ++dst_rate) {
+ for (size_t src_channel = 0; src_channel < arraysize(kChannels);
+ ++src_channel) {
+ for (size_t dst_channel = 0; dst_channel < arraysize(kChannels);
+ ++dst_channel) {
RunAudioConverterTest(kChannels[src_channel], kSampleRates[src_rate],
kChannels[dst_channel], kSampleRates[dst_rate]);
}
diff --git a/webrtc/common_audio/blocker.cc b/webrtc/common_audio/blocker.cc
index 0133550beb..13432f2e7a 100644
--- a/webrtc/common_audio/blocker.cc
+++ b/webrtc/common_audio/blocker.cc
@@ -22,10 +22,10 @@ void AddFrames(const float* const* a,
const float* const* b,
int b_start_index,
size_t num_frames,
- int num_channels,
+ size_t num_channels,
float* const* result,
size_t result_start_index) {
- for (int i = 0; i < num_channels; ++i) {
+ for (size_t i = 0; i < num_channels; ++i) {
for (size_t j = 0; j < num_frames; ++j) {
result[i][j + result_start_index] =
a[i][j + a_start_index] + b[i][j + b_start_index];
@@ -37,10 +37,10 @@ void AddFrames(const float* const* a,
void CopyFrames(const float* const* src,
size_t src_start_index,
size_t num_frames,
- int num_channels,
+ size_t num_channels,
float* const* dst,
size_t dst_start_index) {
- for (int i = 0; i < num_channels; ++i) {
+ for (size_t i = 0; i < num_channels; ++i) {
memcpy(&dst[i][dst_start_index],
&src[i][src_start_index],
num_frames * sizeof(dst[i][dst_start_index]));
@@ -51,10 +51,10 @@ void CopyFrames(const float* const* src,
void MoveFrames(const float* const* src,
size_t src_start_index,
size_t num_frames,
- int num_channels,
+ size_t num_channels,
float* const* dst,
size_t dst_start_index) {
- for (int i = 0; i < num_channels; ++i) {
+ for (size_t i = 0; i < num_channels; ++i) {
memmove(&dst[i][dst_start_index],
&src[i][src_start_index],
num_frames * sizeof(dst[i][dst_start_index]));
@@ -64,8 +64,8 @@ void MoveFrames(const float* const* src,
void ZeroOut(float* const* buffer,
size_t starting_idx,
size_t num_frames,
- int num_channels) {
- for (int i = 0; i < num_channels; ++i) {
+ size_t num_channels) {
+ for (size_t i = 0; i < num_channels; ++i) {
memset(&buffer[i][starting_idx], 0,
num_frames * sizeof(buffer[i][starting_idx]));
}
@@ -75,9 +75,9 @@ void ZeroOut(float* const* buffer,
// stored in |frames|.
void ApplyWindow(const float* window,
size_t num_frames,
- int num_channels,
+ size_t num_channels,
float* const* frames) {
- for (int i = 0; i < num_channels; ++i) {
+ for (size_t i = 0; i < num_channels; ++i) {
for (size_t j = 0; j < num_frames; ++j) {
frames[i][j] = frames[i][j] * window[j];
}
@@ -100,8 +100,8 @@ namespace webrtc {
Blocker::Blocker(size_t chunk_size,
size_t block_size,
- int num_input_channels,
- int num_output_channels,
+ size_t num_input_channels,
+ size_t num_output_channels,
const float* window,
size_t shift_amount,
BlockerCallback* callback)
@@ -166,8 +166,8 @@ Blocker::Blocker(size_t chunk_size,
// TODO(claguna): Look at using ring buffers to eliminate some copies.
void Blocker::ProcessChunk(const float* const* input,
size_t chunk_size,
- int num_input_channels,
- int num_output_channels,
+ size_t num_input_channels,
+ size_t num_output_channels,
float* const* output) {
RTC_CHECK_EQ(chunk_size, chunk_size_);
RTC_CHECK_EQ(num_input_channels, num_input_channels_);
diff --git a/webrtc/common_audio/blocker.h b/webrtc/common_audio/blocker.h
index 025638ae8c..3a67c134d0 100644
--- a/webrtc/common_audio/blocker.h
+++ b/webrtc/common_audio/blocker.h
@@ -26,8 +26,8 @@ class BlockerCallback {
virtual void ProcessBlock(const float* const* input,
size_t num_frames,
- int num_input_channels,
- int num_output_channels,
+ size_t num_input_channels,
+ size_t num_output_channels,
float* const* output) = 0;
};
@@ -65,23 +65,23 @@ class Blocker {
public:
Blocker(size_t chunk_size,
size_t block_size,
- int num_input_channels,
- int num_output_channels,
+ size_t num_input_channels,
+ size_t num_output_channels,
const float* window,
size_t shift_amount,
BlockerCallback* callback);
void ProcessChunk(const float* const* input,
size_t chunk_size,
- int num_input_channels,
- int num_output_channels,
+ size_t num_input_channels,
+ size_t num_output_channels,
float* const* output);
private:
const size_t chunk_size_;
const size_t block_size_;
- const int num_input_channels_;
- const int num_output_channels_;
+ const size_t num_input_channels_;
+ const size_t num_output_channels_;
// The number of frames of delay to add at the beginning of the first chunk.
const size_t initial_delay_;
diff --git a/webrtc/common_audio/blocker_unittest.cc b/webrtc/common_audio/blocker_unittest.cc
index 397e269239..a5a7b56282 100644
--- a/webrtc/common_audio/blocker_unittest.cc
+++ b/webrtc/common_audio/blocker_unittest.cc
@@ -11,6 +11,7 @@
#include "webrtc/common_audio/blocker.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "webrtc/base/arraysize.h"
namespace {
@@ -19,10 +20,10 @@ class PlusThreeBlockerCallback : public webrtc::BlockerCallback {
public:
void ProcessBlock(const float* const* input,
size_t num_frames,
- int num_input_channels,
- int num_output_channels,
+ size_t num_input_channels,
+ size_t num_output_channels,
float* const* output) override {
- for (int i = 0; i < num_output_channels; ++i) {
+ for (size_t i = 0; i < num_output_channels; ++i) {
for (size_t j = 0; j < num_frames; ++j) {
output[i][j] = input[i][j] + 3;
}
@@ -35,10 +36,10 @@ class CopyBlockerCallback : public webrtc::BlockerCallback {
public:
void ProcessBlock(const float* const* input,
size_t num_frames,
- int num_input_channels,
- int num_output_channels,
+ size_t num_input_channels,
+ size_t num_output_channels,
float* const* output) override {
- for (int i = 0; i < num_output_channels; ++i) {
+ for (size_t i = 0; i < num_output_channels; ++i) {
for (size_t j = 0; j < num_frames; ++j) {
output[i][j] = input[i][j];
}
@@ -56,16 +57,16 @@ namespace webrtc {
class BlockerTest : public ::testing::Test {
protected:
void RunTest(Blocker* blocker,
- int chunk_size,
- int num_frames,
+ size_t chunk_size,
+ size_t num_frames,
const float* const* input,
float* const* input_chunk,
float* const* output,
float* const* output_chunk,
- int num_input_channels,
- int num_output_channels) {
- int start = 0;
- int end = chunk_size - 1;
+ size_t num_input_channels,
+ size_t num_output_channels) {
+ size_t start = 0;
+ size_t end = chunk_size - 1;
while (end < num_frames) {
CopyTo(input_chunk, 0, start, num_input_channels, chunk_size, input);
blocker->ProcessChunk(input_chunk,
@@ -75,28 +76,28 @@ class BlockerTest : public ::testing::Test {
output_chunk);
CopyTo(output, start, 0, num_output_channels, chunk_size, output_chunk);
- start = start + chunk_size;
- end = end + chunk_size;
+ start += chunk_size;
+ end += chunk_size;
}
}
void ValidateSignalEquality(const float* const* expected,
const float* const* actual,
- int num_channels,
- int num_frames) {
- for (int i = 0; i < num_channels; ++i) {
- for (int j = 0; j < num_frames; ++j) {
+ size_t num_channels,
+ size_t num_frames) {
+ for (size_t i = 0; i < num_channels; ++i) {
+ for (size_t j = 0; j < num_frames; ++j) {
EXPECT_FLOAT_EQ(expected[i][j], actual[i][j]);
}
}
}
void ValidateInitialDelay(const float* const* output,
- int num_channels,
- int num_frames,
- int initial_delay) {
- for (int i = 0; i < num_channels; ++i) {
- for (int j = 0; j < num_frames; ++j) {
+ size_t num_channels,
+ size_t num_frames,
+ size_t initial_delay) {
+ for (size_t i = 0; i < num_channels; ++i) {
+ for (size_t j = 0; j < num_frames; ++j) {
if (j < initial_delay) {
EXPECT_FLOAT_EQ(output[i][j], 0.f);
} else {
@@ -107,12 +108,12 @@ class BlockerTest : public ::testing::Test {
}
static void CopyTo(float* const* dst,
- int start_index_dst,
- int start_index_src,
- int num_channels,
- int num_frames,
+ size_t start_index_dst,
+ size_t start_index_src,
+ size_t num_channels,
+ size_t num_frames,
const float* const* src) {
- for (int i = 0; i < num_channels; ++i) {
+ for (size_t i = 0; i < num_channels; ++i) {
memcpy(&dst[i][start_index_dst],
&src[i][start_index_src],
num_frames * sizeof(float));
@@ -121,12 +122,12 @@ class BlockerTest : public ::testing::Test {
};
TEST_F(BlockerTest, TestBlockerMutuallyPrimeChunkandBlockSize) {
- const int kNumInputChannels = 3;
- const int kNumOutputChannels = 2;
- const int kNumFrames = 10;
- const int kBlockSize = 4;
- const int kChunkSize = 5;
- const int kShiftAmount = 2;
+ const size_t kNumInputChannels = 3;
+ const size_t kNumOutputChannels = 2;
+ const size_t kNumFrames = 10;
+ const size_t kBlockSize = 4;
+ const size_t kChunkSize = 5;
+ const size_t kShiftAmount = 2;
const float kInput[kNumInputChannels][kNumFrames] = {
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
@@ -174,12 +175,12 @@ TEST_F(BlockerTest, TestBlockerMutuallyPrimeChunkandBlockSize) {
}
TEST_F(BlockerTest, TestBlockerMutuallyPrimeShiftAndBlockSize) {
- const int kNumInputChannels = 3;
- const int kNumOutputChannels = 2;
- const int kNumFrames = 12;
- const int kBlockSize = 4;
- const int kChunkSize = 6;
- const int kShiftAmount = 3;
+ const size_t kNumInputChannels = 3;
+ const size_t kNumOutputChannels = 2;
+ const size_t kNumFrames = 12;
+ const size_t kBlockSize = 4;
+ const size_t kChunkSize = 6;
+ const size_t kShiftAmount = 3;
const float kInput[kNumInputChannels][kNumFrames] = {
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
@@ -227,12 +228,12 @@ TEST_F(BlockerTest, TestBlockerMutuallyPrimeShiftAndBlockSize) {
}
TEST_F(BlockerTest, TestBlockerNoOverlap) {
- const int kNumInputChannels = 3;
- const int kNumOutputChannels = 2;
- const int kNumFrames = 12;
- const int kBlockSize = 4;
- const int kChunkSize = 4;
- const int kShiftAmount = 4;
+ const size_t kNumInputChannels = 3;
+ const size_t kNumOutputChannels = 2;
+ const size_t kNumFrames = 12;
+ const size_t kBlockSize = 4;
+ const size_t kChunkSize = 4;
+ const size_t kShiftAmount = 4;
const float kInput[kNumInputChannels][kNumFrames] = {
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
@@ -280,21 +281,21 @@ TEST_F(BlockerTest, TestBlockerNoOverlap) {
}
TEST_F(BlockerTest, InitialDelaysAreMinimum) {
- const int kNumInputChannels = 3;
- const int kNumOutputChannels = 2;
- const int kNumFrames = 1280;
- const int kChunkSize[] =
+ const size_t kNumInputChannels = 3;
+ const size_t kNumOutputChannels = 2;
+ const size_t kNumFrames = 1280;
+ const size_t kChunkSize[] =
{80, 80, 80, 80, 80, 80, 160, 160, 160, 160, 160, 160};
- const int kBlockSize[] =
+ const size_t kBlockSize[] =
{64, 64, 64, 128, 128, 128, 128, 128, 128, 256, 256, 256};
- const int kShiftAmount[] =
+ const size_t kShiftAmount[] =
{16, 32, 64, 32, 64, 128, 32, 64, 128, 64, 128, 256};
- const int kInitialDelay[] =
+ const size_t kInitialDelay[] =
{48, 48, 48, 112, 112, 112, 96, 96, 96, 224, 224, 224};
float input[kNumInputChannels][kNumFrames];
- for (int i = 0; i < kNumInputChannels; ++i) {
- for (int j = 0; j < kNumFrames; ++j) {
+ for (size_t i = 0; i < kNumInputChannels; ++i) {
+ for (size_t j = 0; j < kNumFrames; ++j) {
input[i][j] = i + 1;
}
}
@@ -305,9 +306,9 @@ TEST_F(BlockerTest, InitialDelaysAreMinimum) {
CopyBlockerCallback callback;
- for (size_t i = 0; i < (sizeof(kChunkSize) / sizeof(*kChunkSize)); ++i) {
+ for (size_t i = 0; i < arraysize(kChunkSize); ++i) {
rtc::scoped_ptr<float[]> window(new float[kBlockSize[i]]);
- for (int j = 0; j < kBlockSize[i]; ++j) {
+ for (size_t j = 0; j < kBlockSize[i]; ++j) {
window[j] = 1.f;
}
diff --git a/webrtc/common_audio/channel_buffer.cc b/webrtc/common_audio/channel_buffer.cc
index d3dc7c04f7..44520c6100 100644
--- a/webrtc/common_audio/channel_buffer.cc
+++ b/webrtc/common_audio/channel_buffer.cc
@@ -13,7 +13,7 @@
namespace webrtc {
IFChannelBuffer::IFChannelBuffer(size_t num_frames,
- int num_channels,
+ size_t num_channels,
size_t num_bands)
: ivalid_(true),
ibuf_(num_frames, num_channels, num_bands),
@@ -47,7 +47,7 @@ void IFChannelBuffer::RefreshF() const {
assert(ivalid_);
const int16_t* const* int_channels = ibuf_.channels();
float* const* float_channels = fbuf_.channels();
- for (int i = 0; i < ibuf_.num_channels(); ++i) {
+ for (size_t i = 0; i < ibuf_.num_channels(); ++i) {
for (size_t j = 0; j < ibuf_.num_frames(); ++j) {
float_channels[i][j] = int_channels[i][j];
}
@@ -61,7 +61,7 @@ void IFChannelBuffer::RefreshI() const {
assert(fvalid_);
int16_t* const* int_channels = ibuf_.channels();
const float* const* float_channels = fbuf_.channels();
- for (int i = 0; i < ibuf_.num_channels(); ++i) {
+ for (size_t i = 0; i < ibuf_.num_channels(); ++i) {
FloatS16ToS16(float_channels[i],
ibuf_.num_frames(),
int_channels[i]);
diff --git a/webrtc/common_audio/channel_buffer.h b/webrtc/common_audio/channel_buffer.h
index 6050090876..d9069163fa 100644
--- a/webrtc/common_audio/channel_buffer.h
+++ b/webrtc/common_audio/channel_buffer.h
@@ -40,7 +40,7 @@ template <typename T>
class ChannelBuffer {
public:
ChannelBuffer(size_t num_frames,
- int num_channels,
+ size_t num_channels,
size_t num_bands = 1)
: data_(new T[num_frames * num_channels]()),
channels_(new T*[num_channels * num_bands]),
@@ -49,7 +49,7 @@ class ChannelBuffer {
num_frames_per_band_(num_frames / num_bands),
num_channels_(num_channels),
num_bands_(num_bands) {
- for (int i = 0; i < num_channels_; ++i) {
+ for (size_t i = 0; i < num_channels_; ++i) {
for (size_t j = 0; j < num_bands_; ++j) {
channels_[j * num_channels_ + i] =
&data_[i * num_frames_ + j * num_frames_per_band_];
@@ -90,12 +90,12 @@ class ChannelBuffer {
// 0 <= channel < |num_channels_|
// 0 <= band < |num_bands_|
// 0 <= sample < |num_frames_per_band_|
- const T* const* bands(int channel) const {
+ const T* const* bands(size_t channel) const {
RTC_DCHECK_LT(channel, num_channels_);
- RTC_DCHECK_GE(channel, 0);
+ RTC_DCHECK_GE(channel, 0u);
return &bands_[channel * num_bands_];
}
- T* const* bands(int channel) {
+ T* const* bands(size_t channel) {
const ChannelBuffer<T>* t = this;
return const_cast<T* const*>(t->bands(channel));
}
@@ -104,7 +104,7 @@ class ChannelBuffer {
// Returns |slice| for convenience.
const T* const* Slice(T** slice, size_t start_frame) const {
RTC_DCHECK_LT(start_frame, num_frames_);
- for (int i = 0; i < num_channels_; ++i)
+ for (size_t i = 0; i < num_channels_; ++i)
slice[i] = &channels_[i][start_frame];
return slice;
}
@@ -115,7 +115,7 @@ class ChannelBuffer {
size_t num_frames() const { return num_frames_; }
size_t num_frames_per_band() const { return num_frames_per_band_; }
- int num_channels() const { return num_channels_; }
+ size_t num_channels() const { return num_channels_; }
size_t num_bands() const { return num_bands_; }
size_t size() const {return num_frames_ * num_channels_; }
@@ -130,7 +130,7 @@ class ChannelBuffer {
rtc::scoped_ptr<T* []> bands_;
const size_t num_frames_;
const size_t num_frames_per_band_;
- const int num_channels_;
+ const size_t num_channels_;
const size_t num_bands_;
};
@@ -142,7 +142,7 @@ class ChannelBuffer {
// fbuf() until the next call to any of the other functions.
class IFChannelBuffer {
public:
- IFChannelBuffer(size_t num_frames, int num_channels, size_t num_bands = 1);
+ IFChannelBuffer(size_t num_frames, size_t num_channels, size_t num_bands = 1);
ChannelBuffer<int16_t>* ibuf();
ChannelBuffer<float>* fbuf();
@@ -151,7 +151,7 @@ class IFChannelBuffer {
size_t num_frames() const { return ibuf_.num_frames(); }
size_t num_frames_per_band() const { return ibuf_.num_frames_per_band(); }
- int num_channels() const { return ibuf_.num_channels(); }
+ size_t num_channels() const { return ibuf_.num_channels(); }
size_t num_bands() const { return ibuf_.num_bands(); }
private:
diff --git a/webrtc/common_audio/common_audio.gyp b/webrtc/common_audio/common_audio.gyp
index 884a8afcf8..f0a6fc9473 100644
--- a/webrtc/common_audio/common_audio.gyp
+++ b/webrtc/common_audio/common_audio.gyp
@@ -101,6 +101,7 @@
'signal_processing/vector_scaling_operations.c',
'sparse_fir_filter.cc',
'sparse_fir_filter.h',
+ 'swap_queue.h',
'vad/include/vad.h',
'vad/include/webrtc_vad.h',
'vad/vad.cc',
@@ -227,9 +228,10 @@
},
], # targets
}],
- ['include_tests==1', {
+ ['include_tests==1 and OS!="ios"', {
'targets' : [
{
+ # Does not compile on iOS: webrtc:4755.
'target_name': 'common_audio_unittests',
'type': '<(gtest_target_type)',
'dependencies': [
@@ -256,6 +258,7 @@
'signal_processing/real_fft_unittest.cc',
'signal_processing/signal_processing_unittest.cc',
'sparse_fir_filter_unittest.cc',
+ 'swap_queue_unittest.cc',
'vad/vad_core_unittest.cc',
'vad/vad_filterbank_unittest.cc',
'vad/vad_gmm_unittest.cc',
diff --git a/webrtc/common_audio/include/audio_util.h b/webrtc/common_audio/include/audio_util.h
index 2c0028ce90..55dfc06a31 100644
--- a/webrtc/common_audio/include/audio_util.h
+++ b/webrtc/common_audio/include/audio_util.h
@@ -87,11 +87,11 @@ void CopyAudioIfNeeded(const T* const* src,
template <typename T>
void Deinterleave(const T* interleaved,
size_t samples_per_channel,
- int num_channels,
+ size_t num_channels,
T* const* deinterleaved) {
- for (int i = 0; i < num_channels; ++i) {
+ for (size_t i = 0; i < num_channels; ++i) {
T* channel = deinterleaved[i];
- int interleaved_idx = i;
+ size_t interleaved_idx = i;
for (size_t j = 0; j < samples_per_channel; ++j) {
channel[j] = interleaved[interleaved_idx];
interleaved_idx += num_channels;
@@ -105,11 +105,11 @@ void Deinterleave(const T* interleaved,
template <typename T>
void Interleave(const T* const* deinterleaved,
size_t samples_per_channel,
- int num_channels,
+ size_t num_channels,
T* interleaved) {
- for (int i = 0; i < num_channels; ++i) {
+ for (size_t i = 0; i < num_channels; ++i) {
const T* channel = deinterleaved[i];
- int interleaved_idx = i;
+ size_t interleaved_idx = i;
for (size_t j = 0; j < samples_per_channel; ++j) {
interleaved[interleaved_idx] = channel[j];
interleaved_idx += num_channels;
diff --git a/webrtc/common_audio/lapped_transform.cc b/webrtc/common_audio/lapped_transform.cc
index c01f1d9d8c..5ab1db1b25 100644
--- a/webrtc/common_audio/lapped_transform.cc
+++ b/webrtc/common_audio/lapped_transform.cc
@@ -21,14 +21,14 @@ namespace webrtc {
void LappedTransform::BlockThunk::ProcessBlock(const float* const* input,
size_t num_frames,
- int num_input_channels,
- int num_output_channels,
+ size_t num_input_channels,
+ size_t num_output_channels,
float* const* output) {
RTC_CHECK_EQ(num_input_channels, parent_->num_in_channels_);
RTC_CHECK_EQ(num_output_channels, parent_->num_out_channels_);
RTC_CHECK_EQ(parent_->block_length_, num_frames);
- for (int i = 0; i < num_input_channels; ++i) {
+ for (size_t i = 0; i < num_input_channels; ++i) {
memcpy(parent_->real_buf_.Row(i), input[i],
num_frames * sizeof(*input[0]));
parent_->fft_->Forward(parent_->real_buf_.Row(i),
@@ -44,7 +44,7 @@ void LappedTransform::BlockThunk::ProcessBlock(const float* const* input,
num_output_channels,
parent_->cplx_post_.Array());
- for (int i = 0; i < num_output_channels; ++i) {
+ for (size_t i = 0; i < num_output_channels; ++i) {
parent_->fft_->Inverse(parent_->cplx_post_.Row(i),
parent_->real_buf_.Row(i));
memcpy(output[i], parent_->real_buf_.Row(i),
@@ -52,8 +52,8 @@ void LappedTransform::BlockThunk::ProcessBlock(const float* const* input,
}
}
-LappedTransform::LappedTransform(int num_in_channels,
- int num_out_channels,
+LappedTransform::LappedTransform(size_t num_in_channels,
+ size_t num_out_channels,
size_t chunk_length,
const float* window,
size_t block_length,
diff --git a/webrtc/common_audio/lapped_transform.h b/webrtc/common_audio/lapped_transform.h
index 21e10e3911..1373ca10e1 100644
--- a/webrtc/common_audio/lapped_transform.h
+++ b/webrtc/common_audio/lapped_transform.h
@@ -35,8 +35,8 @@ class LappedTransform {
virtual ~Callback() {}
virtual void ProcessAudioBlock(const std::complex<float>* const* in_block,
- int num_in_channels, size_t frames,
- int num_out_channels,
+ size_t num_in_channels, size_t frames,
+ size_t num_out_channels,
std::complex<float>* const* out_block) = 0;
};
@@ -46,8 +46,8 @@ class LappedTransform {
// |block_length| defines the length of a block, in samples.
// |shift_amount| is in samples. |callback| is the caller-owned audio
// processing function called for each block of the input chunk.
- LappedTransform(int num_in_channels,
- int num_out_channels,
+ LappedTransform(size_t num_in_channels,
+ size_t num_out_channels,
size_t chunk_length,
const float* window,
size_t block_length,
@@ -75,7 +75,7 @@ class LappedTransform {
// in_chunk.
//
// Returns the same num_in_channels passed to the LappedTransform constructor.
- int num_in_channels() const { return num_in_channels_; }
+ size_t num_in_channels() const { return num_in_channels_; }
// Get the number of output channels.
//
@@ -84,7 +84,7 @@ class LappedTransform {
//
// Returns the same num_out_channels passed to the LappedTransform
// constructor.
- int num_out_channels() const { return num_out_channels_; }
+ size_t num_out_channels() const { return num_out_channels_; }
private:
// Internal middleware callback, given to the blocker. Transforms each block
@@ -93,16 +93,18 @@ class LappedTransform {
public:
explicit BlockThunk(LappedTransform* parent) : parent_(parent) {}
- virtual void ProcessBlock(const float* const* input, size_t num_frames,
- int num_input_channels, int num_output_channels,
+ virtual void ProcessBlock(const float* const* input,
+ size_t num_frames,
+ size_t num_input_channels,
+ size_t num_output_channels,
float* const* output);
private:
LappedTransform* const parent_;
} blocker_callback_;
- const int num_in_channels_;
- const int num_out_channels_;
+ const size_t num_in_channels_;
+ const size_t num_out_channels_;
const size_t block_length_;
const size_t chunk_length_;
diff --git a/webrtc/common_audio/lapped_transform_unittest.cc b/webrtc/common_audio/lapped_transform_unittest.cc
index f688cc240a..a78488e326 100644
--- a/webrtc/common_audio/lapped_transform_unittest.cc
+++ b/webrtc/common_audio/lapped_transform_unittest.cc
@@ -25,23 +25,23 @@ class NoopCallback : public webrtc::LappedTransform::Callback {
NoopCallback() : block_num_(0) {}
virtual void ProcessAudioBlock(const complex<float>* const* in_block,
- int in_channels,
+ size_t in_channels,
size_t frames,
- int out_channels,
+ size_t out_channels,
complex<float>* const* out_block) {
RTC_CHECK_EQ(in_channels, out_channels);
- for (int i = 0; i < out_channels; ++i) {
+ for (size_t i = 0; i < out_channels; ++i) {
memcpy(out_block[i], in_block[i], sizeof(**in_block) * frames);
}
++block_num_;
}
- int block_num() {
+ size_t block_num() {
return block_num_;
}
private:
- int block_num_;
+ size_t block_num_;
};
class FftCheckerCallback : public webrtc::LappedTransform::Callback {
@@ -49,9 +49,9 @@ class FftCheckerCallback : public webrtc::LappedTransform::Callback {
FftCheckerCallback() : block_num_(0) {}
virtual void ProcessAudioBlock(const complex<float>* const* in_block,
- int in_channels,
+ size_t in_channels,
size_t frames,
- int out_channels,
+ size_t out_channels,
complex<float>* const* out_block) {
RTC_CHECK_EQ(in_channels, out_channels);
@@ -69,12 +69,12 @@ class FftCheckerCallback : public webrtc::LappedTransform::Callback {
}
}
- int block_num() {
+ size_t block_num() {
return block_num_;
}
private:
- int block_num_;
+ size_t block_num_;
};
void SetFloatArray(float value, int rows, int cols, float* const* array) {
@@ -90,10 +90,10 @@ void SetFloatArray(float value, int rows, int cols, float* const* array) {
namespace webrtc {
TEST(LappedTransformTest, Windowless) {
- const int kChannels = 3;
- const int kChunkLength = 512;
- const int kBlockLength = 64;
- const int kShiftAmount = 64;
+ const size_t kChannels = 3;
+ const size_t kChunkLength = 512;
+ const size_t kBlockLength = 64;
+ const size_t kShiftAmount = 64;
NoopCallback noop;
// Rectangular window.
@@ -118,8 +118,8 @@ TEST(LappedTransformTest, Windowless) {
trans.ProcessChunk(in_chunk, out_chunk);
- for (int i = 0; i < kChannels; ++i) {
- for (int j = 0; j < kChunkLength; ++j) {
+ for (size_t i = 0; i < kChannels; ++i) {
+ for (size_t j = 0; j < kChunkLength; ++j) {
ASSERT_NEAR(out_chunk[i][j], 2.0f, 1e-5f);
}
}
@@ -128,9 +128,9 @@ TEST(LappedTransformTest, Windowless) {
}
TEST(LappedTransformTest, IdentityProcessor) {
- const int kChunkLength = 512;
- const int kBlockLength = 64;
- const int kShiftAmount = 32;
+ const size_t kChunkLength = 512;
+ const size_t kBlockLength = 64;
+ const size_t kShiftAmount = 32;
NoopCallback noop;
// Identity window for |overlap = block_size / 2|.
@@ -149,7 +149,7 @@ TEST(LappedTransformTest, IdentityProcessor) {
trans.ProcessChunk(&in_chunk, &out_chunk);
- for (int i = 0; i < kChunkLength; ++i) {
+ for (size_t i = 0; i < kChunkLength; ++i) {
ASSERT_NEAR(out_chunk[i],
(i < kBlockLength - kShiftAmount) ? 0.0f : 2.0f,
1e-5f);
@@ -159,8 +159,8 @@ TEST(LappedTransformTest, IdentityProcessor) {
}
TEST(LappedTransformTest, Callbacks) {
- const int kChunkLength = 512;
- const int kBlockLength = 64;
+ const size_t kChunkLength = 512;
+ const size_t kBlockLength = 64;
FftCheckerCallback call;
// Rectangular window.
@@ -183,7 +183,7 @@ TEST(LappedTransformTest, Callbacks) {
}
TEST(LappedTransformTest, chunk_length) {
- const int kBlockLength = 64;
+ const size_t kBlockLength = 64;
FftCheckerCallback call;
const float window[kBlockLength] = {};
diff --git a/webrtc/common_audio/real_fourier.cc b/webrtc/common_audio/real_fourier.cc
index fef3c60c4c..55ec49cba2 100644
--- a/webrtc/common_audio/real_fourier.cc
+++ b/webrtc/common_audio/real_fourier.cc
@@ -19,7 +19,7 @@ namespace webrtc {
using std::complex;
-const int RealFourier::kFftBufferAlignment = 32;
+const size_t RealFourier::kFftBufferAlignment = 32;
rtc::scoped_ptr<RealFourier> RealFourier::Create(int fft_order) {
#if defined(RTC_USE_OPENMAX_DL)
diff --git a/webrtc/common_audio/real_fourier.h b/webrtc/common_audio/real_fourier.h
index ce3bbff679..0be56a58b0 100644
--- a/webrtc/common_audio/real_fourier.h
+++ b/webrtc/common_audio/real_fourier.h
@@ -30,7 +30,7 @@ class RealFourier {
fft_cplx_scoper;
// The alignment required for all input and output buffers, in bytes.
- static const int kFftBufferAlignment;
+ static const size_t kFftBufferAlignment;
// Construct a wrapper instance for the given input order, which must be
// between 1 and kMaxFftOrder, inclusively.
diff --git a/webrtc/common_audio/real_fourier_unittest.cc b/webrtc/common_audio/real_fourier_unittest.cc
index 5c8542138b..eb5880ee8a 100644
--- a/webrtc/common_audio/real_fourier_unittest.cc
+++ b/webrtc/common_audio/real_fourier_unittest.cc
@@ -26,15 +26,15 @@ TEST(RealFourierStaticsTest, AllocatorAlignment) {
RealFourier::fft_real_scoper real;
real = RealFourier::AllocRealBuffer(3);
ASSERT_TRUE(real.get() != nullptr);
- int64_t ptr_value = reinterpret_cast<int64_t>(real.get());
- EXPECT_EQ(0, ptr_value % RealFourier::kFftBufferAlignment);
+ uintptr_t ptr_value = reinterpret_cast<uintptr_t>(real.get());
+ EXPECT_EQ(0u, ptr_value % RealFourier::kFftBufferAlignment);
}
{
RealFourier::fft_cplx_scoper cplx;
cplx = RealFourier::AllocCplxBuffer(3);
ASSERT_TRUE(cplx.get() != nullptr);
- int64_t ptr_value = reinterpret_cast<int64_t>(cplx.get());
- EXPECT_EQ(0, ptr_value % RealFourier::kFftBufferAlignment);
+ uintptr_t ptr_value = reinterpret_cast<uintptr_t>(cplx.get());
+ EXPECT_EQ(0u, ptr_value % RealFourier::kFftBufferAlignment);
}
}
diff --git a/webrtc/common_audio/resampler/include/push_resampler.h b/webrtc/common_audio/resampler/include/push_resampler.h
index b5c0003615..eeda790497 100644
--- a/webrtc/common_audio/resampler/include/push_resampler.h
+++ b/webrtc/common_audio/resampler/include/push_resampler.h
@@ -29,7 +29,7 @@ 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);
+ size_t num_channels);
// Returns the total number of samples provided in destination (e.g. 32 kHz,
// 2 channel audio gives 640 samples).
@@ -40,7 +40,7 @@ class PushResampler {
rtc::scoped_ptr<PushSincResampler> sinc_resampler_right_;
int src_sample_rate_hz_;
int dst_sample_rate_hz_;
- int num_channels_;
+ size_t num_channels_;
rtc::scoped_ptr<T[]> src_left_;
rtc::scoped_ptr<T[]> src_right_;
rtc::scoped_ptr<T[]> dst_left_;
diff --git a/webrtc/common_audio/resampler/include/resampler.h b/webrtc/common_audio/resampler/include/resampler.h
index 0d4c1afe4e..e26ac904c0 100644
--- a/webrtc/common_audio/resampler/include/resampler.h
+++ b/webrtc/common_audio/resampler/include/resampler.h
@@ -28,14 +28,14 @@ class Resampler
public:
Resampler();
- Resampler(int inFreq, int outFreq, int num_channels);
+ Resampler(int inFreq, int outFreq, size_t num_channels);
~Resampler();
// Reset all states
- int Reset(int inFreq, int outFreq, int num_channels);
+ int Reset(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);
+ int ResetIfNeeded(int inFreq, int outFreq, size_t num_channels);
// Resample samplesIn to samplesOut.
int Push(const int16_t* samplesIn, size_t lengthIn, int16_t* samplesOut,
@@ -83,7 +83,7 @@ private:
int my_in_frequency_khz_;
int my_out_frequency_khz_;
ResamplerMode my_mode_;
- int num_channels_;
+ size_t num_channels_;
// Extra instance for stereo
Resampler* slave_left_;
diff --git a/webrtc/common_audio/resampler/push_resampler.cc b/webrtc/common_audio/resampler/push_resampler.cc
index 566acdeaa3..f654e9a397 100644
--- a/webrtc/common_audio/resampler/push_resampler.cc
+++ b/webrtc/common_audio/resampler/push_resampler.cc
@@ -32,7 +32,7 @@ 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) {
if (src_sample_rate_hz == src_sample_rate_hz_ &&
dst_sample_rate_hz == dst_sample_rate_hz_ &&
num_channels == num_channels_)
@@ -68,10 +68,8 @@ int PushResampler<T>::InitializeIfNeeded(int src_sample_rate_hz,
template <typename T>
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);
+ const size_t src_size_10ms = src_sample_rate_hz_ * num_channels_ / 100;
+ const size_t dst_size_10ms = dst_sample_rate_hz_ * num_channels_ / 100;
if (src_length != src_size_10ms || dst_capacity < dst_size_10ms)
return -1;
diff --git a/webrtc/common_audio/resampler/resampler.cc b/webrtc/common_audio/resampler/resampler.cc
index c9e7a1fb96..7c690fc47a 100644
--- a/webrtc/common_audio/resampler/resampler.cc
+++ b/webrtc/common_audio/resampler/resampler.cc
@@ -39,7 +39,7 @@ Resampler::Resampler()
slave_right_(nullptr) {
}
-Resampler::Resampler(int inFreq, int outFreq, int num_channels)
+Resampler::Resampler(int inFreq, int outFreq, size_t num_channels)
: Resampler() {
Reset(inFreq, outFreq, num_channels);
}
@@ -76,7 +76,7 @@ Resampler::~Resampler()
}
}
-int Resampler::ResetIfNeeded(int inFreq, int outFreq, int num_channels)
+int Resampler::ResetIfNeeded(int inFreq, int outFreq, size_t num_channels)
{
int tmpInFreq_kHz = inFreq / 1000;
int tmpOutFreq_kHz = outFreq / 1000;
@@ -91,7 +91,7 @@ int Resampler::ResetIfNeeded(int inFreq, int outFreq, int num_channels)
}
}
-int Resampler::Reset(int inFreq, int outFreq, int num_channels)
+int Resampler::Reset(int inFreq, int outFreq, size_t num_channels)
{
if (num_channels != 1 && num_channels != 2) {
return -1;
diff --git a/webrtc/common_audio/signal_processing/real_fft_unittest.cc b/webrtc/common_audio/signal_processing/real_fft_unittest.cc
index 9bd35cd68b..fa98836b9a 100644
--- a/webrtc/common_audio/signal_processing/real_fft_unittest.cc
+++ b/webrtc/common_audio/signal_processing/real_fft_unittest.cc
@@ -10,7 +10,6 @@
#include "webrtc/common_audio/signal_processing/include/real_fft.h"
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
-#include "webrtc/test/testsupport/gtest_disable.h"
#include "webrtc/typedefs.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/webrtc/common_audio/swap_queue.h b/webrtc/common_audio/swap_queue.h
new file mode 100644
index 0000000000..d8bb5c024e
--- /dev/null
+++ b/webrtc/common_audio/swap_queue.h
@@ -0,0 +1,210 @@
+/*
+ * 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_COMMON_AUDIO_SWAP_QUEUE_H_
+#define WEBRTC_COMMON_AUDIO_SWAP_QUEUE_H_
+
+#include <algorithm>
+#include <utility>
+#include <vector>
+
+#include "webrtc/base/checks.h"
+#include "webrtc/base/criticalsection.h"
+
+namespace webrtc {
+
+namespace internal {
+
+// (Internal; please don't use outside this file.)
+template <typename T>
+bool NoopSwapQueueItemVerifierFunction(const T&) {
+ return true;
+}
+
+} // namespace internal
+
+// Functor to use when supplying a verifier function for the queue.
+template <typename T,
+ bool (*QueueItemVerifierFunction)(const T&) =
+ internal::NoopSwapQueueItemVerifierFunction>
+class SwapQueueItemVerifier {
+ public:
+ bool operator()(const T& t) const { return QueueItemVerifierFunction(t); }
+};
+
+// This class is a fixed-size queue. A producer calls Insert() to insert
+// an element of type T at the back of the queue, and a consumer calls
+// Remove() to remove an element from the front of the queue. It's safe
+// for the producer(s) and the consumer(s) to access the queue
+// concurrently, from different threads.
+//
+// To avoid the construction, copying, and destruction of Ts that a naive
+// queue implementation would require, for each "full" T passed from
+// producer to consumer, SwapQueue<T> passes an "empty" T in the other
+// direction (an "empty" T is one that contains nothing of value for the
+// consumer). This bidirectional movement is implemented with swap().
+//
+// // Create queue:
+// Bottle proto(568); // Prepare an empty Bottle. Heap allocates space for
+// // 568 ml.
+// SwapQueue<Bottle> q(N, proto); // Init queue with N copies of proto.
+// // Each copy allocates on the heap.
+// // Producer pseudo-code:
+// Bottle b(568); // Prepare an empty Bottle. Heap allocates space for 568 ml.
+// loop {
+// b.Fill(amount); // Where amount <= 568 ml.
+// q.Insert(&b); // Swap our full Bottle for an empty one from q.
+// }
+//
+// // Consumer pseudo-code:
+// Bottle b(568); // Prepare an empty Bottle. Heap allocates space for 568 ml.
+// loop {
+// q.Remove(&b); // Swap our empty Bottle for the next-in-line full Bottle.
+// Drink(&b);
+// }
+//
+// For a well-behaved Bottle class, there are no allocations in the
+// producer, since it just fills an empty Bottle that's already large
+// enough; no deallocations in the consumer, since it returns each empty
+// Bottle to the queue after having drunk it; and no copies along the
+// way, since the queue uses swap() everywhere to move full Bottles in
+// one direction and empty ones in the other.
+template <typename T, typename QueueItemVerifier = SwapQueueItemVerifier<T>>
+class SwapQueue {
+ public:
+ // Creates a queue of size size and fills it with default constructed Ts.
+ explicit SwapQueue(size_t size) : queue_(size) {
+ RTC_DCHECK(VerifyQueueSlots());
+ }
+
+ // Same as above and accepts an item verification functor.
+ SwapQueue(size_t size, const QueueItemVerifier& queue_item_verifier)
+ : queue_item_verifier_(queue_item_verifier), queue_(size) {
+ RTC_DCHECK(VerifyQueueSlots());
+ }
+
+ // Creates a queue of size size and fills it with copies of prototype.
+ SwapQueue(size_t size, const T& prototype) : queue_(size, prototype) {
+ RTC_DCHECK(VerifyQueueSlots());
+ }
+
+ // Same as above and accepts an item verification functor.
+ SwapQueue(size_t size,
+ const T& prototype,
+ const QueueItemVerifier& queue_item_verifier)
+ : queue_item_verifier_(queue_item_verifier), queue_(size, prototype) {
+ RTC_DCHECK(VerifyQueueSlots());
+ }
+
+ // Resets the queue to have zero content wile maintaining the queue size.
+ void Clear() {
+ rtc::CritScope cs(&crit_queue_);
+ next_write_index_ = 0;
+ next_read_index_ = 0;
+ num_elements_ = 0;
+ }
+
+ // Inserts a "full" T at the back of the queue by swapping *input with an
+ // "empty" T from the queue.
+ // Returns true if the item was inserted or false if not (the queue was full).
+ // When specified, the T given in *input must pass the ItemVerifier() test.
+ // The contents of *input after the call are then also guaranteed to pass the
+ // ItemVerifier() test.
+ bool Insert(T* input) WARN_UNUSED_RESULT {
+ RTC_DCHECK(input);
+
+ rtc::CritScope cs(&crit_queue_);
+
+ RTC_DCHECK(queue_item_verifier_(*input));
+
+ if (num_elements_ == queue_.size()) {
+ return false;
+ }
+
+ using std::swap;
+ swap(*input, queue_[next_write_index_]);
+
+ ++next_write_index_;
+ if (next_write_index_ == queue_.size()) {
+ next_write_index_ = 0;
+ }
+
+ ++num_elements_;
+
+ RTC_DCHECK_LT(next_write_index_, queue_.size());
+ RTC_DCHECK_LE(num_elements_, queue_.size());
+
+ return true;
+ }
+
+ // Removes the frontmost "full" T from the queue by swapping it with
+ // the "empty" T in *output.
+ // Returns true if an item could be removed or false if not (the queue was
+ // empty). When specified, The T given in *output must pass the ItemVerifier()
+ // test and the contents of *output after the call are then also guaranteed to
+ // pass the ItemVerifier() test.
+ bool Remove(T* output) WARN_UNUSED_RESULT {
+ RTC_DCHECK(output);
+
+ rtc::CritScope cs(&crit_queue_);
+
+ RTC_DCHECK(queue_item_verifier_(*output));
+
+ if (num_elements_ == 0) {
+ return false;
+ }
+
+ using std::swap;
+ swap(*output, queue_[next_read_index_]);
+
+ ++next_read_index_;
+ if (next_read_index_ == queue_.size()) {
+ next_read_index_ = 0;
+ }
+
+ --num_elements_;
+
+ RTC_DCHECK_LT(next_read_index_, queue_.size());
+ RTC_DCHECK_LE(num_elements_, queue_.size());
+
+ return true;
+ }
+
+ private:
+ // Verify that the queue slots complies with the ItemVerifier test.
+ bool VerifyQueueSlots() {
+ rtc::CritScope cs(&crit_queue_);
+ for (const auto& v : queue_) {
+ RTC_DCHECK(queue_item_verifier_(v));
+ }
+ return true;
+ }
+
+ rtc::CriticalSection crit_queue_;
+
+ // TODO(peah): Change this to use std::function() once we can use C++11 std
+ // lib.
+ QueueItemVerifier queue_item_verifier_ GUARDED_BY(crit_queue_);
+
+ // (next_read_index_ + num_elements_) % queue_.size() =
+ // next_write_index_
+ size_t next_write_index_ GUARDED_BY(crit_queue_) = 0;
+ size_t next_read_index_ GUARDED_BY(crit_queue_) = 0;
+ size_t num_elements_ GUARDED_BY(crit_queue_) = 0;
+
+ // queue_.size() is constant.
+ std::vector<T> queue_ GUARDED_BY(crit_queue_);
+
+ RTC_DISALLOW_COPY_AND_ASSIGN(SwapQueue);
+};
+
+} // namespace webrtc
+
+#endif // WEBRTC_COMMON_AUDIO_SWAP_QUEUE_H_
diff --git a/webrtc/common_audio/swap_queue_unittest.cc b/webrtc/common_audio/swap_queue_unittest.cc
new file mode 100644
index 0000000000..104e494bc6
--- /dev/null
+++ b/webrtc/common_audio/swap_queue_unittest.cc
@@ -0,0 +1,225 @@
+/*
+ * 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.
+ */
+
+#include "webrtc/common_audio/swap_queue.h"
+
+#include <vector>
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace webrtc {
+
+namespace {
+
+// Test parameter for the basic sample based SwapQueue Tests.
+const size_t kChunkSize = 3;
+
+// Queue item verification function for the vector test.
+bool LengthVerifierFunction(const std::vector<int>& v) {
+ return v.size() == kChunkSize;
+}
+
+// Queue item verifier for the vector test.
+class LengthVerifierFunctor {
+ public:
+ explicit LengthVerifierFunctor(size_t length) : length_(length) {}
+
+ bool operator()(const std::vector<int>& v) const {
+ return v.size() == length_;
+ }
+
+ private:
+ size_t length_;
+};
+
+} // anonymous namespace
+
+TEST(SwapQueueTest, BasicOperation) {
+ std::vector<int> i(kChunkSize, 0);
+ SwapQueue<std::vector<int>> queue(2, i);
+
+ EXPECT_TRUE(queue.Insert(&i));
+ EXPECT_EQ(i.size(), kChunkSize);
+ EXPECT_TRUE(queue.Insert(&i));
+ EXPECT_EQ(i.size(), kChunkSize);
+ EXPECT_TRUE(queue.Remove(&i));
+ EXPECT_EQ(i.size(), kChunkSize);
+ EXPECT_TRUE(queue.Remove(&i));
+ EXPECT_EQ(i.size(), kChunkSize);
+}
+
+TEST(SwapQueueTest, FullQueue) {
+ SwapQueue<int> queue(2);
+
+ // Fill the queue.
+ int i = 0;
+ EXPECT_TRUE(queue.Insert(&i));
+ i = 1;
+ EXPECT_TRUE(queue.Insert(&i));
+
+ // Ensure that the value is not swapped when doing an Insert
+ // on a full queue.
+ i = 2;
+ EXPECT_FALSE(queue.Insert(&i));
+ EXPECT_EQ(i, 2);
+
+ // Ensure that the Insert didn't overwrite anything in the queue.
+ EXPECT_TRUE(queue.Remove(&i));
+ EXPECT_EQ(i, 0);
+ EXPECT_TRUE(queue.Remove(&i));
+ EXPECT_EQ(i, 1);
+}
+
+TEST(SwapQueueTest, EmptyQueue) {
+ SwapQueue<int> queue(2);
+ int i = 0;
+ EXPECT_FALSE(queue.Remove(&i));
+ EXPECT_TRUE(queue.Insert(&i));
+ EXPECT_TRUE(queue.Remove(&i));
+ EXPECT_FALSE(queue.Remove(&i));
+}
+
+TEST(SwapQueueTest, Clear) {
+ SwapQueue<int> queue(2);
+ int i = 0;
+
+ // Fill the queue.
+ EXPECT_TRUE(queue.Insert(&i));
+ EXPECT_TRUE(queue.Insert(&i));
+
+ // Ensure full queue.
+ EXPECT_FALSE(queue.Insert(&i));
+
+ // Empty the queue.
+ queue.Clear();
+
+ // Ensure that the queue is empty
+ EXPECT_FALSE(queue.Remove(&i));
+
+ // Ensure that the queue is no longer full.
+ EXPECT_TRUE(queue.Insert(&i));
+}
+
+TEST(SwapQueueTest, SuccessfulItemVerifyFunction) {
+ std::vector<int> template_element(kChunkSize);
+ SwapQueue<std::vector<int>,
+ SwapQueueItemVerifier<std::vector<int>, LengthVerifierFunction>>
+ queue(2, template_element);
+ std::vector<int> valid_chunk(kChunkSize, 0);
+
+ EXPECT_TRUE(queue.Insert(&valid_chunk));
+ EXPECT_EQ(valid_chunk.size(), kChunkSize);
+ EXPECT_TRUE(queue.Remove(&valid_chunk));
+ EXPECT_EQ(valid_chunk.size(), kChunkSize);
+}
+
+TEST(SwapQueueTest, SuccessfulItemVerifyFunctor) {
+ std::vector<int> template_element(kChunkSize);
+ LengthVerifierFunctor verifier(kChunkSize);
+ SwapQueue<std::vector<int>, LengthVerifierFunctor> queue(2, template_element,
+ verifier);
+ std::vector<int> valid_chunk(kChunkSize, 0);
+
+ EXPECT_TRUE(queue.Insert(&valid_chunk));
+ EXPECT_EQ(valid_chunk.size(), kChunkSize);
+ EXPECT_TRUE(queue.Remove(&valid_chunk));
+ EXPECT_EQ(valid_chunk.size(), kChunkSize);
+}
+
+#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
+TEST(SwapQueueTest, UnsuccessfulItemVerifyFunctor) {
+ // Queue item verifier for the test.
+ auto minus_2_verifier = [](const int& i) { return i > -2; };
+ SwapQueue<int, decltype(minus_2_verifier)> queue(2, minus_2_verifier);
+
+ int valid_value = 1;
+ int invalid_value = -4;
+ EXPECT_TRUE(queue.Insert(&valid_value));
+ EXPECT_TRUE(queue.Remove(&valid_value));
+ bool result;
+ EXPECT_DEATH(result = queue.Insert(&invalid_value), "");
+}
+
+TEST(SwapQueueTest, UnSuccessfulItemVerifyInsert) {
+ std::vector<int> template_element(kChunkSize);
+ SwapQueue<std::vector<int>,
+ SwapQueueItemVerifier<std::vector<int>, &LengthVerifierFunction>>
+ queue(2, template_element);
+ std::vector<int> invalid_chunk(kChunkSize - 1, 0);
+ bool result;
+ EXPECT_DEATH(result = queue.Insert(&invalid_chunk), "");
+}
+
+TEST(SwapQueueTest, UnSuccessfulItemVerifyRemove) {
+ std::vector<int> template_element(kChunkSize);
+ SwapQueue<std::vector<int>,
+ SwapQueueItemVerifier<std::vector<int>, &LengthVerifierFunction>>
+ queue(2, template_element);
+ std::vector<int> invalid_chunk(kChunkSize - 1, 0);
+ std::vector<int> valid_chunk(kChunkSize, 0);
+ EXPECT_TRUE(queue.Insert(&valid_chunk));
+ EXPECT_EQ(valid_chunk.size(), kChunkSize);
+ bool result;
+ EXPECT_DEATH(result = queue.Remove(&invalid_chunk), "");
+}
+#endif
+
+TEST(SwapQueueTest, VectorContentTest) {
+ const size_t kQueueSize = 10;
+ const size_t kFrameLength = 160;
+ const size_t kDataLength = kQueueSize * kFrameLength;
+ std::vector<int16_t> buffer_reader(kFrameLength, 0);
+ std::vector<int16_t> buffer_writer(kFrameLength, 0);
+ SwapQueue<std::vector<int16_t>> queue(kQueueSize,
+ std::vector<int16_t>(kFrameLength));
+ std::vector<int16_t> samples(kDataLength);
+
+ for (size_t k = 0; k < kDataLength; k++) {
+ samples[k] = k % 9;
+ }
+
+ for (size_t k = 0; k < kQueueSize; k++) {
+ buffer_writer.clear();
+ buffer_writer.insert(buffer_writer.end(), &samples[0] + k * kFrameLength,
+ &samples[0] + (k + 1) * kFrameLength);
+
+ EXPECT_TRUE(queue.Insert(&buffer_writer));
+ }
+
+ for (size_t k = 0; k < kQueueSize; k++) {
+ EXPECT_TRUE(queue.Remove(&buffer_reader));
+
+ for (size_t j = 0; j < buffer_reader.size(); j++) {
+ EXPECT_EQ(buffer_reader[j], samples[k * kFrameLength + j]);
+ }
+ }
+}
+
+TEST(SwapQueueTest, ZeroSlotQueue) {
+ SwapQueue<int> queue(0);
+ int i = 42;
+ EXPECT_FALSE(queue.Insert(&i));
+ EXPECT_FALSE(queue.Remove(&i));
+ EXPECT_EQ(i, 42);
+}
+
+TEST(SwapQueueTest, OneSlotQueue) {
+ SwapQueue<int> queue(1);
+ int i = 42;
+ EXPECT_TRUE(queue.Insert(&i));
+ i = 43;
+ EXPECT_FALSE(queue.Insert(&i));
+ EXPECT_EQ(i, 43);
+ EXPECT_TRUE(queue.Remove(&i));
+ EXPECT_EQ(i, 42);
+ EXPECT_FALSE(queue.Remove(&i));
+}
+
+} // namespace webrtc
diff --git a/webrtc/common_audio/wav_file.cc b/webrtc/common_audio/wav_file.cc
index 8dae7d6e98..94b7a3c2c0 100644
--- a/webrtc/common_audio/wav_file.cc
+++ b/webrtc/common_audio/wav_file.cc
@@ -13,6 +13,7 @@
#include <algorithm>
#include <cstdio>
#include <limits>
+#include <sstream>
#include "webrtc/base/checks.h"
#include "webrtc/base/safe_conversions.h"
@@ -23,7 +24,7 @@ namespace webrtc {
// We write 16-bit PCM WAV files.
static const WavFormat kWavFormat = kWavFormatPcm;
-static const int kBytesPerSample = 2;
+static const size_t kBytesPerSample = 2;
// Doesn't take ownership of the file handle and won't close it.
class ReadableWavFile : public ReadableWav {
@@ -37,13 +38,21 @@ class ReadableWavFile : public ReadableWav {
FILE* file_;
};
+std::string WavFile::FormatAsString() const {
+ std::ostringstream s;
+ s << "Sample rate: " << sample_rate() << " Hz, Channels: " << num_channels()
+ << ", Duration: "
+ << (1.f * num_samples()) / (num_channels() * sample_rate()) << " s";
+ return s.str();
+}
+
WavReader::WavReader(const std::string& filename)
: file_handle_(fopen(filename.c_str(), "rb")) {
- RTC_CHECK(file_handle_ && "Could not open wav file for reading.");
+ RTC_CHECK(file_handle_) << "Could not open wav file for reading.";
ReadableWavFile readable(file_handle_);
WavFormat format;
- int bytes_per_sample;
+ size_t bytes_per_sample;
RTC_CHECK(ReadWavHeader(&readable, &num_channels_, &sample_rate_, &format,
&bytes_per_sample, &num_samples_));
num_samples_remaining_ = num_samples_;
@@ -60,14 +69,13 @@ size_t WavReader::ReadSamples(size_t num_samples, int16_t* samples) {
#error "Need to convert samples to big-endian when reading from WAV file"
#endif
// There could be metadata after the audio; ensure we don't read it.
- num_samples = std::min(rtc::checked_cast<uint32_t>(num_samples),
- num_samples_remaining_);
+ num_samples = std::min(num_samples, num_samples_remaining_);
const size_t read =
fread(samples, sizeof(*samples), num_samples, file_handle_);
// If we didn't read what was requested, ensure we've reached the EOF.
RTC_CHECK(read == num_samples || feof(file_handle_));
RTC_CHECK_LE(read, num_samples_remaining_);
- num_samples_remaining_ -= rtc::checked_cast<uint32_t>(read);
+ num_samples_remaining_ -= read;
return read;
}
@@ -91,12 +99,12 @@ void WavReader::Close() {
}
WavWriter::WavWriter(const std::string& filename, int sample_rate,
- int num_channels)
+ size_t num_channels)
: sample_rate_(sample_rate),
num_channels_(num_channels),
num_samples_(0),
file_handle_(fopen(filename.c_str(), "wb")) {
- RTC_CHECK(file_handle_ && "Could not open wav file for writing.");
+ RTC_CHECK(file_handle_) << "Could not open wav file for writing.";
RTC_CHECK(CheckWavParameters(num_channels_, sample_rate_, kWavFormat,
kBytesPerSample, num_samples_));
@@ -117,9 +125,8 @@ void WavWriter::WriteSamples(const int16_t* samples, size_t num_samples) {
const size_t written =
fwrite(samples, sizeof(*samples), num_samples, file_handle_);
RTC_CHECK_EQ(num_samples, written);
- num_samples_ += static_cast<uint32_t>(written);
- RTC_CHECK(written <= std::numeric_limits<uint32_t>::max() ||
- num_samples_ >= written); // detect uint32_t overflow
+ num_samples_ += written;
+ RTC_CHECK(num_samples_ >= written); // detect size_t overflow
}
void WavWriter::WriteSamples(const float* samples, size_t num_samples) {
@@ -146,7 +153,7 @@ void WavWriter::Close() {
rtc_WavWriter* rtc_WavOpen(const char* filename,
int sample_rate,
- int num_channels) {
+ size_t num_channels) {
return reinterpret_cast<rtc_WavWriter*>(
new webrtc::WavWriter(filename, sample_rate, num_channels));
}
@@ -165,10 +172,10 @@ int rtc_WavSampleRate(const rtc_WavWriter* wf) {
return reinterpret_cast<const webrtc::WavWriter*>(wf)->sample_rate();
}
-int rtc_WavNumChannels(const rtc_WavWriter* wf) {
+size_t rtc_WavNumChannels(const rtc_WavWriter* wf) {
return reinterpret_cast<const webrtc::WavWriter*>(wf)->num_channels();
}
-uint32_t rtc_WavNumSamples(const rtc_WavWriter* wf) {
+size_t rtc_WavNumSamples(const rtc_WavWriter* wf) {
return reinterpret_cast<const webrtc::WavWriter*>(wf)->num_samples();
}
diff --git a/webrtc/common_audio/wav_file.h b/webrtc/common_audio/wav_file.h
index 2eadd3f775..e656eb8643 100644
--- a/webrtc/common_audio/wav_file.h
+++ b/webrtc/common_audio/wav_file.h
@@ -27,8 +27,11 @@ class WavFile {
virtual ~WavFile() {}
virtual int sample_rate() const = 0;
- virtual int num_channels() const = 0;
- virtual uint32_t num_samples() const = 0;
+ virtual size_t num_channels() const = 0;
+ virtual size_t num_samples() const = 0;
+
+ // Returns a human-readable string containing the audio format.
+ std::string FormatAsString() const;
};
// Simple C++ class for writing 16-bit PCM WAV files. All error handling is
@@ -36,7 +39,7 @@ class WavFile {
class WavWriter final : public WavFile {
public:
// Open a new WAV file for writing.
- WavWriter(const std::string& filename, int sample_rate, int num_channels);
+ WavWriter(const std::string& filename, int sample_rate, size_t num_channels);
// Close the WAV file, after writing its header.
~WavWriter();
@@ -48,14 +51,14 @@ class WavWriter final : public WavFile {
void WriteSamples(const int16_t* samples, size_t num_samples);
int sample_rate() const override { return sample_rate_; }
- int num_channels() const override { return num_channels_; }
- uint32_t num_samples() const override { return num_samples_; }
+ size_t num_channels() const override { return num_channels_; }
+ size_t num_samples() const override { return num_samples_; }
private:
void Close();
const int sample_rate_;
- const int num_channels_;
- uint32_t num_samples_; // Total number of samples written to file.
+ const size_t num_channels_;
+ size_t num_samples_; // Total number of samples written to file.
FILE* file_handle_; // Output file, owned by this class
RTC_DISALLOW_COPY_AND_ASSIGN(WavWriter);
@@ -76,15 +79,15 @@ class WavReader final : public WavFile {
size_t ReadSamples(size_t num_samples, int16_t* samples);
int sample_rate() const override { return sample_rate_; }
- int num_channels() const override { return num_channels_; }
- uint32_t num_samples() const override { return num_samples_; }
+ size_t num_channels() const override { return num_channels_; }
+ size_t num_samples() const override { return num_samples_; }
private:
void Close();
int sample_rate_;
- int num_channels_;
- uint32_t num_samples_; // Total number of samples in the file.
- uint32_t num_samples_remaining_;
+ size_t num_channels_;
+ size_t num_samples_; // Total number of samples in the file.
+ size_t num_samples_remaining_;
FILE* file_handle_; // Input file, owned by this class.
RTC_DISALLOW_COPY_AND_ASSIGN(WavReader);
@@ -99,14 +102,14 @@ extern "C" {
typedef struct rtc_WavWriter rtc_WavWriter;
rtc_WavWriter* rtc_WavOpen(const char* filename,
int sample_rate,
- int num_channels);
+ size_t num_channels);
void rtc_WavClose(rtc_WavWriter* wf);
void rtc_WavWriteSamples(rtc_WavWriter* wf,
const float* samples,
size_t num_samples);
int rtc_WavSampleRate(const rtc_WavWriter* wf);
-int rtc_WavNumChannels(const rtc_WavWriter* wf);
-uint32_t rtc_WavNumSamples(const rtc_WavWriter* wf);
+size_t rtc_WavNumChannels(const rtc_WavWriter* wf);
+size_t rtc_WavNumSamples(const rtc_WavWriter* wf);
#ifdef __cplusplus
} // extern "C"
diff --git a/webrtc/common_audio/wav_file_unittest.cc b/webrtc/common_audio/wav_file_unittest.cc
index 78b0a34de9..ba1db1c296 100644
--- a/webrtc/common_audio/wav_file_unittest.cc
+++ b/webrtc/common_audio/wav_file_unittest.cc
@@ -26,11 +26,11 @@ static const float kSamples[] = {0.0, 10.0, 4e4, -1e9};
// Write a tiny WAV file with the C++ interface and verify the result.
TEST(WavWriterTest, CPP) {
const std::string outfile = test::OutputPath() + "wavtest1.wav";
- static const uint32_t kNumSamples = 3;
+ static const size_t kNumSamples = 3;
{
WavWriter w(outfile, 14099, 1);
EXPECT_EQ(14099, w.sample_rate());
- EXPECT_EQ(1, w.num_channels());
+ EXPECT_EQ(1u, w.num_channels());
EXPECT_EQ(0u, w.num_samples());
w.WriteSamples(kSamples, kNumSamples);
EXPECT_EQ(kNumSamples, w.num_samples());
@@ -64,10 +64,10 @@ TEST(WavWriterTest, CPP) {
0xff, 0x7f, // third sample: 4e4 (saturated)
kMetadata[0], kMetadata[1],
};
- static const int kContentSize =
+ static const size_t kContentSize =
kWavHeaderSize + kNumSamples * sizeof(int16_t) + sizeof(kMetadata);
static_assert(sizeof(kExpectedContents) == kContentSize, "content size");
- EXPECT_EQ(size_t(kContentSize), test::GetFileSize(outfile));
+ EXPECT_EQ(kContentSize, test::GetFileSize(outfile));
FILE* f = fopen(outfile.c_str(), "rb");
ASSERT_TRUE(f);
uint8_t contents[kContentSize];
@@ -78,7 +78,7 @@ TEST(WavWriterTest, CPP) {
{
WavReader r(outfile);
EXPECT_EQ(14099, r.sample_rate());
- EXPECT_EQ(1, r.num_channels());
+ EXPECT_EQ(1u, r.num_channels());
EXPECT_EQ(kNumSamples, r.num_samples());
static const float kTruncatedSamples[] = {0.0, 10.0, 32767.0};
float samples[kNumSamples];
@@ -93,9 +93,9 @@ TEST(WavWriterTest, C) {
const std::string outfile = test::OutputPath() + "wavtest2.wav";
rtc_WavWriter* w = rtc_WavOpen(outfile.c_str(), 11904, 2);
EXPECT_EQ(11904, rtc_WavSampleRate(w));
- EXPECT_EQ(2, rtc_WavNumChannels(w));
+ EXPECT_EQ(2u, rtc_WavNumChannels(w));
EXPECT_EQ(0u, rtc_WavNumSamples(w));
- static const uint32_t kNumSamples = 4;
+ static const size_t kNumSamples = 4;
rtc_WavWriteSamples(w, &kSamples[0], 2);
EXPECT_EQ(2u, rtc_WavNumSamples(w));
rtc_WavWriteSamples(w, &kSamples[2], kNumSamples - 2);
@@ -120,10 +120,10 @@ TEST(WavWriterTest, C) {
0xff, 0x7f, // third sample: 4e4 (saturated)
0, 0x80, // fourth sample: -1e9 (saturated)
};
- static const int kContentSize =
+ static const size_t kContentSize =
kWavHeaderSize + kNumSamples * sizeof(int16_t);
static_assert(sizeof(kExpectedContents) == kContentSize, "content size");
- EXPECT_EQ(size_t(kContentSize), test::GetFileSize(outfile));
+ EXPECT_EQ(kContentSize, test::GetFileSize(outfile));
FILE* f = fopen(outfile.c_str(), "rb");
ASSERT_TRUE(f);
uint8_t contents[kContentSize];
@@ -136,10 +136,10 @@ TEST(WavWriterTest, C) {
TEST(WavWriterTest, LargeFile) {
std::string outfile = test::OutputPath() + "wavtest3.wav";
static const int kSampleRate = 8000;
- static const int kNumChannels = 2;
- static const uint32_t kNumSamples = 3 * kSampleRate * kNumChannels;
+ static const size_t kNumChannels = 2;
+ static const size_t kNumSamples = 3 * kSampleRate * kNumChannels;
float samples[kNumSamples];
- for (uint32_t i = 0; i < kNumSamples; i += kNumChannels) {
+ for (size_t i = 0; i < kNumSamples; i += kNumChannels) {
// A nice periodic beeping sound.
static const double kToneHz = 440;
const double t = static_cast<double>(i) / (kNumChannels * kSampleRate);
diff --git a/webrtc/common_audio/wav_header.cc b/webrtc/common_audio/wav_header.cc
index 61cfffe62c..402ea17916 100644
--- a/webrtc/common_audio/wav_header.cc
+++ b/webrtc/common_audio/wav_header.cc
@@ -59,20 +59,19 @@ static_assert(sizeof(WavHeader) == kWavHeaderSize, "no padding in header");
} // namespace
-bool CheckWavParameters(int num_channels,
+bool CheckWavParameters(size_t num_channels,
int sample_rate,
WavFormat format,
- int bytes_per_sample,
- uint32_t num_samples) {
+ size_t bytes_per_sample,
+ size_t num_samples) {
// num_channels, sample_rate, and bytes_per_sample must be positive, must fit
// in their respective fields, and their product must fit in the 32-bit
// ByteRate field.
- if (num_channels <= 0 || sample_rate <= 0 || bytes_per_sample <= 0)
+ if (num_channels == 0 || sample_rate <= 0 || bytes_per_sample == 0)
return false;
if (static_cast<uint64_t>(sample_rate) > std::numeric_limits<uint32_t>::max())
return false;
- if (static_cast<uint64_t>(num_channels) >
- std::numeric_limits<uint16_t>::max())
+ if (num_channels > std::numeric_limits<uint16_t>::max())
return false;
if (static_cast<uint64_t>(bytes_per_sample) * 8 >
std::numeric_limits<uint16_t>::max())
@@ -99,10 +98,9 @@ bool CheckWavParameters(int num_channels,
// The number of bytes in the file, not counting the first ChunkHeader, must
// be less than 2^32; otherwise, the ChunkSize field overflows.
- const uint32_t max_samples =
- (std::numeric_limits<uint32_t>::max()
- - (kWavHeaderSize - sizeof(ChunkHeader))) /
- bytes_per_sample;
+ const size_t header_size = kWavHeaderSize - sizeof(ChunkHeader);
+ const size_t max_samples =
+ (std::numeric_limits<uint32_t>::max() - header_size) / bytes_per_sample;
if (num_samples > max_samples)
return false;
@@ -132,30 +130,32 @@ static inline std::string ReadFourCC(uint32_t x) {
#error "Write be-to-le conversion functions"
#endif
-static inline uint32_t RiffChunkSize(uint32_t bytes_in_payload) {
- return bytes_in_payload + kWavHeaderSize - sizeof(ChunkHeader);
+static inline uint32_t RiffChunkSize(size_t bytes_in_payload) {
+ return static_cast<uint32_t>(
+ bytes_in_payload + kWavHeaderSize - sizeof(ChunkHeader));
}
-static inline uint32_t ByteRate(int num_channels, int sample_rate,
- int bytes_per_sample) {
- return static_cast<uint32_t>(num_channels) * sample_rate * bytes_per_sample;
+static inline uint32_t ByteRate(size_t num_channels, int sample_rate,
+ size_t bytes_per_sample) {
+ return static_cast<uint32_t>(num_channels * sample_rate * bytes_per_sample);
}
-static inline uint16_t BlockAlign(int num_channels, int bytes_per_sample) {
- return num_channels * bytes_per_sample;
+static inline uint16_t BlockAlign(size_t num_channels,
+ size_t bytes_per_sample) {
+ return static_cast<uint16_t>(num_channels * bytes_per_sample);
}
void WriteWavHeader(uint8_t* buf,
- int num_channels,
+ size_t num_channels,
int sample_rate,
WavFormat format,
- int bytes_per_sample,
- uint32_t num_samples) {
+ size_t bytes_per_sample,
+ size_t num_samples) {
RTC_CHECK(CheckWavParameters(num_channels, sample_rate, format,
bytes_per_sample, num_samples));
WavHeader header;
- const uint32_t bytes_in_payload = bytes_per_sample * num_samples;
+ const size_t bytes_in_payload = bytes_per_sample * num_samples;
WriteFourCC(&header.riff.header.ID, 'R', 'I', 'F', 'F');
WriteLE32(&header.riff.header.Size, RiffChunkSize(bytes_in_payload));
@@ -164,15 +164,16 @@ void WriteWavHeader(uint8_t* buf,
WriteFourCC(&header.fmt.header.ID, 'f', 'm', 't', ' ');
WriteLE32(&header.fmt.header.Size, kFmtSubchunkSize);
WriteLE16(&header.fmt.AudioFormat, format);
- WriteLE16(&header.fmt.NumChannels, num_channels);
+ WriteLE16(&header.fmt.NumChannels, static_cast<uint16_t>(num_channels));
WriteLE32(&header.fmt.SampleRate, sample_rate);
WriteLE32(&header.fmt.ByteRate, ByteRate(num_channels, sample_rate,
bytes_per_sample));
WriteLE16(&header.fmt.BlockAlign, BlockAlign(num_channels, bytes_per_sample));
- WriteLE16(&header.fmt.BitsPerSample, 8 * bytes_per_sample);
+ WriteLE16(&header.fmt.BitsPerSample,
+ static_cast<uint16_t>(8 * bytes_per_sample));
WriteFourCC(&header.data.header.ID, 'd', 'a', 't', 'a');
- WriteLE32(&header.data.header.Size, bytes_in_payload);
+ WriteLE32(&header.data.header.Size, static_cast<uint32_t>(bytes_in_payload));
// Do an extra copy rather than writing everything to buf directly, since buf
// might not be correctly aligned.
@@ -180,11 +181,11 @@ void WriteWavHeader(uint8_t* buf,
}
bool ReadWavHeader(ReadableWav* readable,
- int* num_channels,
+ size_t* num_channels,
int* sample_rate,
WavFormat* format,
- int* bytes_per_sample,
- uint32_t* num_samples) {
+ size_t* bytes_per_sample,
+ size_t* num_samples) {
WavHeader header;
if (readable->Read(&header, kWavHeaderSize - sizeof(header.data)) !=
kWavHeaderSize - sizeof(header.data))
@@ -210,8 +211,8 @@ bool ReadWavHeader(ReadableWav* readable,
*num_channels = ReadLE16(header.fmt.NumChannels);
*sample_rate = ReadLE32(header.fmt.SampleRate);
*bytes_per_sample = ReadLE16(header.fmt.BitsPerSample) / 8;
- const uint32_t bytes_in_payload = ReadLE32(header.data.header.Size);
- if (*bytes_per_sample <= 0)
+ const size_t bytes_in_payload = ReadLE32(header.data.header.Size);
+ if (*bytes_per_sample == 0)
return false;
*num_samples = bytes_in_payload / *bytes_per_sample;
diff --git a/webrtc/common_audio/wav_header.h b/webrtc/common_audio/wav_header.h
index 1a0fd7c81d..6844306941 100644
--- a/webrtc/common_audio/wav_header.h
+++ b/webrtc/common_audio/wav_header.h
@@ -32,32 +32,32 @@ enum WavFormat {
};
// Return true if the given parameters will make a well-formed WAV header.
-bool CheckWavParameters(int num_channels,
+bool CheckWavParameters(size_t num_channels,
int sample_rate,
WavFormat format,
- int bytes_per_sample,
- uint32_t num_samples);
+ size_t bytes_per_sample,
+ size_t num_samples);
// Write a kWavHeaderSize bytes long WAV header to buf. The payload that
// follows the header is supposed to have the specified number of interleaved
// channels and contain the specified total number of samples of the specified
// type. CHECKs the input parameters for validity.
void WriteWavHeader(uint8_t* buf,
- int num_channels,
+ size_t num_channels,
int sample_rate,
WavFormat format,
- int bytes_per_sample,
- uint32_t num_samples);
+ size_t bytes_per_sample,
+ size_t num_samples);
// Read a WAV header from an implemented ReadableWav and parse the values into
// the provided output parameters. ReadableWav is used because the header can
// be variably sized. Returns false if the header is invalid.
bool ReadWavHeader(ReadableWav* readable,
- int* num_channels,
+ size_t* num_channels,
int* sample_rate,
WavFormat* format,
- int* bytes_per_sample,
- uint32_t* num_samples);
+ size_t* bytes_per_sample,
+ size_t* num_samples);
} // namespace webrtc
diff --git a/webrtc/common_audio/wav_header_unittest.cc b/webrtc/common_audio/wav_header_unittest.cc
index e03cb303aa..8527939eac 100644
--- a/webrtc/common_audio/wav_header_unittest.cc
+++ b/webrtc/common_audio/wav_header_unittest.cc
@@ -70,7 +70,7 @@ TEST(WavHeaderTest, CheckWavParameters) {
// Try some really stupid values for one parameter at a time.
EXPECT_TRUE(CheckWavParameters(1, 8000, kWavFormatPcm, 1, 0));
EXPECT_FALSE(CheckWavParameters(0, 8000, kWavFormatPcm, 1, 0));
- EXPECT_FALSE(CheckWavParameters(-1, 8000, kWavFormatPcm, 1, 0));
+ EXPECT_FALSE(CheckWavParameters(0x10000, 8000, kWavFormatPcm, 1, 0));
EXPECT_FALSE(CheckWavParameters(1, 0, kWavFormatPcm, 1, 0));
EXPECT_FALSE(CheckWavParameters(1, 8000, WavFormat(0), 1, 0));
EXPECT_FALSE(CheckWavParameters(1, 8000, kWavFormatPcm, 0, 0));
@@ -91,11 +91,11 @@ TEST(WavHeaderTest, CheckWavParameters) {
}
TEST(WavHeaderTest, ReadWavHeaderWithErrors) {
- int num_channels = 0;
+ size_t num_channels = 0;
int sample_rate = 0;
WavFormat format = kWavFormatPcm;
- int bytes_per_sample = 0;
- uint32_t num_samples = 0;
+ size_t bytes_per_sample = 0;
+ size_t num_samples = 0;
// Test a few ways the header can be invalid. We start with the valid header
// used in WriteAndReadWavHeader, and invalidate one field per test. The
@@ -268,19 +268,19 @@ TEST(WavHeaderTest, WriteAndReadWavHeader) {
static_assert(sizeof(kExpectedBuf) == kSize, "buffer size");
EXPECT_EQ(0, memcmp(kExpectedBuf, buf, kSize));
- int num_channels = 0;
+ size_t num_channels = 0;
int sample_rate = 0;
WavFormat format = kWavFormatPcm;
- int bytes_per_sample = 0;
- uint32_t num_samples = 0;
+ size_t bytes_per_sample = 0;
+ size_t num_samples = 0;
ReadableWavBuffer r(buf + 4, sizeof(buf) - 8);
EXPECT_TRUE(
ReadWavHeader(&r, &num_channels, &sample_rate, &format,
&bytes_per_sample, &num_samples));
- EXPECT_EQ(17, num_channels);
+ EXPECT_EQ(17u, num_channels);
EXPECT_EQ(12345, sample_rate);
EXPECT_EQ(kWavFormatALaw, format);
- EXPECT_EQ(1, bytes_per_sample);
+ EXPECT_EQ(1u, bytes_per_sample);
EXPECT_EQ(123457689u, num_samples);
}
@@ -304,19 +304,19 @@ TEST(WavHeaderTest, ReadAtypicalWavHeader) {
0x99, 0xd0, 0x5b, 0x07, // size of payload: 123457689
};
- int num_channels = 0;
+ size_t num_channels = 0;
int sample_rate = 0;
WavFormat format = kWavFormatPcm;
- int bytes_per_sample = 0;
- uint32_t num_samples = 0;
+ size_t bytes_per_sample = 0;
+ size_t num_samples = 0;
ReadableWavBuffer r(kBuf, sizeof(kBuf));
EXPECT_TRUE(
ReadWavHeader(&r, &num_channels, &sample_rate, &format,
&bytes_per_sample, &num_samples));
- EXPECT_EQ(17, num_channels);
+ EXPECT_EQ(17u, num_channels);
EXPECT_EQ(12345, sample_rate);
EXPECT_EQ(kWavFormatALaw, format);
- EXPECT_EQ(1, bytes_per_sample);
+ EXPECT_EQ(1u, bytes_per_sample);
EXPECT_EQ(123457689u, num_samples);
}