diff options
| author | Eric Laurent <elaurent@google.com> | 2010-07-16 07:43:46 -0700 |
|---|---|---|
| committer | Eric Laurent <elaurent@google.com> | 2010-07-21 06:28:01 -0700 |
| commit | 7070b36549d511d6627538c73dfbab23fbae5b43 (patch) | |
| tree | 4a489b863b322e28f7047d7873b17a77056f3b41 | |
| parent | d7514ec6eb17d262d6f9605a2c2f245b7ad7c0b9 (diff) | |
| download | frameworks_base-7070b36549d511d6627538c73dfbab23fbae5b43.zip frameworks_base-7070b36549d511d6627538c73dfbab23fbae5b43.tar.gz frameworks_base-7070b36549d511d6627538c73dfbab23fbae5b43.tar.bz2 | |
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
| -rw-r--r-- | core/jni/android_media_AudioTrack.cpp | 40 | ||||
| -rw-r--r-- | include/media/AudioTrack.h | 5 | ||||
| -rw-r--r-- | include/media/IMediaPlayer.h | 2 | ||||
| -rw-r--r-- | include/media/mediaplayer.h | 3 | ||||
| -rw-r--r-- | media/java/android/media/AudioTrack.java | 62 | ||||
| -rw-r--r-- | media/java/android/media/MediaPlayer.java | 48 | ||||
| -rw-r--r-- | media/jni/android_media_MediaPlayer.cpp | 24 | ||||
| -rw-r--r-- | media/libmedia/AudioTrack.cpp | 14 | ||||
| -rw-r--r-- | media/libmedia/IMediaPlayer.cpp | 30 | ||||
| -rw-r--r-- | media/libmedia/mediaplayer.cpp | 26 | ||||
| -rw-r--r-- | media/libmediaplayerservice/MediaPlayerService.cpp | 47 | ||||
| -rw-r--r-- | media/libmediaplayerservice/MediaPlayerService.h | 7 |
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); |
