1 /* 2 * libjingle 3 * Copyright 2012, Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #include "talk/app/webrtc/test/fakeaudiocapturemodule.h" 29 30 #include <algorithm> 31 32 #include "webrtc/base/gunit.h" 33 #include "webrtc/base/scoped_ref_ptr.h" 34 #include "webrtc/base/thread.h" 35 36 using std::min; 37 38 class FakeAdmTest : public testing::Test, 39 public webrtc::AudioTransport { 40 protected: 41 static const int kMsInSecond = 1000; 42 43 FakeAdmTest() 44 : push_iterations_(0), 45 pull_iterations_(0), 46 rec_buffer_bytes_(0) { 47 memset(rec_buffer_, 0, sizeof(rec_buffer_)); 48 } 49 50 virtual void SetUp() { 51 fake_audio_capture_module_ = FakeAudioCaptureModule::Create( 52 rtc::Thread::Current()); 53 EXPECT_TRUE(fake_audio_capture_module_.get() != NULL); 54 } 55 56 // Callbacks inherited from webrtc::AudioTransport. 57 // ADM is pushing data. 58 virtual int32_t RecordedDataIsAvailable(const void* audioSamples, 59 const uint32_t nSamples, 60 const uint8_t nBytesPerSample, 61 const uint8_t nChannels, 62 const uint32_t samplesPerSec, 63 const uint32_t totalDelayMS, 64 const int32_t clockDrift, 65 const uint32_t currentMicLevel, 66 const bool keyPressed, 67 uint32_t& newMicLevel) { 68 rec_buffer_bytes_ = nSamples * nBytesPerSample; 69 if ((rec_buffer_bytes_ <= 0) || 70 (rec_buffer_bytes_ > FakeAudioCaptureModule::kNumberSamples * 71 FakeAudioCaptureModule::kNumberBytesPerSample)) { 72 ADD_FAILURE(); 73 return -1; 74 } 75 memcpy(rec_buffer_, audioSamples, rec_buffer_bytes_); 76 ++push_iterations_; 77 newMicLevel = currentMicLevel; 78 return 0; 79 } 80 81 // ADM is pulling data. 82 virtual int32_t NeedMorePlayData(const uint32_t nSamples, 83 const uint8_t nBytesPerSample, 84 const uint8_t nChannels, 85 const uint32_t samplesPerSec, 86 void* audioSamples, 87 uint32_t& nSamplesOut, 88 #ifdef USE_WEBRTC_DEV_BRANCH 89 int64_t* elapsed_time_ms, 90 #else 91 uint32_t* rtp_timestamp, 92 #endif 93 int64_t* ntp_time_ms) { 94 ++pull_iterations_; 95 const uint32_t audio_buffer_size = nSamples * nBytesPerSample; 96 const uint32_t bytes_out = RecordedDataReceived() ? 97 CopyFromRecBuffer(audioSamples, audio_buffer_size): 98 GenerateZeroBuffer(audioSamples, audio_buffer_size); 99 nSamplesOut = bytes_out / nBytesPerSample; 100 #ifdef USE_WEBRTC_DEV_BRANCH 101 *elapsed_time_ms = 0; 102 #else 103 *rtp_timestamp = 0; 104 #endif 105 *ntp_time_ms = 0; 106 return 0; 107 } 108 109 int push_iterations() const { return push_iterations_; } 110 int pull_iterations() const { return pull_iterations_; } 111 112 rtc::scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module_; 113 114 private: 115 bool RecordedDataReceived() const { 116 return rec_buffer_bytes_ != 0; 117 } 118 int32_t GenerateZeroBuffer(void* audio_buffer, uint32_t audio_buffer_size) { 119 memset(audio_buffer, 0, audio_buffer_size); 120 return audio_buffer_size; 121 } 122 int32_t CopyFromRecBuffer(void* audio_buffer, uint32_t audio_buffer_size) { 123 EXPECT_EQ(audio_buffer_size, rec_buffer_bytes_); 124 const uint32_t min_buffer_size = min(audio_buffer_size, rec_buffer_bytes_); 125 memcpy(audio_buffer, rec_buffer_, min_buffer_size); 126 return min_buffer_size; 127 } 128 129 int push_iterations_; 130 int pull_iterations_; 131 132 char rec_buffer_[FakeAudioCaptureModule::kNumberSamples * 133 FakeAudioCaptureModule::kNumberBytesPerSample]; 134 uint32_t rec_buffer_bytes_; 135 }; 136 137 TEST_F(FakeAdmTest, TestProccess) { 138 // Next process call must be some time in the future (or now). 139 EXPECT_LE(0, fake_audio_capture_module_->TimeUntilNextProcess()); 140 // Process call updates TimeUntilNextProcess() but there are no guarantees on 141 // timing so just check that Process can ba called successfully. 142 EXPECT_LE(0, fake_audio_capture_module_->Process()); 143 } 144 145 TEST_F(FakeAdmTest, PlayoutTest) { 146 EXPECT_EQ(0, fake_audio_capture_module_->RegisterAudioCallback(this)); 147 148 bool stereo_available = false; 149 EXPECT_EQ(0, 150 fake_audio_capture_module_->StereoPlayoutIsAvailable( 151 &stereo_available)); 152 EXPECT_TRUE(stereo_available); 153 154 EXPECT_NE(0, fake_audio_capture_module_->StartPlayout()); 155 EXPECT_FALSE(fake_audio_capture_module_->PlayoutIsInitialized()); 156 EXPECT_FALSE(fake_audio_capture_module_->Playing()); 157 EXPECT_EQ(0, fake_audio_capture_module_->StopPlayout()); 158 159 EXPECT_EQ(0, fake_audio_capture_module_->InitPlayout()); 160 EXPECT_TRUE(fake_audio_capture_module_->PlayoutIsInitialized()); 161 EXPECT_FALSE(fake_audio_capture_module_->Playing()); 162 163 EXPECT_EQ(0, fake_audio_capture_module_->StartPlayout()); 164 EXPECT_TRUE(fake_audio_capture_module_->Playing()); 165 166 uint16_t delay_ms = 10; 167 EXPECT_EQ(0, fake_audio_capture_module_->PlayoutDelay(&delay_ms)); 168 EXPECT_EQ(0, delay_ms); 169 170 EXPECT_TRUE_WAIT(pull_iterations() > 0, kMsInSecond); 171 EXPECT_GE(0, push_iterations()); 172 173 EXPECT_EQ(0, fake_audio_capture_module_->StopPlayout()); 174 EXPECT_FALSE(fake_audio_capture_module_->Playing()); 175 } 176 177 TEST_F(FakeAdmTest, RecordTest) { 178 EXPECT_EQ(0, fake_audio_capture_module_->RegisterAudioCallback(this)); 179 180 bool stereo_available = false; 181 EXPECT_EQ(0, fake_audio_capture_module_->StereoRecordingIsAvailable( 182 &stereo_available)); 183 EXPECT_FALSE(stereo_available); 184 185 EXPECT_NE(0, fake_audio_capture_module_->StartRecording()); 186 EXPECT_FALSE(fake_audio_capture_module_->Recording()); 187 EXPECT_EQ(0, fake_audio_capture_module_->StopRecording()); 188 189 EXPECT_EQ(0, fake_audio_capture_module_->InitRecording()); 190 EXPECT_EQ(0, fake_audio_capture_module_->StartRecording()); 191 EXPECT_TRUE(fake_audio_capture_module_->Recording()); 192 193 EXPECT_TRUE_WAIT(push_iterations() > 0, kMsInSecond); 194 EXPECT_GE(0, pull_iterations()); 195 196 EXPECT_EQ(0, fake_audio_capture_module_->StopRecording()); 197 EXPECT_FALSE(fake_audio_capture_module_->Recording()); 198 } 199 200 TEST_F(FakeAdmTest, DuplexTest) { 201 EXPECT_EQ(0, fake_audio_capture_module_->RegisterAudioCallback(this)); 202 203 EXPECT_EQ(0, fake_audio_capture_module_->InitPlayout()); 204 EXPECT_EQ(0, fake_audio_capture_module_->StartPlayout()); 205 206 EXPECT_EQ(0, fake_audio_capture_module_->InitRecording()); 207 EXPECT_EQ(0, fake_audio_capture_module_->StartRecording()); 208 209 EXPECT_TRUE_WAIT(push_iterations() > 0, kMsInSecond); 210 EXPECT_TRUE_WAIT(pull_iterations() > 0, kMsInSecond); 211 212 EXPECT_EQ(0, fake_audio_capture_module_->StopPlayout()); 213 EXPECT_EQ(0, fake_audio_capture_module_->StopRecording()); 214 } 215