Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7070b365 authored by Eric Laurent's avatar Eric Laurent
Browse files

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
parent d7514ec6
Loading
Loading
Loading
Loading
+40 −0
Original line number Diff line number Diff line
@@ -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},
};


+3 −2
Original line number Diff line number Diff line
@@ -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;
};


+2 −0
Original line number Diff line number Diff line
@@ -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.
+3 −0
Original line number Diff line number Diff line
@@ -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
+62 −0
Original line number Diff line number Diff line
@@ -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
    //------------------
Loading