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