| 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 |
| 11 #include "webrtc/voice_engine/transmit_mixer.h" | 11 #include "webrtc/voice_engine/transmit_mixer.h" |
| 12 | 12 |
| 13 #include <memory> | 13 #include <memory> |
| 14 | 14 |
| 15 #include "webrtc/audio/utility/audio_frame_operations.h" | 15 #include "webrtc/audio/utility/audio_frame_operations.h" |
| 16 #include "webrtc/base/format_macros.h" | 16 #include "webrtc/base/format_macros.h" |
| 17 #include "webrtc/base/logging.h" | 17 #include "webrtc/base/logging.h" |
| 18 #include "webrtc/system_wrappers/include/event_wrapper.h" | 18 #include "webrtc/system_wrappers/include/event_wrapper.h" |
| 19 #include "webrtc/system_wrappers/include/trace.h" | 19 #include "webrtc/system_wrappers/include/trace.h" |
| 20 #include "webrtc/voice_engine/channel.h" | 20 #include "webrtc/voice_engine/channel.h" |
| 21 #include "webrtc/voice_engine/channel_manager.h" | 21 #include "webrtc/voice_engine/channel_manager.h" |
| 22 #include "webrtc/voice_engine/include/voe_external_media.h" | |
| 23 #include "webrtc/voice_engine/statistics.h" | 22 #include "webrtc/voice_engine/statistics.h" |
| 24 #include "webrtc/voice_engine/utility.h" | 23 #include "webrtc/voice_engine/utility.h" |
| 25 #include "webrtc/voice_engine/voe_base_impl.h" | 24 #include "webrtc/voice_engine/voe_base_impl.h" |
| 26 | 25 |
| 27 namespace webrtc { | 26 namespace webrtc { |
| 28 namespace voe { | 27 namespace voe { |
| 29 | 28 |
| 30 // TODO(ajm): The thread safety of this is dubious... | 29 // TODO(ajm): The thread safety of this is dubious... |
| 31 void | 30 void |
| 32 TransmitMixer::OnPeriodicProcess() | 31 TransmitMixer::OnPeriodicProcess() |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 192 _fileCallRecording(false), | 191 _fileCallRecording(false), |
| 193 _audioLevel(), | 192 _audioLevel(), |
| 194 #if WEBRTC_VOICE_ENGINE_TYPING_DETECTION | 193 #if WEBRTC_VOICE_ENGINE_TYPING_DETECTION |
| 195 _typingNoiseWarningPending(false), | 194 _typingNoiseWarningPending(false), |
| 196 _typingNoiseDetected(false), | 195 _typingNoiseDetected(false), |
| 197 #endif | 196 #endif |
| 198 _saturationWarning(false), | 197 _saturationWarning(false), |
| 199 _instanceId(instanceId), | 198 _instanceId(instanceId), |
| 200 _mixFileWithMicrophone(false), | 199 _mixFileWithMicrophone(false), |
| 201 _captureLevel(0), | 200 _captureLevel(0), |
| 202 external_postproc_ptr_(NULL), | |
| 203 external_preproc_ptr_(NULL), | |
| 204 _mute(false), | 201 _mute(false), |
| 205 stereo_codec_(false), | 202 stereo_codec_(false), |
| 206 swap_stereo_channels_(false) | 203 swap_stereo_channels_(false) |
| 207 { | 204 { |
| 208 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId, -1), | 205 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId, -1), |
| 209 "TransmitMixer::TransmitMixer() - ctor"); | 206 "TransmitMixer::TransmitMixer() - ctor"); |
| 210 } | 207 } |
| 211 | 208 |
| 212 TransmitMixer::~TransmitMixer() | 209 TransmitMixer::~TransmitMixer() |
| 213 { | 210 { |
| 214 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId, -1), | 211 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId, -1), |
| 215 "TransmitMixer::~TransmitMixer() - dtor"); | 212 "TransmitMixer::~TransmitMixer() - dtor"); |
| 216 _monitorModule.DeRegisterObserver(); | 213 _monitorModule.DeRegisterObserver(); |
| 217 if (_processThreadPtr) | 214 if (_processThreadPtr) |
| 218 { | 215 { |
| 219 _processThreadPtr->DeRegisterModule(&_monitorModule); | 216 _processThreadPtr->DeRegisterModule(&_monitorModule); |
| 220 } | 217 } |
| 221 DeRegisterExternalMediaProcessing(kRecordingAllChannelsMixed); | |
| 222 DeRegisterExternalMediaProcessing(kRecordingPreprocessing); | |
| 223 { | 218 { |
| 224 rtc::CritScope cs(&_critSect); | 219 rtc::CritScope cs(&_critSect); |
| 225 if (file_recorder_) { | 220 if (file_recorder_) { |
| 226 file_recorder_->RegisterModuleFileCallback(NULL); | 221 file_recorder_->RegisterModuleFileCallback(NULL); |
| 227 file_recorder_->StopRecording(); | 222 file_recorder_->StopRecording(); |
| 228 } | 223 } |
| 229 if (file_call_recorder_) { | 224 if (file_call_recorder_) { |
| 230 file_call_recorder_->RegisterModuleFileCallback(NULL); | 225 file_call_recorder_->RegisterModuleFileCallback(NULL); |
| 231 file_call_recorder_->StopRecording(); | 226 file_call_recorder_->StopRecording(); |
| 232 } | 227 } |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 316 "clockDrift=%d, currentMicLevel=%u)", | 311 "clockDrift=%d, currentMicLevel=%u)", |
| 317 nSamples, nChannels, samplesPerSec, totalDelayMS, clockDrift, | 312 nSamples, nChannels, samplesPerSec, totalDelayMS, clockDrift, |
| 318 currentMicLevel); | 313 currentMicLevel); |
| 319 | 314 |
| 320 // --- Resample input audio and create/store the initial audio frame | 315 // --- Resample input audio and create/store the initial audio frame |
| 321 GenerateAudioFrame(static_cast<const int16_t*>(audioSamples), | 316 GenerateAudioFrame(static_cast<const int16_t*>(audioSamples), |
| 322 nSamples, | 317 nSamples, |
| 323 nChannels, | 318 nChannels, |
| 324 samplesPerSec); | 319 samplesPerSec); |
| 325 | 320 |
| 326 { | |
| 327 rtc::CritScope cs(&_callbackCritSect); | |
| 328 if (external_preproc_ptr_) { | |
| 329 external_preproc_ptr_->Process(-1, kRecordingPreprocessing, | |
| 330 _audioFrame.data_, | |
| 331 _audioFrame.samples_per_channel_, | |
| 332 _audioFrame.sample_rate_hz_, | |
| 333 _audioFrame.num_channels_ == 2); | |
| 334 } | |
| 335 } | |
| 336 | |
| 337 // --- Near-end audio processing. | 321 // --- Near-end audio processing. |
| 338 ProcessAudio(totalDelayMS, clockDrift, currentMicLevel, keyPressed); | 322 ProcessAudio(totalDelayMS, clockDrift, currentMicLevel, keyPressed); |
| 339 | 323 |
| 340 if (swap_stereo_channels_ && stereo_codec_) | 324 if (swap_stereo_channels_ && stereo_codec_) |
| 341 // Only bother swapping if we're using a stereo codec. | 325 // Only bother swapping if we're using a stereo codec. |
| 342 AudioFrameOperations::SwapStereoChannels(&_audioFrame); | 326 AudioFrameOperations::SwapStereoChannels(&_audioFrame); |
| 343 | 327 |
| 344 // --- Annoying typing detection (utilizes the APM/VAD decision) | 328 // --- Annoying typing detection (utilizes the APM/VAD decision) |
| 345 #if WEBRTC_VOICE_ENGINE_TYPING_DETECTION | 329 #if WEBRTC_VOICE_ENGINE_TYPING_DETECTION |
| 346 TypingDetection(keyPressed); | 330 TypingDetection(keyPressed); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 359 bool file_recording = false; | 343 bool file_recording = false; |
| 360 { | 344 { |
| 361 rtc::CritScope cs(&_critSect); | 345 rtc::CritScope cs(&_critSect); |
| 362 file_recording = _fileRecording; | 346 file_recording = _fileRecording; |
| 363 } | 347 } |
| 364 if (file_recording) | 348 if (file_recording) |
| 365 { | 349 { |
| 366 RecordAudioToFile(_audioFrame.sample_rate_hz_); | 350 RecordAudioToFile(_audioFrame.sample_rate_hz_); |
| 367 } | 351 } |
| 368 | 352 |
| 369 { | |
| 370 rtc::CritScope cs(&_callbackCritSect); | |
| 371 if (external_postproc_ptr_) { | |
| 372 external_postproc_ptr_->Process(-1, kRecordingAllChannelsMixed, | |
| 373 _audioFrame.data_, | |
| 374 _audioFrame.samples_per_channel_, | |
| 375 _audioFrame.sample_rate_hz_, | |
| 376 _audioFrame.num_channels_ == 2); | |
| 377 } | |
| 378 } | |
| 379 | |
| 380 // --- Measure audio level of speech after all processing. | 353 // --- Measure audio level of speech after all processing. |
| 381 _audioLevel.ComputeLevel(_audioFrame); | 354 _audioLevel.ComputeLevel(_audioFrame); |
| 382 return 0; | 355 return 0; |
| 383 } | 356 } |
| 384 | 357 |
| 385 int32_t | 358 int32_t |
| 386 TransmitMixer::DemuxAndMix() | 359 TransmitMixer::DemuxAndMix() |
| 387 { | 360 { |
| 388 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, -1), | 361 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, -1), |
| 389 "TransmitMixer::DemuxAndMix()"); | 362 "TransmitMixer::DemuxAndMix()"); |
| (...skipping 565 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 955 | 928 |
| 956 return 0; | 929 return 0; |
| 957 } | 930 } |
| 958 | 931 |
| 959 void | 932 void |
| 960 TransmitMixer::SetMixWithMicStatus(bool mix) | 933 TransmitMixer::SetMixWithMicStatus(bool mix) |
| 961 { | 934 { |
| 962 _mixFileWithMicrophone = mix; | 935 _mixFileWithMicrophone = mix; |
| 963 } | 936 } |
| 964 | 937 |
| 965 int TransmitMixer::RegisterExternalMediaProcessing( | |
| 966 VoEMediaProcess* object, | |
| 967 ProcessingTypes type) { | |
| 968 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1), | |
| 969 "TransmitMixer::RegisterExternalMediaProcessing()"); | |
| 970 | |
| 971 rtc::CritScope cs(&_callbackCritSect); | |
| 972 if (!object) { | |
| 973 return -1; | |
| 974 } | |
| 975 | |
| 976 // Store the callback object according to the processing type. | |
| 977 if (type == kRecordingAllChannelsMixed) { | |
| 978 external_postproc_ptr_ = object; | |
| 979 } else if (type == kRecordingPreprocessing) { | |
| 980 external_preproc_ptr_ = object; | |
| 981 } else { | |
| 982 return -1; | |
| 983 } | |
| 984 return 0; | |
| 985 } | |
| 986 | |
| 987 int TransmitMixer::DeRegisterExternalMediaProcessing(ProcessingTypes type) { | |
| 988 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1), | |
| 989 "TransmitMixer::DeRegisterExternalMediaProcessing()"); | |
| 990 | |
| 991 rtc::CritScope cs(&_callbackCritSect); | |
| 992 if (type == kRecordingAllChannelsMixed) { | |
| 993 external_postproc_ptr_ = NULL; | |
| 994 } else if (type == kRecordingPreprocessing) { | |
| 995 external_preproc_ptr_ = NULL; | |
| 996 } else { | |
| 997 return -1; | |
| 998 } | |
| 999 return 0; | |
| 1000 } | |
| 1001 | |
| 1002 int | 938 int |
| 1003 TransmitMixer::SetMute(bool enable) | 939 TransmitMixer::SetMute(bool enable) |
| 1004 { | 940 { |
| 1005 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1), | 941 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1), |
| 1006 "TransmitMixer::SetMute(enable=%d)", enable); | 942 "TransmitMixer::SetMute(enable=%d)", enable); |
| 1007 _mute = enable; | 943 _mute = enable; |
| 1008 return 0; | 944 return 0; |
| 1009 } | 945 } |
| 1010 | 946 |
| 1011 bool | 947 bool |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1185 // If there is already a warning pending, do not change the state. | 1121 // If there is already a warning pending, do not change the state. |
| 1186 // Otherwise set a warning pending if last callback was for noise detected. | 1122 // Otherwise set a warning pending if last callback was for noise detected. |
| 1187 if (!_typingNoiseWarningPending && _typingNoiseDetected) { | 1123 if (!_typingNoiseWarningPending && _typingNoiseDetected) { |
| 1188 _typingNoiseWarningPending = true; | 1124 _typingNoiseWarningPending = true; |
| 1189 _typingNoiseDetected = false; | 1125 _typingNoiseDetected = false; |
| 1190 } | 1126 } |
| 1191 } | 1127 } |
| 1192 } | 1128 } |
| 1193 #endif | 1129 #endif |
| 1194 | 1130 |
| 1195 int TransmitMixer::GetMixingFrequency() | |
| 1196 { | |
| 1197 assert(_audioFrame.sample_rate_hz_ != 0); | |
| 1198 return _audioFrame.sample_rate_hz_; | |
| 1199 } | |
| 1200 | |
| 1201 #if WEBRTC_VOICE_ENGINE_TYPING_DETECTION | 1131 #if WEBRTC_VOICE_ENGINE_TYPING_DETECTION |
| 1202 int TransmitMixer::TimeSinceLastTyping(int &seconds) | 1132 int TransmitMixer::TimeSinceLastTyping(int &seconds) |
| 1203 { | 1133 { |
| 1204 // We check in VoEAudioProcessingImpl that this is only called when | 1134 // We check in VoEAudioProcessingImpl that this is only called when |
| 1205 // typing detection is active. | 1135 // typing detection is active. |
| 1206 seconds = _typingDetection.TimeSinceLastDetectionInSeconds(); | 1136 seconds = _typingDetection.TimeSinceLastDetectionInSeconds(); |
| 1207 return 0; | 1137 return 0; |
| 1208 } | 1138 } |
| 1209 #endif | 1139 #endif |
| 1210 | 1140 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1228 void TransmitMixer::EnableStereoChannelSwapping(bool enable) { | 1158 void TransmitMixer::EnableStereoChannelSwapping(bool enable) { |
| 1229 swap_stereo_channels_ = enable; | 1159 swap_stereo_channels_ = enable; |
| 1230 } | 1160 } |
| 1231 | 1161 |
| 1232 bool TransmitMixer::IsStereoChannelSwappingEnabled() { | 1162 bool TransmitMixer::IsStereoChannelSwappingEnabled() { |
| 1233 return swap_stereo_channels_; | 1163 return swap_stereo_channels_; |
| 1234 } | 1164 } |
| 1235 | 1165 |
| 1236 } // namespace voe | 1166 } // namespace voe |
| 1237 } // namespace webrtc | 1167 } // namespace webrtc |
| OLD | NEW |