• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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