Skip to content

Commit 8839fd6

Browse files
Optimize minimum delay in blocker
Could not hear any difference when running the beamformer_test, although sample-wise it changes because of the non-linear character of the processing. [email protected] Review URL: https://webrtc-codereview.appspot.com/35679004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@8051 4adac7df-926f-26a2-2b94-8c16560cd09d
1 parent 6207f08 commit 8839fd6

File tree

4 files changed

+120
-25
lines changed

4 files changed

+120
-25
lines changed

webrtc/common_audio/blocker.cc

+11-1
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,16 @@ void ApplyWindow(const float* window,
8383
}
8484
}
8585

86+
int gcd(int a, int b) {
87+
int tmp;
88+
while (b) {
89+
tmp = a;
90+
a = b;
91+
b = tmp % b;
92+
}
93+
return a;
94+
}
95+
8696
} // namespace
8797

8898
namespace webrtc {
@@ -98,7 +108,7 @@ Blocker::Blocker(int chunk_size,
98108
block_size_(block_size),
99109
num_input_channels_(num_input_channels),
100110
num_output_channels_(num_output_channels),
101-
initial_delay_(block_size_),
111+
initial_delay_(block_size_ - gcd(chunk_size, shift_amount)),
102112
frame_offset_(0),
103113
input_buffer_(chunk_size_ + initial_delay_, num_input_channels_),
104114
output_buffer_(chunk_size_ + initial_delay_, num_output_channels_),

webrtc/common_audio/blocker.h

-2
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,6 @@ class Blocker {
8080
const int num_output_channels_;
8181

8282
// The number of frames of delay to add at the beginning of the first chunk.
83-
//
84-
// TODO(claguna): find a lower cap for this than |block_size_|.
8583
const int initial_delay_;
8684

8785
// The frame index into the input buffer where the first block should be read

webrtc/common_audio/blocker_unittest.cc

+104-14
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
namespace {
1616

1717
// Callback Function to add 3 to every sample in the signal.
18-
class SimpleBlockerCallback : public webrtc::BlockerCallback {
18+
class PlusThreeBlockerCallback : public webrtc::BlockerCallback {
1919
public:
2020
virtual void ProcessBlock(const float* const* input,
2121
int num_frames,
@@ -30,6 +30,22 @@ class SimpleBlockerCallback : public webrtc::BlockerCallback {
3030
}
3131
};
3232

33+
// No-op Callback Function.
34+
class CopyBlockerCallback : public webrtc::BlockerCallback {
35+
public:
36+
virtual void ProcessBlock(const float* const* input,
37+
int num_frames,
38+
int num_input_channels,
39+
int num_output_channels,
40+
float* const* output) OVERRIDE {
41+
for (int i = 0; i < num_output_channels; ++i) {
42+
for (int j = 0; j < num_frames; ++j) {
43+
output[i][j] = input[i][j];
44+
}
45+
}
46+
}
47+
};
48+
3349
} // namespace
3450

3551
namespace webrtc {
@@ -75,6 +91,21 @@ class BlockerTest : public ::testing::Test {
7591
}
7692
}
7793

94+
void ValidateInitialDelay(const float* const* output,
95+
int num_channels,
96+
int num_frames,
97+
int initial_delay) {
98+
for (int i = 0; i < num_channels; ++i) {
99+
for (int j = 0; j < num_frames; ++j) {
100+
if (j < initial_delay) {
101+
EXPECT_FLOAT_EQ(output[i][j], 0.f);
102+
} else {
103+
EXPECT_GT(output[i][j], 0.f);
104+
}
105+
}
106+
}
107+
}
108+
78109
static void CopyTo(float* const* dst,
79110
int start_index_dst,
80111
int start_index_src,
@@ -104,8 +135,8 @@ TEST_F(BlockerTest, TestBlockerMutuallyPrimeChunkandBlockSize) {
104135
const ChannelBuffer<float> input_cb(kInput[0], kNumFrames, kNumInputChannels);
105136

106137
const float kExpectedOutput[kNumInputChannels][kNumFrames] = {
107-
{6, 6, 12, 12, 20, 20, 20, 20, 20, 20},
108-
{6, 6, 12, 12, 28, 28, 28, 28, 28, 28}};
138+
{6, 6, 12, 20, 20, 20, 20, 20, 20, 20},
139+
{6, 6, 12, 28, 28, 28, 28, 28, 28, 28}};
109140
const ChannelBuffer<float> expected_output_cb(
110141
kExpectedOutput[0], kNumFrames, kNumInputChannels);
111142

@@ -115,7 +146,7 @@ TEST_F(BlockerTest, TestBlockerMutuallyPrimeChunkandBlockSize) {
115146
ChannelBuffer<float> input_chunk_cb(kChunkSize, kNumInputChannels);
116147
ChannelBuffer<float> output_chunk_cb(kChunkSize, kNumOutputChannels);
117148

118-
SimpleBlockerCallback callback;
149+
PlusThreeBlockerCallback callback;
119150
Blocker blocker(kChunkSize,
120151
kBlockSize,
121152
kNumInputChannels,
@@ -154,19 +185,19 @@ TEST_F(BlockerTest, TestBlockerMutuallyPrimeShiftAndBlockSize) {
154185
{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}};
155186
const ChannelBuffer<float> input_cb(kInput[0], kNumFrames, kNumInputChannels);
156187

157-
const float kExpectedOutput[kNumInputChannels][kNumFrames] = {
158-
{6, 6, 6, 12, 10, 10, 20, 10, 10, 20, 10, 10},
159-
{6, 6, 6, 12, 14, 14, 28, 14, 14, 28, 14, 14}};
188+
const float kExpectedOutput[kNumOutputChannels][kNumFrames] = {
189+
{6, 10, 10, 20, 10, 10, 20, 10, 10, 20, 10, 10},
190+
{6, 14, 14, 28, 14, 14, 28, 14, 14, 28, 14, 14}};
160191
const ChannelBuffer<float> expected_output_cb(
161-
kExpectedOutput[0], kNumFrames, kNumInputChannels);
192+
kExpectedOutput[0], kNumFrames, kNumOutputChannels);
162193

163194
const float kWindow[kBlockSize] = {2.f, 2.f, 2.f, 2.f};
164195

165196
ChannelBuffer<float> actual_output_cb(kNumFrames, kNumOutputChannels);
166197
ChannelBuffer<float> input_chunk_cb(kChunkSize, kNumInputChannels);
167198
ChannelBuffer<float> output_chunk_cb(kChunkSize, kNumOutputChannels);
168199

169-
SimpleBlockerCallback callback;
200+
PlusThreeBlockerCallback callback;
170201
Blocker blocker(kChunkSize,
171202
kBlockSize,
172203
kNumInputChannels,
@@ -205,19 +236,19 @@ TEST_F(BlockerTest, TestBlockerNoOverlap) {
205236
{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}};
206237
const ChannelBuffer<float> input_cb(kInput[0], kNumFrames, kNumInputChannels);
207238

208-
const float kExpectedOutput[kNumInputChannels][kNumFrames] = {
209-
{6, 6, 6, 6, 10, 10, 10, 10, 10, 10, 10, 10},
210-
{6, 6, 6, 6, 14, 14, 14, 14, 14, 14, 14, 14}};
239+
const float kExpectedOutput[kNumOutputChannels][kNumFrames] = {
240+
{10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10},
241+
{14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14}};
211242
const ChannelBuffer<float> expected_output_cb(
212-
kExpectedOutput[0], kNumFrames, kNumInputChannels);
243+
kExpectedOutput[0], kNumFrames, kNumOutputChannels);
213244

214245
const float kWindow[kBlockSize] = {2.f, 2.f, 2.f, 2.f};
215246

216247
ChannelBuffer<float> actual_output_cb(kNumFrames, kNumOutputChannels);
217248
ChannelBuffer<float> input_chunk_cb(kChunkSize, kNumInputChannels);
218249
ChannelBuffer<float> output_chunk_cb(kChunkSize, kNumOutputChannels);
219250

220-
SimpleBlockerCallback callback;
251+
PlusThreeBlockerCallback callback;
221252
Blocker blocker(kChunkSize,
222253
kBlockSize,
223254
kNumInputChannels,
@@ -242,4 +273,63 @@ TEST_F(BlockerTest, TestBlockerNoOverlap) {
242273
kNumFrames);
243274
}
244275

276+
TEST_F(BlockerTest, InitialDelaysAreMinimum) {
277+
const int kNumInputChannels = 3;
278+
const int kNumOutputChannels = 2;
279+
const int kNumFrames = 1280;
280+
const int kChunkSize[] =
281+
{80, 80, 80, 80, 80, 80, 160, 160, 160, 160, 160, 160};
282+
const int kBlockSize[] =
283+
{64, 64, 64, 128, 128, 128, 128, 128, 128, 256, 256, 256};
284+
const int kShiftAmount[] =
285+
{16, 32, 64, 32, 64, 128, 32, 64, 128, 64, 128, 256};
286+
const int kInitialDelay[] =
287+
{48, 48, 48, 112, 112, 112, 96, 96, 96, 224, 224, 224};
288+
289+
float input[kNumInputChannels][kNumFrames];
290+
for (int i = 0; i < kNumInputChannels; ++i) {
291+
for (int j = 0; j < kNumFrames; ++j) {
292+
input[i][j] = i + 1;
293+
}
294+
}
295+
const ChannelBuffer<float> input_cb(input[0], kNumFrames, kNumInputChannels);
296+
297+
ChannelBuffer<float> output_cb(kNumFrames, kNumOutputChannels);
298+
299+
CopyBlockerCallback callback;
300+
301+
for (size_t i = 0; i < (sizeof(kChunkSize) / sizeof(*kChunkSize)); ++i) {
302+
scoped_ptr<float[]> window(new float[kBlockSize[i]]);
303+
for (int j = 0; j < kBlockSize[i]; ++j) {
304+
window[j] = 1.f;
305+
}
306+
307+
ChannelBuffer<float> input_chunk_cb(kChunkSize[i], kNumInputChannels);
308+
ChannelBuffer<float> output_chunk_cb(kChunkSize[i], kNumOutputChannels);
309+
310+
Blocker blocker(kChunkSize[i],
311+
kBlockSize[i],
312+
kNumInputChannels,
313+
kNumOutputChannels,
314+
window.get(),
315+
kShiftAmount[i],
316+
&callback);
317+
318+
RunTest(&blocker,
319+
kChunkSize[i],
320+
kNumFrames,
321+
input_cb.channels(),
322+
input_chunk_cb.channels(),
323+
output_cb.channels(),
324+
output_chunk_cb.channels(),
325+
kNumInputChannels,
326+
kNumOutputChannels);
327+
328+
ValidateInitialDelay(output_cb.channels(),
329+
kNumOutputChannels,
330+
kNumFrames,
331+
kInitialDelay[i]);
332+
}
333+
}
334+
245335
} // namespace webrtc

webrtc/common_audio/lapped_transform_unittest.cc

+5-8
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,7 @@ class FftCheckerCallback : public webrtc::LappedTransform::Callback {
5353
float full_length = (frames - 1) * 2;
5454
++block_num_;
5555

56-
if (block_num_ == 1) {
57-
for (int i = 0; i < frames; ++i) {
58-
ASSERT_NEAR(in_block[0][i].real(), 0.0f, 1e-5f);
59-
ASSERT_NEAR(in_block[0][i].imag(), 0.0f, 1e-5f);
60-
}
61-
} else {
56+
if (block_num_ > 0) {
6257
ASSERT_NEAR(in_block[0][0].real(), full_length, 1e-5f);
6358
ASSERT_NEAR(in_block[0][0].imag(), 0.0f, 1e-5f);
6459
for (int i = 1; i < frames; ++i) {
@@ -114,7 +109,7 @@ TEST(LappedTransformTest, Windowless) {
114109

115110
for (int i = 0; i < kChannels; ++i) {
116111
for (int j = 0; j < kChunkLength; ++j) {
117-
ASSERT_NEAR(out_chunk[i][j], (j < kBlockLength) ? 0.0f : 2.0f, 1e-5f);
112+
ASSERT_NEAR(out_chunk[i][j], 2.0f, 1e-5f);
118113
}
119114
}
120115

@@ -145,7 +140,9 @@ TEST(LappedTransformTest, IdentityProcessor) {
145140
trans.ProcessChunk(&in_chunk, &out_chunk);
146141

147142
for (int i = 0; i < kChunkLength; ++i) {
148-
ASSERT_NEAR(out_chunk[i], (i < kBlockLength) ? 0.0f : 2.0f, 1e-5f);
143+
ASSERT_NEAR(out_chunk[i],
144+
(i < kBlockLength - kShiftAmount) ? 0.0f : 2.0f,
145+
1e-5f);
149146
}
150147

151148
ASSERT_EQ(kChunkLength / kShiftAmount, noop.block_num());

0 commit comments

Comments
 (0)