Stability improvement for audio recording on Android

BUG=NONE
R=magjed@webrtc.org

Review URL: https://codereview.webrtc.org/1363323002 .

Cr-Commit-Position: refs/heads/master@{#10056}
This commit is contained in:
henrika
2015-09-24 16:45:05 +02:00
parent 2bc68c731d
commit 8a88dd271e
3 changed files with 32 additions and 10 deletions

View File

@ -295,8 +295,7 @@ class WebRtcAudioEffects {
Logging.d(TAG, "AcousticEchoCanceler: was "
+ (enabled ? "enabled" : "disabled")
+ ", enable: " + enable + ", is now: "
+ (aec.getEnabled() ? "enabled" : "disabled")
+ ", has control: " + aec.hasControl());
+ (aec.getEnabled() ? "enabled" : "disabled"));
} else {
Logging.e(TAG, "Failed to create the AcousticEchoCanceler instance");
}
@ -315,8 +314,7 @@ class WebRtcAudioEffects {
Logging.d(TAG, "AutomaticGainControl: was "
+ (enabled ? "enabled" : "disabled")
+ ", enable: " + enable + ", is now: "
+ (agc.getEnabled() ? "enabled" : "disabled")
+ ", has control: " + agc.hasControl());
+ (agc.getEnabled() ? "enabled" : "disabled"));
} else {
Logging.e(TAG, "Failed to create the AutomaticGainControl instance");
}
@ -335,8 +333,7 @@ class WebRtcAudioEffects {
Logging.d(TAG, "NoiseSuppressor: was "
+ (enabled ? "enabled" : "disabled")
+ ", enable: " + enable + ", is now: "
+ (ns.getEnabled() ? "enabled" : "disabled")
+ ", has control: " + ns.hasControl());
+ (ns.getEnabled() ? "enabled" : "disabled"));
} else {
Logging.e(TAG, "Failed to create the NoiseSuppressor instance");
}

View File

@ -39,6 +39,11 @@ class WebRtcAudioRecord {
// Average number of callbacks per second.
private static final int BUFFERS_PER_SECOND = 1000 / CALLBACK_BUFFER_SIZE_MS;
// We ask for a native buffer size of BUFFER_SIZE_FACTOR * (minimum required
// buffer size). The extra space is allocated to guard against glitches under
// high load.
private static final int BUFFER_SIZE_FACTOR = 2;
private final long nativeAudioRecord;
private final Context context;
@ -169,15 +174,22 @@ class WebRtcAudioRecord {
// Get the minimum buffer size required for the successful creation of
// an AudioRecord object, in byte units.
// Note that this size doesn't guarantee a smooth recording under load.
// TODO(henrika): Do we need to make this larger to avoid underruns?
int minBufferSize = AudioRecord.getMinBufferSize(
sampleRate,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT);
if (minBufferSize == AudioRecord.ERROR
|| minBufferSize == AudioRecord.ERROR_BAD_VALUE) {
Logging.e(TAG, "AudioRecord.getMinBufferSize failed: " + minBufferSize);
return -1;
}
Logging.w(TAG, "AudioRecord.getMinBufferSize: " + minBufferSize);
int bufferSizeInBytes = Math.max(byteBuffer.capacity(), minBufferSize);
// Use a larger buffer size than the minimum required when creating the
// AudioRecord instance to ensure smooth recording under load. It has been
// verified that it does not increase the actual recording latency.
int bufferSizeInBytes =
Math.max(BUFFER_SIZE_FACTOR * minBufferSize, byteBuffer.capacity());
Logging.w(TAG, "bufferSizeInBytes: " + bufferSizeInBytes);
try {
audioRecord = new AudioRecord(AudioSource.VOICE_COMMUNICATION,
@ -185,7 +197,6 @@ class WebRtcAudioRecord {
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT,
bufferSizeInBytes);
} catch (IllegalArgumentException e) {
Logging.e(TAG,e.getMessage());
return -1;
@ -203,6 +214,15 @@ class WebRtcAudioRecord {
if (effects != null) {
effects.enable(audioRecord.getAudioSessionId());
}
if (WebRtcAudioUtils.runningOnMOrHigher()) {
// Returns the frame count of the native AudioRecord buffer. This is
// greater than or equal to the bufferSizeInBytes converted to frame
// units. The native frame count may be enlarged to accommodate the
// requirements of the source on creation or if the AudioRecord is
// subsequently rerouted.
Logging.d(TAG, "bufferSizeInFrames: "
+ audioRecord.getBufferSizeInFrames());
}
return framesPerBuffer;
}

View File

@ -148,6 +148,11 @@ public final class WebRtcAudioUtils {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
}
public static boolean runningOnMOrHigher() {
// API Level 23.
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
}
// Helper method for building a string of thread information.
public static String getThreadInfo() {
return "@[name=" + Thread.currentThread().getName()