Home | History | Annotate | Download | only in webrtc
      1 /*
      2  * libjingle
      3  * Copyright 2010 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 #ifndef TALK_SESSION_PHONE_FAKEWEBRTCVOICEENGINE_H_
     29 #define TALK_SESSION_PHONE_FAKEWEBRTCVOICEENGINE_H_
     30 
     31 #include <list>
     32 #include <map>
     33 #include <vector>
     34 
     35 #include "talk/media/base/codec.h"
     36 #include "talk/media/base/rtputils.h"
     37 #include "talk/media/webrtc/fakewebrtccommon.h"
     38 #include "talk/media/webrtc/webrtcvoe.h"
     39 #include "webrtc/base/basictypes.h"
     40 #include "webrtc/base/checks.h"
     41 #include "webrtc/base/gunit.h"
     42 #include "webrtc/base/stringutils.h"
     43 #include "webrtc/config.h"
     44 #include "webrtc/modules/audio_coding/acm2/rent_a_codec.h"
     45 #include "webrtc/modules/audio_processing/include/audio_processing.h"
     46 
     47 namespace cricket {
     48 
     49 static const int kOpusBandwidthNb = 4000;
     50 static const int kOpusBandwidthMb = 6000;
     51 static const int kOpusBandwidthWb = 8000;
     52 static const int kOpusBandwidthSwb = 12000;
     53 static const int kOpusBandwidthFb = 20000;
     54 
     55 #define WEBRTC_CHECK_CHANNEL(channel) \
     56   if (channels_.find(channel) == channels_.end()) return -1;
     57 
     58 class FakeAudioProcessing : public webrtc::AudioProcessing {
     59  public:
     60   FakeAudioProcessing() : experimental_ns_enabled_(false) {}
     61 
     62   WEBRTC_STUB(Initialize, ())
     63   WEBRTC_STUB(Initialize, (
     64       int input_sample_rate_hz,
     65       int output_sample_rate_hz,
     66       int reverse_sample_rate_hz,
     67       webrtc::AudioProcessing::ChannelLayout input_layout,
     68       webrtc::AudioProcessing::ChannelLayout output_layout,
     69       webrtc::AudioProcessing::ChannelLayout reverse_layout));
     70   WEBRTC_STUB(Initialize, (
     71       const webrtc::ProcessingConfig& processing_config));
     72 
     73   WEBRTC_VOID_FUNC(SetExtraOptions, (const webrtc::Config& config)) {
     74     experimental_ns_enabled_ = config.Get<webrtc::ExperimentalNs>().enabled;
     75   }
     76 
     77   WEBRTC_STUB_CONST(input_sample_rate_hz, ());
     78   WEBRTC_STUB_CONST(proc_sample_rate_hz, ());
     79   WEBRTC_STUB_CONST(proc_split_sample_rate_hz, ());
     80   size_t num_input_channels() const override { return 0; }
     81   size_t num_proc_channels() const override { return 0; }
     82   size_t num_output_channels() const override { return 0; }
     83   size_t num_reverse_channels() const override { return 0; }
     84   WEBRTC_VOID_STUB(set_output_will_be_muted, (bool muted));
     85   WEBRTC_STUB(ProcessStream, (webrtc::AudioFrame* frame));
     86   WEBRTC_STUB(ProcessStream, (
     87       const float* const* src,
     88       size_t samples_per_channel,
     89       int input_sample_rate_hz,
     90       webrtc::AudioProcessing::ChannelLayout input_layout,
     91       int output_sample_rate_hz,
     92       webrtc::AudioProcessing::ChannelLayout output_layout,
     93       float* const* dest));
     94   WEBRTC_STUB(ProcessStream,
     95               (const float* const* src,
     96                const webrtc::StreamConfig& input_config,
     97                const webrtc::StreamConfig& output_config,
     98                float* const* dest));
     99   WEBRTC_STUB(AnalyzeReverseStream, (webrtc::AudioFrame* frame));
    100   WEBRTC_STUB(ProcessReverseStream, (webrtc::AudioFrame * frame));
    101   WEBRTC_STUB(AnalyzeReverseStream, (
    102       const float* const* data,
    103       size_t samples_per_channel,
    104       int sample_rate_hz,
    105       webrtc::AudioProcessing::ChannelLayout layout));
    106   WEBRTC_STUB(ProcessReverseStream,
    107               (const float* const* src,
    108                const webrtc::StreamConfig& reverse_input_config,
    109                const webrtc::StreamConfig& reverse_output_config,
    110                float* const* dest));
    111   WEBRTC_STUB(set_stream_delay_ms, (int delay));
    112   WEBRTC_STUB_CONST(stream_delay_ms, ());
    113   WEBRTC_BOOL_STUB_CONST(was_stream_delay_set, ());
    114   WEBRTC_VOID_STUB(set_stream_key_pressed, (bool key_pressed));
    115   WEBRTC_VOID_STUB(set_delay_offset_ms, (int offset));
    116   WEBRTC_STUB_CONST(delay_offset_ms, ());
    117   WEBRTC_STUB(StartDebugRecording, (const char filename[kMaxFilenameSize]));
    118   WEBRTC_STUB(StartDebugRecording, (FILE* handle));
    119   WEBRTC_STUB(StopDebugRecording, ());
    120   WEBRTC_VOID_STUB(UpdateHistogramsOnCallEnd, ());
    121   webrtc::EchoCancellation* echo_cancellation() const override { return NULL; }
    122   webrtc::EchoControlMobile* echo_control_mobile() const override {
    123     return NULL;
    124   }
    125   webrtc::GainControl* gain_control() const override { return NULL; }
    126   webrtc::HighPassFilter* high_pass_filter() const override { return NULL; }
    127   webrtc::LevelEstimator* level_estimator() const override { return NULL; }
    128   webrtc::NoiseSuppression* noise_suppression() const override { return NULL; }
    129   webrtc::VoiceDetection* voice_detection() const override { return NULL; }
    130 
    131   bool experimental_ns_enabled() {
    132     return experimental_ns_enabled_;
    133   }
    134 
    135  private:
    136   bool experimental_ns_enabled_;
    137 };
    138 
    139 class FakeWebRtcVoiceEngine
    140     : public webrtc::VoEAudioProcessing,
    141       public webrtc::VoEBase, public webrtc::VoECodec,
    142       public webrtc::VoEHardware,
    143       public webrtc::VoENetwork, public webrtc::VoERTP_RTCP,
    144       public webrtc::VoEVolumeControl {
    145  public:
    146   struct Channel {
    147     explicit Channel()
    148         : external_transport(false),
    149           send(false),
    150           playout(false),
    151           volume_scale(1.0),
    152           vad(false),
    153           codec_fec(false),
    154           max_encoding_bandwidth(0),
    155           opus_dtx(false),
    156           red(false),
    157           nack(false),
    158           cn8_type(13),
    159           cn16_type(105),
    160           red_type(117),
    161           nack_max_packets(0),
    162           send_ssrc(0),
    163           associate_send_channel(-1),
    164           recv_codecs(),
    165           neteq_capacity(-1),
    166           neteq_fast_accelerate(false) {
    167       memset(&send_codec, 0, sizeof(send_codec));
    168     }
    169     bool external_transport;
    170     bool send;
    171     bool playout;
    172     float volume_scale;
    173     bool vad;
    174     bool codec_fec;
    175     int max_encoding_bandwidth;
    176     bool opus_dtx;
    177     bool red;
    178     bool nack;
    179     int cn8_type;
    180     int cn16_type;
    181     int red_type;
    182     int nack_max_packets;
    183     uint32_t send_ssrc;
    184     int associate_send_channel;
    185     std::vector<webrtc::CodecInst> recv_codecs;
    186     webrtc::CodecInst send_codec;
    187     webrtc::PacketTime last_rtp_packet_time;
    188     std::list<std::string> packets;
    189     int neteq_capacity;
    190     bool neteq_fast_accelerate;
    191   };
    192 
    193   FakeWebRtcVoiceEngine()
    194       : inited_(false),
    195         last_channel_(-1),
    196         fail_create_channel_(false),
    197         num_set_send_codecs_(0),
    198         ec_enabled_(false),
    199         ec_metrics_enabled_(false),
    200         cng_enabled_(false),
    201         ns_enabled_(false),
    202         agc_enabled_(false),
    203         highpass_filter_enabled_(false),
    204         stereo_swapping_enabled_(false),
    205         typing_detection_enabled_(false),
    206         ec_mode_(webrtc::kEcDefault),
    207         aecm_mode_(webrtc::kAecmSpeakerphone),
    208         ns_mode_(webrtc::kNsDefault),
    209         agc_mode_(webrtc::kAgcDefault),
    210         observer_(NULL),
    211         playout_fail_channel_(-1),
    212         send_fail_channel_(-1),
    213         recording_sample_rate_(-1),
    214         playout_sample_rate_(-1) {
    215     memset(&agc_config_, 0, sizeof(agc_config_));
    216   }
    217   ~FakeWebRtcVoiceEngine() {
    218     RTC_CHECK(channels_.empty());
    219   }
    220 
    221   bool ec_metrics_enabled() const { return ec_metrics_enabled_; }
    222 
    223   bool IsInited() const { return inited_; }
    224   int GetLastChannel() const { return last_channel_; }
    225   int GetNumChannels() const { return static_cast<int>(channels_.size()); }
    226   uint32_t GetLocalSSRC(int channel) {
    227     return channels_[channel]->send_ssrc;
    228   }
    229   bool GetPlayout(int channel) {
    230     return channels_[channel]->playout;
    231   }
    232   bool GetSend(int channel) {
    233     return channels_[channel]->send;
    234   }
    235   bool GetVAD(int channel) {
    236     return channels_[channel]->vad;
    237   }
    238   bool GetOpusDtx(int channel) {
    239     return channels_[channel]->opus_dtx;
    240   }
    241   bool GetRED(int channel) {
    242     return channels_[channel]->red;
    243   }
    244   bool GetCodecFEC(int channel) {
    245     return channels_[channel]->codec_fec;
    246   }
    247   int GetMaxEncodingBandwidth(int channel) {
    248     return channels_[channel]->max_encoding_bandwidth;
    249   }
    250   bool GetNACK(int channel) {
    251     return channels_[channel]->nack;
    252   }
    253   int GetNACKMaxPackets(int channel) {
    254     return channels_[channel]->nack_max_packets;
    255   }
    256   const webrtc::PacketTime& GetLastRtpPacketTime(int channel) {
    257     RTC_DCHECK(channels_.find(channel) != channels_.end());
    258     return channels_[channel]->last_rtp_packet_time;
    259   }
    260   int GetSendCNPayloadType(int channel, bool wideband) {
    261     return (wideband) ?
    262         channels_[channel]->cn16_type :
    263         channels_[channel]->cn8_type;
    264   }
    265   int GetSendREDPayloadType(int channel) {
    266     return channels_[channel]->red_type;
    267   }
    268   bool CheckPacket(int channel, const void* data, size_t len) {
    269     bool result = !CheckNoPacket(channel);
    270     if (result) {
    271       std::string packet = channels_[channel]->packets.front();
    272       result = (packet == std::string(static_cast<const char*>(data), len));
    273       channels_[channel]->packets.pop_front();
    274     }
    275     return result;
    276   }
    277   bool CheckNoPacket(int channel) {
    278     return channels_[channel]->packets.empty();
    279   }
    280   void TriggerCallbackOnError(int channel_num, int err_code) {
    281     RTC_DCHECK(observer_ != NULL);
    282     observer_->CallbackOnError(channel_num, err_code);
    283   }
    284   void set_playout_fail_channel(int channel) {
    285     playout_fail_channel_ = channel;
    286   }
    287   void set_send_fail_channel(int channel) {
    288     send_fail_channel_ = channel;
    289   }
    290   void set_fail_create_channel(bool fail_create_channel) {
    291     fail_create_channel_ = fail_create_channel;
    292   }
    293   int AddChannel(const webrtc::Config& config) {
    294     if (fail_create_channel_) {
    295       return -1;
    296     }
    297     Channel* ch = new Channel();
    298     auto db = webrtc::acm2::RentACodec::Database();
    299     ch->recv_codecs.assign(db.begin(), db.end());
    300     if (config.Get<webrtc::NetEqCapacityConfig>().enabled) {
    301       ch->neteq_capacity = config.Get<webrtc::NetEqCapacityConfig>().capacity;
    302     }
    303     ch->neteq_fast_accelerate =
    304         config.Get<webrtc::NetEqFastAccelerate>().enabled;
    305     channels_[++last_channel_] = ch;
    306     return last_channel_;
    307   }
    308 
    309   int GetNumSetSendCodecs() const { return num_set_send_codecs_; }
    310 
    311   int GetAssociateSendChannel(int channel) {
    312     return channels_[channel]->associate_send_channel;
    313   }
    314 
    315   WEBRTC_STUB(Release, ());
    316 
    317   // webrtc::VoEBase
    318   WEBRTC_FUNC(RegisterVoiceEngineObserver, (
    319       webrtc::VoiceEngineObserver& observer)) {
    320     observer_ = &observer;
    321     return 0;
    322   }
    323   WEBRTC_STUB(DeRegisterVoiceEngineObserver, ());
    324   WEBRTC_FUNC(Init, (webrtc::AudioDeviceModule* adm,
    325                      webrtc::AudioProcessing* audioproc)) {
    326     inited_ = true;
    327     return 0;
    328   }
    329   WEBRTC_FUNC(Terminate, ()) {
    330     inited_ = false;
    331     return 0;
    332   }
    333   webrtc::AudioProcessing* audio_processing() override {
    334     return &audio_processing_;
    335   }
    336   WEBRTC_FUNC(CreateChannel, ()) {
    337     webrtc::Config empty_config;
    338     return AddChannel(empty_config);
    339   }
    340   WEBRTC_FUNC(CreateChannel, (const webrtc::Config& config)) {
    341     return AddChannel(config);
    342   }
    343   WEBRTC_FUNC(DeleteChannel, (int channel)) {
    344     WEBRTC_CHECK_CHANNEL(channel);
    345     for (const auto& ch : channels_) {
    346       if (ch.second->associate_send_channel == channel) {
    347         ch.second->associate_send_channel = -1;
    348       }
    349     }
    350     delete channels_[channel];
    351     channels_.erase(channel);
    352     return 0;
    353   }
    354   WEBRTC_STUB(StartReceive, (int channel));
    355   WEBRTC_FUNC(StartPlayout, (int channel)) {
    356     if (playout_fail_channel_ != channel) {
    357       WEBRTC_CHECK_CHANNEL(channel);
    358       channels_[channel]->playout = true;
    359       return 0;
    360     } else {
    361       // When playout_fail_channel_ == channel, fail the StartPlayout on this
    362       // channel.
    363       return -1;
    364     }
    365   }
    366   WEBRTC_FUNC(StartSend, (int channel)) {
    367     if (send_fail_channel_ != channel) {
    368       WEBRTC_CHECK_CHANNEL(channel);
    369       channels_[channel]->send = true;
    370       return 0;
    371     } else {
    372       // When send_fail_channel_ == channel, fail the StartSend on this
    373       // channel.
    374       return -1;
    375     }
    376   }
    377   WEBRTC_STUB(StopReceive, (int channel));
    378   WEBRTC_FUNC(StopPlayout, (int channel)) {
    379     WEBRTC_CHECK_CHANNEL(channel);
    380     channels_[channel]->playout = false;
    381     return 0;
    382   }
    383   WEBRTC_FUNC(StopSend, (int channel)) {
    384     WEBRTC_CHECK_CHANNEL(channel);
    385     channels_[channel]->send = false;
    386     return 0;
    387   }
    388   WEBRTC_STUB(GetVersion, (char version[1024]));
    389   WEBRTC_STUB(LastError, ());
    390   WEBRTC_FUNC(AssociateSendChannel, (int channel,
    391                                      int accociate_send_channel)) {
    392     WEBRTC_CHECK_CHANNEL(channel);
    393     channels_[channel]->associate_send_channel = accociate_send_channel;
    394     return 0;
    395   }
    396   webrtc::RtcEventLog* GetEventLog() { return nullptr; }
    397 
    398   // webrtc::VoECodec
    399   WEBRTC_STUB(NumOfCodecs, ());
    400   WEBRTC_STUB(GetCodec, (int index, webrtc::CodecInst& codec));
    401   WEBRTC_FUNC(SetSendCodec, (int channel, const webrtc::CodecInst& codec)) {
    402     WEBRTC_CHECK_CHANNEL(channel);
    403     // To match the behavior of the real implementation.
    404     if (_stricmp(codec.plname, "telephone-event") == 0 ||
    405         _stricmp(codec.plname, "audio/telephone-event") == 0 ||
    406         _stricmp(codec.plname, "CN") == 0 ||
    407         _stricmp(codec.plname, "red") == 0 ) {
    408       return -1;
    409     }
    410     channels_[channel]->send_codec = codec;
    411     ++num_set_send_codecs_;
    412     return 0;
    413   }
    414   WEBRTC_FUNC(GetSendCodec, (int channel, webrtc::CodecInst& codec)) {
    415     WEBRTC_CHECK_CHANNEL(channel);
    416     codec = channels_[channel]->send_codec;
    417     return 0;
    418   }
    419   WEBRTC_STUB(SetBitRate, (int channel, int bitrate_bps));
    420   WEBRTC_STUB(GetRecCodec, (int channel, webrtc::CodecInst& codec));
    421   WEBRTC_FUNC(SetRecPayloadType, (int channel,
    422                                   const webrtc::CodecInst& codec)) {
    423     WEBRTC_CHECK_CHANNEL(channel);
    424     Channel* ch = channels_[channel];
    425     if (ch->playout)
    426       return -1;  // Channel is in use.
    427     // Check if something else already has this slot.
    428     if (codec.pltype != -1) {
    429       for (std::vector<webrtc::CodecInst>::iterator it =
    430           ch->recv_codecs.begin(); it != ch->recv_codecs.end(); ++it) {
    431         if (it->pltype == codec.pltype &&
    432             _stricmp(it->plname, codec.plname) != 0) {
    433           return -1;
    434         }
    435       }
    436     }
    437     // Otherwise try to find this codec and update its payload type.
    438     int result = -1;  // not found
    439     for (std::vector<webrtc::CodecInst>::iterator it = ch->recv_codecs.begin();
    440          it != ch->recv_codecs.end(); ++it) {
    441       if (strcmp(it->plname, codec.plname) == 0 &&
    442           it->plfreq == codec.plfreq &&
    443           it->channels == codec.channels) {
    444         it->pltype = codec.pltype;
    445         result = 0;
    446       }
    447     }
    448     return result;
    449   }
    450   WEBRTC_FUNC(SetSendCNPayloadType, (int channel, int type,
    451                                      webrtc::PayloadFrequencies frequency)) {
    452     WEBRTC_CHECK_CHANNEL(channel);
    453     if (frequency == webrtc::kFreq8000Hz) {
    454       channels_[channel]->cn8_type = type;
    455     } else if (frequency == webrtc::kFreq16000Hz) {
    456       channels_[channel]->cn16_type = type;
    457     }
    458     return 0;
    459   }
    460   WEBRTC_FUNC(GetRecPayloadType, (int channel, webrtc::CodecInst& codec)) {
    461     WEBRTC_CHECK_CHANNEL(channel);
    462     Channel* ch = channels_[channel];
    463     for (std::vector<webrtc::CodecInst>::iterator it = ch->recv_codecs.begin();
    464          it != ch->recv_codecs.end(); ++it) {
    465       if (strcmp(it->plname, codec.plname) == 0 &&
    466           it->plfreq == codec.plfreq &&
    467           it->channels == codec.channels &&
    468           it->pltype != -1) {
    469         codec.pltype = it->pltype;
    470         return 0;
    471       }
    472     }
    473     return -1;  // not found
    474   }
    475   WEBRTC_FUNC(SetVADStatus, (int channel, bool enable, webrtc::VadModes mode,
    476                              bool disableDTX)) {
    477     WEBRTC_CHECK_CHANNEL(channel);
    478     if (channels_[channel]->send_codec.channels == 2) {
    479       // Replicating VoE behavior; VAD cannot be enabled for stereo.
    480       return -1;
    481     }
    482     channels_[channel]->vad = enable;
    483     return 0;
    484   }
    485   WEBRTC_STUB(GetVADStatus, (int channel, bool& enabled,
    486                              webrtc::VadModes& mode, bool& disabledDTX));
    487 
    488   WEBRTC_FUNC(SetFECStatus, (int channel, bool enable)) {
    489     WEBRTC_CHECK_CHANNEL(channel);
    490     if (_stricmp(channels_[channel]->send_codec.plname, "opus") != 0) {
    491       // Return -1 if current send codec is not Opus.
    492       // TODO(minyue): Excludes other codecs if they support inband FEC.
    493       return -1;
    494     }
    495     channels_[channel]->codec_fec = enable;
    496     return 0;
    497   }
    498   WEBRTC_FUNC(GetFECStatus, (int channel, bool& enable)) {
    499     WEBRTC_CHECK_CHANNEL(channel);
    500     enable = channels_[channel]->codec_fec;
    501     return 0;
    502   }
    503 
    504   WEBRTC_FUNC(SetOpusMaxPlaybackRate, (int channel, int frequency_hz)) {
    505     WEBRTC_CHECK_CHANNEL(channel);
    506     if (_stricmp(channels_[channel]->send_codec.plname, "opus") != 0) {
    507       // Return -1 if current send codec is not Opus.
    508       return -1;
    509     }
    510     if (frequency_hz <= 8000)
    511       channels_[channel]->max_encoding_bandwidth = kOpusBandwidthNb;
    512     else if (frequency_hz <= 12000)
    513       channels_[channel]->max_encoding_bandwidth = kOpusBandwidthMb;
    514     else if (frequency_hz <= 16000)
    515       channels_[channel]->max_encoding_bandwidth = kOpusBandwidthWb;
    516     else if (frequency_hz <= 24000)
    517       channels_[channel]->max_encoding_bandwidth = kOpusBandwidthSwb;
    518     else
    519       channels_[channel]->max_encoding_bandwidth = kOpusBandwidthFb;
    520     return 0;
    521   }
    522 
    523   WEBRTC_FUNC(SetOpusDtx, (int channel, bool enable_dtx)) {
    524     WEBRTC_CHECK_CHANNEL(channel);
    525     if (_stricmp(channels_[channel]->send_codec.plname, "opus") != 0) {
    526       // Return -1 if current send codec is not Opus.
    527       return -1;
    528     }
    529     channels_[channel]->opus_dtx = enable_dtx;
    530     return 0;
    531   }
    532 
    533   // webrtc::VoEHardware
    534   WEBRTC_STUB(GetNumOfRecordingDevices, (int& num));
    535   WEBRTC_STUB(GetNumOfPlayoutDevices, (int& num));
    536   WEBRTC_STUB(GetRecordingDeviceName, (int i, char* name, char* guid));
    537   WEBRTC_STUB(GetPlayoutDeviceName, (int i, char* name, char* guid));
    538   WEBRTC_STUB(SetRecordingDevice, (int, webrtc::StereoChannel));
    539   WEBRTC_STUB(SetPlayoutDevice, (int));
    540   WEBRTC_STUB(SetAudioDeviceLayer, (webrtc::AudioLayers));
    541   WEBRTC_STUB(GetAudioDeviceLayer, (webrtc::AudioLayers&));
    542   WEBRTC_FUNC(SetRecordingSampleRate, (unsigned int samples_per_sec)) {
    543     recording_sample_rate_ = samples_per_sec;
    544     return 0;
    545   }
    546   WEBRTC_FUNC_CONST(RecordingSampleRate, (unsigned int* samples_per_sec)) {
    547     *samples_per_sec = recording_sample_rate_;
    548     return 0;
    549   }
    550   WEBRTC_FUNC(SetPlayoutSampleRate, (unsigned int samples_per_sec)) {
    551     playout_sample_rate_ = samples_per_sec;
    552     return 0;
    553   }
    554   WEBRTC_FUNC_CONST(PlayoutSampleRate, (unsigned int* samples_per_sec)) {
    555     *samples_per_sec = playout_sample_rate_;
    556     return 0;
    557   }
    558   WEBRTC_STUB(EnableBuiltInAEC, (bool enable));
    559   virtual bool BuiltInAECIsAvailable() const { return false; }
    560   WEBRTC_STUB(EnableBuiltInAGC, (bool enable));
    561   virtual bool BuiltInAGCIsAvailable() const { return false; }
    562   WEBRTC_STUB(EnableBuiltInNS, (bool enable));
    563   virtual bool BuiltInNSIsAvailable() const { return false; }
    564 
    565   // webrtc::VoENetwork
    566   WEBRTC_FUNC(RegisterExternalTransport, (int channel,
    567                                           webrtc::Transport& transport)) {
    568     WEBRTC_CHECK_CHANNEL(channel);
    569     channels_[channel]->external_transport = true;
    570     return 0;
    571   }
    572   WEBRTC_FUNC(DeRegisterExternalTransport, (int channel)) {
    573     WEBRTC_CHECK_CHANNEL(channel);
    574     channels_[channel]->external_transport = false;
    575     return 0;
    576   }
    577   WEBRTC_FUNC(ReceivedRTPPacket, (int channel, const void* data,
    578                                   size_t length)) {
    579     WEBRTC_CHECK_CHANNEL(channel);
    580     if (!channels_[channel]->external_transport) return -1;
    581     channels_[channel]->packets.push_back(
    582         std::string(static_cast<const char*>(data), length));
    583     return 0;
    584   }
    585   WEBRTC_FUNC(ReceivedRTPPacket, (int channel, const void* data,
    586                                   size_t length,
    587                                   const webrtc::PacketTime& packet_time)) {
    588     WEBRTC_CHECK_CHANNEL(channel);
    589     if (ReceivedRTPPacket(channel, data, length) == -1) {
    590       return -1;
    591     }
    592     channels_[channel]->last_rtp_packet_time = packet_time;
    593     return 0;
    594   }
    595 
    596   WEBRTC_STUB(ReceivedRTCPPacket, (int channel, const void* data,
    597                                    size_t length));
    598 
    599   // webrtc::VoERTP_RTCP
    600   WEBRTC_FUNC(SetLocalSSRC, (int channel, unsigned int ssrc)) {
    601     WEBRTC_CHECK_CHANNEL(channel);
    602     channels_[channel]->send_ssrc = ssrc;
    603     return 0;
    604   }
    605   WEBRTC_STUB(GetLocalSSRC, (int channel, unsigned int& ssrc));
    606   WEBRTC_STUB(GetRemoteSSRC, (int channel, unsigned int& ssrc));
    607   WEBRTC_STUB(SetSendAudioLevelIndicationStatus, (int channel, bool enable,
    608       unsigned char id));
    609   WEBRTC_STUB(SetReceiveAudioLevelIndicationStatus, (int channel, bool enable,
    610       unsigned char id));
    611   WEBRTC_STUB(SetSendAbsoluteSenderTimeStatus, (int channel, bool enable,
    612       unsigned char id));
    613   WEBRTC_STUB(SetReceiveAbsoluteSenderTimeStatus, (int channel, bool enable,
    614       unsigned char id));
    615   WEBRTC_STUB(SetRTCPStatus, (int channel, bool enable));
    616   WEBRTC_STUB(GetRTCPStatus, (int channel, bool& enabled));
    617   WEBRTC_STUB(SetRTCP_CNAME, (int channel, const char cname[256]));
    618   WEBRTC_STUB(GetRTCP_CNAME, (int channel, char cname[256]));
    619   WEBRTC_STUB(GetRemoteRTCP_CNAME, (int channel, char* cname));
    620   WEBRTC_STUB(GetRemoteRTCPData, (int channel, unsigned int& NTPHigh,
    621                                   unsigned int& NTPLow,
    622                                   unsigned int& timestamp,
    623                                   unsigned int& playoutTimestamp,
    624                                   unsigned int* jitter,
    625                                   unsigned short* fractionLost));
    626   WEBRTC_STUB(GetRemoteRTCPReportBlocks,
    627               (int channel, std::vector<webrtc::ReportBlock>* receive_blocks));
    628   WEBRTC_STUB(GetRTPStatistics, (int channel, unsigned int& averageJitterMs,
    629                                  unsigned int& maxJitterMs,
    630                                  unsigned int& discardedPackets));
    631   WEBRTC_STUB(GetRTCPStatistics, (int channel, webrtc::CallStatistics& stats));
    632   WEBRTC_FUNC(SetREDStatus, (int channel, bool enable, int redPayloadtype)) {
    633     WEBRTC_CHECK_CHANNEL(channel);
    634     channels_[channel]->red = enable;
    635     channels_[channel]->red_type = redPayloadtype;
    636     return 0;
    637   }
    638   WEBRTC_FUNC(GetREDStatus, (int channel, bool& enable, int& redPayloadtype)) {
    639     WEBRTC_CHECK_CHANNEL(channel);
    640     enable = channels_[channel]->red;
    641     redPayloadtype = channels_[channel]->red_type;
    642     return 0;
    643   }
    644   WEBRTC_FUNC(SetNACKStatus, (int channel, bool enable, int maxNoPackets)) {
    645     WEBRTC_CHECK_CHANNEL(channel);
    646     channels_[channel]->nack = enable;
    647     channels_[channel]->nack_max_packets = maxNoPackets;
    648     return 0;
    649   }
    650 
    651   // webrtc::VoEVolumeControl
    652   WEBRTC_STUB(SetSpeakerVolume, (unsigned int));
    653   WEBRTC_STUB(GetSpeakerVolume, (unsigned int&));
    654   WEBRTC_STUB(SetMicVolume, (unsigned int));
    655   WEBRTC_STUB(GetMicVolume, (unsigned int&));
    656   WEBRTC_STUB(SetInputMute, (int, bool));
    657   WEBRTC_STUB(GetInputMute, (int, bool&));
    658   WEBRTC_STUB(GetSpeechInputLevel, (unsigned int&));
    659   WEBRTC_STUB(GetSpeechOutputLevel, (int, unsigned int&));
    660   WEBRTC_STUB(GetSpeechInputLevelFullRange, (unsigned int&));
    661   WEBRTC_STUB(GetSpeechOutputLevelFullRange, (int, unsigned int&));
    662   WEBRTC_FUNC(SetChannelOutputVolumeScaling, (int channel, float scale)) {
    663     WEBRTC_CHECK_CHANNEL(channel);
    664     channels_[channel]->volume_scale= scale;
    665     return 0;
    666   }
    667   WEBRTC_FUNC(GetChannelOutputVolumeScaling, (int channel, float& scale)) {
    668     WEBRTC_CHECK_CHANNEL(channel);
    669     scale = channels_[channel]->volume_scale;
    670     return 0;
    671   }
    672   WEBRTC_STUB(SetOutputVolumePan, (int channel, float left, float right));
    673   WEBRTC_STUB(GetOutputVolumePan, (int channel, float& left, float& right));
    674 
    675   // webrtc::VoEAudioProcessing
    676   WEBRTC_FUNC(SetNsStatus, (bool enable, webrtc::NsModes mode)) {
    677     ns_enabled_ = enable;
    678     ns_mode_ = mode;
    679     return 0;
    680   }
    681   WEBRTC_FUNC(GetNsStatus, (bool& enabled, webrtc::NsModes& mode)) {
    682     enabled = ns_enabled_;
    683     mode = ns_mode_;
    684     return 0;
    685   }
    686 
    687   WEBRTC_FUNC(SetAgcStatus, (bool enable, webrtc::AgcModes mode)) {
    688     agc_enabled_ = enable;
    689     agc_mode_ = mode;
    690     return 0;
    691   }
    692   WEBRTC_FUNC(GetAgcStatus, (bool& enabled, webrtc::AgcModes& mode)) {
    693     enabled = agc_enabled_;
    694     mode = agc_mode_;
    695     return 0;
    696   }
    697 
    698   WEBRTC_FUNC(SetAgcConfig, (webrtc::AgcConfig config)) {
    699     agc_config_ = config;
    700     return 0;
    701   }
    702   WEBRTC_FUNC(GetAgcConfig, (webrtc::AgcConfig& config)) {
    703     config = agc_config_;
    704     return 0;
    705   }
    706   WEBRTC_FUNC(SetEcStatus, (bool enable, webrtc::EcModes mode)) {
    707     ec_enabled_ = enable;
    708     ec_mode_ = mode;
    709     return 0;
    710   }
    711   WEBRTC_FUNC(GetEcStatus, (bool& enabled, webrtc::EcModes& mode)) {
    712     enabled = ec_enabled_;
    713     mode = ec_mode_;
    714     return 0;
    715   }
    716   WEBRTC_STUB(EnableDriftCompensation, (bool enable))
    717   WEBRTC_BOOL_STUB(DriftCompensationEnabled, ())
    718   WEBRTC_VOID_STUB(SetDelayOffsetMs, (int offset))
    719   WEBRTC_STUB(DelayOffsetMs, ());
    720   WEBRTC_FUNC(SetAecmMode, (webrtc::AecmModes mode, bool enableCNG)) {
    721     aecm_mode_ = mode;
    722     cng_enabled_ = enableCNG;
    723     return 0;
    724   }
    725   WEBRTC_FUNC(GetAecmMode, (webrtc::AecmModes& mode, bool& enabledCNG)) {
    726     mode = aecm_mode_;
    727     enabledCNG = cng_enabled_;
    728     return 0;
    729   }
    730   WEBRTC_STUB(SetRxNsStatus, (int channel, bool enable, webrtc::NsModes mode));
    731   WEBRTC_STUB(GetRxNsStatus, (int channel, bool& enabled,
    732                               webrtc::NsModes& mode));
    733   WEBRTC_STUB(SetRxAgcStatus, (int channel, bool enable,
    734                                webrtc::AgcModes mode));
    735   WEBRTC_STUB(GetRxAgcStatus, (int channel, bool& enabled,
    736                                webrtc::AgcModes& mode));
    737   WEBRTC_STUB(SetRxAgcConfig, (int channel, webrtc::AgcConfig config));
    738   WEBRTC_STUB(GetRxAgcConfig, (int channel, webrtc::AgcConfig& config));
    739 
    740   WEBRTC_STUB(RegisterRxVadObserver, (int, webrtc::VoERxVadCallback&));
    741   WEBRTC_STUB(DeRegisterRxVadObserver, (int channel));
    742   WEBRTC_STUB(VoiceActivityIndicator, (int channel));
    743   WEBRTC_FUNC(SetEcMetricsStatus, (bool enable)) {
    744     ec_metrics_enabled_ = enable;
    745     return 0;
    746   }
    747   WEBRTC_STUB(GetEcMetricsStatus, (bool& enabled));
    748   WEBRTC_STUB(GetEchoMetrics, (int& ERL, int& ERLE, int& RERL, int& A_NLP));
    749   WEBRTC_STUB(GetEcDelayMetrics, (int& delay_median, int& delay_std,
    750       float& fraction_poor_delays));
    751 
    752   WEBRTC_STUB(StartDebugRecording, (const char* fileNameUTF8));
    753   WEBRTC_STUB(StartDebugRecording, (FILE* handle));
    754   WEBRTC_STUB(StopDebugRecording, ());
    755 
    756   WEBRTC_FUNC(SetTypingDetectionStatus, (bool enable)) {
    757     typing_detection_enabled_ = enable;
    758     return 0;
    759   }
    760   WEBRTC_FUNC(GetTypingDetectionStatus, (bool& enabled)) {
    761     enabled = typing_detection_enabled_;
    762     return 0;
    763   }
    764 
    765   WEBRTC_STUB(TimeSinceLastTyping, (int& seconds));
    766   WEBRTC_STUB(SetTypingDetectionParameters, (int timeWindow,
    767                                              int costPerTyping,
    768                                              int reportingThreshold,
    769                                              int penaltyDecay,
    770                                              int typeEventDelay));
    771   int EnableHighPassFilter(bool enable) {
    772     highpass_filter_enabled_ = enable;
    773     return 0;
    774   }
    775   bool IsHighPassFilterEnabled() {
    776     return highpass_filter_enabled_;
    777   }
    778   bool IsStereoChannelSwappingEnabled() {
    779     return stereo_swapping_enabled_;
    780   }
    781   void EnableStereoChannelSwapping(bool enable) {
    782     stereo_swapping_enabled_ = enable;
    783   }
    784   int GetNetEqCapacity() const {
    785     auto ch = channels_.find(last_channel_);
    786     ASSERT(ch != channels_.end());
    787     return ch->second->neteq_capacity;
    788   }
    789   bool GetNetEqFastAccelerate() const {
    790     auto ch = channels_.find(last_channel_);
    791     ASSERT(ch != channels_.end());
    792     return ch->second->neteq_fast_accelerate;
    793   }
    794 
    795  private:
    796   bool inited_;
    797   int last_channel_;
    798   std::map<int, Channel*> channels_;
    799   bool fail_create_channel_;
    800   int num_set_send_codecs_;  // how many times we call SetSendCodec().
    801   bool ec_enabled_;
    802   bool ec_metrics_enabled_;
    803   bool cng_enabled_;
    804   bool ns_enabled_;
    805   bool agc_enabled_;
    806   bool highpass_filter_enabled_;
    807   bool stereo_swapping_enabled_;
    808   bool typing_detection_enabled_;
    809   webrtc::EcModes ec_mode_;
    810   webrtc::AecmModes aecm_mode_;
    811   webrtc::NsModes ns_mode_;
    812   webrtc::AgcModes agc_mode_;
    813   webrtc::AgcConfig agc_config_;
    814   webrtc::VoiceEngineObserver* observer_;
    815   int playout_fail_channel_;
    816   int send_fail_channel_;
    817   int recording_sample_rate_;
    818   int playout_sample_rate_;
    819   FakeAudioProcessing audio_processing_;
    820 };
    821 
    822 }  // namespace cricket
    823 
    824 #endif  // TALK_SESSION_PHONE_FAKEWEBRTCVOICEENGINE_H_
    825