From 07a98029c6813f99a5213ffeb78ab241af632a9f Mon Sep 17 00:00:00 2001 From: Alexander Capehart Date: Tue, 20 Feb 2024 11:10:20 -0700 Subject: [PATCH 1/7] music: fix opus replaygain interpretation - Don't parse the base gain, the media player actually does apply it. - Adjust R128 tags to LUFS -18 to be consistent w/MP3. Resolves #521. --- CHANGELOG.md | 6 +++ .../oxycblt/auxio/music/metadata/TagWorker.kt | 47 ++++++++++++------- 2 files changed, 35 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b7f65701a..9c21c750f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## dev + +#### What's Fixed +- R128 adjustments are now adjusted to -18 LUFS to be consistent with MP3 +- Fixed double application of opus base gain + ## 3.4.0 #### What's New diff --git a/app/src/main/java/org/oxycblt/auxio/music/metadata/TagWorker.kt b/app/src/main/java/org/oxycblt/auxio/music/metadata/TagWorker.kt index 2167c195d..d41b67c73 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/metadata/TagWorker.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/metadata/TagWorker.kt @@ -99,22 +99,27 @@ private class TagWorkerImpl( populateWithId3v2(textTags.id3v2) populateWithVorbis(textTags.vorbis) - // If this metadata is of a vorbis file, we actually need to extract it's base gain - // and divide it by 256 to get the gain in decibels. - if (format.sampleMimeType == MimeTypes.AUDIO_OPUS && - format.initializationData.isNotEmpty() && - format.initializationData[0].size >= 18) { - val header = format.initializationData[0] - val gain = (((header[16]).toInt() and 0xFF) or ((header[17].toInt() shl 8))) / 256f - logD("Obtained opus base gain: $gain dB") - if (gain != 0f) { - logD("Applying opus base gain") - rawSong.replayGainTrackAdjustment = - (rawSong.replayGainTrackAdjustment ?: 0f) + gain - rawSong.replayGainAlbumAdjustment = - (rawSong.replayGainAlbumAdjustment ?: 0f) + gain - } - } + + // OPUS base gain interpretation code: This is likely not needed, as the media player + // should be using the base gain already. Uncomment if that's not the case. + //if (format.sampleMimeType == MimeTypes.AUDIO_OPUS + // && format.initializationData.isNotEmpty() + // && format.initializationData[0].size >= 18) { + // val header = format.initializationData[0] + // val gain = + // (((header[16]).toInt() and 0xFF) or ((header[17].toInt() shl 8))) + // .R128ToLUFS18() + // logD("Obtained opus base gain: $gain dB") + // if (gain != 0f) { + // logD("Applying opus base gain") + // rawSong.replayGainTrackAdjustment = + // (rawSong.replayGainTrackAdjustment ?: 0f) + gain + // rawSong.replayGainAlbumAdjustment = + // (rawSong.replayGainAlbumAdjustment ?: 0f) + gain + // } else { + // logD("Ignoring opus base gain") + // } + //} } else { logD("No metadata could be extracted for ${rawSong.name}") } @@ -317,14 +322,20 @@ private class TagWorkerImpl( // the base adjustment intrinsic to the format to create the normalized adjustment. This is // normally the only tag used for opus files, but some software still writes replay gain // tags anyway. - (comments["r128_track_gain"]?.parseReplayGainAdjustment()?.div(256) + (comments["r128_track_gain"]?.parseR128Adjustment() ?: comments["replaygain_track_gain"]?.parseReplayGainAdjustment()) ?.let { rawSong.replayGainTrackAdjustment = it } - (comments["r128_album_gain"]?.parseReplayGainAdjustment()?.div(256) + (comments["r128_album_gain"]?.parseR128Adjustment() ?: comments["replaygain_album_gain"]?.parseReplayGainAdjustment()) ?.let { rawSong.replayGainAlbumAdjustment = it } } + private fun List.parseR128Adjustment() = + first().replace(REPLAYGAIN_ADJUSTMENT_FILTER_REGEX, "").toFloatOrNull()?.nonZeroOrNull()?.run { + // Convert to fixed-point and adjust to LUFS 18 to match the ReplayGain scale + this / 256f + 5 + } + /** * Parse a ReplayGain adjustment into a float value. * From a036005f751e7cf299d0e7c0057831bc9e6540e5 Mon Sep 17 00:00:00 2001 From: Alexander Capehart Date: Sat, 24 Feb 2024 12:37:49 -0700 Subject: [PATCH 2/7] playback: fix broken state restore --- .../auxio/playback/state/PlaybackStateManager.kt | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt index 0ebaf669f..b4c13cb24 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt @@ -418,12 +418,14 @@ class PlaybackStateManagerImpl @Inject constructor() : PlaybackStateManager { } this.stateHolder = stateHolder - if (isInitialized && stateMirror.index > -1) { - stateHolder.applySavedState(stateMirror.parent, stateMirror.rawQueue, null) - stateHolder.seekTo(stateMirror.progression.calculateElapsedPositionMs()) - stateHolder.playing(false) - pendingDeferredPlayback?.let(stateHolder::handleDeferred) + if (isInitialized) { + if (currentSong != null) { + stateHolder.applySavedState(stateMirror.parent, stateMirror.rawQueue, null) + stateHolder.seekTo(stateMirror.progression.calculateElapsedPositionMs()) + stateHolder.playing(false) + } } + pendingDeferredPlayback?.let(stateHolder::handleDeferred) } @Synchronized From 5efdfb6aacfc7e442730890bc85928d9a8ccd641 Mon Sep 17 00:00:00 2001 From: Alexander Capehart Date: Sat, 24 Feb 2024 13:27:52 -0700 Subject: [PATCH 3/7] home: make sure to avoid touch overlay crash Only configure the touch overlay when the fragment resumes, and don't do any weird post stuff. --- .../java/org/oxycblt/auxio/home/HomeFragment.kt | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/org/oxycblt/auxio/home/HomeFragment.kt b/app/src/main/java/org/oxycblt/auxio/home/HomeFragment.kt index 1d5c5bdde..41a1055a7 100644 --- a/app/src/main/java/org/oxycblt/auxio/home/HomeFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/home/HomeFragment.kt @@ -222,19 +222,17 @@ class HomeFragment : collect(detailModel.toShow.flow, ::handleShow) } - override fun onStart() { - super.onStart() + override fun onResume() { + super.onResume() // Stock bottom sheet overlay won't work with our nested UI setup, have to replicate // it ourselves. requireBinding().root.rootView.apply { - post { - findViewById(R.id.main_scrim).setOnTouchListener { _, event -> - handleSpeedDialBoundaryTouch(event) - } - findViewById(R.id.sheet_scrim).setOnTouchListener { _, event -> - handleSpeedDialBoundaryTouch(event) - } + findViewById(R.id.main_scrim).setOnTouchListener { _, event -> + handleSpeedDialBoundaryTouch(event) + } + findViewById(R.id.sheet_scrim).setOnTouchListener { _, event -> + handleSpeedDialBoundaryTouch(event) } } } From 3a04bef07475c9e8954ac9bfedbbade4d86b5f09 Mon Sep 17 00:00:00 2001 From: Alexander Capehart Date: Sat, 24 Feb 2024 13:28:49 -0700 Subject: [PATCH 4/7] all: reformat --- .../oxycblt/auxio/music/metadata/TagWorker.kt | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/org/oxycblt/auxio/music/metadata/TagWorker.kt b/app/src/main/java/org/oxycblt/auxio/music/metadata/TagWorker.kt index d41b67c73..78669caee 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/metadata/TagWorker.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/metadata/TagWorker.kt @@ -20,7 +20,6 @@ package org.oxycblt.auxio.music.metadata import androidx.core.text.isDigitsOnly import androidx.media3.common.MediaItem -import androidx.media3.common.MimeTypes import androidx.media3.exoplayer.MetadataRetriever import androidx.media3.exoplayer.source.MediaSource import androidx.media3.exoplayer.source.TrackGroupArray @@ -99,10 +98,9 @@ private class TagWorkerImpl( populateWithId3v2(textTags.id3v2) populateWithVorbis(textTags.vorbis) - // OPUS base gain interpretation code: This is likely not needed, as the media player // should be using the base gain already. Uncomment if that's not the case. - //if (format.sampleMimeType == MimeTypes.AUDIO_OPUS + // if (format.sampleMimeType == MimeTypes.AUDIO_OPUS // && format.initializationData.isNotEmpty() // && format.initializationData[0].size >= 18) { // val header = format.initializationData[0] @@ -119,7 +117,7 @@ private class TagWorkerImpl( // } else { // logD("Ignoring opus base gain") // } - //} + // } } else { logD("No metadata could be extracted for ${rawSong.name}") } @@ -331,10 +329,14 @@ private class TagWorkerImpl( } private fun List.parseR128Adjustment() = - first().replace(REPLAYGAIN_ADJUSTMENT_FILTER_REGEX, "").toFloatOrNull()?.nonZeroOrNull()?.run { - // Convert to fixed-point and adjust to LUFS 18 to match the ReplayGain scale - this / 256f + 5 - } + first() + .replace(REPLAYGAIN_ADJUSTMENT_FILTER_REGEX, "") + .toFloatOrNull() + ?.nonZeroOrNull() + ?.run { + // Convert to fixed-point and adjust to LUFS 18 to match the ReplayGain scale + this / 256f + 5 + } /** * Parse a ReplayGain adjustment into a float value. From dd118b4529a34dc2b9054f0d027f5473537759c1 Mon Sep 17 00:00:00 2001 From: Alexander Capehart Date: Sat, 24 Feb 2024 14:38:01 -0700 Subject: [PATCH 5/7] build: bump to 3.4.1 Bump to version 3.4.1 (42). --- CHANGELOG.md | 3 ++- README.md | 4 ++-- app/build.gradle | 4 ++-- fastlane/metadata/android/en-US/changelogs/42.txt | 3 +++ 4 files changed, 9 insertions(+), 5 deletions(-) create mode 100644 fastlane/metadata/android/en-US/changelogs/42.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c21c750f..186558c62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,11 @@ # Changelog -## dev +## 3.4.1 #### What's Fixed - R128 adjustments are now adjusted to -18 LUFS to be consistent with MP3 - Fixed double application of opus base gain +- Fixed playback state not restoring ## 3.4.0 diff --git a/README.md b/README.md index 084ea5a5a..85006d016 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@

Auxio

A simple, rational music player for android.

- - Latest Version + + Latest Version Releases diff --git a/app/build.gradle b/app/build.gradle index af0bf21bb..d17211886 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -21,8 +21,8 @@ android { defaultConfig { applicationId namespace - versionName "3.4.0" - versionCode 41 + versionName "3.4.1" + versionCode 42 minSdk 24 targetSdk 34 diff --git a/fastlane/metadata/android/en-US/changelogs/42.txt b/fastlane/metadata/android/en-US/changelogs/42.txt new file mode 100644 index 000000000..dcea6e4e6 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/42.txt @@ -0,0 +1,3 @@ +Auxio 3.4.0 adds gapless playback and new widget designs, alongside a variety of fixes. +This release fixes critical issues with ReplayGain and playback persistence. +For more information, see https://github.com/OxygenCobalt/Auxio/releases/tag/v3.4.1 \ No newline at end of file From 6a76a55060f6ad8bbbea2dab6a68d9823738bd12 Mon Sep 17 00:00:00 2001 From: Alexander Capehart Date: Sat, 24 Feb 2024 14:38:21 -0700 Subject: [PATCH 6/7] music: bump cache db version --- .../main/java/org/oxycblt/auxio/music/cache/CacheDatabase.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/oxycblt/auxio/music/cache/CacheDatabase.kt b/app/src/main/java/org/oxycblt/auxio/music/cache/CacheDatabase.kt index f64345de2..63e4ccf98 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/cache/CacheDatabase.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/cache/CacheDatabase.kt @@ -32,7 +32,7 @@ import org.oxycblt.auxio.music.info.Date import org.oxycblt.auxio.music.metadata.correctWhitespace import org.oxycblt.auxio.music.metadata.splitEscaped -@Database(entities = [CachedSong::class], version = 38, exportSchema = false) +@Database(entities = [CachedSong::class], version = 42, exportSchema = false) abstract class CacheDatabase : RoomDatabase() { abstract fun cachedSongsDao(): CachedSongsDao } From b2a6d40252cab09a172ca831f22effb2e832b023 Mon Sep 17 00:00:00 2001 From: Alexander Capehart Date: Sat, 24 Feb 2024 14:47:55 -0700 Subject: [PATCH 7/7] playback: cleanup --- .../auxio/playback/state/PlaybackStateManager.kt | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt index b4c13cb24..7498c8e0b 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt @@ -418,12 +418,10 @@ class PlaybackStateManagerImpl @Inject constructor() : PlaybackStateManager { } this.stateHolder = stateHolder - if (isInitialized) { - if (currentSong != null) { - stateHolder.applySavedState(stateMirror.parent, stateMirror.rawQueue, null) - stateHolder.seekTo(stateMirror.progression.calculateElapsedPositionMs()) - stateHolder.playing(false) - } + if (isInitialized && currentSong != null) { + stateHolder.applySavedState(stateMirror.parent, stateMirror.rawQueue, null) + stateHolder.seekTo(stateMirror.progression.calculateElapsedPositionMs()) + stateHolder.playing(false) } pendingDeferredPlayback?.let(stateHolder::handleDeferred) }