Add external media hook for preprocessed audio.
Review URL: https://webrtc-codereview.appspot.com/879007
git-svn-id: http://webrtc.googlecode.com/svn/trunk@2960 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/src/common_types.h b/src/common_types.h
index 0d71f3f..83c55a3 100644
--- a/src/common_types.h
+++ b/src/common_types.h
@@ -131,7 +131,8 @@
kPlaybackPerChannel = 0,
kPlaybackAllChannelsMixed,
kRecordingPerChannel,
- kRecordingAllChannelsMixed
+ kRecordingAllChannelsMixed,
+ kRecordingPreprocessing
};
// Encryption enums
diff --git a/src/voice_engine/transmit_mixer.cc b/src/voice_engine/transmit_mixer.cc
index d987c4e..452af1c 100644
--- a/src/voice_engine/transmit_mixer.cc
+++ b/src/voice_engine/transmit_mixer.cc
@@ -202,8 +202,8 @@
_instanceId(instanceId),
_mixFileWithMicrophone(false),
_captureLevel(0),
- _externalMedia(false),
- _externalMediaCallbackPtr(NULL),
+ external_postproc_ptr_(NULL),
+ external_preproc_ptr_(NULL),
_mute(false),
_remainingMuteMicTimeMs(0),
_mixingFrequency(0),
@@ -223,10 +223,8 @@
{
_processThreadPtr->DeRegisterModule(&_monitorModule);
}
- if (_externalMedia)
- {
- DeRegisterExternalMediaProcessing();
- }
+ DeRegisterExternalMediaProcessing(kRecordingAllChannelsMixed);
+ DeRegisterExternalMediaProcessing(kRecordingPreprocessing);
{
CriticalSectionScoped cs(&_critSect);
if (_fileRecorderPtr)
@@ -362,6 +360,17 @@
return -1;
}
+ {
+ CriticalSectionScoped cs(&_callbackCritSect);
+ if (external_preproc_ptr_) {
+ external_preproc_ptr_->Process(-1, kRecordingPreprocessing,
+ _audioFrame.data_,
+ _audioFrame.samples_per_channel_,
+ _audioFrame.sample_rate_hz_,
+ _audioFrame.num_channels_ == 2);
+ }
+ }
+
// --- Near-end Voice Quality Enhancement (APM) processing
APMProcessStream(totalDelayMS, clockDrift, currentMicLevel);
@@ -413,22 +422,15 @@
RecordAudioToFile(_mixingFrequency);
}
- // --- External media processing
-
- if (_externalMedia)
{
- CriticalSectionScoped cs(&_callbackCritSect);
- const bool isStereo = (_audioFrame.num_channels_ == 2);
- if (_externalMediaCallbackPtr)
- {
- _externalMediaCallbackPtr->Process(
- -1,
- kRecordingAllChannelsMixed,
- (WebRtc_Word16*) _audioFrame.data_,
- _audioFrame.samples_per_channel_,
- _audioFrame.sample_rate_hz_,
- isStereo);
- }
+ CriticalSectionScoped cs(&_callbackCritSect);
+ if (external_postproc_ptr_) {
+ external_postproc_ptr_->Process(-1, kRecordingAllChannelsMixed,
+ _audioFrame.data_,
+ _audioFrame.samples_per_channel_,
+ _audioFrame.sample_rate_hz_,
+ _audioFrame.num_channels_ == 2);
+ }
}
return 0;
@@ -1095,28 +1097,40 @@
}
int TransmitMixer::RegisterExternalMediaProcessing(
- VoEMediaProcess& proccess_object)
-{
- WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
- "TransmitMixer::RegisterExternalMediaProcessing()");
+ VoEMediaProcess* object,
+ ProcessingTypes type) {
+ WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
+ "TransmitMixer::RegisterExternalMediaProcessing()");
- CriticalSectionScoped cs(&_callbackCritSect);
- _externalMediaCallbackPtr = &proccess_object;
- _externalMedia = true;
+ CriticalSectionScoped cs(&_callbackCritSect);
+ if (!object) {
+ return -1;
+ }
- return 0;
+ // Store the callback object according to the processing type.
+ if (type == kRecordingAllChannelsMixed) {
+ external_postproc_ptr_ = object;
+ } else if (type == kRecordingPreprocessing) {
+ external_preproc_ptr_ = object;
+ } else {
+ return -1;
+ }
+ return 0;
}
-int TransmitMixer::DeRegisterExternalMediaProcessing()
-{
- WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
- "TransmitMixer::DeRegisterExternalMediaProcessing()");
+int TransmitMixer::DeRegisterExternalMediaProcessing(ProcessingTypes type) {
+ WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
+ "TransmitMixer::DeRegisterExternalMediaProcessing()");
- CriticalSectionScoped cs(&_callbackCritSect);
- _externalMedia = false;
- _externalMediaCallbackPtr = NULL;
-
- return 0;
+ CriticalSectionScoped cs(&_callbackCritSect);
+ if (type == kRecordingAllChannelsMixed) {
+ external_postproc_ptr_ = NULL;
+ } else if (type == kRecordingPreprocessing) {
+ external_preproc_ptr_ = NULL;
+ } else {
+ return -1;
+ }
+ return 0;
}
int
diff --git a/src/voice_engine/transmit_mixer.h b/src/voice_engine/transmit_mixer.h
index da87218..0dac049 100644
--- a/src/voice_engine/transmit_mixer.h
+++ b/src/voice_engine/transmit_mixer.h
@@ -73,9 +73,9 @@
void UpdateMuteMicrophoneTime(const WebRtc_UWord32 lengthMs);
// VoEExternalMedia
- int RegisterExternalMediaProcessing(VoEMediaProcess& proccess_object);
-
- int DeRegisterExternalMediaProcessing();
+ int RegisterExternalMediaProcessing(VoEMediaProcess* object,
+ ProcessingTypes type);
+ int DeRegisterExternalMediaProcessing(ProcessingTypes type);
int GetMixingFrequency();
@@ -193,8 +193,8 @@
// owns
MonitorModule _monitorModule;
AudioFrame _audioFrame;
- Resampler _audioResampler; // ADM sample rate -> mixing rate
- FilePlayer* _filePlayerPtr;
+ Resampler _audioResampler; // ADM sample rate -> mixing rate
+ FilePlayer* _filePlayerPtr;
FileRecorder* _fileRecorderPtr;
FileRecorder* _fileCallRecorderPtr;
int _filePlayerId;
@@ -228,8 +228,8 @@
int _instanceId;
bool _mixFileWithMicrophone;
WebRtc_UWord32 _captureLevel;
- bool _externalMedia;
- VoEMediaProcess* _externalMediaCallbackPtr;
+ VoEMediaProcess* external_postproc_ptr_;
+ VoEMediaProcess* external_preproc_ptr_;
bool _mute;
WebRtc_Word32 _remainingMuteMicTimeMs;
int _mixingFrequency;
diff --git a/src/voice_engine/transmit_mixer_unittest.cc b/src/voice_engine/transmit_mixer_unittest.cc
new file mode 100644
index 0000000..d8d85b6
--- /dev/null
+++ b/src/voice_engine/transmit_mixer_unittest.cc
@@ -0,0 +1,59 @@
+/*
+ * 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 "voice_engine/transmit_mixer.h"
+
+#include "gtest/gtest.h"
+#include "voice_engine/include/voe_external_media.h"
+
+namespace webrtc {
+namespace voe {
+namespace {
+
+class MediaCallback : public VoEMediaProcess {
+ public:
+ virtual void Process(const int channel, const ProcessingTypes type,
+ int16_t audio[], const int samples_per_channel,
+ const int sample_rate_hz, const bool is_stereo) {
+ }
+};
+
+// TODO(andrew): Mock VoEMediaProcess, and verify the behavior when calling
+// PrepareDemux().
+TEST(TransmitMixerTest, RegisterExternalMediaCallback) {
+ TransmitMixer* tm = NULL;
+ ASSERT_EQ(0, TransmitMixer::Create(tm, 0));
+ ASSERT_TRUE(tm != NULL);
+ MediaCallback callback;
+ EXPECT_EQ(-1, tm->RegisterExternalMediaProcessing(NULL,
+ kRecordingPreprocessing));
+ EXPECT_EQ(-1, tm->RegisterExternalMediaProcessing(&callback,
+ kPlaybackPerChannel));
+ EXPECT_EQ(-1, tm->RegisterExternalMediaProcessing(&callback,
+ kPlaybackAllChannelsMixed));
+ EXPECT_EQ(-1, tm->RegisterExternalMediaProcessing(&callback,
+ kRecordingPerChannel));
+ EXPECT_EQ(0, tm->RegisterExternalMediaProcessing(&callback,
+ kRecordingAllChannelsMixed));
+ EXPECT_EQ(0, tm->RegisterExternalMediaProcessing(&callback,
+ kRecordingPreprocessing));
+ EXPECT_EQ(-1, tm->DeRegisterExternalMediaProcessing(kPlaybackPerChannel));
+ EXPECT_EQ(-1, tm->DeRegisterExternalMediaProcessing(
+ kPlaybackAllChannelsMixed));
+ EXPECT_EQ(-1, tm->DeRegisterExternalMediaProcessing(kRecordingPerChannel));
+ EXPECT_EQ(0, tm->DeRegisterExternalMediaProcessing(
+ kRecordingAllChannelsMixed));
+ EXPECT_EQ(0, tm->DeRegisterExternalMediaProcessing(kRecordingPreprocessing));
+ TransmitMixer::Destroy(tm);
+}
+
+} // namespace
+} // namespace voe
+} // namespace webrtc
diff --git a/src/voice_engine/voe_external_media_impl.cc b/src/voice_engine/voe_external_media_impl.cc
index 0158c3d..0216023 100644
--- a/src/voice_engine/voe_external_media_impl.cc
+++ b/src/voice_engine/voe_external_media_impl.cc
@@ -88,9 +88,10 @@
processObject);
}
case kRecordingAllChannelsMixed:
+ case kRecordingPreprocessing:
{
return shared_->transmit_mixer()->RegisterExternalMediaProcessing(
- processObject);
+ &processObject, type);
}
}
return -1;
@@ -131,9 +132,10 @@
DeRegisterExternalMediaProcessing();
}
case kRecordingAllChannelsMixed:
+ case kRecordingPreprocessing:
{
return shared_->transmit_mixer()->
- DeRegisterExternalMediaProcessing();
+ DeRegisterExternalMediaProcessing(type);
}
}
return -1;
diff --git a/src/voice_engine/voice_engine_core.gypi b/src/voice_engine/voice_engine_core.gypi
index 79d55cd..0478a71 100644
--- a/src/voice_engine/voice_engine_core.gypi
+++ b/src/voice_engine/voice_engine_core.gypi
@@ -144,6 +144,7 @@
'sources': [
'channel_unittest.cc',
'output_mixer_unittest.cc',
+ 'transmit_mixer_unittest.cc',
'voe_audio_processing_unittest.cc',
],
},