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 "talk/base/common.h"
31 #include "talk/base/refcount.h"
32 #include "talk/base/thread.h"
33 #include "talk/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 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 int 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_RUN_PROCESS,
56   MSG_STOP_PROCESS,
57 };
58 
FakeAudioCaptureModule(talk_base::Thread * process_thread)59 FakeAudioCaptureModule::FakeAudioCaptureModule(
60     talk_base::Thread* process_thread)
61     : last_process_time_ms_(0),
62       audio_callback_(NULL),
63       recording_(false),
64       playing_(false),
65       play_is_initialized_(false),
66       rec_is_initialized_(false),
67       current_mic_level_(kMaxVolume),
68       started_(false),
69       next_frame_time_(0),
70       process_thread_(process_thread),
71       frames_received_(0) {
72 }
73 
~FakeAudioCaptureModule()74 FakeAudioCaptureModule::~FakeAudioCaptureModule() {
75   // Ensure that thread stops calling ProcessFrame().
76   process_thread_->Send(this, MSG_STOP_PROCESS);
77 }
78 
Create(talk_base::Thread * process_thread)79 talk_base::scoped_refptr<FakeAudioCaptureModule> FakeAudioCaptureModule::Create(
80     talk_base::Thread* process_thread) {
81   if (process_thread == NULL) return NULL;
82 
83   talk_base::RefCountedObject<FakeAudioCaptureModule>* capture_module =
84       new talk_base::RefCountedObject<FakeAudioCaptureModule>(process_thread);
85   if (!capture_module->Initialize()) {
86     delete capture_module;
87     return NULL;
88   }
89   return capture_module;
90 }
91 
frames_received() const92 int FakeAudioCaptureModule::frames_received() const {
93   return frames_received_;
94 }
95 
Version(char *,uint32_t &,uint32_t &) const96 int32_t FakeAudioCaptureModule::Version(char* /*version*/,
97                                         uint32_t& /*remaining_buffer_in_bytes*/,
98                                         uint32_t& /*position*/) const {
99   ASSERT(false);
100   return 0;
101 }
102 
TimeUntilNextProcess()103 int32_t FakeAudioCaptureModule::TimeUntilNextProcess() {
104   const uint32 current_time = talk_base::Time();
105   if (current_time < last_process_time_ms_) {
106     // TODO: wraparound could be handled more gracefully.
107     return 0;
108   }
109   const uint32 elapsed_time = current_time - last_process_time_ms_;
110   if (kAdmMaxIdleTimeProcess < elapsed_time) {
111     return 0;
112   }
113   return kAdmMaxIdleTimeProcess - elapsed_time;
114 }
115 
Process()116 int32_t FakeAudioCaptureModule::Process() {
117   last_process_time_ms_ = talk_base::Time();
118   return 0;
119 }
120 
ChangeUniqueId(const WebRtc_Word32)121 WebRtc_Word32 FakeAudioCaptureModule::ChangeUniqueId(
122     const WebRtc_Word32 /*id*/) {
123   ASSERT(false);
124   return 0;
125 }
126 
ActiveAudioLayer(AudioLayer *) const127 int32_t FakeAudioCaptureModule::ActiveAudioLayer(
128     AudioLayer* /*audio_layer*/) const {
129   ASSERT(false);
130   return 0;
131 }
132 
LastError() const133 webrtc::AudioDeviceModule::ErrorCode FakeAudioCaptureModule::LastError() const {
134   ASSERT(false);
135   return webrtc::AudioDeviceModule::kAdmErrNone;
136 }
137 
RegisterEventObserver(webrtc::AudioDeviceObserver *)138 int32_t FakeAudioCaptureModule::RegisterEventObserver(
139     webrtc::AudioDeviceObserver* /*event_callback*/) {
140   // Only used to report warnings and errors. This fake implementation won't
141   // generate any so discard this callback.
142   return 0;
143 }
144 
RegisterAudioCallback(webrtc::AudioTransport * audio_callback)145 int32_t FakeAudioCaptureModule::RegisterAudioCallback(
146     webrtc::AudioTransport* audio_callback) {
147   audio_callback_ = audio_callback;
148   return 0;
149 }
150 
Init()151 int32_t FakeAudioCaptureModule::Init() {
152   // Initialize is called by the factory method. Safe to ignore this Init call.
153   return 0;
154 }
155 
Terminate()156 int32_t FakeAudioCaptureModule::Terminate() {
157   // Clean up in the destructor. No action here, just success.
158   return 0;
159 }
160 
Initialized() const161 bool FakeAudioCaptureModule::Initialized() const {
162   ASSERT(false);
163   return 0;
164 }
165 
PlayoutDevices()166 int16_t FakeAudioCaptureModule::PlayoutDevices() {
167   ASSERT(false);
168   return 0;
169 }
170 
RecordingDevices()171 int16_t FakeAudioCaptureModule::RecordingDevices() {
172   ASSERT(false);
173   return 0;
174 }
175 
PlayoutDeviceName(uint16_t,char[webrtc::kAdmMaxDeviceNameSize],char[webrtc::kAdmMaxGuidSize])176 int32_t FakeAudioCaptureModule::PlayoutDeviceName(
177     uint16_t /*index*/,
178     char /*name*/[webrtc::kAdmMaxDeviceNameSize],
179     char /*guid*/[webrtc::kAdmMaxGuidSize]) {
180   ASSERT(false);
181   return 0;
182 }
183 
RecordingDeviceName(uint16_t,char[webrtc::kAdmMaxDeviceNameSize],char[webrtc::kAdmMaxGuidSize])184 int32_t FakeAudioCaptureModule::RecordingDeviceName(
185     uint16_t /*index*/,
186     char /*name*/[webrtc::kAdmMaxDeviceNameSize],
187     char /*guid*/[webrtc::kAdmMaxGuidSize]) {
188   ASSERT(false);
189   return 0;
190 }
191 
SetPlayoutDevice(uint16_t)192 int32_t FakeAudioCaptureModule::SetPlayoutDevice(uint16_t /*index*/) {
193   // No playout device, just playing from file. Return success.
194   return 0;
195 }
196 
SetPlayoutDevice(WindowsDeviceType)197 int32_t FakeAudioCaptureModule::SetPlayoutDevice(WindowsDeviceType /*device*/) {
198   if (play_is_initialized_) {
199     return -1;
200   }
201   return 0;
202 }
203 
SetRecordingDevice(uint16_t)204 int32_t FakeAudioCaptureModule::SetRecordingDevice(uint16_t /*index*/) {
205   // No recording device, just dropping audio. Return success.
206   return 0;
207 }
208 
SetRecordingDevice(WindowsDeviceType)209 int32_t FakeAudioCaptureModule::SetRecordingDevice(
210     WindowsDeviceType /*device*/) {
211   if (rec_is_initialized_) {
212     return -1;
213   }
214   return 0;
215 }
216 
PlayoutIsAvailable(bool *)217 int32_t FakeAudioCaptureModule::PlayoutIsAvailable(bool* /*available*/) {
218   ASSERT(false);
219   return 0;
220 }
221 
InitPlayout()222 int32_t FakeAudioCaptureModule::InitPlayout() {
223   play_is_initialized_ = true;
224   return 0;
225 }
226 
PlayoutIsInitialized() const227 bool FakeAudioCaptureModule::PlayoutIsInitialized() const {
228   return play_is_initialized_;
229 }
230 
RecordingIsAvailable(bool *)231 int32_t FakeAudioCaptureModule::RecordingIsAvailable(bool* /*available*/) {
232   ASSERT(false);
233   return 0;
234 }
235 
InitRecording()236 int32_t FakeAudioCaptureModule::InitRecording() {
237   rec_is_initialized_ = true;
238   return 0;
239 }
240 
RecordingIsInitialized() const241 bool FakeAudioCaptureModule::RecordingIsInitialized() const {
242   ASSERT(false);
243   return 0;
244 }
245 
StartPlayout()246 int32_t FakeAudioCaptureModule::StartPlayout() {
247   if (!play_is_initialized_) {
248     return -1;
249   }
250   playing_ = true;
251   UpdateProcessing();
252   return 0;
253 }
254 
StopPlayout()255 int32_t FakeAudioCaptureModule::StopPlayout() {
256   playing_ = false;
257   UpdateProcessing();
258   return 0;
259 }
260 
Playing() const261 bool FakeAudioCaptureModule::Playing() const {
262   return playing_;
263 }
264 
StartRecording()265 int32_t FakeAudioCaptureModule::StartRecording() {
266   if (!rec_is_initialized_) {
267     return -1;
268   }
269   recording_ = true;
270   UpdateProcessing();
271   return 0;
272 }
273 
StopRecording()274 int32_t FakeAudioCaptureModule::StopRecording() {
275   recording_ = false;
276   UpdateProcessing();
277   return 0;
278 }
279 
Recording() const280 bool FakeAudioCaptureModule::Recording() const {
281   return recording_;
282 }
283 
SetAGC(bool)284 int32_t FakeAudioCaptureModule::SetAGC(bool /*enable*/) {
285   // No AGC but not needed since audio is pregenerated. Return success.
286   return 0;
287 }
288 
AGC() const289 bool FakeAudioCaptureModule::AGC() const {
290   ASSERT(false);
291   return 0;
292 }
293 
SetWaveOutVolume(uint16_t,uint16_t)294 int32_t FakeAudioCaptureModule::SetWaveOutVolume(uint16_t /*volume_left*/,
295                                                  uint16_t /*volume_right*/) {
296   ASSERT(false);
297   return 0;
298 }
299 
WaveOutVolume(uint16_t *,uint16_t *) const300 int32_t FakeAudioCaptureModule::WaveOutVolume(
301     uint16_t* /*volume_left*/,
302     uint16_t* /*volume_right*/) const {
303   ASSERT(false);
304   return 0;
305 }
306 
SpeakerIsAvailable(bool * available)307 int32_t FakeAudioCaptureModule::SpeakerIsAvailable(bool* available) {
308   // No speaker, just dropping audio. Return success.
309   *available = true;
310   return 0;
311 }
312 
InitSpeaker()313 int32_t FakeAudioCaptureModule::InitSpeaker() {
314   // No speaker, just playing from file. Return success.
315   return 0;
316 }
317 
SpeakerIsInitialized() const318 bool FakeAudioCaptureModule::SpeakerIsInitialized() const {
319   ASSERT(false);
320   return 0;
321 }
322 
MicrophoneIsAvailable(bool * available)323 int32_t FakeAudioCaptureModule::MicrophoneIsAvailable(bool* available) {
324   // No microphone, just playing from file. Return success.
325   *available = true;
326   return 0;
327 }
328 
InitMicrophone()329 int32_t FakeAudioCaptureModule::InitMicrophone() {
330   // No microphone, just playing from file. Return success.
331   return 0;
332 }
333 
MicrophoneIsInitialized() const334 bool FakeAudioCaptureModule::MicrophoneIsInitialized() const {
335   ASSERT(false);
336   return 0;
337 }
338 
SpeakerVolumeIsAvailable(bool *)339 int32_t FakeAudioCaptureModule::SpeakerVolumeIsAvailable(bool* /*available*/) {
340   ASSERT(false);
341   return 0;
342 }
343 
SetSpeakerVolume(uint32_t)344 int32_t FakeAudioCaptureModule::SetSpeakerVolume(uint32_t /*volume*/) {
345   ASSERT(false);
346   return 0;
347 }
348 
SpeakerVolume(uint32_t *) const349 int32_t FakeAudioCaptureModule::SpeakerVolume(uint32_t* /*volume*/) const {
350   ASSERT(false);
351   return 0;
352 }
353 
MaxSpeakerVolume(uint32_t *) const354 int32_t FakeAudioCaptureModule::MaxSpeakerVolume(
355     uint32_t* /*max_volume*/) const {
356   ASSERT(false);
357   return 0;
358 }
359 
MinSpeakerVolume(uint32_t *) const360 int32_t FakeAudioCaptureModule::MinSpeakerVolume(
361     uint32_t* /*min_volume*/) const {
362   ASSERT(false);
363   return 0;
364 }
365 
SpeakerVolumeStepSize(uint16_t *) const366 int32_t FakeAudioCaptureModule::SpeakerVolumeStepSize(
367     uint16_t* /*step_size*/) const {
368   ASSERT(false);
369   return 0;
370 }
371 
MicrophoneVolumeIsAvailable(bool *)372 int32_t FakeAudioCaptureModule::MicrophoneVolumeIsAvailable(
373     bool* /*available*/) {
374   ASSERT(false);
375   return 0;
376 }
377 
SetMicrophoneVolume(uint32_t)378 int32_t FakeAudioCaptureModule::SetMicrophoneVolume(uint32_t /*volume*/) {
379   ASSERT(false);
380   return 0;
381 }
382 
MicrophoneVolume(uint32_t *) const383 int32_t FakeAudioCaptureModule::MicrophoneVolume(uint32_t* /*volume*/) const {
384   ASSERT(false);
385   return 0;
386 }
387 
MaxMicrophoneVolume(uint32_t * max_volume) const388 int32_t FakeAudioCaptureModule::MaxMicrophoneVolume(
389     uint32_t* max_volume) const {
390   *max_volume = kMaxVolume;
391   return 0;
392 }
393 
MinMicrophoneVolume(uint32_t *) const394 int32_t FakeAudioCaptureModule::MinMicrophoneVolume(
395     uint32_t* /*min_volume*/) const {
396   ASSERT(false);
397   return 0;
398 }
399 
MicrophoneVolumeStepSize(uint16_t *) const400 int32_t FakeAudioCaptureModule::MicrophoneVolumeStepSize(
401     uint16_t* /*step_size*/) const {
402   ASSERT(false);
403   return 0;
404 }
405 
SpeakerMuteIsAvailable(bool *)406 int32_t FakeAudioCaptureModule::SpeakerMuteIsAvailable(bool* /*available*/) {
407   ASSERT(false);
408   return 0;
409 }
410 
SetSpeakerMute(bool)411 int32_t FakeAudioCaptureModule::SetSpeakerMute(bool /*enable*/) {
412   ASSERT(false);
413   return 0;
414 }
415 
SpeakerMute(bool *) const416 int32_t FakeAudioCaptureModule::SpeakerMute(bool* /*enabled*/) const {
417   ASSERT(false);
418   return 0;
419 }
420 
MicrophoneMuteIsAvailable(bool *)421 int32_t FakeAudioCaptureModule::MicrophoneMuteIsAvailable(bool* /*available*/) {
422   ASSERT(false);
423   return 0;
424 }
425 
SetMicrophoneMute(bool)426 int32_t FakeAudioCaptureModule::SetMicrophoneMute(bool /*enable*/) {
427   ASSERT(false);
428   return 0;
429 }
430 
MicrophoneMute(bool *) const431 int32_t FakeAudioCaptureModule::MicrophoneMute(bool* /*enabled*/) const {
432   ASSERT(false);
433   return 0;
434 }
435 
MicrophoneBoostIsAvailable(bool *)436 int32_t FakeAudioCaptureModule::MicrophoneBoostIsAvailable(
437     bool* /*available*/) {
438   ASSERT(false);
439   return 0;
440 }
441 
SetMicrophoneBoost(bool)442 int32_t FakeAudioCaptureModule::SetMicrophoneBoost(bool /*enable*/) {
443   ASSERT(false);
444   return 0;
445 }
446 
MicrophoneBoost(bool *) const447 int32_t FakeAudioCaptureModule::MicrophoneBoost(bool* /*enabled*/) const {
448   ASSERT(false);
449   return 0;
450 }
451 
StereoPlayoutIsAvailable(bool * available) const452 int32_t FakeAudioCaptureModule::StereoPlayoutIsAvailable(
453     bool* available) const {
454   // No recording device, just dropping audio. Stereo can be dropped just
455   // as easily as mono.
456   *available = true;
457   return 0;
458 }
459 
SetStereoPlayout(bool)460 int32_t FakeAudioCaptureModule::SetStereoPlayout(bool /*enable*/) {
461   // No recording device, just dropping audio. Stereo can be dropped just
462   // as easily as mono.
463   return 0;
464 }
465 
StereoPlayout(bool *) const466 int32_t FakeAudioCaptureModule::StereoPlayout(bool* /*enabled*/) const {
467   ASSERT(false);
468   return 0;
469 }
470 
StereoRecordingIsAvailable(bool * available) const471 int32_t FakeAudioCaptureModule::StereoRecordingIsAvailable(
472     bool* available) const {
473   // Keep thing simple. No stereo recording.
474   *available = false;
475   return 0;
476 }
477 
SetStereoRecording(bool enable)478 int32_t FakeAudioCaptureModule::SetStereoRecording(bool enable) {
479   if (!enable) {
480     return 0;
481   }
482   return -1;
483 }
484 
StereoRecording(bool *) const485 int32_t FakeAudioCaptureModule::StereoRecording(bool* /*enabled*/) const {
486   ASSERT(false);
487   return 0;
488 }
489 
SetRecordingChannel(const ChannelType channel)490 int32_t FakeAudioCaptureModule::SetRecordingChannel(
491     const ChannelType channel) {
492   if (channel != AudioDeviceModule::kChannelBoth) {
493     // There is no right or left in mono. I.e. kChannelBoth should be used for
494     // mono.
495     ASSERT(false);
496     return -1;
497   }
498   return 0;
499 }
500 
RecordingChannel(ChannelType * channel) const501 int32_t FakeAudioCaptureModule::RecordingChannel(ChannelType* channel) const {
502   // Stereo recording not supported. However, WebRTC ADM returns kChannelBoth
503   // in that case. Do the same here.
504   *channel = AudioDeviceModule::kChannelBoth;
505   return 0;
506 }
507 
SetPlayoutBuffer(const BufferType,uint16_t)508 int32_t FakeAudioCaptureModule::SetPlayoutBuffer(const BufferType /*type*/,
509                                                  uint16_t /*size_ms*/) {
510   ASSERT(false);
511   return 0;
512 }
513 
PlayoutBuffer(BufferType *,uint16_t *) const514 int32_t FakeAudioCaptureModule::PlayoutBuffer(BufferType* /*type*/,
515                                               uint16_t* /*size_ms*/) const {
516   ASSERT(false);
517   return 0;
518 }
519 
PlayoutDelay(uint16_t * delay_ms) const520 int32_t FakeAudioCaptureModule::PlayoutDelay(uint16_t* delay_ms) const {
521   // No delay since audio frames are dropped.
522   *delay_ms = 0;
523   return 0;
524 }
525 
RecordingDelay(uint16_t *) const526 int32_t FakeAudioCaptureModule::RecordingDelay(uint16_t* /*delay_ms*/) const {
527   ASSERT(false);
528   return 0;
529 }
530 
CPULoad(uint16_t *) const531 int32_t FakeAudioCaptureModule::CPULoad(uint16_t* /*load*/) const {
532   ASSERT(false);
533   return 0;
534 }
535 
StartRawOutputFileRecording(const char[webrtc::kAdmMaxFileNameSize])536 int32_t FakeAudioCaptureModule::StartRawOutputFileRecording(
537     const char /*pcm_file_name_utf8*/[webrtc::kAdmMaxFileNameSize]) {
538   ASSERT(false);
539   return 0;
540 }
541 
StopRawOutputFileRecording()542 int32_t FakeAudioCaptureModule::StopRawOutputFileRecording() {
543   ASSERT(false);
544   return 0;
545 }
546 
StartRawInputFileRecording(const char[webrtc::kAdmMaxFileNameSize])547 int32_t FakeAudioCaptureModule::StartRawInputFileRecording(
548     const char /*pcm_file_name_utf8*/[webrtc::kAdmMaxFileNameSize]) {
549   ASSERT(false);
550   return 0;
551 }
552 
StopRawInputFileRecording()553 int32_t FakeAudioCaptureModule::StopRawInputFileRecording() {
554   ASSERT(false);
555   return 0;
556 }
557 
SetRecordingSampleRate(const uint32_t)558 int32_t FakeAudioCaptureModule::SetRecordingSampleRate(
559     const uint32_t /*samples_per_sec*/) {
560   ASSERT(false);
561   return 0;
562 }
563 
RecordingSampleRate(uint32_t *) const564 int32_t FakeAudioCaptureModule::RecordingSampleRate(
565     uint32_t* /*samples_per_sec*/) const {
566   ASSERT(false);
567   return 0;
568 }
569 
SetPlayoutSampleRate(const uint32_t)570 int32_t FakeAudioCaptureModule::SetPlayoutSampleRate(
571     const uint32_t /*samples_per_sec*/) {
572   ASSERT(false);
573   return 0;
574 }
575 
PlayoutSampleRate(uint32_t *) const576 int32_t FakeAudioCaptureModule::PlayoutSampleRate(
577     uint32_t* /*samples_per_sec*/) const {
578   ASSERT(false);
579   return 0;
580 }
581 
ResetAudioDevice()582 int32_t FakeAudioCaptureModule::ResetAudioDevice() {
583   ASSERT(false);
584   return 0;
585 }
586 
SetLoudspeakerStatus(bool)587 int32_t FakeAudioCaptureModule::SetLoudspeakerStatus(bool /*enable*/) {
588   ASSERT(false);
589   return 0;
590 }
591 
GetLoudspeakerStatus(bool *) const592 int32_t FakeAudioCaptureModule::GetLoudspeakerStatus(bool* /*enabled*/) const {
593   ASSERT(false);
594   return 0;
595 }
596 
OnMessage(talk_base::Message * msg)597 void FakeAudioCaptureModule::OnMessage(talk_base::Message* msg) {
598   switch (msg->message_id) {
599     case MSG_RUN_PROCESS:
600       ProcessFrameP();
601       break;
602     case MSG_STOP_PROCESS:
603       StopProcessP();
604       break;
605     default:
606       // All existing messages should be caught. Getting here should never
607       // happen.
608       ASSERT(false);
609   }
610 }
611 
Initialize()612 bool FakeAudioCaptureModule::Initialize() {
613   // Set the send buffer samples high enough that it would not occur on the
614   // remote side unless a packet containing a sample of that magnitude has been
615   // sent to it. Note that the audio processing pipeline will likely distort the
616   // original signal.
617   SetSendBuffer(kHighSampleValue);
618   last_process_time_ms_ = talk_base::Time();
619   return true;
620 }
621 
SetSendBuffer(int value)622 void FakeAudioCaptureModule::SetSendBuffer(int value) {
623   Sample* buffer_ptr = reinterpret_cast<Sample*>(send_buffer_);
624   const int buffer_size_in_samples = sizeof(send_buffer_) /
625       kNumberBytesPerSample;
626   for (int i = 0; i < buffer_size_in_samples; ++i) {
627     buffer_ptr[i] = value;
628   }
629 }
630 
ResetRecBuffer()631 void FakeAudioCaptureModule::ResetRecBuffer() {
632   memset(rec_buffer_, 0, sizeof(rec_buffer_));
633 }
634 
CheckRecBuffer(int value)635 bool FakeAudioCaptureModule::CheckRecBuffer(int value) {
636   const Sample* buffer_ptr = reinterpret_cast<const Sample*>(rec_buffer_);
637   const int buffer_size_in_samples = sizeof(rec_buffer_) /
638       kNumberBytesPerSample;
639   for (int i = 0; i < buffer_size_in_samples; ++i) {
640     if (buffer_ptr[i] >= value) return true;
641   }
642   return false;
643 }
644 
UpdateProcessing()645 void FakeAudioCaptureModule::UpdateProcessing() {
646   const bool process = recording_ || playing_;
647   if (process) {
648     if (started_) {
649       // Already started.
650       return;
651     }
652     process_thread_->Post(this, MSG_RUN_PROCESS);
653   } else {
654     process_thread_->Send(this, MSG_STOP_PROCESS);
655   }
656 }
657 
ProcessFrameP()658 void FakeAudioCaptureModule::ProcessFrameP() {
659   ASSERT(talk_base::Thread::Current() == process_thread_);
660   if (!started_) {
661     next_frame_time_ = talk_base::Time();
662     started_ = true;
663   }
664   // Receive and send frames every kTimePerFrameMs.
665   if (audio_callback_ != NULL) {
666     if (playing_) {
667       ReceiveFrameP();
668     }
669     if (recording_) {
670       SendFrameP();
671     }
672   }
673 
674   next_frame_time_ += kTimePerFrameMs;
675   const uint32 current_time = talk_base::Time();
676   const uint32 wait_time = (next_frame_time_ > current_time) ?
677       next_frame_time_ - current_time : 0;
678   process_thread_->PostDelayed(wait_time, this, MSG_RUN_PROCESS);
679 }
680 
ReceiveFrameP()681 void FakeAudioCaptureModule::ReceiveFrameP() {
682   ASSERT(talk_base::Thread::Current() == process_thread_);
683   ResetRecBuffer();
684   uint32_t nSamplesOut = 0;
685   if (audio_callback_->NeedMorePlayData(kNumberSamples, kNumberBytesPerSample,
686                                        kNumberOfChannels, kSamplesPerSecond,
687                                        rec_buffer_, nSamplesOut) != 0) {
688     ASSERT(false);
689   }
690   ASSERT(nSamplesOut == kNumberSamples);
691   // The SetBuffer() function ensures that after decoding, the audio buffer
692   // should contain samples of similar magnitude (there is likely to be some
693   // distortion due to the audio pipeline). If one sample is detected to
694   // have the same or greater magnitude somewhere in the frame, an actual frame
695   // has been received from the remote side (i.e. faked frames are not being
696   // pulled).
697   if (CheckRecBuffer(kHighSampleValue)) ++frames_received_;
698 }
699 
SendFrameP()700 void FakeAudioCaptureModule::SendFrameP() {
701   ASSERT(talk_base::Thread::Current() == process_thread_);
702   if (audio_callback_->RecordedDataIsAvailable(send_buffer_, kNumberSamples,
703                                               kNumberBytesPerSample,
704                                               kNumberOfChannels,
705                                               kSamplesPerSecond, kTotalDelayMs,
706                                               kClockDriftMs, current_mic_level_,
707                                               current_mic_level_) != 0) {
708     ASSERT(false);
709   }
710 }
711 
StopProcessP()712 void FakeAudioCaptureModule::StopProcessP() {
713   ASSERT(talk_base::Thread::Current() == process_thread_);
714   started_ = false;
715   process_thread_->Clear(this);
716 }
717