1 /*
2 * Copyright 2012 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
11 #include "pc/test/fake_audio_capture_module.h"
12
13 #include <string.h>
14
15 #include <algorithm>
16
17 #include "api/scoped_refptr.h"
18 #include "rtc_base/gunit.h"
19 #include "rtc_base/synchronization/mutex.h"
20 #include "test/gtest.h"
21
22 class FakeAdmTest : public ::testing::Test, public webrtc::AudioTransport {
23 protected:
24 static const int kMsInSecond = 1000;
25
FakeAdmTest()26 FakeAdmTest()
27 : push_iterations_(0), pull_iterations_(0), rec_buffer_bytes_(0) {
28 memset(rec_buffer_, 0, sizeof(rec_buffer_));
29 }
30
SetUp()31 void SetUp() override {
32 fake_audio_capture_module_ = FakeAudioCaptureModule::Create();
33 EXPECT_TRUE(fake_audio_capture_module_.get() != NULL);
34 }
35
36 // Callbacks inherited from webrtc::AudioTransport.
37 // ADM is pushing data.
RecordedDataIsAvailable(const void * audioSamples,const size_t nSamples,const size_t nBytesPerSample,const size_t nChannels,const uint32_t samplesPerSec,const uint32_t totalDelayMS,const int32_t clockDrift,const uint32_t currentMicLevel,const bool keyPressed,uint32_t & newMicLevel)38 int32_t RecordedDataIsAvailable(const void* audioSamples,
39 const size_t nSamples,
40 const size_t nBytesPerSample,
41 const size_t nChannels,
42 const uint32_t samplesPerSec,
43 const uint32_t totalDelayMS,
44 const int32_t clockDrift,
45 const uint32_t currentMicLevel,
46 const bool keyPressed,
47 uint32_t& newMicLevel) override {
48 webrtc::MutexLock lock(&mutex_);
49 rec_buffer_bytes_ = nSamples * nBytesPerSample;
50 if ((rec_buffer_bytes_ == 0) ||
51 (rec_buffer_bytes_ >
52 FakeAudioCaptureModule::kNumberSamples *
53 FakeAudioCaptureModule::kNumberBytesPerSample)) {
54 ADD_FAILURE();
55 return -1;
56 }
57 memcpy(rec_buffer_, audioSamples, rec_buffer_bytes_);
58 ++push_iterations_;
59 newMicLevel = currentMicLevel;
60 return 0;
61 }
62
PullRenderData(int bits_per_sample,int sample_rate,size_t number_of_channels,size_t number_of_frames,void * audio_data,int64_t * elapsed_time_ms,int64_t * ntp_time_ms)63 void PullRenderData(int bits_per_sample,
64 int sample_rate,
65 size_t number_of_channels,
66 size_t number_of_frames,
67 void* audio_data,
68 int64_t* elapsed_time_ms,
69 int64_t* ntp_time_ms) override {}
70
71 // ADM is pulling data.
NeedMorePlayData(const size_t nSamples,const size_t nBytesPerSample,const size_t nChannels,const uint32_t samplesPerSec,void * audioSamples,size_t & nSamplesOut,int64_t * elapsed_time_ms,int64_t * ntp_time_ms)72 int32_t NeedMorePlayData(const size_t nSamples,
73 const size_t nBytesPerSample,
74 const size_t nChannels,
75 const uint32_t samplesPerSec,
76 void* audioSamples,
77 size_t& nSamplesOut,
78 int64_t* elapsed_time_ms,
79 int64_t* ntp_time_ms) override {
80 webrtc::MutexLock lock(&mutex_);
81 ++pull_iterations_;
82 const size_t audio_buffer_size = nSamples * nBytesPerSample;
83 const size_t bytes_out =
84 RecordedDataReceived()
85 ? CopyFromRecBuffer(audioSamples, audio_buffer_size)
86 : GenerateZeroBuffer(audioSamples, audio_buffer_size);
87 nSamplesOut = bytes_out / nBytesPerSample;
88 *elapsed_time_ms = 0;
89 *ntp_time_ms = 0;
90 return 0;
91 }
92
push_iterations() const93 int push_iterations() const {
94 webrtc::MutexLock lock(&mutex_);
95 return push_iterations_;
96 }
pull_iterations() const97 int pull_iterations() const {
98 webrtc::MutexLock lock(&mutex_);
99 return pull_iterations_;
100 }
101
102 rtc::scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module_;
103
104 private:
RecordedDataReceived() const105 bool RecordedDataReceived() const { return rec_buffer_bytes_ != 0; }
GenerateZeroBuffer(void * audio_buffer,size_t audio_buffer_size)106 size_t GenerateZeroBuffer(void* audio_buffer, size_t audio_buffer_size) {
107 memset(audio_buffer, 0, audio_buffer_size);
108 return audio_buffer_size;
109 }
CopyFromRecBuffer(void * audio_buffer,size_t audio_buffer_size)110 size_t CopyFromRecBuffer(void* audio_buffer, size_t audio_buffer_size) {
111 EXPECT_EQ(audio_buffer_size, rec_buffer_bytes_);
112 const size_t min_buffer_size =
113 std::min(audio_buffer_size, rec_buffer_bytes_);
114 memcpy(audio_buffer, rec_buffer_, min_buffer_size);
115 return min_buffer_size;
116 }
117
118 rtc::AutoThread main_thread_;
119
120 mutable webrtc::Mutex mutex_;
121
122 int push_iterations_;
123 int pull_iterations_;
124
125 char rec_buffer_[FakeAudioCaptureModule::kNumberSamples *
126 FakeAudioCaptureModule::kNumberBytesPerSample];
127 size_t rec_buffer_bytes_;
128 };
129
TEST_F(FakeAdmTest,PlayoutTest)130 TEST_F(FakeAdmTest, PlayoutTest) {
131 EXPECT_EQ(0, fake_audio_capture_module_->RegisterAudioCallback(this));
132
133 bool stereo_available = false;
134 EXPECT_EQ(0, fake_audio_capture_module_->StereoPlayoutIsAvailable(
135 &stereo_available));
136 EXPECT_TRUE(stereo_available);
137
138 EXPECT_NE(0, fake_audio_capture_module_->StartPlayout());
139 EXPECT_FALSE(fake_audio_capture_module_->PlayoutIsInitialized());
140 EXPECT_FALSE(fake_audio_capture_module_->Playing());
141 EXPECT_EQ(0, fake_audio_capture_module_->StopPlayout());
142
143 EXPECT_EQ(0, fake_audio_capture_module_->InitPlayout());
144 EXPECT_TRUE(fake_audio_capture_module_->PlayoutIsInitialized());
145 EXPECT_FALSE(fake_audio_capture_module_->Playing());
146
147 EXPECT_EQ(0, fake_audio_capture_module_->StartPlayout());
148 EXPECT_TRUE(fake_audio_capture_module_->Playing());
149
150 uint16_t delay_ms = 10;
151 EXPECT_EQ(0, fake_audio_capture_module_->PlayoutDelay(&delay_ms));
152 EXPECT_EQ(0, delay_ms);
153
154 EXPECT_TRUE_WAIT(pull_iterations() > 0, kMsInSecond);
155 EXPECT_GE(0, push_iterations());
156
157 EXPECT_EQ(0, fake_audio_capture_module_->StopPlayout());
158 EXPECT_FALSE(fake_audio_capture_module_->Playing());
159 }
160
TEST_F(FakeAdmTest,RecordTest)161 TEST_F(FakeAdmTest, RecordTest) {
162 EXPECT_EQ(0, fake_audio_capture_module_->RegisterAudioCallback(this));
163
164 bool stereo_available = false;
165 EXPECT_EQ(0, fake_audio_capture_module_->StereoRecordingIsAvailable(
166 &stereo_available));
167 EXPECT_FALSE(stereo_available);
168
169 EXPECT_NE(0, fake_audio_capture_module_->StartRecording());
170 EXPECT_FALSE(fake_audio_capture_module_->Recording());
171 EXPECT_EQ(0, fake_audio_capture_module_->StopRecording());
172
173 EXPECT_EQ(0, fake_audio_capture_module_->InitRecording());
174 EXPECT_EQ(0, fake_audio_capture_module_->StartRecording());
175 EXPECT_TRUE(fake_audio_capture_module_->Recording());
176
177 EXPECT_TRUE_WAIT(push_iterations() > 0, kMsInSecond);
178 EXPECT_GE(0, pull_iterations());
179
180 EXPECT_EQ(0, fake_audio_capture_module_->StopRecording());
181 EXPECT_FALSE(fake_audio_capture_module_->Recording());
182 }
183
TEST_F(FakeAdmTest,DuplexTest)184 TEST_F(FakeAdmTest, DuplexTest) {
185 EXPECT_EQ(0, fake_audio_capture_module_->RegisterAudioCallback(this));
186
187 EXPECT_EQ(0, fake_audio_capture_module_->InitPlayout());
188 EXPECT_EQ(0, fake_audio_capture_module_->StartPlayout());
189
190 EXPECT_EQ(0, fake_audio_capture_module_->InitRecording());
191 EXPECT_EQ(0, fake_audio_capture_module_->StartRecording());
192
193 EXPECT_TRUE_WAIT(push_iterations() > 0, kMsInSecond);
194 EXPECT_TRUE_WAIT(pull_iterations() > 0, kMsInSecond);
195
196 EXPECT_EQ(0, fake_audio_capture_module_->StopPlayout());
197 EXPECT_EQ(0, fake_audio_capture_module_->StopRecording());
198 }
199