From 72784ee9140bbfe5b3d322b1b34f07ebfb82ce27 Mon Sep 17 00:00:00 2001 From: austinried <4966622+austinried@users.noreply.github.com> Date: Fri, 16 Oct 2026 13:06:04 +0000 Subject: [PATCH] playback: warn once when float output would skip the processor Float output is the one way the audio processor chain is skipped on this build, and it is a flag the renderers factory is handed. Nothing sets it, so nothing happens today; if it is ever turned on, this says so once at sink construction rather than leaving replay gain silently inapplicable to high-resolution tracks. Offload has no equivalent check: it is not a flag this code sets, and AudioSink.setOffloadMode is only reachable by building the audio renderer by hand. The factory comment names it instead. --- .../playback/ReplayGainRenderersFactory.kt | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/app/src/main/kotlin/com/subtracks/playback/ReplayGainRenderersFactory.kt b/app/src/main/kotlin/com/subtracks/playback/ReplayGainRenderersFactory.kt index 6e251b42..92fc2363 100644 --- a/app/src/main/kotlin/com/subtracks/playback/ReplayGainRenderersFactory.kt +++ b/app/src/main/kotlin/com/subtracks/playback/ReplayGainRenderersFactory.kt @@ -6,6 +6,7 @@ import androidx.media3.common.util.UnstableApi import androidx.media3.exoplayer.DefaultRenderersFactory import androidx.media3.exoplayer.audio.AudioSink import androidx.media3.exoplayer.audio.DefaultAudioSink +import com.subtracks.log.Log @OptIn(UnstableApi::class) internal class ReplayGainRenderersFactory( @@ -13,16 +14,25 @@ internal class ReplayGainRenderersFactory( private val processor: ReplayGainProcessor, ) : DefaultRenderersFactory(context) { // Mirrors the stock DefaultRenderersFactory.buildAudioSink. setAudioProcessors keeps the default - // chain and prepends ours; DefaultAudioSink omits the whole chain when float output is enabled. + // chain and prepends ours; DefaultAudioSink omits the whole chain when float output is enabled, + // and AudioSink.setOffloadMode bypasses it entirely. public override fun buildAudioSink( context: Context, enableFloatOutput: Boolean, enableAudioOutputPlaybackParameters: Boolean, - ): AudioSink = - DefaultAudioSink + ): AudioSink { + if (enableFloatOutput) { + Log.w(FLOAT_OUTPUT_TAG, "float output is on, so replay gain is not applied to high-resolution tracks") + } + return DefaultAudioSink .Builder(context) .setEnableFloatOutput(enableFloatOutput) .setEnableAudioOutputPlaybackParameters(enableAudioOutputPlaybackParameters) .setAudioProcessors(arrayOf(processor)) .build() + } + + private companion object { + const val FLOAT_OUTPUT_TAG = "replaygain" + } }