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
This commit is contained in:
parent
9a5b904cbe
commit
21ab3ba8f8
@ -131,7 +131,8 @@ enum ProcessingTypes
|
|||||||
kPlaybackPerChannel = 0,
|
kPlaybackPerChannel = 0,
|
||||||
kPlaybackAllChannelsMixed,
|
kPlaybackAllChannelsMixed,
|
||||||
kRecordingPerChannel,
|
kRecordingPerChannel,
|
||||||
kRecordingAllChannelsMixed
|
kRecordingAllChannelsMixed,
|
||||||
|
kRecordingPreprocessing
|
||||||
};
|
};
|
||||||
|
|
||||||
// Encryption enums
|
// Encryption enums
|
||||||
|
@ -202,8 +202,8 @@ TransmitMixer::TransmitMixer(const WebRtc_UWord32 instanceId) :
|
|||||||
_instanceId(instanceId),
|
_instanceId(instanceId),
|
||||||
_mixFileWithMicrophone(false),
|
_mixFileWithMicrophone(false),
|
||||||
_captureLevel(0),
|
_captureLevel(0),
|
||||||
_externalMedia(false),
|
external_postproc_ptr_(NULL),
|
||||||
_externalMediaCallbackPtr(NULL),
|
external_preproc_ptr_(NULL),
|
||||||
_mute(false),
|
_mute(false),
|
||||||
_remainingMuteMicTimeMs(0),
|
_remainingMuteMicTimeMs(0),
|
||||||
_mixingFrequency(0),
|
_mixingFrequency(0),
|
||||||
@ -223,10 +223,8 @@ TransmitMixer::~TransmitMixer()
|
|||||||
{
|
{
|
||||||
_processThreadPtr->DeRegisterModule(&_monitorModule);
|
_processThreadPtr->DeRegisterModule(&_monitorModule);
|
||||||
}
|
}
|
||||||
if (_externalMedia)
|
DeRegisterExternalMediaProcessing(kRecordingAllChannelsMixed);
|
||||||
{
|
DeRegisterExternalMediaProcessing(kRecordingPreprocessing);
|
||||||
DeRegisterExternalMediaProcessing();
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
CriticalSectionScoped cs(&_critSect);
|
CriticalSectionScoped cs(&_critSect);
|
||||||
if (_fileRecorderPtr)
|
if (_fileRecorderPtr)
|
||||||
@ -362,6 +360,17 @@ TransmitMixer::PrepareDemux(const void* audioSamples,
|
|||||||
return -1;
|
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
|
// --- Near-end Voice Quality Enhancement (APM) processing
|
||||||
|
|
||||||
APMProcessStream(totalDelayMS, clockDrift, currentMicLevel);
|
APMProcessStream(totalDelayMS, clockDrift, currentMicLevel);
|
||||||
@ -413,22 +422,15 @@ TransmitMixer::PrepareDemux(const void* audioSamples,
|
|||||||
RecordAudioToFile(_mixingFrequency);
|
RecordAudioToFile(_mixingFrequency);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- External media processing
|
|
||||||
|
|
||||||
if (_externalMedia)
|
|
||||||
{
|
{
|
||||||
CriticalSectionScoped cs(&_callbackCritSect);
|
CriticalSectionScoped cs(&_callbackCritSect);
|
||||||
const bool isStereo = (_audioFrame.num_channels_ == 2);
|
if (external_postproc_ptr_) {
|
||||||
if (_externalMediaCallbackPtr)
|
external_postproc_ptr_->Process(-1, kRecordingAllChannelsMixed,
|
||||||
{
|
_audioFrame.data_,
|
||||||
_externalMediaCallbackPtr->Process(
|
_audioFrame.samples_per_channel_,
|
||||||
-1,
|
_audioFrame.sample_rate_hz_,
|
||||||
kRecordingAllChannelsMixed,
|
_audioFrame.num_channels_ == 2);
|
||||||
(WebRtc_Word16*) _audioFrame.data_,
|
}
|
||||||
_audioFrame.samples_per_channel_,
|
|
||||||
_audioFrame.sample_rate_hz_,
|
|
||||||
isStereo);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1095,28 +1097,40 @@ TransmitMixer::SetMixWithMicStatus(bool mix)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int TransmitMixer::RegisterExternalMediaProcessing(
|
int TransmitMixer::RegisterExternalMediaProcessing(
|
||||||
VoEMediaProcess& proccess_object)
|
VoEMediaProcess* object,
|
||||||
{
|
ProcessingTypes type) {
|
||||||
WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
|
WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
|
||||||
"TransmitMixer::RegisterExternalMediaProcessing()");
|
"TransmitMixer::RegisterExternalMediaProcessing()");
|
||||||
|
|
||||||
CriticalSectionScoped cs(&_callbackCritSect);
|
CriticalSectionScoped cs(&_callbackCritSect);
|
||||||
_externalMediaCallbackPtr = &proccess_object;
|
if (!object) {
|
||||||
_externalMedia = true;
|
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()
|
int TransmitMixer::DeRegisterExternalMediaProcessing(ProcessingTypes type) {
|
||||||
{
|
WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
|
||||||
WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
|
"TransmitMixer::DeRegisterExternalMediaProcessing()");
|
||||||
"TransmitMixer::DeRegisterExternalMediaProcessing()");
|
|
||||||
|
|
||||||
CriticalSectionScoped cs(&_callbackCritSect);
|
CriticalSectionScoped cs(&_callbackCritSect);
|
||||||
_externalMedia = false;
|
if (type == kRecordingAllChannelsMixed) {
|
||||||
_externalMediaCallbackPtr = NULL;
|
external_postproc_ptr_ = NULL;
|
||||||
|
} else if (type == kRecordingPreprocessing) {
|
||||||
return 0;
|
external_preproc_ptr_ = NULL;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -73,9 +73,9 @@ public:
|
|||||||
void UpdateMuteMicrophoneTime(const WebRtc_UWord32 lengthMs);
|
void UpdateMuteMicrophoneTime(const WebRtc_UWord32 lengthMs);
|
||||||
|
|
||||||
// VoEExternalMedia
|
// VoEExternalMedia
|
||||||
int RegisterExternalMediaProcessing(VoEMediaProcess& proccess_object);
|
int RegisterExternalMediaProcessing(VoEMediaProcess* object,
|
||||||
|
ProcessingTypes type);
|
||||||
int DeRegisterExternalMediaProcessing();
|
int DeRegisterExternalMediaProcessing(ProcessingTypes type);
|
||||||
|
|
||||||
int GetMixingFrequency();
|
int GetMixingFrequency();
|
||||||
|
|
||||||
@ -193,8 +193,8 @@ private:
|
|||||||
// owns
|
// owns
|
||||||
MonitorModule _monitorModule;
|
MonitorModule _monitorModule;
|
||||||
AudioFrame _audioFrame;
|
AudioFrame _audioFrame;
|
||||||
Resampler _audioResampler; // ADM sample rate -> mixing rate
|
Resampler _audioResampler; // ADM sample rate -> mixing rate
|
||||||
FilePlayer* _filePlayerPtr;
|
FilePlayer* _filePlayerPtr;
|
||||||
FileRecorder* _fileRecorderPtr;
|
FileRecorder* _fileRecorderPtr;
|
||||||
FileRecorder* _fileCallRecorderPtr;
|
FileRecorder* _fileCallRecorderPtr;
|
||||||
int _filePlayerId;
|
int _filePlayerId;
|
||||||
@ -228,8 +228,8 @@ private:
|
|||||||
int _instanceId;
|
int _instanceId;
|
||||||
bool _mixFileWithMicrophone;
|
bool _mixFileWithMicrophone;
|
||||||
WebRtc_UWord32 _captureLevel;
|
WebRtc_UWord32 _captureLevel;
|
||||||
bool _externalMedia;
|
VoEMediaProcess* external_postproc_ptr_;
|
||||||
VoEMediaProcess* _externalMediaCallbackPtr;
|
VoEMediaProcess* external_preproc_ptr_;
|
||||||
bool _mute;
|
bool _mute;
|
||||||
WebRtc_Word32 _remainingMuteMicTimeMs;
|
WebRtc_Word32 _remainingMuteMicTimeMs;
|
||||||
int _mixingFrequency;
|
int _mixingFrequency;
|
||||||
|
59
src/voice_engine/transmit_mixer_unittest.cc
Normal file
59
src/voice_engine/transmit_mixer_unittest.cc
Normal file
@ -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
|
@ -88,9 +88,10 @@ int VoEExternalMediaImpl::RegisterExternalMediaProcessing(
|
|||||||
processObject);
|
processObject);
|
||||||
}
|
}
|
||||||
case kRecordingAllChannelsMixed:
|
case kRecordingAllChannelsMixed:
|
||||||
|
case kRecordingPreprocessing:
|
||||||
{
|
{
|
||||||
return shared_->transmit_mixer()->RegisterExternalMediaProcessing(
|
return shared_->transmit_mixer()->RegisterExternalMediaProcessing(
|
||||||
processObject);
|
&processObject, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
@ -131,9 +132,10 @@ int VoEExternalMediaImpl::DeRegisterExternalMediaProcessing(
|
|||||||
DeRegisterExternalMediaProcessing();
|
DeRegisterExternalMediaProcessing();
|
||||||
}
|
}
|
||||||
case kRecordingAllChannelsMixed:
|
case kRecordingAllChannelsMixed:
|
||||||
|
case kRecordingPreprocessing:
|
||||||
{
|
{
|
||||||
return shared_->transmit_mixer()->
|
return shared_->transmit_mixer()->
|
||||||
DeRegisterExternalMediaProcessing();
|
DeRegisterExternalMediaProcessing(type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -144,6 +144,7 @@
|
|||||||
'sources': [
|
'sources': [
|
||||||
'channel_unittest.cc',
|
'channel_unittest.cc',
|
||||||
'output_mixer_unittest.cc',
|
'output_mixer_unittest.cc',
|
||||||
|
'transmit_mixer_unittest.cc',
|
||||||
'voe_audio_processing_unittest.cc',
|
'voe_audio_processing_unittest.cc',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user