Revert of - Clean up unused voice engine DTMF code. (patchset #4 id:60001 of https://codereview.webrtc.org/1722253002/ )
Reason for revert: Breaks Chromium FYI bots for Android. E.g. https://build.chromium.org/p/chromium.webrtc.fyi/builders/Android%20Tests%20%28dbg%29%20%28K%20Nexus5%29/builds/4486/steps/content_browsertests/logs/stdio Original issue's description: > - Clean up unused voice engine DTMF code following removal of VoEDtmf APIs. > - Use better types in AudioSendStream::SendTelephoneEvent() and related methods. > > BUG=webrtc:4690 > > Committed: https://crrev.com/8886c816582a7c6190c5429222cb8096fca302a6 > Cr-Commit-Position: refs/heads/master@{#11927} TBR=tina.legrand@webrtc.org,henrik.lundin@webrtc.org # Skipping CQ checks because original CL landed less than 1 days ago. NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=webrtc:4690 Review URL: https://codereview.webrtc.org/1776243003 Cr-Commit-Position: refs/heads/master@{#11930}
This commit is contained in:
parent
57ae82929a
commit
3ecb5c8698
@ -125,8 +125,8 @@ bool AudioSendStream::DeliverRtcp(const uint8_t* packet, size_t length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AudioSendStream::SendTelephoneEvent(int payload_type, int event,
|
||||
int duration_ms) {
|
||||
bool AudioSendStream::SendTelephoneEvent(int payload_type, uint8_t event,
|
||||
uint32_t duration_ms) {
|
||||
RTC_DCHECK(thread_checker_.CalledOnValidThread());
|
||||
return channel_proxy_->SetSendTelephoneEventPayloadType(payload_type) &&
|
||||
channel_proxy_->SendTelephoneEventOutband(event, duration_ms);
|
||||
|
||||
@ -40,8 +40,8 @@ class AudioSendStream final : public webrtc::AudioSendStream {
|
||||
bool DeliverRtcp(const uint8_t* packet, size_t length) override;
|
||||
|
||||
// webrtc::AudioSendStream implementation.
|
||||
bool SendTelephoneEvent(int payload_type, int event,
|
||||
int duration_ms) override;
|
||||
bool SendTelephoneEvent(int payload_type, uint8_t event,
|
||||
uint32_t duration_ms) override;
|
||||
webrtc::AudioSendStream::Stats GetStats() const override;
|
||||
|
||||
const webrtc::AudioSendStream::Config& config() const;
|
||||
|
||||
@ -46,8 +46,8 @@ const CallStatistics kCallStats = {
|
||||
const CodecInst kCodecInst = {-121, "codec_name_send", 48000, -231, 0, -671};
|
||||
const ReportBlock kReportBlock = {456, 780, 123, 567, 890, 132, 143, 13354};
|
||||
const int kTelephoneEventPayloadType = 123;
|
||||
const int kTelephoneEventCode = 45;
|
||||
const int kTelephoneEventDuration = 6789;
|
||||
const uint8_t kTelephoneEventCode = 45;
|
||||
const uint32_t kTelephoneEventDuration = 6789;
|
||||
|
||||
struct ConfigHelper {
|
||||
ConfigHelper()
|
||||
|
||||
@ -90,8 +90,8 @@ class AudioSendStream : public SendStream {
|
||||
};
|
||||
|
||||
// TODO(solenberg): Make payload_type a config property instead.
|
||||
virtual bool SendTelephoneEvent(int payload_type, int event,
|
||||
int duration_ms) = 0;
|
||||
virtual bool SendTelephoneEvent(int payload_type, uint8_t event,
|
||||
uint32_t duration_ms) = 0;
|
||||
virtual Stats GetStats() const = 0;
|
||||
};
|
||||
} // namespace webrtc
|
||||
|
||||
@ -39,8 +39,8 @@ FakeAudioSendStream::TelephoneEvent
|
||||
return latest_telephone_event_;
|
||||
}
|
||||
|
||||
bool FakeAudioSendStream::SendTelephoneEvent(int payload_type, int event,
|
||||
int duration_ms) {
|
||||
bool FakeAudioSendStream::SendTelephoneEvent(int payload_type, uint8_t event,
|
||||
uint32_t duration_ms) {
|
||||
latest_telephone_event_.payload_type = payload_type;
|
||||
latest_telephone_event_.event_code = event;
|
||||
latest_telephone_event_.duration_ms = duration_ms;
|
||||
|
||||
@ -35,8 +35,8 @@ class FakeAudioSendStream final : public webrtc::AudioSendStream {
|
||||
public:
|
||||
struct TelephoneEvent {
|
||||
int payload_type = -1;
|
||||
int event_code = 0;
|
||||
int duration_ms = 0;
|
||||
uint8_t event_code = 0;
|
||||
uint32_t duration_ms = 0;
|
||||
};
|
||||
|
||||
explicit FakeAudioSendStream(const webrtc::AudioSendStream::Config& config);
|
||||
@ -56,8 +56,8 @@ class FakeAudioSendStream final : public webrtc::AudioSendStream {
|
||||
}
|
||||
|
||||
// webrtc::AudioSendStream implementation.
|
||||
bool SendTelephoneEvent(int payload_type, int event,
|
||||
int duration_ms) override;
|
||||
bool SendTelephoneEvent(int payload_type, uint8_t event,
|
||||
uint32_t duration_ms) override;
|
||||
webrtc::AudioSendStream::Stats GetStats() const override;
|
||||
|
||||
TelephoneEvent latest_telephone_event_;
|
||||
|
||||
@ -1178,7 +1178,8 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream
|
||||
RTC_CHECK(stream_);
|
||||
}
|
||||
|
||||
bool SendTelephoneEvent(int payload_type, int event, int duration_ms) {
|
||||
bool SendTelephoneEvent(int payload_type, uint8_t event,
|
||||
uint32_t duration_ms) {
|
||||
RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
|
||||
RTC_DCHECK(stream_);
|
||||
return stream_->SendTelephoneEvent(payload_type, event, duration_ms);
|
||||
|
||||
@ -50,6 +50,14 @@ TwoWayCommunication::~TwoWayCommunication() {
|
||||
delete _channel_B2A;
|
||||
delete _channelRef_A2B;
|
||||
delete _channelRef_B2A;
|
||||
#ifdef WEBRTC_DTMF_DETECTION
|
||||
if (_dtmfDetectorA != NULL) {
|
||||
delete _dtmfDetectorA;
|
||||
}
|
||||
if (_dtmfDetectorB != NULL) {
|
||||
delete _dtmfDetectorB;
|
||||
}
|
||||
#endif
|
||||
_inFileA.Close();
|
||||
_inFileB.Close();
|
||||
_outFileA.Close();
|
||||
|
||||
@ -322,7 +322,7 @@ TEST_F(RtpRtcpAudioTest, DTMF) {
|
||||
(voice_codec.rate < 0) ? 0 : voice_codec.rate));
|
||||
|
||||
// Start DTMF test.
|
||||
int timeStamp = 160;
|
||||
uint32_t timeStamp = 160;
|
||||
|
||||
// Send a DTMF tone using RFC 2833 (4733).
|
||||
for (int i = 0; i < 16; i++) {
|
||||
|
||||
@ -43,7 +43,8 @@ class MockVoEChannelProxy : public voe::ChannelProxy {
|
||||
MOCK_CONST_METHOD0(GetSpeechOutputLevelFullRange, int32_t());
|
||||
MOCK_CONST_METHOD0(GetDelayEstimate, uint32_t());
|
||||
MOCK_METHOD1(SetSendTelephoneEventPayloadType, bool(int payload_type));
|
||||
MOCK_METHOD2(SendTelephoneEventOutband, bool(int event, int duration_ms));
|
||||
MOCK_METHOD2(SendTelephoneEventOutband, bool(uint8_t event,
|
||||
uint32_t duration_ms));
|
||||
};
|
||||
} // namespace test
|
||||
} // namespace webrtc
|
||||
|
||||
@ -18,6 +18,8 @@ source_set("voice_engine") {
|
||||
"channel_proxy.h",
|
||||
"dtmf_inband.cc",
|
||||
"dtmf_inband.h",
|
||||
"dtmf_inband_queue.cc",
|
||||
"dtmf_inband_queue.h",
|
||||
"include/voe_audio_processing.h",
|
||||
"include/voe_base.h",
|
||||
"include/voe_codec.h",
|
||||
|
||||
@ -40,11 +40,13 @@
|
||||
#include "webrtc/voice_engine/transmit_mixer.h"
|
||||
#include "webrtc/voice_engine/utility.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <Qos.h>
|
||||
#endif
|
||||
|
||||
namespace webrtc {
|
||||
namespace voe {
|
||||
|
||||
const int kTelephoneEventAttenuationdB = 10;
|
||||
|
||||
class TransportFeedbackProxy : public TransportFeedbackObserver {
|
||||
public:
|
||||
TransportFeedbackProxy() : feedback_observer_(nullptr) {
|
||||
@ -361,7 +363,7 @@ void Channel::OnPlayTelephoneEvent(uint8_t event,
|
||||
" volume=%u)",
|
||||
event, lengthMs, volume);
|
||||
|
||||
if (event > 15) {
|
||||
if (!_playOutbandDtmfEvent || (event > 15)) {
|
||||
// Ignore callback since feedback is disabled or event is not a
|
||||
// Dtmf tone event.
|
||||
return;
|
||||
@ -759,11 +761,14 @@ Channel::Channel(int32_t channelId,
|
||||
_outputFilePlayerId(VoEModuleId(instanceId, channelId) + 1025),
|
||||
_outputFileRecorderId(VoEModuleId(instanceId, channelId) + 1026),
|
||||
_outputFileRecording(false),
|
||||
_inbandDtmfQueue(VoEModuleId(instanceId, channelId)),
|
||||
_inbandDtmfGenerator(VoEModuleId(instanceId, channelId)),
|
||||
_outputExternalMedia(false),
|
||||
_inputExternalMediaCallbackPtr(NULL),
|
||||
_outputExternalMediaCallbackPtr(NULL),
|
||||
_timeStamp(0), // This is just an offset, RTP module will add it's own
|
||||
// random offset
|
||||
_sendTelephoneEventPayloadType(106),
|
||||
ntp_estimator_(Clock::GetRealTimeClock()),
|
||||
jitter_buffer_playout_timestamp_(0),
|
||||
playout_timestamp_rtp_(0),
|
||||
@ -791,6 +796,8 @@ Channel::Channel(int32_t channelId,
|
||||
_panLeft(1.0f),
|
||||
_panRight(1.0f),
|
||||
_outputGain(1.0f),
|
||||
_playOutbandDtmfEvent(false),
|
||||
_playInbandDtmfEvent(false),
|
||||
_lastLocalTimeStamp(0),
|
||||
_lastPayloadType(0),
|
||||
_includeAudioLevelIndication(false),
|
||||
@ -823,6 +830,8 @@ Channel::Channel(int32_t channelId,
|
||||
config.Get<NetEqFastAccelerate>().enabled;
|
||||
audio_coding_.reset(AudioCodingModule::Create(acm_config));
|
||||
|
||||
_inbandDtmfQueue.ResetDtmf();
|
||||
_inbandDtmfGenerator.Init();
|
||||
_outputAudioLevel.Clear();
|
||||
|
||||
RtpRtcp::Configuration configuration;
|
||||
@ -2203,18 +2212,21 @@ int Channel::GetChannelOutputVolumeScaling(float& scaling) const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Channel::SendTelephoneEventOutband(int event, int duration_ms) {
|
||||
int Channel::SendTelephoneEventOutband(unsigned char eventCode,
|
||||
int lengthMs,
|
||||
int attenuationDb,
|
||||
bool playDtmfEvent) {
|
||||
WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
|
||||
"Channel::SendTelephoneEventOutband(...)");
|
||||
RTC_DCHECK_LE(0, event);
|
||||
RTC_DCHECK_GE(255, event);
|
||||
RTC_DCHECK_LE(0, duration_ms);
|
||||
RTC_DCHECK_GE(65535, duration_ms);
|
||||
"Channel::SendTelephoneEventOutband(..., playDtmfEvent=%d)",
|
||||
playDtmfEvent);
|
||||
if (!Sending()) {
|
||||
return -1;
|
||||
}
|
||||
if (_rtpRtcpModule->SendTelephoneEventOutband(
|
||||
event, duration_ms, kTelephoneEventAttenuationdB) != 0) {
|
||||
|
||||
_playOutbandDtmfEvent = playDtmfEvent;
|
||||
|
||||
if (_rtpRtcpModule->SendTelephoneEventOutband(eventCode, lengthMs,
|
||||
attenuationDb) != 0) {
|
||||
_engineStatisticsPtr->SetLastError(
|
||||
VE_SEND_DTMF_FAILED, kTraceWarning,
|
||||
"SendTelephoneEventOutband() failed to send event");
|
||||
@ -2223,14 +2235,32 @@ int Channel::SendTelephoneEventOutband(int event, int duration_ms) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Channel::SetSendTelephoneEventPayloadType(int payload_type) {
|
||||
int Channel::SendTelephoneEventInband(unsigned char eventCode,
|
||||
int lengthMs,
|
||||
int attenuationDb,
|
||||
bool playDtmfEvent) {
|
||||
WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
|
||||
"Channel::SendTelephoneEventInband(..., playDtmfEvent=%d)",
|
||||
playDtmfEvent);
|
||||
|
||||
_playInbandDtmfEvent = playDtmfEvent;
|
||||
_inbandDtmfQueue.AddDtmf(eventCode, lengthMs, attenuationDb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Channel::SetSendTelephoneEventPayloadType(unsigned char type) {
|
||||
WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
|
||||
"Channel::SetSendTelephoneEventPayloadType()");
|
||||
RTC_DCHECK_LE(0, payload_type);
|
||||
RTC_DCHECK_GE(127, payload_type);
|
||||
CodecInst codec = {0};
|
||||
if (type > 127) {
|
||||
_engineStatisticsPtr->SetLastError(
|
||||
VE_INVALID_ARGUMENT, kTraceError,
|
||||
"SetSendTelephoneEventPayloadType() invalid type");
|
||||
return -1;
|
||||
}
|
||||
CodecInst codec = {};
|
||||
codec.plfreq = 8000;
|
||||
codec.pltype = payload_type;
|
||||
codec.pltype = type;
|
||||
memcpy(codec.plname, "telephone-event", 16);
|
||||
if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) {
|
||||
_rtpRtcpModule->DeRegisterSendPayload(codec.pltype);
|
||||
@ -2242,6 +2272,12 @@ int Channel::SetSendTelephoneEventPayloadType(int payload_type) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
_sendTelephoneEventPayloadType = type;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Channel::GetSendTelephoneEventPayloadType(unsigned char& type) {
|
||||
type = _sendTelephoneEventPayloadType;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2991,6 +3027,8 @@ uint32_t Channel::PrepareEncodeAndSend(int mixingFrequency) {
|
||||
}
|
||||
}
|
||||
|
||||
InsertInbandDtmfTone();
|
||||
|
||||
if (_includeAudioLevelIndication) {
|
||||
size_t length =
|
||||
_audioFrame.samples_per_channel_ * _audioFrame.num_channels_;
|
||||
@ -3310,6 +3348,64 @@ int32_t Channel::MixAudioWithFile(AudioFrame& audioFrame, int mixingFrequency) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Channel::InsertInbandDtmfTone() {
|
||||
// Check if we should start a new tone.
|
||||
if (_inbandDtmfQueue.PendingDtmf() && !_inbandDtmfGenerator.IsAddingTone() &&
|
||||
_inbandDtmfGenerator.DelaySinceLastTone() >
|
||||
kMinTelephoneEventSeparationMs) {
|
||||
int8_t eventCode(0);
|
||||
uint16_t lengthMs(0);
|
||||
uint8_t attenuationDb(0);
|
||||
|
||||
eventCode = _inbandDtmfQueue.NextDtmf(&lengthMs, &attenuationDb);
|
||||
_inbandDtmfGenerator.AddTone(eventCode, lengthMs, attenuationDb);
|
||||
if (_playInbandDtmfEvent) {
|
||||
// Add tone to output mixer using a reduced length to minimize
|
||||
// risk of echo.
|
||||
_outputMixerPtr->PlayDtmfTone(eventCode, lengthMs - 80, attenuationDb);
|
||||
}
|
||||
}
|
||||
|
||||
if (_inbandDtmfGenerator.IsAddingTone()) {
|
||||
uint16_t frequency(0);
|
||||
_inbandDtmfGenerator.GetSampleRate(frequency);
|
||||
|
||||
if (frequency != _audioFrame.sample_rate_hz_) {
|
||||
// Update sample rate of Dtmf tone since the mixing frequency
|
||||
// has changed.
|
||||
_inbandDtmfGenerator.SetSampleRate(
|
||||
(uint16_t)(_audioFrame.sample_rate_hz_));
|
||||
// Reset the tone to be added taking the new sample rate into
|
||||
// account.
|
||||
_inbandDtmfGenerator.ResetTone();
|
||||
}
|
||||
|
||||
int16_t toneBuffer[320];
|
||||
uint16_t toneSamples(0);
|
||||
// Get 10ms tone segment and set time since last tone to zero
|
||||
if (_inbandDtmfGenerator.Get10msTone(toneBuffer, toneSamples) == -1) {
|
||||
WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId),
|
||||
"Channel::EncodeAndSend() inserting Dtmf failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Replace mixed audio with DTMF tone.
|
||||
for (size_t sample = 0; sample < _audioFrame.samples_per_channel_;
|
||||
sample++) {
|
||||
for (size_t channel = 0; channel < _audioFrame.num_channels_; channel++) {
|
||||
const size_t index = sample * _audioFrame.num_channels_ + channel;
|
||||
_audioFrame.data_[index] = toneBuffer[sample];
|
||||
}
|
||||
}
|
||||
|
||||
assert(_audioFrame.samples_per_channel_ == toneSamples);
|
||||
} else {
|
||||
// Add 10ms to "delay-since-last-tone" counter
|
||||
_inbandDtmfGenerator.UpdateDelaySinceLastTone();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Channel::UpdatePlayoutTimestamp(bool rtcp) {
|
||||
uint32_t playout_timestamp = 0;
|
||||
|
||||
|
||||
@ -25,6 +25,8 @@
|
||||
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
|
||||
#include "webrtc/modules/utility/include/file_player.h"
|
||||
#include "webrtc/modules/utility/include/file_recorder.h"
|
||||
#include "webrtc/voice_engine/dtmf_inband.h"
|
||||
#include "webrtc/voice_engine/dtmf_inband_queue.h"
|
||||
#include "webrtc/voice_engine/include/voe_audio_processing.h"
|
||||
#include "webrtc/voice_engine/include/voe_network.h"
|
||||
#include "webrtc/voice_engine/level_indicator.h"
|
||||
@ -294,9 +296,17 @@ class Channel
|
||||
// VoEVideoSyncExtended
|
||||
int GetRtpRtcp(RtpRtcp** rtpRtcpModule, RtpReceiver** rtp_receiver) const;
|
||||
|
||||
// DTMF
|
||||
int SendTelephoneEventOutband(int event, int duration_ms);
|
||||
int SetSendTelephoneEventPayloadType(int payload_type);
|
||||
// VoEDtmf
|
||||
int SendTelephoneEventOutband(unsigned char eventCode,
|
||||
int lengthMs,
|
||||
int attenuationDb,
|
||||
bool playDtmfEvent);
|
||||
int SendTelephoneEventInband(unsigned char eventCode,
|
||||
int lengthMs,
|
||||
int attenuationDb,
|
||||
bool playDtmfEvent);
|
||||
int SetSendTelephoneEventPayloadType(unsigned char type);
|
||||
int GetSendTelephoneEventPayloadType(unsigned char& type);
|
||||
|
||||
// VoEAudioProcessingImpl
|
||||
int UpdateRxVadDetection(AudioFrame& audioFrame);
|
||||
@ -454,6 +464,7 @@ class Channel
|
||||
bool IsPacketInOrder(const RTPHeader& header) const;
|
||||
bool IsPacketRetransmitted(const RTPHeader& header, bool in_order) const;
|
||||
int ResendPackets(const uint16_t* sequence_numbers, int length);
|
||||
int InsertInbandDtmfTone();
|
||||
int32_t MixOrReplaceAudioWithFile(int mixingFrequency);
|
||||
int32_t MixAudioWithFile(AudioFrame& audioFrame, int mixingFrequency);
|
||||
void UpdatePlayoutTimestamp(bool rtcp);
|
||||
@ -499,10 +510,13 @@ class Channel
|
||||
int _outputFilePlayerId;
|
||||
int _outputFileRecorderId;
|
||||
bool _outputFileRecording;
|
||||
DtmfInbandQueue _inbandDtmfQueue;
|
||||
DtmfInband _inbandDtmfGenerator;
|
||||
bool _outputExternalMedia;
|
||||
VoEMediaProcess* _inputExternalMediaCallbackPtr;
|
||||
VoEMediaProcess* _outputExternalMediaCallbackPtr;
|
||||
uint32_t _timeStamp;
|
||||
uint8_t _sendTelephoneEventPayloadType;
|
||||
|
||||
RemoteNtpTimeEstimator ntp_estimator_ GUARDED_BY(ts_stats_lock_);
|
||||
|
||||
@ -546,6 +560,9 @@ class Channel
|
||||
float _panLeft;
|
||||
float _panRight;
|
||||
float _outputGain;
|
||||
// VoEDtmf
|
||||
bool _playOutbandDtmfEvent;
|
||||
bool _playInbandDtmfEvent;
|
||||
// VoeRTP_RTCP
|
||||
uint32_t _lastLocalTimeStamp;
|
||||
int8_t _lastPayloadType;
|
||||
|
||||
@ -148,9 +148,11 @@ bool ChannelProxy::SetSendTelephoneEventPayloadType(int payload_type) {
|
||||
return channel()->SetSendTelephoneEventPayloadType(payload_type) == 0;
|
||||
}
|
||||
|
||||
bool ChannelProxy::SendTelephoneEventOutband(int event, int duration_ms) {
|
||||
bool ChannelProxy::SendTelephoneEventOutband(uint8_t event,
|
||||
uint32_t duration_ms) {
|
||||
RTC_DCHECK(thread_checker_.CalledOnValidThread());
|
||||
return channel()->SendTelephoneEventOutband(event, duration_ms) == 0;
|
||||
return
|
||||
channel()->SendTelephoneEventOutband(event, duration_ms, 10, false) == 0;
|
||||
}
|
||||
|
||||
void ChannelProxy::SetSink(std::unique_ptr<AudioSinkInterface> sink) {
|
||||
|
||||
@ -68,7 +68,7 @@ class ChannelProxy {
|
||||
virtual uint32_t GetDelayEstimate() const;
|
||||
|
||||
virtual bool SetSendTelephoneEventPayloadType(int payload_type);
|
||||
virtual bool SendTelephoneEventOutband(int event, int duration_ms);
|
||||
virtual bool SendTelephoneEventOutband(uint8_t event, uint32_t duration_ms);
|
||||
|
||||
virtual void SetSink(std::unique_ptr<AudioSinkInterface> sink);
|
||||
|
||||
|
||||
@ -17,9 +17,6 @@
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// TODO(solenberg): Used as a DTMF tone generator in voe::OutputMixer. Pull out
|
||||
// the one in NetEq and use that instead? We don't need several
|
||||
// implemenations of this.
|
||||
class DtmfInband
|
||||
{
|
||||
public:
|
||||
|
||||
86
webrtc/voice_engine/dtmf_inband_queue.cc
Normal file
86
webrtc/voice_engine/dtmf_inband_queue.cc
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "webrtc/system_wrappers/include/trace.h"
|
||||
#include "webrtc/voice_engine/dtmf_inband_queue.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
DtmfInbandQueue::DtmfInbandQueue(int32_t id):
|
||||
_id(id),
|
||||
_nextEmptyIndex(0)
|
||||
{
|
||||
memset(_DtmfKey,0, sizeof(_DtmfKey));
|
||||
memset(_DtmfLen,0, sizeof(_DtmfLen));
|
||||
memset(_DtmfLevel,0, sizeof(_DtmfLevel));
|
||||
}
|
||||
|
||||
DtmfInbandQueue::~DtmfInbandQueue()
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
DtmfInbandQueue::AddDtmf(uint8_t key, uint16_t len, uint8_t level)
|
||||
{
|
||||
rtc::CritScope lock(&_DtmfCritsect);
|
||||
|
||||
if (_nextEmptyIndex >= kDtmfInbandMax)
|
||||
{
|
||||
WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_id,-1),
|
||||
"DtmfInbandQueue::AddDtmf() unable to add Dtmf tone");
|
||||
return -1;
|
||||
}
|
||||
int32_t index = _nextEmptyIndex;
|
||||
_DtmfKey[index] = key;
|
||||
_DtmfLen[index] = len;
|
||||
_DtmfLevel[index] = level;
|
||||
_nextEmptyIndex++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t
|
||||
DtmfInbandQueue::NextDtmf(uint16_t* len, uint8_t* level)
|
||||
{
|
||||
rtc::CritScope lock(&_DtmfCritsect);
|
||||
|
||||
if(!PendingDtmf())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
int8_t nextDtmf = _DtmfKey[0];
|
||||
*len=_DtmfLen[0];
|
||||
*level=_DtmfLevel[0];
|
||||
|
||||
memmove(&(_DtmfKey[0]), &(_DtmfKey[1]),
|
||||
_nextEmptyIndex*sizeof(uint8_t));
|
||||
memmove(&(_DtmfLen[0]), &(_DtmfLen[1]),
|
||||
_nextEmptyIndex*sizeof(uint16_t));
|
||||
memmove(&(_DtmfLevel[0]), &(_DtmfLevel[1]),
|
||||
_nextEmptyIndex*sizeof(uint8_t));
|
||||
|
||||
_nextEmptyIndex--;
|
||||
return nextDtmf;
|
||||
}
|
||||
|
||||
bool
|
||||
DtmfInbandQueue::PendingDtmf()
|
||||
{
|
||||
rtc::CritScope lock(&_DtmfCritsect);
|
||||
return _nextEmptyIndex > 0;
|
||||
}
|
||||
|
||||
void
|
||||
DtmfInbandQueue::ResetDtmf()
|
||||
{
|
||||
rtc::CritScope lock(&_DtmfCritsect);
|
||||
_nextEmptyIndex = 0;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
50
webrtc/voice_engine/dtmf_inband_queue.h
Normal file
50
webrtc/voice_engine/dtmf_inband_queue.h
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_VOICE_ENGINE_DTMF_INBAND_QUEUE_H
|
||||
#define WEBRTC_VOICE_ENGINE_DTMF_INBAND_QUEUE_H
|
||||
|
||||
#include "webrtc/base/criticalsection.h"
|
||||
#include "webrtc/typedefs.h"
|
||||
#include "webrtc/voice_engine/voice_engine_defines.h"
|
||||
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class DtmfInbandQueue
|
||||
{
|
||||
public:
|
||||
|
||||
DtmfInbandQueue(int32_t id);
|
||||
|
||||
virtual ~DtmfInbandQueue();
|
||||
|
||||
int AddDtmf(uint8_t DtmfKey, uint16_t len, uint8_t level);
|
||||
|
||||
int8_t NextDtmf(uint16_t* len, uint8_t* level);
|
||||
|
||||
bool PendingDtmf();
|
||||
|
||||
void ResetDtmf();
|
||||
|
||||
private:
|
||||
enum {kDtmfInbandMax = 20};
|
||||
|
||||
int32_t _id;
|
||||
rtc::CriticalSection _DtmfCritsect;
|
||||
uint8_t _nextEmptyIndex;
|
||||
uint8_t _DtmfKey[kDtmfInbandMax];
|
||||
uint16_t _DtmfLen[kDtmfInbandMax];
|
||||
uint8_t _DtmfLevel[kDtmfInbandMax];
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // WEBRTC_VOICE_ENGINE_DTMF_INBAND_QUEUE_H
|
||||
@ -205,6 +205,7 @@ TransmitMixer::TransmitMixer(uint32_t instanceId) :
|
||||
external_postproc_ptr_(NULL),
|
||||
external_preproc_ptr_(NULL),
|
||||
_mute(false),
|
||||
_remainingMuteMicTimeMs(0),
|
||||
stereo_codec_(false),
|
||||
swap_stereo_channels_(false)
|
||||
{
|
||||
@ -358,6 +359,17 @@ TransmitMixer::PrepareDemux(const void* audioSamples,
|
||||
TypingDetection(keyPressed);
|
||||
#endif
|
||||
|
||||
// --- Mute during DTMF tone if direct feedback is enabled
|
||||
if (_remainingMuteMicTimeMs > 0)
|
||||
{
|
||||
AudioFrameOperations::Mute(_audioFrame);
|
||||
_remainingMuteMicTimeMs -= 10;
|
||||
if (_remainingMuteMicTimeMs < 0)
|
||||
{
|
||||
_remainingMuteMicTimeMs = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// --- Mute signal
|
||||
if (_mute)
|
||||
{
|
||||
@ -465,6 +477,15 @@ uint32_t TransmitMixer::CaptureLevel() const
|
||||
return _captureLevel;
|
||||
}
|
||||
|
||||
void
|
||||
TransmitMixer::UpdateMuteMicrophoneTime(uint32_t lengthMs)
|
||||
{
|
||||
WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
|
||||
"TransmitMixer::UpdateMuteMicrophoneTime(lengthMs=%d)",
|
||||
lengthMs);
|
||||
_remainingMuteMicTimeMs = lengthMs;
|
||||
}
|
||||
|
||||
int32_t
|
||||
TransmitMixer::StopSend()
|
||||
{
|
||||
|
||||
@ -75,6 +75,9 @@ public:
|
||||
|
||||
int32_t StopSend();
|
||||
|
||||
// VoEDtmf
|
||||
void UpdateMuteMicrophoneTime(uint32_t lengthMs);
|
||||
|
||||
// VoEExternalMedia
|
||||
int RegisterExternalMediaProcessing(VoEMediaProcess* object,
|
||||
ProcessingTypes type);
|
||||
@ -223,6 +226,7 @@ private:
|
||||
VoEMediaProcess* external_postproc_ptr_;
|
||||
VoEMediaProcess* external_preproc_ptr_;
|
||||
bool _mute;
|
||||
int32_t _remainingMuteMicTimeMs;
|
||||
bool stereo_codec_;
|
||||
bool swap_stereo_channels_;
|
||||
};
|
||||
|
||||
@ -54,6 +54,8 @@
|
||||
'channel_proxy.h',
|
||||
'dtmf_inband.cc',
|
||||
'dtmf_inband.h',
|
||||
'dtmf_inband_queue.cc',
|
||||
'dtmf_inband_queue.h',
|
||||
'level_indicator.cc',
|
||||
'level_indicator.h',
|
||||
'monitor_module.cc',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user