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