Added support for auxiliary audio effects to AudioTrack and MediaPlayer.

Added methods to AudioTrack and MediaPlayer java classes to enable use of
auxiliary audio effects. The effect can be attached and detached by specifying its
ID and the send level controlled.

Change-Id: Ie74ff54a453096a742688476f612ce355543b6f3
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 0f2093a..890786e 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -209,6 +209,7 @@
     mFrameCount = frameCount;
     mNotificationFramesReq = notificationFrames;
     mSessionId = sessionId;
+    mAuxEffectId = 0;
 
     // create the IAudioTrack
     status_t status = createTrack(streamType, sampleRate, format, channelCount,
@@ -458,8 +459,9 @@
     }
 }
 
-status_t AudioTrack::setSendLevel(float level)
+status_t AudioTrack::setAuxEffectSendLevel(float level)
 {
+    LOGV("setAuxEffectSendLevel(%f)", level);
     if (level > 1.0f) {
         return BAD_VALUE;
     }
@@ -471,7 +473,7 @@
     return NO_ERROR;
 }
 
-void AudioTrack::getSendLevel(float* level)
+void AudioTrack::getAuxEffectSendLevel(float* level)
 {
     if (level != NULL) {
         *level  = mSendLevel;
@@ -637,7 +639,12 @@
 
 status_t AudioTrack::attachAuxEffect(int effectId)
 {
-    return mAudioTrack->attachAuxEffect(effectId);
+    LOGV("attachAuxEffect(%d)", effectId);
+    status_t status = mAudioTrack->attachAuxEffect(effectId);
+    if (status == NO_ERROR) {
+        mAuxEffectId = effectId;
+    }
+    return status;
 }
 
 // -------------------------------------------------------------------------
@@ -752,6 +759,7 @@
 
     mCblk->volumeLR = (uint32_t(uint16_t(mVolume[RIGHT] * 0x1000)) << 16) | uint16_t(mVolume[LEFT] * 0x1000);
     mCblk->sendLevel = uint16_t(mSendLevel * 0x1000);
+    mAudioTrack->attachAuxEffect(mAuxEffectId);
     mCblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS;
     mCblk->waitTimeMs = 0;
     mRemainingFrames = mNotificationFramesAct;
diff --git a/media/libmedia/IMediaPlayer.cpp b/media/libmedia/IMediaPlayer.cpp
index ed792b3..0f55b19d 100644
--- a/media/libmedia/IMediaPlayer.cpp
+++ b/media/libmedia/IMediaPlayer.cpp
@@ -45,6 +45,8 @@
     GET_METADATA,
     SUSPEND,
     RESUME,
+    SET_AUX_EFFECT_SEND_LEVEL,
+    ATTACH_AUX_EFFECT
 };
 
 class BpMediaPlayer: public BpInterface<IMediaPlayer>
@@ -221,6 +223,24 @@
 
         return reply.readInt32();
     }
+
+    status_t setAuxEffectSendLevel(float level)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
+        data.writeFloat(level);
+        remote()->transact(SET_AUX_EFFECT_SEND_LEVEL, data, &reply);
+        return reply.readInt32();
+    }
+
+    status_t attachAuxEffect(int effectId)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
+        data.writeInt32(effectId);
+        remote()->transact(ATTACH_AUX_EFFECT, data, &reply);
+        return reply.readInt32();
+    }
 };
 
 IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer");
@@ -339,6 +359,16 @@
             reply->setDataPosition(0);
             return NO_ERROR;
         } break;
+        case SET_AUX_EFFECT_SEND_LEVEL: {
+            CHECK_INTERFACE(IMediaPlayer, data, reply);
+            reply->writeInt32(setAuxEffectSendLevel(data.readFloat()));
+            return NO_ERROR;
+        } break;
+        case ATTACH_AUX_EFFECT: {
+            CHECK_INTERFACE(IMediaPlayer, data, reply);
+            reply->writeInt32(attachAuxEffect(data.readInt32()));
+            return NO_ERROR;
+        } break;
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index b43f75f..1c99ae5 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -270,6 +270,7 @@
                     MEDIA_PLAYER_PLAYBACK_COMPLETE | MEDIA_PLAYER_PAUSED ) ) ) {
         mPlayer->setLooping(mLoop);
         mPlayer->setVolume(mLeftVolume, mRightVolume);
+        mPlayer->setAuxEffectSendLevel(mSendLevel);
         mCurrentState = MEDIA_PLAYER_STARTED;
         status_t ret = mPlayer->start();
         if (ret != NO_ERROR) {
@@ -523,6 +524,31 @@
     return mAudioSessionId;
 }
 
+status_t MediaPlayer::setAuxEffectSendLevel(float level)
+{
+    LOGV("MediaPlayer::setAuxEffectSendLevel(%f)", level);
+    Mutex::Autolock _l(mLock);
+    mSendLevel = level;
+    if (mPlayer != 0) {
+        return mPlayer->setAuxEffectSendLevel(level);
+    }
+    return OK;
+}
+
+status_t MediaPlayer::attachAuxEffect(int effectId)
+{
+    LOGV("MediaPlayer::attachAuxEffect(%d)", effectId);
+    Mutex::Autolock _l(mLock);
+    if (mPlayer == 0 ||
+        (mCurrentState & MEDIA_PLAYER_IDLE) ||
+        (mCurrentState == MEDIA_PLAYER_STATE_ERROR )) {
+        LOGE("attachAuxEffect called in state %d", mCurrentState);
+        return INVALID_OPERATION;
+    }
+
+    return mPlayer->attachAuxEffect(effectId);
+}
+
 void MediaPlayer::notify(int msg, int ext1, int ext2)
 {
     LOGV("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2);