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