Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Сan't initialize Audio Effect with error code -3 #1261

Open
mister-svinia opened this issue Apr 10, 2024 · 4 comments
Open

Сan't initialize Audio Effect with error code -3 #1261

mister-svinia opened this issue Apr 10, 2024 · 4 comments

Comments

@mister-svinia
Copy link

mister-svinia commented Apr 10, 2024

Perhaps, similar problems:
https://stackoverflow.com/questions/73911184/cannot-conect-audiotrack-to-audiofx-equalizer-in-kotlin
GautamChibde/android-audio-visualizer#9

Traceback:

2024-04-10 18:03:23.278 11549-11549 Token                   me.example.mediaplayer                 I  10788 // session ID
2024-04-10 18:03:23.283 11549-11549 AudioEffect             me.example.mediaplayer                 E  set(): AudioFlinger could not create effect 0bed4300-ddd6-11db-8f34-0002a5d5c51b / ec7178ec-e5e1-4432-a3f4-4657e6795210, status: -22
2024-04-10 18:03:23.283 11549-11549 AudioEffects-JNI        me.example.mediaplayer                 E  AudioEffect initCheck failed -3
2024-04-10 18:03:23.283 11549-11549 AudioEffect-JAVA        me.example.mediaplayer                 E  Error code -3 when initializing AudioEffect.
2024-04-10 18:03:23.294 11549-11549 AbstractFuture          me.example.mediaplayer                 E  RuntimeException while executing runnable me.example.mediaplayer.MainActivity$$ExternalSyntheticLambda4@dce6a30 with executor MoreExecutors.directExecutor()
                                                                                                    java.lang.RuntimeException: Cannot initialize effect engine for type: 0bed4300-ddd6-11db-8f34-0002a5d5c51b Error: -3
                                                                                                    	at android.media.audiofx.AudioEffect.<init>(AudioEffect.java:545)
                                                                                                    	at android.media.audiofx.AudioEffect.<init>(AudioEffect.java:503)
                                                                                                    	at android.media.audiofx.AudioEffect.<init>(AudioEffect.java:477)
                                                                                                    	at android.media.audiofx.Equalizer.<init>(Equalizer.java:139)
                                                                                                    	at me.example.mediaplayer.effects.XEqualizer.<init>(AudioEffectUtils.kt:46)
                                                                                                    	at me.example.mediaplayer.effects.AudioEffectManager.<init>(AudioEffectUtils.kt:13)
                                                                                                    	at me.example.mediaplayer.views.PlayerPage.initializeAudioControllers$app_debug(MainPages.kt:354)
                                                                                                    	at me.example.mediaplayer.views.PlayerPage.initializeAudioControllers$app_debug$default(MainPages.kt:340)

AudioEffectManage and Equalizer are wrappers over classes from your library.

That's how I get the token:

private val mediaSessionToken: SessionToken by lazy {
    SessionToken(
        this,
        ComponentName(this, MediaService::class.java)
    )
}
private val mediaControllerFuture by lazy {
    MediaController
        .Builder(this, mediaSessionToken)
        .buildAsync()
}
private var mediaController: MediaController? = null
private val audioManager: AudioManager by lazy {
    [email protected](Context.AUDIO_SERVICE) as AudioManager
}

My background service:

import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.session.MediaSession
import androidx.media3.session.MediaSessionService

class MediaService : MediaSessionService() {
        private var mediaSession: MediaSession? = null

    override fun onCreate() {
        super.onCreate()
        mediaSession = MediaSession
            .Builder(
                this,
                ExoPlayer
                    .Builder(this)
                    .build()
            )
            .build()
    }


    override fun onDestroy() {
        mediaSession?.run {
            player.release()
            release()
            mediaSession = null
        }
        super.onDestroy()
    }

    override fun onGetSession(controllerInfo: MediaSession.ControllerInfo) : MediaSession? =
        mediaSession
}

Listening to the creation of the controller:

mediaControllerFuture
    .addListener({
        pagesAdapter.initializeAudioControllers(
            mediaSessionToken.uid,
            mediaControllerFuture.get(),
            mediaSessionToken
        )
    }, MoreExecutors.directExecutor())

And connect effects:

fun initializeAudioControllers(
    audioSessionID: Int,
    audioController: MediaController,
    sessionToken: SessionToken,
) {
    this.audioController = audioController
    this.sessionToken = sessionToken

    Log.i("Token", audioSessionID.toString()) // 10788

    [email protected]?.equalizer?.enabled = false // does not affect
    [email protected]?.bassBoost?.enabled = false // does not affect

    [email protected] = AudioEffectManager(audioSessionID) // exception
}

The strangest thing is that this error occurred about two days ago, I fixed it by removing <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/> from the manifest (but the effects were still not applied, or I do not know how to distinguish them). Now I was experimenting with the interface, and the error occurred again. I rolled back to the commit that I made as soon as the error disappeared (!), but it remained!

@mister-svinia
Copy link
Author

All traceback:

2024-04-10 18:30:37.003 12173-12173 AudioEffect             me.example.mediaplayer                 E  set(): AudioFlinger could not create effect 0bed4300-ddd6-11db-8f34-0002a5d5c51b / ec7178ec-e5e1-4432-a3f4-4657e6795210, status: -22
2024-04-10 18:30:37.003 12173-12173 AudioEffects-JNI        me.example.mediaplayer                 E  AudioEffect initCheck failed -3
2024-04-10 18:30:37.004 12173-12173 AudioEffect-JAVA        me.example.mediaplayer                 E  Error code -3 when initializing AudioEffect.
2024-04-10 18:30:37.005 12173-12173 AbstractFuture          me.example.mediaplayer                 E  RuntimeException while executing runnable me.example.mediaplayer.MainActivity$$ExternalSyntheticLambda4@378be2 with executor MoreExecutors.directExecutor()
                                                                                                    java.lang.RuntimeException: Cannot initialize effect engine for type: 0bed4300-ddd6-11db-8f34-0002a5d5c51b Error: -3
                                                                                                    	at android.media.audiofx.AudioEffect.<init>(AudioEffect.java:545)
                                                                                                    	at android.media.audiofx.AudioEffect.<init>(AudioEffect.java:503)
                                                                                                    	at android.media.audiofx.AudioEffect.<init>(AudioEffect.java:477)
                                                                                                    	at android.media.audiofx.Equalizer.<init>(Equalizer.java:139)
                                                                                                    	at me.example.mediaplayer.effects.XEqualizer.<init>(AudioEffectUtils.kt:46)
                                                                                                    	at me.example.mediaplayer.effects.AudioEffectManager.<init>(AudioEffectUtils.kt:13)
                                                                                                    	at me.example.mediaplayer.effects.AudioEffectManager.<init>(AudioEffectUtils.kt:7)
                                                                                                    	at me.example.mediaplayer.views.PlayerPage.initializeAudioControllers$app_debug(MainPages.kt:371)
                                                                                                    	at me.example.mediaplayer.views.MainFragmentsAdapter.initializeAudioControllers(MainPages.kt:124)
                                                                                                    	at me.example.mediaplayer.MainActivity.bindMediaService$lambda$9(MainActivity.kt:216)
                                                                                                    	at me.example.mediaplayer.MainActivity.$r8$lambda$Lxbggj3KXT1Maq6pu8YUGeqraf4(Unknown Source:0)
                                                                                                    	at me.example.mediaplayer.MainActivity$$ExternalSyntheticLambda4.run(D8$$SyntheticClass:0)
                                                                                                    	at com.google.common.util.concurrent.DirectExecutor.execute(DirectExecutor.java:31)
                                                                                                    	at com.google.common.util.concurrent.AbstractFuture.executeListener(AbstractFuture.java:1286)
                                                                                                    	at com.google.common.util.concurrent.AbstractFuture.complete(AbstractFuture.java:1055)
                                                                                                    	at com.google.common.util.concurrent.AbstractFuture.set(AbstractFuture.java:782)
                                                                                                    	at androidx.media3.session.MediaControllerHolder.maybeSetFutureResult(MediaControllerHolder.java:62)
                                                                                                    	at androidx.media3.session.MediaControllerHolder.onAccepted(MediaControllerHolder.java:52)
                                                                                                    	at androidx.media3.session.MediaController.notifyAccepted(MediaController.java:1969)
                                                                                                    	at androidx.media3.session.MediaControllerImplBase.onConnected(MediaControllerImplBase.java:2636)
                                                                                                    	at androidx.media3.session.MediaControllerStub.lambda$onConnected$0(MediaControllerStub.java:98)
                                                                                                    	at androidx.media3.session.MediaControllerStub$$ExternalSyntheticLambda12.run(D8$$SyntheticClass:0)
                                                                                                    	at androidx.media3.session.MediaControllerStub.lambda$dispatchControllerTaskOnHandler$12(MediaControllerStub.java:349)
                                                                                                    	at androidx.media3.session.MediaControllerStub$$ExternalSyntheticLambda5.run(D8$$SyntheticClass:0)
                                                                                                    	at androidx.media3.common.util.Util.postOrRun(Util.java:824)
                                                                                                    	at androidx.media3.session.MediaControllerStub.dispatchControllerTaskOnHandler(MediaControllerStub.java:341)
                                                                                                    	at androidx.media3.session.MediaControllerStub.onConnected(MediaControllerStub.java:98)
                                                                                                    	at androidx.media3.session.MediaSessionStub.lambda$connect$17$androidx-media3-session-MediaSessionStub(MediaSessionStub.java:546)
                                                                                                    	at androidx.media3.session.MediaSessionStub$$ExternalSyntheticLambda44.run(D8$$SyntheticClass:0)
                                                                                                    	at androidx.media3.common.util.Util.postOrRun(Util.java:824)
                                                                                                    	at androidx.media3.session.MediaSessionStub.connect(MediaSessionStub.java:470)
                                                                                                    	at androidx.media3.session.MediaSessionImpl.connectFromService(MediaSessionImpl.java:703)
                                                                                                    	at androidx.media3.session.MediaSession.handleControllerConnectionFromService(MediaSession.java:1131)
                                                                                                    	at androidx.media3.session.MediaSessionService$MediaSessionServiceStub.lambda$connect$0$androidx-media3-session-MediaSessionService$MediaSessionServiceStub(MediaSessionService.java:720)
                                                                                                    	at androidx.media3.session.MediaSessionService$MediaSessionServiceStub$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0)
                                                                                                    	at android.os.Handler.handleCallback(Handler.java:942)
                                                                                                    	at android.os.Handler.dispatchMessage(Handler.java:99)
                                                                                                    	at android.os.Looper.loopOnce(Looper.java:226)
                                                                                                    	at android.os.Looper.loop(Looper.java:313)
                                                                                                    	at android.app.ActivityThread.main(ActivityThread.java:8762)
                                                                                                    	at java.lang.reflect.Method.invoke(Native Method)
                                                                                                    	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:604)
                                                                                                    	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)

@mister-svinia mister-svinia changed the title Сan't initialize Audio Effect with code -3 Сan't initialize Audio Effect with error code -3 Apr 11, 2024
@marcbaechinger
Copy link
Contributor

Thanks for your report!

From the stack trace above, it looks like the exception is coming from classes of the app without any library involvement:

...
at me.example.mediaplayer.effects.XEqualizer.<init>(AudioEffectUtils.kt:46)
at me.example.mediaplayer.effects.AudioEffectManager.<init>(AudioEffectUtils.kt:13)
at me.example.mediaplayer.effects.AudioEffectManager.<init>(AudioEffectUtils.kt:7)
at me.example.mediaplayer.views.PlayerPage.initializeAudioControllers$app_debug(MainPages.kt:371)
at me.example.mediaplayer.views.MainFragmentsAdapter.initializeAudioControllers(MainPages.kt:124)
at me.example.mediaplayer.MainActivity.bindMediaService$lambda$9(MainActivity.kt:216)

This looks like a problem that can't be fixed from the library side I'm afraid. If you think this is related to the library, please add some more information how you think this is the case. Else we are probably unable to help you with fixing this.

@mister-svinia
Copy link
Author

The 'XEqualizerandXBassBoost` classes:

class XEqualizer(
    priority: Int,
    audioSessionId: Int,
) : Equalizer(priority, audioSessionId) {

    private val enableStatusListeners = mutableListOf<(Boolean) -> Unit>()
    private val propertiesChangeListeners = mutableListOf<(Settings?) -> Unit>()
    private val bandChangeListeners = mutableListOf<(band: Short, level: Short) -> Unit>()

    private var currPreset: Short = currentPreset
        private set

    fun addEnableStatusChangeListener(listener: (Boolean) -> Unit) {
        enableStatusListeners.add(listener)
    }

    fun removeEnableStatusChangeListener(listener: (Boolean) -> Unit) {
        enableStatusListeners.remove(listener)
    }

    fun addPropertiesChangeListener(listener: (Settings?) -> Unit) {
        propertiesChangeListeners.add(listener)
    }

    fun removePropertiesChangeListener(listener: (Settings?) -> Unit) {
        propertiesChangeListeners.remove(listener)
    }

    fun addBandChangeListeners(listener: (band: Short, level: Short) -> Unit) {
        bandChangeListeners.add(listener)
    }

    fun removeBandChangeListeners(listener: (band: Short, level: Short) -> Unit) {
        bandChangeListeners.remove(listener)
    }

    override fun usePreset(preset: Short) {
        super.usePreset(preset)
        currPreset = preset
    }

    override fun release() {
        try {
            super.release()
        } finally {
            bandChangeListeners.clear()
            propertiesChangeListeners.clear()
            enableStatusListeners.clear()
        }
    }

    override fun setEnabled(enabled: Boolean): Int {
        try {
            return super.setEnabled(enabled)
        } finally {
            enableStatusListeners.forEach {
                it(enabled)
            }
        }
    }

    override fun setProperties(settings: Settings?) {
        try {
            super.setProperties(settings)
        } finally {
            propertiesChangeListeners.forEach {
                it(settings)
            }
        }
    }

    override fun setBandLevel(band: Short, level: Short) {
        try {
            super.setBandLevel(band, level)
        } finally {
            bandChangeListeners.forEach {
                it(band, level)
            }
        }
    }
}

class XBassBoost(
    priority: Int,
    audioSessionId: Int,
) : BassBoost(priority, audioSessionId) {

    private val maxRecommendedStrength = 19

    private val enableStatusListeners = mutableListOf<(Boolean) -> Unit>()
    private val propertiesChangeListeners = mutableListOf<(Settings?) -> Unit>()
    private val strengthChangeListeners = mutableListOf<(Short) -> Unit>()

    fun addEnableStatusChangeListener(listener: (Boolean) -> Unit) {
        enableStatusListeners.add(listener)
    }

    fun removeEnableStatusChangeListener(listener: (Boolean) -> Unit) {
        enableStatusListeners.remove(listener)
    }

    fun addPropertiesChangeListener(listener: (Settings?) -> Unit) {
        propertiesChangeListeners.add(listener)
    }

    fun removePropertiesChangeListener(listener: (Settings?) -> Unit) {
        propertiesChangeListeners.remove(listener)
    }

    fun addBandChangeListeners(listener: (Short) -> Unit) {
        strengthChangeListeners.add(listener)
    }

    fun removeBandChangeListeners(listener: (Short) -> Unit) {
        strengthChangeListeners.remove(listener)
    }

    override fun setStrength(strength: Short) {
        try {
            super.setStrength((1000F / maxRecommendedStrength * strength).toInt().toShort())
        } finally {
            strengthChangeListeners.forEach {
                it(strength)
            }
        }
    }

    override fun getRoundedStrength(): Short {
        return (super.getRoundedStrength() / (1000F / maxRecommendedStrength)).toInt().toShort()
    }

    override fun release() {
        try {
            super.release()
        } finally {
            strengthChangeListeners.clear()
            propertiesChangeListeners.clear()
            enableStatusListeners.clear()
        }
    }

    override fun setEnabled(enabled: Boolean): Int {
        try {
            return super.setEnabled(enabled)
        } finally {
            enableStatusListeners.forEach {
                it(enabled)
            }
        }
    }

    override fun setProperties(settings: Settings?) {
        try {
            super.setProperties(settings)
        } finally {
            propertiesChangeListeners.forEach {
                it(settings)
            }
        }
    }
}

Manager:

class AudioEffectManager(
    audioSessionId: Int,
    initialState: Boolean = true,
) {
    private var releaseListeners = mutableListOf<() -> Unit>()

    var equalizer: XEqualizer = XEqualizer(Integer.MAX_VALUE, audioSessionId)
        private set

    var bassBoost: XBassBoost = XBassBoost(Integer.MAX_VALUE, audioSessionId)
        private set

    init {
        bassBoost.enabled = initialState
        equalizer.enabled = initialState
    }

    fun addReleaseListener(listener: () -> Unit) {
        releaseListeners.add(listener)
    }

    fun removeReleaseListener(listener: () -> Unit) {
        releaseListeners.remove(listener)
    }

    fun release() {
        try {
            equalizer.release()
            bassBoost.release()
        } finally {
            releaseListeners.forEach { it() }
            releaseListeners.clear()
        }
    }
}

@mister-svinia
Copy link
Author

I forgot to mention that this code is located in the activity fields `MainActivity'.

private val mediaSessionToken: SessionToken by lazy {
    SessionToken(
        this,
        ComponentName(this, MediaService::class.java)
    )
}
private val mediaControllerFuture by lazy {
    MediaController
        .Builder(this, mediaSessionToken)
        .buildAsync()
}
private var mediaController: MediaController? = null
private val audioManager: AudioManager by lazy {
    this@MainActivity.getSystemService(Context.AUDIO_SERVICE) as AudioManager
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants