OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / frameworks / base / media / libmedia / AudioEffect.cpp
1 /*
2 **
3 ** Copyright 2010, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 **     http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17
18
19 //#define LOG_NDEBUG 0
20 #define LOG_TAG "AudioEffect"
21
22 #include <stdint.h>
23 #include <sys/types.h>
24 #include <limits.h>
25
26 #include <private/media/AudioEffectShared.h>
27 #include <media/AudioEffect.h>
28
29 #include <utils/Log.h>
30 #include <cutils/atomic.h>
31 #include <binder/IPCThreadState.h>
32
33
34
35 namespace android {
36
37 // ---------------------------------------------------------------------------
38
39 AudioEffect::AudioEffect()
40     : mStatus(NO_INIT)
41 {
42 }
43
44
45 AudioEffect::AudioEffect(const effect_uuid_t *type,
46                 const effect_uuid_t *uuid,
47                 int32_t priority,
48                 effect_callback_t cbf,
49                 void* user,
50                 int sessionId,
51                 audio_io_handle_t output
52                 )
53     : mStatus(NO_INIT)
54 {
55     mStatus = set(type, uuid, priority, cbf, user, sessionId, output);
56 }
57
58 AudioEffect::AudioEffect(const char *typeStr,
59                 const char *uuidStr,
60                 int32_t priority,
61                 effect_callback_t cbf,
62                 void* user,
63                 int sessionId,
64                 audio_io_handle_t output
65                 )
66     : mStatus(NO_INIT)
67 {
68     effect_uuid_t type;
69     effect_uuid_t *pType = NULL;
70     effect_uuid_t uuid;
71     effect_uuid_t *pUuid = NULL;
72
73     LOGV("Constructor string\n - type: %s\n - uuid: %s", typeStr, uuidStr);
74
75     if (typeStr != NULL) {
76         if (stringToGuid(typeStr, &type) == NO_ERROR) {
77             pType = &type;
78         }
79     }
80
81     if (uuidStr != NULL) {
82         if (stringToGuid(uuidStr, &uuid) == NO_ERROR) {
83             pUuid = &uuid;
84         }
85     }
86
87     mStatus = set(pType, pUuid, priority, cbf, user, sessionId, output);
88 }
89
90 status_t AudioEffect::set(const effect_uuid_t *type,
91                 const effect_uuid_t *uuid,
92                 int32_t priority,
93                 effect_callback_t cbf,
94                 void* user,
95                 int sessionId,
96                 audio_io_handle_t output)
97 {
98     sp<IEffect> iEffect;
99     sp<IMemory> cblk;
100     int enabled;
101
102     LOGV("set %p mUserData: %p", this, user);
103
104     if (mIEffect != 0) {
105         LOGW("Effect already in use");
106         return INVALID_OPERATION;
107     }
108
109     const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
110     if (audioFlinger == 0) {
111         LOGE("set(): Could not get audioflinger");
112         return NO_INIT;
113     }
114
115     if (type == NULL && uuid == NULL) {
116         LOGW("Must specify at least type or uuid");
117         return BAD_VALUE;
118     }
119
120     mPriority = priority;
121     mCbf = cbf;
122     mUserData = user;
123     mSessionId = sessionId;
124
125     memset(&mDescriptor, 0, sizeof(effect_descriptor_t));
126     memcpy(&mDescriptor.type, EFFECT_UUID_NULL, sizeof(effect_uuid_t));
127     memcpy(&mDescriptor.uuid, EFFECT_UUID_NULL, sizeof(effect_uuid_t));
128
129     if (type != NULL) {
130         memcpy(&mDescriptor.type, type, sizeof(effect_uuid_t));
131     }
132     if (uuid != NULL) {
133         memcpy(&mDescriptor.uuid, uuid, sizeof(effect_uuid_t));
134     }
135
136     mIEffectClient = new EffectClient(this);
137
138     iEffect = audioFlinger->createEffect(getpid(), (effect_descriptor_t *)&mDescriptor,
139             mIEffectClient, priority, output, mSessionId, &mStatus, &mId, &enabled);
140
141     if (iEffect == 0 || (mStatus != NO_ERROR && mStatus != ALREADY_EXISTS)) {
142         LOGE("set(): AudioFlinger could not create effect, status: %d", mStatus);
143         return mStatus;
144     }
145
146     mEnabled = (volatile int32_t)enabled;
147
148     mIEffect = iEffect;
149     cblk = iEffect->getCblk();
150     if (cblk == 0) {
151         mStatus = NO_INIT;
152         LOGE("Could not get control block");
153         return mStatus;
154     }
155
156     mIEffect = iEffect;
157     mCblkMemory = cblk;
158     mCblk = static_cast<effect_param_cblk_t*>(cblk->pointer());
159     int bufOffset = ((sizeof(effect_param_cblk_t) - 1) / sizeof(int) + 1) * sizeof(int);
160     mCblk->buffer = (uint8_t *)mCblk + bufOffset;
161
162     iEffect->asBinder()->linkToDeath(mIEffectClient);
163     LOGV("set() %p OK effect: %s id: %d status %d enabled %d, ", this, mDescriptor.name, mId, mStatus, mEnabled);
164
165     return mStatus;
166 }
167
168
169 AudioEffect::~AudioEffect()
170 {
171     LOGV("Destructor %p", this);
172
173     if (mStatus == NO_ERROR || mStatus == ALREADY_EXISTS) {
174         setEnabled(false);
175         if (mIEffect != NULL) {
176             mIEffect->disconnect();
177             mIEffect->asBinder()->unlinkToDeath(mIEffectClient);
178         }
179          IPCThreadState::self()->flushCommands();
180     }
181     mIEffect.clear();
182     mIEffectClient.clear();
183     mCblkMemory.clear();
184 }
185
186
187 status_t AudioEffect::initCheck() const
188 {
189     return mStatus;
190 }
191
192 // -------------------------------------------------------------------------
193
194 effect_descriptor_t AudioEffect::descriptor() const
195 {
196     return mDescriptor;
197 }
198
199 bool AudioEffect::getEnabled() const
200 {
201     return (mEnabled != 0);
202 }
203
204 status_t AudioEffect::setEnabled(bool enabled)
205 {
206     if (mStatus != NO_ERROR) {
207         return INVALID_OPERATION;
208     }
209
210     if (enabled) {
211         LOGV("enable %p", this);
212         if (android_atomic_or(1, &mEnabled) == 0) {
213            return mIEffect->enable();
214         }
215     } else {
216         LOGV("disable %p", this);
217         if (android_atomic_and(~1, &mEnabled) == 1) {
218            return mIEffect->disable();
219         }
220     }
221     return NO_ERROR;
222 }
223
224 status_t AudioEffect::command(uint32_t cmdCode,
225                               uint32_t cmdSize,
226                               void *cmdData,
227                               uint32_t *replySize,
228                               void *replyData)
229 {
230     if (mStatus != NO_ERROR && mStatus != ALREADY_EXISTS) {
231         LOGV("command() bad status %d", mStatus);
232         return INVALID_OPERATION;
233     }
234
235     if ((cmdCode == EFFECT_CMD_ENABLE || cmdCode == EFFECT_CMD_DISABLE) &&
236             (replySize == NULL || *replySize != sizeof(status_t) || replyData == NULL)) {
237         return BAD_VALUE;
238     }
239
240     status_t status = mIEffect->command(cmdCode, cmdSize, cmdData, replySize, replyData);
241     if (status != NO_ERROR) {
242         return status;
243     }
244
245     if (cmdCode == EFFECT_CMD_ENABLE || cmdCode == EFFECT_CMD_DISABLE) {
246         status = *(status_t *)replyData;
247         if (status != NO_ERROR) {
248             return status;
249         }
250         if (cmdCode == EFFECT_CMD_ENABLE) {
251             android_atomic_or(1, &mEnabled);
252         } else {
253             android_atomic_and(~1, &mEnabled);
254         }
255     }
256
257     return status;
258 }
259
260
261 status_t AudioEffect::setParameter(effect_param_t *param)
262 {
263     if (mStatus != NO_ERROR) {
264         return INVALID_OPERATION;
265     }
266
267     if (param == NULL || param->psize == 0 || param->vsize == 0) {
268         return BAD_VALUE;
269     }
270
271     uint32_t size = sizeof(int);
272     uint32_t psize = ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) + param->vsize;
273
274     LOGV("setParameter: param: %d, param2: %d", *(int *)param->data, (param->psize == 8) ? *((int *)param->data + 1): -1);
275
276     return mIEffect->command(EFFECT_CMD_SET_PARAM, sizeof (effect_param_t) + psize, param, &size, &param->status);
277 }
278
279 status_t AudioEffect::setParameterDeferred(effect_param_t *param)
280 {
281     if (mStatus != NO_ERROR) {
282         return INVALID_OPERATION;
283     }
284
285     if (param == NULL || param->psize == 0 || param->vsize == 0) {
286         return BAD_VALUE;
287     }
288
289     Mutex::Autolock _l(mCblk->lock);
290
291     int psize = ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) + param->vsize;
292     int size = ((sizeof(effect_param_t) + psize - 1) / sizeof(int) + 1) * sizeof(int);
293
294     if (mCblk->clientIndex + size > EFFECT_PARAM_BUFFER_SIZE) {
295         return NO_MEMORY;
296     }
297     int *p = (int *)(mCblk->buffer + mCblk->clientIndex);
298     *p++ = size;
299     memcpy(p, param, sizeof(effect_param_t) + psize);
300     mCblk->clientIndex += size;
301
302     return NO_ERROR;
303 }
304
305 status_t AudioEffect::setParameterCommit()
306 {
307     if (mStatus != NO_ERROR) {
308         return INVALID_OPERATION;
309     }
310
311     Mutex::Autolock _l(mCblk->lock);
312     if (mCblk->clientIndex == 0) {
313         return INVALID_OPERATION;
314     }
315     uint32_t size = 0;
316     return mIEffect->command(EFFECT_CMD_SET_PARAM_COMMIT, 0, NULL, &size, NULL);
317 }
318
319 status_t AudioEffect::getParameter(effect_param_t *param)
320 {
321     if (mStatus != NO_ERROR && mStatus != ALREADY_EXISTS) {
322         return INVALID_OPERATION;
323     }
324
325     if (param == NULL || param->psize == 0 || param->vsize == 0) {
326         return BAD_VALUE;
327     }
328
329     LOGV("getParameter: param: %d, param2: %d", *(int *)param->data, (param->psize == 8) ? *((int *)param->data + 1): -1);
330
331     uint32_t psize = sizeof(effect_param_t) + ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) + param->vsize;
332
333     return mIEffect->command(EFFECT_CMD_GET_PARAM, sizeof(effect_param_t) + param->psize, param, &psize, param);
334 }
335
336
337 // -------------------------------------------------------------------------
338
339 void AudioEffect::binderDied()
340 {
341     LOGW("IEffect died");
342     mStatus = NO_INIT;
343     if (mCbf) {
344         status_t status = DEAD_OBJECT;
345         mCbf(EVENT_ERROR, mUserData, &status);
346     }
347     mIEffect.clear();
348 }
349
350 // -------------------------------------------------------------------------
351
352 void AudioEffect::controlStatusChanged(bool controlGranted)
353 {
354     LOGV("controlStatusChanged %p control %d callback %p mUserData %p", this, controlGranted, mCbf, mUserData);
355     if (controlGranted) {
356         if (mStatus == ALREADY_EXISTS) {
357             mStatus = NO_ERROR;
358         }
359     } else {
360         if (mStatus == NO_ERROR) {
361             mStatus = ALREADY_EXISTS;
362         }
363     }
364     if (mCbf) {
365         mCbf(EVENT_CONTROL_STATUS_CHANGED, mUserData, &controlGranted);
366     }
367 }
368
369 void AudioEffect::enableStatusChanged(bool enabled)
370 {
371     LOGV("enableStatusChanged %p enabled %d mCbf %p", this, enabled, mCbf);
372     if (mStatus == ALREADY_EXISTS) {
373         if (enabled) {
374             android_atomic_or(1, &mEnabled);
375         } else {
376             android_atomic_and(~1, &mEnabled);
377         }
378         if (mCbf) {
379             mCbf(EVENT_ENABLE_STATUS_CHANGED, mUserData, &enabled);
380         }
381     }
382 }
383
384 void AudioEffect::commandExecuted(uint32_t cmdCode,
385                                   uint32_t cmdSize,
386                                   void *cmdData,
387                                   uint32_t replySize,
388                                   void *replyData)
389 {
390     if (cmdData == NULL || replyData == NULL) {
391         return;
392     }
393
394     if (mCbf && cmdCode == EFFECT_CMD_SET_PARAM) {
395         effect_param_t *cmd = (effect_param_t *)cmdData;
396         cmd->status = *(int32_t *)replyData;
397         mCbf(EVENT_PARAMETER_CHANGED, mUserData, cmd);
398     }
399 }
400
401 // -------------------------------------------------------------------------
402
403 status_t AudioEffect::loadEffectLibrary(const char *libPath, int *handle)
404 {
405     const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
406     if (af == 0) return PERMISSION_DENIED;
407     return af->loadEffectLibrary(libPath, handle);
408 }
409
410 status_t AudioEffect::unloadEffectLibrary(int handle)
411 {
412     const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
413     if (af == 0) return PERMISSION_DENIED;
414     return af->unloadEffectLibrary(handle);
415 }
416
417 status_t AudioEffect::queryNumberEffects(uint32_t *numEffects)
418 {
419     const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
420     if (af == 0) return PERMISSION_DENIED;
421     return af->queryNumberEffects(numEffects);
422 }
423
424 status_t AudioEffect::queryEffect(uint32_t index, effect_descriptor_t *descriptor)
425 {
426     const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
427     if (af == 0) return PERMISSION_DENIED;
428     return af->queryEffect(index, descriptor);
429 }
430
431 status_t AudioEffect::getEffectDescriptor(effect_uuid_t *uuid, effect_descriptor_t *descriptor)
432 {
433     const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
434     if (af == 0) return PERMISSION_DENIED;
435     return af->getEffectDescriptor(uuid, descriptor);
436 }
437
438 // -------------------------------------------------------------------------
439
440 status_t AudioEffect::stringToGuid(const char *str, effect_uuid_t *guid)
441 {
442     if (str == NULL || guid == NULL) {
443         return BAD_VALUE;
444     }
445
446     int tmp[10];
447
448     if (sscanf(str, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
449             tmp, tmp+1, tmp+2, tmp+3, tmp+4, tmp+5, tmp+6, tmp+7, tmp+8, tmp+9) < 10) {
450         return BAD_VALUE;
451     }
452     guid->timeLow = (uint32_t)tmp[0];
453     guid->timeMid = (uint16_t)tmp[1];
454     guid->timeHiAndVersion = (uint16_t)tmp[2];
455     guid->clockSeq = (uint16_t)tmp[3];
456     guid->node[0] = (uint8_t)tmp[4];
457     guid->node[1] = (uint8_t)tmp[5];
458     guid->node[2] = (uint8_t)tmp[6];
459     guid->node[3] = (uint8_t)tmp[7];
460     guid->node[4] = (uint8_t)tmp[8];
461     guid->node[5] = (uint8_t)tmp[9];
462
463     return NO_ERROR;
464 }
465
466 status_t AudioEffect::guidToString(const effect_uuid_t *guid, char *str, size_t maxLen)
467 {
468     if (guid == NULL || str == NULL) {
469         return BAD_VALUE;
470     }
471
472     snprintf(str, maxLen, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
473             guid->timeLow,
474             guid->timeMid,
475             guid->timeHiAndVersion,
476             guid->clockSeq,
477             guid->node[0],
478             guid->node[1],
479             guid->node[2],
480             guid->node[3],
481             guid->node[4],
482             guid->node[5]);
483
484     return NO_ERROR;
485 }
486
487
488 }; // namespace android
489