summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/jni/android_media_AudioTrack.cpp40
-rw-r--r--include/media/AudioTrack.h5
-rw-r--r--include/media/IMediaPlayer.h2
-rw-r--r--include/media/mediaplayer.h3
-rw-r--r--media/java/android/media/AudioTrack.java62
-rw-r--r--media/java/android/media/MediaPlayer.java48
-rw-r--r--media/jni/android_media_MediaPlayer.cpp24
-rw-r--r--media/libmedia/AudioTrack.cpp14
-rw-r--r--media/libmedia/IMediaPlayer.cpp30
-rw-r--r--media/libmedia/mediaplayer.cpp26
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.cpp47
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.h7
12 files changed, 299 insertions, 9 deletions
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index ce43e73..c559670 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -360,6 +360,7 @@ android_media_AudioTrack_start(JNIEnv *env, jobject thiz)
if (lpTrack == NULL ) {
jniThrowException(env, "java/lang/IllegalStateException",
"Unable to retrieve AudioTrack pointer for start()");
+ return;
}
lpTrack->start();
@@ -375,6 +376,7 @@ android_media_AudioTrack_stop(JNIEnv *env, jobject thiz)
if (lpTrack == NULL ) {
jniThrowException(env, "java/lang/IllegalStateException",
"Unable to retrieve AudioTrack pointer for stop()");
+ return;
}
lpTrack->stop();
@@ -390,6 +392,7 @@ android_media_AudioTrack_pause(JNIEnv *env, jobject thiz)
if (lpTrack == NULL ) {
jniThrowException(env, "java/lang/IllegalStateException",
"Unable to retrieve AudioTrack pointer for pause()");
+ return;
}
lpTrack->pause();
@@ -405,6 +408,7 @@ android_media_AudioTrack_flush(JNIEnv *env, jobject thiz)
if (lpTrack == NULL ) {
jniThrowException(env, "java/lang/IllegalStateException",
"Unable to retrieve AudioTrack pointer for flush()");
+ return;
}
lpTrack->flush();
@@ -419,6 +423,7 @@ android_media_AudioTrack_set_volume(JNIEnv *env, jobject thiz, jfloat leftVol, j
if (lpTrack == NULL ) {
jniThrowException(env, "java/lang/IllegalStateException",
"Unable to retrieve AudioTrack pointer for setVolume()");
+ return;
}
lpTrack->setVolume(leftVol, rightVol);
@@ -515,6 +520,7 @@ static jint android_media_AudioTrack_native_write(JNIEnv *env, jobject thiz,
if (lpTrack == NULL) {
jniThrowException(env, "java/lang/IllegalStateException",
"Unable to retrieve AudioTrack pointer for write()");
+ return 0;
}
// get the pointer for the audio data from the java array
@@ -801,6 +807,36 @@ static jint android_media_AudioTrack_get_min_buff_size(JNIEnv *env, jobject thi
return minBuffSize;
}
+// ----------------------------------------------------------------------------
+static void
+android_media_AudioTrack_setAuxEffectSendLevel(JNIEnv *env, jobject thiz, jfloat level )
+{
+ AudioTrack *lpTrack = (AudioTrack *)env->GetIntField(
+ thiz, javaAudioTrackFields.nativeTrackInJavaObj);
+ if (lpTrack == NULL ) {
+ jniThrowException(env, "java/lang/IllegalStateException",
+ "Unable to retrieve AudioTrack pointer for setAuxEffectSendLevel()");
+ return;
+ }
+
+ lpTrack->setAuxEffectSendLevel(level);
+}
+
+// ----------------------------------------------------------------------------
+static jint android_media_AudioTrack_attachAuxEffect(JNIEnv *env, jobject thiz,
+ jint effectId) {
+
+ AudioTrack *lpTrack = (AudioTrack *)env->GetIntField(
+ thiz, javaAudioTrackFields.nativeTrackInJavaObj);
+
+ if (lpTrack) {
+ return android_media_translateErrorCode( lpTrack->attachAuxEffect(effectId) );
+ } else {
+ jniThrowException(env, "java/lang/IllegalStateException",
+ "Unable to retrieve AudioTrack pointer for attachAuxEffect()");
+ return AUDIOTRACK_ERROR;
+ }
+}
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
@@ -837,6 +873,10 @@ static JNINativeMethod gMethods[] = {
"(I)I", (void *)android_media_AudioTrack_get_output_sample_rate},
{"native_get_min_buff_size",
"(III)I", (void *)android_media_AudioTrack_get_min_buff_size},
+ {"native_setAuxEffectSendLevel",
+ "(F)V", (void *)android_media_AudioTrack_setAuxEffectSendLevel},
+ {"native_attachAuxEffect",
+ "(I)I", (void *)android_media_AudioTrack_attachAuxEffect},
};
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index ef537f4..4475d4a 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -261,8 +261,8 @@ public:
/* set the send level for this track. An auxiliary effect should be attached
* to the track with attachEffect(). Level must be <= 1.0.
*/
- status_t setSendLevel(float level);
- void getSendLevel(float* level);
+ status_t setAuxEffectSendLevel(float level);
+ void getAuxEffectSendLevel(float* level);
/* set sample rate for this track, mostly used for games' sound effects
*/
@@ -479,6 +479,7 @@ private:
uint32_t mUpdatePeriod;
uint32_t mFlags;
int mSessionId;
+ int mAuxEffectId;
};
diff --git a/include/media/IMediaPlayer.h b/include/media/IMediaPlayer.h
index 2619691..af9a7ed 100644
--- a/include/media/IMediaPlayer.h
+++ b/include/media/IMediaPlayer.h
@@ -48,6 +48,8 @@ public:
virtual status_t setVolume(float leftVolume, float rightVolume) = 0;
virtual status_t suspend() = 0;
virtual status_t resume() = 0;
+ virtual status_t setAuxEffectSendLevel(float level) = 0;
+ virtual status_t attachAuxEffect(int effectId) = 0;
// Invoke a generic method on the player by using opaque parcels
// for the request and reply.
diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h
index 4963f73..207191d 100644
--- a/include/media/mediaplayer.h
+++ b/include/media/mediaplayer.h
@@ -173,6 +173,8 @@ public:
status_t resume();
status_t setAudioSessionId(int sessionId);
int getAudioSessionId();
+ status_t setAuxEffectSendLevel(float level);
+ status_t attachAuxEffect(int effectId);
private:
void clear_l();
status_t seekTo_l(int msec);
@@ -200,6 +202,7 @@ private:
int mVideoWidth;
int mVideoHeight;
int mAudioSessionId;
+ float mSendLevel;
};
}; // namespace android
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 079c41f..6360541 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -963,6 +963,65 @@ public class AudioTrack
return native_reload_static();
}
+ //--------------------------------------------------------------------------
+ // Audio effects management
+ //--------------------
+
+ /**
+ * Attaches an auxiliary effect to the audio track. A typical auxiliary effect is a
+ * reverberation effect which can be applied on any sound source that directs a certain
+ * amount of its energy to this effect. This amount is defined by setAuxEffectSendLevel().
+ * {@see #setAuxEffectSendLevel(float)}.
+ // TODO when AudioEffect are unhidden
+ * <p>After creating an auxiliary effect (e.g. {_at_link android.media.EnvironmentalReverb}),
+ * retrieve its ID with {_at_link android.media.AudioEffect#getId()} and use it when calling
+ * this method to attach the audio track to the effect.
+ * <p>To detach the effect from the audio track, call this method with a null effect id.
+ *
+ * @param effectId system wide unique id of the effect to attach
+ * @return error code or success, see {@link #SUCCESS},
+ * {@link #ERROR_INVALID_OPERATION}, {@link #ERROR_BAD_VALUE}
+ // FIXME: unhide.
+ * @hide
+ */
+ public int attachAuxEffect(int effectId) {
+ if (mState != STATE_INITIALIZED) {
+ return ERROR_INVALID_OPERATION;
+ }
+ return native_attachAuxEffect(effectId);
+ }
+
+ /**
+ * Sets the send level of the audio track to the attached auxiliary effect
+ * {@see #attachAuxEffect(int)}. The level value range is 0 to 1.0.
+ * <p>By default the send level is 0, so even if an effect is attached to the player
+ * this method must be called for the effect to be applied.
+ * <p>Note that the passed level value is a raw scalar. UI controls should be scaled
+ * logarithmically: the gain applied by audio framework ranges from -72dB to 0dB,
+ * so an appropriate conversion from linear UI input x to level is:
+ * x == 0 -> level = 0
+ * 0 < x <= R -> level = 10^(72*(x-R)/20/R)
+ *
+ * @param level send level scalar
+ * @return error code or success, see {@link #SUCCESS},
+ * {@link #ERROR_INVALID_OPERATION}
+ // FIXME: unhide.
+ * @hide
+ */
+ public int setAuxEffectSendLevel(float level) {
+ if (mState != STATE_INITIALIZED) {
+ return ERROR_INVALID_OPERATION;
+ }
+ // clamp the level
+ if (level < getMinVolume()) {
+ level = getMinVolume();
+ }
+ if (level > getMaxVolume()) {
+ level = getMaxVolume();
+ }
+ native_setAuxEffectSendLevel(level);
+ return SUCCESS;
+ }
//---------------------------------------------------------
// Interface definitions
@@ -1123,6 +1182,9 @@ public class AudioTrack
private native final int native_get_session_id();
+ private native final int native_attachAuxEffect(int effectId);
+ private native final void native_setAuxEffectSendLevel(float level);
+
//---------------------------------------------------------
// Utility methods
//------------------
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 8caa07a..e1f95b2 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -423,7 +423,7 @@ import java.lang.ref.WeakReference;
* <td>Successful invoke of this method in a valid state transfers the
* object to the <em>Stopped</em> state. Calling this method in an
* invalid state transfers the object to the <em>Error</em> state.</p></td></tr>
- * <tr><td>setAudioSessionId </p></td>
+ * <tr><td>setAudioSessionId </p></td>
* <td>{Idle} </p></td>
* <td>{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted,
* Error} </p></td>
@@ -434,6 +434,15 @@ import java.lang.ref.WeakReference;
* <td>{} </p></td>
* <td>This method can be called in any state and calling it does not change
* the object state. </p></td></tr>
+ * <tr><td>attachAuxEffect </p></td>
+ * <td>{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted} </p></td>
+ * <td>{Idle, Error} </p></td>
+ * <td>This method must be called after setDataSource.
+ * Calling it does not change the object state. </p></td></tr>
+ * <tr><td>setAuxEffectSendLevel </p></td>
+ * <td>any</p></td>
+ * <td>{} </p></td>
+ * <td>Calling this method does not change the object state. </p></td></tr>
*
* </table>
*
@@ -1187,7 +1196,7 @@ public class MediaPlayer
* @throws IllegalStateException if it is called in an invalid state
*
// FIXME: unhide.
- // FIXME: link to AudioEffect class when public.
+ // TODO when AudioEffect is unhidden
* @hide
*/
public native void setAudioSessionId(int sessionId) throws IllegalArgumentException, IllegalStateException;
@@ -1203,6 +1212,41 @@ public class MediaPlayer
public native int getAudioSessionId();
/**
+ * Attaches an auxiliary effect to the player. A typical auxiliary effect is a reverberation
+ * effect which can be applied on any sound source that directs a certain amount of its
+ * energy to this effect. This amount is defined by setAuxEffectSendLevel().
+ * {@see #setAuxEffectSendLevel(float)}.
+ // TODO when AudioEffect is unhidden
+ * <p>After creating an auxiliary effect (e.g. {_at_link android.media.EnvironmentalReverb}),
+ * retrieve its ID with {_at_link android.media.AudioEffect#getId()} and use it when calling
+ * this method to attach the player to the effect.
+ * <p>To detach the effect from the player, call this method with a null effect id.
+ * <p>This method must be called after one of the overloaded <code> setDataSource </code>
+ * methods.
+ *
+ * @param effectId system wide unique id of the effect to attach
+ // FIXME: unhide.
+ * @hide
+ */
+ public native void attachAuxEffect(int effectId);
+
+ /**
+ * Sets the send level of the player to the attached auxiliary effect
+ * {@see #attachAuxEffect(int)}. The level value range is 0 to 1.0.
+ * <p>By default the send level is 0, so even if an effect is attached to the player
+ * this method must be called for the effect to be applied.
+ * <p>Note that the passed level value is a raw scalar. UI controls should be scaled
+ * logarithmically: the gain applied by audio framework ranges from -72dB to 0dB,
+ * so an appropriate conversion from linear UI input x to level is:
+ * x == 0 -> level = 0
+ * 0 < x <= R -> level = 10^(72*(x-R)/20/R)
+ * @param level send level scalar
+ // FIXME: unhide.
+ * @hide
+ */
+ public native void setAuxEffectSendLevel(float level);
+
+ /**
* @param request Parcel destinated to the media player. The
* Interface token must be set to the IMediaPlayer
* one to be routed correctly through the system.
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index aedb54a..474a174 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -714,6 +714,28 @@ static jint android_media_MediaPlayer_get_audio_session_id(JNIEnv *env, jobject
return mp->getAudioSessionId();
}
+static void
+android_media_MediaPlayer_setAuxEffectSendLevel(JNIEnv *env, jobject thiz, jfloat level)
+{
+ LOGV("setAuxEffectSendLevel: level %f", level);
+ sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
+ if (mp == NULL ) {
+ jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ return;
+ }
+ process_media_player_call( env, thiz, mp->setAuxEffectSendLevel(level), NULL, NULL );
+}
+
+static void android_media_MediaPlayer_attachAuxEffect(JNIEnv *env, jobject thiz, jint effectId) {
+ LOGV("attachAuxEffect(): %d", sessionId);
+ sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
+ if (mp == NULL ) {
+ jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ return;
+ }
+ process_media_player_call( env, thiz, mp->attachAuxEffect(effectId), NULL, NULL );
+}
+
// ----------------------------------------------------------------------------
static JNINativeMethod gMethods[] = {
@@ -748,6 +770,8 @@ static JNINativeMethod gMethods[] = {
{"native_suspend_resume", "(Z)I", (void *)android_media_MediaPlayer_native_suspend_resume},
{"getAudioSessionId", "()I", (void *)android_media_MediaPlayer_get_audio_session_id},
{"setAudioSessionId", "(I)V", (void *)android_media_MediaPlayer_set_audio_session_id},
+ {"setAuxEffectSendLevel", "(F)V", (void *)android_media_MediaPlayer_setAuxEffectSendLevel},
+ {"attachAuxEffect", "(I)V", (void *)android_media_MediaPlayer_attachAuxEffect},
};
static const char* const kClassPathName = "android/media/MediaPlayer";
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 @@ status_t AudioTrack::set(
mFrameCount = frameCount;
mNotificationFramesReq = notificationFrames;
mSessionId = sessionId;
+ mAuxEffectId = 0;
// create the IAudioTrack
status_t status = createTrack(streamType, sampleRate, format, channelCount,
@@ -458,8 +459,9 @@ void AudioTrack::getVolume(float* left, float* right)
}
}
-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 @@ status_t AudioTrack::setSendLevel(float level)
return NO_ERROR;
}
-void AudioTrack::getSendLevel(float* level)
+void AudioTrack::getAuxEffectSendLevel(float* level)
{
if (level != NULL) {
*level = mSendLevel;
@@ -637,7 +639,12 @@ int AudioTrack::getSessionId()
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 @@ status_t AudioTrack::createTrack(
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 @@ enum {
GET_METADATA,
SUSPEND,
RESUME,
+ SET_AUX_EFFECT_SEND_LEVEL,
+ ATTACH_AUX_EFFECT
};
class BpMediaPlayer: public BpInterface<IMediaPlayer>
@@ -221,6 +223,24 @@ public:
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 @@ status_t BnMediaPlayer::onTransact(
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 @@ status_t MediaPlayer::start()
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 @@ int MediaPlayer::getAudioSessionId()
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);
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 5401ec0..b5972e7 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -329,6 +329,10 @@ status_t MediaPlayerService::AudioOutput::dump(int fd, const Vector<String16>& a
snprintf(buffer, 255, " msec per frame(%f), latency (%d)\n",
mMsecsPerFrame, mLatency);
result.append(buffer);
+ snprintf(buffer, 255, " aux effect id(%d), send level (%f)\n",
+ mAuxEffectId, mSendLevel);
+ result.append(buffer);
+
::write(fd, result.string(), result.size());
if (mTrack != 0) {
mTrack->dump(fd, args);
@@ -1093,6 +1097,21 @@ status_t MediaPlayerService::Client::setVolume(float leftVolume, float rightVolu
return NO_ERROR;
}
+status_t MediaPlayerService::Client::setAuxEffectSendLevel(float level)
+{
+ LOGV("[%d] setAuxEffectSendLevel(%f)", mConnId, level);
+ Mutex::Autolock l(mLock);
+ if (mAudioOutput != 0) return mAudioOutput->setAuxEffectSendLevel(level);
+ return NO_ERROR;
+}
+
+status_t MediaPlayerService::Client::attachAuxEffect(int effectId)
+{
+ LOGV("[%d] attachAuxEffect(%d)", mConnId, effectId);
+ Mutex::Autolock l(mLock);
+ if (mAudioOutput != 0) return mAudioOutput->attachAuxEffect(effectId);
+ return NO_ERROR;
+}
void MediaPlayerService::Client::notify(void* cookie, int msg, int ext1, int ext2)
{
@@ -1285,6 +1304,8 @@ MediaPlayerService::AudioOutput::AudioOutput(int sessionId)
mRightVolume = 1.0;
mLatency = 0;
mMsecsPerFrame = 0;
+ mAuxEffectId = 0;
+ mSendLevel = 0.0;
setMinBufferCount();
}
@@ -1417,10 +1438,13 @@ status_t MediaPlayerService::AudioOutput::open(
LOGV("setVolume");
t->setVolume(mLeftVolume, mRightVolume);
+
mMsecsPerFrame = 1.e3 / (float) sampleRate;
mLatency = t->latency();
mTrack = t;
- return NO_ERROR;
+
+ t->setAuxEffectSendLevel(mSendLevel);
+ return t->attachAuxEffect(mAuxEffectId);;
}
void MediaPlayerService::AudioOutput::start()
@@ -1428,6 +1452,7 @@ void MediaPlayerService::AudioOutput::start()
LOGV("start");
if (mTrack) {
mTrack->setVolume(mLeftVolume, mRightVolume);
+ mTrack->setAuxEffectSendLevel(mSendLevel);
mTrack->start();
}
}
@@ -1481,6 +1506,26 @@ void MediaPlayerService::AudioOutput::setVolume(float left, float right)
}
}
+status_t MediaPlayerService::AudioOutput::setAuxEffectSendLevel(float level)
+{
+ LOGV("setAuxEffectSendLevel(%f)", level);
+ mSendLevel = level;
+ if (mTrack) {
+ return mTrack->setAuxEffectSendLevel(level);
+ }
+ return NO_ERROR;
+}
+
+status_t MediaPlayerService::AudioOutput::attachAuxEffect(int effectId)
+{
+ LOGV("attachAuxEffect(%d)", effectId);
+ mAuxEffectId = effectId;
+ if (mTrack) {
+ return mTrack->attachAuxEffect(effectId);
+ }
+ return NO_ERROR;
+}
+
// static
void MediaPlayerService::AudioOutput::CallbackWrapper(
int event, void *cookie, void *info) {
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 39f525e..a967ee2 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -91,6 +91,8 @@ class MediaPlayerService : public BnMediaPlayerService
virtual void close();
void setAudioStreamType(int streamType) { mStreamType = streamType; }
void setVolume(float left, float right);
+ status_t setAuxEffectSendLevel(float level);
+ status_t attachAuxEffect(int effectId);
virtual status_t dump(int fd, const Vector<String16>& args) const;
static bool isOnEmulator();
@@ -109,7 +111,8 @@ class MediaPlayerService : public BnMediaPlayerService
float mMsecsPerFrame;
uint32_t mLatency;
int mSessionId;
-
+ float mSendLevel;
+ int mAuxEffectId;
static bool mIsOnEmulator;
static int mMinBufferCount; // 12 for emulator; otherwise 4
@@ -221,6 +224,8 @@ private:
Parcel *reply);
virtual status_t suspend();
virtual status_t resume();
+ virtual status_t setAuxEffectSendLevel(float level);
+ virtual status_t attachAuxEffect(int effectId);
sp<MediaPlayerBase> createPlayer(player_type playerType);