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