summaryrefslogtreecommitdiffstats
path: root/media/audio/android
diff options
context:
space:
mode:
authorajm@chromium.org <ajm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-13 08:39:34 +0000
committerajm@chromium.org <ajm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-13 08:39:34 +0000
commit0eddc22125d3d2eef9690ba87e3bad4899b4d17c (patch)
treef61d5f6fee8fc4529ba9d327af091689ddc377af /media/audio/android
parentbc92bc970efc1620e162efabedfee8592afcac06 (diff)
downloadchromium_src-0eddc22125d3d2eef9690ba87e3bad4899b4d17c.zip
chromium_src-0eddc22125d3d2eef9690ba87e3bad4899b4d17c.tar.gz
chromium_src-0eddc22125d3d2eef9690ba87e3bad4899b4d17c.tar.bz2
Enable platform echo cancellation through the AudioRecord path.
Add a platform effects mask member to AudioParameters. This allows the availability of platform effects (currently AEC) to be plumbed up to MediaStreamDependencyFactory, where they can be reconciled with the media constraints to determine if the effects should be enabled. When this is the case, the constraints will be modified to disable the corresponding software effect in PeerConnection. The availability is controlled by a whitelist of device models in AudioManagerAndroid, which for AEC, currently consists of Nexus 5 and Nexus 7. AudioManagerAndroid will use the AudioRecord path iff the platform AEC is enabled. TESTED=Using apprtc on a N5 and N7 (whitelisted): - The AudioRecord input path is used. - The platform AEC is enabled and the software AEC (in PeerConnection) is disabled. - Calls have good echo cancellation quality. Using apprtc with ?audio=googEchoCancellation=false on a N5 and N7: - The OpenSLES input path is used. - Both the platform and software AEC are disabled. Using apprtc on Nexus 4 (non-whitelisted): - The OpenSLES input path is used. - The platform AEC is disabled and the software AEC is enabled. Using apprtc on Galaxy S2 (running ICS): - The OpenSLES input path is used. audio_android_unittest.cc passes on N5, N7 and Galaxy S2 TBR=jschuh Review URL: https://codereview.chromium.org/99033003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@240548 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/audio/android')
-rw-r--r--media/audio/android/audio_android_unittest.cc164
-rw-r--r--media/audio/android/audio_manager_android.cc31
-rw-r--r--media/audio/android/audio_manager_android.h2
-rw-r--r--media/audio/android/audio_record_input.cc3
-rw-r--r--media/audio/android/audio_record_input.h3
5 files changed, 137 insertions, 66 deletions
diff --git a/media/audio/android/audio_android_unittest.cc b/media/audio/android/audio_android_unittest.cc
index 300e154..e791326 100644
--- a/media/audio/android/audio_android_unittest.cc
+++ b/media/audio/android/audio_android_unittest.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/android/build_info.h"
#include "base/basictypes.h"
#include "base/file_util.h"
#include "base/memory/scoped_ptr.h"
@@ -95,7 +96,9 @@ std::ostream& operator<<(std::ostream& os, const AudioParameters& params) {
<< "bytes per buffer: " << params.GetBytesPerBuffer() << endl
<< "bytes per second: " << params.GetBytesPerSecond() << endl
<< "bytes per frame: " << params.GetBytesPerFrame() << endl
- << "frame size in ms: " << ExpectedTimeBetweenCallbacks(params);
+ << "chunk size in ms: " << ExpectedTimeBetweenCallbacks(params) << endl
+ << "echo_canceller: "
+ << (params.effects() & AudioParameters::ECHO_CANCELLER);
return os;
}
@@ -383,10 +386,10 @@ class FullDuplexAudioSinkSource
DISALLOW_COPY_AND_ASSIGN(FullDuplexAudioSinkSource);
};
-// Test fixture class.
-class AudioAndroidTest : public testing::Test {
+// Test fixture class for tests which only exercise the output path.
+class AudioAndroidOutputTest : public testing::Test {
public:
- AudioAndroidTest() {}
+ AudioAndroidOutputTest() {}
protected:
virtual void SetUp() {
@@ -399,11 +402,6 @@ class AudioAndroidTest : public testing::Test {
AudioManager* audio_manager() { return audio_manager_.get(); }
base::MessageLoopForUI* loop() { return loop_.get(); }
- AudioParameters GetDefaultInputStreamParameters() {
- return audio_manager()->GetInputStreamParameters(
- AudioManagerBase::kDefaultDeviceId);
- }
-
AudioParameters GetDefaultOutputStreamParameters() {
return audio_manager()->GetDefaultOutputStreamParameters();
}
@@ -413,28 +411,28 @@ class AudioAndroidTest : public testing::Test {
.InMillisecondsF();
}
- void StartInputStreamCallbacks(const AudioParameters& params) {
+ void StartOutputStreamCallbacks(const AudioParameters& params) {
double expected_time_between_callbacks_ms =
ExpectedTimeBetweenCallbacks(params);
const int num_callbacks =
(kCallbackTestTimeMs / expected_time_between_callbacks_ms);
- AudioInputStream* stream = audio_manager()->MakeAudioInputStream(
- params, AudioManagerBase::kDefaultDeviceId);
+ AudioOutputStream* stream = audio_manager()->MakeAudioOutputStream(
+ params, std::string(), std::string());
EXPECT_TRUE(stream);
int count = 0;
- MockAudioInputCallback sink;
+ MockAudioOutputCallback source;
- EXPECT_CALL(sink,
- OnData(stream, NotNull(), params.GetBytesPerBuffer(), _, _))
+ EXPECT_CALL(source, OnMoreData(NotNull(), _))
.Times(AtLeast(num_callbacks))
.WillRepeatedly(
- CheckCountAndPostQuitTask(&count, num_callbacks, loop()));
- EXPECT_CALL(sink, OnError(stream)).Times(0);
- EXPECT_CALL(sink, OnClose(stream)).Times(1);
+ DoAll(CheckCountAndPostQuitTask(&count, num_callbacks, loop()),
+ Invoke(&source, &MockAudioOutputCallback::RealOnMoreData)));
+ EXPECT_CALL(source, OnError(stream)).Times(0);
+ EXPECT_CALL(source, OnMoreIOData(_, _, _)).Times(0);
EXPECT_TRUE(stream->Open());
- stream->Start(&sink);
+ stream->Start(&source);
start_time_ = base::TimeTicks::Now();
loop()->Run();
end_time_ = base::TimeTicks::Now();
@@ -453,28 +451,73 @@ class AudioAndroidTest : public testing::Test {
1.30 * expected_time_between_callbacks_ms);
}
- void StartOutputStreamCallbacks(const AudioParameters& params) {
+ scoped_ptr<base::MessageLoopForUI> loop_;
+ scoped_ptr<AudioManager> audio_manager_;
+ base::TimeTicks start_time_;
+ base::TimeTicks end_time_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(AudioAndroidOutputTest);
+};
+
+// AudioRecordInputStream should only be created on Jelly Bean and higher. This
+// ensures we only test against the AudioRecord path when that is satisfied.
+std::vector<bool> RunAudioRecordInputPathTests() {
+ std::vector<bool> tests;
+ tests.push_back(false);
+ if (base::android::BuildInfo::GetInstance()->sdk_int() >= 16)
+ tests.push_back(true);
+ return tests;
+}
+
+// Test fixture class for tests which exercise the input path, or both input and
+// output paths. It is value-parameterized to test against both the Java
+// AudioRecord (when true) and native OpenSLES (when false) input paths.
+class AudioAndroidInputTest : public AudioAndroidOutputTest,
+ public testing::WithParamInterface<bool> {
+ public:
+ AudioAndroidInputTest() {}
+
+ protected:
+ AudioParameters GetInputStreamParameters() {
+ AudioParameters input_params = audio_manager()->GetInputStreamParameters(
+ AudioManagerBase::kDefaultDeviceId);
+ // Override the platform effects setting to use the AudioRecord or OpenSLES
+ // path as requested.
+ int effects = GetParam() ? AudioParameters::ECHO_CANCELLER :
+ AudioParameters::NO_EFFECTS;
+ AudioParameters params(input_params.format(),
+ input_params.channel_layout(),
+ input_params.input_channels(),
+ input_params.sample_rate(),
+ input_params.bits_per_sample(),
+ input_params.frames_per_buffer(),
+ effects);
+ return params;
+ }
+
+ void StartInputStreamCallbacks(const AudioParameters& params) {
double expected_time_between_callbacks_ms =
ExpectedTimeBetweenCallbacks(params);
const int num_callbacks =
(kCallbackTestTimeMs / expected_time_between_callbacks_ms);
- AudioOutputStream* stream = audio_manager()->MakeAudioOutputStream(
- params, std::string(), std::string());
+ AudioInputStream* stream = audio_manager()->MakeAudioInputStream(
+ params, AudioManagerBase::kDefaultDeviceId);
EXPECT_TRUE(stream);
int count = 0;
- MockAudioOutputCallback source;
+ MockAudioInputCallback sink;
- EXPECT_CALL(source, OnMoreData(NotNull(), _))
+ EXPECT_CALL(sink,
+ OnData(stream, NotNull(), params.GetBytesPerBuffer(), _, _))
.Times(AtLeast(num_callbacks))
.WillRepeatedly(
- DoAll(CheckCountAndPostQuitTask(&count, num_callbacks, loop()),
- Invoke(&source, &MockAudioOutputCallback::RealOnMoreData)));
- EXPECT_CALL(source, OnError(stream)).Times(0);
- EXPECT_CALL(source, OnMoreIOData(_, _, _)).Times(0);
+ CheckCountAndPostQuitTask(&count, num_callbacks, loop()));
+ EXPECT_CALL(sink, OnError(stream)).Times(0);
+ EXPECT_CALL(sink, OnClose(stream)).Times(1);
EXPECT_TRUE(stream->Open());
- stream->Start(&source);
+ stream->Start(&sink);
start_time_ = base::TimeTicks::Now();
loop()->Run();
end_time_ = base::TimeTicks::Now();
@@ -493,30 +536,30 @@ class AudioAndroidTest : public testing::Test {
1.30 * expected_time_between_callbacks_ms);
}
- scoped_ptr<base::MessageLoopForUI> loop_;
- scoped_ptr<AudioManager> audio_manager_;
- base::TimeTicks start_time_;
- base::TimeTicks end_time_;
- DISALLOW_COPY_AND_ASSIGN(AudioAndroidTest);
+ private:
+ DISALLOW_COPY_AND_ASSIGN(AudioAndroidInputTest);
};
// Get the default audio input parameters and log the result.
-TEST_F(AudioAndroidTest, GetInputStreamParameters) {
- AudioParameters params = GetDefaultInputStreamParameters();
+TEST_P(AudioAndroidInputTest, GetDefaultInputStreamParameters) {
+ // We don't go through AudioAndroidInputTest::GetInputStreamParameters() here
+ // so that we can log the real (non-overridden) values of the effects.
+ AudioParameters params = audio_manager()->GetInputStreamParameters(
+ AudioManagerBase::kDefaultDeviceId);
EXPECT_TRUE(params.IsValid());
VLOG(1) << params;
}
// Get the default audio output parameters and log the result.
-TEST_F(AudioAndroidTest, GetDefaultOutputStreamParameters) {
+TEST_F(AudioAndroidOutputTest, GetDefaultOutputStreamParameters) {
AudioParameters params = GetDefaultOutputStreamParameters();
EXPECT_TRUE(params.IsValid());
VLOG(1) << params;
}
// Check if low-latency output is supported and log the result as output.
-TEST_F(AudioAndroidTest, IsAudioLowLatencySupported) {
+TEST_F(AudioAndroidOutputTest, IsAudioLowLatencySupported) {
AudioManagerAndroid* manager =
static_cast<AudioManagerAndroid*>(audio_manager());
bool low_latency = manager->IsAudioLowLatencySupported();
@@ -525,8 +568,8 @@ TEST_F(AudioAndroidTest, IsAudioLowLatencySupported) {
}
// Ensure that a default input stream can be created and closed.
-TEST_F(AudioAndroidTest, CreateAndCloseInputStream) {
- AudioParameters params = GetDefaultInputStreamParameters();
+TEST_P(AudioAndroidInputTest, CreateAndCloseInputStream) {
+ AudioParameters params = GetInputStreamParameters();
AudioInputStream* ais = audio_manager()->MakeAudioInputStream(
params, AudioManagerBase::kDefaultDeviceId);
EXPECT_TRUE(ais);
@@ -537,7 +580,7 @@ TEST_F(AudioAndroidTest, CreateAndCloseInputStream) {
// TODO(henrika): should we also verify that this API changes the audio mode
// to communication mode, and calls RegisterHeadsetReceiver, the first time
// it is called?
-TEST_F(AudioAndroidTest, CreateAndCloseOutputStream) {
+TEST_F(AudioAndroidOutputTest, CreateAndCloseOutputStream) {
AudioParameters params = GetDefaultOutputStreamParameters();
AudioOutputStream* aos = audio_manager()->MakeAudioOutputStream(
params, std::string(), std::string());
@@ -546,8 +589,8 @@ TEST_F(AudioAndroidTest, CreateAndCloseOutputStream) {
}
// Ensure that a default input stream can be opened and closed.
-TEST_F(AudioAndroidTest, OpenAndCloseInputStream) {
- AudioParameters params = GetDefaultInputStreamParameters();
+TEST_P(AudioAndroidInputTest, OpenAndCloseInputStream) {
+ AudioParameters params = GetInputStreamParameters();
AudioInputStream* ais = audio_manager()->MakeAudioInputStream(
params, AudioManagerBase::kDefaultDeviceId);
EXPECT_TRUE(ais);
@@ -556,7 +599,7 @@ TEST_F(AudioAndroidTest, OpenAndCloseInputStream) {
}
// Ensure that a default output stream can be opened and closed.
-TEST_F(AudioAndroidTest, OpenAndCloseOutputStream) {
+TEST_F(AudioAndroidOutputTest, OpenAndCloseOutputStream) {
AudioParameters params = GetDefaultOutputStreamParameters();
AudioOutputStream* aos = audio_manager()->MakeAudioOutputStream(
params, std::string(), std::string());
@@ -567,8 +610,8 @@ TEST_F(AudioAndroidTest, OpenAndCloseOutputStream) {
// Start input streaming using default input parameters and ensure that the
// callback sequence is sane.
-TEST_F(AudioAndroidTest, StartInputStreamCallbacks) {
- AudioParameters params = GetDefaultInputStreamParameters();
+TEST_P(AudioAndroidInputTest, StartInputStreamCallbacks) {
+ AudioParameters params = GetInputStreamParameters();
StartInputStreamCallbacks(params);
}
@@ -576,19 +619,21 @@ TEST_F(AudioAndroidTest, StartInputStreamCallbacks) {
// callback sequence is sane. The only change we make in this test is to select
// a 10ms buffer size instead of the default size.
// TODO(henrika): possibly add support for more variations.
-TEST_F(AudioAndroidTest, StartInputStreamCallbacksNonDefaultParameters) {
- AudioParameters native_params = GetDefaultInputStreamParameters();
+TEST_P(AudioAndroidInputTest, StartInputStreamCallbacksNonDefaultParameters) {
+ AudioParameters native_params = GetInputStreamParameters();
AudioParameters params(native_params.format(),
native_params.channel_layout(),
+ native_params.input_channels(),
native_params.sample_rate(),
native_params.bits_per_sample(),
- native_params.sample_rate() / 100);
+ native_params.sample_rate() / 100,
+ native_params.effects());
StartInputStreamCallbacks(params);
}
// Start output streaming using default output parameters and ensure that the
// callback sequence is sane.
-TEST_F(AudioAndroidTest, StartOutputStreamCallbacks) {
+TEST_F(AudioAndroidOutputTest, StartOutputStreamCallbacks) {
AudioParameters params = GetDefaultOutputStreamParameters();
StartOutputStreamCallbacks(params);
}
@@ -598,7 +643,7 @@ TEST_F(AudioAndroidTest, StartOutputStreamCallbacks) {
// select a 10ms buffer size instead of the default size and to open up the
// device in mono.
// TODO(henrika): possibly add support for more variations.
-TEST_F(AudioAndroidTest, StartOutputStreamCallbacksNonDefaultParameters) {
+TEST_F(AudioAndroidOutputTest, StartOutputStreamCallbacksNonDefaultParameters) {
AudioParameters native_params = GetDefaultOutputStreamParameters();
AudioParameters params(native_params.format(),
CHANNEL_LAYOUT_MONO,
@@ -612,7 +657,7 @@ TEST_F(AudioAndroidTest, StartOutputStreamCallbacksNonDefaultParameters) {
// the rendered audio sounds OK.
// NOTE: this test requires user interaction and is not designed to run as an
// automatized test on bots.
-TEST_F(AudioAndroidTest, DISABLED_RunOutputStreamWithFileAsSource) {
+TEST_F(AudioAndroidOutputTest, DISABLED_RunOutputStreamWithFileAsSource) {
AudioParameters params = GetDefaultOutputStreamParameters();
VLOG(1) << params;
AudioOutputStream* aos = audio_manager()->MakeAudioOutputStream(
@@ -649,8 +694,8 @@ TEST_F(AudioAndroidTest, DISABLED_RunOutputStreamWithFileAsSource) {
// local audio file.
// NOTE: this test requires user interaction and is not designed to run as an
// automatized test on bots.
-TEST_F(AudioAndroidTest, DISABLED_RunSimplexInputStreamWithFileAsSink) {
- AudioParameters params = GetDefaultInputStreamParameters();
+TEST_P(AudioAndroidInputTest, DISABLED_RunSimplexInputStreamWithFileAsSink) {
+ AudioParameters params = GetInputStreamParameters();
VLOG(1) << params;
AudioInputStream* ais = audio_manager()->MakeAudioInputStream(
params, AudioManagerBase::kDefaultDeviceId);
@@ -676,8 +721,8 @@ TEST_F(AudioAndroidTest, DISABLED_RunSimplexInputStreamWithFileAsSink) {
// streaming is active as well (reads zeros only).
// NOTE: this test requires user interaction and is not designed to run as an
// automatized test on bots.
-TEST_F(AudioAndroidTest, DISABLED_RunDuplexInputStreamWithFileAsSink) {
- AudioParameters in_params = GetDefaultInputStreamParameters();
+TEST_P(AudioAndroidInputTest, DISABLED_RunDuplexInputStreamWithFileAsSink) {
+ AudioParameters in_params = GetInputStreamParameters();
AudioInputStream* ais = audio_manager()->MakeAudioInputStream(
in_params, AudioManagerBase::kDefaultDeviceId);
EXPECT_TRUE(ais);
@@ -720,10 +765,10 @@ TEST_F(AudioAndroidTest, DISABLED_RunDuplexInputStreamWithFileAsSink) {
// printed out during the test.
// NOTE: this test requires user interaction and is not designed to run as an
// automatized test on bots.
-TEST_F(AudioAndroidTest,
+TEST_P(AudioAndroidInputTest,
DISABLED_RunSymmetricInputAndOutputStreamsInFullDuplex) {
// Get native audio parameters for the input side.
- AudioParameters default_input_params = GetDefaultInputStreamParameters();
+ AudioParameters default_input_params = GetInputStreamParameters();
// Modify the parameters so that both input and output can use the same
// parameters by selecting 10ms as buffer size. This will also ensure that
@@ -766,4 +811,7 @@ TEST_F(AudioAndroidTest,
ais->Close();
}
+INSTANTIATE_TEST_CASE_P(AudioAndroidInputTest, AudioAndroidInputTest,
+ testing::ValuesIn(RunAudioRecordInputPathTests()));
+
} // namespace media
diff --git a/media/audio/android/audio_manager_android.cc b/media/audio/android/audio_manager_android.cc
index b588768..3464d89 100644
--- a/media/audio/android/audio_manager_android.cc
+++ b/media/audio/android/audio_manager_android.cc
@@ -11,6 +11,7 @@
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "jni/AudioManagerAndroid_jni.h"
+#include "media/audio/android/audio_record_input.h"
#include "media/audio/android/opensles_input.h"
#include "media/audio/android/opensles_output.h"
#include "media/audio/audio_manager.h"
@@ -103,18 +104,22 @@ void AudioManagerAndroid::GetAudioOutputDeviceNames(
AudioParameters AudioManagerAndroid::GetInputStreamParameters(
const std::string& device_id) {
+ JNIEnv* env = AttachCurrentThread();
// Use mono as preferred number of input channels on Android to save
// resources. Using mono also avoids a driver issue seen on Samsung
// Galaxy S3 and S4 devices. See http://crbug.com/256851 for details.
ChannelLayout channel_layout = CHANNEL_LAYOUT_MONO;
int buffer_size = Java_AudioManagerAndroid_getMinInputFrameSize(
- base::android::AttachCurrentThread(), GetNativeOutputSampleRate(),
+ env, GetNativeOutputSampleRate(),
ChannelLayoutToChannelCount(channel_layout));
-
- return AudioParameters(
- AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout,
+ int effects = AudioParameters::NO_EFFECTS;
+ effects |= Java_AudioManagerAndroid_shouldUseAcousticEchoCanceler(env) ?
+ AudioParameters::ECHO_CANCELLER : AudioParameters::NO_EFFECTS;
+ AudioParameters params(
+ AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, 0,
GetNativeOutputSampleRate(), 16,
- buffer_size <= 0 ? kDefaultInputBufferSize : buffer_size);
+ buffer_size <= 0 ? kDefaultInputBufferSize : buffer_size, effects);
+ return params;
}
AudioOutputStream* AudioManagerAndroid::MakeAudioOutputStream(
@@ -189,6 +194,20 @@ AudioInputStream* AudioManagerAndroid::MakeLowLatencyInputStream(
// device, i.e., this selection does also switch the output device.
// All input and output streams will be affected by the device selection.
SetAudioDevice(device_id);
+
+ if (params.effects() != AudioParameters::NO_EFFECTS) {
+ // Platform effects can only be enabled through the AudioRecord path.
+ // An effect should only have been requested here if recommended by
+ // AudioManagerAndroid.shouldUse<Effect>.
+ //
+ // Creating this class requires Jelly Bean, which is already guaranteed by
+ // shouldUse<Effect>. Only DCHECK on that condition to allow tests to use
+ // the effect settings as a way to select the input path.
+ DCHECK_GE(base::android::BuildInfo::GetInstance()->sdk_int(), 16);
+ DVLOG(1) << "Creating AudioRecordInputStream";
+ return new AudioRecordInputStream(this, params);
+ }
+ DVLOG(1) << "Creating OpenSLESInputStream";
return new OpenSLESInputStream(this, params);
}
@@ -230,7 +249,7 @@ AudioParameters AudioManagerAndroid::GetPreferredOutputStreamParameters(
return AudioParameters(
AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, input_channels,
- sample_rate, bits_per_sample, buffer_size);
+ sample_rate, bits_per_sample, buffer_size, AudioParameters::NO_EFFECTS);
}
// static
diff --git a/media/audio/android/audio_manager_android.h b/media/audio/android/audio_manager_android.h
index d9744ff..2900c0f 100644
--- a/media/audio/android/audio_manager_android.h
+++ b/media/audio/android/audio_manager_android.h
@@ -79,7 +79,7 @@ class MEDIA_EXPORT AudioManagerAndroid : public AudioManagerBase {
void DoSetMuteOnAudioThread(bool muted);
// Allow the AudioAndroidTest to access private methods.
- FRIEND_TEST_ALL_PREFIXES(AudioAndroidTest, IsAudioLowLatencySupported);
+ FRIEND_TEST_ALL_PREFIXES(AudioAndroidOutputTest, IsAudioLowLatencySupported);
// Java AudioManager instance.
base::android::ScopedJavaGlobalRef<jobject> j_audio_manager_;
diff --git a/media/audio/android/audio_record_input.cc b/media/audio/android/audio_record_input.cc
index 51c436f..15a0c3d 100644
--- a/media/audio/android/audio_record_input.cc
+++ b/media/audio/android/audio_record_input.cc
@@ -24,7 +24,8 @@ AudioRecordInputStream::AudioRecordInputStream(
params.sample_rate(),
params.channels(),
params.bits_per_sample(),
- params.GetBytesPerBuffer()));
+ params.GetBytesPerBuffer(),
+ params.effects() & AudioParameters::ECHO_CANCELLER));
}
AudioRecordInputStream::~AudioRecordInputStream() {
diff --git a/media/audio/android/audio_record_input.h b/media/audio/android/audio_record_input.h
index 3a95d51..0a2578b 100644
--- a/media/audio/android/audio_record_input.h
+++ b/media/audio/android/audio_record_input.h
@@ -19,6 +19,9 @@ class AudioManagerAndroid;
// AudioRecordInput.java. This class is created and lives on the Audio Manager
// thread but recorded audio buffers are delivered on a thread managed by
// the Java class.
+//
+// The Java class makes use of AudioEffect features which are first available
+// in Jelly Bean. It should not be instantiated running against earlier SDKs.
class MEDIA_EXPORT AudioRecordInputStream : public AudioInputStream {
public:
AudioRecordInputStream(AudioManagerAndroid* manager,