blob: 321e76ba09ba9a454c4c8bffbbd2efde8a7199a5 [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
2 * libjingle
jlmiller@webrtc.org5f93d0a2015-01-20 21:36:13 +00003 * Copyright 2012 Google Inc.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00004 *
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
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000030#include "webrtc/base/common.h"
31#include "webrtc/base/refcount.h"
32#include "webrtc/base/thread.h"
33#include "webrtc/base/timeutils.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000034
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.
39static 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/
43static 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.
47static const int kTimePerFrameMs = 10;
Peter Kastingb7e50542015-06-11 12:55:50 -070048static const uint8_t kNumberOfChannels = 1;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000049static const int kSamplesPerSecond = 44000;
50static const int kTotalDelayMs = 0;
51static const int kClockDriftMs = 0;
52static const uint32_t kMaxVolume = 14392;
53
54enum {
wu@webrtc.org8804a292013-10-22 23:09:20 +000055 MSG_START_PROCESS,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000056 MSG_RUN_PROCESS,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000057};
58
deadbeefee8c6d32015-08-13 14:27:18 -070059FakeAudioCaptureModule::FakeAudioCaptureModule()
henrike@webrtc.org28e20752013-07-10 00:45:36 +000060 : last_process_time_ms_(0),
deadbeefee8c6d32015-08-13 14:27:18 -070061 audio_callback_(nullptr),
henrike@webrtc.org28e20752013-07-10 00:45:36 +000062 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),
henrike@webrtc.org28e20752013-07-10 00:45:36 +000069 frames_received_(0) {
70}
71
72FakeAudioCaptureModule::~FakeAudioCaptureModule() {
deadbeefee8c6d32015-08-13 14:27:18 -070073 if (process_thread_) {
74 process_thread_->Stop();
75 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +000076}
77
deadbeefee8c6d32015-08-13 14:27:18 -070078rtc::scoped_refptr<FakeAudioCaptureModule> FakeAudioCaptureModule::Create() {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000079 rtc::scoped_refptr<FakeAudioCaptureModule> capture_module(
deadbeefee8c6d32015-08-13 14:27:18 -070080 new rtc::RefCountedObject<FakeAudioCaptureModule>());
henrike@webrtc.org28e20752013-07-10 00:45:36 +000081 if (!capture_module->Initialize()) {
deadbeefee8c6d32015-08-13 14:27:18 -070082 return nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000083 }
84 return capture_module;
85}
86
87int FakeAudioCaptureModule::frames_received() const {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000088 rtc::CritScope cs(&crit_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000089 return frames_received_;
90}
91
pkasting@chromium.org0b1534c2014-12-15 22:09:40 +000092int64_t FakeAudioCaptureModule::TimeUntilNextProcess() {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000093 const uint32 current_time = rtc::Time();
henrike@webrtc.org28e20752013-07-10 00:45:36 +000094 if (current_time < last_process_time_ms_) {
95 // TODO: wraparound could be handled more gracefully.
96 return 0;
97 }
98 const uint32 elapsed_time = current_time - last_process_time_ms_;
99 if (kAdmMaxIdleTimeProcess < elapsed_time) {
100 return 0;
101 }
102 return kAdmMaxIdleTimeProcess - elapsed_time;
103}
104
105int32_t FakeAudioCaptureModule::Process() {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000106 last_process_time_ms_ = rtc::Time();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000107 return 0;
108}
109
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000110int32_t FakeAudioCaptureModule::ActiveAudioLayer(
111 AudioLayer* /*audio_layer*/) const {
112 ASSERT(false);
113 return 0;
114}
115
116webrtc::AudioDeviceModule::ErrorCode FakeAudioCaptureModule::LastError() const {
117 ASSERT(false);
118 return webrtc::AudioDeviceModule::kAdmErrNone;
119}
120
121int32_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
128int32_t FakeAudioCaptureModule::RegisterAudioCallback(
129 webrtc::AudioTransport* audio_callback) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000130 rtc::CritScope cs(&crit_callback_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000131 audio_callback_ = audio_callback;
132 return 0;
133}
134
135int32_t FakeAudioCaptureModule::Init() {
136 // Initialize is called by the factory method. Safe to ignore this Init call.
137 return 0;
138}
139
140int32_t FakeAudioCaptureModule::Terminate() {
141 // Clean up in the destructor. No action here, just success.
142 return 0;
143}
144
145bool FakeAudioCaptureModule::Initialized() const {
146 ASSERT(false);
147 return 0;
148}
149
150int16_t FakeAudioCaptureModule::PlayoutDevices() {
151 ASSERT(false);
152 return 0;
153}
154
155int16_t FakeAudioCaptureModule::RecordingDevices() {
156 ASSERT(false);
157 return 0;
158}
159
160int32_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
168int32_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
176int32_t FakeAudioCaptureModule::SetPlayoutDevice(uint16_t /*index*/) {
177 // No playout device, just playing from file. Return success.
178 return 0;
179}
180
181int32_t FakeAudioCaptureModule::SetPlayoutDevice(WindowsDeviceType /*device*/) {
182 if (play_is_initialized_) {
183 return -1;
184 }
185 return 0;
186}
187
188int32_t FakeAudioCaptureModule::SetRecordingDevice(uint16_t /*index*/) {
189 // No recording device, just dropping audio. Return success.
190 return 0;
191}
192
193int32_t FakeAudioCaptureModule::SetRecordingDevice(
194 WindowsDeviceType /*device*/) {
195 if (rec_is_initialized_) {
196 return -1;
197 }
198 return 0;
199}
200
201int32_t FakeAudioCaptureModule::PlayoutIsAvailable(bool* /*available*/) {
202 ASSERT(false);
203 return 0;
204}
205
206int32_t FakeAudioCaptureModule::InitPlayout() {
207 play_is_initialized_ = true;
208 return 0;
209}
210
211bool FakeAudioCaptureModule::PlayoutIsInitialized() const {
212 return play_is_initialized_;
213}
214
215int32_t FakeAudioCaptureModule::RecordingIsAvailable(bool* /*available*/) {
216 ASSERT(false);
217 return 0;
218}
219
220int32_t FakeAudioCaptureModule::InitRecording() {
221 rec_is_initialized_ = true;
222 return 0;
223}
224
225bool FakeAudioCaptureModule::RecordingIsInitialized() const {
226 ASSERT(false);
227 return 0;
228}
229
230int32_t FakeAudioCaptureModule::StartPlayout() {
231 if (!play_is_initialized_) {
232 return -1;
233 }
wu@webrtc.org8804a292013-10-22 23:09:20 +0000234 {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000235 rtc::CritScope cs(&crit_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000236 playing_ = true;
237 }
238 bool start = true;
239 UpdateProcessing(start);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000240 return 0;
241}
242
243int32_t FakeAudioCaptureModule::StopPlayout() {
wu@webrtc.org8804a292013-10-22 23:09:20 +0000244 bool start = false;
245 {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000246 rtc::CritScope cs(&crit_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000247 playing_ = false;
248 start = ShouldStartProcessing();
249 }
250 UpdateProcessing(start);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000251 return 0;
252}
253
254bool FakeAudioCaptureModule::Playing() const {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000255 rtc::CritScope cs(&crit_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000256 return playing_;
257}
258
259int32_t FakeAudioCaptureModule::StartRecording() {
260 if (!rec_is_initialized_) {
261 return -1;
262 }
wu@webrtc.org8804a292013-10-22 23:09:20 +0000263 {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000264 rtc::CritScope cs(&crit_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000265 recording_ = true;
266 }
267 bool start = true;
268 UpdateProcessing(start);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000269 return 0;
270}
271
272int32_t FakeAudioCaptureModule::StopRecording() {
wu@webrtc.org8804a292013-10-22 23:09:20 +0000273 bool start = false;
274 {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000275 rtc::CritScope cs(&crit_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000276 recording_ = false;
277 start = ShouldStartProcessing();
278 }
279 UpdateProcessing(start);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000280 return 0;
281}
282
283bool FakeAudioCaptureModule::Recording() const {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000284 rtc::CritScope cs(&crit_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000285 return recording_;
286}
287
288int32_t FakeAudioCaptureModule::SetAGC(bool /*enable*/) {
289 // No AGC but not needed since audio is pregenerated. Return success.
290 return 0;
291}
292
293bool FakeAudioCaptureModule::AGC() const {
294 ASSERT(false);
295 return 0;
296}
297
298int32_t FakeAudioCaptureModule::SetWaveOutVolume(uint16_t /*volume_left*/,
299 uint16_t /*volume_right*/) {
300 ASSERT(false);
301 return 0;
302}
303
304int32_t FakeAudioCaptureModule::WaveOutVolume(
305 uint16_t* /*volume_left*/,
306 uint16_t* /*volume_right*/) const {
307 ASSERT(false);
308 return 0;
309}
310
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000311int32_t FakeAudioCaptureModule::InitSpeaker() {
312 // No speaker, just playing from file. Return success.
313 return 0;
314}
315
316bool FakeAudioCaptureModule::SpeakerIsInitialized() const {
317 ASSERT(false);
318 return 0;
319}
320
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000321int32_t FakeAudioCaptureModule::InitMicrophone() {
322 // No microphone, just playing from file. Return success.
323 return 0;
324}
325
326bool FakeAudioCaptureModule::MicrophoneIsInitialized() const {
327 ASSERT(false);
328 return 0;
329}
330
331int32_t FakeAudioCaptureModule::SpeakerVolumeIsAvailable(bool* /*available*/) {
332 ASSERT(false);
333 return 0;
334}
335
336int32_t FakeAudioCaptureModule::SetSpeakerVolume(uint32_t /*volume*/) {
337 ASSERT(false);
338 return 0;
339}
340
341int32_t FakeAudioCaptureModule::SpeakerVolume(uint32_t* /*volume*/) const {
342 ASSERT(false);
343 return 0;
344}
345
346int32_t FakeAudioCaptureModule::MaxSpeakerVolume(
347 uint32_t* /*max_volume*/) const {
348 ASSERT(false);
349 return 0;
350}
351
352int32_t FakeAudioCaptureModule::MinSpeakerVolume(
353 uint32_t* /*min_volume*/) const {
354 ASSERT(false);
355 return 0;
356}
357
358int32_t FakeAudioCaptureModule::SpeakerVolumeStepSize(
359 uint16_t* /*step_size*/) const {
360 ASSERT(false);
361 return 0;
362}
363
364int32_t FakeAudioCaptureModule::MicrophoneVolumeIsAvailable(
365 bool* /*available*/) {
366 ASSERT(false);
367 return 0;
368}
369
wu@webrtc.org8804a292013-10-22 23:09:20 +0000370int32_t FakeAudioCaptureModule::SetMicrophoneVolume(uint32_t volume) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000371 rtc::CritScope cs(&crit_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000372 current_mic_level_ = volume;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000373 return 0;
374}
375
376int32_t FakeAudioCaptureModule::MicrophoneVolume(uint32_t* volume) const {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000377 rtc::CritScope cs(&crit_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000378 *volume = current_mic_level_;
379 return 0;
380}
381
382int32_t FakeAudioCaptureModule::MaxMicrophoneVolume(
383 uint32_t* max_volume) const {
384 *max_volume = kMaxVolume;
385 return 0;
386}
387
388int32_t FakeAudioCaptureModule::MinMicrophoneVolume(
389 uint32_t* /*min_volume*/) const {
390 ASSERT(false);
391 return 0;
392}
393
394int32_t FakeAudioCaptureModule::MicrophoneVolumeStepSize(
395 uint16_t* /*step_size*/) const {
396 ASSERT(false);
397 return 0;
398}
399
400int32_t FakeAudioCaptureModule::SpeakerMuteIsAvailable(bool* /*available*/) {
401 ASSERT(false);
402 return 0;
403}
404
405int32_t FakeAudioCaptureModule::SetSpeakerMute(bool /*enable*/) {
406 ASSERT(false);
407 return 0;
408}
409
410int32_t FakeAudioCaptureModule::SpeakerMute(bool* /*enabled*/) const {
411 ASSERT(false);
412 return 0;
413}
414
415int32_t FakeAudioCaptureModule::MicrophoneMuteIsAvailable(bool* /*available*/) {
416 ASSERT(false);
417 return 0;
418}
419
420int32_t FakeAudioCaptureModule::SetMicrophoneMute(bool /*enable*/) {
421 ASSERT(false);
422 return 0;
423}
424
425int32_t FakeAudioCaptureModule::MicrophoneMute(bool* /*enabled*/) const {
426 ASSERT(false);
427 return 0;
428}
429
430int32_t FakeAudioCaptureModule::MicrophoneBoostIsAvailable(
431 bool* /*available*/) {
432 ASSERT(false);
433 return 0;
434}
435
436int32_t FakeAudioCaptureModule::SetMicrophoneBoost(bool /*enable*/) {
437 ASSERT(false);
438 return 0;
439}
440
441int32_t FakeAudioCaptureModule::MicrophoneBoost(bool* /*enabled*/) const {
442 ASSERT(false);
443 return 0;
444}
445
446int32_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
454int32_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
460int32_t FakeAudioCaptureModule::StereoPlayout(bool* /*enabled*/) const {
461 ASSERT(false);
462 return 0;
463}
464
465int32_t FakeAudioCaptureModule::StereoRecordingIsAvailable(
466 bool* available) const {
467 // Keep thing simple. No stereo recording.
468 *available = false;
469 return 0;
470}
471
472int32_t FakeAudioCaptureModule::SetStereoRecording(bool enable) {
473 if (!enable) {
474 return 0;
475 }
476 return -1;
477}
478
479int32_t FakeAudioCaptureModule::StereoRecording(bool* /*enabled*/) const {
480 ASSERT(false);
481 return 0;
482}
483
484int32_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
495int32_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
502int32_t FakeAudioCaptureModule::SetPlayoutBuffer(const BufferType /*type*/,
503 uint16_t /*size_ms*/) {
504 ASSERT(false);
505 return 0;
506}
507
508int32_t FakeAudioCaptureModule::PlayoutBuffer(BufferType* /*type*/,
509 uint16_t* /*size_ms*/) const {
510 ASSERT(false);
511 return 0;
512}
513
514int32_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
520int32_t FakeAudioCaptureModule::RecordingDelay(uint16_t* /*delay_ms*/) const {
521 ASSERT(false);
522 return 0;
523}
524
525int32_t FakeAudioCaptureModule::CPULoad(uint16_t* /*load*/) const {
526 ASSERT(false);
527 return 0;
528}
529
530int32_t FakeAudioCaptureModule::StartRawOutputFileRecording(
531 const char /*pcm_file_name_utf8*/[webrtc::kAdmMaxFileNameSize]) {
532 ASSERT(false);
533 return 0;
534}
535
536int32_t FakeAudioCaptureModule::StopRawOutputFileRecording() {
537 ASSERT(false);
538 return 0;
539}
540
541int32_t FakeAudioCaptureModule::StartRawInputFileRecording(
542 const char /*pcm_file_name_utf8*/[webrtc::kAdmMaxFileNameSize]) {
543 ASSERT(false);
544 return 0;
545}
546
547int32_t FakeAudioCaptureModule::StopRawInputFileRecording() {
548 ASSERT(false);
549 return 0;
550}
551
552int32_t FakeAudioCaptureModule::SetRecordingSampleRate(
553 const uint32_t /*samples_per_sec*/) {
554 ASSERT(false);
555 return 0;
556}
557
558int32_t FakeAudioCaptureModule::RecordingSampleRate(
559 uint32_t* /*samples_per_sec*/) const {
560 ASSERT(false);
561 return 0;
562}
563
564int32_t FakeAudioCaptureModule::SetPlayoutSampleRate(
565 const uint32_t /*samples_per_sec*/) {
566 ASSERT(false);
567 return 0;
568}
569
570int32_t FakeAudioCaptureModule::PlayoutSampleRate(
571 uint32_t* /*samples_per_sec*/) const {
572 ASSERT(false);
573 return 0;
574}
575
576int32_t FakeAudioCaptureModule::ResetAudioDevice() {
577 ASSERT(false);
578 return 0;
579}
580
581int32_t FakeAudioCaptureModule::SetLoudspeakerStatus(bool /*enable*/) {
582 ASSERT(false);
583 return 0;
584}
585
586int32_t FakeAudioCaptureModule::GetLoudspeakerStatus(bool* /*enabled*/) const {
587 ASSERT(false);
588 return 0;
589}
590
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000591void FakeAudioCaptureModule::OnMessage(rtc::Message* msg) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000592 switch (msg->message_id) {
wu@webrtc.org8804a292013-10-22 23:09:20 +0000593 case MSG_START_PROCESS:
594 StartProcessP();
595 break;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000596 case MSG_RUN_PROCESS:
597 ProcessFrameP();
598 break;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000599 default:
600 // All existing messages should be caught. Getting here should never
601 // happen.
602 ASSERT(false);
603 }
604}
605
606bool 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);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000612 last_process_time_ms_ = rtc::Time();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000613 return true;
614}
615
616void FakeAudioCaptureModule::SetSendBuffer(int value) {
617 Sample* buffer_ptr = reinterpret_cast<Sample*>(send_buffer_);
Peter Kasting728d9032015-06-11 14:31:38 -0700618 const int buffer_size_in_samples =
619 sizeof(send_buffer_) / kNumberBytesPerSample;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000620 for (int i = 0; i < buffer_size_in_samples; ++i) {
621 buffer_ptr[i] = value;
622 }
623}
624
625void FakeAudioCaptureModule::ResetRecBuffer() {
626 memset(rec_buffer_, 0, sizeof(rec_buffer_));
627}
628
629bool FakeAudioCaptureModule::CheckRecBuffer(int value) {
630 const Sample* buffer_ptr = reinterpret_cast<const Sample*>(rec_buffer_);
Peter Kasting728d9032015-06-11 14:31:38 -0700631 const int buffer_size_in_samples =
632 sizeof(rec_buffer_) / kNumberBytesPerSample;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000633 for (int i = 0; i < buffer_size_in_samples; ++i) {
634 if (buffer_ptr[i] >= value) return true;
635 }
636 return false;
637}
638
wu@webrtc.org8804a292013-10-22 23:09:20 +0000639bool FakeAudioCaptureModule::ShouldStartProcessing() {
640 return recording_ || playing_;
641}
642
643void FakeAudioCaptureModule::UpdateProcessing(bool start) {
644 if (start) {
deadbeefee8c6d32015-08-13 14:27:18 -0700645 if (!process_thread_) {
646 process_thread_.reset(new rtc::Thread());
647 process_thread_->Start();
648 }
wu@webrtc.org8804a292013-10-22 23:09:20 +0000649 process_thread_->Post(this, MSG_START_PROCESS);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000650 } else {
deadbeefee8c6d32015-08-13 14:27:18 -0700651 if (process_thread_) {
652 process_thread_->Stop();
653 process_thread_.reset(nullptr);
654 }
655 started_ = false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000656 }
657}
658
wu@webrtc.org8804a292013-10-22 23:09:20 +0000659void FakeAudioCaptureModule::StartProcessP() {
deadbeefee8c6d32015-08-13 14:27:18 -0700660 ASSERT(process_thread_->IsCurrent());
wu@webrtc.org8804a292013-10-22 23:09:20 +0000661 if (started_) {
662 // Already started.
663 return;
664 }
665 ProcessFrameP();
666}
667
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000668void FakeAudioCaptureModule::ProcessFrameP() {
deadbeefee8c6d32015-08-13 14:27:18 -0700669 ASSERT(process_thread_->IsCurrent());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000670 if (!started_) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000671 next_frame_time_ = rtc::Time();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000672 started_ = true;
673 }
wu@webrtc.org8804a292013-10-22 23:09:20 +0000674
wu@webrtc.org8804a292013-10-22 23:09:20 +0000675 {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000676 rtc::CritScope cs(&crit_);
deadbeefee8c6d32015-08-13 14:27:18 -0700677 // Receive and send frames every kTimePerFrameMs.
678 if (playing_) {
679 ReceiveFrameP();
680 }
681 if (recording_) {
682 SendFrameP();
683 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000684 }
685
686 next_frame_time_ += kTimePerFrameMs;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000687 const uint32 current_time = rtc::Time();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000688 const uint32 wait_time = (next_frame_time_ > current_time) ?
689 next_frame_time_ - current_time : 0;
690 process_thread_->PostDelayed(wait_time, this, MSG_RUN_PROCESS);
691}
692
693void FakeAudioCaptureModule::ReceiveFrameP() {
deadbeefee8c6d32015-08-13 14:27:18 -0700694 ASSERT(process_thread_->IsCurrent());
wu@webrtc.org8804a292013-10-22 23:09:20 +0000695 {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000696 rtc::CritScope cs(&crit_callback_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000697 if (!audio_callback_) {
698 return;
699 }
700 ResetRecBuffer();
701 uint32_t nSamplesOut = 0;
wu@webrtc.org94454b72014-06-05 20:34:08 +0000702 int64_t elapsed_time_ms = 0;
wu@webrtc.orgcb711f72014-05-19 17:39:11 +0000703 int64_t ntp_time_ms = 0;
704 if (audio_callback_->NeedMorePlayData(kNumberSamples, kNumberBytesPerSample,
705 kNumberOfChannels, kSamplesPerSecond,
706 rec_buffer_, nSamplesOut,
wu@webrtc.org94454b72014-06-05 20:34:08 +0000707 &elapsed_time_ms, &ntp_time_ms) != 0) {
wu@webrtc.org8804a292013-10-22 23:09:20 +0000708 ASSERT(false);
709 }
710 ASSERT(nSamplesOut == kNumberSamples);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000711 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000712 // 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).
wu@webrtc.org8804a292013-10-22 23:09:20 +0000718 if (CheckRecBuffer(kHighSampleValue)) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000719 rtc::CritScope cs(&crit_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000720 ++frames_received_;
721 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000722}
723
724void FakeAudioCaptureModule::SendFrameP() {
deadbeefee8c6d32015-08-13 14:27:18 -0700725 ASSERT(process_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000726 rtc::CritScope cs(&crit_callback_);
wu@webrtc.org8804a292013-10-22 23:09:20 +0000727 if (!audio_callback_) {
728 return;
729 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000730 bool key_pressed = false;
wu@webrtc.org8804a292013-10-22 23:09:20 +0000731 uint32_t current_mic_level = 0;
732 MicrophoneVolume(&current_mic_level);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000733 if (audio_callback_->RecordedDataIsAvailable(send_buffer_, kNumberSamples,
734 kNumberBytesPerSample,
735 kNumberOfChannels,
736 kSamplesPerSecond, kTotalDelayMs,
wu@webrtc.org8804a292013-10-22 23:09:20 +0000737 kClockDriftMs, current_mic_level,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000738 key_pressed,
wu@webrtc.org8804a292013-10-22 23:09:20 +0000739 current_mic_level) != 0) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000740 ASSERT(false);
741 }
wu@webrtc.org8804a292013-10-22 23:09:20 +0000742 SetMicrophoneVolume(current_mic_level);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000743}
744