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