blob: dbbc0441cdd88cba78143edde97e77cca0f6afaf [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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "pc/test/fakeaudiocapturemodule.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000012
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020013#include "rtc_base/checks.h"
14#include "rtc_base/refcount.h"
Niels Möller84255bb2017-10-06 13:43:23 +020015#include "rtc_base/refcountedobject.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020016#include "rtc_base/thread.h"
17#include "rtc_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
henrike@webrtc.org28e20752013-07-10 00:45:36 +000025// Constants here are derived by running VoE using a real ADM.
26// The constants correspond to 10ms of mono audio at 44kHz.
27static const int kTimePerFrameMs = 10;
Peter Kastingb7e50542015-06-11 12:55:50 -070028static const uint8_t kNumberOfChannels = 1;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000029static const int kSamplesPerSecond = 44000;
30static const int kTotalDelayMs = 0;
31static const int kClockDriftMs = 0;
32static const uint32_t kMaxVolume = 14392;
33
34enum {
wu@webrtc.org8804a292013-10-22 23:09:20 +000035 MSG_START_PROCESS,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000036 MSG_RUN_PROCESS,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000037};
38
deadbeefee8c6d32015-08-13 14:27:18 -070039FakeAudioCaptureModule::FakeAudioCaptureModule()
Fredrik Solenberga32dd012017-10-04 13:27:21 +020040 : audio_callback_(nullptr),
henrike@webrtc.org28e20752013-07-10 00:45:36 +000041 recording_(false),
42 playing_(false),
43 play_is_initialized_(false),
44 rec_is_initialized_(false),
45 current_mic_level_(kMaxVolume),
46 started_(false),
47 next_frame_time_(0),
henrike@webrtc.org28e20752013-07-10 00:45:36 +000048 frames_received_(0) {
49}
50
51FakeAudioCaptureModule::~FakeAudioCaptureModule() {
deadbeefee8c6d32015-08-13 14:27:18 -070052 if (process_thread_) {
53 process_thread_->Stop();
54 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +000055}
56
deadbeefee8c6d32015-08-13 14:27:18 -070057rtc::scoped_refptr<FakeAudioCaptureModule> FakeAudioCaptureModule::Create() {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000058 rtc::scoped_refptr<FakeAudioCaptureModule> capture_module(
deadbeefee8c6d32015-08-13 14:27:18 -070059 new rtc::RefCountedObject<FakeAudioCaptureModule>());
henrike@webrtc.org28e20752013-07-10 00:45:36 +000060 if (!capture_module->Initialize()) {
deadbeefee8c6d32015-08-13 14:27:18 -070061 return nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000062 }
63 return capture_module;
64}
65
66int FakeAudioCaptureModule::frames_received() const {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000067 rtc::CritScope cs(&crit_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000068 return frames_received_;
69}
70
henrike@webrtc.org28e20752013-07-10 00:45:36 +000071int32_t FakeAudioCaptureModule::ActiveAudioLayer(
72 AudioLayer* /*audio_layer*/) const {
nissec80e7412017-01-11 05:56:46 -080073 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +000074 return 0;
75}
76
henrike@webrtc.org28e20752013-07-10 00:45:36 +000077int32_t FakeAudioCaptureModule::RegisterAudioCallback(
78 webrtc::AudioTransport* audio_callback) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000079 rtc::CritScope cs(&crit_callback_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000080 audio_callback_ = audio_callback;
81 return 0;
82}
83
84int32_t FakeAudioCaptureModule::Init() {
85 // Initialize is called by the factory method. Safe to ignore this Init call.
86 return 0;
87}
88
89int32_t FakeAudioCaptureModule::Terminate() {
90 // Clean up in the destructor. No action here, just success.
91 return 0;
92}
93
94bool FakeAudioCaptureModule::Initialized() const {
nissec80e7412017-01-11 05:56:46 -080095 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +000096 return 0;
97}
98
99int16_t FakeAudioCaptureModule::PlayoutDevices() {
nissec80e7412017-01-11 05:56:46 -0800100 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000101 return 0;
102}
103
104int16_t FakeAudioCaptureModule::RecordingDevices() {
nissec80e7412017-01-11 05:56:46 -0800105 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000106 return 0;
107}
108
109int32_t FakeAudioCaptureModule::PlayoutDeviceName(
110 uint16_t /*index*/,
111 char /*name*/[webrtc::kAdmMaxDeviceNameSize],
112 char /*guid*/[webrtc::kAdmMaxGuidSize]) {
nissec80e7412017-01-11 05:56:46 -0800113 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000114 return 0;
115}
116
117int32_t FakeAudioCaptureModule::RecordingDeviceName(
118 uint16_t /*index*/,
119 char /*name*/[webrtc::kAdmMaxDeviceNameSize],
120 char /*guid*/[webrtc::kAdmMaxGuidSize]) {
nissec80e7412017-01-11 05:56:46 -0800121 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000122 return 0;
123}
124
125int32_t FakeAudioCaptureModule::SetPlayoutDevice(uint16_t /*index*/) {
126 // No playout device, just playing from file. Return success.
127 return 0;
128}
129
130int32_t FakeAudioCaptureModule::SetPlayoutDevice(WindowsDeviceType /*device*/) {
131 if (play_is_initialized_) {
132 return -1;
133 }
134 return 0;
135}
136
137int32_t FakeAudioCaptureModule::SetRecordingDevice(uint16_t /*index*/) {
138 // No recording device, just dropping audio. Return success.
139 return 0;
140}
141
142int32_t FakeAudioCaptureModule::SetRecordingDevice(
143 WindowsDeviceType /*device*/) {
144 if (rec_is_initialized_) {
145 return -1;
146 }
147 return 0;
148}
149
150int32_t FakeAudioCaptureModule::PlayoutIsAvailable(bool* /*available*/) {
nissec80e7412017-01-11 05:56:46 -0800151 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000152 return 0;
153}
154
155int32_t FakeAudioCaptureModule::InitPlayout() {
156 play_is_initialized_ = true;
157 return 0;
158}
159
160bool FakeAudioCaptureModule::PlayoutIsInitialized() const {
161 return play_is_initialized_;
162}
163
164int32_t FakeAudioCaptureModule::RecordingIsAvailable(bool* /*available*/) {
nissec80e7412017-01-11 05:56:46 -0800165 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000166 return 0;
167}
168
169int32_t FakeAudioCaptureModule::InitRecording() {
170 rec_is_initialized_ = true;
171 return 0;
172}
173
174bool FakeAudioCaptureModule::RecordingIsInitialized() const {
solenbergd53a3f92016-04-14 13:56:37 -0700175 return rec_is_initialized_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000176}
177
178int32_t FakeAudioCaptureModule::StartPlayout() {
179 if (!play_is_initialized_) {
180 return -1;
181 }
wu@webrtc.org8804a292013-10-22 23:09:20 +0000182 {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000183 rtc::CritScope cs(&crit_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000184 playing_ = true;
185 }
186 bool start = true;
187 UpdateProcessing(start);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000188 return 0;
189}
190
191int32_t FakeAudioCaptureModule::StopPlayout() {
wu@webrtc.org8804a292013-10-22 23:09:20 +0000192 bool start = false;
193 {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000194 rtc::CritScope cs(&crit_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000195 playing_ = false;
196 start = ShouldStartProcessing();
197 }
198 UpdateProcessing(start);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000199 return 0;
200}
201
202bool FakeAudioCaptureModule::Playing() const {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000203 rtc::CritScope cs(&crit_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000204 return playing_;
205}
206
207int32_t FakeAudioCaptureModule::StartRecording() {
208 if (!rec_is_initialized_) {
209 return -1;
210 }
wu@webrtc.org8804a292013-10-22 23:09:20 +0000211 {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000212 rtc::CritScope cs(&crit_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000213 recording_ = true;
214 }
215 bool start = true;
216 UpdateProcessing(start);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000217 return 0;
218}
219
220int32_t FakeAudioCaptureModule::StopRecording() {
wu@webrtc.org8804a292013-10-22 23:09:20 +0000221 bool start = false;
222 {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000223 rtc::CritScope cs(&crit_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000224 recording_ = false;
225 start = ShouldStartProcessing();
226 }
227 UpdateProcessing(start);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000228 return 0;
229}
230
231bool FakeAudioCaptureModule::Recording() const {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000232 rtc::CritScope cs(&crit_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000233 return recording_;
234}
235
236int32_t FakeAudioCaptureModule::SetAGC(bool /*enable*/) {
237 // No AGC but not needed since audio is pregenerated. Return success.
238 return 0;
239}
240
241bool FakeAudioCaptureModule::AGC() const {
nissec80e7412017-01-11 05:56:46 -0800242 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000243 return 0;
244}
245
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000246int32_t FakeAudioCaptureModule::InitSpeaker() {
247 // No speaker, just playing from file. Return success.
248 return 0;
249}
250
251bool FakeAudioCaptureModule::SpeakerIsInitialized() const {
nissec80e7412017-01-11 05:56:46 -0800252 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000253 return 0;
254}
255
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000256int32_t FakeAudioCaptureModule::InitMicrophone() {
257 // No microphone, just playing from file. Return success.
258 return 0;
259}
260
261bool FakeAudioCaptureModule::MicrophoneIsInitialized() const {
nissec80e7412017-01-11 05:56:46 -0800262 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000263 return 0;
264}
265
266int32_t FakeAudioCaptureModule::SpeakerVolumeIsAvailable(bool* /*available*/) {
nissec80e7412017-01-11 05:56:46 -0800267 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000268 return 0;
269}
270
271int32_t FakeAudioCaptureModule::SetSpeakerVolume(uint32_t /*volume*/) {
nissec80e7412017-01-11 05:56:46 -0800272 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000273 return 0;
274}
275
276int32_t FakeAudioCaptureModule::SpeakerVolume(uint32_t* /*volume*/) const {
nissec80e7412017-01-11 05:56:46 -0800277 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000278 return 0;
279}
280
281int32_t FakeAudioCaptureModule::MaxSpeakerVolume(
282 uint32_t* /*max_volume*/) const {
nissec80e7412017-01-11 05:56:46 -0800283 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000284 return 0;
285}
286
287int32_t FakeAudioCaptureModule::MinSpeakerVolume(
288 uint32_t* /*min_volume*/) 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::MicrophoneVolumeIsAvailable(
294 bool* /*available*/) {
nissec80e7412017-01-11 05:56:46 -0800295 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000296 return 0;
297}
298
wu@webrtc.org8804a292013-10-22 23:09:20 +0000299int32_t FakeAudioCaptureModule::SetMicrophoneVolume(uint32_t volume) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000300 rtc::CritScope cs(&crit_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000301 current_mic_level_ = volume;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000302 return 0;
303}
304
305int32_t FakeAudioCaptureModule::MicrophoneVolume(uint32_t* volume) const {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000306 rtc::CritScope cs(&crit_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000307 *volume = current_mic_level_;
308 return 0;
309}
310
311int32_t FakeAudioCaptureModule::MaxMicrophoneVolume(
312 uint32_t* max_volume) const {
313 *max_volume = kMaxVolume;
314 return 0;
315}
316
317int32_t FakeAudioCaptureModule::MinMicrophoneVolume(
318 uint32_t* /*min_volume*/) const {
nissec80e7412017-01-11 05:56:46 -0800319 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000320 return 0;
321}
322
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000323int32_t FakeAudioCaptureModule::SpeakerMuteIsAvailable(bool* /*available*/) {
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::SetSpeakerMute(bool /*enable*/) {
nissec80e7412017-01-11 05:56:46 -0800329 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000330 return 0;
331}
332
333int32_t FakeAudioCaptureModule::SpeakerMute(bool* /*enabled*/) const {
nissec80e7412017-01-11 05:56:46 -0800334 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000335 return 0;
336}
337
338int32_t FakeAudioCaptureModule::MicrophoneMuteIsAvailable(bool* /*available*/) {
nissec80e7412017-01-11 05:56:46 -0800339 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000340 return 0;
341}
342
343int32_t FakeAudioCaptureModule::SetMicrophoneMute(bool /*enable*/) {
nissec80e7412017-01-11 05:56:46 -0800344 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000345 return 0;
346}
347
348int32_t FakeAudioCaptureModule::MicrophoneMute(bool* /*enabled*/) const {
nissec80e7412017-01-11 05:56:46 -0800349 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000350 return 0;
351}
352
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000353int32_t FakeAudioCaptureModule::StereoPlayoutIsAvailable(
354 bool* available) const {
355 // No recording device, just dropping audio. Stereo can be dropped just
356 // as easily as mono.
357 *available = true;
358 return 0;
359}
360
361int32_t FakeAudioCaptureModule::SetStereoPlayout(bool /*enable*/) {
362 // No recording device, just dropping audio. Stereo can be dropped just
363 // as easily as mono.
364 return 0;
365}
366
367int32_t FakeAudioCaptureModule::StereoPlayout(bool* /*enabled*/) const {
nissec80e7412017-01-11 05:56:46 -0800368 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000369 return 0;
370}
371
372int32_t FakeAudioCaptureModule::StereoRecordingIsAvailable(
373 bool* available) const {
374 // Keep thing simple. No stereo recording.
375 *available = false;
376 return 0;
377}
378
379int32_t FakeAudioCaptureModule::SetStereoRecording(bool enable) {
380 if (!enable) {
381 return 0;
382 }
383 return -1;
384}
385
386int32_t FakeAudioCaptureModule::StereoRecording(bool* /*enabled*/) const {
nissec80e7412017-01-11 05:56:46 -0800387 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000388 return 0;
389}
390
391int32_t FakeAudioCaptureModule::SetRecordingChannel(
392 const ChannelType channel) {
393 if (channel != AudioDeviceModule::kChannelBoth) {
394 // There is no right or left in mono. I.e. kChannelBoth should be used for
395 // mono.
nissec80e7412017-01-11 05:56:46 -0800396 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000397 return -1;
398 }
399 return 0;
400}
401
402int32_t FakeAudioCaptureModule::RecordingChannel(ChannelType* channel) const {
403 // Stereo recording not supported. However, WebRTC ADM returns kChannelBoth
404 // in that case. Do the same here.
405 *channel = AudioDeviceModule::kChannelBoth;
406 return 0;
407}
408
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000409int32_t FakeAudioCaptureModule::PlayoutDelay(uint16_t* delay_ms) const {
410 // No delay since audio frames are dropped.
411 *delay_ms = 0;
412 return 0;
413}
414
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000415int32_t FakeAudioCaptureModule::SetRecordingSampleRate(
416 const uint32_t /*samples_per_sec*/) {
nissec80e7412017-01-11 05:56:46 -0800417 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000418 return 0;
419}
420
421int32_t FakeAudioCaptureModule::RecordingSampleRate(
422 uint32_t* /*samples_per_sec*/) const {
nissec80e7412017-01-11 05:56:46 -0800423 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000424 return 0;
425}
426
427int32_t FakeAudioCaptureModule::SetPlayoutSampleRate(
428 const uint32_t /*samples_per_sec*/) {
nissec80e7412017-01-11 05:56:46 -0800429 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000430 return 0;
431}
432
433int32_t FakeAudioCaptureModule::PlayoutSampleRate(
434 uint32_t* /*samples_per_sec*/) const {
nissec80e7412017-01-11 05:56:46 -0800435 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000436 return 0;
437}
438
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000439int32_t FakeAudioCaptureModule::SetLoudspeakerStatus(bool /*enable*/) {
nissec80e7412017-01-11 05:56:46 -0800440 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000441 return 0;
442}
443
444int32_t FakeAudioCaptureModule::GetLoudspeakerStatus(bool* /*enabled*/) const {
nissec80e7412017-01-11 05:56:46 -0800445 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000446 return 0;
447}
448
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000449void FakeAudioCaptureModule::OnMessage(rtc::Message* msg) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000450 switch (msg->message_id) {
wu@webrtc.org8804a292013-10-22 23:09:20 +0000451 case MSG_START_PROCESS:
452 StartProcessP();
453 break;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000454 case MSG_RUN_PROCESS:
455 ProcessFrameP();
456 break;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000457 default:
458 // All existing messages should be caught. Getting here should never
459 // happen.
nissec80e7412017-01-11 05:56:46 -0800460 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000461 }
462}
463
464bool FakeAudioCaptureModule::Initialize() {
465 // Set the send buffer samples high enough that it would not occur on the
466 // remote side unless a packet containing a sample of that magnitude has been
467 // sent to it. Note that the audio processing pipeline will likely distort the
468 // original signal.
469 SetSendBuffer(kHighSampleValue);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000470 return true;
471}
472
473void FakeAudioCaptureModule::SetSendBuffer(int value) {
474 Sample* buffer_ptr = reinterpret_cast<Sample*>(send_buffer_);
Peter Kastingdce40cf2015-08-24 14:52:23 -0700475 const size_t buffer_size_in_samples =
Peter Kasting728d9032015-06-11 14:31:38 -0700476 sizeof(send_buffer_) / kNumberBytesPerSample;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700477 for (size_t i = 0; i < buffer_size_in_samples; ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000478 buffer_ptr[i] = value;
479 }
480}
481
482void FakeAudioCaptureModule::ResetRecBuffer() {
483 memset(rec_buffer_, 0, sizeof(rec_buffer_));
484}
485
486bool FakeAudioCaptureModule::CheckRecBuffer(int value) {
487 const Sample* buffer_ptr = reinterpret_cast<const Sample*>(rec_buffer_);
Peter Kastingdce40cf2015-08-24 14:52:23 -0700488 const size_t buffer_size_in_samples =
Peter Kasting728d9032015-06-11 14:31:38 -0700489 sizeof(rec_buffer_) / kNumberBytesPerSample;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700490 for (size_t i = 0; i < buffer_size_in_samples; ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000491 if (buffer_ptr[i] >= value) return true;
492 }
493 return false;
494}
495
wu@webrtc.org8804a292013-10-22 23:09:20 +0000496bool FakeAudioCaptureModule::ShouldStartProcessing() {
497 return recording_ || playing_;
498}
499
500void FakeAudioCaptureModule::UpdateProcessing(bool start) {
501 if (start) {
deadbeefee8c6d32015-08-13 14:27:18 -0700502 if (!process_thread_) {
tommie7251592017-07-14 14:44:46 -0700503 process_thread_ = rtc::Thread::Create();
deadbeefee8c6d32015-08-13 14:27:18 -0700504 process_thread_->Start();
505 }
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700506 process_thread_->Post(RTC_FROM_HERE, this, MSG_START_PROCESS);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000507 } else {
deadbeefee8c6d32015-08-13 14:27:18 -0700508 if (process_thread_) {
509 process_thread_->Stop();
510 process_thread_.reset(nullptr);
511 }
512 started_ = false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000513 }
514}
515
wu@webrtc.org8804a292013-10-22 23:09:20 +0000516void FakeAudioCaptureModule::StartProcessP() {
nissec8ee8822017-01-18 07:20:55 -0800517 RTC_CHECK(process_thread_->IsCurrent());
wu@webrtc.org8804a292013-10-22 23:09:20 +0000518 if (started_) {
519 // Already started.
520 return;
521 }
522 ProcessFrameP();
523}
524
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000525void FakeAudioCaptureModule::ProcessFrameP() {
nissec8ee8822017-01-18 07:20:55 -0800526 RTC_CHECK(process_thread_->IsCurrent());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000527 if (!started_) {
Honghai Zhang82d78622016-05-06 11:29:15 -0700528 next_frame_time_ = rtc::TimeMillis();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000529 started_ = true;
530 }
wu@webrtc.org8804a292013-10-22 23:09:20 +0000531
wu@webrtc.org8804a292013-10-22 23:09:20 +0000532 {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000533 rtc::CritScope cs(&crit_);
deadbeefee8c6d32015-08-13 14:27:18 -0700534 // Receive and send frames every kTimePerFrameMs.
535 if (playing_) {
536 ReceiveFrameP();
537 }
538 if (recording_) {
539 SendFrameP();
540 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000541 }
542
543 next_frame_time_ += kTimePerFrameMs;
Honghai Zhang82d78622016-05-06 11:29:15 -0700544 const int64_t current_time = rtc::TimeMillis();
545 const int64_t wait_time =
Peter Boström0c4e06b2015-10-07 12:23:21 +0200546 (next_frame_time_ > current_time) ? next_frame_time_ - current_time : 0;
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700547 process_thread_->PostDelayed(RTC_FROM_HERE, wait_time, this, MSG_RUN_PROCESS);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000548}
549
550void FakeAudioCaptureModule::ReceiveFrameP() {
nissec8ee8822017-01-18 07:20:55 -0800551 RTC_CHECK(process_thread_->IsCurrent());
wu@webrtc.org8804a292013-10-22 23:09:20 +0000552 {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000553 rtc::CritScope cs(&crit_callback_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000554 if (!audio_callback_) {
555 return;
556 }
557 ResetRecBuffer();
Peter Kastingdce40cf2015-08-24 14:52:23 -0700558 size_t nSamplesOut = 0;
wu@webrtc.org94454b72014-06-05 20:34:08 +0000559 int64_t elapsed_time_ms = 0;
wu@webrtc.orgcb711f72014-05-19 17:39:11 +0000560 int64_t ntp_time_ms = 0;
561 if (audio_callback_->NeedMorePlayData(kNumberSamples, kNumberBytesPerSample,
562 kNumberOfChannels, kSamplesPerSecond,
563 rec_buffer_, nSamplesOut,
wu@webrtc.org94454b72014-06-05 20:34:08 +0000564 &elapsed_time_ms, &ntp_time_ms) != 0) {
nissec80e7412017-01-11 05:56:46 -0800565 RTC_NOTREACHED();
wu@webrtc.org8804a292013-10-22 23:09:20 +0000566 }
nissec8ee8822017-01-18 07:20:55 -0800567 RTC_CHECK(nSamplesOut == kNumberSamples);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000568 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000569 // The SetBuffer() function ensures that after decoding, the audio buffer
570 // should contain samples of similar magnitude (there is likely to be some
571 // distortion due to the audio pipeline). If one sample is detected to
572 // have the same or greater magnitude somewhere in the frame, an actual frame
573 // has been received from the remote side (i.e. faked frames are not being
574 // pulled).
wu@webrtc.org8804a292013-10-22 23:09:20 +0000575 if (CheckRecBuffer(kHighSampleValue)) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000576 rtc::CritScope cs(&crit_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000577 ++frames_received_;
578 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000579}
580
581void FakeAudioCaptureModule::SendFrameP() {
nissec8ee8822017-01-18 07:20:55 -0800582 RTC_CHECK(process_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000583 rtc::CritScope cs(&crit_callback_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000584 if (!audio_callback_) {
585 return;
586 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000587 bool key_pressed = false;
wu@webrtc.org8804a292013-10-22 23:09:20 +0000588 uint32_t current_mic_level = 0;
589 MicrophoneVolume(&current_mic_level);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000590 if (audio_callback_->RecordedDataIsAvailable(send_buffer_, kNumberSamples,
591 kNumberBytesPerSample,
592 kNumberOfChannels,
593 kSamplesPerSecond, kTotalDelayMs,
wu@webrtc.org8804a292013-10-22 23:09:20 +0000594 kClockDriftMs, current_mic_level,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000595 key_pressed,
wu@webrtc.org8804a292013-10-22 23:09:20 +0000596 current_mic_level) != 0) {
nissec80e7412017-01-11 05:56:46 -0800597 RTC_NOTREACHED();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000598 }
wu@webrtc.org8804a292013-10-22 23:09:20 +0000599 SetMicrophoneVolume(current_mic_level);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000600}