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/base/basictypes.h"
     36 #include "talk/base/gunit.h"
     37 #include "talk/base/stringutils.h"
     38 #include "talk/media/base/codec.h"
     39 #include "talk/media/base/rtputils.h"
     40 #include "talk/media/base/voiceprocessor.h"
     41 #include "talk/media/webrtc/fakewebrtccommon.h"
     42 #include "talk/media/webrtc/webrtcvoe.h"
     43 
     44 namespace webrtc {
     45 class ViENetwork;
     46 }
     47 
     48 namespace cricket {
     49 
     50 // Function returning stats will return these values
     51 // for all values based on type.
     52 const int kIntStatValue = 123;
     53 const float kFractionLostStatValue = 0.5;
     54 
     55 static const char kFakeDefaultDeviceName[] = "Fake Default";
     56 static const int kFakeDefaultDeviceId = -1;
     57 static const char kFakeDeviceName[] = "Fake Device";
     58 #ifdef WIN32
     59 static const int kFakeDeviceId = 0;
     60 #else
     61 static const int kFakeDeviceId = 1;
     62 #endif
     63 
     64 // Verify the header extension ID, if enabled, is within the bounds specified in
     65 // [RFC5285]: 1-14 inclusive.
     66 #define WEBRTC_CHECK_HEADER_EXTENSION_ID(enable, id) \
     67   do { \
     68     if (enable && (id < 1 || id > 14)) { \
     69       return -1; \
     70     } \
     71   } while (0);
     72 
     73 class FakeWebRtcVoiceEngine
     74     : public webrtc::VoEAudioProcessing,
     75       public webrtc::VoEBase, public webrtc::VoECodec, public webrtc::VoEDtmf,
     76       public webrtc::VoEFile, public webrtc::VoEHardware,
     77       public webrtc::VoEExternalMedia, public webrtc::VoENetEqStats,
     78       public webrtc::VoENetwork, public webrtc::VoERTP_RTCP,
     79       public webrtc::VoEVideoSync, public webrtc::VoEVolumeControl {
     80  public:
     81   struct DtmfInfo {
     82     DtmfInfo()
     83       : dtmf_event_code(-1),
     84         dtmf_out_of_band(false),
     85         dtmf_length_ms(-1) {}
     86     int dtmf_event_code;
     87     bool dtmf_out_of_band;
     88     int dtmf_length_ms;
     89   };
     90   struct Channel {
     91     explicit Channel()
     92         : external_transport(false),
     93           send(false),
     94           playout(false),
     95           volume_scale(1.0),
     96           volume_pan_left(1.0),
     97           volume_pan_right(1.0),
     98           file(false),
     99           vad(false),
    100           codec_fec(false),
    101           red(false),
    102           nack(false),
    103           media_processor_registered(false),
    104           rx_agc_enabled(false),
    105           rx_agc_mode(webrtc::kAgcDefault),
    106           cn8_type(13),
    107           cn16_type(105),
    108           dtmf_type(106),
    109           red_type(117),
    110           nack_max_packets(0),
    111           vie_network(NULL),
    112           video_channel(-1),
    113           send_ssrc(0),
    114           send_audio_level_ext_(-1),
    115           receive_audio_level_ext_(-1),
    116           send_absolute_sender_time_ext_(-1),
    117           receive_absolute_sender_time_ext_(-1) {
    118       memset(&send_codec, 0, sizeof(send_codec));
    119       memset(&rx_agc_config, 0, sizeof(rx_agc_config));
    120     }
    121     bool external_transport;
    122     bool send;
    123     bool playout;
    124     float volume_scale;
    125     float volume_pan_left;
    126     float volume_pan_right;
    127     bool file;
    128     bool vad;
    129     bool codec_fec;
    130     bool red;
    131     bool nack;
    132     bool media_processor_registered;
    133     bool rx_agc_enabled;
    134     webrtc::AgcModes rx_agc_mode;
    135     webrtc::AgcConfig rx_agc_config;
    136     int cn8_type;
    137     int cn16_type;
    138     int dtmf_type;
    139     int red_type;
    140     int nack_max_packets;
    141     webrtc::ViENetwork* vie_network;
    142     int video_channel;
    143     uint32 send_ssrc;
    144     int send_audio_level_ext_;
    145     int receive_audio_level_ext_;
    146     int send_absolute_sender_time_ext_;
    147     int receive_absolute_sender_time_ext_;
    148     DtmfInfo dtmf_info;
    149     std::vector<webrtc::CodecInst> recv_codecs;
    150     webrtc::CodecInst send_codec;
    151     webrtc::PacketTime last_rtp_packet_time;
    152     std::list<std::string> packets;
    153   };
    154 
    155   FakeWebRtcVoiceEngine(const cricket::AudioCodec* const* codecs,
    156                         int num_codecs)
    157       : inited_(false),
    158         last_channel_(-1),
    159         fail_create_channel_(false),
    160         codecs_(codecs),
    161         num_codecs_(num_codecs),
    162         num_set_send_codecs_(0),
    163         ec_enabled_(false),
    164         ec_metrics_enabled_(false),
    165         cng_enabled_(false),
    166         ns_enabled_(false),
    167         agc_enabled_(false),
    168         highpass_filter_enabled_(false),
    169         stereo_swapping_enabled_(false),
    170         typing_detection_enabled_(false),
    171         ec_mode_(webrtc::kEcDefault),
    172         aecm_mode_(webrtc::kAecmSpeakerphone),
    173         ns_mode_(webrtc::kNsDefault),
    174         agc_mode_(webrtc::kAgcDefault),
    175         observer_(NULL),
    176         playout_fail_channel_(-1),
    177         send_fail_channel_(-1),
    178         fail_start_recording_microphone_(false),
    179         recording_microphone_(false),
    180         recording_sample_rate_(-1),
    181         playout_sample_rate_(-1),
    182         media_processor_(NULL) {
    183     memset(&agc_config_, 0, sizeof(agc_config_));
    184   }
    185   ~FakeWebRtcVoiceEngine() {
    186     // Ought to have all been deleted by the WebRtcVoiceMediaChannel
    187     // destructors, but just in case ...
    188     for (std::map<int, Channel*>::const_iterator i = channels_.begin();
    189          i != channels_.end(); ++i) {
    190       delete i->second;
    191     }
    192   }
    193 
    194   bool IsExternalMediaProcessorRegistered() const {
    195     return media_processor_ != NULL;
    196   }
    197   bool IsInited() const { return inited_; }
    198   int GetLastChannel() const { return last_channel_; }
    199   int GetChannelFromLocalSsrc(uint32 local_ssrc) const {
    200     for (std::map<int, Channel*>::const_iterator iter = channels_.begin();
    201          iter != channels_.end(); ++iter) {
    202       if (local_ssrc == iter->second->send_ssrc)
    203         return iter->first;
    204     }
    205     return -1;
    206   }
    207   int GetNumChannels() const { return static_cast<int>(channels_.size()); }
    208   bool GetPlayout(int channel) {
    209     return channels_[channel]->playout;
    210   }
    211   bool GetSend(int channel) {
    212     return channels_[channel]->send;
    213   }
    214   bool GetRecordingMicrophone() {
    215     return recording_microphone_;
    216   }
    217   bool GetVAD(int channel) {
    218     return channels_[channel]->vad;
    219   }
    220   bool GetRED(int channel) {
    221     return channels_[channel]->red;
    222   }
    223   bool GetCodecFEC(int channel) {
    224     return channels_[channel]->codec_fec;
    225   }
    226   bool GetNACK(int channel) {
    227     return channels_[channel]->nack;
    228   }
    229   int GetNACKMaxPackets(int channel) {
    230     return channels_[channel]->nack_max_packets;
    231   }
    232   webrtc::ViENetwork* GetViENetwork(int channel) {
    233     WEBRTC_ASSERT_CHANNEL(channel);
    234     return channels_[channel]->vie_network;
    235   }
    236   int GetVideoChannel(int channel) {
    237     WEBRTC_ASSERT_CHANNEL(channel);
    238     return channels_[channel]->video_channel;
    239   }
    240   const webrtc::PacketTime& GetLastRtpPacketTime(int channel) {
    241     WEBRTC_ASSERT_CHANNEL(channel);
    242     return channels_[channel]->last_rtp_packet_time;
    243   }
    244   int GetSendCNPayloadType(int channel, bool wideband) {
    245     return (wideband) ?
    246         channels_[channel]->cn16_type :
    247         channels_[channel]->cn8_type;
    248   }
    249   int GetSendTelephoneEventPayloadType(int channel) {
    250     return channels_[channel]->dtmf_type;
    251   }
    252   int GetSendREDPayloadType(int channel) {
    253     return channels_[channel]->red_type;
    254   }
    255   bool CheckPacket(int channel, const void* data, size_t len) {
    256     bool result = !CheckNoPacket(channel);
    257     if (result) {
    258       std::string packet = channels_[channel]->packets.front();
    259       result = (packet == std::string(static_cast<const char*>(data), len));
    260       channels_[channel]->packets.pop_front();
    261     }
    262     return result;
    263   }
    264   bool CheckNoPacket(int channel) {
    265     return channels_[channel]->packets.empty();
    266   }
    267   void TriggerCallbackOnError(int channel_num, int err_code) {
    268     ASSERT(observer_ != NULL);
    269     observer_->CallbackOnError(channel_num, err_code);
    270   }
    271   void set_playout_fail_channel(int channel) {
    272     playout_fail_channel_ = channel;
    273   }
    274   void set_send_fail_channel(int channel) {
    275     send_fail_channel_ = channel;
    276   }
    277   void set_fail_start_recording_microphone(
    278       bool fail_start_recording_microphone) {
    279     fail_start_recording_microphone_ = fail_start_recording_microphone;
    280   }
    281   void set_fail_create_channel(bool fail_create_channel) {
    282     fail_create_channel_ = fail_create_channel;
    283   }
    284   void TriggerProcessPacket(MediaProcessorDirection direction) {
    285     webrtc::ProcessingTypes pt =
    286         (direction == cricket::MPD_TX) ?
    287             webrtc::kRecordingPerChannel : webrtc::kPlaybackAllChannelsMixed;
    288     if (media_processor_ != NULL) {
    289       media_processor_->Process(0,
    290                                 pt,
    291                                 NULL,
    292                                 0,
    293                                 0,
    294                                 true);
    295     }
    296   }
    297   int AddChannel() {
    298     if (fail_create_channel_) {
    299       return -1;
    300     }
    301     Channel* ch = new Channel();
    302     for (int i = 0; i < NumOfCodecs(); ++i) {
    303       webrtc::CodecInst codec;
    304       GetCodec(i, codec);
    305       ch->recv_codecs.push_back(codec);
    306     }
    307     channels_[++last_channel_] = ch;
    308     return last_channel_;
    309   }
    310   int GetSendRtpExtensionId(int channel, const std::string& extension) {
    311     WEBRTC_ASSERT_CHANNEL(channel);
    312     if (extension == kRtpAudioLevelHeaderExtension) {
    313       return channels_[channel]->send_audio_level_ext_;
    314     } else if (extension == kRtpAbsoluteSenderTimeHeaderExtension) {
    315       return channels_[channel]->send_absolute_sender_time_ext_;
    316     }
    317     return -1;
    318   }
    319   int GetReceiveRtpExtensionId(int channel, const std::string& extension) {
    320     WEBRTC_ASSERT_CHANNEL(channel);
    321     if (extension == kRtpAudioLevelHeaderExtension) {
    322       return channels_[channel]->receive_audio_level_ext_;
    323     } else if (extension == kRtpAbsoluteSenderTimeHeaderExtension) {
    324       return channels_[channel]->receive_absolute_sender_time_ext_;
    325     }
    326     return -1;
    327   }
    328 
    329   int GetNumSetSendCodecs() const { return num_set_send_codecs_; }
    330 
    331   WEBRTC_STUB(Release, ());
    332 
    333   // webrtc::VoEBase
    334   WEBRTC_FUNC(RegisterVoiceEngineObserver, (
    335       webrtc::VoiceEngineObserver& observer)) {
    336     observer_ = &observer;
    337     return 0;
    338   }
    339   WEBRTC_STUB(DeRegisterVoiceEngineObserver, ());
    340   WEBRTC_FUNC(Init, (webrtc::AudioDeviceModule* adm,
    341                      webrtc::AudioProcessing* audioproc)) {
    342     inited_ = true;
    343     return 0;
    344   }
    345   WEBRTC_FUNC(Terminate, ()) {
    346     inited_ = false;
    347     return 0;
    348   }
    349   virtual webrtc::AudioProcessing* audio_processing() OVERRIDE {
    350     return NULL;
    351   }
    352   WEBRTC_FUNC(CreateChannel, ()) {
    353     return AddChannel();
    354   }
    355   WEBRTC_FUNC(CreateChannel, (const webrtc::Config& /*config*/)) {
    356     return AddChannel();
    357   }
    358   WEBRTC_FUNC(DeleteChannel, (int channel)) {
    359     WEBRTC_CHECK_CHANNEL(channel);
    360     delete channels_[channel];
    361     channels_.erase(channel);
    362     return 0;
    363   }
    364   WEBRTC_STUB(StartReceive, (int channel));
    365   WEBRTC_FUNC(StartPlayout, (int channel)) {
    366     if (playout_fail_channel_ != channel) {
    367       WEBRTC_CHECK_CHANNEL(channel);
    368       channels_[channel]->playout = true;
    369       return 0;
    370     } else {
    371       // When playout_fail_channel_ == channel, fail the StartPlayout on this
    372       // channel.
    373       return -1;
    374     }
    375   }
    376   WEBRTC_FUNC(StartSend, (int channel)) {
    377     if (send_fail_channel_ != channel) {
    378       WEBRTC_CHECK_CHANNEL(channel);
    379       channels_[channel]->send = true;
    380       return 0;
    381     } else {
    382       // When send_fail_channel_ == channel, fail the StartSend on this
    383       // channel.
    384       return -1;
    385     }
    386   }
    387   WEBRTC_STUB(StopReceive, (int channel));
    388   WEBRTC_FUNC(StopPlayout, (int channel)) {
    389     WEBRTC_CHECK_CHANNEL(channel);
    390     channels_[channel]->playout = false;
    391     return 0;
    392   }
    393   WEBRTC_FUNC(StopSend, (int channel)) {
    394     WEBRTC_CHECK_CHANNEL(channel);
    395     channels_[channel]->send = false;
    396     return 0;
    397   }
    398   WEBRTC_STUB(GetVersion, (char version[1024]));
    399   WEBRTC_STUB(LastError, ());
    400   WEBRTC_STUB(SetOnHoldStatus, (int, bool, webrtc::OnHoldModes));
    401   WEBRTC_STUB(GetOnHoldStatus, (int, bool&, webrtc::OnHoldModes&));
    402   WEBRTC_STUB(SetNetEQPlayoutMode, (int, webrtc::NetEqModes));
    403   WEBRTC_STUB(GetNetEQPlayoutMode, (int, webrtc::NetEqModes&));
    404 
    405   // webrtc::VoECodec
    406   WEBRTC_FUNC(NumOfCodecs, ()) {
    407     return num_codecs_;
    408   }
    409   WEBRTC_FUNC(GetCodec, (int index, webrtc::CodecInst& codec)) {
    410     if (index < 0 || index >= NumOfCodecs()) {
    411       return -1;
    412     }
    413     const cricket::AudioCodec& c(*codecs_[index]);
    414     codec.pltype = c.id;
    415     talk_base::strcpyn(codec.plname, sizeof(codec.plname), c.name.c_str());
    416     codec.plfreq = c.clockrate;
    417     codec.pacsize = 0;
    418     codec.channels = c.channels;
    419     codec.rate = c.bitrate;
    420     return 0;
    421   }
    422   WEBRTC_FUNC(SetSendCodec, (int channel, const webrtc::CodecInst& codec)) {
    423     WEBRTC_CHECK_CHANNEL(channel);
    424     // To match the behavior of the real implementation.
    425     if (_stricmp(codec.plname, "telephone-event") == 0 ||
    426         _stricmp(codec.plname, "audio/telephone-event") == 0 ||
    427         _stricmp(codec.plname, "CN") == 0 ||
    428         _stricmp(codec.plname, "red") == 0 ) {
    429       return -1;
    430     }
    431     channels_[channel]->send_codec = codec;
    432     ++num_set_send_codecs_;
    433     return 0;
    434   }
    435   WEBRTC_FUNC(GetSendCodec, (int channel, webrtc::CodecInst& codec)) {
    436     WEBRTC_CHECK_CHANNEL(channel);
    437     codec = channels_[channel]->send_codec;
    438     return 0;
    439   }
    440   WEBRTC_STUB(SetSecondarySendCodec, (int channel,
    441                                       const webrtc::CodecInst& codec,
    442                                       int red_payload_type));
    443   WEBRTC_STUB(RemoveSecondarySendCodec, (int channel));
    444   WEBRTC_STUB(GetSecondarySendCodec, (int channel,
    445                                       webrtc::CodecInst& codec));
    446   WEBRTC_FUNC(GetRecCodec, (int channel, webrtc::CodecInst& codec)) {
    447     WEBRTC_CHECK_CHANNEL(channel);
    448     const Channel* c = channels_[channel];
    449     for (std::list<std::string>::const_iterator it_packet = c->packets.begin();
    450         it_packet != c->packets.end(); ++it_packet) {
    451       int pltype;
    452       if (!GetRtpPayloadType(it_packet->data(), it_packet->length(), &pltype)) {
    453         continue;
    454       }
    455       for (std::vector<webrtc::CodecInst>::const_iterator it_codec =
    456           c->recv_codecs.begin(); it_codec != c->recv_codecs.end();
    457           ++it_codec) {
    458         if (it_codec->pltype == pltype) {
    459           codec = *it_codec;
    460           return 0;
    461         }
    462       }
    463     }
    464     return -1;
    465   }
    466   WEBRTC_STUB(SetAMREncFormat, (int channel, webrtc::AmrMode mode));
    467   WEBRTC_STUB(SetAMRDecFormat, (int channel, webrtc::AmrMode mode));
    468   WEBRTC_STUB(SetAMRWbEncFormat, (int channel, webrtc::AmrMode mode));
    469   WEBRTC_STUB(SetAMRWbDecFormat, (int channel, webrtc::AmrMode mode));
    470   WEBRTC_STUB(SetISACInitTargetRate, (int channel, int rateBps,
    471                                       bool useFixedFrameSize));
    472   WEBRTC_STUB(SetISACMaxRate, (int channel, int rateBps));
    473   WEBRTC_STUB(SetISACMaxPayloadSize, (int channel, int sizeBytes));
    474   WEBRTC_FUNC(SetRecPayloadType, (int channel,
    475                                   const webrtc::CodecInst& codec)) {
    476     WEBRTC_CHECK_CHANNEL(channel);
    477     Channel* ch = channels_[channel];
    478     if (ch->playout)
    479       return -1;  // Channel is in use.
    480     // Check if something else already has this slot.
    481     if (codec.pltype != -1) {
    482       for (std::vector<webrtc::CodecInst>::iterator it =
    483           ch->recv_codecs.begin(); it != ch->recv_codecs.end(); ++it) {
    484         if (it->pltype == codec.pltype &&
    485             _stricmp(it->plname, codec.plname) != 0) {
    486           return -1;
    487         }
    488       }
    489     }
    490     // Otherwise try to find this codec and update its payload type.
    491     for (std::vector<webrtc::CodecInst>::iterator it = ch->recv_codecs.begin();
    492          it != ch->recv_codecs.end(); ++it) {
    493       if (strcmp(it->plname, codec.plname) == 0 &&
    494           it->plfreq == codec.plfreq) {
    495         it->pltype = codec.pltype;
    496         it->channels = codec.channels;
    497         return 0;
    498       }
    499     }
    500     return -1;  // not found
    501   }
    502   WEBRTC_FUNC(SetSendCNPayloadType, (int channel, int type,
    503                                      webrtc::PayloadFrequencies frequency)) {
    504     WEBRTC_CHECK_CHANNEL(channel);
    505     if (frequency == webrtc::kFreq8000Hz) {
    506       channels_[channel]->cn8_type = type;
    507     } else if (frequency == webrtc::kFreq16000Hz) {
    508       channels_[channel]->cn16_type = type;
    509     }
    510     return 0;
    511   }
    512   WEBRTC_FUNC(GetRecPayloadType, (int channel, webrtc::CodecInst& codec)) {
    513     WEBRTC_CHECK_CHANNEL(channel);
    514     Channel* ch = channels_[channel];
    515     for (std::vector<webrtc::CodecInst>::iterator it = ch->recv_codecs.begin();
    516          it != ch->recv_codecs.end(); ++it) {
    517       if (strcmp(it->plname, codec.plname) == 0 &&
    518           it->plfreq == codec.plfreq &&
    519           it->channels == codec.channels &&
    520           it->pltype != -1) {
    521         codec.pltype = it->pltype;
    522         return 0;
    523       }
    524     }
    525     return -1;  // not found
    526   }
    527   WEBRTC_FUNC(SetVADStatus, (int channel, bool enable, webrtc::VadModes mode,
    528                              bool disableDTX)) {
    529     WEBRTC_CHECK_CHANNEL(channel);
    530     if (channels_[channel]->send_codec.channels == 2) {
    531       // Replicating VoE behavior; VAD cannot be enabled for stereo.
    532       return -1;
    533     }
    534     channels_[channel]->vad = enable;
    535     return 0;
    536   }
    537   WEBRTC_STUB(GetVADStatus, (int channel, bool& enabled,
    538                              webrtc::VadModes& mode, bool& disabledDTX));
    539 #ifdef USE_WEBRTC_DEV_BRANCH
    540   WEBRTC_FUNC(SetFECStatus, (int channel, bool enable)) {
    541     WEBRTC_CHECK_CHANNEL(channel);
    542     channels_[channel]->codec_fec = enable;
    543     return 0;
    544   }
    545   WEBRTC_FUNC(GetFECStatus, (int channel, bool& enable)) {
    546     WEBRTC_CHECK_CHANNEL(channel);
    547     enable = channels_[channel]->codec_fec;
    548     return 0;
    549   }
    550 #endif  // USE_WEBRTC_DEV_BRANCH
    551 
    552   // webrtc::VoEDtmf
    553   WEBRTC_FUNC(SendTelephoneEvent, (int channel, int event_code,
    554       bool out_of_band = true, int length_ms = 160, int attenuation_db = 10)) {
    555     channels_[channel]->dtmf_info.dtmf_event_code = event_code;
    556     channels_[channel]->dtmf_info.dtmf_out_of_band = out_of_band;
    557     channels_[channel]->dtmf_info.dtmf_length_ms = length_ms;
    558     return 0;
    559   }
    560 
    561   WEBRTC_FUNC(SetSendTelephoneEventPayloadType,
    562       (int channel, unsigned char type)) {
    563     channels_[channel]->dtmf_type = type;
    564     return 0;
    565   };
    566   WEBRTC_STUB(GetSendTelephoneEventPayloadType,
    567       (int channel, unsigned char& type));
    568 
    569   WEBRTC_STUB(SetDtmfFeedbackStatus, (bool enable, bool directFeedback));
    570   WEBRTC_STUB(GetDtmfFeedbackStatus, (bool& enabled, bool& directFeedback));
    571   WEBRTC_STUB(SetDtmfPlayoutStatus, (int channel, bool enable));
    572   WEBRTC_STUB(GetDtmfPlayoutStatus, (int channel, bool& enabled));
    573 
    574   WEBRTC_FUNC(PlayDtmfTone,
    575       (int event_code, int length_ms = 200, int attenuation_db = 10)) {
    576     dtmf_info_.dtmf_event_code = event_code;
    577     dtmf_info_.dtmf_length_ms = length_ms;
    578     return 0;
    579   }
    580   WEBRTC_STUB(StartPlayingDtmfTone,
    581       (int eventCode, int attenuationDb = 10));
    582   WEBRTC_STUB(StopPlayingDtmfTone, ());
    583 
    584   // webrtc::VoEFile
    585   WEBRTC_FUNC(StartPlayingFileLocally, (int channel, const char* fileNameUTF8,
    586                                         bool loop, webrtc::FileFormats format,
    587                                         float volumeScaling, int startPointMs,
    588                                         int stopPointMs)) {
    589     WEBRTC_CHECK_CHANNEL(channel);
    590     channels_[channel]->file = true;
    591     return 0;
    592   }
    593   WEBRTC_FUNC(StartPlayingFileLocally, (int channel, webrtc::InStream* stream,
    594                                         webrtc::FileFormats format,
    595                                         float volumeScaling, int startPointMs,
    596                                         int stopPointMs)) {
    597     WEBRTC_CHECK_CHANNEL(channel);
    598     channels_[channel]->file = true;
    599     return 0;
    600   }
    601   WEBRTC_FUNC(StopPlayingFileLocally, (int channel)) {
    602     WEBRTC_CHECK_CHANNEL(channel);
    603     channels_[channel]->file = false;
    604     return 0;
    605   }
    606   WEBRTC_FUNC(IsPlayingFileLocally, (int channel)) {
    607     WEBRTC_CHECK_CHANNEL(channel);
    608     return (channels_[channel]->file) ? 1 : 0;
    609   }
    610   WEBRTC_STUB(ScaleLocalFilePlayout, (int channel, float scale));
    611   WEBRTC_STUB(StartPlayingFileAsMicrophone, (int channel,
    612                                              const char* fileNameUTF8,
    613                                              bool loop,
    614                                              bool mixWithMicrophone,
    615                                              webrtc::FileFormats format,
    616                                              float volumeScaling));
    617   WEBRTC_STUB(StartPlayingFileAsMicrophone, (int channel,
    618                                              webrtc::InStream* stream,
    619                                              bool mixWithMicrophone,
    620                                              webrtc::FileFormats format,
    621                                              float volumeScaling));
    622   WEBRTC_STUB(StopPlayingFileAsMicrophone, (int channel));
    623   WEBRTC_STUB(IsPlayingFileAsMicrophone, (int channel));
    624   WEBRTC_STUB(ScaleFileAsMicrophonePlayout, (int channel, float scale));
    625   WEBRTC_STUB(StartRecordingPlayout, (int channel, const char* fileNameUTF8,
    626                                       webrtc::CodecInst* compression,
    627                                       int maxSizeBytes));
    628   WEBRTC_STUB(StartRecordingPlayout, (int channel, webrtc::OutStream* stream,
    629                                       webrtc::CodecInst* compression));
    630   WEBRTC_STUB(StopRecordingPlayout, (int channel));
    631   WEBRTC_FUNC(StartRecordingMicrophone, (const char* fileNameUTF8,
    632                                          webrtc::CodecInst* compression,
    633                                          int maxSizeBytes)) {
    634     if (fail_start_recording_microphone_) {
    635       return -1;
    636     }
    637     recording_microphone_ = true;
    638     return 0;
    639   }
    640   WEBRTC_FUNC(StartRecordingMicrophone, (webrtc::OutStream* stream,
    641                                          webrtc::CodecInst* compression)) {
    642     if (fail_start_recording_microphone_) {
    643       return -1;
    644     }
    645     recording_microphone_ = true;
    646     return 0;
    647   }
    648   WEBRTC_FUNC(StopRecordingMicrophone, ()) {
    649     if (!recording_microphone_) {
    650       return -1;
    651     }
    652     recording_microphone_ = false;
    653     return 0;
    654   }
    655   WEBRTC_STUB(ConvertPCMToWAV, (const char* fileNameInUTF8,
    656                                 const char* fileNameOutUTF8));
    657   WEBRTC_STUB(ConvertPCMToWAV, (webrtc::InStream* streamIn,
    658                                 webrtc::OutStream* streamOut));
    659   WEBRTC_STUB(ConvertWAVToPCM, (const char* fileNameInUTF8,
    660                                 const char* fileNameOutUTF8));
    661   WEBRTC_STUB(ConvertWAVToPCM, (webrtc::InStream* streamIn,
    662                                 webrtc::OutStream* streamOut));
    663   WEBRTC_STUB(ConvertPCMToCompressed, (const char* fileNameInUTF8,
    664                                        const char* fileNameOutUTF8,
    665                                        webrtc::CodecInst* compression));
    666   WEBRTC_STUB(ConvertPCMToCompressed, (webrtc::InStream* streamIn,
    667                                        webrtc::OutStream* streamOut,
    668                                        webrtc::CodecInst* compression));
    669   WEBRTC_STUB(ConvertCompressedToPCM, (const char* fileNameInUTF8,
    670                                      const char* fileNameOutUTF8));
    671   WEBRTC_STUB(ConvertCompressedToPCM, (webrtc::InStream* streamIn,
    672                                        webrtc::OutStream* streamOut));
    673   WEBRTC_STUB(GetFileDuration, (const char* fileNameUTF8, int& durationMs,
    674                                 webrtc::FileFormats format));
    675   WEBRTC_STUB(GetPlaybackPosition, (int channel, int& positionMs));
    676 
    677   // webrtc::VoEHardware
    678   WEBRTC_STUB(GetCPULoad, (int&));
    679   WEBRTC_FUNC(GetNumOfRecordingDevices, (int& num)) {
    680     return GetNumDevices(num);
    681   }
    682   WEBRTC_FUNC(GetNumOfPlayoutDevices, (int& num)) {
    683     return GetNumDevices(num);
    684   }
    685   WEBRTC_FUNC(GetRecordingDeviceName, (int i, char* name, char* guid)) {
    686     return GetDeviceName(i, name, guid);
    687   }
    688   WEBRTC_FUNC(GetPlayoutDeviceName, (int i, char* name, char* guid)) {
    689     return GetDeviceName(i, name, guid);
    690   }
    691   WEBRTC_STUB(SetRecordingDevice, (int, webrtc::StereoChannel));
    692   WEBRTC_STUB(SetPlayoutDevice, (int));
    693   WEBRTC_STUB(SetAudioDeviceLayer, (webrtc::AudioLayers));
    694   WEBRTC_STUB(GetAudioDeviceLayer, (webrtc::AudioLayers&));
    695   WEBRTC_STUB(GetPlayoutDeviceStatus, (bool&));
    696   WEBRTC_STUB(GetRecordingDeviceStatus, (bool&));
    697   WEBRTC_STUB(ResetAudioDevice, ());
    698   WEBRTC_STUB(AudioDeviceControl, (unsigned int, unsigned int, unsigned int));
    699   WEBRTC_STUB(SetLoudspeakerStatus, (bool enable));
    700   WEBRTC_STUB(GetLoudspeakerStatus, (bool& enabled));
    701   WEBRTC_FUNC(SetRecordingSampleRate, (unsigned int samples_per_sec)) {
    702     recording_sample_rate_ = samples_per_sec;
    703     return 0;
    704   }
    705   WEBRTC_FUNC_CONST(RecordingSampleRate, (unsigned int* samples_per_sec)) {
    706     *samples_per_sec = recording_sample_rate_;
    707     return 0;
    708   }
    709   WEBRTC_FUNC(SetPlayoutSampleRate, (unsigned int samples_per_sec)) {
    710     playout_sample_rate_ = samples_per_sec;
    711     return 0;
    712   }
    713   WEBRTC_FUNC_CONST(PlayoutSampleRate, (unsigned int* samples_per_sec)) {
    714     *samples_per_sec = playout_sample_rate_;
    715     return 0;
    716   }
    717   WEBRTC_STUB(EnableBuiltInAEC, (bool enable));
    718   virtual bool BuiltInAECIsEnabled() const { return true; }
    719 
    720   // webrtc::VoENetEqStats
    721   WEBRTC_STUB(GetNetworkStatistics, (int, webrtc::NetworkStatistics&));
    722   WEBRTC_FUNC_CONST(GetDecodingCallStatistics, (int channel,
    723       webrtc::AudioDecodingCallStats*)) {
    724     WEBRTC_CHECK_CHANNEL(channel);
    725     return 0;
    726   }
    727 
    728   // webrtc::VoENetwork
    729   WEBRTC_FUNC(RegisterExternalTransport, (int channel,
    730                                           webrtc::Transport& transport)) {
    731     WEBRTC_CHECK_CHANNEL(channel);
    732     channels_[channel]->external_transport = true;
    733     return 0;
    734   }
    735   WEBRTC_FUNC(DeRegisterExternalTransport, (int channel)) {
    736     WEBRTC_CHECK_CHANNEL(channel);
    737     channels_[channel]->external_transport = false;
    738     return 0;
    739   }
    740   WEBRTC_FUNC(ReceivedRTPPacket, (int channel, const void* data,
    741                                   unsigned int length)) {
    742     WEBRTC_CHECK_CHANNEL(channel);
    743     if (!channels_[channel]->external_transport) return -1;
    744     channels_[channel]->packets.push_back(
    745         std::string(static_cast<const char*>(data), length));
    746     return 0;
    747   }
    748   WEBRTC_FUNC(ReceivedRTPPacket, (int channel, const void* data,
    749                                   unsigned int length,
    750                                   const webrtc::PacketTime& packet_time)) {
    751     WEBRTC_CHECK_CHANNEL(channel);
    752     if (ReceivedRTPPacket(channel, data, length) == -1) {
    753       return -1;
    754     }
    755     channels_[channel]->last_rtp_packet_time = packet_time;
    756     return 0;
    757   }
    758 
    759   WEBRTC_STUB(ReceivedRTCPPacket, (int channel, const void* data,
    760                                    unsigned int length));
    761 
    762   // webrtc::VoERTP_RTCP
    763   WEBRTC_STUB(RegisterRTPObserver, (int channel,
    764                                     webrtc::VoERTPObserver& observer));
    765   WEBRTC_STUB(DeRegisterRTPObserver, (int channel));
    766   WEBRTC_STUB(RegisterRTCPObserver, (int channel,
    767                                      webrtc::VoERTCPObserver& observer));
    768   WEBRTC_STUB(DeRegisterRTCPObserver, (int channel));
    769   WEBRTC_FUNC(SetLocalSSRC, (int channel, unsigned int ssrc)) {
    770     WEBRTC_CHECK_CHANNEL(channel);
    771     channels_[channel]->send_ssrc = ssrc;
    772     return 0;
    773   }
    774   WEBRTC_FUNC(GetLocalSSRC, (int channel, unsigned int& ssrc)) {
    775     WEBRTC_CHECK_CHANNEL(channel);
    776     ssrc = channels_[channel]->send_ssrc;
    777     return 0;
    778   }
    779   WEBRTC_STUB(GetRemoteSSRC, (int channel, unsigned int& ssrc));
    780   WEBRTC_FUNC(SetSendAudioLevelIndicationStatus, (int channel, bool enable,
    781       unsigned char id)) {
    782     WEBRTC_CHECK_CHANNEL(channel);
    783     WEBRTC_CHECK_HEADER_EXTENSION_ID(enable, id);
    784     channels_[channel]->send_audio_level_ext_ = (enable) ? id : -1;
    785     return 0;
    786   }
    787 #ifdef USE_WEBRTC_DEV_BRANCH
    788   WEBRTC_FUNC(SetReceiveAudioLevelIndicationStatus, (int channel, bool enable,
    789       unsigned char id)) {
    790     WEBRTC_CHECK_CHANNEL(channel);
    791     WEBRTC_CHECK_HEADER_EXTENSION_ID(enable, id);
    792     channels_[channel]->receive_audio_level_ext_ = (enable) ? id : -1;
    793    return 0;
    794   }
    795 #endif  // USE_WEBRTC_DEV_BRANCH
    796   WEBRTC_FUNC(SetSendAbsoluteSenderTimeStatus, (int channel, bool enable,
    797       unsigned char id)) {
    798     WEBRTC_CHECK_CHANNEL(channel);
    799     WEBRTC_CHECK_HEADER_EXTENSION_ID(enable, id);
    800     channels_[channel]->send_absolute_sender_time_ext_ = (enable) ? id : -1;
    801     return 0;
    802   }
    803   WEBRTC_FUNC(SetReceiveAbsoluteSenderTimeStatus, (int channel, bool enable,
    804       unsigned char id)) {
    805     WEBRTC_CHECK_CHANNEL(channel);
    806     WEBRTC_CHECK_HEADER_EXTENSION_ID(enable, id);
    807     channels_[channel]->receive_absolute_sender_time_ext_ = (enable) ? id : -1;
    808     return 0;
    809   }
    810 
    811   WEBRTC_STUB(GetRemoteCSRCs, (int channel, unsigned int arrCSRC[15]));
    812   WEBRTC_STUB(SetRTCPStatus, (int channel, bool enable));
    813   WEBRTC_STUB(GetRTCPStatus, (int channel, bool& enabled));
    814   WEBRTC_STUB(SetRTCP_CNAME, (int channel, const char cname[256]));
    815   WEBRTC_STUB(GetRTCP_CNAME, (int channel, char cname[256]));
    816   WEBRTC_STUB(GetRemoteRTCP_CNAME, (int channel, char* cname));
    817   WEBRTC_STUB(GetRemoteRTCPData, (int channel, unsigned int& NTPHigh,
    818                                   unsigned int& NTPLow,
    819                                   unsigned int& timestamp,
    820                                   unsigned int& playoutTimestamp,
    821                                   unsigned int* jitter,
    822                                   unsigned short* fractionLost));
    823   WEBRTC_STUB(GetRemoteRTCPSenderInfo, (int channel,
    824                                         webrtc::SenderInfo* sender_info));
    825   WEBRTC_FUNC(GetRemoteRTCPReportBlocks,
    826               (int channel, std::vector<webrtc::ReportBlock>* receive_blocks)) {
    827     WEBRTC_CHECK_CHANNEL(channel);
    828     webrtc::ReportBlock block;
    829     block.source_SSRC = channels_[channel]->send_ssrc;
    830     webrtc::CodecInst send_codec = channels_[channel]->send_codec;
    831     if (send_codec.pltype >= 0) {
    832       block.fraction_lost = (unsigned char)(kFractionLostStatValue * 256);
    833       if (send_codec.plfreq / 1000 > 0) {
    834         block.interarrival_jitter = kIntStatValue * (send_codec.plfreq / 1000);
    835       }
    836       block.cumulative_num_packets_lost = kIntStatValue;
    837       block.extended_highest_sequence_number = kIntStatValue;
    838       receive_blocks->push_back(block);
    839     }
    840     return 0;
    841   }
    842   WEBRTC_STUB(SendApplicationDefinedRTCPPacket, (int channel,
    843                                                  unsigned char subType,
    844                                                  unsigned int name,
    845                                                  const char* data,
    846                                                  unsigned short dataLength));
    847   WEBRTC_STUB(GetRTPStatistics, (int channel, unsigned int& averageJitterMs,
    848                                  unsigned int& maxJitterMs,
    849                                  unsigned int& discardedPackets));
    850   WEBRTC_FUNC(GetRTCPStatistics, (int channel, webrtc::CallStatistics& stats)) {
    851     WEBRTC_CHECK_CHANNEL(channel);
    852     stats.fractionLost = static_cast<int16>(kIntStatValue);
    853     stats.cumulativeLost = kIntStatValue;
    854     stats.extendedMax = kIntStatValue;
    855     stats.jitterSamples = kIntStatValue;
    856     stats.rttMs = kIntStatValue;
    857     stats.bytesSent = kIntStatValue;
    858     stats.packetsSent = kIntStatValue;
    859     stats.bytesReceived = kIntStatValue;
    860     stats.packetsReceived = kIntStatValue;
    861     return 0;
    862   }
    863 #ifdef USE_WEBRTC_DEV_BRANCH
    864   WEBRTC_FUNC(SetREDStatus, (int channel, bool enable, int redPayloadtype)) {
    865 #else
    866   WEBRTC_FUNC(SetFECStatus, (int channel, bool enable, int redPayloadtype)) {
    867 #endif  // USE_WEBRTC_DEV_BRANCH
    868     WEBRTC_CHECK_CHANNEL(channel);
    869     channels_[channel]->red = enable;
    870     channels_[channel]->red_type = redPayloadtype;
    871     return 0;
    872   }
    873 #ifdef USE_WEBRTC_DEV_BRANCH
    874   WEBRTC_FUNC(GetREDStatus, (int channel, bool& enable, int& redPayloadtype)) {
    875 #else
    876   WEBRTC_FUNC(GetFECStatus, (int channel, bool& enable, int& redPayloadtype)) {
    877 #endif  // USE_WEBRTC_DEV_BRANCH
    878     WEBRTC_CHECK_CHANNEL(channel);
    879     enable = channels_[channel]->red;
    880     redPayloadtype = channels_[channel]->red_type;
    881     return 0;
    882   }
    883   WEBRTC_FUNC(SetNACKStatus, (int channel, bool enable, int maxNoPackets)) {
    884     WEBRTC_CHECK_CHANNEL(channel);
    885     channels_[channel]->nack = enable;
    886     channels_[channel]->nack_max_packets = maxNoPackets;
    887     return 0;
    888   }
    889   WEBRTC_STUB(StartRTPDump, (int channel, const char* fileNameUTF8,
    890                              webrtc::RTPDirections direction));
    891   WEBRTC_STUB(StopRTPDump, (int channel, webrtc::RTPDirections direction));
    892   WEBRTC_STUB(RTPDumpIsActive, (int channel, webrtc::RTPDirections direction));
    893   WEBRTC_STUB(InsertExtraRTPPacket, (int channel, unsigned char payloadType,
    894                                      bool markerBit, const char* payloadData,
    895                                      unsigned short payloadSize));
    896   WEBRTC_STUB(GetLastRemoteTimeStamp, (int channel,
    897                                        uint32_t* lastRemoteTimeStamp));
    898   WEBRTC_FUNC(SetVideoEngineBWETarget, (int channel,
    899                                         webrtc::ViENetwork* vie_network,
    900                                         int video_channel)) {
    901     WEBRTC_CHECK_CHANNEL(channel);
    902     channels_[channel]->vie_network = vie_network;
    903     channels_[channel]->video_channel = video_channel;
    904     return 0;
    905   }
    906 
    907   // webrtc::VoEVideoSync
    908   WEBRTC_STUB(GetPlayoutBufferSize, (int& bufferMs));
    909   WEBRTC_STUB(GetPlayoutTimestamp, (int channel, unsigned int& timestamp));
    910   WEBRTC_STUB(GetRtpRtcp, (int, webrtc::RtpRtcp**, webrtc::RtpReceiver**));
    911   WEBRTC_STUB(SetInitTimestamp, (int channel, unsigned int timestamp));
    912   WEBRTC_STUB(SetInitSequenceNumber, (int channel, short sequenceNumber));
    913   WEBRTC_STUB(SetMinimumPlayoutDelay, (int channel, int delayMs));
    914   WEBRTC_STUB(SetInitialPlayoutDelay, (int channel, int delay_ms));
    915   WEBRTC_STUB(GetDelayEstimate, (int channel, int* jitter_buffer_delay_ms,
    916                                  int* playout_buffer_delay_ms));
    917   WEBRTC_STUB_CONST(GetLeastRequiredDelayMs, (int channel));
    918 
    919   // webrtc::VoEVolumeControl
    920   WEBRTC_STUB(SetSpeakerVolume, (unsigned int));
    921   WEBRTC_STUB(GetSpeakerVolume, (unsigned int&));
    922   WEBRTC_STUB(SetSystemOutputMute, (bool));
    923   WEBRTC_STUB(GetSystemOutputMute, (bool&));
    924   WEBRTC_STUB(SetMicVolume, (unsigned int));
    925   WEBRTC_STUB(GetMicVolume, (unsigned int&));
    926   WEBRTC_STUB(SetInputMute, (int, bool));
    927   WEBRTC_STUB(GetInputMute, (int, bool&));
    928   WEBRTC_STUB(SetSystemInputMute, (bool));
    929   WEBRTC_STUB(GetSystemInputMute, (bool&));
    930   WEBRTC_STUB(GetSpeechInputLevel, (unsigned int&));
    931   WEBRTC_STUB(GetSpeechOutputLevel, (int, unsigned int&));
    932   WEBRTC_STUB(GetSpeechInputLevelFullRange, (unsigned int&));
    933   WEBRTC_STUB(GetSpeechOutputLevelFullRange, (int, unsigned int&));
    934   WEBRTC_FUNC(SetChannelOutputVolumeScaling, (int channel, float scale)) {
    935     WEBRTC_CHECK_CHANNEL(channel);
    936     channels_[channel]->volume_scale= scale;
    937     return 0;
    938   }
    939   WEBRTC_FUNC(GetChannelOutputVolumeScaling, (int channel, float& scale)) {
    940     WEBRTC_CHECK_CHANNEL(channel);
    941     scale = channels_[channel]->volume_scale;
    942     return 0;
    943   }
    944   WEBRTC_FUNC(SetOutputVolumePan, (int channel, float left, float right)) {
    945     WEBRTC_CHECK_CHANNEL(channel);
    946     channels_[channel]->volume_pan_left = left;
    947     channels_[channel]->volume_pan_right = right;
    948     return 0;
    949   }
    950   WEBRTC_FUNC(GetOutputVolumePan, (int channel, float& left, float& right)) {
    951     WEBRTC_CHECK_CHANNEL(channel);
    952     left = channels_[channel]->volume_pan_left;
    953     right = channels_[channel]->volume_pan_right;
    954     return 0;
    955   }
    956 
    957   // webrtc::VoEAudioProcessing
    958   WEBRTC_FUNC(SetNsStatus, (bool enable, webrtc::NsModes mode)) {
    959     ns_enabled_ = enable;
    960     ns_mode_ = mode;
    961     return 0;
    962   }
    963   WEBRTC_FUNC(GetNsStatus, (bool& enabled, webrtc::NsModes& mode)) {
    964     enabled = ns_enabled_;
    965     mode = ns_mode_;
    966     return 0;
    967   }
    968 
    969   WEBRTC_FUNC(SetAgcStatus, (bool enable, webrtc::AgcModes mode)) {
    970     agc_enabled_ = enable;
    971     agc_mode_ = mode;
    972     return 0;
    973   }
    974   WEBRTC_FUNC(GetAgcStatus, (bool& enabled, webrtc::AgcModes& mode)) {
    975     enabled = agc_enabled_;
    976     mode = agc_mode_;
    977     return 0;
    978   }
    979 
    980   WEBRTC_FUNC(SetAgcConfig, (webrtc::AgcConfig config)) {
    981     agc_config_ = config;
    982     return 0;
    983   }
    984   WEBRTC_FUNC(GetAgcConfig, (webrtc::AgcConfig& config)) {
    985     config = agc_config_;
    986     return 0;
    987   }
    988   WEBRTC_FUNC(SetEcStatus, (bool enable, webrtc::EcModes mode)) {
    989     ec_enabled_ = enable;
    990     ec_mode_ = mode;
    991     return 0;
    992   }
    993   WEBRTC_FUNC(GetEcStatus, (bool& enabled, webrtc::EcModes& mode)) {
    994     enabled = ec_enabled_;
    995     mode = ec_mode_;
    996     return 0;
    997   }
    998   WEBRTC_STUB(EnableDriftCompensation, (bool enable))
    999   WEBRTC_BOOL_STUB(DriftCompensationEnabled, ())
   1000   WEBRTC_VOID_STUB(SetDelayOffsetMs, (int offset))
   1001   WEBRTC_STUB(DelayOffsetMs, ());
   1002   WEBRTC_FUNC(SetAecmMode, (webrtc::AecmModes mode, bool enableCNG)) {
   1003     aecm_mode_ = mode;
   1004     cng_enabled_ = enableCNG;
   1005     return 0;
   1006   }
   1007   WEBRTC_FUNC(GetAecmMode, (webrtc::AecmModes& mode, bool& enabledCNG)) {
   1008     mode = aecm_mode_;
   1009     enabledCNG = cng_enabled_;
   1010     return 0;
   1011   }
   1012   WEBRTC_STUB(SetRxNsStatus, (int channel, bool enable, webrtc::NsModes mode));
   1013   WEBRTC_STUB(GetRxNsStatus, (int channel, bool& enabled,
   1014                               webrtc::NsModes& mode));
   1015   WEBRTC_FUNC(SetRxAgcStatus, (int channel, bool enable,
   1016                                webrtc::AgcModes mode)) {
   1017     channels_[channel]->rx_agc_enabled = enable;
   1018     channels_[channel]->rx_agc_mode = mode;
   1019     return 0;
   1020   }
   1021   WEBRTC_FUNC(GetRxAgcStatus, (int channel, bool& enabled,
   1022                                webrtc::AgcModes& mode)) {
   1023     enabled = channels_[channel]->rx_agc_enabled;
   1024     mode = channels_[channel]->rx_agc_mode;
   1025     return 0;
   1026   }
   1027 
   1028   WEBRTC_FUNC(SetRxAgcConfig, (int channel, webrtc::AgcConfig config)) {
   1029     channels_[channel]->rx_agc_config = config;
   1030     return 0;
   1031   }
   1032   WEBRTC_FUNC(GetRxAgcConfig, (int channel, webrtc::AgcConfig& config)) {
   1033     config = channels_[channel]->rx_agc_config;
   1034     return 0;
   1035   }
   1036 
   1037   WEBRTC_STUB(RegisterRxVadObserver, (int, webrtc::VoERxVadCallback&));
   1038   WEBRTC_STUB(DeRegisterRxVadObserver, (int channel));
   1039   WEBRTC_STUB(VoiceActivityIndicator, (int channel));
   1040   WEBRTC_FUNC(SetEcMetricsStatus, (bool enable)) {
   1041     ec_metrics_enabled_ = enable;
   1042     return 0;
   1043   }
   1044   WEBRTC_FUNC(GetEcMetricsStatus, (bool& enabled)) {
   1045     enabled = ec_metrics_enabled_;
   1046     return 0;
   1047   }
   1048   WEBRTC_STUB(GetEchoMetrics, (int& ERL, int& ERLE, int& RERL, int& A_NLP));
   1049   WEBRTC_STUB(GetEcDelayMetrics, (int& delay_median, int& delay_std));
   1050 
   1051   WEBRTC_STUB(StartDebugRecording, (const char* fileNameUTF8));
   1052   WEBRTC_STUB(StartDebugRecording, (FILE* handle));
   1053   WEBRTC_STUB(StopDebugRecording, ());
   1054 
   1055   WEBRTC_FUNC(SetTypingDetectionStatus, (bool enable)) {
   1056     typing_detection_enabled_ = enable;
   1057     return 0;
   1058   }
   1059   WEBRTC_FUNC(GetTypingDetectionStatus, (bool& enabled)) {
   1060     enabled = typing_detection_enabled_;
   1061     return 0;
   1062   }
   1063 
   1064   WEBRTC_STUB(TimeSinceLastTyping, (int& seconds));
   1065   WEBRTC_STUB(SetTypingDetectionParameters, (int timeWindow,
   1066                                              int costPerTyping,
   1067                                              int reportingThreshold,
   1068                                              int penaltyDecay,
   1069                                              int typeEventDelay));
   1070   int EnableHighPassFilter(bool enable) {
   1071     highpass_filter_enabled_ = enable;
   1072     return 0;
   1073   }
   1074   bool IsHighPassFilterEnabled() {
   1075     return highpass_filter_enabled_;
   1076   }
   1077   bool IsStereoChannelSwappingEnabled() {
   1078     return stereo_swapping_enabled_;
   1079   }
   1080   void EnableStereoChannelSwapping(bool enable) {
   1081     stereo_swapping_enabled_ = enable;
   1082   }
   1083   bool WasSendTelephoneEventCalled(int channel, int event_code, int length_ms) {
   1084     return (channels_[channel]->dtmf_info.dtmf_event_code == event_code &&
   1085             channels_[channel]->dtmf_info.dtmf_out_of_band == true &&
   1086             channels_[channel]->dtmf_info.dtmf_length_ms == length_ms);
   1087   }
   1088   bool WasPlayDtmfToneCalled(int event_code, int length_ms) {
   1089     return (dtmf_info_.dtmf_event_code == event_code &&
   1090             dtmf_info_.dtmf_length_ms == length_ms);
   1091   }
   1092   // webrtc::VoEExternalMedia
   1093   WEBRTC_FUNC(RegisterExternalMediaProcessing,
   1094               (int channel, webrtc::ProcessingTypes type,
   1095                webrtc::VoEMediaProcess& processObject)) {
   1096     WEBRTC_CHECK_CHANNEL(channel);
   1097     if (channels_[channel]->media_processor_registered) {
   1098       return -1;
   1099     }
   1100     channels_[channel]->media_processor_registered = true;
   1101     media_processor_ = &processObject;
   1102     return 0;
   1103   }
   1104   WEBRTC_FUNC(DeRegisterExternalMediaProcessing,
   1105               (int channel, webrtc::ProcessingTypes type)) {
   1106     WEBRTC_CHECK_CHANNEL(channel);
   1107     if (!channels_[channel]->media_processor_registered) {
   1108       return -1;
   1109     }
   1110     channels_[channel]->media_processor_registered = false;
   1111     media_processor_ = NULL;
   1112     return 0;
   1113   }
   1114   WEBRTC_STUB(SetExternalRecordingStatus, (bool enable));
   1115   WEBRTC_STUB(SetExternalPlayoutStatus, (bool enable));
   1116   WEBRTC_STUB(ExternalRecordingInsertData,
   1117               (const int16_t speechData10ms[], int lengthSamples,
   1118                int samplingFreqHz, int current_delay_ms));
   1119   WEBRTC_STUB(ExternalPlayoutGetData,
   1120               (int16_t speechData10ms[], int samplingFreqHz,
   1121                int current_delay_ms, int& lengthSamples));
   1122   WEBRTC_STUB(GetAudioFrame, (int channel, int desired_sample_rate_hz,
   1123                               webrtc::AudioFrame* frame));
   1124   WEBRTC_STUB(SetExternalMixing, (int channel, bool enable));
   1125 
   1126  private:
   1127   int GetNumDevices(int& num) {
   1128 #ifdef WIN32
   1129     num = 1;
   1130 #else
   1131     // On non-Windows platforms VE adds a special entry for the default device,
   1132     // so if there is one physical device then there are two entries in the
   1133     // list.
   1134     num = 2;
   1135 #endif
   1136     return 0;
   1137   }
   1138 
   1139   int GetDeviceName(int i, char* name, char* guid) {
   1140     const char *s;
   1141 #ifdef WIN32
   1142     if (0 == i) {
   1143       s = kFakeDeviceName;
   1144     } else {
   1145       return -1;
   1146     }
   1147 #else
   1148     // See comment above.
   1149     if (0 == i) {
   1150       s = kFakeDefaultDeviceName;
   1151     } else if (1 == i) {
   1152       s = kFakeDeviceName;
   1153     } else {
   1154       return -1;
   1155     }
   1156 #endif
   1157     strcpy(name, s);
   1158     guid[0] = '\0';
   1159     return 0;
   1160   }
   1161 
   1162   bool inited_;
   1163   int last_channel_;
   1164   std::map<int, Channel*> channels_;
   1165   bool fail_create_channel_;
   1166   const cricket::AudioCodec* const* codecs_;
   1167   int num_codecs_;
   1168   int num_set_send_codecs_;  // how many times we call SetSendCodec().
   1169   bool ec_enabled_;
   1170   bool ec_metrics_enabled_;
   1171   bool cng_enabled_;
   1172   bool ns_enabled_;
   1173   bool agc_enabled_;
   1174   bool highpass_filter_enabled_;
   1175   bool stereo_swapping_enabled_;
   1176   bool typing_detection_enabled_;
   1177   webrtc::EcModes ec_mode_;
   1178   webrtc::AecmModes aecm_mode_;
   1179   webrtc::NsModes ns_mode_;
   1180   webrtc::AgcModes agc_mode_;
   1181   webrtc::AgcConfig agc_config_;
   1182   webrtc::VoiceEngineObserver* observer_;
   1183   int playout_fail_channel_;
   1184   int send_fail_channel_;
   1185   bool fail_start_recording_microphone_;
   1186   bool recording_microphone_;
   1187   int recording_sample_rate_;
   1188   int playout_sample_rate_;
   1189   DtmfInfo dtmf_info_;
   1190   webrtc::VoEMediaProcess* media_processor_;
   1191 };
   1192 
   1193 #undef WEBRTC_CHECK_HEADER_EXTENSION_ID
   1194 
   1195 }  // namespace cricket
   1196 
   1197 #endif  // TALK_SESSION_PHONE_FAKEWEBRTCVOICEENGINE_H_
   1198