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 "talk/base/gunit.h" 33 #include "talk/base/scoped_ref_ptr.h" 34 #include "talk/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 talk_base::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 ++pull_iterations_; 89 const uint32_t audio_buffer_size = nSamples * nBytesPerSample; 90 const uint32_t bytes_out = RecordedDataReceived() ? 91 CopyFromRecBuffer(audioSamples, audio_buffer_size): 92 GenerateZeroBuffer(audioSamples, audio_buffer_size); 93 nSamplesOut = bytes_out / nBytesPerSample; 94 return 0; 95 } 96 97 int push_iterations() const { return push_iterations_; } 98 int pull_iterations() const { return pull_iterations_; } 99 100 talk_base::scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module_; 101 102 private: 103 bool RecordedDataReceived() const { 104 return rec_buffer_bytes_ != 0; 105 } 106 int32_t GenerateZeroBuffer(void* audio_buffer, uint32_t audio_buffer_size) { 107 memset(audio_buffer, 0, audio_buffer_size); 108 return audio_buffer_size; 109 } 110 int32_t CopyFromRecBuffer(void* audio_buffer, uint32_t audio_buffer_size) { 111 EXPECT_EQ(audio_buffer_size, rec_buffer_bytes_); 112 const uint32_t min_buffer_size = min(audio_buffer_size, rec_buffer_bytes_); 113 memcpy(audio_buffer, rec_buffer_, min_buffer_size); 114 return min_buffer_size; 115 } 116 117 int push_iterations_; 118 int pull_iterations_; 119 120 char rec_buffer_[FakeAudioCaptureModule::kNumberSamples * 121 FakeAudioCaptureModule::kNumberBytesPerSample]; 122 uint32_t rec_buffer_bytes_; 123 }; 124 125 TEST_F(FakeAdmTest, TestProccess) { 126 // Next process call must be some time in the future (or now). 127 EXPECT_LE(0, fake_audio_capture_module_->TimeUntilNextProcess()); 128 // Process call updates TimeUntilNextProcess() but there are no guarantees on 129 // timing so just check that Process can ba called successfully. 130 EXPECT_LE(0, fake_audio_capture_module_->Process()); 131 } 132 133 TEST_F(FakeAdmTest, PlayoutTest) { 134 EXPECT_EQ(0, fake_audio_capture_module_->RegisterAudioCallback(this)); 135 136 bool speaker_available = false; 137 EXPECT_EQ(0, fake_audio_capture_module_->SpeakerIsAvailable( 138 &speaker_available)); 139 EXPECT_TRUE(speaker_available); 140 141 bool stereo_available = false; 142 EXPECT_EQ(0, 143 fake_audio_capture_module_->StereoPlayoutIsAvailable( 144 &stereo_available)); 145 EXPECT_TRUE(stereo_available); 146 147 EXPECT_NE(0, fake_audio_capture_module_->StartPlayout()); 148 EXPECT_FALSE(fake_audio_capture_module_->PlayoutIsInitialized()); 149 EXPECT_FALSE(fake_audio_capture_module_->Playing()); 150 EXPECT_EQ(0, fake_audio_capture_module_->StopPlayout()); 151 152 EXPECT_EQ(0, fake_audio_capture_module_->InitPlayout()); 153 EXPECT_TRUE(fake_audio_capture_module_->PlayoutIsInitialized()); 154 EXPECT_FALSE(fake_audio_capture_module_->Playing()); 155 156 EXPECT_EQ(0, fake_audio_capture_module_->StartPlayout()); 157 EXPECT_TRUE(fake_audio_capture_module_->Playing()); 158 159 uint16_t delay_ms = 10; 160 EXPECT_EQ(0, fake_audio_capture_module_->PlayoutDelay(&delay_ms)); 161 EXPECT_EQ(0, delay_ms); 162 163 EXPECT_TRUE_WAIT(pull_iterations() > 0, kMsInSecond); 164 EXPECT_GE(0, push_iterations()); 165 166 EXPECT_EQ(0, fake_audio_capture_module_->StopPlayout()); 167 EXPECT_FALSE(fake_audio_capture_module_->Playing()); 168 } 169 170 TEST_F(FakeAdmTest, RecordTest) { 171 EXPECT_EQ(0, fake_audio_capture_module_->RegisterAudioCallback(this)); 172 173 bool microphone_available = false; 174 EXPECT_EQ(0, fake_audio_capture_module_->MicrophoneIsAvailable( 175 µphone_available)); 176 EXPECT_TRUE(microphone_available); 177 178 bool stereo_available = false; 179 EXPECT_EQ(0, fake_audio_capture_module_->StereoRecordingIsAvailable( 180 &stereo_available)); 181 EXPECT_FALSE(stereo_available); 182 183 EXPECT_NE(0, fake_audio_capture_module_->StartRecording()); 184 EXPECT_FALSE(fake_audio_capture_module_->Recording()); 185 EXPECT_EQ(0, fake_audio_capture_module_->StopRecording()); 186 187 EXPECT_EQ(0, fake_audio_capture_module_->InitRecording()); 188 EXPECT_EQ(0, fake_audio_capture_module_->StartRecording()); 189 EXPECT_TRUE(fake_audio_capture_module_->Recording()); 190 191 EXPECT_TRUE_WAIT(push_iterations() > 0, kMsInSecond); 192 EXPECT_GE(0, pull_iterations()); 193 194 EXPECT_EQ(0, fake_audio_capture_module_->StopRecording()); 195 EXPECT_FALSE(fake_audio_capture_module_->Recording()); 196 } 197 198 TEST_F(FakeAdmTest, DuplexTest) { 199 EXPECT_EQ(0, fake_audio_capture_module_->RegisterAudioCallback(this)); 200 201 EXPECT_EQ(0, fake_audio_capture_module_->InitPlayout()); 202 EXPECT_EQ(0, fake_audio_capture_module_->StartPlayout()); 203 204 EXPECT_EQ(0, fake_audio_capture_module_->InitRecording()); 205 EXPECT_EQ(0, fake_audio_capture_module_->StartRecording()); 206 207 EXPECT_TRUE_WAIT(push_iterations() > 0, kMsInSecond); 208 EXPECT_TRUE_WAIT(pull_iterations() > 0, kMsInSecond); 209 210 EXPECT_EQ(0, fake_audio_capture_module_->StopPlayout()); 211 EXPECT_EQ(0, fake_audio_capture_module_->StopRecording()); 212 } 213