Merge "Enhance channel masks conversion between AIDL and SDK"
This commit is contained in:
committed by
Android (Google) Code Review
commit
fd747ca630
@@ -675,8 +675,44 @@ public final class AudioFormat implements Parcelable {
|
||||
public static final int CHANNEL_IN_Z_AXIS = 0x2000;
|
||||
public static final int CHANNEL_IN_VOICE_UPLINK = 0x4000;
|
||||
public static final int CHANNEL_IN_VOICE_DNLINK = 0x8000;
|
||||
// CHANNEL_IN_BACK_LEFT to TOP_RIGHT are not microphone positions
|
||||
// but surround channels which are used when dealing with multi-channel inputs,
|
||||
// e.g. via HDMI input on TV.
|
||||
/** @hide */
|
||||
public static final int CHANNEL_IN_BACK_LEFT = 0x10000;
|
||||
/** @hide */
|
||||
public static final int CHANNEL_IN_BACK_RIGHT = 0x20000;
|
||||
/** @hide */
|
||||
public static final int CHANNEL_IN_CENTER = 0x40000;
|
||||
/** @hide */
|
||||
public static final int CHANNEL_IN_LOW_FREQUENCY = 0x100000;
|
||||
/** @hide */
|
||||
public static final int CHANNEL_IN_TOP_LEFT = 0x200000;
|
||||
/** @hide */
|
||||
public static final int CHANNEL_IN_TOP_RIGHT = 0x400000;
|
||||
public static final int CHANNEL_IN_MONO = CHANNEL_IN_FRONT;
|
||||
public static final int CHANNEL_IN_STEREO = (CHANNEL_IN_LEFT | CHANNEL_IN_RIGHT);
|
||||
// Surround channel masks corresponding to output masks, used for
|
||||
// surround sound inputs.
|
||||
/** @hide */
|
||||
public static final int CHANNEL_IN_2POINT0POINT2 = (
|
||||
CHANNEL_IN_LEFT | CHANNEL_IN_RIGHT | CHANNEL_IN_TOP_LEFT | CHANNEL_IN_TOP_RIGHT);
|
||||
/** @hide */
|
||||
public static final int CHANNEL_IN_2POINT1POINT2 = (
|
||||
CHANNEL_IN_LEFT | CHANNEL_IN_RIGHT | CHANNEL_IN_TOP_LEFT | CHANNEL_IN_TOP_RIGHT
|
||||
| CHANNEL_IN_LOW_FREQUENCY);
|
||||
/** @hide */
|
||||
public static final int CHANNEL_IN_3POINT0POINT2 = (
|
||||
CHANNEL_IN_LEFT | CHANNEL_IN_CENTER | CHANNEL_IN_RIGHT | CHANNEL_IN_TOP_LEFT
|
||||
| CHANNEL_IN_TOP_RIGHT);
|
||||
/** @hide */
|
||||
public static final int CHANNEL_IN_3POINT1POINT2 = (
|
||||
CHANNEL_IN_LEFT | CHANNEL_IN_CENTER | CHANNEL_IN_RIGHT | CHANNEL_IN_TOP_LEFT
|
||||
| CHANNEL_IN_TOP_RIGHT | CHANNEL_IN_LOW_FREQUENCY);
|
||||
/** @hide */
|
||||
public static final int CHANNEL_IN_5POINT1 = (
|
||||
CHANNEL_IN_LEFT | CHANNEL_IN_CENTER | CHANNEL_IN_RIGHT | CHANNEL_IN_BACK_LEFT
|
||||
| CHANNEL_IN_BACK_RIGHT | CHANNEL_IN_LOW_FREQUENCY);
|
||||
/** @hide */
|
||||
public static final int CHANNEL_IN_FRONT_BACK = CHANNEL_IN_FRONT | CHANNEL_IN_BACK;
|
||||
// CHANNEL_IN_ALL is not yet defined; if added then it should match AUDIO_CHANNEL_IN_ALL
|
||||
|
||||
@@ -131,6 +131,124 @@ public class AidlConversion {
|
||||
/** Convert from legacy audio_usage_t to AIDL AudioUsage. */
|
||||
public static native int legacy2aidl_audio_usage_t_AudioUsage(int /*audio_usage_t*/ legacy);
|
||||
|
||||
/** Convert from a channel bit of AIDL AudioChannelLayout to SDK AudioFormat.CHANNEL_* bit. */
|
||||
private static int aidl2api_AudioChannelLayoutBit_AudioFormatChannel(
|
||||
int aidlBit, boolean isInput) {
|
||||
if (isInput) {
|
||||
switch (aidlBit) {
|
||||
case AudioChannelLayout.CHANNEL_FRONT_LEFT:
|
||||
return AudioFormat.CHANNEL_IN_LEFT;
|
||||
case AudioChannelLayout.CHANNEL_FRONT_RIGHT:
|
||||
return AudioFormat.CHANNEL_IN_RIGHT;
|
||||
case AudioChannelLayout.CHANNEL_FRONT_CENTER:
|
||||
return AudioFormat.CHANNEL_IN_CENTER;
|
||||
case AudioChannelLayout.CHANNEL_BACK_CENTER:
|
||||
return AudioFormat.CHANNEL_IN_BACK;
|
||||
// CHANNEL_IN_*_PROCESSED not supported
|
||||
// CHANNEL_IN_PRESSURE not supported
|
||||
// CHANNEL_IN_*_AXIS not supported
|
||||
// CHANNEL_IN_VOICE_* not supported
|
||||
case AudioChannelLayout.CHANNEL_BACK_LEFT:
|
||||
return AudioFormat.CHANNEL_IN_BACK_LEFT;
|
||||
case AudioChannelLayout.CHANNEL_BACK_RIGHT:
|
||||
return AudioFormat.CHANNEL_IN_BACK_RIGHT;
|
||||
case AudioChannelLayout.CHANNEL_LOW_FREQUENCY:
|
||||
return AudioFormat.CHANNEL_IN_LOW_FREQUENCY;
|
||||
case AudioChannelLayout.CHANNEL_TOP_SIDE_LEFT:
|
||||
return AudioFormat.CHANNEL_IN_TOP_LEFT;
|
||||
case AudioChannelLayout.CHANNEL_TOP_SIDE_RIGHT:
|
||||
return AudioFormat.CHANNEL_IN_TOP_RIGHT;
|
||||
default:
|
||||
return AudioFormat.CHANNEL_INVALID;
|
||||
}
|
||||
} else {
|
||||
switch (aidlBit) {
|
||||
case AudioChannelLayout.CHANNEL_FRONT_LEFT:
|
||||
return AudioFormat.CHANNEL_OUT_FRONT_LEFT;
|
||||
case AudioChannelLayout.CHANNEL_FRONT_RIGHT:
|
||||
return AudioFormat.CHANNEL_OUT_FRONT_RIGHT;
|
||||
case AudioChannelLayout.CHANNEL_FRONT_CENTER:
|
||||
return AudioFormat.CHANNEL_OUT_FRONT_CENTER;
|
||||
case AudioChannelLayout.CHANNEL_LOW_FREQUENCY:
|
||||
return AudioFormat.CHANNEL_OUT_LOW_FREQUENCY;
|
||||
case AudioChannelLayout.CHANNEL_BACK_LEFT:
|
||||
return AudioFormat.CHANNEL_OUT_BACK_LEFT;
|
||||
case AudioChannelLayout.CHANNEL_BACK_RIGHT:
|
||||
return AudioFormat.CHANNEL_OUT_BACK_RIGHT;
|
||||
case AudioChannelLayout.CHANNEL_FRONT_LEFT_OF_CENTER:
|
||||
return AudioFormat.CHANNEL_OUT_FRONT_LEFT_OF_CENTER;
|
||||
case AudioChannelLayout.CHANNEL_FRONT_RIGHT_OF_CENTER:
|
||||
return AudioFormat.CHANNEL_OUT_FRONT_RIGHT_OF_CENTER;
|
||||
case AudioChannelLayout.CHANNEL_BACK_CENTER:
|
||||
return AudioFormat.CHANNEL_OUT_BACK_CENTER;
|
||||
case AudioChannelLayout.CHANNEL_SIDE_LEFT:
|
||||
return AudioFormat.CHANNEL_OUT_SIDE_LEFT;
|
||||
case AudioChannelLayout.CHANNEL_SIDE_RIGHT:
|
||||
return AudioFormat.CHANNEL_OUT_SIDE_RIGHT;
|
||||
case AudioChannelLayout.CHANNEL_TOP_CENTER:
|
||||
return AudioFormat.CHANNEL_OUT_TOP_CENTER;
|
||||
case AudioChannelLayout.CHANNEL_TOP_FRONT_LEFT:
|
||||
return AudioFormat.CHANNEL_OUT_TOP_FRONT_LEFT;
|
||||
case AudioChannelLayout.CHANNEL_TOP_FRONT_CENTER:
|
||||
return AudioFormat.CHANNEL_OUT_TOP_FRONT_CENTER;
|
||||
case AudioChannelLayout.CHANNEL_TOP_FRONT_RIGHT:
|
||||
return AudioFormat.CHANNEL_OUT_TOP_FRONT_RIGHT;
|
||||
case AudioChannelLayout.CHANNEL_TOP_BACK_LEFT:
|
||||
return AudioFormat.CHANNEL_OUT_TOP_BACK_LEFT;
|
||||
case AudioChannelLayout.CHANNEL_TOP_BACK_CENTER:
|
||||
return AudioFormat.CHANNEL_OUT_TOP_BACK_CENTER;
|
||||
case AudioChannelLayout.CHANNEL_TOP_BACK_RIGHT:
|
||||
return AudioFormat.CHANNEL_OUT_TOP_BACK_RIGHT;
|
||||
case AudioChannelLayout.CHANNEL_TOP_SIDE_LEFT:
|
||||
return AudioFormat.CHANNEL_OUT_TOP_SIDE_LEFT;
|
||||
case AudioChannelLayout.CHANNEL_TOP_SIDE_RIGHT:
|
||||
return AudioFormat.CHANNEL_OUT_TOP_SIDE_RIGHT;
|
||||
case AudioChannelLayout.CHANNEL_BOTTOM_FRONT_LEFT:
|
||||
return AudioFormat.CHANNEL_OUT_BOTTOM_FRONT_LEFT;
|
||||
case AudioChannelLayout.CHANNEL_BOTTOM_FRONT_CENTER:
|
||||
return AudioFormat.CHANNEL_OUT_BOTTOM_FRONT_CENTER;
|
||||
case AudioChannelLayout.CHANNEL_BOTTOM_FRONT_RIGHT:
|
||||
return AudioFormat.CHANNEL_OUT_BOTTOM_FRONT_RIGHT;
|
||||
case AudioChannelLayout.CHANNEL_LOW_FREQUENCY_2:
|
||||
return AudioFormat.CHANNEL_OUT_LOW_FREQUENCY_2;
|
||||
case AudioChannelLayout.CHANNEL_FRONT_WIDE_LEFT:
|
||||
return AudioFormat.CHANNEL_OUT_FRONT_WIDE_LEFT;
|
||||
case AudioChannelLayout.CHANNEL_FRONT_WIDE_RIGHT:
|
||||
return AudioFormat.CHANNEL_OUT_FRONT_WIDE_RIGHT;
|
||||
case AudioChannelLayout.CHANNEL_HAPTIC_A:
|
||||
return AudioFormat.CHANNEL_OUT_HAPTIC_A;
|
||||
case AudioChannelLayout.CHANNEL_HAPTIC_B:
|
||||
return AudioFormat.CHANNEL_OUT_HAPTIC_B;
|
||||
default:
|
||||
return AudioFormat.CHANNEL_INVALID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert from a channel bitmask of AIDL AudioChannelLayout to
|
||||
* SDK AudioFormat.CHANNEL_* bitmask.
|
||||
*/
|
||||
private static int aidl2api_AudioChannelLayoutBitMask_AudioFormatChannelMask(
|
||||
int aidlBitMask, boolean isInput) {
|
||||
int apiMask = 0;
|
||||
for (int bit = 1 << 31; bit != 0; bit >>>= 1) {
|
||||
if ((aidlBitMask & bit) == bit) {
|
||||
int apiBit = aidl2api_AudioChannelLayoutBit_AudioFormatChannel(bit, isInput);
|
||||
if (apiBit != AudioFormat.CHANNEL_INVALID) {
|
||||
apiMask |= apiBit;
|
||||
aidlBitMask &= ~bit;
|
||||
if (aidlBitMask == 0) {
|
||||
return apiMask;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return AudioFormat.CHANNEL_INVALID;
|
||||
}
|
||||
|
||||
/** Convert from AIDL AudioChannelLayout to SDK AudioFormat.CHANNEL_*. */
|
||||
public static int aidl2api_AudioChannelLayout_AudioFormatChannelMask(
|
||||
@NonNull AudioChannelLayout aidlMask, boolean isInput) {
|
||||
@@ -155,8 +273,17 @@ public class AidlConversion {
|
||||
return AudioFormat.CHANNEL_IN_STEREO;
|
||||
case AudioChannelLayout.LAYOUT_FRONT_BACK:
|
||||
return AudioFormat.CHANNEL_IN_FRONT_BACK;
|
||||
default:
|
||||
return AudioFormat.CHANNEL_INVALID;
|
||||
case AudioChannelLayout.LAYOUT_2POINT0POINT2:
|
||||
return AudioFormat.CHANNEL_IN_2POINT0POINT2;
|
||||
case AudioChannelLayout.LAYOUT_2POINT1POINT2:
|
||||
return AudioFormat.CHANNEL_IN_2POINT1POINT2;
|
||||
case AudioChannelLayout.LAYOUT_3POINT0POINT2:
|
||||
return AudioFormat.CHANNEL_IN_3POINT0POINT2;
|
||||
case AudioChannelLayout.LAYOUT_3POINT1POINT2:
|
||||
return AudioFormat.CHANNEL_IN_3POINT1POINT2;
|
||||
case AudioChannelLayout.LAYOUT_5POINT1:
|
||||
return AudioFormat.CHANNEL_IN_5POINT1;
|
||||
default: // fall through
|
||||
}
|
||||
} else {
|
||||
switch (aidlMask.getLayoutMask()) {
|
||||
@@ -264,10 +391,12 @@ public class AidlConversion {
|
||||
case AudioChannelLayout.LAYOUT_FRONT_BACK:
|
||||
return AudioFormat.CHANNEL_OUT_FRONT_CENTER
|
||||
| AudioFormat.CHANNEL_OUT_BACK_CENTER;
|
||||
default:
|
||||
return AudioFormat.CHANNEL_INVALID;
|
||||
default: // fall through
|
||||
}
|
||||
}
|
||||
// If a match for a predefined layout wasn't found, make a custom one from bits.
|
||||
return aidl2api_AudioChannelLayoutBitMask_AudioFormatChannelMask(
|
||||
aidlMask.getLayoutMask(), isInput);
|
||||
case AudioChannelLayout.voiceMask:
|
||||
if (isInput) {
|
||||
switch (aidlMask.getVoiceMask()) {
|
||||
|
||||
@@ -66,6 +66,19 @@ public final class AidlConversionUnitTests {
|
||||
assertEquals(AudioFormat.CHANNEL_OUT_MONO, api);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAudioChannelConversionApiOutputMask() {
|
||||
final AudioChannelLayout aidl = AudioChannelLayout.layoutMask(
|
||||
AudioChannelLayout.CHANNEL_FRONT_LEFT | AudioChannelLayout.CHANNEL_FRONT_RIGHT
|
||||
| AudioChannelLayout.CHANNEL_FRONT_WIDE_LEFT
|
||||
| AudioChannelLayout.CHANNEL_FRONT_WIDE_RIGHT);
|
||||
final int api = AidlConversion.aidl2api_AudioChannelLayout_AudioFormatChannelMask(
|
||||
aidl, false /*isInput*/);
|
||||
assertEquals(AudioFormat.CHANNEL_OUT_FRONT_LEFT | AudioFormat.CHANNEL_OUT_FRONT_RIGHT
|
||||
| AudioFormat.CHANNEL_OUT_FRONT_WIDE_LEFT
|
||||
| AudioFormat.CHANNEL_OUT_FRONT_WIDE_RIGHT, api);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAudioChannelConversionApiInput() {
|
||||
final AudioChannelLayout aidl = AudioChannelLayout.layoutMask(
|
||||
@@ -75,6 +88,20 @@ public final class AidlConversionUnitTests {
|
||||
assertEquals(AudioFormat.CHANNEL_IN_MONO, api);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAudioChannelConversionApiInputMask() {
|
||||
final AudioChannelLayout aidl = AudioChannelLayout.layoutMask(
|
||||
AudioChannelLayout.CHANNEL_FRONT_LEFT | AudioChannelLayout.CHANNEL_FRONT_RIGHT
|
||||
| AudioChannelLayout.CHANNEL_TOP_SIDE_LEFT
|
||||
| AudioChannelLayout.CHANNEL_TOP_SIDE_RIGHT);
|
||||
final int api = AidlConversion.aidl2api_AudioChannelLayout_AudioFormatChannelMask(
|
||||
aidl, true /*isInput*/);
|
||||
assertEquals(AudioFormat.CHANNEL_IN_LEFT | AudioFormat.CHANNEL_IN_RIGHT
|
||||
// | AudioFormat.CHANNEL_IN_TOP_LEFT | AudioFormat.CHANNEL_IN_TOP_RIGHT,
|
||||
| 0x200000 | 0x400000, // TODO: Replace with names when revealed.
|
||||
api);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAudioChannelConversionApiIndex() {
|
||||
final AudioChannelLayout aidl = AudioChannelLayout.indexMask(
|
||||
|
||||
Reference in New Issue
Block a user