add new audio sources for audio capture
This commit adds the following audio capture sources:
- AUDIO_SOURCE_VOICE_PERFORMANCE: for real time live performances like Karaoke.
- AUDIO_SOURCE_ECHO_REFERENCE: for capturing the reference signal to suppress by an echo
canceller. Protected by privileged permission CAPTURE_AUDIO_OUTPUT.
Also added device AUDIO_DEVICE_IN_ECHO_REFERENCE selected when the requested
capture source is AUDIO_SOURCE_ECHO_REFERENCE.
Bug: 118203066
Test: CTS tests for audio capture
Change-Id: Ieb159ea82a7b81acf762506a44e24ec80111609f
diff --git a/media/libaaudio/include/aaudio/AAudio.h b/media/libaaudio/include/aaudio/AAudio.h
index 1493b26..8e36c77 100644
--- a/media/libaaudio/include/aaudio/AAudio.h
+++ b/media/libaaudio/include/aaudio/AAudio.h
@@ -373,6 +373,13 @@
* so the recorded volume may be very low.
*/
AAUDIO_INPUT_PRESET_UNPROCESSED = 9,
+
+ /**
+ * Use this preset for capturing audio meant to be processed in real time
+ * and played back for live performance (e.g karaoke).
+ * The capture path will minimize latency and coupling with playback path.
+ */
+ AAUDIO_INPUT_PRESET_VOICE_PERFORMANCE = 10,
};
typedef int32_t aaudio_input_preset_t;
diff --git a/media/libaaudio/src/core/AAudioStreamParameters.cpp b/media/libaaudio/src/core/AAudioStreamParameters.cpp
index bd42697..88da53a 100644
--- a/media/libaaudio/src/core/AAudioStreamParameters.cpp
+++ b/media/libaaudio/src/core/AAudioStreamParameters.cpp
@@ -158,6 +158,7 @@
case AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION:
case AAUDIO_INPUT_PRESET_VOICE_RECOGNITION:
case AAUDIO_INPUT_PRESET_UNPROCESSED:
+ case AAUDIO_INPUT_PRESET_VOICE_PERFORMANCE:
break; // valid
default:
ALOGE("input preset not valid = %d", mInputPreset);
diff --git a/media/libaaudio/src/utility/AAudioUtilities.cpp b/media/libaaudio/src/utility/AAudioUtilities.cpp
index f5b3ad4..723cbf1 100644
--- a/media/libaaudio/src/utility/AAudioUtilities.cpp
+++ b/media/libaaudio/src/utility/AAudioUtilities.cpp
@@ -210,6 +210,7 @@
STATIC_ASSERT(AAUDIO_INPUT_PRESET_VOICE_RECOGNITION == AUDIO_SOURCE_VOICE_RECOGNITION);
STATIC_ASSERT(AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION == AUDIO_SOURCE_VOICE_COMMUNICATION);
STATIC_ASSERT(AAUDIO_INPUT_PRESET_UNPROCESSED == AUDIO_SOURCE_UNPROCESSED);
+ STATIC_ASSERT(AAUDIO_INPUT_PRESET_VOICE_PERFORMANCE == AUDIO_SOURCE_VOICE_PERFORMANCE);
if (preset == AAUDIO_UNSPECIFIED) {
preset = AAUDIO_INPUT_PRESET_VOICE_RECOGNITION;
}
diff --git a/media/libaaudio/tests/test_attributes.cpp b/media/libaaudio/tests/test_attributes.cpp
index b01af25..dbf8712 100644
--- a/media/libaaudio/tests/test_attributes.cpp
+++ b/media/libaaudio/tests/test_attributes.cpp
@@ -130,6 +130,7 @@
AAUDIO_INPUT_PRESET_VOICE_RECOGNITION,
AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION,
AAUDIO_INPUT_PRESET_UNPROCESSED,
+ AAUDIO_INPUT_PRESET_VOICE_PERFORMANCE,
};
static void checkAttributesUsage(aaudio_performance_mode_t perfMode) {
diff --git a/media/libeffects/config/src/EffectsConfig.cpp b/media/libeffects/config/src/EffectsConfig.cpp
index 76b4adc..f39eb0c 100644
--- a/media/libeffects/config/src/EffectsConfig.cpp
+++ b/media/libeffects/config/src/EffectsConfig.cpp
@@ -115,6 +115,7 @@
{AUDIO_SOURCE_VOICE_RECOGNITION, "voice_recognition"},
{AUDIO_SOURCE_VOICE_COMMUNICATION, "voice_communication"},
{AUDIO_SOURCE_UNPROCESSED, "unprocessed"},
+ {AUDIO_SOURCE_VOICE_PERFORMANCE, "voice_performance"},
};
/** Find the stream type enum corresponding to the stream type name or return false */
diff --git a/media/libmedia/TypeConverter.cpp b/media/libmedia/TypeConverter.cpp
index b5a7172..0ab0e9b 100644
--- a/media/libmedia/TypeConverter.cpp
+++ b/media/libmedia/TypeConverter.cpp
@@ -93,6 +93,8 @@
MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BUS),
MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_PROXY),
MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_USB_HEADSET),
+ MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_BLE),
+ MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_ECHO_REFERENCE),
MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_DEFAULT),
// STUB must be after DEFAULT, so the latter is picked up by toString first.
MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_STUB),
@@ -357,6 +359,8 @@
MAKE_STRING_FROM_ENUM(AUDIO_SOURCE_VOICE_COMMUNICATION),
MAKE_STRING_FROM_ENUM(AUDIO_SOURCE_REMOTE_SUBMIX),
MAKE_STRING_FROM_ENUM(AUDIO_SOURCE_UNPROCESSED),
+ MAKE_STRING_FROM_ENUM(AUDIO_SOURCE_VOICE_PERFORMANCE),
+ MAKE_STRING_FROM_ENUM(AUDIO_SOURCE_ECHO_REFERENCE),
MAKE_STRING_FROM_ENUM(AUDIO_SOURCE_FM_TUNER),
MAKE_STRING_FROM_ENUM(AUDIO_SOURCE_HOTWORD),
TERMINATOR
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 989e6eb..607d2d1 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -494,6 +494,8 @@
case AUDIO_SOURCE_VOICE_COMMUNICATION: return "voice communication";
case AUDIO_SOURCE_REMOTE_SUBMIX: return "remote submix";
case AUDIO_SOURCE_UNPROCESSED: return "unprocessed";
+ case AUDIO_SOURCE_VOICE_PERFORMANCE: return "voice performance";
+ case AUDIO_SOURCE_ECHO_REFERENCE: return "echo reference";
case AUDIO_SOURCE_FM_TUNER: return "FM tuner";
case AUDIO_SOURCE_HOTWORD: return "hotword";
default: return "unknown";
diff --git a/services/audiopolicy/common/include/policy.h b/services/audiopolicy/common/include/policy.h
index 30b0044..46a2a40 100644
--- a/services/audiopolicy/common/include/policy.h
+++ b/services/audiopolicy/common/include/policy.h
@@ -83,7 +83,10 @@
* @param[in] inputSource to consider. Valid sources are:
* - AUDIO_SOURCE_VOICE_COMMUNICATION
* - AUDIO_SOURCE_CAMCORDER
+ * - AUDIO_SOURCE_VOICE_PERFORMANCE
+ * - AUDIO_SOURCE_UNPROCESSED
* - AUDIO_SOURCE_MIC
+ * - AUDIO_SOURCE_ECHO_REFERENCE
* - AUDIO_SOURCE_FM_TUNER
* - AUDIO_SOURCE_VOICE_RECOGNITION
* - AUDIO_SOURCE_HOTWORD
@@ -96,10 +99,16 @@
{
switch (inputSource) {
case AUDIO_SOURCE_VOICE_COMMUNICATION:
- return 6;
+ return 9;
case AUDIO_SOURCE_CAMCORDER:
- return 5;
+ return 8;
+ case AUDIO_SOURCE_VOICE_PERFORMANCE:
+ return 7;
+ case AUDIO_SOURCE_UNPROCESSED:
+ return 6;
case AUDIO_SOURCE_MIC:
+ return 5;
+ case AUDIO_SOURCE_ECHO_REFERENCE:
return 4;
case AUDIO_SOURCE_FM_TUNER:
return 3;
diff --git a/services/audiopolicy/engineconfigurable/src/InputSource.cpp b/services/audiopolicy/engineconfigurable/src/InputSource.cpp
index b9a38d4..d252d3f 100644
--- a/services/audiopolicy/engineconfigurable/src/InputSource.cpp
+++ b/services/audiopolicy/engineconfigurable/src/InputSource.cpp
@@ -25,7 +25,8 @@
status_t Element<audio_source_t>::setIdentifier(audio_source_t identifier)
{
- if (identifier > AUDIO_SOURCE_MAX && identifier != AUDIO_SOURCE_HOTWORD) {
+ if (identifier > AUDIO_SOURCE_MAX && identifier != AUDIO_SOURCE_HOTWORD
+ && identifier != AUDIO_SOURCE_FM_TUNER && identifier != AUDIO_SOURCE_ECHO_REFERENCE) {
return BAD_VALUE;
}
mIdentifier = identifier;
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index 69395f3..0ef6f52 100644
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -631,6 +631,7 @@
case AUDIO_SOURCE_UNPROCESSED:
case AUDIO_SOURCE_HOTWORD:
case AUDIO_SOURCE_CAMCORDER:
+ case AUDIO_SOURCE_VOICE_PERFORMANCE:
inputSource = AUDIO_SOURCE_VOICE_COMMUNICATION;
break;
default:
@@ -737,16 +738,32 @@
device = AUDIO_DEVICE_IN_VOICE_CALL;
}
break;
+ case AUDIO_SOURCE_VOICE_PERFORMANCE:
+ if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
+ device = AUDIO_DEVICE_IN_WIRED_HEADSET;
+ } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) {
+ device = AUDIO_DEVICE_IN_USB_HEADSET;
+ } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
+ device = AUDIO_DEVICE_IN_USB_DEVICE;
+ } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
+ device = AUDIO_DEVICE_IN_BUILTIN_MIC;
+ }
+ break;
case AUDIO_SOURCE_REMOTE_SUBMIX:
if (availableDeviceTypes & AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
}
break;
- case AUDIO_SOURCE_FM_TUNER:
+ case AUDIO_SOURCE_FM_TUNER:
if (availableDeviceTypes & AUDIO_DEVICE_IN_FM_TUNER) {
device = AUDIO_DEVICE_IN_FM_TUNER;
}
break;
+ case AUDIO_SOURCE_ECHO_REFERENCE:
+ if (availableDeviceTypes & AUDIO_DEVICE_IN_ECHO_REFERENCE) {
+ device = AUDIO_DEVICE_IN_ECHO_REFERENCE;
+ }
+ break;
default:
ALOGW("getDeviceForInputSource() invalid input source %d", inputSource);
break;
diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp
index 29b0561..919a90d 100644
--- a/services/audiopolicy/service/AudioPolicyEffects.cpp
+++ b/services/audiopolicy/service/AudioPolicyEffects.cpp
@@ -330,11 +330,12 @@
return BAD_VALUE;
}
- // HOTWORD and FM_TUNER are two special case sources > MAX.
+ // HOTWORD, FM_TUNER and ECHO_REFERENCE are special case sources > MAX.
if (source < AUDIO_SOURCE_DEFAULT ||
(source > AUDIO_SOURCE_MAX &&
source != AUDIO_SOURCE_HOTWORD &&
- source != AUDIO_SOURCE_FM_TUNER)) {
+ source != AUDIO_SOURCE_FM_TUNER &&
+ source != AUDIO_SOURCE_ECHO_REFERENCE)) {
ALOGE("addSourceDefaultEffect(): Unsupported source type %d", source);
return BAD_VALUE;
}
@@ -534,7 +535,8 @@
CAMCORDER_SRC_TAG,
VOICE_REC_SRC_TAG,
VOICE_COMM_SRC_TAG,
- UNPROCESSED_SRC_TAG
+ UNPROCESSED_SRC_TAG,
+ VOICE_PERFORMANCE_SRC_TAG
};
// returns the audio_source_t enum corresponding to the input source name or
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 80503fd..2c904d9 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -336,8 +336,11 @@
}
// already checked by client, but double-check in case the client wrapper is bypassed
- if (attr->source < AUDIO_SOURCE_DEFAULT && attr->source >= AUDIO_SOURCE_CNT &&
- attr->source != AUDIO_SOURCE_HOTWORD && attr->source != AUDIO_SOURCE_FM_TUNER) {
+ if ((attr->source < AUDIO_SOURCE_DEFAULT)
+ || (attr->source >= AUDIO_SOURCE_CNT
+ && attr->source != AUDIO_SOURCE_HOTWORD
+ && attr->source != AUDIO_SOURCE_FM_TUNER
+ && attr->source != AUDIO_SOURCE_ECHO_REFERENCE)) {
return BAD_VALUE;
}
@@ -367,7 +370,8 @@
if ((attr->source == AUDIO_SOURCE_VOICE_UPLINK ||
attr->source == AUDIO_SOURCE_VOICE_DOWNLINK ||
- attr->source == AUDIO_SOURCE_VOICE_CALL) &&
+ attr->source == AUDIO_SOURCE_VOICE_CALL ||
+ attr->source == AUDIO_SOURCE_ECHO_REFERENCE) &&
!captureAudioOutputAllowed(pid, uid)) {
return PERMISSION_DENIED;
}