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
|
/*
* 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/IAudioPolicyService.h>
#include <media/IEffect.h>
#include <media/IEffectClient.h>
#include <hardware/audio_effect.h>
#include <media/AudioSystem.h>
#include <utils/RefBase.h>
#include <utils/Errors.h>
#include <binder/IInterface.h>
namespace android {
// ----------------------------------------------------------------------------
struct effect_param_cblk_t;
// ----------------------------------------------------------------------------
class AudioEffect : public RefBase
{
public:
/*
* 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(const effect_uuid_t *uuid,
effect_descriptor_t *descriptor) /*const*/;
/*
* Returns a list of descriptors corresponding to the pre processings enabled by default
* on an AudioRecord with the supplied audio session ID.
*
* Parameters:
* audioSession: audio session ID.
* descriptors: address where the effect descriptors should be returned.
* count: as input, the maximum number of descriptor than should be returned
* as output, the number of descriptor returned if status is NO_ERROR or the actual
* number of enabled pre processings if status is NO_MEMORY
*
* Returned status (from utils/Errors.h) can be:
* NO_ERROR successful operation.
* NO_MEMORY the number of descriptor to return is more than the maximum number
* indicated by count.
* PERMISSION_DENIED could not get AudioFlinger interface
* NO_INIT effect library failed to initialize
* BAD_VALUE invalid audio session or descriptor pointers
*
* Returned value
* *descriptor updated with descriptors of pre processings enabled by default
* *count number of descriptors returned if returned status is NO_ERROR.
* total number of pre processing enabled by default if returned status is
* NO_MEMORY. This happens if the count passed as input is less than the number
* of descriptors to return.
* *count is limited to kMaxPreProcessing on return.
*/
static status_t queryDefaultPreProcessing(int audioSession,
effect_descriptor_t *descriptors,
uint32_t *count);
/*
* 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 equal to AUDIO_SESSION_OUTPUT_MIX, the effect will be global to
* the output mix. Otherwise, the effect will be applied to all players
* (AudioTrack or MediaPLayer) within the same audio session.
* io: HAL audio output or input 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 = NULL,
void* user = NULL,
int sessionId = AUDIO_SESSION_OUTPUT_MIX,
audio_io_handle_t io = AUDIO_IO_HANDLE_NONE
);
/* 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 = NULL,
void* user = NULL,
int sessionId = AUDIO_SESSION_OUTPUT_MIX,
audio_io_handle_t io = AUDIO_IO_HANDLE_NONE
);
/* 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 = NULL,
void* user = NULL,
int sessionId = AUDIO_SESSION_OUTPUT_MIX,
audio_io_handle_t io = AUDIO_IO_HANDLE_NONE
);
/* 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 audio_effect.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 audio_effect.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 audio_effect.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 audio_effect.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 audio_effect.h for details on effect command() function, valid command codes
* and formats.
*/
virtual status_t command(uint32_t cmdCode,
uint32_t cmdSize,
void *cmdData,
uint32_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);
// kMaxPreProcessing is a reasonable value for the maximum number of preprocessing effects
// that can be applied simultaneously.
static const uint32_t kMaxPreProcessing = 10;
protected:
bool 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
Mutex mLock; // Mutex for mEnabled access
// IEffectClient
virtual void controlStatusChanged(bool controlGranted);
virtual void enableStatusChanged(bool enabled);
virtual void commandExecuted(uint32_t cmdCode,
uint32_t cmdSize,
void *pCmdData,
uint32_t replySize,
void *pReplyData);
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(uint32_t cmdCode,
uint32_t cmdSize,
void *pCmdData,
uint32_t replySize,
void *pReplyData) {
mEffect->commandExecuted(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
}
// IBinder::DeathRecipient
virtual void binderDied(const wp<IBinder>& who) {mEffect->binderDied();}
private:
AudioEffect *mEffect;
};
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
pid_t mClientPid;
};
}; // namespace android
#endif // ANDROID_AUDIOEFFECT_H
|