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 |