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 43 namespace cricket { 44 45 // Function returning stats will return these values 46 // for all values based on type. 47 const int kIntStatValue = 123; 48 const float kFractionLostStatValue = 0.5; 49 50 static const char kFakeDefaultDeviceName[] = "Fake Default"; 51 static const int kFakeDefaultDeviceId = -1; 52 static const char kFakeDeviceName[] = "Fake Device"; 53 #ifdef WIN32 54 static const int kFakeDeviceId = 0; 55 #else 56 static const int kFakeDeviceId = 1; 57 #endif 58 59 60 class 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