1ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu/*
2ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu * Copyright (C) 2014 The Android Open Source Project
3ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu *
4ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu * Licensed under the Apache License, Version 2.0 (the "License");
5ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu * you may not use this file except in compliance with the License.
6ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu * You may obtain a copy of the License at
7ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu *
8ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu *      http://www.apache.org/licenses/LICENSE-2.0
9ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu *
10ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu * Unless required by applicable law or agreed to in writing, software
11ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu * distributed under the License is distributed on an "AS IS" BASIS,
12ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu * See the License for the specific language governing permissions and
14ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu * limitations under the License.
15ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu */
16ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
17ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu#ifndef ANDROID_AUDIOPOLICYEFFECTS_H
18ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu#define ANDROID_AUDIOPOLICYEFFECTS_H
19ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
20ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu#include <stdlib.h>
21ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu#include <stdio.h>
22ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu#include <string.h>
23ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu#include <cutils/misc.h>
24ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu#include <media/AudioEffect.h>
25ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu#include <system/audio.h>
26ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu#include <hardware/audio_effect.h>
27ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu#include <utils/Vector.h>
28ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu#include <utils/SortedVector.h>
29ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
30ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liunamespace android {
31ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
32ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu// ----------------------------------------------------------------------------
33ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
34ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu// AudioPolicyEffects class
35ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu// This class will manage all effects attached to input and output streams in
36ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu// AudioPolicyService as configured in audio_effects.conf.
37ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liuclass AudioPolicyEffects : public RefBase
38ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{
39ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
40ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liupublic:
41ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
42ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    // The constructor will parse audio_effects.conf
43ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    // First it will look whether vendor specific file exists,
44ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    // otherwise it will parse the system default file.
45ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu	         AudioPolicyEffects();
46ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    virtual ~AudioPolicyEffects();
47ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
488b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent    // NOTE: methods on AudioPolicyEffects should never be called with the AudioPolicyService
498b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent    // main mutex (mLock) held as they will indirectly call back into AudioPolicyService when
508b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent    // managing audio effects.
518b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent
52ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    // Return a list of effect descriptors for default input effects
53ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    // associated with audioSession
54ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    status_t queryDefaultInputEffects(int audioSession,
55ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                             effect_descriptor_t *descriptors,
56ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                             uint32_t *count);
57ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
58ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    // Add all input effects associated with this input
59ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    // Effects are attached depending on the audio_source_t
60ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    status_t addInputEffects(audio_io_handle_t input,
61ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                             audio_source_t inputSource,
62ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                             int audioSession);
63ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
64ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    // Add all input effects associated to this input
65ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    status_t releaseInputEffects(audio_io_handle_t input);
66ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
67ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
68ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    // Return a list of effect descriptors for default output effects
69ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    // associated with audioSession
70ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    status_t queryDefaultOutputSessionEffects(int audioSession,
71ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                             effect_descriptor_t *descriptors,
72ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                             uint32_t *count);
73ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
74ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    // Add all output effects associated to this output
75ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    // Effects are attached depending on the audio_stream_type_t
76ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    status_t addOutputSessionEffects(audio_io_handle_t output,
77ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                             audio_stream_type_t stream,
78ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                             int audioSession);
79ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
80ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    // release all output effects associated with this output stream and audiosession
81ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    status_t releaseOutputSessionEffects(audio_io_handle_t output,
82ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                             audio_stream_type_t stream,
83ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                             int audioSession);
84ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
85ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liuprivate:
86ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
87ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    // class to store the description of an effects and its parameters
88ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    // as defined in audio_effects.conf
89ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    class EffectDesc {
90ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    public:
91ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        EffectDesc(const char *name, const effect_uuid_t& uuid) :
92ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                        mName(strdup(name)),
93ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                        mUuid(uuid) { }
94ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        EffectDesc(const EffectDesc& orig) :
95ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                        mName(strdup(orig.mName)),
96ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                        mUuid(orig.mUuid) {
97ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                            // deep copy mParams
98ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                            for (size_t k = 0; k < orig.mParams.size(); k++) {
99ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                                effect_param_t *origParam = orig.mParams[k];
100ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                                // psize and vsize are rounded up to an int boundary for allocation
101ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                                size_t origSize = sizeof(effect_param_t) +
102ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                                                  ((origParam->psize + 3) & ~3) +
103ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                                                  ((origParam->vsize + 3) & ~3);
104ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                                effect_param_t *dupParam = (effect_param_t *) malloc(origSize);
105ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                                memcpy(dupParam, origParam, origSize);
106ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                                // This works because the param buffer allocation is also done by
107ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                                // multiples of 4 bytes originally. In theory we should memcpy only
108ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                                // the actual param size, that is without rounding vsize.
109ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                                mParams.add(dupParam);
110ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                            }
111ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                        }
112ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        /*virtual*/ ~EffectDesc() {
113ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            free(mName);
114ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            for (size_t k = 0; k < mParams.size(); k++) {
115ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                free(mParams[k]);
116ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            }
117ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        }
118ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        char *mName;
119ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        effect_uuid_t mUuid;
120ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        Vector <effect_param_t *> mParams;
121ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    };
122ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
123ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    // class to store voctor of EffectDesc
124ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    class EffectDescVector {
125ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    public:
126ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        EffectDescVector() {}
127ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        /*virtual*/ ~EffectDescVector() {
128ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            for (size_t j = 0; j < mEffects.size(); j++) {
129ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                delete mEffects[j];
130ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            }
131ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        }
132ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        Vector <EffectDesc *> mEffects;
133ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    };
134ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
135ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    // class to store voctor of AudioEffects
136ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    class EffectVector {
137ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    public:
138890a5637b3e3eb197fd2c7f5deec816c7feb13fcbryant_liu        EffectVector(int session) : mSessionId(session), mRefCount(0) {}
139ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        /*virtual*/ ~EffectVector() {}
1408b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent
1418b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent        // Enable or disable all effects in effect vector
1428b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent        void setProcessorEnabled(bool enabled);
1438b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent
144ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        const int mSessionId;
145890a5637b3e3eb197fd2c7f5deec816c7feb13fcbryant_liu        // AudioPolicyManager keeps mLock, no need for lock on reference count here
146890a5637b3e3eb197fd2c7f5deec816c7feb13fcbryant_liu        int mRefCount;
147ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        Vector< sp<AudioEffect> >mEffects;
148ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    };
149ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
150ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
151ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    static const char * const kInputSourceNames[AUDIO_SOURCE_CNT -1];
1528b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent    static audio_source_t inputSourceNameToEnum(const char *name);
153ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
154223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    static const char *kStreamNames[AUDIO_STREAM_PUBLIC_CNT+1]; //+1 required as streams start from -1
155ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    audio_stream_type_t streamNameToEnum(const char *name);
156ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
157ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    // Parse audio_effects.conf
158ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    status_t loadAudioEffectConfig(const char *path);
159ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
160ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    // Load all effects descriptors in configuration file
161ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    status_t loadEffects(cnode *root, Vector <EffectDesc *>& effects);
162ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    EffectDesc *loadEffect(cnode *root);
163ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
164ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    // Load all automatic effect configurations
165ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    status_t loadInputEffectConfigurations(cnode *root, const Vector <EffectDesc *>& effects);
166ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    status_t loadStreamEffectConfigurations(cnode *root, const Vector <EffectDesc *>& effects);
167ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    EffectDescVector *loadEffectConfig(cnode *root, const Vector <EffectDesc *>& effects);
168ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
169ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    // Load all automatic effect parameters
170ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    void loadEffectParameters(cnode *root, Vector <effect_param_t *>& params);
171ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    effect_param_t *loadEffectParameter(cnode *root);
172ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    size_t readParamValue(cnode *node,
173ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                          char *param,
174ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                          size_t *curSize,
175ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                          size_t *totSize);
176ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    size_t growParamSize(char *param,
177ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                         size_t size,
178ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                         size_t *curSize,
179ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                         size_t *totSize);
180ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
1818b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent    // protects access to mInputSources, mInputs, mOutputStreams, mOutputSessions
1828b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent    Mutex mLock;
183ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    // Automatic input effects are configured per audio_source_t
184ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    KeyedVector< audio_source_t, EffectDescVector* > mInputSources;
185ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    // Automatic input effects are unique for audio_io_handle_t
186ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    KeyedVector< audio_io_handle_t, EffectVector* > mInputs;
187ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
188ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    // Automatic output effects are organized per audio_stream_type_t
189ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    KeyedVector< audio_stream_type_t, EffectDescVector* > mOutputStreams;
190ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    // Automatic output effects are unique for audiosession ID
191ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    KeyedVector< int32_t, EffectVector* > mOutputSessions;
192ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu};
193ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
194ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu}; // namespace android
195ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
196ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu#endif // ANDROID_AUDIOPOLICYEFFECTS_H
197