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