mirror of
https://github.com/austinried/subtracks.git
synced 2026-11-11 07:29:14 +01:00
playback: apply the item's gain in one tested step
Review follow-ups. - `ReplayGainController.applyItem` owns reading the gain off a `MediaItem`, so the transition, the controller and the extras read are exercised together rather than only in isolation. - drop the leftover `setTrack(null)` on a missing active source: now that the transition sets the gain from the item, that line only raced it and could reset a playing item to unity. - tests for a zero gain surviving the extras round trip (zero is a real gain, not an absent one), for the latest item's gain being the one left applied, and for a missing item applying unity.
This commit is contained in:
@@ -266,6 +266,10 @@ private fun Bundle.putGain(
|
|||||||
|
|
||||||
private fun Bundle.gain(key: String): Float? = if (containsKey(key)) getFloat(key) else null
|
private fun Bundle.gain(key: String): Float? = if (containsKey(key)) getFloat(key) else null
|
||||||
|
|
||||||
|
internal fun ReplayGainController.applyItem(mediaItem: MediaItem?) {
|
||||||
|
setTrack(mediaItem.replayGain())
|
||||||
|
}
|
||||||
|
|
||||||
internal fun queueMediaItem(
|
internal fun queueMediaItem(
|
||||||
item: QueueItem,
|
item: QueueItem,
|
||||||
local: String?,
|
local: String?,
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ class PlaybackService : MediaSessionService() {
|
|||||||
reason: Int,
|
reason: Int,
|
||||||
) {
|
) {
|
||||||
observeCurrentSong(mediaItem?.mediaId)
|
observeCurrentSong(mediaItem?.mediaId)
|
||||||
replayGain.setTrack(mediaItem?.replayGain())
|
replayGain.applyItem(mediaItem)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -187,11 +187,7 @@ class PlaybackService : MediaSessionService() {
|
|||||||
session?.setMediaButtonPreferences(listOf(starButton(false)))
|
session?.setMediaButtonPreferences(listOf(starButton(false)))
|
||||||
songJob =
|
songJob =
|
||||||
scope.launch {
|
scope.launch {
|
||||||
val sourceId = sourceRepository?.activeSourceIdOnce()
|
val sourceId = sourceRepository?.activeSourceIdOnce() ?: return@launch
|
||||||
if (sourceId == null) {
|
|
||||||
replayGain.setTrack(null)
|
|
||||||
return@launch
|
|
||||||
}
|
|
||||||
library.song(sourceId, songId).collect { song ->
|
library.song(sourceId, songId).collect { song ->
|
||||||
if (currentSongId != songId) return@collect
|
if (currentSongId != songId) return@collect
|
||||||
starred = song?.starred != null
|
starred = song?.starred != null
|
||||||
|
|||||||
@@ -76,4 +76,17 @@ class MediaItemTest {
|
|||||||
|
|
||||||
assertEquals(ReplayGain(), item.replayGain())
|
assertEquals(ReplayGain(), item.replayGain())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun aZeroGainIsNotMistakenForNoGain() {
|
||||||
|
val item =
|
||||||
|
queueMediaItem(
|
||||||
|
song.copy(replayGain = ReplayGain(trackGain = 0f, trackPeak = 0.5f)),
|
||||||
|
local = null,
|
||||||
|
stream = "http://server/stream?s=s1",
|
||||||
|
transcode = false,
|
||||||
|
)
|
||||||
|
|
||||||
|
assertEquals(ReplayGain(trackGain = 0f, trackPeak = 0.5f), item.replayGain())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
package com.subtracks.playback
|
package com.subtracks.playback
|
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
import com.subtracks.data.prefs.ReplayGainMode
|
import com.subtracks.data.prefs.ReplayGainMode
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
class ReplayGainControllerTest {
|
class ReplayGainControllerTest {
|
||||||
private val applied = mutableListOf<Float>()
|
private val applied = mutableListOf<Float>()
|
||||||
private val controller = ReplayGainController { applied += it }
|
private val controller = ReplayGainController { applied += it }
|
||||||
@@ -43,6 +46,52 @@ class ReplayGainControllerTest {
|
|||||||
assertEquals(1f, applied.last(), TOLERANCE)
|
assertEquals(1f, applied.last(), TOLERANCE)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun theLatestItemLeavesItsGainApplied() {
|
||||||
|
controller.setSettings(ReplayGainSettings(ReplayGainMode.Track, 0f))
|
||||||
|
|
||||||
|
controller.applyItem(item("a", trackGain = 6.0206f))
|
||||||
|
controller.applyItem(item("b", trackGain = -6.0206f))
|
||||||
|
|
||||||
|
assertEquals(0.5f, applied.last(), TOLERANCE)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun anItemWithoutGainPlaysAtUnity() {
|
||||||
|
controller.setSettings(ReplayGainSettings(ReplayGainMode.Track, 0f))
|
||||||
|
|
||||||
|
controller.applyItem(item("a", trackGain = null))
|
||||||
|
|
||||||
|
assertEquals(1f, applied.last(), TOLERANCE)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun noItemPlaysAtUnity() {
|
||||||
|
controller.setSettings(ReplayGainSettings(ReplayGainMode.Track, 0f))
|
||||||
|
controller.applyItem(item("a", trackGain = 6.0206f))
|
||||||
|
|
||||||
|
controller.applyItem(null)
|
||||||
|
|
||||||
|
assertEquals(1f, applied.last(), TOLERANCE)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun item(
|
||||||
|
id: String,
|
||||||
|
trackGain: Float?,
|
||||||
|
) = queueMediaItem(
|
||||||
|
QueueItem(
|
||||||
|
id = id,
|
||||||
|
title = id,
|
||||||
|
artist = null,
|
||||||
|
album = null,
|
||||||
|
coverArtId = null,
|
||||||
|
replayGain = ReplayGain(trackGain = trackGain),
|
||||||
|
),
|
||||||
|
local = null,
|
||||||
|
stream = "http://server/$id",
|
||||||
|
transcode = false,
|
||||||
|
)
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
const val TOLERANCE = 0.001f
|
const val TOLERANCE = 0.001f
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user