From a1c834d35335ff819d8d4ae27c616746e3e64228 Mon Sep 17 00:00:00 2001 From: bastard <134429563+RustoMCSpit@users.noreply.github.com> Date: Sat, 26 Oct 2024 18:36:42 +0100 Subject: [PATCH] feat: changing reverb (#600) Co-authored-by: henry --- .../zyrouge/symphony/services/radio/Radio.kt | 11 ++- .../symphony/services/radio/RadioPlayer.kt | 22 +++++ .../zyrouge/symphony/ui/view/NowPlaying.kt | 2 + .../symphony/ui/view/nowPlaying/BottomBar.kt | 12 ++- .../ui/view/nowPlaying/SpeedPitchDialog.kt | 98 +++++++++++++++++++ 5 files changed, 143 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/io/github/zyrouge/symphony/services/radio/Radio.kt b/app/src/main/java/io/github/zyrouge/symphony/services/radio/Radio.kt index 56ec6743..d4a0bc78 100644 --- a/app/src/main/java/io/github/zyrouge/symphony/services/radio/Radio.kt +++ b/app/src/main/java/io/github/zyrouge/symphony/services/radio/Radio.kt @@ -68,6 +68,7 @@ class Radio(private val symphony: Symphony) : SymphonyHooks { var persistedSpeed: Float = RadioPlayer.DEFAULT_SPEED var persistedPitch: Float = RadioPlayer.DEFAULT_PITCH + var persistedReverb: Float = RadioPlayer.DEFAULT_REVERB var sleepTimer: RadioSleepTimer? = null var pauseOnCurrentSongEnd = false @@ -244,7 +245,15 @@ class Radio(private val symphony: Symphony) : SymphonyHooks { onUpdate.dispatch(RadioEvents.PitchChanged) } } - + fun setReverb(reverb: Float, persist: Boolean) { + player?.let { + it.setReverb(reverb) + if (persist) { + persistedReverb = reverb + } + onUpdate.dispatch(RadioEvents.PitchChanged) + } + } fun setSleepTimer( duration: Long, quitOnEnd: Boolean, diff --git a/app/src/main/java/io/github/zyrouge/symphony/services/radio/RadioPlayer.kt b/app/src/main/java/io/github/zyrouge/symphony/services/radio/RadioPlayer.kt index 8c396288..506bcc34 100644 --- a/app/src/main/java/io/github/zyrouge/symphony/services/radio/RadioPlayer.kt +++ b/app/src/main/java/io/github/zyrouge/symphony/services/radio/RadioPlayer.kt @@ -54,6 +54,7 @@ class RadioPlayer(val symphony: Symphony, uri: Uri) { var volume: Float = MAX_VOLUME var speed: Float = DEFAULT_SPEED var pitch: Float = DEFAULT_PITCH + var reverb: Float = DEFAULT_REVERB val fadePlayback: Boolean get() = symphony.settings.fadePlayback.value val audioSessionId: Int? @@ -187,6 +188,26 @@ class RadioPlayer(val symphony: Symphony, uri: Uri) { } } + @JvmName("setReverbTo") + fun setReverb(to: Float) { + if (!hasPlayedOnce) { + reverb = to + return + } + mediaPlayer?.let { + val isPlaying = it.isPlaying + try { + it.playbackParams = it.playbackParams.setReverb(to) + reverb = to + } catch (err: Exception) { + Logger.error("RadioPlayer", "changing reverb failed", err) + } + if (!isPlaying) { + it.pause() + } + } + } + fun setOnPlaybackPositionListener(listener: RadioPlayerOnPlaybackPositionListener?) { onPlaybackPosition = listener } @@ -218,5 +239,6 @@ class RadioPlayer(val symphony: Symphony, uri: Uri) { const val DUCK_VOLUME = 0.2f const val DEFAULT_SPEED = 1f const val DEFAULT_PITCH = 1f + const val DEFAULT_REVERB = 1f } } diff --git a/app/src/main/java/io/github/zyrouge/symphony/ui/view/NowPlaying.kt b/app/src/main/java/io/github/zyrouge/symphony/ui/view/NowPlaying.kt index 7b742a9d..a04a777c 100644 --- a/app/src/main/java/io/github/zyrouge/symphony/ui/view/NowPlaying.kt +++ b/app/src/main/java/io/github/zyrouge/symphony/ui/view/NowPlaying.kt @@ -24,8 +24,10 @@ data class NowPlayingData( val currentShuffleMode: Boolean, val currentSpeed: Float, val currentPitch: Float, + val currentReverb: Float, val persistedSpeed: Float, val persistedPitch: Float, + val persistedReverb: Float, val hasSleepTimer: Boolean, val pauseOnCurrentSongEnd: Boolean, val showSongAdditionalInfo: Boolean, diff --git a/app/src/main/java/io/github/zyrouge/symphony/ui/view/nowPlaying/BottomBar.kt b/app/src/main/java/io/github/zyrouge/symphony/ui/view/nowPlaying/BottomBar.kt index f5dca088..601e7a76 100644 --- a/app/src/main/java/io/github/zyrouge/symphony/ui/view/nowPlaying/BottomBar.kt +++ b/app/src/main/java/io/github/zyrouge/symphony/ui/view/nowPlaying/BottomBar.kt @@ -73,6 +73,7 @@ fun NowPlayingBodyBottomBar( var showSleepTimerDialog by remember { mutableStateOf(false) } var showSpeedDialog by remember { mutableStateOf(false) } var showPitchDialog by remember { mutableStateOf(false) } + var showReverbDialog by remember { mutableStateOf(false) } var showExtraOptions by remember { mutableStateOf(false) } data.run { @@ -212,7 +213,16 @@ fun NowPlayingBodyBottomBar( } ) } - + if (showReverbDialog) { + NowPlayingReverbDialog( + context, + currentReverb= data.currentReverb, + persistedReverb = data.persistedReverb, + onDismissRequest = { + showReverbDialog = false + } + ) + } if (showExtraOptions) { val sheetState = rememberModalBottomSheetState() val closeBottomSheet = { diff --git a/app/src/main/java/io/github/zyrouge/symphony/ui/view/nowPlaying/SpeedPitchDialog.kt b/app/src/main/java/io/github/zyrouge/symphony/ui/view/nowPlaying/SpeedPitchDialog.kt index 689fbe90..14e80278 100644 --- a/app/src/main/java/io/github/zyrouge/symphony/ui/view/nowPlaying/SpeedPitchDialog.kt +++ b/app/src/main/java/io/github/zyrouge/symphony/ui/view/nowPlaying/SpeedPitchDialog.kt @@ -1,5 +1,6 @@ package io.github.zyrouge.symphony.ui.view.nowPlaying +import android.media.audiofx.PresetReverb import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement @@ -222,3 +223,100 @@ fun NowPlayingPitchDialog( }, ) } + +@Composable +fun NowPlayingReverbDialog( + context: ViewContext, + currentReverb: Float, + persistedReverb: Float, + onDismissRequest: () -> Unit, +) { + val allowedReverb = listOf(0.5f, 1f, 1.5f, 2f, 3f) + val allowedReverbRange = allowedReverb.first()..allowedReverb.last() + var persistent by remember { + mutableStateOf(currentReverb == persistedReverb) + } + + ScaffoldDialog( + onDismissRequest = onDismissRequest, + title = { + Text(context.symphony.t.Reverb) + }, + content = { + Column(modifier = Modifier.padding(0.dp, 8.dp)) { + Row( + horizontalArrangement = Arrangement.spacedBy( + 4.dp, + Alignment.CenterHorizontally + ), + modifier = Modifier + .fillMaxWidth() + .padding(top = 16.dp), + ) { + allowedReverb.forEach { reverb -> + val onClick = { + context.symphony.radio.setReverb(reverb, persistent) + } + val shape = RoundedCornerShape(4.dp) + + Text( + "x$reverb", + style = MaterialTheme.typography.labelMedium, + modifier = Modifier + .background( + MaterialTheme.colorScheme.surfaceVariant, + shape, + ) + .clip(shape) + . clickable(onClick = onClick) + .padding(8.dp, 4.dp) + ) + } + } + Slider( + value = currentReverb, + onChange = { value -> + val reverb = (value * 10).roundToInt().toFloat() / 10 + context.symphony.radio.setReverb(reverb, persistent) + }, + range = allowedReverbRange, + label = { value -> + Text("x$value") + }, + modifier = Modifier + .padding(top = 24.dp, bottom = 8.dp) + ) + + Row( + modifier = Modifier.padding(12.dp, 0.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Checkbox( + checked = persistent, + onCheckedChange = { + persistent = !persistent + context.symphony.radio.setReverb(currentReverb, persistent) + } + ) + Spacer(modifier = Modifier.width(8.dp)) + Text(context.symphony.t.PersistUntilQueueEnd) + } + } + }, + actions = { + TextButton( + onClick = { + context.symphony.radio.setReverb(1f, persistent) + onDismissRequest() + } + ) { + Text(context.symphony.t.Reset) + } + TextButton( + onClick = onDismissRequest + ) { + Text(context.symphony.t.Done) + } + }, + ) +}