From 4af977657d88bddf1f8dfe30adf74f2a764066f9 Mon Sep 17 00:00:00 2001 From: Alexis Hildebrandt Date: Wed, 13 Jul 2022 08:53:17 +0200 Subject: [PATCH 1/6] Fix width of time tracker when muted --- src/musikcube/app/window/TransportWindow.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/musikcube/app/window/TransportWindow.cpp b/src/musikcube/app/window/TransportWindow.cpp index 1ccd7bfec..c775b1dc8 100755 --- a/src/musikcube/app/window/TransportWindow.cpp +++ b/src/musikcube/app/window/TransportWindow.cpp @@ -774,8 +774,9 @@ void TransportWindow::Update(TimeMode timeMode) { const std::string replayGain = replayGainEnabled ? "rg" : ""; + int const escapedPercentSignWidth = (muted ? 0 : 1); /* 1 for escaped percent sign when not muted */ int const bottomRowControlsWidth = - displayCache.Columns(volume) - (muted ? 0 : 1) + /* -1 for escaped percent sign when not muted */ + displayCache.Columns(volume) - escapedPercentSignWidth + (replayGainEnabled ? (narrow_cast(u8cols(replayGain)) + 4) : 0) + /* [] brackets */ narrow_cast(u8cols(currentTime)) + 1 + /* +1 for space padding */ /* timer track with thumb */ @@ -784,7 +785,8 @@ void TransportWindow::Update(TimeMode timeMode) { int const timerTrackWidth = this->GetContentWidth() - - bottomRowControlsWidth - 1; /* this `- 1` is a hack i don't know why we need it please send help */ + bottomRowControlsWidth - + escapedPercentSignWidth; thumbOffset = 0; From f311ad4de7ee842005a36c63acc34779ec463598 Mon Sep 17 00:00:00 2001 From: casey langen Date: Tue, 19 Jul 2022 19:27:06 -0700 Subject: [PATCH 2/6] Fix xiph album art extraction. --- CHANGELOG.txt | 8 ++++- .../taglib_plugin/TaglibMetadataReader.cpp | 34 +++++++++++-------- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 9504cd268..b6f9f5838 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,4 +1,10 @@ -0.98 +0.98.1 + +* fixed album art extraction for xiph comments. + +-------------------------------------------------------------------------------- + +0.98.0 * added the ability to click the browse and tracklist headers to change filter options diff --git a/src/plugins/taglib_plugin/TaglibMetadataReader.cpp b/src/plugins/taglib_plugin/TaglibMetadataReader.cpp index 1e805bd7e..9c03d00fd 100644 --- a/src/plugins/taglib_plugin/TaglibMetadataReader.cpp +++ b/src/plugins/taglib_plugin/TaglibMetadataReader.cpp @@ -225,6 +225,18 @@ static inline bool replayGainValid(ReplayGain& rg) { rg.trackGain != 1.0 || rg.trackPeak != 1.0; } +static inline void processAlbumArt(TagLib::List pictures, ITagStore* target) { + for (auto picture : pictures) { + if (picture->type() == TagLib::FLAC::Picture::FrontCover) { + auto byteVector = picture->data(); + if (byteVector.size()) { + target->SetThumbnail(byteVector.data(), byteVector.size()); + } + break; + } + } +} + TaglibMetadataReader::TaglibMetadataReader() { } @@ -337,6 +349,7 @@ bool TaglibMetadataReader::ReadGeneric( field list. if we're dealing with a straight-up Xiph tag, process it now */ const auto xiphTag = dynamic_cast(tag); if (xiphTag) { + processAlbumArt(xiphTag->pictureList(), target); this->ReadFromMap(xiphTag->fieldListMap(), target); this->ExtractReplayGain(xiphTag->fieldListMap(), target); } @@ -347,25 +360,16 @@ bool TaglibMetadataReader::ReadGeneric( bool handled = false; /* flac files may have more than one type of tag embedded. see if there's - see if there's a xiph comment burried deep. */ + see if there's a xiph comment buried deep. */ auto flacFile = dynamic_cast(file.file()); if (flacFile) { - auto pictures = flacFile->pictureList(); - for (auto picture : pictures) { - if (picture->type() == TagLib::FLAC::Picture::FrontCover) { - auto byteVector = picture->data(); - if (byteVector.size()) { - target->SetThumbnail(byteVector.data(), byteVector.size()); - } - break; - } + processAlbumArt(flacFile->pictureList(), target); + if (flacFile->hasXiphComment()) { + this->ReadFromMap(flacFile->xiphComment()->fieldListMap(), target); + this->ExtractReplayGain(flacFile->xiphComment()->fieldListMap(), target); + handled = true; } } - if (flacFile && flacFile->hasXiphComment()) { - this->ReadFromMap(flacFile->xiphComment()->fieldListMap(), target); - this->ExtractReplayGain(flacFile->xiphComment()->fieldListMap(), target); - handled = true; - } /* similarly, mp4 buries disc number and album artist. however, taglib does NOT exposed a map with normalized keys, so we have to do special property From 88c0449daeb424f214980e49d8f121c81d036466 Mon Sep 17 00:00:00 2001 From: casey langen Date: Tue, 19 Jul 2022 19:27:26 -0700 Subject: [PATCH 3/6] Version update. --- CMakeLists.txt | 2 +- musikcube.spec | 2 +- src/musikcore/version.h | 6 +++--- src/musikcube/musikcube.rc | Bin 4880 -> 4880 bytes 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f741e366d..ac32f28f6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ cmake_minimum_required(VERSION 3.0) project(musikcube) set (musikcube_VERSION_MAJOR 0) set (musikcube_VERSION_MINOR 98) -set (musikcube_VERSION_PATCH 0) +set (musikcube_VERSION_PATCH 1) set (musikcube_VERSION "${musikcube_VERSION_MAJOR}.${musikcube_VERSION_MINOR}.${musikcube_VERSION_PATCH}") set (LIBRARY_OUTPUT_PATH ${musikcube_SOURCE_DIR}/bin/plugins) set (EXECUTABLE_OUTPUT_PATH ${musikcube_SOURCE_DIR}/bin) diff --git a/musikcube.spec b/musikcube.spec index fe76723ff..89c3da50e 100644 --- a/musikcube.spec +++ b/musikcube.spec @@ -1,6 +1,6 @@ %define name musikcube %define build_timestamp %{lua: print(os.date("%Y%m%d"))} -%define version 0.98.0 +%define version 0.98.1 Name: %{name} Version: %{version} Release: %{dist} diff --git a/src/musikcore/version.h b/src/musikcore/version.h index fc16bb266..a21c170de 100644 --- a/src/musikcore/version.h +++ b/src/musikcore/version.h @@ -38,9 +38,9 @@ #define VERSION_MAJOR 0 #define VERSION_MINOR 98 -#define VERSION_PATCH 0 -#define VERSION_COMMIT_HASH "#6a440c69" -#define VERSION "0.98.0" +#define VERSION_PATCH 1 +#define VERSION_COMMIT_HASH "#f311ad4d" +#define VERSION "0.98.1" namespace musik { namespace cube { diff --git a/src/musikcube/musikcube.rc b/src/musikcube/musikcube.rc index cf417823cced1d953cad89d36373de609b03eb9d..b723b2e440de29ec0c6c8bce8000a7dab76a772e 100644 GIT binary patch delta 56 zcmbQBHbHHJ0T-j;WJ4}PRzn6I27}3Kxx_cuam``^a`k}RMqcgB9=xX*nStEN@43Y{ J>+nBe1^}1e4&VR) delta 56 zcmbQBHbHHJ0T-jeWJ4}PRs#kd27}3Kxx_cuam``^a`k}RMqcgB9=xX*nStEN@43Y{ J>+nBe1^|~{4%`3$ From 7b6db07037ae88a90e169db91e0ce22a938cd6cf Mon Sep 17 00:00:00 2001 From: casey langen Date: Thu, 21 Jul 2022 14:04:20 -0700 Subject: [PATCH 4/6] PulseAudio's output plugin should not include ALSA headers. --- CHANGELOG.txt | 1 + src/plugins/pulseout/pch.h | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index b6f9f5838..d28e7fa92 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,6 +1,7 @@ 0.98.1 * fixed album art extraction for xiph comments. +* fixed PulseAudio compile issue -------------------------------------------------------------------------------- diff --git a/src/plugins/pulseout/pch.h b/src/plugins/pulseout/pch.h index d9a0a4cea..354a6680f 100755 --- a/src/plugins/pulseout/pch.h +++ b/src/plugins/pulseout/pch.h @@ -37,5 +37,3 @@ #include #include - -#include From 5b91e0dd5008482a147f5baaac26cf7841c5c201 Mon Sep 17 00:00:00 2001 From: casey langen Date: Fri, 22 Jul 2022 00:35:37 -0700 Subject: [PATCH 5/6] Dependency updates for Android app. Opus decoding seems more stable now. --- src/3rdparty/bin | 2 +- src/musikdroid/app/build.gradle | 30 +++++++++---------- .../impl/player/GaplessExoPlayerWrapper.kt | 3 -- .../activity/RemoteSettingsActivity.kt | 8 ++--- .../remote/ui/settings/model/Connection.kt | 18 +++++------ src/musikdroid/build.gradle | 8 ++--- .../gradle/wrapper/gradle-wrapper.properties | 2 +- 7 files changed, 33 insertions(+), 38 deletions(-) diff --git a/src/3rdparty/bin b/src/3rdparty/bin index d0c091be6..8b6a9f577 160000 --- a/src/3rdparty/bin +++ b/src/3rdparty/bin @@ -1 +1 @@ -Subproject commit d0c091be64b2c124b2791c7e51916876ef0e1a76 +Subproject commit 8b6a9f577c49864fbfe3c01e6151099bd25c4c4d diff --git a/src/musikdroid/app/build.gradle b/src/musikdroid/app/build.gradle index abdea001a..6a0f0e176 100644 --- a/src/musikdroid/app/build.gradle +++ b/src/musikdroid/app/build.gradle @@ -12,14 +12,14 @@ apply plugin: 'kotlin-kapt' apply plugin: 'com.google.firebase.crashlytics' android { - compileSdkVersion 31 + compileSdkVersion 33 defaultConfig { applicationId "io.casey.musikcube.remote" minSdkVersion 21 - targetSdkVersion 31 + targetSdkVersion 33 versionCode 111 - versionName "0.96.10" + versionName "0.98.1" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } @@ -60,22 +60,22 @@ dependencies { exclude group: 'com.android.support', module: 'support-annotations' }) - implementation 'com.google.firebase:firebase-analytics:20.1.0' - implementation 'com.google.firebase:firebase-core:20.1.0' - implementation 'com.google.firebase:firebase-crashlytics:18.2.9' + implementation 'com.google.firebase:firebase-analytics:21.1.0' + implementation 'com.google.firebase:firebase-core:21.1.0' + implementation 'com.google.firebase:firebase-crashlytics:18.2.11' implementation 'org.slf4j:slf4j-android:1.7.21' implementation "androidx.room:room-runtime:2.4.2" kapt "androidx.room:room-compiler:2.4.2" - implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.4.1" + implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.5.0" implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" - implementation "androidx.lifecycle:lifecycle-common-java8:2.4.1" + implementation "androidx.lifecycle:lifecycle-common-java8:2.5.0" compileOnly 'org.glassfish:javax.annotation:10.0-b28' - implementation 'com.google.dagger:dagger:2.38.1' - kapt 'com.google.dagger:dagger-compiler:2.38.1' + implementation 'com.google.dagger:dagger:2.42' + kapt 'com.google.dagger:dagger-compiler:2.42' implementation 'com.neovisionaries:nv-websocket-client:1.31' implementation 'com.squareup.okhttp3:okhttp:4.9.2' @@ -85,15 +85,15 @@ dependencies { implementation 'io.reactivex.rxjava2:rxjava:2.2.16' implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' implementation 'io.reactivex.rxjava2:rxkotlin:2.4.0' - implementation 'com.google.android.exoplayer:exoplayer:2.17.1' - implementation 'com.google.android.exoplayer:extension-okhttp:2.17.1' + implementation 'com.google.android.exoplayer:exoplayer:2.18.0' + implementation 'com.google.android.exoplayer:extension-okhttp:2.18.0' implementation 'com.simplecityapps:recyclerview-fastscroll:2.0.0' implementation 'me.zhanghai.android.materialprogressbar:library:1.6.1' - implementation 'androidx.appcompat:appcompat:1.4.1' + implementation 'androidx.appcompat:appcompat:1.4.2' implementation 'androidx.recyclerview:recyclerview:1.2.1' - implementation 'com.google.android.material:material:1.6.0-alpha03' - implementation 'androidx.media:media:1.5.0' + implementation 'com.google.android.material:material:1.7.0-alpha03' + implementation 'androidx.media:media:1.6.0' testImplementation 'junit:junit:4.13.1' } diff --git a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/service/playback/impl/player/GaplessExoPlayerWrapper.kt b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/service/playback/impl/player/GaplessExoPlayerWrapper.kt index 9ec454460..12f9b1811 100644 --- a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/service/playback/impl/player/GaplessExoPlayerWrapper.kt +++ b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/service/playback/impl/player/GaplessExoPlayerWrapper.kt @@ -228,9 +228,6 @@ class GaplessExoPlayerWrapper : PlayerWrapper() { } private var eventListener = object : Player.Listener { - override fun onTracksChanged(trackGroups: TrackGroupArray, trackSelections: TrackSelectionArray) { - } - override fun onLoadingChanged(isLoading: Boolean) { } diff --git a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/settings/activity/RemoteSettingsActivity.kt b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/settings/activity/RemoteSettingsActivity.kt index 0bde7b17e..52de5700f 100644 --- a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/settings/activity/RemoteSettingsActivity.kt +++ b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/settings/activity/RemoteSettingsActivity.kt @@ -1,5 +1,6 @@ package io.casey.musikcube.remote.ui.settings.activity +import android.annotation.SuppressLint import android.content.Context import android.content.Intent import android.os.Bundle @@ -80,10 +81,8 @@ class RemoteSettingsActivity: BaseActivity() { return super.onOptionsItemSelected(item) } - override fun onPrepareOptionsMenu(menu: Menu?): Boolean { - menu?.findItem(R.id.action_save)?.isEnabled = - viewModel.state == ViewModelState.Ready - + override fun onPrepareOptionsMenu(menu: Menu): Boolean { + menu.findItem(R.id.action_save)?.isEnabled = viewModel.state == ViewModelState.Ready return super.onPrepareOptionsMenu(menu) } @@ -139,6 +138,7 @@ class RemoteSettingsActivity: BaseActivity() { viewModel.save(replayGainMode, preampGain, transport, driverName, deviceId) } + @SuppressLint("CheckResult") private fun initListeners() { /* metadata */ reindexButton.setOnClickListener { diff --git a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/settings/model/Connection.kt b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/settings/model/Connection.kt index 41f847e78..3d920584e 100644 --- a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/settings/model/Connection.kt +++ b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/settings/model/Connection.kt @@ -32,16 +32,14 @@ class Connection : Parcelable { return name.isNotBlank() && hostname.isNotEmpty() && httpPort > 0 && wssPort > 0 } - override fun writeToParcel(parcel: Parcel?, flags: Int) { - if (parcel != null) { - parcel.writeString(name) - parcel.writeString(hostname) - parcel.writeString(password) - parcel.writeInt(httpPort) - parcel.writeInt(wssPort) - parcel.writeInt(if (ssl) 1 else 0) - parcel.writeInt(if (noValidate) 1 else 0) - } + override fun writeToParcel(parcel: Parcel, flags: Int) { + parcel.writeString(name) + parcel.writeString(hostname) + parcel.writeString(password) + parcel.writeInt(httpPort) + parcel.writeInt(wssPort) + parcel.writeInt(if (ssl) 1 else 0) + parcel.writeInt(if (noValidate) 1 else 0) } override fun describeContents(): Int { diff --git a/src/musikdroid/build.gradle b/src/musikdroid/build.gradle index b3d19c161..ed573548e 100644 --- a/src/musikdroid/build.gradle +++ b/src/musikdroid/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlin_version = '1.6.10' + ext.kotlin_version = '1.7.10' repositories { google() @@ -7,10 +7,10 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:7.1.2' + classpath 'com.android.tools.build:gradle:7.2.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - classpath 'com.google.gms:google-services:4.3.10' - classpath 'com.google.firebase:firebase-crashlytics-gradle:2.8.1' + classpath 'com.google.gms:google-services:4.3.13' + classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.1' } } diff --git a/src/musikdroid/gradle/wrapper/gradle-wrapper.properties b/src/musikdroid/gradle/wrapper/gradle-wrapper.properties index 19cb50070..b7366fca5 100644 --- a/src/musikdroid/gradle/wrapper/gradle-wrapper.properties +++ b/src/musikdroid/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip From 3f384305e23c4bccc93106c3217337bb4c6b3cf2 Mon Sep 17 00:00:00 2001 From: casey langen Date: Fri, 22 Jul 2022 00:40:04 -0700 Subject: [PATCH 6/6] Fix ExoPlayer deprecations in Android client. --- .../impl/player/GaplessExoPlayerWrapper.kt | 33 ++++++------------- 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/service/playback/impl/player/GaplessExoPlayerWrapper.kt b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/service/playback/impl/player/GaplessExoPlayerWrapper.kt index 12f9b1811..a3d11e29c 100644 --- a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/service/playback/impl/player/GaplessExoPlayerWrapper.kt +++ b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/service/playback/impl/player/GaplessExoPlayerWrapper.kt @@ -9,10 +9,7 @@ import com.google.android.exoplayer2.source.MediaSource import com.google.android.exoplayer2.source.ProgressiveMediaSource import com.google.android.exoplayer2.source.TrackGroupArray import com.google.android.exoplayer2.trackselection.TrackSelectionArray -import com.google.android.exoplayer2.upstream.DataSource -import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter -import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory -import com.google.android.exoplayer2.upstream.DefaultHttpDataSource +import com.google.android.exoplayer2.upstream.* import com.google.android.exoplayer2.util.Util import io.casey.musikcube.remote.Application import io.casey.musikcube.remote.service.playback.PlayerWrapper @@ -37,16 +34,13 @@ class GaplessExoPlayerWrapper : PlayerWrapper() { init { val userAgent = Util.getUserAgent(context, "musikdroid") - val httpFactory: DataSource.Factory = DefaultHttpDataSource.Factory().apply { setUserAgent(userAgent) setConnectTimeoutMs(TIMEOUT) setReadTimeoutMs(TIMEOUT) setAllowCrossProtocolRedirects(true) } - - this.sourceFactory = DefaultDataSourceFactory(context, null, httpFactory) - + this.sourceFactory = DefaultDataSource.Factory(context, httpFactory) this.transcoding = prefs.getInt(Prefs.Key.TRANSCODER_BITRATE_INDEX, 0) != 0 } @@ -144,7 +138,7 @@ class GaplessExoPlayerWrapper : PlayerWrapper() { this.lastPosition = -1 if (gaplessPlayer?.playbackState != Player.STATE_IDLE) { - if (gaplessPlayer?.isCurrentWindowSeekable == true) { + if (gaplessPlayer?.isCurrentMediaItemSeekable == true) { var offset = millis.toLong() val isInitialSeek = initialOffsetMs > 0 && (millis == initialOffsetMs) @@ -228,16 +222,7 @@ class GaplessExoPlayerWrapper : PlayerWrapper() { } private var eventListener = object : Player.Listener { - override fun onLoadingChanged(isLoading: Boolean) { - } - - override fun onSeekProcessed() { - } - - override fun onShuffleModeEnabledChanged(shuffleModeEnabled: Boolean) { - } - - override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) { + override fun onPlaybackStateChanged(playbackState: Int) { Preconditions.throwIfNotOnMainThread() if (playbackState == Player.STATE_BUFFERING) { @@ -290,11 +275,13 @@ class GaplessExoPlayerWrapper : PlayerWrapper() { } } - override fun onPositionDiscontinuity(type: Int) { + override fun onPositionDiscontinuity( + oldPosition: Player.PositionInfo, newPosition: Player.PositionInfo,type: Int) + { /* window index corresponds to the position of the current song in the queue. the current song should always be 0! if it's not, then that means we advanced to the next one... */ - if (gaplessPlayer?.currentWindowIndex ?: 0 != 0) { + if ((gaplessPlayer?.currentMediaItemIndex ?: 0) != 0) { promoteNext() state = State.Finished } @@ -313,7 +300,7 @@ class GaplessExoPlayerWrapper : PlayerWrapper() { private val context: Context by lazy { Application.instance } private var all = mutableListOf() private lateinit var dcms: ConcatenatingMediaSource - private var gaplessPlayer: SimpleExoPlayer? = null + private var gaplessPlayer: ExoPlayer? = null private fun promoteNext() { if (all.size > 0) { @@ -334,7 +321,7 @@ class GaplessExoPlayerWrapper : PlayerWrapper() { all.clear() gaplessPlayer?.stop() gaplessPlayer?.release() - gaplessPlayer = SimpleExoPlayer.Builder(context) + gaplessPlayer = ExoPlayer.Builder(context) .setBandwidthMeter(DefaultBandwidthMeter.Builder(context).build()) .build() dcms = ConcatenatingMediaSource()