Index: webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioRecord.java |
diff --git a/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioRecord.java b/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioRecord.java |
index 21e43c86f33e714f29c8afb2265d2e51daab3ce8..a55966d1397aaf022af8a1c9bfbe36ff60e0fe06 100644 |
--- a/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioRecord.java |
+++ b/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioRecord.java |
@@ -16,9 +16,6 @@ import java.util.concurrent.TimeUnit; |
import android.content.Context; |
import android.media.AudioFormat; |
-import android.media.audiofx.AcousticEchoCanceler; |
-import android.media.audiofx.AudioEffect; |
-import android.media.audiofx.AudioEffect.Descriptor; |
import android.media.AudioRecord; |
import android.media.MediaRecorder.AudioSource; |
import android.os.Build; |
@@ -45,14 +42,13 @@ class WebRtcAudioRecord { |
private final long nativeAudioRecord; |
private final Context context; |
+ private WebRtcAudioEffects effects = null; |
+ |
private ByteBuffer byteBuffer; |
private AudioRecord audioRecord = null; |
private AudioRecordThread audioThread = null; |
- private AcousticEchoCanceler aec = null; |
- private boolean useBuiltInAEC = false; |
- |
/** |
* Audio thread which keeps calling ByteBuffer.read() waiting for audio |
* to be recorded. Feeds recorded data to the native counterpart as a |
@@ -69,7 +65,7 @@ class WebRtcAudioRecord { |
@Override |
public void run() { |
Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_AUDIO); |
- Logd("AudioRecordThread" + WebRtcAudioUtils.getThreadInfo()); |
+ Logging.w(TAG, "AudioRecordThread" + WebRtcAudioUtils.getThreadInfo()); |
assertTrue(audioRecord.getRecordingState() |
== AudioRecord.RECORDSTATE_RECORDING); |
@@ -79,7 +75,7 @@ class WebRtcAudioRecord { |
if (bytesRead == byteBuffer.capacity()) { |
nativeDataIsRecorded(bytesRead, nativeAudioRecord); |
} else { |
- Loge("AudioRecord.read failed: " + bytesRead); |
+ Logging.e(TAG,"AudioRecord.read failed: " + bytesRead); |
if (bytesRead == AudioRecord.ERROR_INVALID_OPERATION) { |
keepAlive = false; |
} |
@@ -89,14 +85,14 @@ class WebRtcAudioRecord { |
long durationInMs = |
TimeUnit.NANOSECONDS.toMillis((nowTime - lastTime)); |
lastTime = nowTime; |
- Logd("bytesRead[" + durationInMs + "] " + bytesRead); |
+ Logging.w(TAG, "bytesRead[" + durationInMs + "] " + bytesRead); |
} |
} |
try { |
audioRecord.stop(); |
} catch (IllegalStateException e) { |
- Loge("AudioRecord.stop failed: " + e.getMessage()); |
+ Logging.e(TAG,"AudioRecord.stop failed: " + e.getMessage()); |
} |
} |
@@ -113,47 +109,58 @@ class WebRtcAudioRecord { |
} |
WebRtcAudioRecord(Context context, long nativeAudioRecord) { |
- Logd("ctor" + WebRtcAudioUtils.getThreadInfo()); |
+ Logging.w(TAG, "ctor" + WebRtcAudioUtils.getThreadInfo()); |
this.context = context; |
this.nativeAudioRecord = nativeAudioRecord; |
if (DEBUG) { |
WebRtcAudioUtils.logDeviceInfo(TAG); |
} |
+ effects = WebRtcAudioEffects.create(); |
} |
- private boolean EnableBuiltInAEC(boolean enable) { |
- Logd("EnableBuiltInAEC(" + enable + ')'); |
- assertTrue(WebRtcAudioUtils.isAcousticEchoCancelerApproved()); |
- // Store the AEC state. |
- useBuiltInAEC = enable; |
- // Set AEC state if AEC has already been created. |
- if (aec != null) { |
- int ret = aec.setEnabled(enable); |
- if (ret != AudioEffect.SUCCESS) { |
- Loge("AcousticEchoCanceler.setEnabled failed"); |
- return false; |
- } |
- Logd("AcousticEchoCanceler.getEnabled: " + aec.getEnabled()); |
+ private boolean enableBuiltInAEC(boolean enable) { |
+ Logging.w(TAG, "enableBuiltInAEC(" + enable + ')'); |
+ if (effects == null) { |
+ Logging.e(TAG,"Built-in AEC is not supported on this platform"); |
+ return false; |
} |
- return true; |
+ return effects.setAEC(enable); |
+ } |
+ |
+ private boolean enableBuiltInAGC(boolean enable) { |
+ Logging.w(TAG, "enableBuiltInAGC(" + enable + ')'); |
+ if (effects == null) { |
+ Logging.e(TAG,"Built-in AGC is not supported on this platform"); |
+ return false; |
+ } |
+ return effects.setAGC(enable); |
+ } |
+ |
+ private boolean enableBuiltInNS(boolean enable) { |
+ Logging.w(TAG, "enableBuiltInNS(" + enable + ')'); |
+ if (effects == null) { |
+ Logging.e(TAG,"Built-in NS is not supported on this platform"); |
+ return false; |
+ } |
+ return effects.setNS(enable); |
} |
- private int InitRecording(int sampleRate, int channels) { |
- Logd("InitRecording(sampleRate=" + sampleRate + ", channels=" + |
+ private int initRecording(int sampleRate, int channels) { |
+ Logging.w(TAG, "initRecording(sampleRate=" + sampleRate + ", channels=" + |
channels + ")"); |
if (!WebRtcAudioUtils.hasPermission( |
context, android.Manifest.permission.RECORD_AUDIO)) { |
- Loge("RECORD_AUDIO permission is missing"); |
+ Logging.e(TAG,"RECORD_AUDIO permission is missing"); |
return -1; |
} |
if (audioRecord != null) { |
- Loge("InitRecording() called twice without StopRecording()"); |
+ Logging.e(TAG,"InitRecording() called twice without StopRecording()"); |
return -1; |
} |
final int bytesPerFrame = channels * (BITS_PER_SAMPLE / 8); |
final int framesPerBuffer = sampleRate / BUFFERS_PER_SECOND; |
byteBuffer = ByteBuffer.allocateDirect(bytesPerFrame * framesPerBuffer); |
- Logd("byteBuffer.capacity: " + byteBuffer.capacity()); |
+ Logging.w(TAG, "byteBuffer.capacity: " + byteBuffer.capacity()); |
// Rather than passing the ByteBuffer with every callback (requiring |
// the potentially expensive GetDirectBufferAddress) we simply have the |
// the native class cache the address to the memory once. |
@@ -167,11 +174,11 @@ class WebRtcAudioRecord { |
sampleRate, |
AudioFormat.CHANNEL_IN_MONO, |
AudioFormat.ENCODING_PCM_16BIT); |
- Logd("AudioRecord.getMinBufferSize: " + minBufferSize); |
+ Logging.w(TAG, "AudioRecord.getMinBufferSize: " + minBufferSize); |
int bufferSizeInBytes = Math.max(byteBuffer.capacity(), minBufferSize); |
- Logd("bufferSizeInBytes: " + bufferSizeInBytes); |
+ Logging.w(TAG, "bufferSizeInBytes: " + bufferSizeInBytes); |
try { |
audioRecord = new AudioRecord(AudioSource.VOICE_COMMUNICATION, |
sampleRate, |
@@ -180,63 +187,37 @@ class WebRtcAudioRecord { |
bufferSizeInBytes); |
} catch (IllegalArgumentException e) { |
- Loge(e.getMessage()); |
+ Logging.e(TAG,e.getMessage()); |
return -1; |
} |
if (audioRecord == null || |
audioRecord.getState() != AudioRecord.STATE_INITIALIZED) { |
- Loge("Failed to create a new AudioRecord instance"); |
+ Logging.e(TAG,"Failed to create a new AudioRecord instance"); |
return -1; |
} |
- |
- Logd("AudioRecord " + |
- "session ID: " + audioRecord.getAudioSessionId() + ", " + |
- "audio format: " + audioRecord.getAudioFormat() + ", " + |
- "channels: " + audioRecord.getChannelCount() + ", " + |
- "sample rate: " + audioRecord.getSampleRate()); |
- Logd("AcousticEchoCanceler.isAvailable: " + builtInAECIsAvailable()); |
- if (!builtInAECIsAvailable()) { |
- return framesPerBuffer; |
- } |
- if (WebRtcAudioUtils.deviceIsBlacklistedForHwAecUsage()) { |
- // Just in case, ensure that no attempt has been done to enable the |
- // HW AEC on a blacklisted device. |
- assertTrue(!useBuiltInAEC); |
- } |
- // We create an AEC also for blacklisted devices since it is possible that |
- // HW EAC is enabled by default. Hence, the AEC object is needed to be |
- // able to check the current state and to disable the AEC if enabled. |
- aec = AcousticEchoCanceler.create(audioRecord.getAudioSessionId()); |
- if (aec == null) { |
- Loge("AcousticEchoCanceler.create failed"); |
- return -1; |
- } |
- int ret = aec.setEnabled(useBuiltInAEC); |
- if (ret != AudioEffect.SUCCESS) { |
- Loge("AcousticEchoCanceler.setEnabled failed"); |
- return -1; |
+ Logging.w(TAG, "AudioRecord " |
+ + "session ID: " + audioRecord.getAudioSessionId() + ", " |
+ + "audio format: " + audioRecord.getAudioFormat() + ", " |
+ + "channels: " + audioRecord.getChannelCount() + ", " |
+ + "sample rate: " + audioRecord.getSampleRate()); |
+ if (effects != null) { |
+ effects.enable(audioRecord.getAudioSessionId()); |
} |
- Descriptor descriptor = aec.getDescriptor(); |
- Logd("AcousticEchoCanceler " + |
- "name: " + descriptor.name + ", " + |
- "implementor: " + descriptor.implementor + ", " + |
- "uuid: " + descriptor.uuid); |
- Logd("AcousticEchoCanceler.getEnabled: " + aec.getEnabled()); |
return framesPerBuffer; |
} |
- private boolean StartRecording() { |
- Logd("StartRecording"); |
+ private boolean startRecording() { |
+ Logging.w(TAG, "startRecording"); |
assertTrue(audioRecord != null); |
assertTrue(audioThread == null); |
try { |
audioRecord.startRecording(); |
} catch (IllegalStateException e) { |
- Loge("AudioRecord.startRecording failed: " + e.getMessage()); |
+ Logging.e(TAG,"AudioRecord.startRecording failed: " + e.getMessage()); |
return false; |
} |
if (audioRecord.getRecordingState() != AudioRecord.RECORDSTATE_RECORDING) { |
- Loge("AudioRecord.startRecording failed"); |
+ Logging.e(TAG,"AudioRecord.startRecording failed"); |
return false; |
} |
audioThread = new AudioRecordThread("AudioRecordJavaThread"); |
@@ -244,26 +225,19 @@ class WebRtcAudioRecord { |
return true; |
} |
- private boolean StopRecording() { |
- Logd("StopRecording"); |
+ private boolean stopRecording() { |
+ Logging.w(TAG, "stopRecording"); |
assertTrue(audioThread != null); |
audioThread.joinThread(); |
audioThread = null; |
- if (aec != null) { |
- aec.release(); |
- aec = null; |
+ if (effects != null) { |
+ effects.release(); |
} |
audioRecord.release(); |
audioRecord = null; |
return true; |
} |
- // Returns true if built-in AEC is available. Does not take blacklisting |
- // into account. |
- private static boolean builtInAECIsAvailable() { |
- return WebRtcAudioUtils.isAcousticEchoCancelerSupported(); |
- } |
- |
// Helper method which throws an exception when an assertion has failed. |
private static void assertTrue(boolean condition) { |
if (!condition) { |
@@ -271,14 +245,6 @@ class WebRtcAudioRecord { |
} |
} |
- private static void Logd(String msg) { |
- Logging.d(TAG, msg); |
- } |
- |
- private static void Loge(String msg) { |
- Logging.e(TAG, msg); |
- } |
- |
private native void nativeCacheDirectBufferAddress( |
ByteBuffer byteBuffer, long nativeAudioRecord); |