blob: 43d3f6353d30c1dd8a64cc63d3400ed7623923c5 [file] [log] [blame]
henrika86d907c2015-09-07 16:09:50 +02001/*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "modules/audio_device/fine_audio_buffer.h"
henrika86d907c2015-09-07 16:09:50 +020012
13#include <limits.h>
14#include <memory>
15
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020016#include "api/array_view.h"
17#include "modules/audio_device/mock_audio_device_buffer.h"
18#include "test/gmock.h"
19#include "test/gtest.h"
henrika86d907c2015-09-07 16:09:50 +020020
21using ::testing::_;
22using ::testing::AtLeast;
23using ::testing::InSequence;
24using ::testing::Return;
25
26namespace webrtc {
27
henrikabb6f7522017-05-30 02:01:30 -070028const int kSampleRate = 44100;
29const int kSamplesPer10Ms = kSampleRate * 10 / 1000;
30
henrika86d907c2015-09-07 16:09:50 +020031// The fake audio data is 0,1,..SCHAR_MAX-1,0,1,... This is to make it easy
32// to detect errors. This function verifies that the buffers contain such data.
33// E.g. if there are two buffers of size 3, buffer 1 would contain 0,1,2 and
34// buffer 2 would contain 3,4,5. Note that SCHAR_MAX is 127 so wrap-around
35// will happen.
36// |buffer| is the audio buffer to verify.
37bool VerifyBuffer(const int8_t* buffer, int buffer_number, int size) {
38 int start_value = (buffer_number * size) % SCHAR_MAX;
39 for (int i = 0; i < size; ++i) {
40 if (buffer[i] != (i + start_value) % SCHAR_MAX) {
41 return false;
42 }
43 }
44 return true;
45}
46
47// This function replaces the real AudioDeviceBuffer::GetPlayoutData when it's
48// called (which is done implicitly when calling GetBufferData). It writes the
49// sequence 0,1,..SCHAR_MAX-1,0,1,... to the buffer. Note that this is likely a
50// buffer of different size than the one VerifyBuffer verifies.
51// |iteration| is the number of calls made to UpdateBuffer prior to this call.
52// |samples_per_10_ms| is the number of samples that should be written to the
53// buffer (|arg0|).
54ACTION_P2(UpdateBuffer, iteration, samples_per_10_ms) {
55 int8_t* buffer = static_cast<int8_t*>(arg0);
56 int bytes_per_10_ms = samples_per_10_ms * static_cast<int>(sizeof(int16_t));
57 int start_value = (iteration * bytes_per_10_ms) % SCHAR_MAX;
58 for (int i = 0; i < bytes_per_10_ms; ++i) {
59 buffer[i] = (i + start_value) % SCHAR_MAX;
60 }
61 return samples_per_10_ms;
62}
63
64// Writes a periodic ramp pattern to the supplied |buffer|. See UpdateBuffer()
65// for details.
66void UpdateInputBuffer(int8_t* buffer, int iteration, int size) {
67 int start_value = (iteration * size) % SCHAR_MAX;
68 for (int i = 0; i < size; ++i) {
69 buffer[i] = (i + start_value) % SCHAR_MAX;
70 }
71}
72
73// Action macro which verifies that the recorded 10ms chunk of audio data
74// (in |arg0|) contains the correct reference values even if they have been
75// supplied using a buffer size that is smaller or larger than 10ms.
76// See VerifyBuffer() for details.
77ACTION_P2(VerifyInputBuffer, iteration, samples_per_10_ms) {
78 const int8_t* buffer = static_cast<const int8_t*>(arg0);
79 int bytes_per_10_ms = samples_per_10_ms * static_cast<int>(sizeof(int16_t));
80 int start_value = (iteration * bytes_per_10_ms) % SCHAR_MAX;
81 for (int i = 0; i < bytes_per_10_ms; ++i) {
82 EXPECT_EQ(buffer[i], (i + start_value) % SCHAR_MAX);
83 }
84 return 0;
85}
86
henrikabb6f7522017-05-30 02:01:30 -070087void RunFineBufferTest(int frame_size_in_samples) {
henrika86d907c2015-09-07 16:09:50 +020088 const int kFrameSizeBytes =
89 frame_size_in_samples * static_cast<int>(sizeof(int16_t));
90 const int kNumberOfFrames = 5;
91 // Ceiling of integer division: 1 + ((x - 1) / y)
92 const int kNumberOfUpdateBufferCalls =
93 1 + ((kNumberOfFrames * frame_size_in_samples - 1) / kSamplesPer10Ms);
94
95 MockAudioDeviceBuffer audio_device_buffer;
96 EXPECT_CALL(audio_device_buffer, RequestPlayoutData(_))
97 .WillRepeatedly(Return(kSamplesPer10Ms));
98 {
99 InSequence s;
100 for (int i = 0; i < kNumberOfUpdateBufferCalls; ++i) {
101 EXPECT_CALL(audio_device_buffer, GetPlayoutData(_))
102 .WillOnce(UpdateBuffer(i, kSamplesPer10Ms))
103 .RetiresOnSaturation();
104 }
105 }
106 {
107 InSequence s;
108 for (int j = 0; j < kNumberOfUpdateBufferCalls - 1; ++j) {
109 EXPECT_CALL(audio_device_buffer, SetRecordedBuffer(_, kSamplesPer10Ms))
110 .WillOnce(VerifyInputBuffer(j, kSamplesPer10Ms))
111 .RetiresOnSaturation();
112 }
113 }
114 EXPECT_CALL(audio_device_buffer, SetVQEData(_, _, _))
115 .Times(kNumberOfUpdateBufferCalls - 1);
116 EXPECT_CALL(audio_device_buffer, DeliverRecordedData())
117 .Times(kNumberOfUpdateBufferCalls - 1)
118 .WillRepeatedly(Return(kSamplesPer10Ms));
119
henrikabb6f7522017-05-30 02:01:30 -0700120 FineAudioBuffer fine_buffer(&audio_device_buffer, kSampleRate,
121 kFrameSizeBytes);
122 std::unique_ptr<int8_t[]> out_buffer(new int8_t[kFrameSizeBytes]);
123 std::unique_ptr<int8_t[]> in_buffer(new int8_t[kFrameSizeBytes]);
henrika86d907c2015-09-07 16:09:50 +0200124
henrika86d907c2015-09-07 16:09:50 +0200125 for (int i = 0; i < kNumberOfFrames; ++i) {
henrikabb6f7522017-05-30 02:01:30 -0700126 fine_buffer.GetPlayoutData(
127 rtc::ArrayView<int8_t>(out_buffer.get(), kFrameSizeBytes));
henrika86d907c2015-09-07 16:09:50 +0200128 EXPECT_TRUE(VerifyBuffer(out_buffer.get(), i, kFrameSizeBytes));
129 UpdateInputBuffer(in_buffer.get(), i, kFrameSizeBytes);
henrikabb6f7522017-05-30 02:01:30 -0700130 fine_buffer.DeliverRecordedData(
131 rtc::ArrayView<const int8_t>(in_buffer.get(), kFrameSizeBytes), 0, 0);
henrika86d907c2015-09-07 16:09:50 +0200132 }
133}
134
135TEST(FineBufferTest, BufferLessThan10ms) {
henrika86d907c2015-09-07 16:09:50 +0200136 const int kFrameSizeSamples = kSamplesPer10Ms - 50;
henrikabb6f7522017-05-30 02:01:30 -0700137 RunFineBufferTest(kFrameSizeSamples);
henrika86d907c2015-09-07 16:09:50 +0200138}
139
140TEST(FineBufferTest, GreaterThan10ms) {
henrika86d907c2015-09-07 16:09:50 +0200141 const int kFrameSizeSamples = kSamplesPer10Ms + 50;
henrikabb6f7522017-05-30 02:01:30 -0700142 RunFineBufferTest(kFrameSizeSamples);
henrika86d907c2015-09-07 16:09:50 +0200143}
144
145} // namespace webrtc