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
22 namespace webrtc {
23 namespace test {
24
FakeAudioDevice(Clock * clock,const std::string & filename)25 FakeAudioDevice::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
~FakeAudioDevice()43 FakeAudioDevice::~FakeAudioDevice() {
44 Stop();
45
46 thread_.Stop();
47 }
48
Init()49 int32_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
RegisterAudioCallback(AudioTransport * callback)61 int32_t FakeAudioDevice::RegisterAudioCallback(AudioTransport* callback) {
62 rtc::CritScope cs(&lock_);
63 audio_callback_ = callback;
64 return 0;
65 }
66
Playing() const67 bool FakeAudioDevice::Playing() const {
68 rtc::CritScope cs(&lock_);
69 return capturing_;
70 }
71
PlayoutDelay(uint16_t * delay_ms) const72 int32_t FakeAudioDevice::PlayoutDelay(uint16_t* delay_ms) const {
73 *delay_ms = 0;
74 return 0;
75 }
76
Recording() const77 bool FakeAudioDevice::Recording() const {
78 rtc::CritScope cs(&lock_);
79 return capturing_;
80 }
81
Run(void * obj)82 bool FakeAudioDevice::Run(void* obj) {
83 static_cast<FakeAudioDevice*>(obj)->CaptureAudio();
84 return true;
85 }
86
CaptureAudio()87 void 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
Start()134 void FakeAudioDevice::Start() {
135 rtc::CritScope cs(&lock_);
136 capturing_ = true;
137 }
138
Stop()139 void FakeAudioDevice::Stop() {
140 rtc::CritScope cs(&lock_);
141 capturing_ = false;
142 }
143 } // namespace test
144 } // namespace webrtc
145