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

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

Merge "Define an extensible audio channel layout description"

parents f7a8339e cf2fa818
Loading
Loading
Loading
Loading
+179 −0
Original line number Diff line number Diff line
@@ -412,12 +412,121 @@ ConversionResult<media::AudioFormatSys> legacy2aidl_audio_format_t_AudioFormat(
namespace {

namespace detail {
using AudioChannelPair = std::pair<audio_channel_mask_t, media::AudioChannelLayout>;
using AudioChannelPairs = std::vector<AudioChannelPair>;
using AudioDevicePair = std::pair<audio_devices_t, media::AudioDeviceDescription>;
using AudioDevicePairs = std::vector<AudioDevicePair>;
using AudioFormatPair = std::pair<audio_format_t, media::AudioFormatDescription>;
using AudioFormatPairs = std::vector<AudioFormatPair>;
}

const detail::AudioChannelPairs& getIndexAudioChannelPairs() {
    static const detail::AudioChannelPairs pairs = {
#define DEFINE_INDEX_MASK(n)                                                                \
            {                                                                               \
                AUDIO_CHANNEL_INDEX_MASK_##n,                                               \
                media::AudioChannelLayout::make<media::AudioChannelLayout::Tag::indexMask>( \
                        media::AudioChannelLayout::INDEX_MASK_##n)                          \
            }

            DEFINE_INDEX_MASK(1),
            DEFINE_INDEX_MASK(2),
            DEFINE_INDEX_MASK(3),
            DEFINE_INDEX_MASK(4),
            DEFINE_INDEX_MASK(5),
            DEFINE_INDEX_MASK(6),
            DEFINE_INDEX_MASK(7),
            DEFINE_INDEX_MASK(8),
            DEFINE_INDEX_MASK(9),
            DEFINE_INDEX_MASK(10),
            DEFINE_INDEX_MASK(11),
            DEFINE_INDEX_MASK(12),
            DEFINE_INDEX_MASK(13),
            DEFINE_INDEX_MASK(14),
            DEFINE_INDEX_MASK(15),
            DEFINE_INDEX_MASK(16),
            DEFINE_INDEX_MASK(17),
            DEFINE_INDEX_MASK(18),
            DEFINE_INDEX_MASK(19),
            DEFINE_INDEX_MASK(20),
            DEFINE_INDEX_MASK(21),
            DEFINE_INDEX_MASK(22),
            DEFINE_INDEX_MASK(23),
            DEFINE_INDEX_MASK(24)
#undef DEFINE_INDEX_MASK
    };
    return pairs;
}

const detail::AudioChannelPairs& getInAudioChannelPairs() {
    static const detail::AudioChannelPairs pairs = {
#define DEFINE_INPUT_LAYOUT(n)                                                               \
            {                                                                                \
                AUDIO_CHANNEL_IN_##n,                                                        \
                media::AudioChannelLayout::make<media::AudioChannelLayout::Tag::layoutMask>( \
                        media::AudioChannelLayout::LAYOUT_##n)                               \
            }

        DEFINE_INPUT_LAYOUT(MONO),
        DEFINE_INPUT_LAYOUT(STEREO),
        DEFINE_INPUT_LAYOUT(FRONT_BACK),
        // AUDIO_CHANNEL_IN_6 not supported
        DEFINE_INPUT_LAYOUT(2POINT0POINT2),
        DEFINE_INPUT_LAYOUT(2POINT1POINT2),
        DEFINE_INPUT_LAYOUT(3POINT0POINT2),
        DEFINE_INPUT_LAYOUT(3POINT1POINT2),
        DEFINE_INPUT_LAYOUT(5POINT1),
        DEFINE_INPUT_LAYOUT(VOICE_UPLINK_MONO),
        DEFINE_INPUT_LAYOUT(VOICE_DNLINK_MONO),
        DEFINE_INPUT_LAYOUT(VOICE_CALL_MONO)
#undef DEFINE_INPUT_LAYOUT
    };
    return pairs;
}

const detail::AudioChannelPairs& getOutAudioChannelPairs() {
    static const detail::AudioChannelPairs pairs = {
#define DEFINE_OUTPUT_LAYOUT(n)                                                              \
            {                                                                                \
                AUDIO_CHANNEL_OUT_##n,                                                       \
                media::AudioChannelLayout::make<media::AudioChannelLayout::Tag::layoutMask>( \
                        media::AudioChannelLayout::LAYOUT_##n)                               \
            }

        DEFINE_OUTPUT_LAYOUT(MONO),
        DEFINE_OUTPUT_LAYOUT(STEREO),
        DEFINE_OUTPUT_LAYOUT(2POINT1),
        DEFINE_OUTPUT_LAYOUT(TRI),
        DEFINE_OUTPUT_LAYOUT(TRI_BACK),
        DEFINE_OUTPUT_LAYOUT(3POINT1),
        DEFINE_OUTPUT_LAYOUT(2POINT0POINT2),
        DEFINE_OUTPUT_LAYOUT(2POINT1POINT2),
        DEFINE_OUTPUT_LAYOUT(3POINT0POINT2),
        DEFINE_OUTPUT_LAYOUT(3POINT1POINT2),
        DEFINE_OUTPUT_LAYOUT(QUAD),
        DEFINE_OUTPUT_LAYOUT(QUAD_SIDE),
        DEFINE_OUTPUT_LAYOUT(SURROUND),
        DEFINE_OUTPUT_LAYOUT(PENTA),
        DEFINE_OUTPUT_LAYOUT(5POINT1),
        DEFINE_OUTPUT_LAYOUT(5POINT1_SIDE),
        DEFINE_OUTPUT_LAYOUT(5POINT1POINT2),
        DEFINE_OUTPUT_LAYOUT(5POINT1POINT4),
        DEFINE_OUTPUT_LAYOUT(6POINT1),
        DEFINE_OUTPUT_LAYOUT(7POINT1),
        DEFINE_OUTPUT_LAYOUT(7POINT1POINT2),
        DEFINE_OUTPUT_LAYOUT(7POINT1POINT4),
        DEFINE_OUTPUT_LAYOUT(13POINT_360RA),
        DEFINE_OUTPUT_LAYOUT(22POINT2),
        DEFINE_OUTPUT_LAYOUT(MONO_HAPTIC_A),
        DEFINE_OUTPUT_LAYOUT(STEREO_HAPTIC_A),
        DEFINE_OUTPUT_LAYOUT(HAPTIC_AB),
        DEFINE_OUTPUT_LAYOUT(MONO_HAPTIC_AB),
        DEFINE_OUTPUT_LAYOUT(STEREO_HAPTIC_AB)
#undef DEFINE_OUTPUT_LAYOUT
    };
    return pairs;
}

media::AudioDeviceDescription make_AudioDeviceDescription(media::AudioDeviceType type,
        const std::string& connection = "") {
    media::AudioDeviceDescription result;
@@ -983,6 +1092,76 @@ std::unordered_map<T, S> make_ReverseMap(const std::vector<std::pair<S, T>>& v)

}  // namespace

ConversionResult<audio_channel_mask_t> aidl2legacy_AudioChannelLayout_audio_channel_mask_t(
        const media::AudioChannelLayout& aidl, bool isOutput) {
    using ReverseMap = std::unordered_map<media::AudioChannelLayout, audio_channel_mask_t>;
    using Tag = media::AudioChannelLayout::Tag;
    static const ReverseMap mIdx = make_ReverseMap(getIndexAudioChannelPairs());
    static const ReverseMap mIn = make_ReverseMap(getInAudioChannelPairs());
    static const ReverseMap mOut = make_ReverseMap(getOutAudioChannelPairs());

    auto convert = [](const media::AudioChannelLayout& aidl, const ReverseMap& m,
            const char* func, const char* type) -> ConversionResult<audio_channel_mask_t> {
        if (auto it = m.find(aidl); it != m.end()) {
            return it->second;
        } else {
            ALOGE("%s: no legacy %s audio_channel_mask_t found for %s", func, type,
                    aidl.toString().c_str());
            return unexpected(BAD_VALUE);
        }
    };

    switch (aidl.getTag()) {
        case Tag::none:
            return AUDIO_CHANNEL_NONE;
        case Tag::invalid:
            return AUDIO_CHANNEL_INVALID;
        case Tag::indexMask:
            return convert(aidl, mIdx, __func__, "index");
        case Tag::layoutMask:
            return convert(aidl, isOutput ? mOut : mIn, __func__, isOutput ? "output" : "input");
    }
    ALOGE("%s: unexpected tag value %d", __func__, aidl.getTag());
    return unexpected(BAD_VALUE);
}

ConversionResult<media::AudioChannelLayout> legacy2aidl_audio_channel_mask_t_AudioChannelLayout(
        audio_channel_mask_t legacy, bool isOutput) {
    using DirectMap = std::unordered_map<audio_channel_mask_t, media::AudioChannelLayout>;
    using Tag = media::AudioChannelLayout::Tag;
    static const DirectMap mIdx = make_DirectMap(getIndexAudioChannelPairs());
    static const DirectMap mIn = make_DirectMap(getInAudioChannelPairs());
    static const DirectMap mOut = make_DirectMap(getOutAudioChannelPairs());

    auto convert = [](const audio_channel_mask_t legacy, const DirectMap& m,
            const char* func, const char* type) -> ConversionResult<media::AudioChannelLayout> {
        if (auto it = m.find(legacy); it != m.end()) {
            return it->second;
        } else {
            ALOGE("%s: no AudioChannelLayout found for legacy %s audio_channel_mask_t value 0x%x",
                    func, type, legacy);
            return unexpected(BAD_VALUE);
        }
    };

    if (legacy == AUDIO_CHANNEL_NONE) {
        return media::AudioChannelLayout{};
    } else if (legacy == AUDIO_CHANNEL_INVALID) {
        return media::AudioChannelLayout::make<Tag::invalid>(0);
    }

    const audio_channel_representation_t repr = audio_channel_mask_get_representation(legacy);
    if (repr == AUDIO_CHANNEL_REPRESENTATION_INDEX) {
        return convert(legacy, mIdx, __func__, "index");
    } else if (repr == AUDIO_CHANNEL_REPRESENTATION_POSITION) {
        return convert(legacy, isOutput ? mOut : mIn, __func__, isOutput ? "output" : "input");
    }

    ALOGE("%s: unknown representation %d in audio_channel_mask_t value 0x%x",
            __func__, repr, legacy);
    return unexpected(BAD_VALUE);
}

ConversionResult<audio_devices_t> aidl2legacy_AudioDeviceDescription_audio_devices_t(
        const media::AudioDeviceDescription& aidl) {
    static const std::unordered_map<media::AudioDeviceDescription, audio_devices_t> m =
+1 −0
Original line number Diff line number Diff line
@@ -303,6 +303,7 @@ aidl_interface {
    local_include_dir: "aidl",
    srcs: [
        "aidl/android/media/AudioAttributesInternal.aidl",
        "aidl/android/media/AudioChannelLayout.aidl",
        "aidl/android/media/AudioChannelMask.aidl",
        "aidl/android/media/AudioClient.aidl",
        "aidl/android/media/AudioConfig.aidl",
+240 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.media;

/**
 * This structure describes a layout of a multi-channel stream.
 * There are two possible ways for representing a layout:
 *
 * - indexed mask, which tells what channels of an audio frame are used, but
 *   doesn't label them in any way, thus a correspondence between channels in
 *   the same position of frames originating from different streams must be
 *   established externally;
 *
 * - layout mask, which gives a label to each channel, thus allowing to
 *   match channels between streams of different layouts.
 *
 * Both representations are agnostic of the direction of audio transfer. Also,
 * by construction, the number of bits set to '1' in the mask indicates the
 * number of channels in the audio frame. A channel mask per se only defines the
 * presence or absence of a channel, not the order. Please see 'INTERLEAVE_*'
 * constants for the platform convention of order.
 */
union AudioChannelLayout {
    /**
     * This variant is used for representing the "null" ("none") value
     * for the channel layout. The field value must always be '0'.
     */
    int none = 0;
    /**
     * This variant is used for indicating an "invalid" layout for use by the
     * framework only. HAL implementations must not accept or emit
     * AudioChannelLayout values for this variant. The field value must always
     * be '0'.
     */
    int invalid = 0;
    /**
     * This variant is used for representing indexed masks. The value
     * must be one of the 'INDEX_MASK_*' constants. The 'indexMask' field
     * must have at least one bit set.
     */
    int indexMask;
    /**
     * This variant is used for representing layout masks.
     * It is recommended to use one of 'LAYOUT_*' values. The 'layoutMask' field
     * must have at least one bit set.
     */
    int layoutMask;

    /**
     * 'INDEX_MASK_' constants define how many channels are used.
     */
    const int INDEX_MASK_1 = (1 << 1) - 1;
    const int INDEX_MASK_2 = (1 << 2) - 1;
    const int INDEX_MASK_3 = (1 << 3) - 1;
    const int INDEX_MASK_4 = (1 << 4) - 1;
    const int INDEX_MASK_5 = (1 << 5) - 1;
    const int INDEX_MASK_6 = (1 << 6) - 1;
    const int INDEX_MASK_7 = (1 << 7) - 1;
    const int INDEX_MASK_8 = (1 << 8) - 1;
    const int INDEX_MASK_9 = (1 << 9) - 1;
    const int INDEX_MASK_10 = (1 << 10) - 1;
    const int INDEX_MASK_11 = (1 << 11) - 1;
    const int INDEX_MASK_12 = (1 << 12) - 1;
    const int INDEX_MASK_13 = (1 << 13) - 1;
    const int INDEX_MASK_14 = (1 << 14) - 1;
    const int INDEX_MASK_15 = (1 << 15) - 1;
    const int INDEX_MASK_16 = (1 << 16) - 1;
    const int INDEX_MASK_17 = (1 << 17) - 1;
    const int INDEX_MASK_18 = (1 << 18) - 1;
    const int INDEX_MASK_19 = (1 << 19) - 1;
    const int INDEX_MASK_20 = (1 << 20) - 1;
    const int INDEX_MASK_21 = (1 << 21) - 1;
    const int INDEX_MASK_22 = (1 << 22) - 1;
    const int INDEX_MASK_23 = (1 << 23) - 1;
    const int INDEX_MASK_24 = (1 << 24) - 1;

    /**
     * 'LAYOUT_*' constants define channel layouts recognized by
     * the audio system. The order of the channels in the frame is assumed
     * to be from the LSB to MSB for all the bits set to '1'.
     */
    const int LAYOUT_MONO = CHANNEL_FRONT_LEFT;
    const int LAYOUT_STEREO =
            CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT;
    const int LAYOUT_2POINT1 =
            CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | CHANNEL_LOW_FREQUENCY;
    const int LAYOUT_TRI =
            CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | CHANNEL_FRONT_CENTER;
    const int LAYOUT_TRI_BACK =
            CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | CHANNEL_BACK_CENTER;
    const int LAYOUT_3POINT1 =
            CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | CHANNEL_FRONT_CENTER |
            CHANNEL_LOW_FREQUENCY;
    const int LAYOUT_2POINT0POINT2 =
            CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
            CHANNEL_TOP_SIDE_LEFT | CHANNEL_TOP_SIDE_RIGHT;
    const int LAYOUT_2POINT1POINT2 =
            LAYOUT_2POINT0POINT2 | CHANNEL_LOW_FREQUENCY;
    const int LAYOUT_3POINT0POINT2 =
            CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
            CHANNEL_FRONT_CENTER |
            CHANNEL_TOP_SIDE_LEFT | CHANNEL_TOP_SIDE_RIGHT;
    const int LAYOUT_3POINT1POINT2 =
            LAYOUT_3POINT0POINT2 | CHANNEL_LOW_FREQUENCY;
    const int LAYOUT_QUAD =
            CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
            CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT;
    const int LAYOUT_QUAD_SIDE =
            CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
            CHANNEL_SIDE_LEFT | CHANNEL_SIDE_RIGHT;
    const int LAYOUT_SURROUND =
            CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
            CHANNEL_FRONT_CENTER | CHANNEL_BACK_CENTER;
    const int LAYOUT_PENTA = LAYOUT_QUAD | CHANNEL_FRONT_CENTER;
    const int LAYOUT_5POINT1 =
            CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
            CHANNEL_FRONT_CENTER | CHANNEL_LOW_FREQUENCY |
            CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT;
    const int LAYOUT_5POINT1_SIDE =
            CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
            CHANNEL_FRONT_CENTER | CHANNEL_LOW_FREQUENCY |
            CHANNEL_SIDE_LEFT | CHANNEL_SIDE_RIGHT;
    const int LAYOUT_5POINT1POINT2 = LAYOUT_5POINT1 |
            CHANNEL_TOP_SIDE_LEFT | CHANNEL_TOP_SIDE_RIGHT;
    const int LAYOUT_5POINT1POINT4 = LAYOUT_5POINT1 |
            CHANNEL_TOP_FRONT_LEFT | CHANNEL_TOP_FRONT_RIGHT |
            CHANNEL_TOP_BACK_LEFT | CHANNEL_TOP_BACK_RIGHT;
    const int LAYOUT_6POINT1 =
            CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
            CHANNEL_FRONT_CENTER | CHANNEL_LOW_FREQUENCY |
            CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT | CHANNEL_BACK_CENTER;
    const int LAYOUT_7POINT1 = LAYOUT_5POINT1 |
            CHANNEL_SIDE_LEFT | CHANNEL_SIDE_RIGHT;
    const int LAYOUT_7POINT1POINT2 = LAYOUT_7POINT1 |
            CHANNEL_TOP_SIDE_LEFT | CHANNEL_TOP_SIDE_RIGHT;
    const int LAYOUT_7POINT1POINT4 = LAYOUT_7POINT1 |
            CHANNEL_TOP_FRONT_LEFT | CHANNEL_TOP_FRONT_RIGHT |
            CHANNEL_TOP_BACK_LEFT | CHANNEL_TOP_BACK_RIGHT;
    const int LAYOUT_9POINT1POINT4 = LAYOUT_7POINT1POINT4 |
            CHANNEL_FRONT_WIDE_LEFT | CHANNEL_FRONT_WIDE_RIGHT;
    const int LAYOUT_9POINT1POINT6 = LAYOUT_9POINT1POINT4 |
            CHANNEL_TOP_SIDE_LEFT | CHANNEL_TOP_SIDE_RIGHT;
    const int LAYOUT_13POINT_360RA =
            CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
            CHANNEL_FRONT_CENTER |
            CHANNEL_SIDE_LEFT | CHANNEL_SIDE_RIGHT |
            CHANNEL_TOP_FRONT_LEFT | CHANNEL_TOP_FRONT_RIGHT |
            CHANNEL_TOP_FRONT_CENTER |
            CHANNEL_TOP_BACK_LEFT | CHANNEL_TOP_BACK_RIGHT |
            CHANNEL_BOTTOM_FRONT_LEFT | CHANNEL_BOTTOM_FRONT_RIGHT |
            CHANNEL_BOTTOM_FRONT_CENTER;
    const int LAYOUT_22POINT2 = LAYOUT_7POINT1POINT4 |
            CHANNEL_FRONT_LEFT_OF_CENTER | CHANNEL_FRONT_RIGHT_OF_CENTER |
            CHANNEL_BACK_CENTER | CHANNEL_TOP_CENTER |
            CHANNEL_TOP_FRONT_CENTER | CHANNEL_TOP_BACK_CENTER |
            CHANNEL_TOP_SIDE_LEFT | CHANNEL_TOP_SIDE_RIGHT |
            CHANNEL_BOTTOM_FRONT_LEFT | CHANNEL_BOTTOM_FRONT_RIGHT |
            CHANNEL_BOTTOM_FRONT_CENTER |
            CHANNEL_LOW_FREQUENCY_2;
    const int LAYOUT_MONO_HAPTIC_A =
            LAYOUT_MONO | CHANNEL_HAPTIC_A;
    const int LAYOUT_STEREO_HAPTIC_A =
            LAYOUT_STEREO | CHANNEL_HAPTIC_A;
    const int LAYOUT_HAPTIC_AB =
            CHANNEL_HAPTIC_A | CHANNEL_HAPTIC_B;
    const int LAYOUT_MONO_HAPTIC_AB =
            LAYOUT_MONO | LAYOUT_HAPTIC_AB;
    const int LAYOUT_STEREO_HAPTIC_AB =
            LAYOUT_STEREO | LAYOUT_HAPTIC_AB;
    const int LAYOUT_FRONT_BACK =
            CHANNEL_FRONT_CENTER | CHANNEL_BACK_CENTER;
    const int LAYOUT_VOICE_UPLINK_MONO =
            LAYOUT_MONO | CHANNEL_VOICE_UPLINK;
    const int LAYOUT_VOICE_DNLINK_MONO =
            LAYOUT_MONO | CHANNEL_VOICE_DNLINK;
    const int LAYOUT_VOICE_CALL_MONO =
            CHANNEL_VOICE_UPLINK | CHANNEL_VOICE_DNLINK;

    /**
     * Expresses the convention when stereo audio samples are stored interleaved
     * in an array.  This should improve readability by allowing code to use
     * symbolic indices instead of hard-coded [0] and [1].
     *
     * For multi-channel beyond stereo, the platform convention is that channels
     * are interleaved in order from least significant channel mask bit to most
     * significant channel mask bit, with unused bits skipped. Any exceptions
     * to this convention will be noted at the appropriate API.
     */
    const int INTERLEAVE_LEFT = 0;
    const int INTERLEAVE_RIGHT = 1;

    /**
     * 'CHANNEL_*' constants are used to build 'LAYOUT_*' masks.
     * Each constant must have exactly one bit set.
     */
    const int CHANNEL_FRONT_LEFT = 1 << 0;
    const int CHANNEL_FRONT_RIGHT = 1 << 1;
    const int CHANNEL_FRONT_CENTER = 1 << 2;
    const int CHANNEL_LOW_FREQUENCY = 1 << 3;
    const int CHANNEL_BACK_LEFT = 1 << 4;
    const int CHANNEL_BACK_RIGHT = 1 << 5;
    const int CHANNEL_FRONT_LEFT_OF_CENTER = 1 << 6;
    const int CHANNEL_FRONT_RIGHT_OF_CENTER = 1 << 7;
    const int CHANNEL_BACK_CENTER = 1 << 8;
    const int CHANNEL_SIDE_LEFT = 1 << 9;
    const int CHANNEL_SIDE_RIGHT = 1 << 10;
    const int CHANNEL_TOP_CENTER = 1 << 11;
    const int CHANNEL_TOP_FRONT_LEFT = 1 << 12;
    const int CHANNEL_TOP_FRONT_CENTER = 1 << 13;
    const int CHANNEL_TOP_FRONT_RIGHT = 1 << 14;
    const int CHANNEL_TOP_BACK_LEFT = 1 << 15;
    const int CHANNEL_TOP_BACK_CENTER = 1 << 16;
    const int CHANNEL_TOP_BACK_RIGHT = 1 << 17;
    const int CHANNEL_TOP_SIDE_LEFT = 1 << 18;
    const int CHANNEL_TOP_SIDE_RIGHT = 1 << 19;
    const int CHANNEL_BOTTOM_FRONT_LEFT = 1 << 20;
    const int CHANNEL_BOTTOM_FRONT_CENTER = 1 << 21;
    const int CHANNEL_BOTTOM_FRONT_RIGHT = 1 << 22;
    const int CHANNEL_LOW_FREQUENCY_2 = 1 << 23;
    const int CHANNEL_FRONT_WIDE_LEFT = 1 << 24;
    const int CHANNEL_FRONT_WIDE_RIGHT = 1 << 25;
    const int CHANNEL_VOICE_UPLINK = 1 << 26;
    const int CHANNEL_VOICE_DNLINK = 1 << 27;
    const int CHANNEL_HAPTIC_B = 1 << 28;  // B then A to match legacy const.
    const int CHANNEL_HAPTIC_A = 1 << 29;
}
+6 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <system/audio.h>

#include <android/media/AudioAttributesInternal.h>
#include <android/media/AudioChannelLayout.h>
#include <android/media/AudioClient.h>
#include <android/media/AudioConfig.h>
#include <android/media/AudioConfigBase.h>
@@ -140,6 +141,11 @@ ConversionResult<audio_format_t> aidl2legacy_AudioFormat_audio_format_t(
ConversionResult<media::AudioFormatSys> legacy2aidl_audio_format_t_AudioFormat(
        audio_format_t legacy);

ConversionResult<audio_channel_mask_t> aidl2legacy_AudioChannelLayout_audio_channel_mask_t(
        const media::AudioChannelLayout& aidl, bool isOutput);
ConversionResult<media::AudioChannelLayout> legacy2aidl_audio_channel_mask_t_AudioChannelLayout(
        audio_channel_mask_t legacy, bool isOutput);

ConversionResult<audio_devices_t> aidl2legacy_AudioDeviceDescription_audio_devices_t(
        const media::AudioDeviceDescription& aidl);
ConversionResult<media::AudioDeviceDescription> legacy2aidl_audio_devices_t_AudioDeviceDescription(
+24 −3
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@

#include <functional>

#include <android/media/AudioChannelLayout.h>
#include <android/media/AudioDeviceDescription.h>
#include <android/media/AudioFormatDescription.h>
#include <binder/Parcelable.h>
@@ -37,9 +38,29 @@ static size_t hash_combine(size_t seed, size_t v) {

namespace std {

// Note: when extending Audio{Device|Format}Description we need to account for the
// possibility of comparison between different versions of it, e.g. a HAL
// may be using a previous version of the AIDL interface.
// Note: when extending the types hashed below we need to account for the
// possibility of processing types belonging to different versions of the type,
// e.g. a HAL may be using a previous version of the AIDL interface.

template<> struct hash<android::media::AudioChannelLayout>
{
    std::size_t operator()(const android::media::AudioChannelLayout& acl) const noexcept {
        using Tag = android::media::AudioChannelLayout::Tag;
        const size_t seed = std::hash<Tag>{}(acl.getTag());
        switch (acl.getTag()) {
            case Tag::none:
                return hash_combine(seed, std::hash<int32_t>{}(acl.get<Tag::none>()));
            case Tag::invalid:
                return hash_combine(seed, std::hash<int32_t>{}(acl.get<Tag::invalid>()));
            case Tag::indexMask:
                return hash_combine(seed, std::hash<int32_t>{}(acl.get<Tag::indexMask>()));
            case Tag::layoutMask:
                return hash_combine(seed, std::hash<int32_t>{}(acl.get<Tag::layoutMask>()));
        }
        return seed;
    }
};

template<> struct hash<android::media::AudioDeviceDescription>
{
    std::size_t operator()(const android::media::AudioDeviceDescription& add) const noexcept {
Loading