1/* 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 11#include "webrtc/test/fake_audio_device.h" 12 13#include <algorithm> 14 15#include "testing/gtest/include/gtest/gtest.h" 16#include "webrtc/base/platform_thread.h" 17#include "webrtc/modules/media_file/media_file_utility.h" 18#include "webrtc/system_wrappers/include/clock.h" 19#include "webrtc/system_wrappers/include/event_wrapper.h" 20#include "webrtc/system_wrappers/include/file_wrapper.h" 21 22namespace webrtc { 23namespace test { 24 25FakeAudioDevice::FakeAudioDevice(Clock* clock, const std::string& filename) 26 : audio_callback_(NULL), 27 capturing_(false), 28 captured_audio_(), 29 playout_buffer_(), 30 last_playout_ms_(-1), 31 clock_(clock), 32 tick_(EventTimerWrapper::Create()), 33 thread_(FakeAudioDevice::Run, this, "FakeAudioDevice"), 34 file_utility_(new ModuleFileUtility(0)), 35 input_stream_(FileWrapper::Create()) { 36 memset(captured_audio_, 0, sizeof(captured_audio_)); 37 memset(playout_buffer_, 0, sizeof(playout_buffer_)); 38 // Open audio input file as read-only and looping. 39 EXPECT_EQ(0, input_stream_->OpenFile(filename.c_str(), true, true)) 40 << filename; 41} 42 43FakeAudioDevice::~FakeAudioDevice() { 44 Stop(); 45 46 thread_.Stop(); 47} 48 49int32_t FakeAudioDevice::Init() { 50 rtc::CritScope cs(&lock_); 51 if (file_utility_->InitPCMReading(*input_stream_.get()) != 0) 52 return -1; 53 54 if (!tick_->StartTimer(true, 10)) 55 return -1; 56 thread_.Start(); 57 thread_.SetPriority(rtc::kHighPriority); 58 return 0; 59} 60 61int32_t FakeAudioDevice::RegisterAudioCallback(AudioTransport* callback) { 62 rtc::CritScope cs(&lock_); 63 audio_callback_ = callback; 64 return 0; 65} 66 67bool FakeAudioDevice::Playing() const { 68 rtc::CritScope cs(&lock_); 69 return capturing_; 70} 71 72int32_t FakeAudioDevice::PlayoutDelay(uint16_t* delay_ms) const { 73 *delay_ms = 0; 74 return 0; 75} 76 77bool FakeAudioDevice::Recording() const { 78 rtc::CritScope cs(&lock_); 79 return capturing_; 80} 81 82bool FakeAudioDevice::Run(void* obj) { 83 static_cast<FakeAudioDevice*>(obj)->CaptureAudio(); 84 return true; 85} 86 87void FakeAudioDevice::CaptureAudio() { 88 { 89 rtc::CritScope cs(&lock_); 90 if (capturing_) { 91 int bytes_read = file_utility_->ReadPCMData( 92 *input_stream_.get(), captured_audio_, kBufferSizeBytes); 93 if (bytes_read <= 0) 94 return; 95 // 2 bytes per sample. 96 size_t num_samples = static_cast<size_t>(bytes_read / 2); 97 uint32_t new_mic_level; 98 EXPECT_EQ(0, 99 audio_callback_->RecordedDataIsAvailable(captured_audio_, 100 num_samples, 101 2, 102 1, 103 kFrequencyHz, 104 0, 105 0, 106 0, 107 false, 108 new_mic_level)); 109 size_t samples_needed = kFrequencyHz / 100; 110 int64_t now_ms = clock_->TimeInMilliseconds(); 111 uint32_t time_since_last_playout_ms = now_ms - last_playout_ms_; 112 if (last_playout_ms_ > 0 && time_since_last_playout_ms > 0) { 113 samples_needed = std::min( 114 static_cast<size_t>(kFrequencyHz / time_since_last_playout_ms), 115 kBufferSizeBytes / 2); 116 } 117 size_t samples_out = 0; 118 int64_t elapsed_time_ms = -1; 119 int64_t ntp_time_ms = -1; 120 EXPECT_EQ(0, 121 audio_callback_->NeedMorePlayData(samples_needed, 122 2, 123 1, 124 kFrequencyHz, 125 playout_buffer_, 126 samples_out, 127 &elapsed_time_ms, 128 &ntp_time_ms)); 129 } 130 } 131 tick_->Wait(WEBRTC_EVENT_INFINITE); 132} 133 134void FakeAudioDevice::Start() { 135 rtc::CritScope cs(&lock_); 136 capturing_ = true; 137} 138 139void FakeAudioDevice::Stop() { 140 rtc::CritScope cs(&lock_); 141 capturing_ = false; 142} 143} // namespace test 144} // namespace webrtc 145