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