summaryrefslogtreecommitdiffstats
path: root/include/media/AudioEffect.h
blob: e9ff8a35e7dfdeec5b6113b6b9d197c728c7fe31 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
/*
 * Copyright (C) 2009 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.
 */

#ifndef ANDROID_AUDIOEFFECT_H
#define ANDROID_AUDIOEFFECT_H

#include <stdint.h>
#include <sys/types.h>

#include <media/IAudioFlinger.h>
#include <media/IEffect.h>
#include <media/IEffectClient.h>
#include <media/EffectApi.h>
#include <media/AudioSystem.h>

#include <utils/RefBase.h>
#include <utils/Errors.h>
#include <binder/IInterface.h>


namespace android {

// ----------------------------------------------------------------------------

class effect_param_cblk_t;

// ----------------------------------------------------------------------------

class AudioEffect : public RefBase
{
public:

    /*
     *  Static methods for effect libraries management.
     */

    /*
     *   Loads the effect library which path is given as first argument.
     *   This must be the full path of a dynamic library (.so) implementing one or
     *   more effect engines and exposing the effect library interface described in
     *   EffectApi.h. The function returns a handle on the library for use by
     *   further call to unloadEffectLibrary() to unload the library.
     *
     *   Parameters:
     *          libPath:    full path of the dynamic library file in the file system.
     *          handle:     address where to return the library handle
     *
     *   Returned status (from utils/Errors.h) can be:
     *          NO_ERROR    successful operation.
     *          PERMISSION_DENIED could not get AudioFlinger interface or
     *                      application does not have permission to configure audio
     *          NO_INIT     effect factory not initialized or
     *                      library could not be loaded or
     *                      library does not implement required functions
     *          BAD_VALUE   invalid libPath string or handle
     *
     *   Returned value:
     *          *handle updated with library handle
     */
    static status_t loadEffectLibrary(const char *libPath, int *handle);

    /*
     *   Unloads the effect library which handle is given as argument.
     *
     *   Parameters:
     *          handle: library handle
     *
     *   Returned status (from utils/Errors.h) can be:
     *          NO_ERROR    successful operation.
     *          PERMISSION_DENIED could not get AudioFlinger interface or
     *                      application does not have permission to configure audio
     *          NO_INIT     effect factory not initialized
     *          BAD_VALUE   invalid handle
     */
    static status_t unloadEffectLibrary(int handle);

    /*
     *  Static methods for effects enumeration.
     */

    /*
     * Returns the number of effects available. This method together
     * with queryEffect() is used to enumerate all effects:
     * The enumeration sequence is:
     *      queryNumberEffects(&num_effects);
     *      for (i = 0; i < num_effects; i++)
     *          queryEffect(i,...);
     *
     * Parameters:
     *      numEffects:    address where the number of effects should be returned.
     *
     * Returned status (from utils/Errors.h) can be:
     *      NO_ERROR   successful operation.
     *      PERMISSION_DENIED could not get AudioFlinger interface
     *      NO_INIT    effect library failed to initialize
     *      BAD_VALUE  invalid numEffects pointer
     *
     * Returned value
     *   *numEffects:     updated with number of effects available
     */
    static status_t queryNumberEffects(uint32_t *numEffects);

    /*
     * Returns an effect descriptor during effect
     * enumeration.
     *
     * Parameters:
     *      index:      index of the queried effect.
     *      descriptor: address where the effect descriptor should be returned.
     *
     * Returned status (from utils/Errors.h) can be:
     *      NO_ERROR        successful operation.
     *      PERMISSION_DENIED could not get AudioFlinger interface
     *      NO_INIT         effect library failed to initialize
     *      BAD_VALUE       invalid descriptor pointer or index
     *      INVALID_OPERATION  effect list has changed since last execution of queryNumberEffects()
     *
     * Returned value
     *   *descriptor:     updated with effect descriptor
     */
    static status_t queryEffect(uint32_t index, effect_descriptor_t *descriptor);


    /*
     * Returns the descriptor for the specified effect uuid.
     *
     * Parameters:
     *      uuid:       pointer to effect uuid.
     *      descriptor: address where the effect descriptor should be returned.
     *
     * Returned status (from utils/Errors.h) can be:
     *      NO_ERROR        successful operation.
     *      PERMISSION_DENIED could not get AudioFlinger interface
     *      NO_INIT         effect library failed to initialize
     *      BAD_VALUE       invalid uuid or descriptor pointers
     *      NAME_NOT_FOUND  no effect with this uuid found
     *
     * Returned value
     *   *descriptor updated with effect descriptor
     */
    static status_t getEffectDescriptor(effect_uuid_t *uuid, effect_descriptor_t *descriptor);


    /*
     * Events used by callback function (effect_callback_t).
     */
    enum event_type {
        EVENT_CONTROL_STATUS_CHANGED = 0,
        EVENT_ENABLE_STATUS_CHANGED = 1,
        EVENT_PARAMETER_CHANGED = 2,
        EVENT_ERROR = 3
    };

    /* Callback function notifying client application of a change in effect engine state or
     * configuration.
     * An effect engine can be shared by several applications but only one has the control
     * of the engine activity and configuration at a time.
     * The EVENT_CONTROL_STATUS_CHANGED event is received when an application loses or
     * retrieves the control of the effect engine. Loss of control happens
     * if another application requests the use of the engine by creating an AudioEffect for
     * the same effect type but with a higher priority. Control is returned when the
     * application having the control deletes its AudioEffect object.
     * The EVENT_ENABLE_STATUS_CHANGED event is received by all applications not having the
     * control of the effect engine when the effect is enabled or disabled.
     * The EVENT_PARAMETER_CHANGED event is received by all applications not having the
     * control of the effect engine when an effect parameter is changed.
     * The EVENT_ERROR event is received when the media server process dies.
     *
     * Parameters:
     *
     * event:   type of event notified (see enum AudioEffect::event_type).
     * user:    Pointer to context for use by the callback receiver.
     * info:    Pointer to optional parameter according to event type:
     *  - EVENT_CONTROL_STATUS_CHANGED:  boolean indicating if control is granted (true)
     *  or stolen (false).
     *  - EVENT_ENABLE_STATUS_CHANGED: boolean indicating if effect is now enabled (true)
     *  or disabled (false).
     *  - EVENT_PARAMETER_CHANGED: pointer to a effect_param_t structure.
     *  - EVENT_ERROR:  status_t indicating the error (DEAD_OBJECT when media server dies).
     */

    typedef void (*effect_callback_t)(int32_t event, void* user, void *info);


    /* Constructor.
     * AudioEffect is the base class for creating and controlling an effect engine from
     * the application process. Creating an AudioEffect object will create the effect engine
     * in the AudioFlinger if no engine of the specified type exists. If one exists, this engine
     * will be used. The application creating the AudioEffect object (or a derived class like
     * Reverb for instance) will either receive control of the effect engine or not, depending
     * on the priority parameter. If priority is higher than the priority used by the current
     * effect engine owner, the control will be transfered to the new application. Otherwise
     * control will remain to the previous application. In this case, the new application will be
     * notified of changes in effect engine state or control ownership by the effect callback.
     * After creating the AudioEffect, the application must call the initCheck() method and
     * check the creation status before trying to control the effect engine (see initCheck()).
     * If the effect is to be applied to an AudioTrack or MediaPlayer only the application
     * must specify the audio session ID corresponding to this player.
     */

    /* Simple Constructor.
     */
    AudioEffect();


    /* Constructor.
     *
     * Parameters:
     *
     * type:  type of effect created: can be null if uuid is specified. This corresponds to
     *        the OpenSL ES interface implemented by this effect.
     * uuid:  Uuid of effect created: can be null if type is specified. This uuid corresponds to
     *        a particular implementation of an effect type.
     * priority:    requested priority for effect control: the priority level corresponds to the
     *      value of priority parameter: negative values indicate lower priorities, positive values
     *      higher priorities, 0 being the normal priority.
     * cbf:         optional callback function (see effect_callback_t)
     * user:        pointer to context for use by the callback receiver.
     * sessionID:   audio session this effect is associated to. If 0, the effect will be global to
     *      the output mix. If not 0, the effect will be applied to all players
     *      (AudioTrack or MediaPLayer) within the same audio session.
     * output:  HAL audio output stream to which this effect must be attached. Leave at 0 for
     *      automatic output selection by AudioFlinger.
     */

    AudioEffect(const effect_uuid_t *type,
                const effect_uuid_t *uuid = NULL,
                  int32_t priority = 0,
                  effect_callback_t cbf = 0,
                  void* user = 0,
                  int sessionId = 0,
                  audio_io_handle_t output = 0
                  );

    /* Constructor.
     *      Same as above but with type and uuid specified by character strings
     */
    AudioEffect(const char *typeStr,
                    const char *uuidStr = NULL,
                    int32_t priority = 0,
                    effect_callback_t cbf = 0,
                    void* user = 0,
                    int sessionId = 0,
                    audio_io_handle_t output = 0
                    );

    /* Terminates the AudioEffect and unregisters it from AudioFlinger.
     * The effect engine is also destroyed if this AudioEffect was the last controlling
     * the engine.
     */
                        ~AudioEffect();

    /* Initialize an uninitialized AudioEffect.
    * Returned status (from utils/Errors.h) can be:
    *  - NO_ERROR or ALREADY_EXISTS: successful initialization
    *  - INVALID_OPERATION: AudioEffect is already initialized
    *  - BAD_VALUE: invalid parameter
    *  - NO_INIT: audio flinger or audio hardware not initialized
    * */
            status_t    set(const effect_uuid_t *type,
                            const effect_uuid_t *uuid = NULL,
                            int32_t priority = 0,
                            effect_callback_t cbf = 0,
                            void* user = 0,
                            int sessionId = 0,
                            audio_io_handle_t output = 0
                            );

    /* Result of constructing the AudioEffect. This must be checked
     * before using any AudioEffect API.
     * initCheck() can return:
     *  - NO_ERROR:    the effect engine is successfully created and the application has control.
     *  - ALREADY_EXISTS: the effect engine is successfully created but the application does not
     *              have control.
     *  - NO_INIT:     the effect creation failed.
     *
     */
            status_t    initCheck() const;


    /* Returns the unique effect Id for the controlled effect engine. This ID is unique
     * system wide and is used for instance in the case of auxiliary effects to attach
     * the effect to an AudioTrack or MediaPlayer.
     *
     */
            int32_t     id() const { return mId; }

    /* Returns a descriptor for the effect (see effect_descriptor_t in EffectApi.h).
     */
            effect_descriptor_t descriptor() const;

    /* Returns effect control priority of this AudioEffect object.
     */
            int32_t     priority() const { return mPriority; }


    /* Enables or disables the effect engine.
     *
     * Parameters:
     *  enabled: requested enable state.
     *
     * Returned status (from utils/Errors.h) can be:
     *  - NO_ERROR: successful operation
     *  - INVALID_OPERATION: the application does not have control of the effect engine or the
     *  effect is already in the requested state.
     */
    virtual status_t    setEnabled(bool enabled);
            bool        getEnabled() const;

    /* Sets a parameter value.
     *
     * Parameters:
     *      param:  pointer to effect_param_t structure containing the parameter
     *          and its value (See EffectApi.h).
     * Returned status (from utils/Errors.h) can be:
     *  - NO_ERROR: successful operation.
     *  - INVALID_OPERATION: the application does not have control of the effect engine.
     *  - BAD_VALUE: invalid parameter identifier or value.
     *  - DEAD_OBJECT: the effect engine has been deleted.
     */
     virtual status_t   setParameter(effect_param_t *param);

    /* Prepare a new parameter value that will be set by next call to
     * setParameterCommit(). This method can be used to set multiple parameters
     * in a synchronous manner or to avoid multiple binder calls for each
     * parameter.
     *
     * Parameters:
     *      param:  pointer to effect_param_t structure containing the parameter
     *          and its value (See EffectApi.h).
     *
     * Returned status (from utils/Errors.h) can be:
     *  - NO_ERROR: successful operation.
     *  - INVALID_OPERATION: the application does not have control of the effect engine.
     *  - NO_MEMORY: no more space available in shared memory used for deferred parameter
     *  setting.
     */
     virtual status_t   setParameterDeferred(effect_param_t *param);

     /* Commit all parameter values previously prepared by setParameterDeferred().
      *
      * Parameters:
      *     none
      *
      * Returned status (from utils/Errors.h) can be:
      *  - NO_ERROR: successful operation.
      *  - INVALID_OPERATION: No new parameter values ready for commit.
      *  - BAD_VALUE: invalid parameter identifier or value: there is no indication
      *     as to which of the parameters caused this error.
      *  - DEAD_OBJECT: the effect engine has been deleted.
      */
     virtual status_t   setParameterCommit();

    /* Gets a parameter value.
     *
     * Parameters:
     *      param:  pointer to effect_param_t structure containing the parameter
     *          and the returned value (See EffectApi.h).
     *
     * Returned status (from utils/Errors.h) can be:
     *  - NO_ERROR: successful operation.
     *  - INVALID_OPERATION: the AudioEffect was not successfully initialized.
     *  - BAD_VALUE: invalid parameter identifier.
     *  - DEAD_OBJECT: the effect engine has been deleted.
     */
     virtual status_t   getParameter(effect_param_t *param);

     /* Sends a command and receives a response to/from effect engine.
      *     See EffectApi.h for details on effect command() function, valid command codes
      *     and formats.
      */
     virtual status_t command(int32_t cmdCode,
                              int32_t cmdSize,
                              void *cmdData,
                              int32_t *replySize,
                              void *replyData);


     /*
      * Utility functions.
      */

     /* Converts the string passed as first argument to the effect_uuid_t
      * pointed to by second argument
      */
     static status_t stringToGuid(const char *str, effect_uuid_t *guid);
     /* Converts the effect_uuid_t pointed to by first argument to the
      * string passed as second argument
      */
     static status_t guidToString(const effect_uuid_t *guid, char *str, size_t maxLen);

protected:
     volatile int32_t        mEnabled;           // enable state
     int32_t                 mSessionId;         // audio session ID
     int32_t                 mPriority;          // priority for effect control
     status_t                mStatus;            // effect status
     effect_callback_t       mCbf;               // callback function for status, control and
                                                 // parameter changes notifications
     void*                   mUserData;          // client context for callback function
     effect_descriptor_t     mDescriptor;        // effect descriptor
     int32_t                 mId;                // system wide unique effect engine instance ID

private:

     // Implements the IEffectClient interface
    class EffectClient : public android::BnEffectClient,  public android::IBinder::DeathRecipient
    {
    public:

        EffectClient(AudioEffect *effect) : mEffect(effect){}

        // IEffectClient
        virtual void controlStatusChanged(bool controlGranted) {
            mEffect->controlStatusChanged(controlGranted);
        }
        virtual void enableStatusChanged(bool enabled) {
            mEffect->enableStatusChanged(enabled);
        }
        virtual void commandExecuted(int cmdCode,
                                     int cmdSize,
                                     void *pCmdData,
                                     int replySize,
                                     void *pReplyData) {
            mEffect->commandExecuted(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
        }

        // IBinder::DeathRecipient
        virtual void binderDied(const wp<IBinder>& who) {mEffect->binderDied();}

    private:
        AudioEffect *mEffect;
    };


    friend class EffectClient;

    // IEffectClient
    void controlStatusChanged(bool controlGranted);
    void enableStatusChanged(bool enabled);
    void commandExecuted(int cmdCode, int cmdSize, void *pCmdData, int replySize, void *pReplyData);
    void binderDied();


    sp<IEffect>             mIEffect;           // IEffect binder interface
    sp<EffectClient>        mIEffectClient;     // IEffectClient implementation
    sp<IMemory>             mCblkMemory;        // shared memory for deferred parameter setting
    effect_param_cblk_t*    mCblk;              // control block for deferred parameter setting
};


}; // namespace android

#endif // ANDROID_AUDIOEFFECT_H