156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi/*
256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * Copyright (C) 2015 The Android Open Source Project
356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi *
456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License");
556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * you may not use this file except in compliance with the License.
656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * You may obtain a copy of the License at
756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi *
856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi *      http://www.apache.org/licenses/LICENSE-2.0
956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi *
1056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * Unless required by applicable law or agreed to in writing, software
1156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS,
1256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * See the License for the specific language governing permissions and
1456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * limitations under the License.
1556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi */
1656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
17ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie#pragma once
18ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie
19cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie#include "AudioCollections.h"
20112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie#include "AudioProfile.h"
21ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie#include <utils/String8.h>
22ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie#include <utils/Vector.h>
23ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie#include <utils/RefBase.h>
24ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie#include <utils/Errors.h>
25ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie#include <system/audio.h>
26ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie#include <cutils/config_utils.h>
27ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie
2856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivinamespace android {
2956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
3056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Triviclass HwModule;
31ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffieclass AudioGain;
32cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffieclass AudioRoute;
33a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffietypedef Vector<sp<AudioGain> > AudioGainCollection;
3456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
3553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffieclass AudioPort : public virtual RefBase
3656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
3756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivipublic:
38a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie    AudioPort(const String8& name, audio_port_type_t type,  audio_port_role_t role) :
39a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie        mName(name), mType(type), mRole(role), mFlags(AUDIO_OUTPUT_FLAG_NONE) {}
40a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie
4156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    virtual ~AudioPort() {}
4256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
431d4481fb9cb1ea149f79f2a5d22110af84fbc90bFrançois Gaffie    void setName(const String8 &name) { mName = name; }
44a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie    const String8 &getName() const { return mName; }
45a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie
46a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie    audio_port_type_t getType() const { return mType; }
47a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie    audio_port_role_t getRole() const { return mRole; }
48a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie
49cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie    virtual const String8 getTagName() const = 0;
50cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie
51a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie    void setGains(const AudioGainCollection &gains) { mGains = gains; }
52a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie    const AudioGainCollection &getGains() const { return mGains; }
53a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie
54f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie    void setFlags(uint32_t flags)
55f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie    {
56f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie        //force direct flag if offload flag is set: offloading implies a direct output stream
57f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie        // and all common behaviors are driven by checking only the direct flag
58f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie        // this should normally be set appropriately in the policy configuration file
59f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie        if (mRole == AUDIO_PORT_ROLE_SOURCE && (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
60f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie            flags |= AUDIO_OUTPUT_FLAG_DIRECT;
61f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie        }
62f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie        mFlags = flags;
63f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie    }
64a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie    uint32_t getFlags() const { return mFlags; }
65a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie
66322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent    virtual void attach(const sp<HwModule>& module);
67322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent    bool isAttached() { return mModule != 0; }
6856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
69f0c6d7d940314dbec47c9b53cb99da79eb022787Glenn Kasten    // Audio port IDs are in a different namespace than AudioFlinger unique IDs
7098cc191247388132b6fd8a4ecd07abd6e4c5a0edFrançois Gaffie    static audio_port_handle_t getNextUniqueId();
7198cc191247388132b6fd8a4ecd07abd6e4c5a0edFrançois Gaffie
7256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    virtual void toAudioPort(struct audio_port *port) const;
7356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
74e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsieh    virtual void importAudioPort(const sp<AudioPort>& port);
7556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
76112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    void addAudioProfile(const sp<AudioProfile> &profile) { mProfiles.add(profile); }
77112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie
78112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    void setAudioProfiles(const AudioProfileVector &profiles) { mProfiles = profiles; }
79112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    AudioProfileVector &getAudioProfiles() { return mProfiles; }
80112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie
81112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    bool hasValidAudioProfile() const { return mProfiles.hasValidProfile(); }
82112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie
83112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    bool hasDynamicAudioProfile() const { return mProfiles.hasDynamicProfile(); }
84112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie
85112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    // searches for an exact match
86112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    status_t checkExactAudioProfile(uint32_t samplingRate,
87112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie                                    audio_channel_mask_t channelMask,
88112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie                                    audio_format_t format) const
89a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie    {
90112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie        return mProfiles.checkExactProfile(samplingRate, channelMask, format);
91a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie    }
92112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie
93112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    // searches for a compatible match, currently implemented for input
94112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    // parameters are input|output, returned value is the best match.
95112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    status_t checkCompatibleAudioProfile(uint32_t &samplingRate,
96112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie                                         audio_channel_mask_t &channelMask,
97112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie                                         audio_format_t &format) const
98a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie    {
99112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie        return mProfiles.checkCompatibleProfile(samplingRate, channelMask, format, mType, mRole);
100a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie    }
10156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
102112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    void clearAudioProfiles() { return mProfiles.clearProfiles(); }
103112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie
10456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    status_t checkGain(const struct audio_gain_config *gainConfig, int index) const;
10556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
106112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    void pickAudioProfile(uint32_t &samplingRate,
107112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie                          audio_channel_mask_t &channelMask,
108112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie                          audio_format_t &format) const;
10956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
11056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    static const audio_format_t sPcmFormatCompareTable[];
111112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie
11256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    static int compareFormats(audio_format_t format1, audio_format_t format2);
11356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
114e693002b0fb25099540588245892ed98103749baEric Laurent    // Used to select an audio HAL output stream with a sample format providing the
115e693002b0fb25099540588245892ed98103749baEric Laurent    // less degradation for a given AudioTrack sample format.
116e693002b0fb25099540588245892ed98103749baEric Laurent    static bool isBetterFormatMatch(audio_format_t newFormat,
117e693002b0fb25099540588245892ed98103749baEric Laurent                                        audio_format_t currentFormat,
118e693002b0fb25099540588245892ed98103749baEric Laurent                                        audio_format_t targetFormat);
119e693002b0fb25099540588245892ed98103749baEric Laurent
12053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    audio_module_handle_t getModuleHandle() const;
1219ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov    uint32_t getModuleVersionMajor() const;
122322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent    const char *getModuleName() const;
12353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie
124a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie    bool useInputChannelMask() const
125a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie    {
126a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie        return ((mType == AUDIO_PORT_TYPE_DEVICE) && (mRole == AUDIO_PORT_ROLE_SOURCE)) ||
127a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie                ((mType == AUDIO_PORT_TYPE_MIX) && (mRole == AUDIO_PORT_ROLE_SINK));
128a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie    }
129a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie
130112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    inline bool isDirectOutput() const
131112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    {
132112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie        return (mType == AUDIO_PORT_TYPE_MIX) && (mRole == AUDIO_PORT_ROLE_SOURCE) &&
133112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie                (mFlags & (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD));
134112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    }
135112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie
136cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie    void addRoute(const sp<AudioRoute> &route) { mRoutes.add(route); }
137cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie    const AudioRouteVector &getRoutes() const { return mRoutes; }
138cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie
139112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    void dump(int fd, int spaces, bool verbose = true) const;
140aa9811945f575614b3482d09e4d969792701cebbPaul McLean    void log(const char* indent) const;
14156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
142a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie    AudioGainCollection mGains; // gain controllers
14356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    sp<HwModule> mModule;                 // audio HW module exposing this I/O stream
14456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
145ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffieprivate:
146112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    void pickChannelMask(audio_channel_mask_t &channelMask, const ChannelsVector &channelMasks) const;
147112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    void pickSamplingRate(uint32_t &rate,const SampleRateVector &samplingRates) const;
148112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie
149cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie    String8  mName;
150a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie    audio_port_type_t mType;
151a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie    audio_port_role_t mRole;
152a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie    uint32_t mFlags; // attribute flags mask (e.g primary output, direct output...).
153112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    AudioProfileVector mProfiles; // AudioProfiles supported by this port (format, Rates, Channels)
154cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie    AudioRouteVector mRoutes; // Routes involving this port
155ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie    static volatile int32_t mNextUniqueId;
15656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi};
15756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
15853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffieclass AudioPortConfig : public virtual RefBase
15956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
16056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivipublic:
16156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    AudioPortConfig();
16256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    virtual ~AudioPortConfig() {}
16356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
16456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    status_t applyAudioPortConfig(const struct audio_port_config *config,
165112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie                                  struct audio_port_config *backupConfig = NULL);
16656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
167112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie                                   const struct audio_port_config *srcConfig = NULL) const = 0;
16856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    virtual sp<AudioPort> getAudioPort() const = 0;
169fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    virtual bool hasSameHwModuleAs(const sp<AudioPortConfig>& other) const {
170fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        return (other != 0) &&
171fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                (other->getAudioPort()->getModuleHandle() == getAudioPort()->getModuleHandle());
172fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    }
17356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    uint32_t mSamplingRate;
17456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    audio_format_t mFormat;
17556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    audio_channel_mask_t mChannelMask;
17656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    struct audio_gain_config mGain;
17756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi};
17856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
17956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}; // namespace android
180