1 /*
2  * libjingle
3  * Copyright 2012 Google Inc.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  *  1. Redistributions of source code must retain the above copyright notice,
9  *     this list of conditions and the following disclaimer.
10  *  2. Redistributions in binary form must reproduce the above copyright notice,
11  *     this list of conditions and the following disclaimer in the documentation
12  *     and/or other materials provided with the distribution.
13  *  3. The name of the author may not be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #include "talk/app/webrtc/test/fakeaudiocapturemodule.h"
29 
30 #include "webrtc/base/common.h"
31 #include "webrtc/base/refcount.h"
32 #include "webrtc/base/thread.h"
33 #include "webrtc/base/timeutils.h"
34 
35 // Audio sample value that is high enough that it doesn't occur naturally when
36 // frames are being faked. E.g. NetEq will not generate this large sample value
37 // unless it has received an audio frame containing a sample of this value.
38 // Even simpler buffers would likely just contain audio sample values of 0.
39 static const int kHighSampleValue = 10000;
40 
41 // Same value as src/modules/audio_device/main/source/audio_device_config.h in
42 // https://code.google.com/p/webrtc/
43 static const uint32_t kAdmMaxIdleTimeProcess = 1000;
44 
45 // Constants here are derived by running VoE using a real ADM.
46 // The constants correspond to 10ms of mono audio at 44kHz.
47 static const int kTimePerFrameMs = 10;
48 static const uint8_t kNumberOfChannels = 1;
49 static const int kSamplesPerSecond = 44000;
50 static const int kTotalDelayMs = 0;
51 static const int kClockDriftMs = 0;
52 static const uint32_t kMaxVolume = 14392;
53 
54 enum {
55   MSG_START_PROCESS,
56   MSG_RUN_PROCESS,
57 };
58 
FakeAudioCaptureModule()59 FakeAudioCaptureModule::FakeAudioCaptureModule()
60     : last_process_time_ms_(0),
61       audio_callback_(nullptr),
62       recording_(false),
63       playing_(false),
64       play_is_initialized_(false),
65       rec_is_initialized_(false),
66       current_mic_level_(kMaxVolume),
67       started_(false),
68       next_frame_time_(0),
69       frames_received_(0) {
70 }
71 
~FakeAudioCaptureModule()72 FakeAudioCaptureModule::~FakeAudioCaptureModule() {
73   if (process_thread_) {
74     process_thread_->Stop();
75   }
76 }
77 
Create()78 rtc::scoped_refptr<FakeAudioCaptureModule> FakeAudioCaptureModule::Create() {
79   rtc::scoped_refptr<FakeAudioCaptureModule> capture_module(
80       new rtc::RefCountedObject<FakeAudioCaptureModule>());
81   if (!capture_module->Initialize()) {
82     return nullptr;
83   }
84   return capture_module;
85 }
86 
frames_received() const87 int FakeAudioCaptureModule::frames_received() const {
88   rtc::CritScope cs(&crit_);
89   return frames_received_;
90 }
91 
TimeUntilNextProcess()92 int64_t FakeAudioCaptureModule::TimeUntilNextProcess() {
93   const uint32_t current_time = rtc::Time();
94   if (current_time < last_process_time_ms_) {
95     // TODO: wraparound could be handled more gracefully.
96     return 0;
97   }
98   const uint32_t elapsed_time = current_time - last_process_time_ms_;
99   if (kAdmMaxIdleTimeProcess < elapsed_time) {
100     return 0;
101   }
102   return kAdmMaxIdleTimeProcess - elapsed_time;
103 }
104 
Process()105 int32_t FakeAudioCaptureModule::Process() {
106   last_process_time_ms_ = rtc::Time();
107   return 0;
108 }
109 
ActiveAudioLayer(AudioLayer *) const110 int32_t FakeAudioCaptureModule::ActiveAudioLayer(
111     AudioLayer* /*audio_layer*/) const {
112   ASSERT(false);
113   return 0;
114 }
115 
LastError() const116 webrtc::AudioDeviceModule::ErrorCode FakeAudioCaptureModule::LastError() const {
117   ASSERT(false);
118   return webrtc::AudioDeviceModule::kAdmErrNone;
119 }
120 
RegisterEventObserver(webrtc::AudioDeviceObserver *)121 int32_t FakeAudioCaptureModule::RegisterEventObserver(
122     webrtc::AudioDeviceObserver* /*event_callback*/) {
123   // Only used to report warnings and errors. This fake implementation won't
124   // generate any so discard this callback.
125   return 0;
126 }
127 
RegisterAudioCallback(webrtc::AudioTransport * audio_callback)128 int32_t FakeAudioCaptureModule::RegisterAudioCallback(
129     webrtc::AudioTransport* audio_callback) {
130   rtc::CritScope cs(&crit_callback_);
131   audio_callback_ = audio_callback;
132   return 0;
133 }
134 
Init()135 int32_t FakeAudioCaptureModule::Init() {
136   // Initialize is called by the factory method. Safe to ignore this Init call.
137   return 0;
138 }
139 
Terminate()140 int32_t FakeAudioCaptureModule::Terminate() {
141   // Clean up in the destructor. No action here, just success.
142   return 0;
143 }
144 
Initialized() const145 bool FakeAudioCaptureModule::Initialized() const {
146   ASSERT(false);
147   return 0;
148 }
149 
PlayoutDevices()150 int16_t FakeAudioCaptureModule::PlayoutDevices() {
151   ASSERT(false);
152   return 0;
153 }
154 
RecordingDevices()155 int16_t FakeAudioCaptureModule::RecordingDevices() {
156   ASSERT(false);
157   return 0;
158 }
159 
PlayoutDeviceName(uint16_t,char[webrtc::kAdmMaxDeviceNameSize],char[webrtc::kAdmMaxGuidSize])160 int32_t FakeAudioCaptureModule::PlayoutDeviceName(
161     uint16_t /*index*/,
162     char /*name*/[webrtc::kAdmMaxDeviceNameSize],
163     char /*guid*/[webrtc::kAdmMaxGuidSize]) {
164   ASSERT(false);
165   return 0;
166 }
167 
RecordingDeviceName(uint16_t,char[webrtc::kAdmMaxDeviceNameSize],char[webrtc::kAdmMaxGuidSize])168 int32_t FakeAudioCaptureModule::RecordingDeviceName(
169     uint16_t /*index*/,
170     char /*name*/[webrtc::kAdmMaxDeviceNameSize],
171     char /*guid*/[webrtc::kAdmMaxGuidSize]) {
172   ASSERT(false);
173   return 0;
174 }
175 
SetPlayoutDevice(uint16_t)176 int32_t FakeAudioCaptureModule::SetPlayoutDevice(uint16_t /*index*/) {
177   // No playout device, just playing from file. Return success.
178   return 0;
179 }
180 
SetPlayoutDevice(WindowsDeviceType)181 int32_t FakeAudioCaptureModule::SetPlayoutDevice(WindowsDeviceType /*device*/) {
182   if (play_is_initialized_) {
183     return -1;
184   }
185   return 0;
186 }
187 
SetRecordingDevice(uint16_t)188 int32_t FakeAudioCaptureModule::SetRecordingDevice(uint16_t /*index*/) {
189   // No recording device, just dropping audio. Return success.
190   return 0;
191 }
192 
SetRecordingDevice(WindowsDeviceType)193 int32_t FakeAudioCaptureModule::SetRecordingDevice(
194     WindowsDeviceType /*device*/) {
195   if (rec_is_initialized_) {
196     return -1;
197   }
198   return 0;
199 }
200 
PlayoutIsAvailable(bool *)201 int32_t FakeAudioCaptureModule::PlayoutIsAvailable(bool* /*available*/) {
202   ASSERT(false);
203   return 0;
204 }
205 
InitPlayout()206 int32_t FakeAudioCaptureModule::InitPlayout() {
207   play_is_initialized_ = true;
208   return 0;
209 }
210 
PlayoutIsInitialized() const211 bool FakeAudioCaptureModule::PlayoutIsInitialized() const {
212   return play_is_initialized_;
213 }
214 
RecordingIsAvailable(bool *)215 int32_t FakeAudioCaptureModule::RecordingIsAvailable(bool* /*available*/) {
216   ASSERT(false);
217   return 0;
218 }
219 
InitRecording()220 int32_t FakeAudioCaptureModule::InitRecording() {
221   rec_is_initialized_ = true;
222   return 0;
223 }
224 
RecordingIsInitialized() const225 bool FakeAudioCaptureModule::RecordingIsInitialized() const {
226   ASSERT(false);
227   return 0;
228 }
229 
StartPlayout()230 int32_t FakeAudioCaptureModule::StartPlayout() {
231   if (!play_is_initialized_) {
232     return -1;
233   }
234   {
235     rtc::CritScope cs(&crit_);
236     playing_ = true;
237   }
238   bool start = true;
239   UpdateProcessing(start);
240   return 0;
241 }
242 
StopPlayout()243 int32_t FakeAudioCaptureModule::StopPlayout() {
244   bool start = false;
245   {
246     rtc::CritScope cs(&crit_);
247     playing_ = false;
248     start = ShouldStartProcessing();
249   }
250   UpdateProcessing(start);
251   return 0;
252 }
253 
Playing() const254 bool FakeAudioCaptureModule::Playing() const {
255   rtc::CritScope cs(&crit_);
256   return playing_;
257 }
258 
StartRecording()259 int32_t FakeAudioCaptureModule::StartRecording() {
260   if (!rec_is_initialized_) {
261     return -1;
262   }
263   {
264     rtc::CritScope cs(&crit_);
265     recording_ = true;
266   }
267   bool start = true;
268   UpdateProcessing(start);
269   return 0;
270 }
271 
StopRecording()272 int32_t FakeAudioCaptureModule::StopRecording() {
273   bool start = false;
274   {
275     rtc::CritScope cs(&crit_);
276     recording_ = false;
277     start = ShouldStartProcessing();
278   }
279   UpdateProcessing(start);
280   return 0;
281 }
282 
Recording() const283 bool FakeAudioCaptureModule::Recording() const {
284   rtc::CritScope cs(&crit_);
285   return recording_;
286 }
287 
SetAGC(bool)288 int32_t FakeAudioCaptureModule::SetAGC(bool /*enable*/) {
289   // No AGC but not needed since audio is pregenerated. Return success.
290   return 0;
291 }
292 
AGC() const293 bool FakeAudioCaptureModule::AGC() const {
294   ASSERT(false);
295   return 0;
296 }
297 
SetWaveOutVolume(uint16_t,uint16_t)298 int32_t FakeAudioCaptureModule::SetWaveOutVolume(uint16_t /*volume_left*/,
299                                                  uint16_t /*volume_right*/) {
300   ASSERT(false);
301   return 0;
302 }
303 
WaveOutVolume(uint16_t *,uint16_t *) const304 int32_t FakeAudioCaptureModule::WaveOutVolume(
305     uint16_t* /*volume_left*/,
306     uint16_t* /*volume_right*/) const {
307   ASSERT(false);
308   return 0;
309 }
310 
InitSpeaker()311 int32_t FakeAudioCaptureModule::InitSpeaker() {
312   // No speaker, just playing from file. Return success.
313   return 0;
314 }
315 
SpeakerIsInitialized() const316 bool FakeAudioCaptureModule::SpeakerIsInitialized() const {
317   ASSERT(false);
318   return 0;
319 }
320 
InitMicrophone()321 int32_t FakeAudioCaptureModule::InitMicrophone() {
322   // No microphone, just playing from file. Return success.
323   return 0;
324 }
325 
MicrophoneIsInitialized() const326 bool FakeAudioCaptureModule::MicrophoneIsInitialized() const {
327   ASSERT(false);
328   return 0;
329 }
330 
SpeakerVolumeIsAvailable(bool *)331 int32_t FakeAudioCaptureModule::SpeakerVolumeIsAvailable(bool* /*available*/) {
332   ASSERT(false);
333   return 0;
334 }
335 
SetSpeakerVolume(uint32_t)336 int32_t FakeAudioCaptureModule::SetSpeakerVolume(uint32_t /*volume*/) {
337   ASSERT(false);
338   return 0;
339 }
340 
SpeakerVolume(uint32_t *) const341 int32_t FakeAudioCaptureModule::SpeakerVolume(uint32_t* /*volume*/) const {
342   ASSERT(false);
343   return 0;
344 }
345 
MaxSpeakerVolume(uint32_t *) const346 int32_t FakeAudioCaptureModule::MaxSpeakerVolume(
347     uint32_t* /*max_volume*/) const {
348   ASSERT(false);
349   return 0;
350 }
351 
MinSpeakerVolume(uint32_t *) const352 int32_t FakeAudioCaptureModule::MinSpeakerVolume(
353     uint32_t* /*min_volume*/) const {
354   ASSERT(false);
355   return 0;
356 }
357 
SpeakerVolumeStepSize(uint16_t *) const358 int32_t FakeAudioCaptureModule::SpeakerVolumeStepSize(
359     uint16_t* /*step_size*/) const {
360   ASSERT(false);
361   return 0;
362 }
363 
MicrophoneVolumeIsAvailable(bool *)364 int32_t FakeAudioCaptureModule::MicrophoneVolumeIsAvailable(
365     bool* /*available*/) {
366   ASSERT(false);
367   return 0;
368 }
369 
SetMicrophoneVolume(uint32_t volume)370 int32_t FakeAudioCaptureModule::SetMicrophoneVolume(uint32_t volume) {
371   rtc::CritScope cs(&crit_);
372   current_mic_level_ = volume;
373   return 0;
374 }
375 
MicrophoneVolume(uint32_t * volume) const376 int32_t FakeAudioCaptureModule::MicrophoneVolume(uint32_t* volume) const {
377   rtc::CritScope cs(&crit_);
378   *volume = current_mic_level_;
379   return 0;
380 }
381 
MaxMicrophoneVolume(uint32_t * max_volume) const382 int32_t FakeAudioCaptureModule::MaxMicrophoneVolume(
383     uint32_t* max_volume) const {
384   *max_volume = kMaxVolume;
385   return 0;
386 }
387 
MinMicrophoneVolume(uint32_t *) const388 int32_t FakeAudioCaptureModule::MinMicrophoneVolume(
389     uint32_t* /*min_volume*/) const {
390   ASSERT(false);
391   return 0;
392 }
393 
MicrophoneVolumeStepSize(uint16_t *) const394 int32_t FakeAudioCaptureModule::MicrophoneVolumeStepSize(
395     uint16_t* /*step_size*/) const {
396   ASSERT(false);
397   return 0;
398 }
399 
SpeakerMuteIsAvailable(bool *)400 int32_t FakeAudioCaptureModule::SpeakerMuteIsAvailable(bool* /*available*/) {
401   ASSERT(false);
402   return 0;
403 }
404 
SetSpeakerMute(bool)405 int32_t FakeAudioCaptureModule::SetSpeakerMute(bool /*enable*/) {
406   ASSERT(false);
407   return 0;
408 }
409 
SpeakerMute(bool *) const410 int32_t FakeAudioCaptureModule::SpeakerMute(bool* /*enabled*/) const {
411   ASSERT(false);
412   return 0;
413 }
414 
MicrophoneMuteIsAvailable(bool *)415 int32_t FakeAudioCaptureModule::MicrophoneMuteIsAvailable(bool* /*available*/) {
416   ASSERT(false);
417   return 0;
418 }
419 
SetMicrophoneMute(bool)420 int32_t FakeAudioCaptureModule::SetMicrophoneMute(bool /*enable*/) {
421   ASSERT(false);
422   return 0;
423 }
424 
MicrophoneMute(bool *) const425 int32_t FakeAudioCaptureModule::MicrophoneMute(bool* /*enabled*/) const {
426   ASSERT(false);
427   return 0;
428 }
429 
MicrophoneBoostIsAvailable(bool *)430 int32_t FakeAudioCaptureModule::MicrophoneBoostIsAvailable(
431     bool* /*available*/) {
432   ASSERT(false);
433   return 0;
434 }
435 
SetMicrophoneBoost(bool)436 int32_t FakeAudioCaptureModule::SetMicrophoneBoost(bool /*enable*/) {
437   ASSERT(false);
438   return 0;
439 }
440 
MicrophoneBoost(bool *) const441 int32_t FakeAudioCaptureModule::MicrophoneBoost(bool* /*enabled*/) const {
442   ASSERT(false);
443   return 0;
444 }
445 
StereoPlayoutIsAvailable(bool * available) const446 int32_t FakeAudioCaptureModule::StereoPlayoutIsAvailable(
447     bool* available) const {
448   // No recording device, just dropping audio. Stereo can be dropped just
449   // as easily as mono.
450   *available = true;
451   return 0;
452 }
453 
SetStereoPlayout(bool)454 int32_t FakeAudioCaptureModule::SetStereoPlayout(bool /*enable*/) {
455   // No recording device, just dropping audio. Stereo can be dropped just
456   // as easily as mono.
457   return 0;
458 }
459 
StereoPlayout(bool *) const460 int32_t FakeAudioCaptureModule::StereoPlayout(bool* /*enabled*/) const {
461   ASSERT(false);
462   return 0;
463 }
464 
StereoRecordingIsAvailable(bool * available) const465 int32_t FakeAudioCaptureModule::StereoRecordingIsAvailable(
466     bool* available) const {
467   // Keep thing simple. No stereo recording.
468   *available = false;
469   return 0;
470 }
471 
SetStereoRecording(bool enable)472 int32_t FakeAudioCaptureModule::SetStereoRecording(bool enable) {
473   if (!enable) {
474     return 0;
475   }
476   return -1;
477 }
478 
StereoRecording(bool *) const479 int32_t FakeAudioCaptureModule::StereoRecording(bool* /*enabled*/) const {
480   ASSERT(false);
481   return 0;
482 }
483 
SetRecordingChannel(const ChannelType channel)484 int32_t FakeAudioCaptureModule::SetRecordingChannel(
485     const ChannelType channel) {
486   if (channel != AudioDeviceModule::kChannelBoth) {
487     // There is no right or left in mono. I.e. kChannelBoth should be used for
488     // mono.
489     ASSERT(false);
490     return -1;
491   }
492   return 0;
493 }
494 
RecordingChannel(ChannelType * channel) const495 int32_t FakeAudioCaptureModule::RecordingChannel(ChannelType* channel) const {
496   // Stereo recording not supported. However, WebRTC ADM returns kChannelBoth
497   // in that case. Do the same here.
498   *channel = AudioDeviceModule::kChannelBoth;
499   return 0;
500 }
501 
SetPlayoutBuffer(const BufferType,uint16_t)502 int32_t FakeAudioCaptureModule::SetPlayoutBuffer(const BufferType /*type*/,
503                                                  uint16_t /*size_ms*/) {
504   ASSERT(false);
505   return 0;
506 }
507 
PlayoutBuffer(BufferType *,uint16_t *) const508 int32_t FakeAudioCaptureModule::PlayoutBuffer(BufferType* /*type*/,
509                                               uint16_t* /*size_ms*/) const {
510   ASSERT(false);
511   return 0;
512 }
513 
PlayoutDelay(uint16_t * delay_ms) const514 int32_t FakeAudioCaptureModule::PlayoutDelay(uint16_t* delay_ms) const {
515   // No delay since audio frames are dropped.
516   *delay_ms = 0;
517   return 0;
518 }
519 
RecordingDelay(uint16_t *) const520 int32_t FakeAudioCaptureModule::RecordingDelay(uint16_t* /*delay_ms*/) const {
521   ASSERT(false);
522   return 0;
523 }
524 
CPULoad(uint16_t *) const525 int32_t FakeAudioCaptureModule::CPULoad(uint16_t* /*load*/) const {
526   ASSERT(false);
527   return 0;
528 }
529 
StartRawOutputFileRecording(const char[webrtc::kAdmMaxFileNameSize])530 int32_t FakeAudioCaptureModule::StartRawOutputFileRecording(
531     const char /*pcm_file_name_utf8*/[webrtc::kAdmMaxFileNameSize]) {
532   ASSERT(false);
533   return 0;
534 }
535 
StopRawOutputFileRecording()536 int32_t FakeAudioCaptureModule::StopRawOutputFileRecording() {
537   ASSERT(false);
538   return 0;
539 }
540 
StartRawInputFileRecording(const char[webrtc::kAdmMaxFileNameSize])541 int32_t FakeAudioCaptureModule::StartRawInputFileRecording(
542     const char /*pcm_file_name_utf8*/[webrtc::kAdmMaxFileNameSize]) {
543   ASSERT(false);
544   return 0;
545 }
546 
StopRawInputFileRecording()547 int32_t FakeAudioCaptureModule::StopRawInputFileRecording() {
548   ASSERT(false);
549   return 0;
550 }
551 
SetRecordingSampleRate(const uint32_t)552 int32_t FakeAudioCaptureModule::SetRecordingSampleRate(
553     const uint32_t /*samples_per_sec*/) {
554   ASSERT(false);
555   return 0;
556 }
557 
RecordingSampleRate(uint32_t *) const558 int32_t FakeAudioCaptureModule::RecordingSampleRate(
559     uint32_t* /*samples_per_sec*/) const {
560   ASSERT(false);
561   return 0;
562 }
563 
SetPlayoutSampleRate(const uint32_t)564 int32_t FakeAudioCaptureModule::SetPlayoutSampleRate(
565     const uint32_t /*samples_per_sec*/) {
566   ASSERT(false);
567   return 0;
568 }
569 
PlayoutSampleRate(uint32_t *) const570 int32_t FakeAudioCaptureModule::PlayoutSampleRate(
571     uint32_t* /*samples_per_sec*/) const {
572   ASSERT(false);
573   return 0;
574 }
575 
ResetAudioDevice()576 int32_t FakeAudioCaptureModule::ResetAudioDevice() {
577   ASSERT(false);
578   return 0;
579 }
580 
SetLoudspeakerStatus(bool)581 int32_t FakeAudioCaptureModule::SetLoudspeakerStatus(bool /*enable*/) {
582   ASSERT(false);
583   return 0;
584 }
585 
GetLoudspeakerStatus(bool *) const586 int32_t FakeAudioCaptureModule::GetLoudspeakerStatus(bool* /*enabled*/) const {
587   ASSERT(false);
588   return 0;
589 }
590 
OnMessage(rtc::Message * msg)591 void FakeAudioCaptureModule::OnMessage(rtc::Message* msg) {
592   switch (msg->message_id) {
593     case MSG_START_PROCESS:
594       StartProcessP();
595       break;
596     case MSG_RUN_PROCESS:
597       ProcessFrameP();
598       break;
599     default:
600       // All existing messages should be caught. Getting here should never
601       // happen.
602       ASSERT(false);
603   }
604 }
605 
Initialize()606 bool FakeAudioCaptureModule::Initialize() {
607   // Set the send buffer samples high enough that it would not occur on the
608   // remote side unless a packet containing a sample of that magnitude has been
609   // sent to it. Note that the audio processing pipeline will likely distort the
610   // original signal.
611   SetSendBuffer(kHighSampleValue);
612   last_process_time_ms_ = rtc::Time();
613   return true;
614 }
615 
SetSendBuffer(int value)616 void FakeAudioCaptureModule::SetSendBuffer(int value) {
617   Sample* buffer_ptr = reinterpret_cast<Sample*>(send_buffer_);
618   const size_t buffer_size_in_samples =
619       sizeof(send_buffer_) / kNumberBytesPerSample;
620   for (size_t i = 0; i < buffer_size_in_samples; ++i) {
621     buffer_ptr[i] = value;
622   }
623 }
624 
ResetRecBuffer()625 void FakeAudioCaptureModule::ResetRecBuffer() {
626   memset(rec_buffer_, 0, sizeof(rec_buffer_));
627 }
628 
CheckRecBuffer(int value)629 bool FakeAudioCaptureModule::CheckRecBuffer(int value) {
630   const Sample* buffer_ptr = reinterpret_cast<const Sample*>(rec_buffer_);
631   const size_t buffer_size_in_samples =
632       sizeof(rec_buffer_) / kNumberBytesPerSample;
633   for (size_t i = 0; i < buffer_size_in_samples; ++i) {
634     if (buffer_ptr[i] >= value) return true;
635   }
636   return false;
637 }
638 
ShouldStartProcessing()639 bool FakeAudioCaptureModule::ShouldStartProcessing() {
640   return recording_ || playing_;
641 }
642 
UpdateProcessing(bool start)643 void FakeAudioCaptureModule::UpdateProcessing(bool start) {
644   if (start) {
645     if (!process_thread_) {
646       process_thread_.reset(new rtc::Thread());
647       process_thread_->Start();
648     }
649     process_thread_->Post(this, MSG_START_PROCESS);
650   } else {
651     if (process_thread_) {
652       process_thread_->Stop();
653       process_thread_.reset(nullptr);
654     }
655     started_ = false;
656   }
657 }
658 
StartProcessP()659 void FakeAudioCaptureModule::StartProcessP() {
660   ASSERT(process_thread_->IsCurrent());
661   if (started_) {
662     // Already started.
663     return;
664   }
665   ProcessFrameP();
666 }
667 
ProcessFrameP()668 void FakeAudioCaptureModule::ProcessFrameP() {
669   ASSERT(process_thread_->IsCurrent());
670   if (!started_) {
671     next_frame_time_ = rtc::Time();
672     started_ = true;
673   }
674 
675   {
676     rtc::CritScope cs(&crit_);
677     // Receive and send frames every kTimePerFrameMs.
678     if (playing_) {
679       ReceiveFrameP();
680     }
681     if (recording_) {
682       SendFrameP();
683     }
684   }
685 
686   next_frame_time_ += kTimePerFrameMs;
687   const uint32_t current_time = rtc::Time();
688   const uint32_t wait_time =
689       (next_frame_time_ > current_time) ? next_frame_time_ - current_time : 0;
690   process_thread_->PostDelayed(wait_time, this, MSG_RUN_PROCESS);
691 }
692 
ReceiveFrameP()693 void FakeAudioCaptureModule::ReceiveFrameP() {
694   ASSERT(process_thread_->IsCurrent());
695   {
696     rtc::CritScope cs(&crit_callback_);
697     if (!audio_callback_) {
698       return;
699     }
700     ResetRecBuffer();
701     size_t nSamplesOut = 0;
702     int64_t elapsed_time_ms = 0;
703     int64_t ntp_time_ms = 0;
704     if (audio_callback_->NeedMorePlayData(kNumberSamples, kNumberBytesPerSample,
705                                          kNumberOfChannels, kSamplesPerSecond,
706                                          rec_buffer_, nSamplesOut,
707                                          &elapsed_time_ms, &ntp_time_ms) != 0) {
708       ASSERT(false);
709     }
710     ASSERT(nSamplesOut == kNumberSamples);
711   }
712   // The SetBuffer() function ensures that after decoding, the audio buffer
713   // should contain samples of similar magnitude (there is likely to be some
714   // distortion due to the audio pipeline). If one sample is detected to
715   // have the same or greater magnitude somewhere in the frame, an actual frame
716   // has been received from the remote side (i.e. faked frames are not being
717   // pulled).
718   if (CheckRecBuffer(kHighSampleValue)) {
719     rtc::CritScope cs(&crit_);
720     ++frames_received_;
721   }
722 }
723 
SendFrameP()724 void FakeAudioCaptureModule::SendFrameP() {
725   ASSERT(process_thread_->IsCurrent());
726   rtc::CritScope cs(&crit_callback_);
727   if (!audio_callback_) {
728     return;
729   }
730   bool key_pressed = false;
731   uint32_t current_mic_level = 0;
732   MicrophoneVolume(&current_mic_level);
733   if (audio_callback_->RecordedDataIsAvailable(send_buffer_, kNumberSamples,
734                                               kNumberBytesPerSample,
735                                               kNumberOfChannels,
736                                               kSamplesPerSecond, kTotalDelayMs,
737                                               kClockDriftMs, current_mic_level,
738                                               key_pressed,
739                                               current_mic_level) != 0) {
740     ASSERT(false);
741   }
742   SetMicrophoneVolume(current_mic_level);
743 }
744 
745