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