blob: 43ff664d0c12c5ad5267a04d1cc7226d7305cc6a [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
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000013#include "webrtc/base/common.h"
14#include "webrtc/base/refcount.h"
15#include "webrtc/base/thread.h"
16#include "webrtc/base/timeutils.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000017
18// Audio sample value that is high enough that it doesn't occur naturally when
19// frames are being faked. E.g. NetEq will not generate this large sample value
20// unless it has received an audio frame containing a sample of this value.
21// Even simpler buffers would likely just contain audio sample values of 0.
22static const int kHighSampleValue = 10000;
23
24// Same value as src/modules/audio_device/main/source/audio_device_config.h in
25// https://code.google.com/p/webrtc/
Honghai Zhang82d78622016-05-06 11:29:15 -070026static const int kAdmMaxIdleTimeProcess = 1000;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000027
28// Constants here are derived by running VoE using a real ADM.
29// The constants correspond to 10ms of mono audio at 44kHz.
30static const int kTimePerFrameMs = 10;
Peter Kastingb7e50542015-06-11 12:55:50 -070031static const uint8_t kNumberOfChannels = 1;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000032static const int kSamplesPerSecond = 44000;
33static const int kTotalDelayMs = 0;
34static const int kClockDriftMs = 0;
35static const uint32_t kMaxVolume = 14392;
36
37enum {
wu@webrtc.org8804a292013-10-22 23:09:20 +000038 MSG_START_PROCESS,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000039 MSG_RUN_PROCESS,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000040};
41
deadbeefee8c6d32015-08-13 14:27:18 -070042FakeAudioCaptureModule::FakeAudioCaptureModule()
henrike@webrtc.org28e20752013-07-10 00:45:36 +000043 : last_process_time_ms_(0),
deadbeefee8c6d32015-08-13 14:27:18 -070044 audio_callback_(nullptr),
henrike@webrtc.org28e20752013-07-10 00:45:36 +000045 recording_(false),
46 playing_(false),
47 play_is_initialized_(false),
48 rec_is_initialized_(false),
49 current_mic_level_(kMaxVolume),
50 started_(false),
51 next_frame_time_(0),
henrike@webrtc.org28e20752013-07-10 00:45:36 +000052 frames_received_(0) {
53}
54
55FakeAudioCaptureModule::~FakeAudioCaptureModule() {
deadbeefee8c6d32015-08-13 14:27:18 -070056 if (process_thread_) {
57 process_thread_->Stop();
58 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +000059}
60
deadbeefee8c6d32015-08-13 14:27:18 -070061rtc::scoped_refptr<FakeAudioCaptureModule> FakeAudioCaptureModule::Create() {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000062 rtc::scoped_refptr<FakeAudioCaptureModule> capture_module(
deadbeefee8c6d32015-08-13 14:27:18 -070063 new rtc::RefCountedObject<FakeAudioCaptureModule>());
henrike@webrtc.org28e20752013-07-10 00:45:36 +000064 if (!capture_module->Initialize()) {
deadbeefee8c6d32015-08-13 14:27:18 -070065 return nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000066 }
67 return capture_module;
68}
69
70int FakeAudioCaptureModule::frames_received() const {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000071 rtc::CritScope cs(&crit_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000072 return frames_received_;
73}
74
pkasting@chromium.org0b1534c2014-12-15 22:09:40 +000075int64_t FakeAudioCaptureModule::TimeUntilNextProcess() {
Honghai Zhang82d78622016-05-06 11:29:15 -070076 const int64_t current_time = rtc::TimeMillis();
henrike@webrtc.org28e20752013-07-10 00:45:36 +000077 if (current_time < last_process_time_ms_) {
78 // TODO: wraparound could be handled more gracefully.
79 return 0;
80 }
Honghai Zhang82d78622016-05-06 11:29:15 -070081 const int64_t elapsed_time = current_time - last_process_time_ms_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000082 if (kAdmMaxIdleTimeProcess < elapsed_time) {
83 return 0;
84 }
85 return kAdmMaxIdleTimeProcess - elapsed_time;
86}
87
pbosa26ac922016-02-25 04:50:01 -080088void FakeAudioCaptureModule::Process() {
Honghai Zhang82d78622016-05-06 11:29:15 -070089 last_process_time_ms_ = rtc::TimeMillis();
henrike@webrtc.org28e20752013-07-10 00:45:36 +000090}
91
henrike@webrtc.org28e20752013-07-10 00:45:36 +000092int32_t FakeAudioCaptureModule::ActiveAudioLayer(
93 AudioLayer* /*audio_layer*/) const {
94 ASSERT(false);
95 return 0;
96}
97
98webrtc::AudioDeviceModule::ErrorCode FakeAudioCaptureModule::LastError() const {
99 ASSERT(false);
100 return webrtc::AudioDeviceModule::kAdmErrNone;
101}
102
103int32_t FakeAudioCaptureModule::RegisterEventObserver(
104 webrtc::AudioDeviceObserver* /*event_callback*/) {
105 // Only used to report warnings and errors. This fake implementation won't
106 // generate any so discard this callback.
107 return 0;
108}
109
110int32_t FakeAudioCaptureModule::RegisterAudioCallback(
111 webrtc::AudioTransport* audio_callback) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000112 rtc::CritScope cs(&crit_callback_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000113 audio_callback_ = audio_callback;
114 return 0;
115}
116
117int32_t FakeAudioCaptureModule::Init() {
118 // Initialize is called by the factory method. Safe to ignore this Init call.
119 return 0;
120}
121
122int32_t FakeAudioCaptureModule::Terminate() {
123 // Clean up in the destructor. No action here, just success.
124 return 0;
125}
126
127bool FakeAudioCaptureModule::Initialized() const {
128 ASSERT(false);
129 return 0;
130}
131
132int16_t FakeAudioCaptureModule::PlayoutDevices() {
133 ASSERT(false);
134 return 0;
135}
136
137int16_t FakeAudioCaptureModule::RecordingDevices() {
138 ASSERT(false);
139 return 0;
140}
141
142int32_t FakeAudioCaptureModule::PlayoutDeviceName(
143 uint16_t /*index*/,
144 char /*name*/[webrtc::kAdmMaxDeviceNameSize],
145 char /*guid*/[webrtc::kAdmMaxGuidSize]) {
146 ASSERT(false);
147 return 0;
148}
149
150int32_t FakeAudioCaptureModule::RecordingDeviceName(
151 uint16_t /*index*/,
152 char /*name*/[webrtc::kAdmMaxDeviceNameSize],
153 char /*guid*/[webrtc::kAdmMaxGuidSize]) {
154 ASSERT(false);
155 return 0;
156}
157
158int32_t FakeAudioCaptureModule::SetPlayoutDevice(uint16_t /*index*/) {
159 // No playout device, just playing from file. Return success.
160 return 0;
161}
162
163int32_t FakeAudioCaptureModule::SetPlayoutDevice(WindowsDeviceType /*device*/) {
164 if (play_is_initialized_) {
165 return -1;
166 }
167 return 0;
168}
169
170int32_t FakeAudioCaptureModule::SetRecordingDevice(uint16_t /*index*/) {
171 // No recording device, just dropping audio. Return success.
172 return 0;
173}
174
175int32_t FakeAudioCaptureModule::SetRecordingDevice(
176 WindowsDeviceType /*device*/) {
177 if (rec_is_initialized_) {
178 return -1;
179 }
180 return 0;
181}
182
183int32_t FakeAudioCaptureModule::PlayoutIsAvailable(bool* /*available*/) {
184 ASSERT(false);
185 return 0;
186}
187
188int32_t FakeAudioCaptureModule::InitPlayout() {
189 play_is_initialized_ = true;
190 return 0;
191}
192
193bool FakeAudioCaptureModule::PlayoutIsInitialized() const {
194 return play_is_initialized_;
195}
196
197int32_t FakeAudioCaptureModule::RecordingIsAvailable(bool* /*available*/) {
198 ASSERT(false);
199 return 0;
200}
201
202int32_t FakeAudioCaptureModule::InitRecording() {
203 rec_is_initialized_ = true;
204 return 0;
205}
206
207bool FakeAudioCaptureModule::RecordingIsInitialized() const {
solenbergd53a3f92016-04-14 13:56:37 -0700208 return rec_is_initialized_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000209}
210
211int32_t FakeAudioCaptureModule::StartPlayout() {
212 if (!play_is_initialized_) {
213 return -1;
214 }
wu@webrtc.org8804a292013-10-22 23:09:20 +0000215 {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000216 rtc::CritScope cs(&crit_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000217 playing_ = true;
218 }
219 bool start = true;
220 UpdateProcessing(start);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000221 return 0;
222}
223
224int32_t FakeAudioCaptureModule::StopPlayout() {
wu@webrtc.org8804a292013-10-22 23:09:20 +0000225 bool start = false;
226 {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000227 rtc::CritScope cs(&crit_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000228 playing_ = false;
229 start = ShouldStartProcessing();
230 }
231 UpdateProcessing(start);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000232 return 0;
233}
234
235bool FakeAudioCaptureModule::Playing() const {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000236 rtc::CritScope cs(&crit_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000237 return playing_;
238}
239
240int32_t FakeAudioCaptureModule::StartRecording() {
241 if (!rec_is_initialized_) {
242 return -1;
243 }
wu@webrtc.org8804a292013-10-22 23:09:20 +0000244 {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000245 rtc::CritScope cs(&crit_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000246 recording_ = true;
247 }
248 bool start = true;
249 UpdateProcessing(start);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000250 return 0;
251}
252
253int32_t FakeAudioCaptureModule::StopRecording() {
wu@webrtc.org8804a292013-10-22 23:09:20 +0000254 bool start = false;
255 {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000256 rtc::CritScope cs(&crit_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000257 recording_ = false;
258 start = ShouldStartProcessing();
259 }
260 UpdateProcessing(start);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000261 return 0;
262}
263
264bool FakeAudioCaptureModule::Recording() const {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000265 rtc::CritScope cs(&crit_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000266 return recording_;
267}
268
269int32_t FakeAudioCaptureModule::SetAGC(bool /*enable*/) {
270 // No AGC but not needed since audio is pregenerated. Return success.
271 return 0;
272}
273
274bool FakeAudioCaptureModule::AGC() const {
275 ASSERT(false);
276 return 0;
277}
278
279int32_t FakeAudioCaptureModule::SetWaveOutVolume(uint16_t /*volume_left*/,
280 uint16_t /*volume_right*/) {
281 ASSERT(false);
282 return 0;
283}
284
285int32_t FakeAudioCaptureModule::WaveOutVolume(
286 uint16_t* /*volume_left*/,
287 uint16_t* /*volume_right*/) const {
288 ASSERT(false);
289 return 0;
290}
291
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000292int32_t FakeAudioCaptureModule::InitSpeaker() {
293 // No speaker, just playing from file. Return success.
294 return 0;
295}
296
297bool FakeAudioCaptureModule::SpeakerIsInitialized() const {
298 ASSERT(false);
299 return 0;
300}
301
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000302int32_t FakeAudioCaptureModule::InitMicrophone() {
303 // No microphone, just playing from file. Return success.
304 return 0;
305}
306
307bool FakeAudioCaptureModule::MicrophoneIsInitialized() const {
308 ASSERT(false);
309 return 0;
310}
311
312int32_t FakeAudioCaptureModule::SpeakerVolumeIsAvailable(bool* /*available*/) {
313 ASSERT(false);
314 return 0;
315}
316
317int32_t FakeAudioCaptureModule::SetSpeakerVolume(uint32_t /*volume*/) {
318 ASSERT(false);
319 return 0;
320}
321
322int32_t FakeAudioCaptureModule::SpeakerVolume(uint32_t* /*volume*/) const {
323 ASSERT(false);
324 return 0;
325}
326
327int32_t FakeAudioCaptureModule::MaxSpeakerVolume(
328 uint32_t* /*max_volume*/) const {
329 ASSERT(false);
330 return 0;
331}
332
333int32_t FakeAudioCaptureModule::MinSpeakerVolume(
334 uint32_t* /*min_volume*/) const {
335 ASSERT(false);
336 return 0;
337}
338
339int32_t FakeAudioCaptureModule::SpeakerVolumeStepSize(
340 uint16_t* /*step_size*/) const {
341 ASSERT(false);
342 return 0;
343}
344
345int32_t FakeAudioCaptureModule::MicrophoneVolumeIsAvailable(
346 bool* /*available*/) {
347 ASSERT(false);
348 return 0;
349}
350
wu@webrtc.org8804a292013-10-22 23:09:20 +0000351int32_t FakeAudioCaptureModule::SetMicrophoneVolume(uint32_t volume) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000352 rtc::CritScope cs(&crit_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000353 current_mic_level_ = volume;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000354 return 0;
355}
356
357int32_t FakeAudioCaptureModule::MicrophoneVolume(uint32_t* volume) const {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000358 rtc::CritScope cs(&crit_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000359 *volume = current_mic_level_;
360 return 0;
361}
362
363int32_t FakeAudioCaptureModule::MaxMicrophoneVolume(
364 uint32_t* max_volume) const {
365 *max_volume = kMaxVolume;
366 return 0;
367}
368
369int32_t FakeAudioCaptureModule::MinMicrophoneVolume(
370 uint32_t* /*min_volume*/) const {
371 ASSERT(false);
372 return 0;
373}
374
375int32_t FakeAudioCaptureModule::MicrophoneVolumeStepSize(
376 uint16_t* /*step_size*/) const {
377 ASSERT(false);
378 return 0;
379}
380
381int32_t FakeAudioCaptureModule::SpeakerMuteIsAvailable(bool* /*available*/) {
382 ASSERT(false);
383 return 0;
384}
385
386int32_t FakeAudioCaptureModule::SetSpeakerMute(bool /*enable*/) {
387 ASSERT(false);
388 return 0;
389}
390
391int32_t FakeAudioCaptureModule::SpeakerMute(bool* /*enabled*/) const {
392 ASSERT(false);
393 return 0;
394}
395
396int32_t FakeAudioCaptureModule::MicrophoneMuteIsAvailable(bool* /*available*/) {
397 ASSERT(false);
398 return 0;
399}
400
401int32_t FakeAudioCaptureModule::SetMicrophoneMute(bool /*enable*/) {
402 ASSERT(false);
403 return 0;
404}
405
406int32_t FakeAudioCaptureModule::MicrophoneMute(bool* /*enabled*/) const {
407 ASSERT(false);
408 return 0;
409}
410
411int32_t FakeAudioCaptureModule::MicrophoneBoostIsAvailable(
412 bool* /*available*/) {
413 ASSERT(false);
414 return 0;
415}
416
417int32_t FakeAudioCaptureModule::SetMicrophoneBoost(bool /*enable*/) {
418 ASSERT(false);
419 return 0;
420}
421
422int32_t FakeAudioCaptureModule::MicrophoneBoost(bool* /*enabled*/) const {
423 ASSERT(false);
424 return 0;
425}
426
427int32_t FakeAudioCaptureModule::StereoPlayoutIsAvailable(
428 bool* available) const {
429 // No recording device, just dropping audio. Stereo can be dropped just
430 // as easily as mono.
431 *available = true;
432 return 0;
433}
434
435int32_t FakeAudioCaptureModule::SetStereoPlayout(bool /*enable*/) {
436 // No recording device, just dropping audio. Stereo can be dropped just
437 // as easily as mono.
438 return 0;
439}
440
441int32_t FakeAudioCaptureModule::StereoPlayout(bool* /*enabled*/) const {
442 ASSERT(false);
443 return 0;
444}
445
446int32_t FakeAudioCaptureModule::StereoRecordingIsAvailable(
447 bool* available) const {
448 // Keep thing simple. No stereo recording.
449 *available = false;
450 return 0;
451}
452
453int32_t FakeAudioCaptureModule::SetStereoRecording(bool enable) {
454 if (!enable) {
455 return 0;
456 }
457 return -1;
458}
459
460int32_t FakeAudioCaptureModule::StereoRecording(bool* /*enabled*/) const {
461 ASSERT(false);
462 return 0;
463}
464
465int32_t FakeAudioCaptureModule::SetRecordingChannel(
466 const ChannelType channel) {
467 if (channel != AudioDeviceModule::kChannelBoth) {
468 // There is no right or left in mono. I.e. kChannelBoth should be used for
469 // mono.
470 ASSERT(false);
471 return -1;
472 }
473 return 0;
474}
475
476int32_t FakeAudioCaptureModule::RecordingChannel(ChannelType* channel) const {
477 // Stereo recording not supported. However, WebRTC ADM returns kChannelBoth
478 // in that case. Do the same here.
479 *channel = AudioDeviceModule::kChannelBoth;
480 return 0;
481}
482
483int32_t FakeAudioCaptureModule::SetPlayoutBuffer(const BufferType /*type*/,
484 uint16_t /*size_ms*/) {
485 ASSERT(false);
486 return 0;
487}
488
489int32_t FakeAudioCaptureModule::PlayoutBuffer(BufferType* /*type*/,
490 uint16_t* /*size_ms*/) const {
491 ASSERT(false);
492 return 0;
493}
494
495int32_t FakeAudioCaptureModule::PlayoutDelay(uint16_t* delay_ms) const {
496 // No delay since audio frames are dropped.
497 *delay_ms = 0;
498 return 0;
499}
500
501int32_t FakeAudioCaptureModule::RecordingDelay(uint16_t* /*delay_ms*/) const {
502 ASSERT(false);
503 return 0;
504}
505
506int32_t FakeAudioCaptureModule::CPULoad(uint16_t* /*load*/) const {
507 ASSERT(false);
508 return 0;
509}
510
511int32_t FakeAudioCaptureModule::StartRawOutputFileRecording(
512 const char /*pcm_file_name_utf8*/[webrtc::kAdmMaxFileNameSize]) {
513 ASSERT(false);
514 return 0;
515}
516
517int32_t FakeAudioCaptureModule::StopRawOutputFileRecording() {
518 ASSERT(false);
519 return 0;
520}
521
522int32_t FakeAudioCaptureModule::StartRawInputFileRecording(
523 const char /*pcm_file_name_utf8*/[webrtc::kAdmMaxFileNameSize]) {
524 ASSERT(false);
525 return 0;
526}
527
528int32_t FakeAudioCaptureModule::StopRawInputFileRecording() {
529 ASSERT(false);
530 return 0;
531}
532
533int32_t FakeAudioCaptureModule::SetRecordingSampleRate(
534 const uint32_t /*samples_per_sec*/) {
535 ASSERT(false);
536 return 0;
537}
538
539int32_t FakeAudioCaptureModule::RecordingSampleRate(
540 uint32_t* /*samples_per_sec*/) const {
541 ASSERT(false);
542 return 0;
543}
544
545int32_t FakeAudioCaptureModule::SetPlayoutSampleRate(
546 const uint32_t /*samples_per_sec*/) {
547 ASSERT(false);
548 return 0;
549}
550
551int32_t FakeAudioCaptureModule::PlayoutSampleRate(
552 uint32_t* /*samples_per_sec*/) const {
553 ASSERT(false);
554 return 0;
555}
556
557int32_t FakeAudioCaptureModule::ResetAudioDevice() {
558 ASSERT(false);
559 return 0;
560}
561
562int32_t FakeAudioCaptureModule::SetLoudspeakerStatus(bool /*enable*/) {
563 ASSERT(false);
564 return 0;
565}
566
567int32_t FakeAudioCaptureModule::GetLoudspeakerStatus(bool* /*enabled*/) const {
568 ASSERT(false);
569 return 0;
570}
571
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000572void FakeAudioCaptureModule::OnMessage(rtc::Message* msg) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000573 switch (msg->message_id) {
wu@webrtc.org8804a292013-10-22 23:09:20 +0000574 case MSG_START_PROCESS:
575 StartProcessP();
576 break;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000577 case MSG_RUN_PROCESS:
578 ProcessFrameP();
579 break;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000580 default:
581 // All existing messages should be caught. Getting here should never
582 // happen.
583 ASSERT(false);
584 }
585}
586
587bool FakeAudioCaptureModule::Initialize() {
588 // Set the send buffer samples high enough that it would not occur on the
589 // remote side unless a packet containing a sample of that magnitude has been
590 // sent to it. Note that the audio processing pipeline will likely distort the
591 // original signal.
592 SetSendBuffer(kHighSampleValue);
Honghai Zhang82d78622016-05-06 11:29:15 -0700593 last_process_time_ms_ = rtc::TimeMillis();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000594 return true;
595}
596
597void FakeAudioCaptureModule::SetSendBuffer(int value) {
598 Sample* buffer_ptr = reinterpret_cast<Sample*>(send_buffer_);
Peter Kastingdce40cf2015-08-24 14:52:23 -0700599 const size_t buffer_size_in_samples =
Peter Kasting728d9032015-06-11 14:31:38 -0700600 sizeof(send_buffer_) / kNumberBytesPerSample;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700601 for (size_t i = 0; i < buffer_size_in_samples; ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000602 buffer_ptr[i] = value;
603 }
604}
605
606void FakeAudioCaptureModule::ResetRecBuffer() {
607 memset(rec_buffer_, 0, sizeof(rec_buffer_));
608}
609
610bool FakeAudioCaptureModule::CheckRecBuffer(int value) {
611 const Sample* buffer_ptr = reinterpret_cast<const Sample*>(rec_buffer_);
Peter Kastingdce40cf2015-08-24 14:52:23 -0700612 const size_t buffer_size_in_samples =
Peter Kasting728d9032015-06-11 14:31:38 -0700613 sizeof(rec_buffer_) / kNumberBytesPerSample;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700614 for (size_t i = 0; i < buffer_size_in_samples; ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000615 if (buffer_ptr[i] >= value) return true;
616 }
617 return false;
618}
619
wu@webrtc.org8804a292013-10-22 23:09:20 +0000620bool FakeAudioCaptureModule::ShouldStartProcessing() {
621 return recording_ || playing_;
622}
623
624void FakeAudioCaptureModule::UpdateProcessing(bool start) {
625 if (start) {
deadbeefee8c6d32015-08-13 14:27:18 -0700626 if (!process_thread_) {
627 process_thread_.reset(new rtc::Thread());
628 process_thread_->Start();
629 }
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700630 process_thread_->Post(RTC_FROM_HERE, this, MSG_START_PROCESS);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000631 } else {
deadbeefee8c6d32015-08-13 14:27:18 -0700632 if (process_thread_) {
633 process_thread_->Stop();
634 process_thread_.reset(nullptr);
635 }
636 started_ = false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000637 }
638}
639
wu@webrtc.org8804a292013-10-22 23:09:20 +0000640void FakeAudioCaptureModule::StartProcessP() {
deadbeefee8c6d32015-08-13 14:27:18 -0700641 ASSERT(process_thread_->IsCurrent());
wu@webrtc.org8804a292013-10-22 23:09:20 +0000642 if (started_) {
643 // Already started.
644 return;
645 }
646 ProcessFrameP();
647}
648
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000649void FakeAudioCaptureModule::ProcessFrameP() {
deadbeefee8c6d32015-08-13 14:27:18 -0700650 ASSERT(process_thread_->IsCurrent());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000651 if (!started_) {
Honghai Zhang82d78622016-05-06 11:29:15 -0700652 next_frame_time_ = rtc::TimeMillis();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000653 started_ = true;
654 }
wu@webrtc.org8804a292013-10-22 23:09:20 +0000655
wu@webrtc.org8804a292013-10-22 23:09:20 +0000656 {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000657 rtc::CritScope cs(&crit_);
deadbeefee8c6d32015-08-13 14:27:18 -0700658 // Receive and send frames every kTimePerFrameMs.
659 if (playing_) {
660 ReceiveFrameP();
661 }
662 if (recording_) {
663 SendFrameP();
664 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000665 }
666
667 next_frame_time_ += kTimePerFrameMs;
Honghai Zhang82d78622016-05-06 11:29:15 -0700668 const int64_t current_time = rtc::TimeMillis();
669 const int64_t wait_time =
Peter Boström0c4e06b2015-10-07 12:23:21 +0200670 (next_frame_time_ > current_time) ? next_frame_time_ - current_time : 0;
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700671 process_thread_->PostDelayed(RTC_FROM_HERE, wait_time, this, MSG_RUN_PROCESS);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000672}
673
674void FakeAudioCaptureModule::ReceiveFrameP() {
deadbeefee8c6d32015-08-13 14:27:18 -0700675 ASSERT(process_thread_->IsCurrent());
wu@webrtc.org8804a292013-10-22 23:09:20 +0000676 {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000677 rtc::CritScope cs(&crit_callback_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000678 if (!audio_callback_) {
679 return;
680 }
681 ResetRecBuffer();
Peter Kastingdce40cf2015-08-24 14:52:23 -0700682 size_t nSamplesOut = 0;
wu@webrtc.org94454b72014-06-05 20:34:08 +0000683 int64_t elapsed_time_ms = 0;
wu@webrtc.orgcb711f72014-05-19 17:39:11 +0000684 int64_t ntp_time_ms = 0;
685 if (audio_callback_->NeedMorePlayData(kNumberSamples, kNumberBytesPerSample,
686 kNumberOfChannels, kSamplesPerSecond,
687 rec_buffer_, nSamplesOut,
wu@webrtc.org94454b72014-06-05 20:34:08 +0000688 &elapsed_time_ms, &ntp_time_ms) != 0) {
wu@webrtc.org8804a292013-10-22 23:09:20 +0000689 ASSERT(false);
690 }
691 ASSERT(nSamplesOut == kNumberSamples);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000692 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000693 // The SetBuffer() function ensures that after decoding, the audio buffer
694 // should contain samples of similar magnitude (there is likely to be some
695 // distortion due to the audio pipeline). If one sample is detected to
696 // have the same or greater magnitude somewhere in the frame, an actual frame
697 // has been received from the remote side (i.e. faked frames are not being
698 // pulled).
wu@webrtc.org8804a292013-10-22 23:09:20 +0000699 if (CheckRecBuffer(kHighSampleValue)) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000700 rtc::CritScope cs(&crit_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000701 ++frames_received_;
702 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000703}
704
705void FakeAudioCaptureModule::SendFrameP() {
deadbeefee8c6d32015-08-13 14:27:18 -0700706 ASSERT(process_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000707 rtc::CritScope cs(&crit_callback_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000708 if (!audio_callback_) {
709 return;
710 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000711 bool key_pressed = false;
wu@webrtc.org8804a292013-10-22 23:09:20 +0000712 uint32_t current_mic_level = 0;
713 MicrophoneVolume(&current_mic_level);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000714 if (audio_callback_->RecordedDataIsAvailable(send_buffer_, kNumberSamples,
715 kNumberBytesPerSample,
716 kNumberOfChannels,
717 kSamplesPerSecond, kTotalDelayMs,
wu@webrtc.org8804a292013-10-22 23:09:20 +0000718 kClockDriftMs, current_mic_level,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000719 key_pressed,
wu@webrtc.org8804a292013-10-22 23:09:20 +0000720 current_mic_level) != 0) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000721 ASSERT(false);
722 }
wu@webrtc.org8804a292013-10-22 23:09:20 +0000723 SetMicrophoneVolume(current_mic_level);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000724}
725