diff --git a/webrtc/modules/audio_device/android/audio_manager.cc b/webrtc/modules/audio_device/android/audio_manager.cc index 01e5d5fe4f..d7108dca48 100644 --- a/webrtc/modules/audio_device/android/audio_manager.cc +++ b/webrtc/modules/audio_device/android/audio_manager.cc @@ -78,7 +78,7 @@ AudioManager::AudioManager() RTC_CHECK(j_environment_); JNINativeMethod native_methods[] = { {"nativeCacheAudioParameters", - "(IIZZZZIIJ)V", + "(IIZZZZZIIJ)V", reinterpret_cast(&webrtc::AudioManager::CacheAudioParameters)}}; j_native_registration_ = j_environment_->RegisterNatives( "org/webrtc/voiceengine/WebRtcAudioManager", native_methods, @@ -167,6 +167,15 @@ bool AudioManager::IsLowLatencyPlayoutSupported() const { false : low_latency_playout_; } +bool AudioManager::IsProAudioSupported() const { + RTC_DCHECK(thread_checker_.CalledOnValidThread()); + ALOGD("IsProAudioSupported()"); + // TODO(henrika): return the state independently of if OpenSL ES is + // blacklisted or not for now. We could use the same approach as in + // IsLowLatencyPlayoutSupported() but I can't see the need for it yet. + return pro_audio_; +} + int AudioManager::GetDelayEstimateInMilliseconds() const { return delay_estimate_in_milliseconds_; } @@ -179,6 +188,7 @@ void JNICALL AudioManager::CacheAudioParameters(JNIEnv* env, jboolean hardware_agc, jboolean hardware_ns, jboolean low_latency_output, + jboolean pro_audio, jint output_buffer_size, jint input_buffer_size, jlong native_audio_manager) { @@ -186,7 +196,7 @@ void JNICALL AudioManager::CacheAudioParameters(JNIEnv* env, reinterpret_cast(native_audio_manager); this_object->OnCacheAudioParameters( env, sample_rate, channels, hardware_aec, hardware_agc, hardware_ns, - low_latency_output, output_buffer_size, input_buffer_size); + low_latency_output, pro_audio, output_buffer_size, input_buffer_size); } void AudioManager::OnCacheAudioParameters(JNIEnv* env, @@ -196,6 +206,7 @@ void AudioManager::OnCacheAudioParameters(JNIEnv* env, jboolean hardware_agc, jboolean hardware_ns, jboolean low_latency_output, + jboolean pro_audio, jint output_buffer_size, jint input_buffer_size) { ALOGD("OnCacheAudioParameters%s", GetThreadInfo().c_str()); @@ -203,6 +214,7 @@ void AudioManager::OnCacheAudioParameters(JNIEnv* env, ALOGD("hardware_agc: %d", hardware_agc); ALOGD("hardware_ns: %d", hardware_ns); ALOGD("low_latency_output: %d", low_latency_output); + ALOGD("pro_audio: %d", pro_audio); ALOGD("sample_rate: %d", sample_rate); ALOGD("channels: %d", channels); ALOGD("output_buffer_size: %d", output_buffer_size); @@ -212,6 +224,7 @@ void AudioManager::OnCacheAudioParameters(JNIEnv* env, hardware_agc_ = hardware_agc; hardware_ns_ = hardware_ns; low_latency_playout_ = low_latency_output; + pro_audio_ = pro_audio; // TODO(henrika): add support for stereo output. playout_parameters_.reset(sample_rate, static_cast(channels), static_cast(output_buffer_size)); diff --git a/webrtc/modules/audio_device/android/audio_manager.h b/webrtc/modules/audio_device/android/audio_manager.h index b4264a6f8c..aa51d092d0 100644 --- a/webrtc/modules/audio_device/android/audio_manager.h +++ b/webrtc/modules/audio_device/android/audio_manager.h @@ -88,6 +88,10 @@ class AudioManager { // combination with OpenSL ES. bool IsLowLatencyPlayoutSupported() const; + // Returns true if the device supports pro-audio features in combination with + // OpenSL ES. + bool IsProAudioSupported() const; + // Returns the estimated total delay of this device. Unit is in milliseconds. // The vaule is set once at construction and never changes after that. // Possible values are webrtc::kLowLatencyModeDelayEstimateInMilliseconds and @@ -106,6 +110,7 @@ class AudioManager { jboolean hardware_agc, jboolean hardware_ns, jboolean low_latency_output, + jboolean pro_audio, jint output_buffer_size, jint input_buffer_size, jlong native_audio_manager); @@ -116,6 +121,7 @@ class AudioManager { jboolean hardware_agc, jboolean hardware_ns, jboolean low_latency_output, + jboolean pro_audio, jint output_buffer_size, jint input_buffer_size); @@ -152,6 +158,9 @@ class AudioManager { // True if device supports the low-latency OpenSL ES audio path. bool low_latency_playout_; + // True if device supports the low-latency OpenSL ES pro-audio path. + bool pro_audio_; + // The delay estimate can take one of two fixed values depending on if the // device supports low-latency output or not. int delay_estimate_in_milliseconds_; diff --git a/webrtc/modules/audio_device/android/audio_manager_unittest.cc b/webrtc/modules/audio_device/android/audio_manager_unittest.cc index d1107e05fd..3abfc5a8ce 100644 --- a/webrtc/modules/audio_device/android/audio_manager_unittest.cc +++ b/webrtc/modules/audio_device/android/audio_manager_unittest.cc @@ -77,6 +77,11 @@ TEST_F(AudioManagerTest, IsLowLatencyPlayoutSupported) { audio_manager()->IsLowLatencyPlayoutSupported() ? "Yes" : "No"); } +TEST_F(AudioManagerTest, IsProAudioSupported) { + PRINT("%sPro audio support: %s\n", kTag, + audio_manager()->IsProAudioSupported() ? "Yes" : "No"); +} + TEST_F(AudioManagerTest, ShowAudioParameterInfo) { const bool low_latency_out = audio_manager()->IsLowLatencyPlayoutSupported(); PRINT("PLAYOUT:\n"); diff --git a/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioManager.java b/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioManager.java index 1213f333d9..497e234bf0 100644 --- a/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioManager.java +++ b/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioManager.java @@ -81,6 +81,7 @@ public class WebRtcAudioManager { private boolean hardwareAGC; private boolean hardwareNS; private boolean lowLatencyOutput; + private boolean proAudio; private int sampleRate; private int channels; private int outputBufferSize; @@ -98,7 +99,7 @@ public class WebRtcAudioManager { storeAudioParameters(); nativeCacheAudioParameters( sampleRate, channels, hardwareAEC, hardwareAGC, hardwareNS, - lowLatencyOutput, outputBufferSize, inputBufferSize, + lowLatencyOutput, proAudio, outputBufferSize, inputBufferSize, nativeAudioManager); } @@ -142,6 +143,7 @@ public class WebRtcAudioManager { hardwareAGC = isAutomaticGainControlSupported(); hardwareNS = isNoiseSuppressorSupported(); lowLatencyOutput = isLowLatencyOutputSupported(); + proAudio = isProAudioSupported(); outputBufferSize = lowLatencyOutput ? getLowLatencyOutputFramesPerBuffer() : getMinOutputFrameSize(sampleRate, channels); @@ -168,8 +170,16 @@ public class WebRtcAudioManager { // as well. The NDK doc states that: "As of API level 21, lower latency // audio input is supported on select devices. To take advantage of this // feature, first confirm that lower latency output is available". - return WebRtcAudioUtils.runningOnLollipopOrHigher() && - isLowLatencyOutputSupported(); + return WebRtcAudioUtils.runningOnLollipopOrHigher() + && isLowLatencyOutputSupported(); + } + + // Returns true if the device has professional audio level of functionality + // and therefore supports the lowest possible round-trip latency. + private boolean isProAudioSupported() { + return WebRtcAudioUtils.runningOnMarshmallowOrHigher() + && context.getPackageManager().hasSystemFeature( + PackageManager.FEATURE_AUDIO_PRO); } // Returns the native output sample rate for this device's output stream. @@ -287,6 +297,6 @@ public class WebRtcAudioManager { private native void nativeCacheAudioParameters( int sampleRate, int channels, boolean hardwareAEC, boolean hardwareAGC, - boolean hardwareNS, boolean lowLatencyOutput, int outputBufferSize, - int inputBufferSize, long nativeAudioManager); + boolean hardwareNS, boolean lowLatencyOutput, boolean proAudio, + int outputBufferSize, int inputBufferSize, long nativeAudioManager); } diff --git a/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioUtils.java b/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioUtils.java index 579482e14b..fecefc75c3 100644 --- a/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioUtils.java +++ b/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioUtils.java @@ -169,11 +169,10 @@ public final class WebRtcAudioUtils { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; } - // TODO(phoglund): enable when all downstream users use M. - // public static boolean runningOnMOrHigher() { + public static boolean runningOnMarshmallowOrHigher() { // API Level 23. - // return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M; - //} + return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M; + } // Helper method for building a string of thread information. public static String getThreadInfo() {