Skip to content

Commit

Permalink
music: re-add song deduplication
Browse files Browse the repository at this point in the history
  • Loading branch information
OxygenCobalt committed Nov 26, 2024
1 parent 3bf8007 commit 9d9f810
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.toList
import org.oxycblt.auxio.music.Music
import org.oxycblt.auxio.music.stack.Indexer
import org.oxycblt.auxio.music.stack.explore.AudioFile
import org.oxycblt.auxio.music.stack.explore.PlaylistFile
Expand All @@ -42,6 +43,7 @@ import org.oxycblt.auxio.music.stack.interpret.model.MutableLibrary
import org.oxycblt.auxio.music.stack.interpret.model.SongImpl
import org.oxycblt.auxio.music.stack.interpret.prepare.PreSong
import org.oxycblt.auxio.music.stack.interpret.prepare.Preparer
import timber.log.Timber as L

interface Interpreter {
suspend fun interpret(
Expand Down Expand Up @@ -88,8 +90,22 @@ class InterpreterImpl @Inject constructor(private val preparer: Preparer) : Inte
.toList()
val albums = albumLinker.resolve()

val songs = albumLinkedSongs.map { SongImpl(it) }
return LibraryImpl(songs, albums, artists, genres)
val uidMap = mutableMapOf<Music.UID, SongImpl>()
val songs = albumLinkedSongs.mapNotNull {
val uid = it.preSong.computeUid()
val other = uidMap[uid]
if (other == null) {
SongImpl(it)
} else {
L.d("Song @ $uid already exists at ${other.path}, ignoring")
null
}
}
return LibraryImpl(
songs,
albums.onEach { it.finalize() },
artists.onEach { it.finalize() },
genres.onEach { it.finalize() })
}

private data class LinkedSongImpl(private val albumLinkedSong: AlbumLinker.LinkedSong) :
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,23 +43,7 @@ import org.oxycblt.auxio.util.update
class SongImpl(linkedSong: LinkedSong) : Song {
private val preSong = linkedSong.preSong

override val uid =
// Attempt to use a MusicBrainz ID first before falling back to a hashed UID.
preSong.musicBrainzId?.let { Music.UID.musicBrainz(MusicType.SONGS, it) }
?: Music.UID.auxio(MusicType.SONGS) {
// Song UIDs are based on the raw data without parsing so that they remain
// consistent across music setting changes. Parents are not held up to the
// same standard since grouping is already inherently linked to settings.
update(preSong.rawName)
update(preSong.preAlbum.rawName)
update(preSong.date)

update(preSong.track)
update(preSong.disc?.number)

update(preSong.preArtists.map { it.rawName })
update(preSong.preAlbum.preArtists.map { it.rawName })
}
override val uid = preSong.computeUid()
override val name = preSong.name
override val track = preSong.track
override val disc = preSong.disc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ class LibraryImpl(
) : MutableLibrary {
override val playlists = emptySet<Playlist>()

private val songUidMap = songs.associ { it.uid }

override fun findSong(uid: Music.UID): Song? {
TODO("Not yet implemented")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ package org.oxycblt.auxio.music.stack.interpret.prepare
import android.net.Uri
import java.util.UUID
import org.oxycblt.auxio.image.extractor.Cover
import org.oxycblt.auxio.music.Music
import org.oxycblt.auxio.music.MusicType
import org.oxycblt.auxio.music.info.Date
import org.oxycblt.auxio.music.info.Disc
import org.oxycblt.auxio.music.info.Name
Expand All @@ -29,6 +31,7 @@ import org.oxycblt.auxio.music.stack.explore.PlaylistHandle
import org.oxycblt.auxio.music.stack.explore.fs.MimeType
import org.oxycblt.auxio.music.stack.explore.fs.Path
import org.oxycblt.auxio.playback.replaygain.ReplayGainAdjustment
import org.oxycblt.auxio.util.update

data class PreSong(
val musicBrainzId: UUID?,
Expand All @@ -48,7 +51,24 @@ data class PreSong(
val preAlbum: PreAlbum,
val preArtists: List<PreArtist>,
val preGenres: List<PreGenre>
)
) {
fun computeUid() =
musicBrainzId?.let { Music.UID.musicBrainz(MusicType.SONGS, it) }
?: Music.UID.auxio(MusicType.SONGS) {
// Song UIDs are based on the raw data without parsing so that they remain
// consistent across music setting changes. Parents are not held up to the
// same standard since grouping is already inherently linked to settings.
update(rawName)
update(preAlbum.rawName)
update(date)

update(track)
update(disc?.number)

update(preArtists.map { artist -> artist.rawName })
update(preAlbum.preArtists.map { artist -> artist.rawName })
}
}

data class PreAlbum(
val musicBrainzId: UUID?,
Expand Down

0 comments on commit 9d9f810

Please sign in to comment.