To support playing mono file with stereo codec as mixing with microphone capture
BUG=413
TEST=Manual test.
Review URL: https://webrtc-codereview.appspot.com/460004
git-svn-id: http://webrtc.googlecode.com/svn/trunk@1953 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/src/voice_engine/main/source/channel.cc b/src/voice_engine/main/source/channel.cc
index cd76607..94b6dd4 100644
--- a/src/voice_engine/main/source/channel.cc
+++ b/src/voice_engine/main/source/channel.cc
@@ -6151,7 +6151,7 @@
WebRtc_Word32
Channel::MixOrReplaceAudioWithFile(const int mixingFrequency)
{
- WebRtc_Word16 fileBuffer[320];
+ scoped_array<WebRtc_Word16> fileBuffer(new WebRtc_Word16[640]);
WebRtc_UWord32 fileSamples(0);
{
@@ -6166,7 +6166,7 @@
return -1;
}
- if (_inputFilePlayerPtr->Get10msAudioFromFile(fileBuffer,
+ if (_inputFilePlayerPtr->Get10msAudioFromFile(fileBuffer.get(),
fileSamples,
mixingFrequency) == -1)
{
@@ -6189,17 +6189,23 @@
if (_mixFileWithMicrophone)
{
+ // Currently file stream is always mono.
+ // TODO(xians): Change the code when FilePlayer supports real stereo.
Utility::MixWithSat(_audioFrame._payloadData,
- fileBuffer,
- (WebRtc_UWord16)fileSamples);
+ static_cast<int>(_audioFrame._audioChannel),
+ fileBuffer.get(),
+ 1,
+ static_cast<int>(fileSamples));
}
else
{
- // replace ACM audio with file
+ // Replace ACM audio with file.
+ // Currently file stream is always mono.
+ // TODO(xians): Change the code when FilePlayer supports real stereo.
_audioFrame.UpdateFrame(_channelId,
-1,
- fileBuffer,
- (WebRtc_UWord16)fileSamples,
+ fileBuffer.get(),
+ static_cast<WebRtc_UWord16>(fileSamples),
mixingFrequency,
AudioFrame::kNormalSpeech,
AudioFrame::kVadUnknown,
@@ -6215,7 +6221,7 @@
{
assert(mixingFrequency <= 32000);
- WebRtc_Word16 fileBuffer[640];
+ scoped_array<WebRtc_Word16> fileBuffer(new WebRtc_Word16[640]);
WebRtc_UWord32 fileSamples(0);
{
@@ -6230,7 +6236,7 @@
}
// We should get the frequency we ask for.
- if (_outputFilePlayerPtr->Get10msAudioFromFile(fileBuffer,
+ if (_outputFilePlayerPtr->Get10msAudioFromFile(fileBuffer.get(),
fileSamples,
mixingFrequency) == -1)
{
@@ -6243,28 +6249,13 @@
if (audioFrame._payloadDataLengthInSamples == fileSamples)
{
- // In case the incoming stream is stereo and file stream is mono,
- // turn the file stream into stereo.
- // TODO(xians): remove the code when FilePlayer supports real stereo.
- if (audioFrame._audioChannel == 2)
- {
- // The mono file stream is copied to be stereo.
- WebRtc_Word16* FileBufferCopy = new WebRtc_Word16[fileSamples];
- memcpy(FileBufferCopy, fileBuffer,
- sizeof(WebRtc_Word16) * fileSamples);
- for (unsigned int i = 0; i < fileSamples; i++)
- {
- fileBuffer[2*i] = FileBufferCopy[i];
- fileBuffer[2*i+1] = FileBufferCopy[i];
- }
- fileSamples = 2*fileSamples;
- delete [] FileBufferCopy;
- }
-
- // Mix the incoming stream and file stream.
+ // Currently file stream is always mono.
+ // TODO(xians): Change the code when FilePlayer supports real stereo.
Utility::MixWithSat(audioFrame._payloadData,
- fileBuffer,
- (WebRtc_UWord16)fileSamples);
+ static_cast<int>(audioFrame._audioChannel),
+ fileBuffer.get(),
+ 1,
+ static_cast<int>(fileSamples));
}
else
{
diff --git a/src/voice_engine/main/source/transmit_mixer.cc b/src/voice_engine/main/source/transmit_mixer.cc
index cf7f38e..cd1e2ac 100644
--- a/src/voice_engine/main/source/transmit_mixer.cc
+++ b/src/voice_engine/main/source/transmit_mixer.cc
@@ -1218,7 +1218,7 @@
WebRtc_Word32 TransmitMixer::MixOrReplaceAudioWithFile(
const int mixingFrequency)
{
- WebRtc_Word16 fileBuffer[320];
+ scoped_array<WebRtc_Word16> fileBuffer(new WebRtc_Word16[640]);
WebRtc_UWord32 fileSamples(0);
@@ -1233,7 +1233,7 @@
return -1;
}
- if (_filePlayerPtr->Get10msAudioFromFile(fileBuffer,
+ if (_filePlayerPtr->Get10msAudioFromFile(fileBuffer.get(),
fileSamples,
mixingFrequency) == -1)
{
@@ -1244,19 +1244,27 @@
}
}
+ assert(_audioFrame._payloadDataLengthInSamples == fileSamples);
+
if (_mixFileWithMicrophone)
{
+ // Currently file stream is always mono.
+ // TODO(xians): Change the code when FilePlayer supports real stereo.
Utility::MixWithSat(_audioFrame._payloadData,
- fileBuffer,
- (WebRtc_UWord16) fileSamples);
- assert(_audioFrame._payloadDataLengthInSamples == fileSamples);
+ static_cast<int>(_audioFrame._audioChannel),
+ fileBuffer.get(),
+ 1,
+ static_cast<int>(fileSamples));
} else
{
- // replace ACM audio with file
+ // Replace ACM audio with file.
+ // Currently file stream is always mono.
+ // TODO(xians): Change the code when FilePlayer supports real stereo.
_audioFrame.UpdateFrame(-1,
-1,
- fileBuffer,
- (WebRtc_UWord16) fileSamples, mixingFrequency,
+ fileBuffer.get(),
+ static_cast<WebRtc_UWord16>(fileSamples),
+ mixingFrequency,
AudioFrame::kNormalSpeech,
AudioFrame::kVadUnknown,
1);
diff --git a/src/voice_engine/main/source/utility.cc b/src/voice_engine/main/source/utility.cc
index 6e70156..1ef108e 100644
--- a/src/voice_engine/main/source/utility.cc
+++ b/src/voice_engine/main/source/utility.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ * 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
@@ -12,27 +12,53 @@
#include "module.h"
#include "trace.h"
+#include "signal_processing_library.h"
namespace webrtc
{
namespace voe
{
+enum{kMaxTargetLen = 2*32*10}; // stereo 32KHz 10ms
void Utility::MixWithSat(WebRtc_Word16 target[],
+ int target_channel,
const WebRtc_Word16 source[],
- WebRtc_UWord16 len)
+ int source_channel,
+ int source_len)
{
- WebRtc_Word32 temp(0);
- for (int i = 0; i < len; i++)
+ assert((target_channel == 1) || (target_channel == 2));
+ assert((source_channel == 1) || (source_channel == 2));
+ assert(source_len <= kMaxTargetLen);
+
+ if ((target_channel == 2) && (source_channel == 1))
{
- temp = source[i] + target[i];
- if (temp > 32767)
- target[i] = 32767;
- else if (temp < -32768)
- target[i] = -32768;
- else
- target[i] = (WebRtc_Word16) temp;
+ // Convert source from mono to stereo.
+ WebRtc_Word32 left = 0;
+ WebRtc_Word32 right = 0;
+ for (int i = 0; i < source_len; ++i) {
+ left = source[i] + target[i*2];
+ right = source[i] + target[i*2 + 1];
+ target[i*2] = WebRtcSpl_SatW32ToW16(left);
+ target[i*2 + 1] = WebRtcSpl_SatW32ToW16(right);
+ }
+ }
+ else if ((target_channel == 1) && (source_channel == 2))
+ {
+ // Convert source from stereo to mono.
+ WebRtc_Word32 temp = 0;
+ for (int i = 0; i < source_len/2; ++i) {
+ temp = ((source[i*2] + source[i*2 + 1])>>1) + target[i];
+ target[i] = WebRtcSpl_SatW32ToW16(temp);
+ }
+ }
+ else
+ {
+ WebRtc_Word32 temp = 0;
+ for (int i = 0; i < source_len; ++i) {
+ temp = source[i] + target[i];
+ target[i] = WebRtcSpl_SatW32ToW16(temp);
+ }
}
}
diff --git a/src/voice_engine/main/source/utility.h b/src/voice_engine/main/source/utility.h
index 084ddf4..a8af8bd 100644
--- a/src/voice_engine/main/source/utility.h
+++ b/src/voice_engine/main/source/utility.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ * 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
@@ -30,8 +30,10 @@
{
public:
static void MixWithSat(WebRtc_Word16 target[],
+ int target_channel,
const WebRtc_Word16 source[],
- WebRtc_UWord16 len);
+ int source_channel,
+ int source_len);
static void MixSubtractWithSat(WebRtc_Word16 target[],
const WebRtc_Word16 source[],