playback: switch audioreactor to callback system

Switch AudioReactor to a callback-based system. This makes updating the
volume much faster, as it's no longer reliant on a 500ms polling
interval.
This commit is contained in:
OxygenCobalt 2022-01-07 15:56:43 -07:00
parent 70ac37ca8a
commit e099d1c38c
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
2 changed files with 22 additions and 11 deletions

View file

@ -37,7 +37,10 @@ import kotlin.math.pow
* Manages the current volume and playback state across ReplayGain and AudioFocus events. * Manages the current volume and playback state across ReplayGain and AudioFocus events.
* @author OxygenCobalt * @author OxygenCobalt
*/ */
class AudioReactor(context: Context) : AudioManager.OnAudioFocusChangeListener, SettingsManager.Callback { class AudioReactor(
context: Context,
private val callback: (Float) -> Unit
) : AudioManager.OnAudioFocusChangeListener, SettingsManager.Callback {
private data class Gain(val track: Float, val album: Float) private data class Gain(val track: Float, val album: Float)
private val playbackManager = PlaybackStateManager.maybeGetInstance() private val playbackManager = PlaybackStateManager.maybeGetInstance()
@ -55,12 +58,19 @@ class AudioReactor(context: Context) : AudioManager.OnAudioFocusChangeListener,
.setOnAudioFocusChangeListener(this) .setOnAudioFocusChangeListener(this)
.build() .build()
private var multiplier = 1f
private var pauseWasTransient = false private var pauseWasTransient = false
private var multiplier = 1f
set(value) {
field = value
callback(volume)
}
var volume = 0f private var volume = 0f
get() = field * multiplier get() = field * multiplier
private set set(value) {
field = value
callback(volume)
}
init { init {
settingsManager.addCallback(this) settingsManager.addCallback(this)

View file

@ -126,9 +126,13 @@ class PlaybackService : Service(), Player.Listener, PlaybackStateManager.Callbac
false false
) )
audioReactor = AudioReactor(this) { volume ->
logD("Updating player volume to $volume")
player.volume = volume
}
// --- SYSTEM SETUP --- // --- SYSTEM SETUP ---
audioReactor = AudioReactor(this)
widgets = WidgetController(this) widgets = WidgetController(this)
// Set up the media button callbacks // Set up the media button callbacks
@ -402,19 +406,16 @@ class PlaybackService : Service(), Player.Listener, PlaybackStateManager.Callbac
* Start polling the position on a coroutine. * Start polling the position on a coroutine.
*/ */
private fun startPolling() { private fun startPolling() {
data class Poll(val pos: Long, val multiplier: Float)
val pollFlow = flow { val pollFlow = flow {
while (true) { while (true) {
emit(Poll(player.currentPosition, audioReactor.volume)) emit(player.currentPosition)
delay(POS_POLL_INTERVAL) delay(POS_POLL_INTERVAL)
} }
}.conflate() }.conflate()
serviceScope.launch { serviceScope.launch {
pollFlow.takeWhile { player.isPlaying }.collect { poll -> pollFlow.takeWhile { player.isPlaying }.collect { pos ->
playbackManager.setPosition(poll.pos) playbackManager.setPosition(pos)
player.volume = audioReactor.volume
} }
} }
} }