Skip to content

Commit

Permalink
Add an optional override for AudioRecord device
Browse files Browse the repository at this point in the history
This is important when we have multiple named devices connected over
USB (eg. "Webcam", "Microphone", "Headset") and there is some way to
choose a specific input device to route from.

Bug: b/154440591
Change-Id: I8dc1801a5e4db7f7bb439e855d43897c1f7d8bc4
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/173748
Commit-Queue: Robin Lee <rgl@google.com>
Reviewed-by: Sami Kalliomäki <sakal@webrtc.org>
Reviewed-by: Henrik Andreassson <henrika@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#31130}
  • Loading branch information
hex539 authored and Commit Bot committed Apr 24, 2020
1 parent c8660b1 commit 1b8ef63
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 1 deletion.
17 changes: 16 additions & 1 deletion sdk/android/api/org/webrtc/audio/JavaAudioDeviceModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@

package org.webrtc.audio;

import android.media.AudioManager;
import android.content.Context;
import android.media.AudioDeviceInfo;
import android.media.AudioManager;
import android.os.Build;
import android.support.annotation.RequiresApi;
import org.webrtc.JniCommon;
import org.webrtc.Logging;

Expand Down Expand Up @@ -369,6 +372,18 @@ public void setMicrophoneMute(boolean mute) {
audioInput.setMicrophoneMute(mute);
}

/**
* Start to prefer a specific {@link AudioDeviceInfo} device for recording. Typically this should
* only be used if a client gives an explicit option for choosing a physical device to record
* from. Otherwise the best-matching device for other parameters will be used. Calling after
* recording is started may cause a temporary interruption if the audio routing changes.
*/
@RequiresApi(Build.VERSION_CODES.M)
public void setPreferredInputDevice(AudioDeviceInfo preferredInputDevice) {
Logging.d(TAG, "setPreferredInputDevice: " + preferredInputDevice);
audioInput.setPreferredDevice(preferredInputDevice);
}

private static native long nativeCreateAudioDeviceModule(Context context,
AudioManager audioManager, WebRtcAudioRecord audioInput, WebRtcAudioTrack audioOutput,
int inputSampleRate, int outputSampleRate, boolean useStereoInput, boolean useStereoOutput);
Expand Down
22 changes: 22 additions & 0 deletions sdk/android/src/java/org/webrtc/audio/WebRtcAudioRecord.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import android.os.Build;
import android.os.Process;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import java.lang.System;
import java.nio.ByteBuffer;
import java.util.Arrays;
Expand Down Expand Up @@ -87,6 +88,7 @@ class WebRtcAudioRecord {

private @Nullable AudioRecord audioRecord;
private @Nullable AudioRecordThread audioThread;
private @Nullable AudioDeviceInfo preferredDevice;

private @Nullable ScheduledExecutorService executor;
private @Nullable ScheduledFuture<String> future;
Expand Down Expand Up @@ -296,6 +298,9 @@ private int initRecording(int sampleRate, int channels) {
// Throws IllegalArgumentException.
audioRecord = createAudioRecordOnMOrHigher(
audioSource, sampleRate, channelConfig, audioFormat, bufferSizeInBytes);
if (preferredDevice != null) {
setPreferredDevice(preferredDevice);
}
} else {
// Use the old AudioRecord constructor for API levels below 23.
// Throws UnsupportedOperationException.
Expand Down Expand Up @@ -329,6 +334,23 @@ private int initRecording(int sampleRate, int channels) {
return framesPerBuffer;
}

/**
* Prefer a specific {@link AudioDeviceInfo} device for recording. Calling after recording starts
* is valid but may cause a temporary interruption if the audio routing changes.
*/
@RequiresApi(Build.VERSION_CODES.M)
@TargetApi(Build.VERSION_CODES.M)
void setPreferredDevice(@Nullable AudioDeviceInfo preferredDevice) {
Logging.d(
TAG, "setPreferredDevice " + (preferredDevice != null ? preferredDevice.getId() : null));
this.preferredDevice = preferredDevice;
if (audioRecord != null) {
if (!audioRecord.setPreferredDevice(preferredDevice)) {
Logging.e(TAG, "setPreferredDevice failed");
}
}
}

@CalledByNative
private boolean startRecording() {
Logging.d(TAG, "startRecording");
Expand Down

0 comments on commit 1b8ef63

Please sign in to comment.