Loading core/jni/android_media_AudioTrack.cpp +40 −0 Original line number Diff line number Diff line Loading @@ -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(); Loading @@ -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(); Loading @@ -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(); Loading @@ -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(); Loading @@ -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); Loading Loading @@ -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 Loading Loading @@ -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; } } // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- Loading Loading @@ -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}, }; Loading include/media/AudioTrack.h +3 −2 Original line number Diff line number Diff line Loading @@ -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 */ Loading Loading @@ -479,6 +479,7 @@ private: uint32_t mUpdatePeriod; uint32_t mFlags; int mSessionId; int mAuxEffectId; }; Loading include/media/IMediaPlayer.h +2 −0 Original line number Diff line number Diff line Loading @@ -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. Loading include/media/mediaplayer.h +3 −0 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -200,6 +202,7 @@ private: int mVideoWidth; int mVideoHeight; int mAudioSessionId; float mSendLevel; }; }; // namespace android Loading media/java/android/media/AudioTrack.java +62 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 //------------------ Loading Loading
core/jni/android_media_AudioTrack.cpp +40 −0 Original line number Diff line number Diff line Loading @@ -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(); Loading @@ -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(); Loading @@ -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(); Loading @@ -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(); Loading @@ -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); Loading Loading @@ -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 Loading Loading @@ -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; } } // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- Loading Loading @@ -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}, }; Loading
include/media/AudioTrack.h +3 −2 Original line number Diff line number Diff line Loading @@ -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 */ Loading Loading @@ -479,6 +479,7 @@ private: uint32_t mUpdatePeriod; uint32_t mFlags; int mSessionId; int mAuxEffectId; }; Loading
include/media/IMediaPlayer.h +2 −0 Original line number Diff line number Diff line Loading @@ -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. Loading
include/media/mediaplayer.h +3 −0 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -200,6 +202,7 @@ private: int mVideoWidth; int mVideoHeight; int mAudioSessionId; float mSendLevel; }; }; // namespace android Loading
media/java/android/media/AudioTrack.java +62 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 //------------------ Loading