blob: c0b761fd3dd64f87d60ec977fbb181379d038abe [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
kjellanderb24317b2016-02-10 07:54:43 -08002 * Copyright 2012 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003 *
kjellanderb24317b2016-02-10 07:54:43 -08004 * 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.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00009 */
10
Henrik Kjellander15583c12016-02-10 10:53:12 +010011#include "webrtc/api/test/fakeaudiocapturemodule.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000012
nissec80e7412017-01-11 05:56:46 -080013#include "webrtc/base/checks.h"
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000014#include "webrtc/base/common.h"
15#include "webrtc/base/refcount.h"
16#include "webrtc/base/thread.h"
17#include "webrtc/base/timeutils.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000018
19// Audio sample value that is high enough that it doesn't occur naturally when
20// frames are being faked. E.g. NetEq will not generate this large sample value
21// unless it has received an audio frame containing a sample of this value.
22// Even simpler buffers would likely just contain audio sample values of 0.
23static const int kHighSampleValue = 10000;
24
25// Same value as src/modules/audio_device/main/source/audio_device_config.h in
26// https://code.google.com/p/webrtc/
Honghai Zhang82d78622016-05-06 11:29:15 -070027static const int kAdmMaxIdleTimeProcess = 1000;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000028
29// Constants here are derived by running VoE using a real ADM.
30// The constants correspond to 10ms of mono audio at 44kHz.
31static const int kTimePerFrameMs = 10;
Peter Kastingb7e50542015-06-11 12:55:50 -070032static const uint8_t kNumberOfChannels = 1;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000033static const int kSamplesPerSecond = 44000;
34static const int kTotalDelayMs = 0;
35static const int kClockDriftMs = 0;
36static const uint32_t kMaxVolume = 14392;
37
38enum {
wu@webrtc.org8804a292013-10-22 23:09:20 +000039 MSG_START_PROCESS,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000040 MSG_RUN_PROCESS,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000041};
42
deadbeefee8c6d32015-08-13 14:27:18 -070043FakeAudioCaptureModule::FakeAudioCaptureModule()
henrike@webrtc.org28e20752013-07-10 00:45:36 +000044 : last_process_time_ms_(0),
deadbeefee8c6d32015-08-13 14:27:18 -070045 audio_callback_(nullptr),
henrike@webrtc.org28e20752013-07-10 00:45:36 +000046 recording_(false),
47 playing_(false),
48 play_is_initialized_(false),
49 rec_is_initialized_(false),
50 current_mic_level_(kMaxVolume),
51 started_(false),
52 next_frame_time_(0),
henrike@webrtc.org28e20752013-07-10 00:45:36 +000053 frames_received_(0) {
54}
55
56FakeAudioCaptureModule::~FakeAudioCaptureModule() {
deadbeefee8c6d32015-08-13 14:27:18 -070057 if (process_thread_) {
58 process_thread_->Stop();
59 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +000060}
61
deadbeefee8c6d32015-08-13 14:27:18 -070062rtc::scoped_refptr<FakeAudioCaptureModule> FakeAudioCaptureModule::Create() {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000063 rtc::scoped_refptr<FakeAudioCaptureModule> capture_module(
deadbeefee8c6d32015-08-13 14:27:18 -070064 new rtc::RefCountedObject<FakeAudioCaptureModule>());
henrike@webrtc.org28e20752013-07-10 00:45:36 +000065 if (!capture_module->Initialize()) {
deadbeefee8c6d32015-08-13 14:27:18 -070066 return nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000067 }
68 return capture_module;
69}
70
71int FakeAudioCaptureModule::frames_received() const {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000072 rtc::CritScope cs(&crit_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000073 return frames_received_;
74}
75
pkasting@chromium.org0b1534c2014-12-15 22:09:40 +000076int64_t FakeAudioCaptureModule::TimeUntilNextProcess() {
Honghai Zhang82d78622016-05-06 11:29:15 -070077 const int64_t current_time = rtc::TimeMillis();
henrike@webrtc.org28e20752013-07-10 00:45:36 +000078 if (current_time < last_process_time_ms_) {
79 // TODO: wraparound could be handled more gracefully.
80 return 0;
81 }
Honghai Zhang82d78622016-05-06 11:29:15 -070082 const int64_t elapsed_time = current_time - last_process_time_ms_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000083 if (kAdmMaxIdleTimeProcess < elapsed_time) {
84 return 0;
85 }
86 return kAdmMaxIdleTimeProcess - elapsed_time;
87}
88
pbosa26ac922016-02-25 04:50:01 -080089void FakeAudioCaptureModule::Process() {
Honghai Zhang82d78622016-05-06 11:29:15 -070090 last_process_time_ms_ = rtc::TimeMillis();
henrike@webrtc.org28e20752013-07-10 00:45:36 +000091}
92
henrike@webrtc.org28e20752013-07-10 00:45:36 +000093int32_t FakeAudioCaptureModule::ActiveAudioLayer(
94 AudioLayer* /*audio_layer*/) const {
nissec80e7412017-01-11 05:56:46 -080095 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +000096 return 0;
97}
98
99webrtc::AudioDeviceModule::ErrorCode FakeAudioCaptureModule::LastError() const {
nissec80e7412017-01-11 05:56:46 -0800100 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000101 return webrtc::AudioDeviceModule::kAdmErrNone;
102}
103
104int32_t FakeAudioCaptureModule::RegisterEventObserver(
105 webrtc::AudioDeviceObserver* /*event_callback*/) {
106 // Only used to report warnings and errors. This fake implementation won't
107 // generate any so discard this callback.
108 return 0;
109}
110
111int32_t FakeAudioCaptureModule::RegisterAudioCallback(
112 webrtc::AudioTransport* audio_callback) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000113 rtc::CritScope cs(&crit_callback_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000114 audio_callback_ = audio_callback;
115 return 0;
116}
117
118int32_t FakeAudioCaptureModule::Init() {
119 // Initialize is called by the factory method. Safe to ignore this Init call.
120 return 0;
121}
122
123int32_t FakeAudioCaptureModule::Terminate() {
124 // Clean up in the destructor. No action here, just success.
125 return 0;
126}
127
128bool FakeAudioCaptureModule::Initialized() const {
nissec80e7412017-01-11 05:56:46 -0800129 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000130 return 0;
131}
132
133int16_t FakeAudioCaptureModule::PlayoutDevices() {
nissec80e7412017-01-11 05:56:46 -0800134 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000135 return 0;
136}
137
138int16_t FakeAudioCaptureModule::RecordingDevices() {
nissec80e7412017-01-11 05:56:46 -0800139 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000140 return 0;
141}
142
143int32_t FakeAudioCaptureModule::PlayoutDeviceName(
144 uint16_t /*index*/,
145 char /*name*/[webrtc::kAdmMaxDeviceNameSize],
146 char /*guid*/[webrtc::kAdmMaxGuidSize]) {
nissec80e7412017-01-11 05:56:46 -0800147 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000148 return 0;
149}
150
151int32_t FakeAudioCaptureModule::RecordingDeviceName(
152 uint16_t /*index*/,
153 char /*name*/[webrtc::kAdmMaxDeviceNameSize],
154 char /*guid*/[webrtc::kAdmMaxGuidSize]) {
nissec80e7412017-01-11 05:56:46 -0800155 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000156 return 0;
157}
158
159int32_t FakeAudioCaptureModule::SetPlayoutDevice(uint16_t /*index*/) {
160 // No playout device, just playing from file. Return success.
161 return 0;
162}
163
164int32_t FakeAudioCaptureModule::SetPlayoutDevice(WindowsDeviceType /*device*/) {
165 if (play_is_initialized_) {
166 return -1;
167 }
168 return 0;
169}
170
171int32_t FakeAudioCaptureModule::SetRecordingDevice(uint16_t /*index*/) {
172 // No recording device, just dropping audio. Return success.
173 return 0;
174}
175
176int32_t FakeAudioCaptureModule::SetRecordingDevice(
177 WindowsDeviceType /*device*/) {
178 if (rec_is_initialized_) {
179 return -1;
180 }
181 return 0;
182}
183
184int32_t FakeAudioCaptureModule::PlayoutIsAvailable(bool* /*available*/) {
nissec80e7412017-01-11 05:56:46 -0800185 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000186 return 0;
187}
188
189int32_t FakeAudioCaptureModule::InitPlayout() {
190 play_is_initialized_ = true;
191 return 0;
192}
193
194bool FakeAudioCaptureModule::PlayoutIsInitialized() const {
195 return play_is_initialized_;
196}
197
198int32_t FakeAudioCaptureModule::RecordingIsAvailable(bool* /*available*/) {
nissec80e7412017-01-11 05:56:46 -0800199 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000200 return 0;
201}
202
203int32_t FakeAudioCaptureModule::InitRecording() {
204 rec_is_initialized_ = true;
205 return 0;
206}
207
208bool FakeAudioCaptureModule::RecordingIsInitialized() const {
solenbergd53a3f92016-04-14 13:56:37 -0700209 return rec_is_initialized_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000210}
211
212int32_t FakeAudioCaptureModule::StartPlayout() {
213 if (!play_is_initialized_) {
214 return -1;
215 }
wu@webrtc.org8804a292013-10-22 23:09:20 +0000216 {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000217 rtc::CritScope cs(&crit_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000218 playing_ = true;
219 }
220 bool start = true;
221 UpdateProcessing(start);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000222 return 0;
223}
224
225int32_t FakeAudioCaptureModule::StopPlayout() {
wu@webrtc.org8804a292013-10-22 23:09:20 +0000226 bool start = false;
227 {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000228 rtc::CritScope cs(&crit_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000229 playing_ = false;
230 start = ShouldStartProcessing();
231 }
232 UpdateProcessing(start);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000233 return 0;
234}
235
236bool FakeAudioCaptureModule::Playing() const {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000237 rtc::CritScope cs(&crit_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000238 return playing_;
239}
240
241int32_t FakeAudioCaptureModule::StartRecording() {
242 if (!rec_is_initialized_) {
243 return -1;
244 }
wu@webrtc.org8804a292013-10-22 23:09:20 +0000245 {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000246 rtc::CritScope cs(&crit_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000247 recording_ = true;
248 }
249 bool start = true;
250 UpdateProcessing(start);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000251 return 0;
252}
253
254int32_t FakeAudioCaptureModule::StopRecording() {
wu@webrtc.org8804a292013-10-22 23:09:20 +0000255 bool start = false;
256 {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000257 rtc::CritScope cs(&crit_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000258 recording_ = false;
259 start = ShouldStartProcessing();
260 }
261 UpdateProcessing(start);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000262 return 0;
263}
264
265bool FakeAudioCaptureModule::Recording() const {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000266 rtc::CritScope cs(&crit_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000267 return recording_;
268}
269
270int32_t FakeAudioCaptureModule::SetAGC(bool /*enable*/) {
271 // No AGC but not needed since audio is pregenerated. Return success.
272 return 0;
273}
274
275bool FakeAudioCaptureModule::AGC() const {
nissec80e7412017-01-11 05:56:46 -0800276 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000277 return 0;
278}
279
280int32_t FakeAudioCaptureModule::SetWaveOutVolume(uint16_t /*volume_left*/,
281 uint16_t /*volume_right*/) {
nissec80e7412017-01-11 05:56:46 -0800282 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000283 return 0;
284}
285
286int32_t FakeAudioCaptureModule::WaveOutVolume(
287 uint16_t* /*volume_left*/,
288 uint16_t* /*volume_right*/) const {
nissec80e7412017-01-11 05:56:46 -0800289 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000290 return 0;
291}
292
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000293int32_t FakeAudioCaptureModule::InitSpeaker() {
294 // No speaker, just playing from file. Return success.
295 return 0;
296}
297
298bool FakeAudioCaptureModule::SpeakerIsInitialized() const {
nissec80e7412017-01-11 05:56:46 -0800299 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000300 return 0;
301}
302
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000303int32_t FakeAudioCaptureModule::InitMicrophone() {
304 // No microphone, just playing from file. Return success.
305 return 0;
306}
307
308bool FakeAudioCaptureModule::MicrophoneIsInitialized() const {
nissec80e7412017-01-11 05:56:46 -0800309 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000310 return 0;
311}
312
313int32_t FakeAudioCaptureModule::SpeakerVolumeIsAvailable(bool* /*available*/) {
nissec80e7412017-01-11 05:56:46 -0800314 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000315 return 0;
316}
317
318int32_t FakeAudioCaptureModule::SetSpeakerVolume(uint32_t /*volume*/) {
nissec80e7412017-01-11 05:56:46 -0800319 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000320 return 0;
321}
322
323int32_t FakeAudioCaptureModule::SpeakerVolume(uint32_t* /*volume*/) const {
nissec80e7412017-01-11 05:56:46 -0800324 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000325 return 0;
326}
327
328int32_t FakeAudioCaptureModule::MaxSpeakerVolume(
329 uint32_t* /*max_volume*/) const {
nissec80e7412017-01-11 05:56:46 -0800330 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000331 return 0;
332}
333
334int32_t FakeAudioCaptureModule::MinSpeakerVolume(
335 uint32_t* /*min_volume*/) const {
nissec80e7412017-01-11 05:56:46 -0800336 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000337 return 0;
338}
339
340int32_t FakeAudioCaptureModule::SpeakerVolumeStepSize(
341 uint16_t* /*step_size*/) const {
nissec80e7412017-01-11 05:56:46 -0800342 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000343 return 0;
344}
345
346int32_t FakeAudioCaptureModule::MicrophoneVolumeIsAvailable(
347 bool* /*available*/) {
nissec80e7412017-01-11 05:56:46 -0800348 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000349 return 0;
350}
351
wu@webrtc.org8804a292013-10-22 23:09:20 +0000352int32_t FakeAudioCaptureModule::SetMicrophoneVolume(uint32_t volume) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000353 rtc::CritScope cs(&crit_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000354 current_mic_level_ = volume;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000355 return 0;
356}
357
358int32_t FakeAudioCaptureModule::MicrophoneVolume(uint32_t* volume) const {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000359 rtc::CritScope cs(&crit_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000360 *volume = current_mic_level_;
361 return 0;
362}
363
364int32_t FakeAudioCaptureModule::MaxMicrophoneVolume(
365 uint32_t* max_volume) const {
366 *max_volume = kMaxVolume;
367 return 0;
368}
369
370int32_t FakeAudioCaptureModule::MinMicrophoneVolume(
371 uint32_t* /*min_volume*/) const {
nissec80e7412017-01-11 05:56:46 -0800372 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000373 return 0;
374}
375
376int32_t FakeAudioCaptureModule::MicrophoneVolumeStepSize(
377 uint16_t* /*step_size*/) const {
nissec80e7412017-01-11 05:56:46 -0800378 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000379 return 0;
380}
381
382int32_t FakeAudioCaptureModule::SpeakerMuteIsAvailable(bool* /*available*/) {
nissec80e7412017-01-11 05:56:46 -0800383 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000384 return 0;
385}
386
387int32_t FakeAudioCaptureModule::SetSpeakerMute(bool /*enable*/) {
nissec80e7412017-01-11 05:56:46 -0800388 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000389 return 0;
390}
391
392int32_t FakeAudioCaptureModule::SpeakerMute(bool* /*enabled*/) const {
nissec80e7412017-01-11 05:56:46 -0800393 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000394 return 0;
395}
396
397int32_t FakeAudioCaptureModule::MicrophoneMuteIsAvailable(bool* /*available*/) {
nissec80e7412017-01-11 05:56:46 -0800398 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000399 return 0;
400}
401
402int32_t FakeAudioCaptureModule::SetMicrophoneMute(bool /*enable*/) {
nissec80e7412017-01-11 05:56:46 -0800403 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000404 return 0;
405}
406
407int32_t FakeAudioCaptureModule::MicrophoneMute(bool* /*enabled*/) const {
nissec80e7412017-01-11 05:56:46 -0800408 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000409 return 0;
410}
411
412int32_t FakeAudioCaptureModule::MicrophoneBoostIsAvailable(
413 bool* /*available*/) {
nissec80e7412017-01-11 05:56:46 -0800414 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000415 return 0;
416}
417
418int32_t FakeAudioCaptureModule::SetMicrophoneBoost(bool /*enable*/) {
nissec80e7412017-01-11 05:56:46 -0800419 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000420 return 0;
421}
422
423int32_t FakeAudioCaptureModule::MicrophoneBoost(bool* /*enabled*/) const {
nissec80e7412017-01-11 05:56:46 -0800424 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000425 return 0;
426}
427
428int32_t FakeAudioCaptureModule::StereoPlayoutIsAvailable(
429 bool* available) const {
430 // No recording device, just dropping audio. Stereo can be dropped just
431 // as easily as mono.
432 *available = true;
433 return 0;
434}
435
436int32_t FakeAudioCaptureModule::SetStereoPlayout(bool /*enable*/) {
437 // No recording device, just dropping audio. Stereo can be dropped just
438 // as easily as mono.
439 return 0;
440}
441
442int32_t FakeAudioCaptureModule::StereoPlayout(bool* /*enabled*/) const {
nissec80e7412017-01-11 05:56:46 -0800443 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000444 return 0;
445}
446
447int32_t FakeAudioCaptureModule::StereoRecordingIsAvailable(
448 bool* available) const {
449 // Keep thing simple. No stereo recording.
450 *available = false;
451 return 0;
452}
453
454int32_t FakeAudioCaptureModule::SetStereoRecording(bool enable) {
455 if (!enable) {
456 return 0;
457 }
458 return -1;
459}
460
461int32_t FakeAudioCaptureModule::StereoRecording(bool* /*enabled*/) const {
nissec80e7412017-01-11 05:56:46 -0800462 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000463 return 0;
464}
465
466int32_t FakeAudioCaptureModule::SetRecordingChannel(
467 const ChannelType channel) {
468 if (channel != AudioDeviceModule::kChannelBoth) {
469 // There is no right or left in mono. I.e. kChannelBoth should be used for
470 // mono.
nissec80e7412017-01-11 05:56:46 -0800471 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000472 return -1;
473 }
474 return 0;
475}
476
477int32_t FakeAudioCaptureModule::RecordingChannel(ChannelType* channel) const {
478 // Stereo recording not supported. However, WebRTC ADM returns kChannelBoth
479 // in that case. Do the same here.
480 *channel = AudioDeviceModule::kChannelBoth;
481 return 0;
482}
483
484int32_t FakeAudioCaptureModule::SetPlayoutBuffer(const BufferType /*type*/,
485 uint16_t /*size_ms*/) {
nissec80e7412017-01-11 05:56:46 -0800486 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000487 return 0;
488}
489
490int32_t FakeAudioCaptureModule::PlayoutBuffer(BufferType* /*type*/,
491 uint16_t* /*size_ms*/) const {
nissec80e7412017-01-11 05:56:46 -0800492 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000493 return 0;
494}
495
496int32_t FakeAudioCaptureModule::PlayoutDelay(uint16_t* delay_ms) const {
497 // No delay since audio frames are dropped.
498 *delay_ms = 0;
499 return 0;
500}
501
502int32_t FakeAudioCaptureModule::RecordingDelay(uint16_t* /*delay_ms*/) const {
nissec80e7412017-01-11 05:56:46 -0800503 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000504 return 0;
505}
506
507int32_t FakeAudioCaptureModule::CPULoad(uint16_t* /*load*/) const {
nissec80e7412017-01-11 05:56:46 -0800508 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000509 return 0;
510}
511
512int32_t FakeAudioCaptureModule::StartRawOutputFileRecording(
513 const char /*pcm_file_name_utf8*/[webrtc::kAdmMaxFileNameSize]) {
nissec80e7412017-01-11 05:56:46 -0800514 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000515 return 0;
516}
517
518int32_t FakeAudioCaptureModule::StopRawOutputFileRecording() {
nissec80e7412017-01-11 05:56:46 -0800519 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000520 return 0;
521}
522
523int32_t FakeAudioCaptureModule::StartRawInputFileRecording(
524 const char /*pcm_file_name_utf8*/[webrtc::kAdmMaxFileNameSize]) {
nissec80e7412017-01-11 05:56:46 -0800525 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000526 return 0;
527}
528
529int32_t FakeAudioCaptureModule::StopRawInputFileRecording() {
nissec80e7412017-01-11 05:56:46 -0800530 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000531 return 0;
532}
533
534int32_t FakeAudioCaptureModule::SetRecordingSampleRate(
535 const uint32_t /*samples_per_sec*/) {
nissec80e7412017-01-11 05:56:46 -0800536 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000537 return 0;
538}
539
540int32_t FakeAudioCaptureModule::RecordingSampleRate(
541 uint32_t* /*samples_per_sec*/) const {
nissec80e7412017-01-11 05:56:46 -0800542 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000543 return 0;
544}
545
546int32_t FakeAudioCaptureModule::SetPlayoutSampleRate(
547 const uint32_t /*samples_per_sec*/) {
nissec80e7412017-01-11 05:56:46 -0800548 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000549 return 0;
550}
551
552int32_t FakeAudioCaptureModule::PlayoutSampleRate(
553 uint32_t* /*samples_per_sec*/) const {
nissec80e7412017-01-11 05:56:46 -0800554 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000555 return 0;
556}
557
558int32_t FakeAudioCaptureModule::ResetAudioDevice() {
nissec80e7412017-01-11 05:56:46 -0800559 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000560 return 0;
561}
562
563int32_t FakeAudioCaptureModule::SetLoudspeakerStatus(bool /*enable*/) {
nissec80e7412017-01-11 05:56:46 -0800564 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000565 return 0;
566}
567
568int32_t FakeAudioCaptureModule::GetLoudspeakerStatus(bool* /*enabled*/) const {
nissec80e7412017-01-11 05:56:46 -0800569 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000570 return 0;
571}
572
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000573void FakeAudioCaptureModule::OnMessage(rtc::Message* msg) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000574 switch (msg->message_id) {
wu@webrtc.org8804a292013-10-22 23:09:20 +0000575 case MSG_START_PROCESS:
576 StartProcessP();
577 break;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000578 case MSG_RUN_PROCESS:
579 ProcessFrameP();
580 break;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000581 default:
582 // All existing messages should be caught. Getting here should never
583 // happen.
nissec80e7412017-01-11 05:56:46 -0800584 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000585 }
586}
587
588bool FakeAudioCaptureModule::Initialize() {
589 // Set the send buffer samples high enough that it would not occur on the
590 // remote side unless a packet containing a sample of that magnitude has been
591 // sent to it. Note that the audio processing pipeline will likely distort the
592 // original signal.
593 SetSendBuffer(kHighSampleValue);
Honghai Zhang82d78622016-05-06 11:29:15 -0700594 last_process_time_ms_ = rtc::TimeMillis();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000595 return true;
596}
597
598void FakeAudioCaptureModule::SetSendBuffer(int value) {
599 Sample* buffer_ptr = reinterpret_cast<Sample*>(send_buffer_);
Peter Kastingdce40cf2015-08-24 14:52:23 -0700600 const size_t buffer_size_in_samples =
Peter Kasting728d9032015-06-11 14:31:38 -0700601 sizeof(send_buffer_) / kNumberBytesPerSample;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700602 for (size_t i = 0; i < buffer_size_in_samples; ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000603 buffer_ptr[i] = value;
604 }
605}
606
607void FakeAudioCaptureModule::ResetRecBuffer() {
608 memset(rec_buffer_, 0, sizeof(rec_buffer_));
609}
610
611bool FakeAudioCaptureModule::CheckRecBuffer(int value) {
612 const Sample* buffer_ptr = reinterpret_cast<const Sample*>(rec_buffer_);
Peter Kastingdce40cf2015-08-24 14:52:23 -0700613 const size_t buffer_size_in_samples =
Peter Kasting728d9032015-06-11 14:31:38 -0700614 sizeof(rec_buffer_) / kNumberBytesPerSample;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700615 for (size_t i = 0; i < buffer_size_in_samples; ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000616 if (buffer_ptr[i] >= value) return true;
617 }
618 return false;
619}
620
wu@webrtc.org8804a292013-10-22 23:09:20 +0000621bool FakeAudioCaptureModule::ShouldStartProcessing() {
622 return recording_ || playing_;
623}
624
625void FakeAudioCaptureModule::UpdateProcessing(bool start) {
626 if (start) {
deadbeefee8c6d32015-08-13 14:27:18 -0700627 if (!process_thread_) {
628 process_thread_.reset(new rtc::Thread());
629 process_thread_->Start();
630 }
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700631 process_thread_->Post(RTC_FROM_HERE, this, MSG_START_PROCESS);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000632 } else {
deadbeefee8c6d32015-08-13 14:27:18 -0700633 if (process_thread_) {
634 process_thread_->Stop();
635 process_thread_.reset(nullptr);
636 }
637 started_ = false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000638 }
639}
640
wu@webrtc.org8804a292013-10-22 23:09:20 +0000641void FakeAudioCaptureModule::StartProcessP() {
nissec8ee8822017-01-18 07:20:55 -0800642 RTC_CHECK(process_thread_->IsCurrent());
wu@webrtc.org8804a292013-10-22 23:09:20 +0000643 if (started_) {
644 // Already started.
645 return;
646 }
647 ProcessFrameP();
648}
649
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000650void FakeAudioCaptureModule::ProcessFrameP() {
nissec8ee8822017-01-18 07:20:55 -0800651 RTC_CHECK(process_thread_->IsCurrent());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000652 if (!started_) {
Honghai Zhang82d78622016-05-06 11:29:15 -0700653 next_frame_time_ = rtc::TimeMillis();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000654 started_ = true;
655 }
wu@webrtc.org8804a292013-10-22 23:09:20 +0000656
wu@webrtc.org8804a292013-10-22 23:09:20 +0000657 {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000658 rtc::CritScope cs(&crit_);
deadbeefee8c6d32015-08-13 14:27:18 -0700659 // Receive and send frames every kTimePerFrameMs.
660 if (playing_) {
661 ReceiveFrameP();
662 }
663 if (recording_) {
664 SendFrameP();
665 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000666 }
667
668 next_frame_time_ += kTimePerFrameMs;
Honghai Zhang82d78622016-05-06 11:29:15 -0700669 const int64_t current_time = rtc::TimeMillis();
670 const int64_t wait_time =
Peter Boström0c4e06b2015-10-07 12:23:21 +0200671 (next_frame_time_ > current_time) ? next_frame_time_ - current_time : 0;
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700672 process_thread_->PostDelayed(RTC_FROM_HERE, wait_time, this, MSG_RUN_PROCESS);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000673}
674
675void FakeAudioCaptureModule::ReceiveFrameP() {
nissec8ee8822017-01-18 07:20:55 -0800676 RTC_CHECK(process_thread_->IsCurrent());
wu@webrtc.org8804a292013-10-22 23:09:20 +0000677 {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000678 rtc::CritScope cs(&crit_callback_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000679 if (!audio_callback_) {
680 return;
681 }
682 ResetRecBuffer();
Peter Kastingdce40cf2015-08-24 14:52:23 -0700683 size_t nSamplesOut = 0;
wu@webrtc.org94454b72014-06-05 20:34:08 +0000684 int64_t elapsed_time_ms = 0;
wu@webrtc.orgcb711f72014-05-19 17:39:11 +0000685 int64_t ntp_time_ms = 0;
686 if (audio_callback_->NeedMorePlayData(kNumberSamples, kNumberBytesPerSample,
687 kNumberOfChannels, kSamplesPerSecond,
688 rec_buffer_, nSamplesOut,
wu@webrtc.org94454b72014-06-05 20:34:08 +0000689 &elapsed_time_ms, &ntp_time_ms) != 0) {
nissec80e7412017-01-11 05:56:46 -0800690 RTC_NOTREACHED();
wu@webrtc.org8804a292013-10-22 23:09:20 +0000691 }
nissec8ee8822017-01-18 07:20:55 -0800692 RTC_CHECK(nSamplesOut == kNumberSamples);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000693 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000694 // The SetBuffer() function ensures that after decoding, the audio buffer
695 // should contain samples of similar magnitude (there is likely to be some
696 // distortion due to the audio pipeline). If one sample is detected to
697 // have the same or greater magnitude somewhere in the frame, an actual frame
698 // has been received from the remote side (i.e. faked frames are not being
699 // pulled).
wu@webrtc.org8804a292013-10-22 23:09:20 +0000700 if (CheckRecBuffer(kHighSampleValue)) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000701 rtc::CritScope cs(&crit_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000702 ++frames_received_;
703 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000704}
705
706void FakeAudioCaptureModule::SendFrameP() {
nissec8ee8822017-01-18 07:20:55 -0800707 RTC_CHECK(process_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000708 rtc::CritScope cs(&crit_callback_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000709 if (!audio_callback_) {
710 return;
711 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000712 bool key_pressed = false;
wu@webrtc.org8804a292013-10-22 23:09:20 +0000713 uint32_t current_mic_level = 0;
714 MicrophoneVolume(&current_mic_level);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000715 if (audio_callback_->RecordedDataIsAvailable(send_buffer_, kNumberSamples,
716 kNumberBytesPerSample,
717 kNumberOfChannels,
718 kSamplesPerSecond, kTotalDelayMs,
wu@webrtc.org8804a292013-10-22 23:09:20 +0000719 kClockDriftMs, current_mic_level,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000720 key_pressed,
wu@webrtc.org8804a292013-10-22 23:09:20 +0000721 current_mic_level) != 0) {
nissec80e7412017-01-11 05:56:46 -0800722 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000723 }
wu@webrtc.org8804a292013-10-22 23:09:20 +0000724 SetMicrophoneVolume(current_mic_level);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000725}