Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fd747ca6 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Enhance channel masks conversion between AIDL and SDK"

parents 533d486d e1f9659e
Loading
Loading
Loading
Loading
+36 −0
Original line number Original line Diff line number Diff line
@@ -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_Z_AXIS = 0x2000;
    public static final int CHANNEL_IN_VOICE_UPLINK = 0x4000;
    public static final int CHANNEL_IN_VOICE_UPLINK = 0x4000;
    public static final int CHANNEL_IN_VOICE_DNLINK = 0x8000;
    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_MONO = CHANNEL_IN_FRONT;
    public static final int CHANNEL_IN_STEREO = (CHANNEL_IN_LEFT | CHANNEL_IN_RIGHT);
    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 */
    /** @hide */
    public static final int CHANNEL_IN_FRONT_BACK = CHANNEL_IN_FRONT | CHANNEL_IN_BACK;
    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
    // CHANNEL_IN_ALL is not yet defined; if added then it should match AUDIO_CHANNEL_IN_ALL
+133 −4
Original line number Original line Diff line number Diff line
@@ -131,6 +131,124 @@ public class AidlConversion {
    /** Convert from legacy audio_usage_t to AIDL AudioUsage. */
    /** Convert from legacy audio_usage_t to AIDL AudioUsage. */
    public static native int legacy2aidl_audio_usage_t_AudioUsage(int /*audio_usage_t*/ legacy);
    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_*. */
    /** Convert from AIDL AudioChannelLayout to SDK AudioFormat.CHANNEL_*. */
    public static int aidl2api_AudioChannelLayout_AudioFormatChannelMask(
    public static int aidl2api_AudioChannelLayout_AudioFormatChannelMask(
            @NonNull AudioChannelLayout aidlMask, boolean isInput) {
            @NonNull AudioChannelLayout aidlMask, boolean isInput) {
@@ -155,8 +273,17 @@ public class AidlConversion {
                            return AudioFormat.CHANNEL_IN_STEREO;
                            return AudioFormat.CHANNEL_IN_STEREO;
                        case AudioChannelLayout.LAYOUT_FRONT_BACK:
                        case AudioChannelLayout.LAYOUT_FRONT_BACK:
                            return AudioFormat.CHANNEL_IN_FRONT_BACK;
                            return AudioFormat.CHANNEL_IN_FRONT_BACK;
                        default:
                        case AudioChannelLayout.LAYOUT_2POINT0POINT2:
                            return AudioFormat.CHANNEL_INVALID;
                            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 {
                } else {
                    switch (aidlMask.getLayoutMask()) {
                    switch (aidlMask.getLayoutMask()) {
@@ -264,10 +391,12 @@ public class AidlConversion {
                        case AudioChannelLayout.LAYOUT_FRONT_BACK:
                        case AudioChannelLayout.LAYOUT_FRONT_BACK:
                            return AudioFormat.CHANNEL_OUT_FRONT_CENTER
                            return AudioFormat.CHANNEL_OUT_FRONT_CENTER
                                    | AudioFormat.CHANNEL_OUT_BACK_CENTER;
                                    | AudioFormat.CHANNEL_OUT_BACK_CENTER;
                        default:
                        default: // fall through
                            return AudioFormat.CHANNEL_INVALID;
                    }
                    }
                }
                }
                // 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:
            case AudioChannelLayout.voiceMask:
                if (isInput) {
                if (isInput) {
                    switch (aidlMask.getVoiceMask()) {
                    switch (aidlMask.getVoiceMask()) {
+27 −0
Original line number Original line Diff line number Diff line
@@ -66,6 +66,19 @@ public final class AidlConversionUnitTests {
        assertEquals(AudioFormat.CHANNEL_OUT_MONO, api);
        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
    @Test
    public void testAudioChannelConversionApiInput() {
    public void testAudioChannelConversionApiInput() {
        final AudioChannelLayout aidl = AudioChannelLayout.layoutMask(
        final AudioChannelLayout aidl = AudioChannelLayout.layoutMask(
@@ -75,6 +88,20 @@ public final class AidlConversionUnitTests {
        assertEquals(AudioFormat.CHANNEL_IN_MONO, api);
        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
    @Test
    public void testAudioChannelConversionApiIndex() {
    public void testAudioChannelConversionApiIndex() {
        final AudioChannelLayout aidl = AudioChannelLayout.indexMask(
        final AudioChannelLayout aidl = AudioChannelLayout.indexMask(