summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2010-06-01 23:49:17 -0700
committerEric Laurent <elaurent@google.com>2010-06-03 03:21:53 -0700
commitbe916aa1267e2e6b1c148f51d11bcbbc79cb864c (patch)
tree7e2be6182cde7d023ae9afec28463d69d231d7bc /media
parentc282e3eee921453fc9188705b4879d6289b71f9c (diff)
downloadframeworks_av-be916aa1267e2e6b1c148f51d11bcbbc79cb864c.zip
frameworks_av-be916aa1267e2e6b1c148f51d11bcbbc79cb864c.tar.gz
frameworks_av-be916aa1267e2e6b1c148f51d11bcbbc79cb864c.tar.bz2
Issue 2667801: [Audio Effect Framework] AudioFlinger, AudioMixer AudioTrack modifications.
First drop of audio framework modifications for audio effects support. - AudioTrack/AudioRecord: Added support for auxiliary effects in AudioTrack Added support for audio sessions Fixed left right channel inversion in setVolume() - IAudioFlinger: Added interface methods for effect enumeraiton and instantiation Added support for audio sessions. - IAudioTrack: Added method to attach auxiliary effect. - AudioFlinger Created new classes to control effect engines in effect library and manage effect connections to tracks or output mix: EffectModule: wrapper object controlling the effect engine implementation in the effect library. There is one EffectModule per instance of an effect in a given audio session EffectChain: group of effects associated to one audio session. There is one EffectChain per audio session. EffectChain for session 0 is for output mix effects, other chains are attached to audio tracks with same session ID. Each chain contains a variable number of EffectModules EffectHandle: implements the IEffect interface. There is one EffectHandle object for each application controlling (or using) an effect module. THe EffectModule maintians a list of EffectHandles. Added support for effect modules and effect chains creation in PlaybackThread. modified mixer thread loop to allow track volume control by effect modules and call effect processing. -AudioMixer Each track now specifies its output buffer used by mixer for accumulation Modified mixer process functions to process tracks by groups of tracks with same buffer Modified track process functions to support accumulation to auxiliary channel Change-Id: I26d5f7c9e070a89bdd383e1a659f8b7ca150379c
Diffstat (limited to 'media')
-rw-r--r--media/libeffects/EffectEqualizer.cpp2
-rw-r--r--media/libeffects/EffectReverb.c5
-rw-r--r--media/libeffects/EffectReverb.h2
-rw-r--r--media/libeffects/EffectsFactory.c12
-rw-r--r--media/libmedia/AudioRecord.cpp21
-rw-r--r--media/libmedia/AudioSystem.cpp6
-rw-r--r--media/libmedia/AudioTrack.cpp66
-rw-r--r--media/libmedia/IAudioFlinger.cpp260
-rw-r--r--media/libmedia/IAudioTrack.cpp24
9 files changed, 369 insertions, 29 deletions
diff --git a/media/libeffects/EffectEqualizer.cpp b/media/libeffects/EffectEqualizer.cpp
index c08f4f5..e39e595 100644
--- a/media/libeffects/EffectEqualizer.cpp
+++ b/media/libeffects/EffectEqualizer.cpp
@@ -114,7 +114,7 @@ int Equalizer_setParameter(AudioEqualizer * pEqualizer, int32_t *pParam, void *p
//--- Effect Library Interface Implementation
//
-extern "C" int EffectQueryNumberEffects(int *pNumEffects) {
+extern "C" int EffectQueryNumberEffects(uint32_t *pNumEffects) {
*pNumEffects = 1;
gEffectIndex = 0;
return 0;
diff --git a/media/libeffects/EffectReverb.c b/media/libeffects/EffectReverb.c
index 3181504..202f50b 100644
--- a/media/libeffects/EffectReverb.c
+++ b/media/libeffects/EffectReverb.c
@@ -18,7 +18,8 @@
//
#define LOG_NDEBUG 0
#include <cutils/log.h>
-
+#include <stdlib.h>
+#include <string.h>
#include <stdbool.h>
#include "EffectReverb.h"
#include "EffectsMath.h"
@@ -86,7 +87,7 @@ static const effect_descriptor_t * const gDescriptors[] = {
/*--- Effect Library Interface Implementation ---*/
-int EffectQueryNumberEffects(int *pNumEffects) {
+int EffectQueryNumberEffects(uint32_t *pNumEffects) {
*pNumEffects = sizeof(gDescriptors) / sizeof(const effect_descriptor_t *)
- 1;
gEffectIndex = 0;
diff --git a/media/libeffects/EffectReverb.h b/media/libeffects/EffectReverb.h
index cd14891..578e09e 100644
--- a/media/libeffects/EffectReverb.h
+++ b/media/libeffects/EffectReverb.h
@@ -292,7 +292,7 @@ typedef struct reverb_module_s {
* Effect API
*------------------------------------
*/
-int EffectQueryNumberEffects(int *pNumEffects);
+int EffectQueryNumberEffects(uint32_t *pNumEffects);
int EffectQueryNext(effect_descriptor_t *pDescriptor);
int EffectCreate(effect_uuid_t *effectUID, effect_interface_t *pInterface);
int EffectRelease(effect_interface_t interface);
diff --git a/media/libeffects/EffectsFactory.c b/media/libeffects/EffectsFactory.c
index 35a1001..6800765 100644
--- a/media/libeffects/EffectsFactory.c
+++ b/media/libeffects/EffectsFactory.c
@@ -39,7 +39,7 @@ static int gInitDone; // true is global initialization has been preformed
static int init();
static int loadLibrary(const char *libPath, int *handle);
static int unloadLibrary(int handle);
-static int numEffectModules();
+static uint32_t numEffectModules();
static int findEffect(effect_uuid_t *uuid, lib_entry_t **lib, effect_descriptor_t **desc);
static void dumpEffectDescriptor(effect_descriptor_t *desc, char *str, size_t len);
@@ -96,7 +96,7 @@ const struct effect_interface_s gInterface = {
// Effect Factory Interface functions
/////////////////////////////////////////////////
-int EffectQueryNumberEffects(int *pNumEffects)
+int EffectQueryNumberEffects(uint32_t *pNumEffects)
{
int ret = init();
if (ret < 0) {
@@ -353,8 +353,8 @@ int loadLibrary(const char *libPath, int *handle)
effect_QueryNextEffect_t queryFx;
effect_CreateEffect_t createFx;
effect_ReleaseEffect_t releaseFx;
- int numFx;
- int fx;
+ uint32_t numFx;
+ uint32_t fx;
int ret;
list_elem_t *e, *descHead = NULL;
lib_entry_t *l;
@@ -525,9 +525,9 @@ int unloadLibrary(int handle)
-int numEffectModules() {
+uint32_t numEffectModules() {
list_elem_t *e = gLibraryList;
- int cnt = 0;
+ uint32_t cnt = 0;
// Reset pointers for EffectQueryNext()
gCurLib = e;
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index fd2b1ce..a2436ab 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -45,7 +45,7 @@ namespace android {
// ---------------------------------------------------------------------------
AudioRecord::AudioRecord()
- : mStatus(NO_INIT)
+ : mStatus(NO_INIT), mSessionId(0)
{
}
@@ -58,11 +58,12 @@ AudioRecord::AudioRecord(
uint32_t flags,
callback_t cbf,
void* user,
- int notificationFrames)
- : mStatus(NO_INIT)
+ int notificationFrames,
+ int sessionId)
+ : mStatus(NO_INIT), mSessionId(0)
{
mStatus = set(inputSource, sampleRate, format, channels,
- frameCount, flags, cbf, user, notificationFrames);
+ frameCount, flags, cbf, user, notificationFrames, sessionId);
}
AudioRecord::~AudioRecord()
@@ -91,7 +92,8 @@ status_t AudioRecord::set(
callback_t cbf,
void* user,
int notificationFrames,
- bool threadCanCallJava)
+ bool threadCanCallJava,
+ int sessionId)
{
LOGV("set(): sampleRate %d, channels %d, frameCount %d",sampleRate, channels, frameCount);
@@ -119,6 +121,7 @@ status_t AudioRecord::set(
if (!AudioSystem::isInputChannel(channels)) {
return BAD_VALUE;
}
+
int channelCount = AudioSystem::popCount(channels);
audio_io_handle_t input = AudioSystem::getInput(inputSource,
@@ -164,6 +167,8 @@ status_t AudioRecord::set(
notificationFrames = frameCount/2;
}
+ mSessionId = sessionId;
+
// create the IAudioRecord
status_t status = openRecord(sampleRate, format, channelCount,
frameCount, flags, input);
@@ -414,6 +419,7 @@ status_t AudioRecord::openRecord(
channelCount,
frameCount,
((uint16_t)flags) << 16,
+ &mSessionId,
&status);
if (record == 0) {
LOGE("AudioFlinger could not create record track, status: %d", status);
@@ -532,6 +538,11 @@ audio_io_handle_t AudioRecord::getInput()
return mInput;
}
+int AudioRecord::getSessionId()
+{
+ return mSessionId;
+}
+
// -------------------------------------------------------------------------
ssize_t AudioRecord::read(void* buffer, size_t userSize)
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index 5e6ce42..c77f551 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -364,6 +364,12 @@ unsigned int AudioSystem::getInputFramesLost(audio_io_handle_t ioHandle) {
return result;
}
+int AudioSystem::newAudioSessionId() {
+ const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ if (af == 0) return 0;
+ return af->newAudioSessionId();
+}
+
// ---------------------------------------------------------------------------
void AudioSystem::AudioFlingerClient::binderDied(const wp<IBinder>& who) {
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index c350532..4b61131 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -58,7 +58,8 @@ AudioTrack::AudioTrack(
uint32_t flags,
callback_t cbf,
void* user,
- int notificationFrames)
+ int notificationFrames,
+ int sessionId)
: mStatus(NO_INIT)
{
mStatus = set(streamType, sampleRate, format, channels,
@@ -74,7 +75,8 @@ AudioTrack::AudioTrack(
uint32_t flags,
callback_t cbf,
void* user,
- int notificationFrames)
+ int notificationFrames,
+ int sessionId)
: mStatus(NO_INIT)
{
mStatus = set(streamType, sampleRate, format, channels,
@@ -110,7 +112,8 @@ status_t AudioTrack::set(
void* user,
int notificationFrames,
const sp<IMemory>& sharedBuffer,
- bool threadCanCallJava)
+ bool threadCanCallJava,
+ int sessionId)
{
LOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(), sharedBuffer->size());
@@ -171,8 +174,11 @@ status_t AudioTrack::set(
mVolume[LEFT] = 1.0f;
mVolume[RIGHT] = 1.0f;
+ mSendLevel = 0;
mFrameCount = frameCount;
mNotificationFramesReq = notificationFrames;
+ mSessionId = sessionId;
+
// create the IAudioTrack
status_t status = createTrack(streamType, sampleRate, format, channelCount,
frameCount, flags, sharedBuffer, output, true);
@@ -396,19 +402,49 @@ bool AudioTrack::muted() const
return mMuted;
}
-void AudioTrack::setVolume(float left, float right)
+status_t AudioTrack::setVolume(float left, float right)
{
+ if (left > 1.0f || right > 1.0f) {
+ return BAD_VALUE;
+ }
+
mVolume[LEFT] = left;
mVolume[RIGHT] = right;
// write must be atomic
- mCblk->volumeLR = (int32_t(int16_t(left * 0x1000)) << 16) | int16_t(right * 0x1000);
+ mCblk->volumeLR = (uint32_t(uint16_t(right * 0x1000)) << 16) | uint16_t(left * 0x1000);
+
+ return NO_ERROR;
}
void AudioTrack::getVolume(float* left, float* right)
{
- *left = mVolume[LEFT];
- *right = mVolume[RIGHT];
+ if (left != NULL) {
+ *left = mVolume[LEFT];
+ }
+ if (right != NULL) {
+ *right = mVolume[RIGHT];
+ }
+}
+
+status_t AudioTrack::setSendLevel(float level)
+{
+ if (level > 1.0f) {
+ return BAD_VALUE;
+ }
+
+ mSendLevel = level;
+
+ mCblk->sendLevel = uint16_t(level * 0x1000);
+
+ return NO_ERROR;
+}
+
+void AudioTrack::getSendLevel(float* level)
+{
+ if (level != NULL) {
+ *level = mSendLevel;
+ }
}
status_t AudioTrack::setSampleRate(int rate)
@@ -563,6 +599,16 @@ audio_io_handle_t AudioTrack::getOutput()
mCblk->sampleRate, mFormat, mChannels, (AudioSystem::output_flags)mFlags);
}
+int AudioTrack::getSessionId()
+{
+ return mSessionId;
+}
+
+status_t AudioTrack::attachAuxEffect(int effectId)
+{
+ return mAudioTrack->attachAuxEffect(effectId);
+}
+
// -------------------------------------------------------------------------
status_t AudioTrack::createTrack(
@@ -647,6 +693,7 @@ status_t AudioTrack::createTrack(
((uint16_t)flags) << 16,
sharedBuffer,
output,
+ &mSessionId,
&status);
if (track == 0) {
@@ -672,7 +719,8 @@ status_t AudioTrack::createTrack(
mCblk->stepUser(mCblk->frameCount);
}
- mCblk->volumeLR = (int32_t(int16_t(mVolume[LEFT] * 0x1000)) << 16) | int16_t(mVolume[RIGHT] * 0x1000);
+ mCblk->volumeLR = (uint32_t(uint16_t(mVolume[RIGHT] * 0x1000)) << 16) | uint16_t(mVolume[LEFT] * 0x1000);
+ mCblk->sendLevel = uint16_t(mSendLevel * 0x1000);
mCblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS;
mCblk->waitTimeMs = 0;
mRemainingFrames = mNotificationFramesAct;
@@ -1016,7 +1064,7 @@ audio_track_cblk_t::audio_track_cblk_t()
: lock(Mutex::SHARED), cv(Condition::SHARED), user(0), server(0),
userBase(0), serverBase(0), buffers(0), frameCount(0),
loopStart(UINT_MAX), loopEnd(UINT_MAX), loopCount(0), volumeLR(0),
- flags(0)
+ flags(0), sendLevel(0)
{
}
diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp
index 47bcc12..f2a8db3 100644
--- a/media/libmedia/IAudioFlinger.cpp
+++ b/media/libmedia/IAudioFlinger.cpp
@@ -62,7 +62,14 @@ enum {
SET_STREAM_OUTPUT,
SET_VOICE_VOLUME,
GET_RENDER_POSITION,
- GET_INPUT_FRAMES_LOST
+ GET_INPUT_FRAMES_LOST,
+ NEW_AUDIO_SESSION_ID,
+ LOAD_EFFECT_LIBRARY,
+ UNLOAD_EFFECT_LIBRARY,
+ QUERY_NUM_EFFECTS,
+ QUERY_NEXT_EFFECT,
+ GET_EFFECT_DESCRIPTOR,
+ CREATE_EFFECT
};
class BpAudioFlinger : public BpInterface<IAudioFlinger>
@@ -83,6 +90,7 @@ public:
uint32_t flags,
const sp<IMemory>& sharedBuffer,
int output,
+ int *sessionId,
status_t *status)
{
Parcel data, reply;
@@ -97,10 +105,19 @@ public:
data.writeInt32(flags);
data.writeStrongBinder(sharedBuffer->asBinder());
data.writeInt32(output);
+ int lSessionId = 0;
+ if (sessionId != NULL) {
+ lSessionId = *sessionId;
+ }
+ data.writeInt32(lSessionId);
status_t lStatus = remote()->transact(CREATE_TRACK, data, &reply);
if (lStatus != NO_ERROR) {
LOGE("createTrack error: %s", strerror(-lStatus));
} else {
+ lSessionId = reply.readInt32();
+ if (sessionId != NULL) {
+ *sessionId = lSessionId;
+ }
lStatus = reply.readInt32();
track = interface_cast<IAudioTrack>(reply.readStrongBinder());
}
@@ -118,6 +135,7 @@ public:
int channelCount,
int frameCount,
uint32_t flags,
+ int *sessionId,
status_t *status)
{
Parcel data, reply;
@@ -130,10 +148,19 @@ public:
data.writeInt32(channelCount);
data.writeInt32(frameCount);
data.writeInt32(flags);
+ int lSessionId = 0;
+ if (sessionId != NULL) {
+ lSessionId = *sessionId;
+ }
+ data.writeInt32(lSessionId);
status_t lStatus = remote()->transact(OPEN_RECORD, data, &reply);
if (lStatus != NO_ERROR) {
LOGE("openRecord error: %s", strerror(-lStatus));
} else {
+ lSessionId = reply.readInt32();
+ if (sessionId != NULL) {
+ *sessionId = lSessionId;
+ }
lStatus = reply.readInt32();
record = interface_cast<IAudioRecord>(reply.readStrongBinder());
}
@@ -497,6 +524,157 @@ public:
remote()->transact(GET_INPUT_FRAMES_LOST, data, &reply);
return reply.readInt32();
}
+
+ virtual int newAudioSessionId()
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
+ status_t status = remote()->transact(NEW_AUDIO_SESSION_ID, data, &reply);
+ int id = 0;
+ if (status == NO_ERROR) {
+ id = reply.readInt32();
+ }
+ return id;
+ }
+
+ virtual status_t loadEffectLibrary(const char *libPath, int *handle)
+ {
+ if (libPath == NULL || handle == NULL) {
+ return BAD_VALUE;
+ }
+ *handle = 0;
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
+ data.writeCString(libPath);
+ status_t status = remote()->transact(LOAD_EFFECT_LIBRARY, data, &reply);
+ if (status == NO_ERROR) {
+ status = reply.readInt32();
+ if (status == NO_ERROR) {
+ *handle = reply.readInt32();
+ }
+ }
+ return status;
+ }
+
+ virtual status_t unloadEffectLibrary(int handle)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
+ data.writeInt32(handle);
+ status_t status = remote()->transact(UNLOAD_EFFECT_LIBRARY, data, &reply);
+ if (status == NO_ERROR) {
+ status = reply.readInt32();
+ }
+ return status;
+ }
+
+ virtual status_t queryNumberEffects(uint32_t *numEffects)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
+ status_t status = remote()->transact(QUERY_NUM_EFFECTS, data, &reply);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = reply.readInt32();
+ if (status != NO_ERROR) {
+ return status;
+ }
+ if (numEffects) {
+ *numEffects = (uint32_t)reply.readInt32();
+ }
+ return NO_ERROR;
+ }
+
+ virtual status_t queryNextEffect(effect_descriptor_t *pDescriptor)
+ {
+ if (pDescriptor == NULL) {
+ return BAD_VALUE;
+ }
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
+ status_t status = remote()->transact(QUERY_NEXT_EFFECT, data, &reply);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = reply.readInt32();
+ if (status != NO_ERROR) {
+ return status;
+ }
+ reply.read(pDescriptor, sizeof(effect_descriptor_t));
+ return NO_ERROR;
+ }
+
+ virtual status_t getEffectDescriptor(effect_uuid_t *pUuid, effect_descriptor_t *pDescriptor)
+ {
+ if (pUuid == NULL || pDescriptor == NULL) {
+ return BAD_VALUE;
+ }
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
+ data.write(pUuid, sizeof(effect_uuid_t));
+ status_t status = remote()->transact(GET_EFFECT_DESCRIPTOR, data, &reply);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = reply.readInt32();
+ if (status != NO_ERROR) {
+ return status;
+ }
+ reply.read(pDescriptor, sizeof(effect_descriptor_t));
+ return NO_ERROR;
+ }
+
+ virtual sp<IEffect> createEffect(pid_t pid,
+ effect_descriptor_t *pDesc,
+ const sp<IEffectClient>& client,
+ int32_t priority,
+ int output,
+ int sessionId,
+ status_t *status,
+ int *id,
+ int *enabled)
+ {
+ Parcel data, reply;
+ sp<IEffect> effect;
+
+ if (pDesc == NULL) {
+ return effect;
+ if (status) {
+ *status = BAD_VALUE;
+ }
+ }
+
+ data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
+ data.writeInt32(pid);
+ data.write(pDesc, sizeof(effect_descriptor_t));
+ data.writeStrongBinder(client->asBinder());
+ data.writeInt32(priority);
+ data.writeInt32(output);
+ data.writeInt32(sessionId);
+
+ status_t lStatus = remote()->transact(CREATE_EFFECT, data, &reply);
+ if (lStatus != NO_ERROR) {
+ LOGE("createEffect error: %s", strerror(-lStatus));
+ } else {
+ lStatus = reply.readInt32();
+ int tmp = reply.readInt32();
+ if (id) {
+ *id = tmp;
+ }
+ tmp = reply.readInt32();
+ if (enabled) {
+ *enabled = tmp;
+ }
+ effect = interface_cast<IEffect>(reply.readStrongBinder());
+ reply.read(pDesc, sizeof(effect_descriptor_t));
+ }
+ if (status) {
+ *status = lStatus;
+ }
+
+ return effect;
+ }
};
IMPLEMENT_META_INTERFACE(AudioFlinger, "android.media.IAudioFlinger");
@@ -518,10 +696,12 @@ status_t BnAudioFlinger::onTransact(
uint32_t flags = data.readInt32();
sp<IMemory> buffer = interface_cast<IMemory>(data.readStrongBinder());
int output = data.readInt32();
+ int sessionId = data.readInt32();
status_t status;
sp<IAudioTrack> track = createTrack(pid,
streamType, sampleRate, format,
- channelCount, bufferCount, flags, buffer, output, &status);
+ channelCount, bufferCount, flags, buffer, output, &sessionId, &status);
+ reply->writeInt32(sessionId);
reply->writeInt32(status);
reply->writeStrongBinder(track->asBinder());
return NO_ERROR;
@@ -535,9 +715,11 @@ status_t BnAudioFlinger::onTransact(
int channelCount = data.readInt32();
size_t bufferCount = data.readInt32();
uint32_t flags = data.readInt32();
+ int sessionId = data.readInt32();
status_t status;
sp<IAudioRecord> record = openRecord(pid, input,
- sampleRate, format, channelCount, bufferCount, flags, &status);
+ sampleRate, format, channelCount, bufferCount, flags, &sessionId, &status);
+ reply->writeInt32(sessionId);
reply->writeInt32(status);
reply->writeStrongBinder(record->asBinder());
return NO_ERROR;
@@ -768,7 +950,79 @@ status_t BnAudioFlinger::onTransact(
reply->writeInt32(getInputFramesLost(ioHandle));
return NO_ERROR;
} break;
+ case NEW_AUDIO_SESSION_ID: {
+ CHECK_INTERFACE(IAudioFlinger, data, reply);
+ reply->writeInt32(newAudioSessionId());
+ return NO_ERROR;
+ } break;
+ case LOAD_EFFECT_LIBRARY: {
+ CHECK_INTERFACE(IAudioFlinger, data, reply);
+ int handle;
+ status_t status = loadEffectLibrary(data.readCString(), &handle);
+ reply->writeInt32(status);
+ if (status == NO_ERROR) {
+ reply->writeInt32(handle);
+ }
+ return NO_ERROR;
+ }
+ case UNLOAD_EFFECT_LIBRARY: {
+ CHECK_INTERFACE(IAudioFlinger, data, reply);
+ reply->writeInt32(unloadEffectLibrary(data.readInt32()));
+ return NO_ERROR;
+ }
+ case QUERY_NUM_EFFECTS: {
+ CHECK_INTERFACE(IAudioFlinger, data, reply);
+ uint32_t numEffects;
+ status_t status = queryNumberEffects(&numEffects);
+ reply->writeInt32(status);
+ if (status == NO_ERROR) {
+ reply->writeInt32((int32_t)numEffects);
+ }
+ return NO_ERROR;
+ }
+ case QUERY_NEXT_EFFECT: {
+ CHECK_INTERFACE(IAudioFlinger, data, reply);
+ effect_descriptor_t desc;
+ status_t status = queryNextEffect(&desc);
+ reply->writeInt32(status);
+ if (status == NO_ERROR) {
+ reply->write(&desc, sizeof(effect_descriptor_t));
+ }
+ return NO_ERROR;
+ }
+ case GET_EFFECT_DESCRIPTOR: {
+ CHECK_INTERFACE(IAudioFlinger, data, reply);
+ effect_uuid_t uuid;
+ data.read(&uuid, sizeof(effect_uuid_t));
+ effect_descriptor_t desc;
+ status_t status = getEffectDescriptor(&uuid, &desc);
+ reply->writeInt32(status);
+ if (status == NO_ERROR) {
+ reply->write(&desc, sizeof(effect_descriptor_t));
+ }
+ return NO_ERROR;
+ }
+ case CREATE_EFFECT: {
+ CHECK_INTERFACE(IAudioFlinger, data, reply);
+ pid_t pid = data.readInt32();
+ effect_descriptor_t desc;
+ data.read(&desc, sizeof(effect_descriptor_t));
+ sp<IEffectClient> client = interface_cast<IEffectClient>(data.readStrongBinder());
+ int32_t priority = data.readInt32();
+ int output = data.readInt32();
+ int sessionId = data.readInt32();
+ status_t status;
+ int id;
+ int enabled;
+ sp<IEffect> effect = createEffect(pid, &desc, client, priority, output, sessionId, &status, &id, &enabled);
+ reply->writeInt32(status);
+ reply->writeInt32(id);
+ reply->writeInt32(enabled);
+ reply->writeStrongBinder(effect->asBinder());
+ reply->write(&desc, sizeof(effect_descriptor_t));
+ return NO_ERROR;
+ } break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/media/libmedia/IAudioTrack.cpp b/media/libmedia/IAudioTrack.cpp
index 01ffd75..bc8ff34 100644
--- a/media/libmedia/IAudioTrack.cpp
+++ b/media/libmedia/IAudioTrack.cpp
@@ -34,7 +34,8 @@ enum {
STOP,
FLUSH,
MUTE,
- PAUSE
+ PAUSE,
+ ATTACH_AUX_EFFECT
};
class BpAudioTrack : public BpInterface<IAudioTrack>
@@ -97,7 +98,21 @@ public:
cblk = interface_cast<IMemory>(reply.readStrongBinder());
}
return cblk;
- }
+ }
+
+ virtual status_t attachAuxEffect(int effectId)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
+ data.writeInt32(effectId);
+ status_t status = remote()->transact(ATTACH_AUX_EFFECT, data, &reply);
+ if (status == NO_ERROR) {
+ status = reply.readInt32();
+ } else {
+ LOGW("attachAuxEffect() error: %s", strerror(-status));
+ }
+ return status;
+ }
};
IMPLEMENT_META_INTERFACE(AudioTrack, "android.media.IAudioTrack");
@@ -138,6 +153,11 @@ status_t BnAudioTrack::onTransact(
pause();
return NO_ERROR;
}
+ case ATTACH_AUX_EFFECT: {
+ CHECK_INTERFACE(IAudioTrack, data, reply);
+ reply->writeInt32(attachAuxEffect(data.readInt32()));
+ return NO_ERROR;
+ } break;
default:
return BBinder::onTransact(code, data, reply, flags);
}