Bug 694814: Patch 1: Add farend input to webrtc.org upstream rs=padenot

This commit is contained in:
Randell Jesup 2014-04-02 13:58:19 -04:00
parent 07df38f7df
commit 73e3825d95
6 changed files with 92 additions and 9 deletions

View File

@ -43,6 +43,9 @@ class FakeVoEExternalMedia : public VoEExternalMedia {
WEBRTC_STUB(ExternalPlayoutGetData,
(int16_t speechData10ms[], int samplingFreqHz,
int current_delay_ms, int& lengthSamples));
WEBRTC_STUB(ExternalPlayoutData,
(int16_t speechData10ms[], int samplingFreqHz,
int num_channels, int current_delay_ms, int& lengthSamples));
WEBRTC_STUB(GetAudioFrame, (int channel, int desired_sample_rate_hz,
AudioFrame* frame));
WEBRTC_STUB(SetExternalMixing, (int channel, bool enable));

View File

@ -97,10 +97,18 @@ public:
int samplingFreqHz, int current_delay_ms) = 0;
// This function inserts audio written to the OS audio drivers for use
// as the far-end signal for AEC processing. The length of the block
// must be 160, 320, 441 or 480 samples (for 16000, 32000, 44100 or
// 48000 kHz sampling rates respectively).
virtual int ExternalPlayoutData(
int16_t speechData10ms[], int samplingFreqHz, int num_channels,
int current_delay_ms, int& lengthSamples) = 0;
// This function gets audio for an external playout sink.
// During transmission, this function should be called every ~10 ms
// to obtain a new 10 ms frame of audio. The length of the block will
// be 160, 320, 440 or 480 samples (for 16000, 32000, 44100 or 48000
// be 160, 320, 441 or 480 samples (for 16000, 32000, 44100 or 48000
// kHz sampling rates respectively).
virtual int ExternalPlayoutGetData(
int16_t speechData10ms[], int samplingFreqHz,

View File

@ -566,7 +566,7 @@ OutputMixer::DoOperationsOnCombinedSignal()
// --- Far-end Voice Quality Enhancement (AudioProcessing Module)
APMAnalyzeReverseStream();
APMAnalyzeReverseStream(_audioFrame);
// --- External media processing
@ -592,17 +592,13 @@ OutputMixer::DoOperationsOnCombinedSignal()
return 0;
}
// ----------------------------------------------------------------------------
// Private methods
// ----------------------------------------------------------------------------
void OutputMixer::APMAnalyzeReverseStream() {
void OutputMixer::APMAnalyzeReverseStream(AudioFrame &audioFrame) {
// Convert from mixing to AudioProcessing sample rate, determined by the send
// side. Downmix to mono.
AudioFrame frame;
frame.num_channels_ = 1;
frame.sample_rate_hz_ = _audioProcessingModulePtr->sample_rate_hz();
if (RemixAndResample(_audioFrame, &audioproc_resampler_, &frame) == -1)
if (RemixAndResample(audioFrame, &audioproc_resampler_, &frame) == -1)
return;
if (_audioProcessingModulePtr->AnalyzeReverseStream(&frame) == -1) {
@ -611,6 +607,10 @@ void OutputMixer::APMAnalyzeReverseStream() {
}
}
// ----------------------------------------------------------------------------
// Private methods
// ----------------------------------------------------------------------------
int
OutputMixer::InsertInbandDtmfTone()
{

View File

@ -118,9 +118,11 @@ public:
void PlayFileEnded(int32_t id);
void RecordFileEnded(int32_t id);
// so ExternalPlayoutData() can insert far-end audio from the audio drivers
void APMAnalyzeReverseStream(AudioFrame &audioFrame);
private:
OutputMixer(uint32_t instanceId);
void APMAnalyzeReverseStream();
int InsertInbandDtmfTone();
// uses

View File

@ -280,6 +280,68 @@ int VoEExternalMediaImpl::SetExternalPlayoutStatus(bool enable)
#endif
}
// This inserts a copy of the raw audio sent to the output drivers to use
// as the "far end" signal for the AEC. Currently only 10ms chunks are
// supported unfortunately. Since we have to rechunk to 10ms to call this,
// thre isn't much gained by allowing N*10ms here; external code can loop
// if needed.
int VoEExternalMediaImpl::ExternalPlayoutData(
int16_t speechData10ms[],
int samplingFreqHz,
int num_channels,
int current_delay_ms,
int& lengthSamples)
{
WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(shared_->instance_id(), -1),
"ExternalPlayoutData(speechData10ms=0x%x,"
" lengthSamples=%u, samplingFreqHz=%d, current_delay_ms=%d)",
&speechData10ms[0], lengthSamples, samplingFreqHz,
current_delay_ms);
#ifdef WEBRTC_VOE_EXTERNAL_REC_AND_PLAYOUT
if (!shared_->statistics().Initialized())
{
shared_->SetLastError(VE_NOT_INITED, kTraceError);
return -1;
}
// FIX(jesup) - check if this is enabled?
if (shared_->NumOfSendingChannels() == 0)
{
shared_->SetLastError(VE_ALREADY_SENDING, kTraceError,
"SetExternalRecordingStatus() no channel is sending");
return -1;
}
if ((16000 != samplingFreqHz) && (32000 != samplingFreqHz) &&
(48000 != samplingFreqHz) && (44100 != samplingFreqHz))
{
shared_->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
"SetExternalRecordingStatus() invalid sample rate");
return -1;
}
if (current_delay_ms < 0)
{
shared_->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
"SetExternalRecordingStatus() invalid delay)");
return -1;
}
// Far-end data is inserted without going through neteq/etc.
// Only supports 10ms chunks; AnalyzeReverseStream() enforces that
// lower down.
AudioFrame audioFrame;
audioFrame.UpdateFrame(-1, 0xFFFFFFFF,
speechData10ms,
lengthSamples,
samplingFreqHz,
AudioFrame::kNormalSpeech,
AudioFrame::kVadUnknown,
num_channels);
shared_->output_mixer()->APMAnalyzeReverseStream(audioFrame);
#endif
return 0;
}
int VoEExternalMediaImpl::ExternalPlayoutGetData(
int16_t speechData10ms[],
int samplingFreqHz,

View File

@ -39,6 +39,14 @@ public:
int samplingFreqHz,
int current_delay_ms);
// Insertion of far-end data as actually played out to the OS audio driver
virtual int ExternalPlayoutData(
int16_t speechData10ms[],
int samplingFreqHz,
int num_channels,
int current_delay_ms,
int& lengthSamples);
virtual int ExternalPlayoutGetData(int16_t speechData10ms[],
int samplingFreqHz,
int current_delay_ms,