blob: de0cc6dc7aa41cb92372eba0c3c449b334f2311b [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.
henrika8d7393b2018-04-19 13:40:15 +020037bool VerifyBuffer(const int16_t* buffer, int buffer_number, int size) {
henrika86d907c2015-09-07 16:09:50 +020038 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) {
henrika8d7393b2018-04-19 13:40:15 +020055 int16_t* buffer = static_cast<int16_t*>(arg0);
56 int start_value = (iteration * samples_per_10_ms) % SCHAR_MAX;
57 for (int i = 0; i < samples_per_10_ms; ++i) {
henrika86d907c2015-09-07 16:09:50 +020058 buffer[i] = (i + start_value) % SCHAR_MAX;
59 }
60 return samples_per_10_ms;
61}
62
63// Writes a periodic ramp pattern to the supplied |buffer|. See UpdateBuffer()
64// for details.
henrika8d7393b2018-04-19 13:40:15 +020065void UpdateInputBuffer(int16_t* buffer, int iteration, int size) {
henrika86d907c2015-09-07 16:09:50 +020066 int start_value = (iteration * size) % SCHAR_MAX;
67 for (int i = 0; i < size; ++i) {
68 buffer[i] = (i + start_value) % SCHAR_MAX;
69 }
70}
71
72// Action macro which verifies that the recorded 10ms chunk of audio data
73// (in |arg0|) contains the correct reference values even if they have been
74// supplied using a buffer size that is smaller or larger than 10ms.
75// See VerifyBuffer() for details.
76ACTION_P2(VerifyInputBuffer, iteration, samples_per_10_ms) {
henrika8d7393b2018-04-19 13:40:15 +020077 const int16_t* buffer = static_cast<const int16_t*>(arg0);
78 int start_value = (iteration * samples_per_10_ms) % SCHAR_MAX;
79 for (int i = 0; i < samples_per_10_ms; ++i) {
henrika86d907c2015-09-07 16:09:50 +020080 EXPECT_EQ(buffer[i], (i + start_value) % SCHAR_MAX);
81 }
82 return 0;
83}
84
henrikabb6f7522017-05-30 02:01:30 -070085void RunFineBufferTest(int frame_size_in_samples) {
henrika8d7393b2018-04-19 13:40:15 +020086 const int kFrameSizeSamples = frame_size_in_samples;
henrika86d907c2015-09-07 16:09:50 +020087 const int kNumberOfFrames = 5;
88 // Ceiling of integer division: 1 + ((x - 1) / y)
89 const int kNumberOfUpdateBufferCalls =
90 1 + ((kNumberOfFrames * frame_size_in_samples - 1) / kSamplesPer10Ms);
91
92 MockAudioDeviceBuffer audio_device_buffer;
93 EXPECT_CALL(audio_device_buffer, RequestPlayoutData(_))
94 .WillRepeatedly(Return(kSamplesPer10Ms));
95 {
96 InSequence s;
97 for (int i = 0; i < kNumberOfUpdateBufferCalls; ++i) {
98 EXPECT_CALL(audio_device_buffer, GetPlayoutData(_))
99 .WillOnce(UpdateBuffer(i, kSamplesPer10Ms))
100 .RetiresOnSaturation();
101 }
102 }
103 {
104 InSequence s;
105 for (int j = 0; j < kNumberOfUpdateBufferCalls - 1; ++j) {
106 EXPECT_CALL(audio_device_buffer, SetRecordedBuffer(_, kSamplesPer10Ms))
107 .WillOnce(VerifyInputBuffer(j, kSamplesPer10Ms))
108 .RetiresOnSaturation();
109 }
110 }
Fredrik Solenberg1a50cd52018-01-16 09:19:38 +0100111 EXPECT_CALL(audio_device_buffer, SetVQEData(_, _))
henrika86d907c2015-09-07 16:09:50 +0200112 .Times(kNumberOfUpdateBufferCalls - 1);
113 EXPECT_CALL(audio_device_buffer, DeliverRecordedData())
114 .Times(kNumberOfUpdateBufferCalls - 1)
115 .WillRepeatedly(Return(kSamplesPer10Ms));
116
henrikabb6f7522017-05-30 02:01:30 -0700117 FineAudioBuffer fine_buffer(&audio_device_buffer, kSampleRate,
henrika8d7393b2018-04-19 13:40:15 +0200118 kFrameSizeSamples);
119 std::unique_ptr<int16_t[]> out_buffer(new int16_t[kFrameSizeSamples]);
120 std::unique_ptr<int16_t[]> in_buffer(new int16_t[kFrameSizeSamples]);
henrika86d907c2015-09-07 16:09:50 +0200121
henrika86d907c2015-09-07 16:09:50 +0200122 for (int i = 0; i < kNumberOfFrames; ++i) {
henrikabb6f7522017-05-30 02:01:30 -0700123 fine_buffer.GetPlayoutData(
henrika8d7393b2018-04-19 13:40:15 +0200124 rtc::ArrayView<int16_t>(out_buffer.get(), kFrameSizeSamples), 0);
125 EXPECT_TRUE(VerifyBuffer(out_buffer.get(), i, kFrameSizeSamples));
126 UpdateInputBuffer(in_buffer.get(), i, kFrameSizeSamples);
henrikabb6f7522017-05-30 02:01:30 -0700127 fine_buffer.DeliverRecordedData(
henrika8d7393b2018-04-19 13:40:15 +0200128 rtc::ArrayView<const int16_t>(in_buffer.get(), kFrameSizeSamples), 0);
henrika86d907c2015-09-07 16:09:50 +0200129 }
130}
131
132TEST(FineBufferTest, BufferLessThan10ms) {
henrika86d907c2015-09-07 16:09:50 +0200133 const int kFrameSizeSamples = kSamplesPer10Ms - 50;
henrikabb6f7522017-05-30 02:01:30 -0700134 RunFineBufferTest(kFrameSizeSamples);
henrika86d907c2015-09-07 16:09:50 +0200135}
136
137TEST(FineBufferTest, GreaterThan10ms) {
henrika86d907c2015-09-07 16:09:50 +0200138 const int kFrameSizeSamples = kSamplesPer10Ms + 50;
henrikabb6f7522017-05-30 02:01:30 -0700139 RunFineBufferTest(kFrameSizeSamples);
henrika86d907c2015-09-07 16:09:50 +0200140}
141
142} // namespace webrtc