Home | History | Annotate | Download | only in test
      1 /*
      2  *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 #include "webrtc/test/fake_audio_device.h"
     12 
     13 #include <algorithm>
     14 
     15 #include "testing/gtest/include/gtest/gtest.h"
     16 #include "webrtc/base/platform_thread.h"
     17 #include "webrtc/modules/media_file/media_file_utility.h"
     18 #include "webrtc/system_wrappers/include/clock.h"
     19 #include "webrtc/system_wrappers/include/event_wrapper.h"
     20 #include "webrtc/system_wrappers/include/file_wrapper.h"
     21 
     22 namespace webrtc {
     23 namespace test {
     24 
     25 FakeAudioDevice::FakeAudioDevice(Clock* clock, const std::string& filename)
     26     : audio_callback_(NULL),
     27       capturing_(false),
     28       captured_audio_(),
     29       playout_buffer_(),
     30       last_playout_ms_(-1),
     31       clock_(clock),
     32       tick_(EventTimerWrapper::Create()),
     33       thread_(FakeAudioDevice::Run, this, "FakeAudioDevice"),
     34       file_utility_(new ModuleFileUtility(0)),
     35       input_stream_(FileWrapper::Create()) {
     36   memset(captured_audio_, 0, sizeof(captured_audio_));
     37   memset(playout_buffer_, 0, sizeof(playout_buffer_));
     38   // Open audio input file as read-only and looping.
     39   EXPECT_EQ(0, input_stream_->OpenFile(filename.c_str(), true, true))
     40       << filename;
     41 }
     42 
     43 FakeAudioDevice::~FakeAudioDevice() {
     44   Stop();
     45 
     46   thread_.Stop();
     47 }
     48 
     49 int32_t FakeAudioDevice::Init() {
     50   rtc::CritScope cs(&lock_);
     51   if (file_utility_->InitPCMReading(*input_stream_.get()) != 0)
     52     return -1;
     53 
     54   if (!tick_->StartTimer(true, 10))
     55     return -1;
     56   thread_.Start();
     57   thread_.SetPriority(rtc::kHighPriority);
     58   return 0;
     59 }
     60 
     61 int32_t FakeAudioDevice::RegisterAudioCallback(AudioTransport* callback) {
     62   rtc::CritScope cs(&lock_);
     63   audio_callback_ = callback;
     64   return 0;
     65 }
     66 
     67 bool FakeAudioDevice::Playing() const {
     68   rtc::CritScope cs(&lock_);
     69   return capturing_;
     70 }
     71 
     72 int32_t FakeAudioDevice::PlayoutDelay(uint16_t* delay_ms) const {
     73   *delay_ms = 0;
     74   return 0;
     75 }
     76 
     77 bool FakeAudioDevice::Recording() const {
     78   rtc::CritScope cs(&lock_);
     79   return capturing_;
     80 }
     81 
     82 bool FakeAudioDevice::Run(void* obj) {
     83   static_cast<FakeAudioDevice*>(obj)->CaptureAudio();
     84   return true;
     85 }
     86 
     87 void FakeAudioDevice::CaptureAudio() {
     88   {
     89     rtc::CritScope cs(&lock_);
     90     if (capturing_) {
     91       int bytes_read = file_utility_->ReadPCMData(
     92           *input_stream_.get(), captured_audio_, kBufferSizeBytes);
     93       if (bytes_read <= 0)
     94         return;
     95       // 2 bytes per sample.
     96       size_t num_samples = static_cast<size_t>(bytes_read / 2);
     97       uint32_t new_mic_level;
     98       EXPECT_EQ(0,
     99                 audio_callback_->RecordedDataIsAvailable(captured_audio_,
    100                                                          num_samples,
    101                                                          2,
    102                                                          1,
    103                                                          kFrequencyHz,
    104                                                          0,
    105                                                          0,
    106                                                          0,
    107                                                          false,
    108                                                          new_mic_level));
    109       size_t samples_needed = kFrequencyHz / 100;
    110       int64_t now_ms = clock_->TimeInMilliseconds();
    111       uint32_t time_since_last_playout_ms = now_ms - last_playout_ms_;
    112       if (last_playout_ms_ > 0 && time_since_last_playout_ms > 0) {
    113         samples_needed = std::min(
    114             static_cast<size_t>(kFrequencyHz / time_since_last_playout_ms),
    115             kBufferSizeBytes / 2);
    116       }
    117       size_t samples_out = 0;
    118       int64_t elapsed_time_ms = -1;
    119       int64_t ntp_time_ms = -1;
    120       EXPECT_EQ(0,
    121                 audio_callback_->NeedMorePlayData(samples_needed,
    122                                                   2,
    123                                                   1,
    124                                                   kFrequencyHz,
    125                                                   playout_buffer_,
    126                                                   samples_out,
    127                                                   &elapsed_time_ms,
    128                                                   &ntp_time_ms));
    129     }
    130   }
    131   tick_->Wait(WEBRTC_EVENT_INFINITE);
    132 }
    133 
    134 void FakeAudioDevice::Start() {
    135   rtc::CritScope cs(&lock_);
    136   capturing_ = true;
    137 }
    138 
    139 void FakeAudioDevice::Stop() {
    140   rtc::CritScope cs(&lock_);
    141   capturing_ = false;
    142 }
    143 }  // namespace test
    144 }  // namespace webrtc
    145