AudioEffect.h revision 65580f9adf6c4d98449ad0716488f9fe3869aa5a
1/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ANDROID_AUDIOEFFECT_H
18#define ANDROID_AUDIOEFFECT_H
19
20#include <stdint.h>
21#include <sys/types.h>
22
23#include <media/IAudioFlinger.h>
24#include <media/IEffect.h>
25#include <media/IEffectClient.h>
26#include <hardware/audio_effect.h>
27#include <media/AudioSystem.h>
28
29#include <utils/RefBase.h>
30#include <utils/Errors.h>
31#include <binder/IInterface.h>
32
33
34namespace android {
35
36// ----------------------------------------------------------------------------
37
38class effect_param_cblk_t;
39
40// ----------------------------------------------------------------------------
41
42class AudioEffect : public RefBase
43{
44public:
45
46    /*
47     *  Static methods for effects enumeration.
48     */
49
50    /*
51     * Returns the number of effects available. This method together
52     * with queryEffect() is used to enumerate all effects:
53     * The enumeration sequence is:
54     *      queryNumberEffects(&num_effects);
55     *      for (i = 0; i < num_effects; i++)
56     *          queryEffect(i,...);
57     *
58     * Parameters:
59     *      numEffects:    address where the number of effects should be returned.
60     *
61     * Returned status (from utils/Errors.h) can be:
62     *      NO_ERROR   successful operation.
63     *      PERMISSION_DENIED could not get AudioFlinger interface
64     *      NO_INIT    effect library failed to initialize
65     *      BAD_VALUE  invalid numEffects pointer
66     *
67     * Returned value
68     *   *numEffects:     updated with number of effects available
69     */
70    static status_t queryNumberEffects(uint32_t *numEffects);
71
72    /*
73     * Returns an effect descriptor during effect
74     * enumeration.
75     *
76     * Parameters:
77     *      index:      index of the queried effect.
78     *      descriptor: address where the effect descriptor should be returned.
79     *
80     * Returned status (from utils/Errors.h) can be:
81     *      NO_ERROR        successful operation.
82     *      PERMISSION_DENIED could not get AudioFlinger interface
83     *      NO_INIT         effect library failed to initialize
84     *      BAD_VALUE       invalid descriptor pointer or index
85     *      INVALID_OPERATION  effect list has changed since last execution of queryNumberEffects()
86     *
87     * Returned value
88     *   *descriptor:     updated with effect descriptor
89     */
90    static status_t queryEffect(uint32_t index, effect_descriptor_t *descriptor);
91
92
93    /*
94     * Returns the descriptor for the specified effect uuid.
95     *
96     * Parameters:
97     *      uuid:       pointer to effect uuid.
98     *      descriptor: address where the effect descriptor should be returned.
99     *
100     * Returned status (from utils/Errors.h) can be:
101     *      NO_ERROR        successful operation.
102     *      PERMISSION_DENIED could not get AudioFlinger interface
103     *      NO_INIT         effect library failed to initialize
104     *      BAD_VALUE       invalid uuid or descriptor pointers
105     *      NAME_NOT_FOUND  no effect with this uuid found
106     *
107     * Returned value
108     *   *descriptor updated with effect descriptor
109     */
110    static status_t getEffectDescriptor(effect_uuid_t *uuid, effect_descriptor_t *descriptor);
111
112
113    /*
114     * Events used by callback function (effect_callback_t).
115     */
116    enum event_type {
117        EVENT_CONTROL_STATUS_CHANGED = 0,
118        EVENT_ENABLE_STATUS_CHANGED = 1,
119        EVENT_PARAMETER_CHANGED = 2,
120        EVENT_ERROR = 3
121    };
122
123    /* Callback function notifying client application of a change in effect engine state or
124     * configuration.
125     * An effect engine can be shared by several applications but only one has the control
126     * of the engine activity and configuration at a time.
127     * The EVENT_CONTROL_STATUS_CHANGED event is received when an application loses or
128     * retrieves the control of the effect engine. Loss of control happens
129     * if another application requests the use of the engine by creating an AudioEffect for
130     * the same effect type but with a higher priority. Control is returned when the
131     * application having the control deletes its AudioEffect object.
132     * The EVENT_ENABLE_STATUS_CHANGED event is received by all applications not having the
133     * control of the effect engine when the effect is enabled or disabled.
134     * The EVENT_PARAMETER_CHANGED event is received by all applications not having the
135     * control of the effect engine when an effect parameter is changed.
136     * The EVENT_ERROR event is received when the media server process dies.
137     *
138     * Parameters:
139     *
140     * event:   type of event notified (see enum AudioEffect::event_type).
141     * user:    Pointer to context for use by the callback receiver.
142     * info:    Pointer to optional parameter according to event type:
143     *  - EVENT_CONTROL_STATUS_CHANGED:  boolean indicating if control is granted (true)
144     *  or stolen (false).
145     *  - EVENT_ENABLE_STATUS_CHANGED: boolean indicating if effect is now enabled (true)
146     *  or disabled (false).
147     *  - EVENT_PARAMETER_CHANGED: pointer to a effect_param_t structure.
148     *  - EVENT_ERROR:  status_t indicating the error (DEAD_OBJECT when media server dies).
149     */
150
151    typedef void (*effect_callback_t)(int32_t event, void* user, void *info);
152
153
154    /* Constructor.
155     * AudioEffect is the base class for creating and controlling an effect engine from
156     * the application process. Creating an AudioEffect object will create the effect engine
157     * in the AudioFlinger if no engine of the specified type exists. If one exists, this engine
158     * will be used. The application creating the AudioEffect object (or a derived class like
159     * Reverb for instance) will either receive control of the effect engine or not, depending
160     * on the priority parameter. If priority is higher than the priority used by the current
161     * effect engine owner, the control will be transfered to the new application. Otherwise
162     * control will remain to the previous application. In this case, the new application will be
163     * notified of changes in effect engine state or control ownership by the effect callback.
164     * After creating the AudioEffect, the application must call the initCheck() method and
165     * check the creation status before trying to control the effect engine (see initCheck()).
166     * If the effect is to be applied to an AudioTrack or MediaPlayer only the application
167     * must specify the audio session ID corresponding to this player.
168     */
169
170    /* Simple Constructor.
171     */
172    AudioEffect();
173
174
175    /* Constructor.
176     *
177     * Parameters:
178     *
179     * type:  type of effect created: can be null if uuid is specified. This corresponds to
180     *        the OpenSL ES interface implemented by this effect.
181     * uuid:  Uuid of effect created: can be null if type is specified. This uuid corresponds to
182     *        a particular implementation of an effect type.
183     * priority:    requested priority for effect control: the priority level corresponds to the
184     *      value of priority parameter: negative values indicate lower priorities, positive values
185     *      higher priorities, 0 being the normal priority.
186     * cbf:         optional callback function (see effect_callback_t)
187     * user:        pointer to context for use by the callback receiver.
188     * sessionID:   audio session this effect is associated to. If 0, the effect will be global to
189     *      the output mix. If not 0, the effect will be applied to all players
190     *      (AudioTrack or MediaPLayer) within the same audio session.
191     * output:  HAL audio output stream to which this effect must be attached. Leave at 0 for
192     *      automatic output selection by AudioFlinger.
193     */
194
195    AudioEffect(const effect_uuid_t *type,
196                const effect_uuid_t *uuid = NULL,
197                  int32_t priority = 0,
198                  effect_callback_t cbf = 0,
199                  void* user = 0,
200                  int sessionId = 0,
201                  audio_io_handle_t output = 0
202                  );
203
204    /* Constructor.
205     *      Same as above but with type and uuid specified by character strings
206     */
207    AudioEffect(const char *typeStr,
208                    const char *uuidStr = NULL,
209                    int32_t priority = 0,
210                    effect_callback_t cbf = 0,
211                    void* user = 0,
212                    int sessionId = 0,
213                    audio_io_handle_t output = 0
214                    );
215
216    /* Terminates the AudioEffect and unregisters it from AudioFlinger.
217     * The effect engine is also destroyed if this AudioEffect was the last controlling
218     * the engine.
219     */
220                        ~AudioEffect();
221
222    /* Initialize an uninitialized AudioEffect.
223    * Returned status (from utils/Errors.h) can be:
224    *  - NO_ERROR or ALREADY_EXISTS: successful initialization
225    *  - INVALID_OPERATION: AudioEffect is already initialized
226    *  - BAD_VALUE: invalid parameter
227    *  - NO_INIT: audio flinger or audio hardware not initialized
228    * */
229            status_t    set(const effect_uuid_t *type,
230                            const effect_uuid_t *uuid = NULL,
231                            int32_t priority = 0,
232                            effect_callback_t cbf = 0,
233                            void* user = 0,
234                            int sessionId = 0,
235                            audio_io_handle_t output = 0
236                            );
237
238    /* Result of constructing the AudioEffect. This must be checked
239     * before using any AudioEffect API.
240     * initCheck() can return:
241     *  - NO_ERROR:    the effect engine is successfully created and the application has control.
242     *  - ALREADY_EXISTS: the effect engine is successfully created but the application does not
243     *              have control.
244     *  - NO_INIT:     the effect creation failed.
245     *
246     */
247            status_t    initCheck() const;
248
249
250    /* Returns the unique effect Id for the controlled effect engine. This ID is unique
251     * system wide and is used for instance in the case of auxiliary effects to attach
252     * the effect to an AudioTrack or MediaPlayer.
253     *
254     */
255            int32_t     id() const { return mId; }
256
257    /* Returns a descriptor for the effect (see effect_descriptor_t in audio_effect.h).
258     */
259            effect_descriptor_t descriptor() const;
260
261    /* Returns effect control priority of this AudioEffect object.
262     */
263            int32_t     priority() const { return mPriority; }
264
265
266    /* Enables or disables the effect engine.
267     *
268     * Parameters:
269     *  enabled: requested enable state.
270     *
271     * Returned status (from utils/Errors.h) can be:
272     *  - NO_ERROR: successful operation
273     *  - INVALID_OPERATION: the application does not have control of the effect engine or the
274     *  effect is already in the requested state.
275     */
276    virtual status_t    setEnabled(bool enabled);
277            bool        getEnabled() const;
278
279    /* Sets a parameter value.
280     *
281     * Parameters:
282     *      param:  pointer to effect_param_t structure containing the parameter
283     *          and its value (See audio_effect.h).
284     * Returned status (from utils/Errors.h) can be:
285     *  - NO_ERROR: successful operation.
286     *  - INVALID_OPERATION: the application does not have control of the effect engine.
287     *  - BAD_VALUE: invalid parameter identifier or value.
288     *  - DEAD_OBJECT: the effect engine has been deleted.
289     */
290     virtual status_t   setParameter(effect_param_t *param);
291
292    /* Prepare a new parameter value that will be set by next call to
293     * setParameterCommit(). This method can be used to set multiple parameters
294     * in a synchronous manner or to avoid multiple binder calls for each
295     * parameter.
296     *
297     * Parameters:
298     *      param:  pointer to effect_param_t structure containing the parameter
299     *          and its value (See audio_effect.h).
300     *
301     * Returned status (from utils/Errors.h) can be:
302     *  - NO_ERROR: successful operation.
303     *  - INVALID_OPERATION: the application does not have control of the effect engine.
304     *  - NO_MEMORY: no more space available in shared memory used for deferred parameter
305     *  setting.
306     */
307     virtual status_t   setParameterDeferred(effect_param_t *param);
308
309     /* Commit all parameter values previously prepared by setParameterDeferred().
310      *
311      * Parameters:
312      *     none
313      *
314      * Returned status (from utils/Errors.h) can be:
315      *  - NO_ERROR: successful operation.
316      *  - INVALID_OPERATION: No new parameter values ready for commit.
317      *  - BAD_VALUE: invalid parameter identifier or value: there is no indication
318      *     as to which of the parameters caused this error.
319      *  - DEAD_OBJECT: the effect engine has been deleted.
320      */
321     virtual status_t   setParameterCommit();
322
323    /* Gets a parameter value.
324     *
325     * Parameters:
326     *      param:  pointer to effect_param_t structure containing the parameter
327     *          and the returned value (See audio_effect.h).
328     *
329     * Returned status (from utils/Errors.h) can be:
330     *  - NO_ERROR: successful operation.
331     *  - INVALID_OPERATION: the AudioEffect was not successfully initialized.
332     *  - BAD_VALUE: invalid parameter identifier.
333     *  - DEAD_OBJECT: the effect engine has been deleted.
334     */
335     virtual status_t   getParameter(effect_param_t *param);
336
337     /* Sends a command and receives a response to/from effect engine.
338      *     See audio_effect.h for details on effect command() function, valid command codes
339      *     and formats.
340      */
341     virtual status_t command(uint32_t cmdCode,
342                              uint32_t cmdSize,
343                              void *cmdData,
344                              uint32_t *replySize,
345                              void *replyData);
346
347
348     /*
349      * Utility functions.
350      */
351
352     /* Converts the string passed as first argument to the effect_uuid_t
353      * pointed to by second argument
354      */
355     static status_t stringToGuid(const char *str, effect_uuid_t *guid);
356     /* Converts the effect_uuid_t pointed to by first argument to the
357      * string passed as second argument
358      */
359     static status_t guidToString(const effect_uuid_t *guid, char *str, size_t maxLen);
360
361protected:
362     bool                    mEnabled;           // enable state
363     int32_t                 mSessionId;         // audio session ID
364     int32_t                 mPriority;          // priority for effect control
365     status_t                mStatus;            // effect status
366     effect_callback_t       mCbf;               // callback function for status, control and
367                                                 // parameter changes notifications
368     void*                   mUserData;          // client context for callback function
369     effect_descriptor_t     mDescriptor;        // effect descriptor
370     int32_t                 mId;                // system wide unique effect engine instance ID
371     Mutex                   mLock;               // Mutex for mEnabled access
372
373private:
374
375     // Implements the IEffectClient interface
376    class EffectClient : public android::BnEffectClient,  public android::IBinder::DeathRecipient
377    {
378    public:
379
380        EffectClient(AudioEffect *effect) : mEffect(effect){}
381
382        // IEffectClient
383        virtual void controlStatusChanged(bool controlGranted) {
384            mEffect->controlStatusChanged(controlGranted);
385        }
386        virtual void enableStatusChanged(bool enabled) {
387            mEffect->enableStatusChanged(enabled);
388        }
389        virtual void commandExecuted(uint32_t cmdCode,
390                                     uint32_t cmdSize,
391                                     void *pCmdData,
392                                     uint32_t replySize,
393                                     void *pReplyData) {
394            mEffect->commandExecuted(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
395        }
396
397        // IBinder::DeathRecipient
398        virtual void binderDied(const wp<IBinder>& who) {mEffect->binderDied();}
399
400    private:
401        AudioEffect *mEffect;
402    };
403
404
405    friend class EffectClient;
406
407    // IEffectClient
408    void controlStatusChanged(bool controlGranted);
409    void enableStatusChanged(bool enabled);
410    void commandExecuted(uint32_t cmdCode,
411                         uint32_t cmdSize,
412                         void *pCmdData,
413                         uint32_t replySize,
414                         void *pReplyData);
415    void binderDied();
416
417
418    sp<IEffect>             mIEffect;           // IEffect binder interface
419    sp<EffectClient>        mIEffectClient;     // IEffectClient implementation
420    sp<IMemory>             mCblkMemory;        // shared memory for deferred parameter setting
421    effect_param_cblk_t*    mCblk;              // control block for deferred parameter setting
422};
423
424
425}; // namespace android
426
427#endif // ANDROID_AUDIOEFFECT_H
428