blob: b85f30b8361b0746791d017ade29bba677da2919 [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/
Peter Boström0c4e06b2015-10-07 12:23:21 +020026static const uint32_t 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() {
Peter Boström0c4e06b2015-10-07 12:23:21 +020076 const uint32_t current_time = rtc::Time();
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 }
Peter Boström0c4e06b2015-10-07 12:23:21 +020081 const uint32_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
88int32_t FakeAudioCaptureModule::Process() {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000089 last_process_time_ms_ = rtc::Time();
henrike@webrtc.org28e20752013-07-10 00:45:36 +000090 return 0;
91}
92
henrike@webrtc.org28e20752013-07-10 00:45:36 +000093int32_t FakeAudioCaptureModule::ActiveAudioLayer(
94 AudioLayer* /*audio_layer*/) const {
95 ASSERT(false);
96 return 0;
97}
98
99webrtc::AudioDeviceModule::ErrorCode FakeAudioCaptureModule::LastError() const {
100 ASSERT(false);
101 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 {
129 ASSERT(false);
130 return 0;
131}
132
133int16_t FakeAudioCaptureModule::PlayoutDevices() {
134 ASSERT(false);
135 return 0;
136}
137
138int16_t FakeAudioCaptureModule::RecordingDevices() {
139 ASSERT(false);
140 return 0;
141}
142
143int32_t FakeAudioCaptureModule::PlayoutDeviceName(
144 uint16_t /*index*/,
145 char /*name*/[webrtc::kAdmMaxDeviceNameSize],
146 char /*guid*/[webrtc::kAdmMaxGuidSize]) {
147 ASSERT(false);
148 return 0;
149}
150
151int32_t FakeAudioCaptureModule::RecordingDeviceName(
152 uint16_t /*index*/,
153 char /*name*/[webrtc::kAdmMaxDeviceNameSize],
154 char /*guid*/[webrtc::kAdmMaxGuidSize]) {
155 ASSERT(false);
156 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*/) {
185 ASSERT(false);
186 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*/) {
199 ASSERT(false);
200 return 0;
201}
202
203int32_t FakeAudioCaptureModule::InitRecording() {
204 rec_is_initialized_ = true;
205 return 0;
206}
207
208bool FakeAudioCaptureModule::RecordingIsInitialized() const {
209 ASSERT(false);
210 return 0;
211}
212
213int32_t FakeAudioCaptureModule::StartPlayout() {
214 if (!play_is_initialized_) {
215 return -1;
216 }
wu@webrtc.org8804a292013-10-22 23:09:20 +0000217 {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000218 rtc::CritScope cs(&crit_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000219 playing_ = true;
220 }
221 bool start = true;
222 UpdateProcessing(start);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000223 return 0;
224}
225
226int32_t FakeAudioCaptureModule::StopPlayout() {
wu@webrtc.org8804a292013-10-22 23:09:20 +0000227 bool start = false;
228 {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000229 rtc::CritScope cs(&crit_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000230 playing_ = false;
231 start = ShouldStartProcessing();
232 }
233 UpdateProcessing(start);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000234 return 0;
235}
236
237bool FakeAudioCaptureModule::Playing() const {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000238 rtc::CritScope cs(&crit_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000239 return playing_;
240}
241
242int32_t FakeAudioCaptureModule::StartRecording() {
243 if (!rec_is_initialized_) {
244 return -1;
245 }
wu@webrtc.org8804a292013-10-22 23:09:20 +0000246 {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000247 rtc::CritScope cs(&crit_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000248 recording_ = true;
249 }
250 bool start = true;
251 UpdateProcessing(start);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000252 return 0;
253}
254
255int32_t FakeAudioCaptureModule::StopRecording() {
wu@webrtc.org8804a292013-10-22 23:09:20 +0000256 bool start = false;
257 {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000258 rtc::CritScope cs(&crit_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000259 recording_ = false;
260 start = ShouldStartProcessing();
261 }
262 UpdateProcessing(start);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000263 return 0;
264}
265
266bool FakeAudioCaptureModule::Recording() const {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000267 rtc::CritScope cs(&crit_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000268 return recording_;
269}
270
271int32_t FakeAudioCaptureModule::SetAGC(bool /*enable*/) {
272 // No AGC but not needed since audio is pregenerated. Return success.
273 return 0;
274}
275
276bool FakeAudioCaptureModule::AGC() const {
277 ASSERT(false);
278 return 0;
279}
280
281int32_t FakeAudioCaptureModule::SetWaveOutVolume(uint16_t /*volume_left*/,
282 uint16_t /*volume_right*/) {
283 ASSERT(false);
284 return 0;
285}
286
287int32_t FakeAudioCaptureModule::WaveOutVolume(
288 uint16_t* /*volume_left*/,
289 uint16_t* /*volume_right*/) const {
290 ASSERT(false);
291 return 0;
292}
293
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000294int32_t FakeAudioCaptureModule::InitSpeaker() {
295 // No speaker, just playing from file. Return success.
296 return 0;
297}
298
299bool FakeAudioCaptureModule::SpeakerIsInitialized() const {
300 ASSERT(false);
301 return 0;
302}
303
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000304int32_t FakeAudioCaptureModule::InitMicrophone() {
305 // No microphone, just playing from file. Return success.
306 return 0;
307}
308
309bool FakeAudioCaptureModule::MicrophoneIsInitialized() const {
310 ASSERT(false);
311 return 0;
312}
313
314int32_t FakeAudioCaptureModule::SpeakerVolumeIsAvailable(bool* /*available*/) {
315 ASSERT(false);
316 return 0;
317}
318
319int32_t FakeAudioCaptureModule::SetSpeakerVolume(uint32_t /*volume*/) {
320 ASSERT(false);
321 return 0;
322}
323
324int32_t FakeAudioCaptureModule::SpeakerVolume(uint32_t* /*volume*/) const {
325 ASSERT(false);
326 return 0;
327}
328
329int32_t FakeAudioCaptureModule::MaxSpeakerVolume(
330 uint32_t* /*max_volume*/) const {
331 ASSERT(false);
332 return 0;
333}
334
335int32_t FakeAudioCaptureModule::MinSpeakerVolume(
336 uint32_t* /*min_volume*/) const {
337 ASSERT(false);
338 return 0;
339}
340
341int32_t FakeAudioCaptureModule::SpeakerVolumeStepSize(
342 uint16_t* /*step_size*/) const {
343 ASSERT(false);
344 return 0;
345}
346
347int32_t FakeAudioCaptureModule::MicrophoneVolumeIsAvailable(
348 bool* /*available*/) {
349 ASSERT(false);
350 return 0;
351}
352
wu@webrtc.org8804a292013-10-22 23:09:20 +0000353int32_t FakeAudioCaptureModule::SetMicrophoneVolume(uint32_t volume) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000354 rtc::CritScope cs(&crit_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000355 current_mic_level_ = volume;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000356 return 0;
357}
358
359int32_t FakeAudioCaptureModule::MicrophoneVolume(uint32_t* volume) const {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000360 rtc::CritScope cs(&crit_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000361 *volume = current_mic_level_;
362 return 0;
363}
364
365int32_t FakeAudioCaptureModule::MaxMicrophoneVolume(
366 uint32_t* max_volume) const {
367 *max_volume = kMaxVolume;
368 return 0;
369}
370
371int32_t FakeAudioCaptureModule::MinMicrophoneVolume(
372 uint32_t* /*min_volume*/) const {
373 ASSERT(false);
374 return 0;
375}
376
377int32_t FakeAudioCaptureModule::MicrophoneVolumeStepSize(
378 uint16_t* /*step_size*/) const {
379 ASSERT(false);
380 return 0;
381}
382
383int32_t FakeAudioCaptureModule::SpeakerMuteIsAvailable(bool* /*available*/) {
384 ASSERT(false);
385 return 0;
386}
387
388int32_t FakeAudioCaptureModule::SetSpeakerMute(bool /*enable*/) {
389 ASSERT(false);
390 return 0;
391}
392
393int32_t FakeAudioCaptureModule::SpeakerMute(bool* /*enabled*/) const {
394 ASSERT(false);
395 return 0;
396}
397
398int32_t FakeAudioCaptureModule::MicrophoneMuteIsAvailable(bool* /*available*/) {
399 ASSERT(false);
400 return 0;
401}
402
403int32_t FakeAudioCaptureModule::SetMicrophoneMute(bool /*enable*/) {
404 ASSERT(false);
405 return 0;
406}
407
408int32_t FakeAudioCaptureModule::MicrophoneMute(bool* /*enabled*/) const {
409 ASSERT(false);
410 return 0;
411}
412
413int32_t FakeAudioCaptureModule::MicrophoneBoostIsAvailable(
414 bool* /*available*/) {
415 ASSERT(false);
416 return 0;
417}
418
419int32_t FakeAudioCaptureModule::SetMicrophoneBoost(bool /*enable*/) {
420 ASSERT(false);
421 return 0;
422}
423
424int32_t FakeAudioCaptureModule::MicrophoneBoost(bool* /*enabled*/) const {
425 ASSERT(false);
426 return 0;
427}
428
429int32_t FakeAudioCaptureModule::StereoPlayoutIsAvailable(
430 bool* available) const {
431 // No recording device, just dropping audio. Stereo can be dropped just
432 // as easily as mono.
433 *available = true;
434 return 0;
435}
436
437int32_t FakeAudioCaptureModule::SetStereoPlayout(bool /*enable*/) {
438 // No recording device, just dropping audio. Stereo can be dropped just
439 // as easily as mono.
440 return 0;
441}
442
443int32_t FakeAudioCaptureModule::StereoPlayout(bool* /*enabled*/) const {
444 ASSERT(false);
445 return 0;
446}
447
448int32_t FakeAudioCaptureModule::StereoRecordingIsAvailable(
449 bool* available) const {
450 // Keep thing simple. No stereo recording.
451 *available = false;
452 return 0;
453}
454
455int32_t FakeAudioCaptureModule::SetStereoRecording(bool enable) {
456 if (!enable) {
457 return 0;
458 }
459 return -1;
460}
461
462int32_t FakeAudioCaptureModule::StereoRecording(bool* /*enabled*/) const {
463 ASSERT(false);
464 return 0;
465}
466
467int32_t FakeAudioCaptureModule::SetRecordingChannel(
468 const ChannelType channel) {
469 if (channel != AudioDeviceModule::kChannelBoth) {
470 // There is no right or left in mono. I.e. kChannelBoth should be used for
471 // mono.
472 ASSERT(false);
473 return -1;
474 }
475 return 0;
476}
477
478int32_t FakeAudioCaptureModule::RecordingChannel(ChannelType* channel) const {
479 // Stereo recording not supported. However, WebRTC ADM returns kChannelBoth
480 // in that case. Do the same here.
481 *channel = AudioDeviceModule::kChannelBoth;
482 return 0;
483}
484
485int32_t FakeAudioCaptureModule::SetPlayoutBuffer(const BufferType /*type*/,
486 uint16_t /*size_ms*/) {
487 ASSERT(false);
488 return 0;
489}
490
491int32_t FakeAudioCaptureModule::PlayoutBuffer(BufferType* /*type*/,
492 uint16_t* /*size_ms*/) const {
493 ASSERT(false);
494 return 0;
495}
496
497int32_t FakeAudioCaptureModule::PlayoutDelay(uint16_t* delay_ms) const {
498 // No delay since audio frames are dropped.
499 *delay_ms = 0;
500 return 0;
501}
502
503int32_t FakeAudioCaptureModule::RecordingDelay(uint16_t* /*delay_ms*/) const {
504 ASSERT(false);
505 return 0;
506}
507
508int32_t FakeAudioCaptureModule::CPULoad(uint16_t* /*load*/) const {
509 ASSERT(false);
510 return 0;
511}
512
513int32_t FakeAudioCaptureModule::StartRawOutputFileRecording(
514 const char /*pcm_file_name_utf8*/[webrtc::kAdmMaxFileNameSize]) {
515 ASSERT(false);
516 return 0;
517}
518
519int32_t FakeAudioCaptureModule::StopRawOutputFileRecording() {
520 ASSERT(false);
521 return 0;
522}
523
524int32_t FakeAudioCaptureModule::StartRawInputFileRecording(
525 const char /*pcm_file_name_utf8*/[webrtc::kAdmMaxFileNameSize]) {
526 ASSERT(false);
527 return 0;
528}
529
530int32_t FakeAudioCaptureModule::StopRawInputFileRecording() {
531 ASSERT(false);
532 return 0;
533}
534
535int32_t FakeAudioCaptureModule::SetRecordingSampleRate(
536 const uint32_t /*samples_per_sec*/) {
537 ASSERT(false);
538 return 0;
539}
540
541int32_t FakeAudioCaptureModule::RecordingSampleRate(
542 uint32_t* /*samples_per_sec*/) const {
543 ASSERT(false);
544 return 0;
545}
546
547int32_t FakeAudioCaptureModule::SetPlayoutSampleRate(
548 const uint32_t /*samples_per_sec*/) {
549 ASSERT(false);
550 return 0;
551}
552
553int32_t FakeAudioCaptureModule::PlayoutSampleRate(
554 uint32_t* /*samples_per_sec*/) const {
555 ASSERT(false);
556 return 0;
557}
558
559int32_t FakeAudioCaptureModule::ResetAudioDevice() {
560 ASSERT(false);
561 return 0;
562}
563
564int32_t FakeAudioCaptureModule::SetLoudspeakerStatus(bool /*enable*/) {
565 ASSERT(false);
566 return 0;
567}
568
569int32_t FakeAudioCaptureModule::GetLoudspeakerStatus(bool* /*enabled*/) const {
570 ASSERT(false);
571 return 0;
572}
573
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000574void FakeAudioCaptureModule::OnMessage(rtc::Message* msg) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000575 switch (msg->message_id) {
wu@webrtc.org8804a292013-10-22 23:09:20 +0000576 case MSG_START_PROCESS:
577 StartProcessP();
578 break;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000579 case MSG_RUN_PROCESS:
580 ProcessFrameP();
581 break;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000582 default:
583 // All existing messages should be caught. Getting here should never
584 // happen.
585 ASSERT(false);
586 }
587}
588
589bool FakeAudioCaptureModule::Initialize() {
590 // Set the send buffer samples high enough that it would not occur on the
591 // remote side unless a packet containing a sample of that magnitude has been
592 // sent to it. Note that the audio processing pipeline will likely distort the
593 // original signal.
594 SetSendBuffer(kHighSampleValue);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000595 last_process_time_ms_ = rtc::Time();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000596 return true;
597}
598
599void FakeAudioCaptureModule::SetSendBuffer(int value) {
600 Sample* buffer_ptr = reinterpret_cast<Sample*>(send_buffer_);
Peter Kastingdce40cf2015-08-24 14:52:23 -0700601 const size_t buffer_size_in_samples =
Peter Kasting728d9032015-06-11 14:31:38 -0700602 sizeof(send_buffer_) / kNumberBytesPerSample;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700603 for (size_t i = 0; i < buffer_size_in_samples; ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000604 buffer_ptr[i] = value;
605 }
606}
607
608void FakeAudioCaptureModule::ResetRecBuffer() {
609 memset(rec_buffer_, 0, sizeof(rec_buffer_));
610}
611
612bool FakeAudioCaptureModule::CheckRecBuffer(int value) {
613 const Sample* buffer_ptr = reinterpret_cast<const Sample*>(rec_buffer_);
Peter Kastingdce40cf2015-08-24 14:52:23 -0700614 const size_t buffer_size_in_samples =
Peter Kasting728d9032015-06-11 14:31:38 -0700615 sizeof(rec_buffer_) / kNumberBytesPerSample;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700616 for (size_t i = 0; i < buffer_size_in_samples; ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000617 if (buffer_ptr[i] >= value) return true;
618 }
619 return false;
620}
621
wu@webrtc.org8804a292013-10-22 23:09:20 +0000622bool FakeAudioCaptureModule::ShouldStartProcessing() {
623 return recording_ || playing_;
624}
625
626void FakeAudioCaptureModule::UpdateProcessing(bool start) {
627 if (start) {
deadbeefee8c6d32015-08-13 14:27:18 -0700628 if (!process_thread_) {
629 process_thread_.reset(new rtc::Thread());
630 process_thread_->Start();
631 }
wu@webrtc.org8804a292013-10-22 23:09:20 +0000632 process_thread_->Post(this, MSG_START_PROCESS);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000633 } else {
deadbeefee8c6d32015-08-13 14:27:18 -0700634 if (process_thread_) {
635 process_thread_->Stop();
636 process_thread_.reset(nullptr);
637 }
638 started_ = false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000639 }
640}
641
wu@webrtc.org8804a292013-10-22 23:09:20 +0000642void FakeAudioCaptureModule::StartProcessP() {
deadbeefee8c6d32015-08-13 14:27:18 -0700643 ASSERT(process_thread_->IsCurrent());
wu@webrtc.org8804a292013-10-22 23:09:20 +0000644 if (started_) {
645 // Already started.
646 return;
647 }
648 ProcessFrameP();
649}
650
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000651void FakeAudioCaptureModule::ProcessFrameP() {
deadbeefee8c6d32015-08-13 14:27:18 -0700652 ASSERT(process_thread_->IsCurrent());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000653 if (!started_) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000654 next_frame_time_ = rtc::Time();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000655 started_ = true;
656 }
wu@webrtc.org8804a292013-10-22 23:09:20 +0000657
wu@webrtc.org8804a292013-10-22 23:09:20 +0000658 {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000659 rtc::CritScope cs(&crit_);
deadbeefee8c6d32015-08-13 14:27:18 -0700660 // Receive and send frames every kTimePerFrameMs.
661 if (playing_) {
662 ReceiveFrameP();
663 }
664 if (recording_) {
665 SendFrameP();
666 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000667 }
668
669 next_frame_time_ += kTimePerFrameMs;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200670 const uint32_t current_time = rtc::Time();
671 const uint32_t wait_time =
672 (next_frame_time_ > current_time) ? next_frame_time_ - current_time : 0;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000673 process_thread_->PostDelayed(wait_time, this, MSG_RUN_PROCESS);
674}
675
676void FakeAudioCaptureModule::ReceiveFrameP() {
deadbeefee8c6d32015-08-13 14:27:18 -0700677 ASSERT(process_thread_->IsCurrent());
wu@webrtc.org8804a292013-10-22 23:09:20 +0000678 {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000679 rtc::CritScope cs(&crit_callback_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000680 if (!audio_callback_) {
681 return;
682 }
683 ResetRecBuffer();
Peter Kastingdce40cf2015-08-24 14:52:23 -0700684 size_t nSamplesOut = 0;
wu@webrtc.org94454b72014-06-05 20:34:08 +0000685 int64_t elapsed_time_ms = 0;
wu@webrtc.orgcb711f72014-05-19 17:39:11 +0000686 int64_t ntp_time_ms = 0;
687 if (audio_callback_->NeedMorePlayData(kNumberSamples, kNumberBytesPerSample,
688 kNumberOfChannels, kSamplesPerSecond,
689 rec_buffer_, nSamplesOut,
wu@webrtc.org94454b72014-06-05 20:34:08 +0000690 &elapsed_time_ms, &ntp_time_ms) != 0) {
wu@webrtc.org8804a292013-10-22 23:09:20 +0000691 ASSERT(false);
692 }
693 ASSERT(nSamplesOut == kNumberSamples);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000694 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000695 // The SetBuffer() function ensures that after decoding, the audio buffer
696 // should contain samples of similar magnitude (there is likely to be some
697 // distortion due to the audio pipeline). If one sample is detected to
698 // have the same or greater magnitude somewhere in the frame, an actual frame
699 // has been received from the remote side (i.e. faked frames are not being
700 // pulled).
wu@webrtc.org8804a292013-10-22 23:09:20 +0000701 if (CheckRecBuffer(kHighSampleValue)) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000702 rtc::CritScope cs(&crit_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000703 ++frames_received_;
704 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000705}
706
707void FakeAudioCaptureModule::SendFrameP() {
deadbeefee8c6d32015-08-13 14:27:18 -0700708 ASSERT(process_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000709 rtc::CritScope cs(&crit_callback_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000710 if (!audio_callback_) {
711 return;
712 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000713 bool key_pressed = false;
wu@webrtc.org8804a292013-10-22 23:09:20 +0000714 uint32_t current_mic_level = 0;
715 MicrophoneVolume(&current_mic_level);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000716 if (audio_callback_->RecordedDataIsAvailable(send_buffer_, kNumberSamples,
717 kNumberBytesPerSample,
718 kNumberOfChannels,
719 kSamplesPerSecond, kTotalDelayMs,
wu@webrtc.org8804a292013-10-22 23:09:20 +0000720 kClockDriftMs, current_mic_level,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000721 key_pressed,
wu@webrtc.org8804a292013-10-22 23:09:20 +0000722 current_mic_level) != 0) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000723 ASSERT(false);
724 }
wu@webrtc.org8804a292013-10-22 23:09:20 +0000725 SetMicrophoneVolume(current_mic_level);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000726}
727