| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 33 #include "webrtc/modules/utility/include/process_thread.h" | 33 #include "webrtc/modules/utility/include/process_thread.h" |
| 34 #include "webrtc/system_wrappers/include/trace.h" | 34 #include "webrtc/system_wrappers/include/trace.h" |
| 35 #include "webrtc/voice_engine/include/voe_base.h" | 35 #include "webrtc/voice_engine/include/voe_base.h" |
| 36 #include "webrtc/voice_engine/include/voe_external_media.h" | 36 #include "webrtc/voice_engine/include/voe_external_media.h" |
| 37 #include "webrtc/voice_engine/include/voe_rtp_rtcp.h" | 37 #include "webrtc/voice_engine/include/voe_rtp_rtcp.h" |
| 38 #include "webrtc/voice_engine/output_mixer.h" | 38 #include "webrtc/voice_engine/output_mixer.h" |
| 39 #include "webrtc/voice_engine/statistics.h" | 39 #include "webrtc/voice_engine/statistics.h" |
| 40 #include "webrtc/voice_engine/transmit_mixer.h" | 40 #include "webrtc/voice_engine/transmit_mixer.h" |
| 41 #include "webrtc/voice_engine/utility.h" | 41 #include "webrtc/voice_engine/utility.h" |
| 42 | 42 |
| 43 #if defined(_WIN32) |
| 44 #include <Qos.h> |
| 45 #endif |
| 46 |
| 43 namespace webrtc { | 47 namespace webrtc { |
| 44 namespace voe { | 48 namespace voe { |
| 45 | 49 |
| 46 const int kTelephoneEventAttenuationdB = 10; | |
| 47 | |
| 48 class TransportFeedbackProxy : public TransportFeedbackObserver { | 50 class TransportFeedbackProxy : public TransportFeedbackObserver { |
| 49 public: | 51 public: |
| 50 TransportFeedbackProxy() : feedback_observer_(nullptr) { | 52 TransportFeedbackProxy() : feedback_observer_(nullptr) { |
| 51 pacer_thread_.DetachFromThread(); | 53 pacer_thread_.DetachFromThread(); |
| 52 network_thread_.DetachFromThread(); | 54 network_thread_.DetachFromThread(); |
| 53 } | 55 } |
| 54 | 56 |
| 55 void SetTransportFeedbackObserver( | 57 void SetTransportFeedbackObserver( |
| 56 TransportFeedbackObserver* feedback_observer) { | 58 TransportFeedbackObserver* feedback_observer) { |
| 57 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 59 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 354 } | 356 } |
| 355 | 357 |
| 356 void Channel::OnPlayTelephoneEvent(uint8_t event, | 358 void Channel::OnPlayTelephoneEvent(uint8_t event, |
| 357 uint16_t lengthMs, | 359 uint16_t lengthMs, |
| 358 uint8_t volume) { | 360 uint8_t volume) { |
| 359 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId), | 361 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId), |
| 360 "Channel::OnPlayTelephoneEvent(event=%u, lengthMs=%u," | 362 "Channel::OnPlayTelephoneEvent(event=%u, lengthMs=%u," |
| 361 " volume=%u)", | 363 " volume=%u)", |
| 362 event, lengthMs, volume); | 364 event, lengthMs, volume); |
| 363 | 365 |
| 364 if (event > 15) { | 366 if (!_playOutbandDtmfEvent || (event > 15)) { |
| 365 // Ignore callback since feedback is disabled or event is not a | 367 // Ignore callback since feedback is disabled or event is not a |
| 366 // Dtmf tone event. | 368 // Dtmf tone event. |
| 367 return; | 369 return; |
| 368 } | 370 } |
| 369 | 371 |
| 370 assert(_outputMixerPtr != NULL); | 372 assert(_outputMixerPtr != NULL); |
| 371 | 373 |
| 372 // Start playing out the Dtmf tone (if playout is enabled). | 374 // Start playing out the Dtmf tone (if playout is enabled). |
| 373 // Reduce length of tone with 80ms to the reduce risk of echo. | 375 // Reduce length of tone with 80ms to the reduce risk of echo. |
| 374 _outputMixerPtr->PlayDtmfTone(event, lengthMs - 80, volume); | 376 _outputMixerPtr->PlayDtmfTone(event, lengthMs - 80, volume); |
| (...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 752 _externalTransport(false), | 754 _externalTransport(false), |
| 753 _inputFilePlayerPtr(NULL), | 755 _inputFilePlayerPtr(NULL), |
| 754 _outputFilePlayerPtr(NULL), | 756 _outputFilePlayerPtr(NULL), |
| 755 _outputFileRecorderPtr(NULL), | 757 _outputFileRecorderPtr(NULL), |
| 756 // Avoid conflict with other channels by adding 1024 - 1026, | 758 // Avoid conflict with other channels by adding 1024 - 1026, |
| 757 // won't use as much as 1024 channels. | 759 // won't use as much as 1024 channels. |
| 758 _inputFilePlayerId(VoEModuleId(instanceId, channelId) + 1024), | 760 _inputFilePlayerId(VoEModuleId(instanceId, channelId) + 1024), |
| 759 _outputFilePlayerId(VoEModuleId(instanceId, channelId) + 1025), | 761 _outputFilePlayerId(VoEModuleId(instanceId, channelId) + 1025), |
| 760 _outputFileRecorderId(VoEModuleId(instanceId, channelId) + 1026), | 762 _outputFileRecorderId(VoEModuleId(instanceId, channelId) + 1026), |
| 761 _outputFileRecording(false), | 763 _outputFileRecording(false), |
| 764 _inbandDtmfQueue(VoEModuleId(instanceId, channelId)), |
| 765 _inbandDtmfGenerator(VoEModuleId(instanceId, channelId)), |
| 762 _outputExternalMedia(false), | 766 _outputExternalMedia(false), |
| 763 _inputExternalMediaCallbackPtr(NULL), | 767 _inputExternalMediaCallbackPtr(NULL), |
| 764 _outputExternalMediaCallbackPtr(NULL), | 768 _outputExternalMediaCallbackPtr(NULL), |
| 765 _timeStamp(0), // This is just an offset, RTP module will add it's own | 769 _timeStamp(0), // This is just an offset, RTP module will add it's own |
| 766 // random offset | 770 // random offset |
| 771 _sendTelephoneEventPayloadType(106), |
| 767 ntp_estimator_(Clock::GetRealTimeClock()), | 772 ntp_estimator_(Clock::GetRealTimeClock()), |
| 768 jitter_buffer_playout_timestamp_(0), | 773 jitter_buffer_playout_timestamp_(0), |
| 769 playout_timestamp_rtp_(0), | 774 playout_timestamp_rtp_(0), |
| 770 playout_timestamp_rtcp_(0), | 775 playout_timestamp_rtcp_(0), |
| 771 playout_delay_ms_(0), | 776 playout_delay_ms_(0), |
| 772 _numberOfDiscardedPackets(0), | 777 _numberOfDiscardedPackets(0), |
| 773 send_sequence_number_(0), | 778 send_sequence_number_(0), |
| 774 rtp_ts_wraparound_handler_(new rtc::TimestampWrapAroundHandler()), | 779 rtp_ts_wraparound_handler_(new rtc::TimestampWrapAroundHandler()), |
| 775 capture_start_rtp_time_stamp_(-1), | 780 capture_start_rtp_time_stamp_(-1), |
| 776 capture_start_ntp_time_ms_(-1), | 781 capture_start_ntp_time_ms_(-1), |
| 777 _engineStatisticsPtr(NULL), | 782 _engineStatisticsPtr(NULL), |
| 778 _outputMixerPtr(NULL), | 783 _outputMixerPtr(NULL), |
| 779 _transmitMixerPtr(NULL), | 784 _transmitMixerPtr(NULL), |
| 780 _moduleProcessThreadPtr(NULL), | 785 _moduleProcessThreadPtr(NULL), |
| 781 _audioDeviceModulePtr(NULL), | 786 _audioDeviceModulePtr(NULL), |
| 782 _voiceEngineObserverPtr(NULL), | 787 _voiceEngineObserverPtr(NULL), |
| 783 _callbackCritSectPtr(NULL), | 788 _callbackCritSectPtr(NULL), |
| 784 _transportPtr(NULL), | 789 _transportPtr(NULL), |
| 785 _rxVadObserverPtr(NULL), | 790 _rxVadObserverPtr(NULL), |
| 786 _oldVadDecision(-1), | 791 _oldVadDecision(-1), |
| 787 _sendFrameType(0), | 792 _sendFrameType(0), |
| 788 _externalMixing(false), | 793 _externalMixing(false), |
| 789 _mixFileWithMicrophone(false), | 794 _mixFileWithMicrophone(false), |
| 790 _mute(false), | 795 _mute(false), |
| 791 _panLeft(1.0f), | 796 _panLeft(1.0f), |
| 792 _panRight(1.0f), | 797 _panRight(1.0f), |
| 793 _outputGain(1.0f), | 798 _outputGain(1.0f), |
| 799 _playOutbandDtmfEvent(false), |
| 800 _playInbandDtmfEvent(false), |
| 794 _lastLocalTimeStamp(0), | 801 _lastLocalTimeStamp(0), |
| 795 _lastPayloadType(0), | 802 _lastPayloadType(0), |
| 796 _includeAudioLevelIndication(false), | 803 _includeAudioLevelIndication(false), |
| 797 _outputSpeechType(AudioFrame::kNormalSpeech), | 804 _outputSpeechType(AudioFrame::kNormalSpeech), |
| 798 _average_jitter_buffer_delay_us(0), | 805 _average_jitter_buffer_delay_us(0), |
| 799 _previousTimestamp(0), | 806 _previousTimestamp(0), |
| 800 _recPacketDelayMs(20), | 807 _recPacketDelayMs(20), |
| 801 _RxVadDetection(false), | 808 _RxVadDetection(false), |
| 802 _rxAgcIsEnabled(false), | 809 _rxAgcIsEnabled(false), |
| 803 _rxNsIsEnabled(false), | 810 _rxNsIsEnabled(false), |
| (...skipping 12 matching lines...) Expand all Loading... |
| 816 if (config.Get<NetEqCapacityConfig>().enabled) { | 823 if (config.Get<NetEqCapacityConfig>().enabled) { |
| 817 // Clamping the buffer capacity at 20 packets. While going lower will | 824 // Clamping the buffer capacity at 20 packets. While going lower will |
| 818 // probably work, it makes little sense. | 825 // probably work, it makes little sense. |
| 819 acm_config.neteq_config.max_packets_in_buffer = | 826 acm_config.neteq_config.max_packets_in_buffer = |
| 820 std::max(20, config.Get<NetEqCapacityConfig>().capacity); | 827 std::max(20, config.Get<NetEqCapacityConfig>().capacity); |
| 821 } | 828 } |
| 822 acm_config.neteq_config.enable_fast_accelerate = | 829 acm_config.neteq_config.enable_fast_accelerate = |
| 823 config.Get<NetEqFastAccelerate>().enabled; | 830 config.Get<NetEqFastAccelerate>().enabled; |
| 824 audio_coding_.reset(AudioCodingModule::Create(acm_config)); | 831 audio_coding_.reset(AudioCodingModule::Create(acm_config)); |
| 825 | 832 |
| 833 _inbandDtmfQueue.ResetDtmf(); |
| 834 _inbandDtmfGenerator.Init(); |
| 826 _outputAudioLevel.Clear(); | 835 _outputAudioLevel.Clear(); |
| 827 | 836 |
| 828 RtpRtcp::Configuration configuration; | 837 RtpRtcp::Configuration configuration; |
| 829 configuration.audio = true; | 838 configuration.audio = true; |
| 830 configuration.outgoing_transport = this; | 839 configuration.outgoing_transport = this; |
| 831 configuration.audio_messages = this; | 840 configuration.audio_messages = this; |
| 832 configuration.receive_statistics = rtp_receive_statistics_.get(); | 841 configuration.receive_statistics = rtp_receive_statistics_.get(); |
| 833 configuration.bandwidth_callback = rtcp_observer_.get(); | 842 configuration.bandwidth_callback = rtcp_observer_.get(); |
| 834 if (pacing_enabled_) { | 843 if (pacing_enabled_) { |
| 835 configuration.paced_sender = rtp_packet_sender_proxy_.get(); | 844 configuration.paced_sender = rtp_packet_sender_proxy_.get(); |
| (...skipping 1360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2196 _outputGain = scaling; | 2205 _outputGain = scaling; |
| 2197 return 0; | 2206 return 0; |
| 2198 } | 2207 } |
| 2199 | 2208 |
| 2200 int Channel::GetChannelOutputVolumeScaling(float& scaling) const { | 2209 int Channel::GetChannelOutputVolumeScaling(float& scaling) const { |
| 2201 rtc::CritScope cs(&volume_settings_critsect_); | 2210 rtc::CritScope cs(&volume_settings_critsect_); |
| 2202 scaling = _outputGain; | 2211 scaling = _outputGain; |
| 2203 return 0; | 2212 return 0; |
| 2204 } | 2213 } |
| 2205 | 2214 |
| 2206 int Channel::SendTelephoneEventOutband(int event, int duration_ms) { | 2215 int Channel::SendTelephoneEventOutband(unsigned char eventCode, |
| 2216 int lengthMs, |
| 2217 int attenuationDb, |
| 2218 bool playDtmfEvent) { |
| 2207 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), | 2219 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), |
| 2208 "Channel::SendTelephoneEventOutband(...)"); | 2220 "Channel::SendTelephoneEventOutband(..., playDtmfEvent=%d)", |
| 2209 RTC_DCHECK_LE(0, event); | 2221 playDtmfEvent); |
| 2210 RTC_DCHECK_GE(255, event); | |
| 2211 RTC_DCHECK_LE(0, duration_ms); | |
| 2212 RTC_DCHECK_GE(65535, duration_ms); | |
| 2213 if (!Sending()) { | 2222 if (!Sending()) { |
| 2214 return -1; | 2223 return -1; |
| 2215 } | 2224 } |
| 2216 if (_rtpRtcpModule->SendTelephoneEventOutband( | 2225 |
| 2217 event, duration_ms, kTelephoneEventAttenuationdB) != 0) { | 2226 _playOutbandDtmfEvent = playDtmfEvent; |
| 2227 |
| 2228 if (_rtpRtcpModule->SendTelephoneEventOutband(eventCode, lengthMs, |
| 2229 attenuationDb) != 0) { |
| 2218 _engineStatisticsPtr->SetLastError( | 2230 _engineStatisticsPtr->SetLastError( |
| 2219 VE_SEND_DTMF_FAILED, kTraceWarning, | 2231 VE_SEND_DTMF_FAILED, kTraceWarning, |
| 2220 "SendTelephoneEventOutband() failed to send event"); | 2232 "SendTelephoneEventOutband() failed to send event"); |
| 2221 return -1; | 2233 return -1; |
| 2222 } | 2234 } |
| 2223 return 0; | 2235 return 0; |
| 2224 } | 2236 } |
| 2225 | 2237 |
| 2226 int Channel::SetSendTelephoneEventPayloadType(int payload_type) { | 2238 int Channel::SendTelephoneEventInband(unsigned char eventCode, |
| 2239 int lengthMs, |
| 2240 int attenuationDb, |
| 2241 bool playDtmfEvent) { |
| 2242 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), |
| 2243 "Channel::SendTelephoneEventInband(..., playDtmfEvent=%d)", |
| 2244 playDtmfEvent); |
| 2245 |
| 2246 _playInbandDtmfEvent = playDtmfEvent; |
| 2247 _inbandDtmfQueue.AddDtmf(eventCode, lengthMs, attenuationDb); |
| 2248 |
| 2249 return 0; |
| 2250 } |
| 2251 |
| 2252 int Channel::SetSendTelephoneEventPayloadType(unsigned char type) { |
| 2227 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), | 2253 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), |
| 2228 "Channel::SetSendTelephoneEventPayloadType()"); | 2254 "Channel::SetSendTelephoneEventPayloadType()"); |
| 2229 RTC_DCHECK_LE(0, payload_type); | 2255 if (type > 127) { |
| 2230 RTC_DCHECK_GE(127, payload_type); | 2256 _engineStatisticsPtr->SetLastError( |
| 2231 CodecInst codec = {0}; | 2257 VE_INVALID_ARGUMENT, kTraceError, |
| 2258 "SetSendTelephoneEventPayloadType() invalid type"); |
| 2259 return -1; |
| 2260 } |
| 2261 CodecInst codec = {}; |
| 2232 codec.plfreq = 8000; | 2262 codec.plfreq = 8000; |
| 2233 codec.pltype = payload_type; | 2263 codec.pltype = type; |
| 2234 memcpy(codec.plname, "telephone-event", 16); | 2264 memcpy(codec.plname, "telephone-event", 16); |
| 2235 if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) { | 2265 if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) { |
| 2236 _rtpRtcpModule->DeRegisterSendPayload(codec.pltype); | 2266 _rtpRtcpModule->DeRegisterSendPayload(codec.pltype); |
| 2237 if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) { | 2267 if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) { |
| 2238 _engineStatisticsPtr->SetLastError( | 2268 _engineStatisticsPtr->SetLastError( |
| 2239 VE_RTP_RTCP_MODULE_ERROR, kTraceError, | 2269 VE_RTP_RTCP_MODULE_ERROR, kTraceError, |
| 2240 "SetSendTelephoneEventPayloadType() failed to register send" | 2270 "SetSendTelephoneEventPayloadType() failed to register send" |
| 2241 "payload type"); | 2271 "payload type"); |
| 2242 return -1; | 2272 return -1; |
| 2243 } | 2273 } |
| 2244 } | 2274 } |
| 2275 _sendTelephoneEventPayloadType = type; |
| 2245 return 0; | 2276 return 0; |
| 2246 } | 2277 } |
| 2247 | 2278 |
| 2279 int Channel::GetSendTelephoneEventPayloadType(unsigned char& type) { |
| 2280 type = _sendTelephoneEventPayloadType; |
| 2281 return 0; |
| 2282 } |
| 2283 |
| 2248 int Channel::UpdateRxVadDetection(AudioFrame& audioFrame) { | 2284 int Channel::UpdateRxVadDetection(AudioFrame& audioFrame) { |
| 2249 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId), | 2285 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId), |
| 2250 "Channel::UpdateRxVadDetection()"); | 2286 "Channel::UpdateRxVadDetection()"); |
| 2251 | 2287 |
| 2252 int vadDecision = 1; | 2288 int vadDecision = 1; |
| 2253 | 2289 |
| 2254 vadDecision = (audioFrame.vad_activity_ == AudioFrame::kVadActive) ? 1 : 0; | 2290 vadDecision = (audioFrame.vad_activity_ == AudioFrame::kVadActive) ? 1 : 0; |
| 2255 | 2291 |
| 2256 if ((vadDecision != _oldVadDecision) && _rxVadObserverPtr) { | 2292 if ((vadDecision != _oldVadDecision) && _rxVadObserverPtr) { |
| 2257 OnRxVadDetected(vadDecision); | 2293 OnRxVadDetected(vadDecision); |
| (...skipping 726 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2984 rtc::CritScope cs(&_callbackCritSect); | 3020 rtc::CritScope cs(&_callbackCritSect); |
| 2985 const bool isStereo = (_audioFrame.num_channels_ == 2); | 3021 const bool isStereo = (_audioFrame.num_channels_ == 2); |
| 2986 if (_inputExternalMediaCallbackPtr) { | 3022 if (_inputExternalMediaCallbackPtr) { |
| 2987 _inputExternalMediaCallbackPtr->Process( | 3023 _inputExternalMediaCallbackPtr->Process( |
| 2988 _channelId, kRecordingPerChannel, (int16_t*)_audioFrame.data_, | 3024 _channelId, kRecordingPerChannel, (int16_t*)_audioFrame.data_, |
| 2989 _audioFrame.samples_per_channel_, _audioFrame.sample_rate_hz_, | 3025 _audioFrame.samples_per_channel_, _audioFrame.sample_rate_hz_, |
| 2990 isStereo); | 3026 isStereo); |
| 2991 } | 3027 } |
| 2992 } | 3028 } |
| 2993 | 3029 |
| 3030 InsertInbandDtmfTone(); |
| 3031 |
| 2994 if (_includeAudioLevelIndication) { | 3032 if (_includeAudioLevelIndication) { |
| 2995 size_t length = | 3033 size_t length = |
| 2996 _audioFrame.samples_per_channel_ * _audioFrame.num_channels_; | 3034 _audioFrame.samples_per_channel_ * _audioFrame.num_channels_; |
| 2997 if (is_muted) { | 3035 if (is_muted) { |
| 2998 rms_level_.ProcessMuted(length); | 3036 rms_level_.ProcessMuted(length); |
| 2999 } else { | 3037 } else { |
| 3000 rms_level_.Process(_audioFrame.data_, length); | 3038 rms_level_.Process(_audioFrame.data_, length); |
| 3001 } | 3039 } |
| 3002 } | 3040 } |
| 3003 | 3041 |
| (...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3303 "Channel::MixAudioWithFile() samples_per_channel_(%" PRIuS | 3341 "Channel::MixAudioWithFile() samples_per_channel_(%" PRIuS |
| 3304 ") != " | 3342 ") != " |
| 3305 "fileSamples(%" PRIuS ")", | 3343 "fileSamples(%" PRIuS ")", |
| 3306 audioFrame.samples_per_channel_, fileSamples); | 3344 audioFrame.samples_per_channel_, fileSamples); |
| 3307 return -1; | 3345 return -1; |
| 3308 } | 3346 } |
| 3309 | 3347 |
| 3310 return 0; | 3348 return 0; |
| 3311 } | 3349 } |
| 3312 | 3350 |
| 3351 int Channel::InsertInbandDtmfTone() { |
| 3352 // Check if we should start a new tone. |
| 3353 if (_inbandDtmfQueue.PendingDtmf() && !_inbandDtmfGenerator.IsAddingTone() && |
| 3354 _inbandDtmfGenerator.DelaySinceLastTone() > |
| 3355 kMinTelephoneEventSeparationMs) { |
| 3356 int8_t eventCode(0); |
| 3357 uint16_t lengthMs(0); |
| 3358 uint8_t attenuationDb(0); |
| 3359 |
| 3360 eventCode = _inbandDtmfQueue.NextDtmf(&lengthMs, &attenuationDb); |
| 3361 _inbandDtmfGenerator.AddTone(eventCode, lengthMs, attenuationDb); |
| 3362 if (_playInbandDtmfEvent) { |
| 3363 // Add tone to output mixer using a reduced length to minimize |
| 3364 // risk of echo. |
| 3365 _outputMixerPtr->PlayDtmfTone(eventCode, lengthMs - 80, attenuationDb); |
| 3366 } |
| 3367 } |
| 3368 |
| 3369 if (_inbandDtmfGenerator.IsAddingTone()) { |
| 3370 uint16_t frequency(0); |
| 3371 _inbandDtmfGenerator.GetSampleRate(frequency); |
| 3372 |
| 3373 if (frequency != _audioFrame.sample_rate_hz_) { |
| 3374 // Update sample rate of Dtmf tone since the mixing frequency |
| 3375 // has changed. |
| 3376 _inbandDtmfGenerator.SetSampleRate( |
| 3377 (uint16_t)(_audioFrame.sample_rate_hz_)); |
| 3378 // Reset the tone to be added taking the new sample rate into |
| 3379 // account. |
| 3380 _inbandDtmfGenerator.ResetTone(); |
| 3381 } |
| 3382 |
| 3383 int16_t toneBuffer[320]; |
| 3384 uint16_t toneSamples(0); |
| 3385 // Get 10ms tone segment and set time since last tone to zero |
| 3386 if (_inbandDtmfGenerator.Get10msTone(toneBuffer, toneSamples) == -1) { |
| 3387 WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId), |
| 3388 "Channel::EncodeAndSend() inserting Dtmf failed"); |
| 3389 return -1; |
| 3390 } |
| 3391 |
| 3392 // Replace mixed audio with DTMF tone. |
| 3393 for (size_t sample = 0; sample < _audioFrame.samples_per_channel_; |
| 3394 sample++) { |
| 3395 for (size_t channel = 0; channel < _audioFrame.num_channels_; channel++) { |
| 3396 const size_t index = sample * _audioFrame.num_channels_ + channel; |
| 3397 _audioFrame.data_[index] = toneBuffer[sample]; |
| 3398 } |
| 3399 } |
| 3400 |
| 3401 assert(_audioFrame.samples_per_channel_ == toneSamples); |
| 3402 } else { |
| 3403 // Add 10ms to "delay-since-last-tone" counter |
| 3404 _inbandDtmfGenerator.UpdateDelaySinceLastTone(); |
| 3405 } |
| 3406 return 0; |
| 3407 } |
| 3408 |
| 3313 void Channel::UpdatePlayoutTimestamp(bool rtcp) { | 3409 void Channel::UpdatePlayoutTimestamp(bool rtcp) { |
| 3314 uint32_t playout_timestamp = 0; | 3410 uint32_t playout_timestamp = 0; |
| 3315 | 3411 |
| 3316 if (audio_coding_->PlayoutTimestamp(&playout_timestamp) == -1) { | 3412 if (audio_coding_->PlayoutTimestamp(&playout_timestamp) == -1) { |
| 3317 // This can happen if this channel has not been received any RTP packet. In | 3413 // This can happen if this channel has not been received any RTP packet. In |
| 3318 // this case, NetEq is not capable of computing playout timestamp. | 3414 // this case, NetEq is not capable of computing playout timestamp. |
| 3319 return; | 3415 return; |
| 3320 } | 3416 } |
| 3321 | 3417 |
| 3322 uint16_t delay_ms = 0; | 3418 uint16_t delay_ms = 0; |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3551 int64_t min_rtt = 0; | 3647 int64_t min_rtt = 0; |
| 3552 if (_rtpRtcpModule->RTT(remoteSSRC, &rtt, &avg_rtt, &min_rtt, &max_rtt) != | 3648 if (_rtpRtcpModule->RTT(remoteSSRC, &rtt, &avg_rtt, &min_rtt, &max_rtt) != |
| 3553 0) { | 3649 0) { |
| 3554 return 0; | 3650 return 0; |
| 3555 } | 3651 } |
| 3556 return rtt; | 3652 return rtt; |
| 3557 } | 3653 } |
| 3558 | 3654 |
| 3559 } // namespace voe | 3655 } // namespace voe |
| 3560 } // namespace webrtc | 3656 } // namespace webrtc |
| OLD | NEW |