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