1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Use of this source code is governed by a BSD-style license 5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * that can be found in the LICENSE file in the root of the source 6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * tree. An additional intellectual property rights grant can be found 7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * in the file PATENTS. All contributing project authors may 8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1115a03fd972746f234e2dd9bb5540ae0b4ad6ee82turaj@webrtc.org#include "webrtc/voice_engine/voe_dtmf_impl.h" 12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1315a03fd972746f234e2dd9bb5540ae0b4ad6ee82turaj@webrtc.org#include "webrtc/system_wrappers/interface/critical_section_wrapper.h" 1415a03fd972746f234e2dd9bb5540ae0b4ad6ee82turaj@webrtc.org#include "webrtc/system_wrappers/interface/trace.h" 1515a03fd972746f234e2dd9bb5540ae0b4ad6ee82turaj@webrtc.org#include "webrtc/voice_engine/channel.h" 1615a03fd972746f234e2dd9bb5540ae0b4ad6ee82turaj@webrtc.org#include "webrtc/voice_engine/include/voe_errors.h" 1715a03fd972746f234e2dd9bb5540ae0b4ad6ee82turaj@webrtc.org#include "webrtc/voice_engine/output_mixer.h" 1815a03fd972746f234e2dd9bb5540ae0b4ad6ee82turaj@webrtc.org#include "webrtc/voice_engine/transmit_mixer.h" 1915a03fd972746f234e2dd9bb5540ae0b4ad6ee82turaj@webrtc.org#include "webrtc/voice_engine/voice_engine_impl.h" 20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace webrtc { 22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVoEDtmf* VoEDtmf::GetInterface(VoiceEngine* voiceEngine) 24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifndef WEBRTC_VOICE_ENGINE_DTMF_API 26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return NULL; 27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#else 28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (NULL == voiceEngine) 29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return NULL; 31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 32b9e5a3d589349ee55e41cb54eca4ec822018f5c5tommi@webrtc.org VoiceEngineImpl* s = static_cast<VoiceEngineImpl*>(voiceEngine); 33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org s->AddRef(); 34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return s; 35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif 36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef WEBRTC_VOICE_ENGINE_DTMF_API 39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVoEDtmfImpl::VoEDtmfImpl(voe::SharedData* shared) : 41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _dtmfFeedback(true), 42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _dtmfDirectFeedback(false), 43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared(shared) 44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1), 46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "VoEDtmfImpl::VoEDtmfImpl() - ctor"); 47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVoEDtmfImpl::~VoEDtmfImpl() 50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1), 52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "VoEDtmfImpl::~VoEDtmfImpl() - dtor"); 53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VoEDtmfImpl::SendTelephoneEvent(int channel, 56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int eventCode, 57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool outOfBand, 58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int lengthMs, 59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int attenuationDb) 60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), 62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "SendTelephoneEvent(channel=%d, eventCode=%d, outOfBand=%d," 63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "length=%d, attenuationDb=%d)", 64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org channel, eventCode, (int)outOfBand, lengthMs, attenuationDb); 65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!_shared->statistics().Initialized()) 66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_NOT_INITED, kTraceError); 68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 70b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); 71b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org voe::Channel* channelPtr = ch.channel(); 72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (channelPtr == NULL) 73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, 75b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "SendTelephoneEvent() failed to locate channel"); 76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!channelPtr->Sending()) 79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_NOT_SENDING, kTraceError, 81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "SendTelephoneEvent() sending is not active"); 82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Sanity check 86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const int maxEventCode = outOfBand ? 87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org static_cast<int>(kMaxTelephoneEventCode) : 88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org static_cast<int>(kMaxDtmfEventCode); 89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const bool testFailed = ((eventCode < 0) || 90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (eventCode > maxEventCode) || 91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (lengthMs < kMinTelephoneEventDuration) || 92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (lengthMs > kMaxTelephoneEventDuration) || 93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (attenuationDb < kMinTelephoneEventAttenuation) || 94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (attenuationDb > kMaxTelephoneEventAttenuation)); 95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (testFailed) 96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError, 98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "SendTelephoneEvent() invalid parameter(s)"); 99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const bool isDtmf = 103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (eventCode >= 0) && (eventCode <= kMaxDtmfEventCode); 104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const bool playDtmfToneDirect = 105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org isDtmf && (_dtmfFeedback && _dtmfDirectFeedback); 106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (playDtmfToneDirect) 108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Mute the microphone signal while playing back the tone directly. 110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // This is to reduce the risk of introducing echo from the added output. 111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->transmit_mixer()->UpdateMuteMicrophoneTime(lengthMs); 112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Play out local feedback tone directly (same approach for both inband 114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // and outband). 115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Reduce the length of the the tone with 80ms to reduce risk of echo. 116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // For non-direct feedback, outband and inband cases are handled 117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // differently. 118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->output_mixer()->PlayDtmfTone(eventCode, lengthMs - 80, 119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org attenuationDb); 120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (outOfBand) 123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // The RTP/RTCP module will always deliver OnPlayTelephoneEvent when 125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // an event is transmitted. It is up to the VoE to utilize it or not. 126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // This flag ensures that feedback/playout is enabled; however, the 127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // channel object must still parse out the Dtmf events (0-15) from 128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // all possible events (0-255). 129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const bool playDTFMEvent = (_dtmfFeedback && !_dtmfDirectFeedback); 130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return channelPtr->SendTelephoneEventOutband(eventCode, 132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org lengthMs, 133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org attenuationDb, 134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org playDTFMEvent); 135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else 137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // For Dtmf tones, we want to ensure that inband tones are played out 139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // in sync with the transmitted audio. This flag is utilized by the 140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // channel object to determine if the queued Dtmf e vent shall also 141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // be fed to the output mixer in the same step as input audio is 142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // replaced by inband Dtmf tones. 143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const bool playDTFMEvent = 144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (isDtmf && _dtmfFeedback && !_dtmfDirectFeedback); 145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return channelPtr->SendTelephoneEventInband(eventCode, 147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org lengthMs, 148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org attenuationDb, 149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org playDTFMEvent); 150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VoEDtmfImpl::SetSendTelephoneEventPayloadType(int channel, 154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org unsigned char type) 155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), 157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "SetSendTelephoneEventPayloadType(channel=%d, type=%u)", 158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org channel, type); 159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!_shared->statistics().Initialized()) 160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_NOT_INITED, kTraceError); 162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 164b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); 165b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org voe::Channel* channelPtr = ch.channel(); 166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (channelPtr == NULL) 167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, 169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "SetSendTelephoneEventPayloadType() failed to locate channel"); 170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return channelPtr->SetSendTelephoneEventPayloadType(type); 173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VoEDtmfImpl::GetSendTelephoneEventPayloadType(int channel, 176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org unsigned char& type) 177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), 179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "GetSendTelephoneEventPayloadType(channel=%d)", channel); 180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!_shared->statistics().Initialized()) 181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_NOT_INITED, kTraceError); 183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 185b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); 186b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org voe::Channel* channelPtr = ch.channel(); 187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (channelPtr == NULL) 188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, 190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "GetSendTelephoneEventPayloadType() failed to locate channel"); 191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return channelPtr->GetSendTelephoneEventPayloadType(type); 194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VoEDtmfImpl::PlayDtmfTone(int eventCode, 197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int lengthMs, 198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int attenuationDb) 199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), 201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "PlayDtmfTone(eventCode=%d, lengthMs=%d, attenuationDb=%d)", 202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org eventCode, lengthMs, attenuationDb); 203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!_shared->statistics().Initialized()) 205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 206b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_NOT_INITED, kTraceError); 207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!_shared->audio_device()->Playing()) 210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_NOT_PLAYING, kTraceError, 212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "PlayDtmfTone() no channel is playing out"); 213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((eventCode < kMinDtmfEventCode) || 216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (eventCode > kMaxDtmfEventCode) || 217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (lengthMs < kMinTelephoneEventDuration) || 218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (lengthMs > kMaxTelephoneEventDuration) || 219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (attenuationDb <kMinTelephoneEventAttenuation) || 220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (attenuationDb > kMaxTelephoneEventAttenuation)) 221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError, 223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "PlayDtmfTone() invalid tone parameter(s)"); 224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return _shared->output_mixer()->PlayDtmfTone(eventCode, lengthMs, 227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org attenuationDb); 228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VoEDtmfImpl::SetDtmfFeedbackStatus(bool enable, bool directFeedback) 231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), 233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "SetDtmfFeedbackStatus(enable=%d, directFeeback=%d)", 234b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (int)enable, (int)directFeedback); 235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped sc(_shared->crit_sec()); 237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _dtmfFeedback = enable; 239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _dtmfDirectFeedback = directFeedback; 240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VoEDtmfImpl::GetDtmfFeedbackStatus(bool& enabled, bool& directFeedback) 245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), 247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "GetDtmfFeedbackStatus()"); 248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped sc(_shared->crit_sec()); 250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org enabled = _dtmfFeedback; 252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org directFeedback = _dtmfDirectFeedback; 253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org VoEId(_shared->instance_id(), -1), 256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "GetDtmfFeedbackStatus() => enabled=%d, directFeedback=%d", 257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org enabled, directFeedback); 258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VoEDtmfImpl::SetDtmfPlayoutStatus(int channel, bool enable) 262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), 264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "SetDtmfPlayoutStatus(channel=%d, enable=%d)", 265b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org channel, enable); 266b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 267b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!_shared->statistics().Initialized()) 268b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 269b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_NOT_INITED, kTraceError); 270b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 271b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 272b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); 273b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org voe::Channel* channelPtr = ch.channel(); 274b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (channelPtr == NULL) 275b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 276b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, 277b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "SetDtmfPlayoutStatus() failed to locate channel"); 278b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 279b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 280b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return channelPtr->SetDtmfPlayoutStatus(enable); 281b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 282b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 283b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VoEDtmfImpl::GetDtmfPlayoutStatus(int channel, bool& enabled) 284b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 285b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), 286b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "GetDtmfPlayoutStatus(channel=%d, enabled=?)", channel); 287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!_shared->statistics().Initialized()) 288b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 289b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_NOT_INITED, kTraceError); 290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 291b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 292b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); 293b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org voe::Channel* channelPtr = ch.channel(); 294b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (channelPtr == NULL) 295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, 297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "GetDtmfPlayoutStatus() failed to locate channel"); 298b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 299b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org enabled = channelPtr->DtmfPlayoutStatus(); 301b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 302b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org VoEId(_shared->instance_id(), -1), 303b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "GetDtmfPlayoutStatus() => enabled=%d", enabled); 304b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 305b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 306b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 307b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif // #ifdef WEBRTC_VOICE_ENGINE_DTMF_API 308b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 309b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} // namespace webrtc 310