music: fix enqueueing

Fix enqueuing issues encountered during testing.
This commit is contained in:
Alexander Capehart 2023-01-05 11:38:32 -07:00
parent 743220d0aa
commit a10cf1e0c3
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
3 changed files with 27 additions and 13 deletions

View file

@ -242,13 +242,7 @@ class ReplayGainAudioProcessor(private val context: Context) :
} else {
for (i in pos until limit step 2) {
// 16-bit PCM audio, deserialize a little-endian short.
var sample =
inputBuffer
.get(i + 1)
.toInt()
.shl(8)
.or(inputBuffer.get(i).toInt().and(0xFF))
.toShort()
var sample = inputBuffer.getLeShort(i)
// Ensure we clamp the values to the minimum and maximum values possible
// for the encoding. This prevents issues where samples amplified beyond
// 1 << 16 will end up becoming truncated during the conversion to a short,
@ -259,7 +253,7 @@ class ReplayGainAudioProcessor(private val context: Context) :
.coerceAtLeast(Short.MIN_VALUE.toInt())
.coerceAtMost(Short.MAX_VALUE.toInt())
.toShort()
buffer.put(sample.toByte()).put(sample.toInt().shr(8).toByte())
buffer.putLeShort(sample)
}
}
@ -267,6 +261,22 @@ class ReplayGainAudioProcessor(private val context: Context) :
buffer.flip()
}
/**
* Always read a little-endian [Short] from the [ByteBuffer] at the given index.
* @param at The index to read the [Short] from.
*/
private fun ByteBuffer.getLeShort(at: Int) =
get(at + 1).toInt().shl(8).or(get(at).toInt().and(0xFF)).toShort()
/**
* Always write a little-endian [Short] at the end of the [ByteBuffer].
* @param short The [Short] to write.
*/
private fun ByteBuffer.putLeShort(short: Short) {
put(short.toByte())
put(short.toInt().shr(8).toByte())
}
/**
* The resolved ReplayGain adjustment for a file.
* @param track The track adjustment (in dB), or 0 if it is not present.

View file

@ -238,6 +238,8 @@ class PlaybackStateManager private constructor() {
when (queue.playNext(songs)) {
Queue.ChangeResult.MAPPING -> notifyQueueChanged(Queue.ChangeResult.MAPPING)
Queue.ChangeResult.SONG -> {
// Enqueueing actually started a new playback session from all songs.
parent = null
internalPlayer.loadSong(queue.currentSong, true)
notifyNewPlayback()
}
@ -261,6 +263,8 @@ class PlaybackStateManager private constructor() {
when (queue.addToQueue(songs)) {
Queue.ChangeResult.MAPPING -> notifyQueueChanged(Queue.ChangeResult.MAPPING)
Queue.ChangeResult.SONG -> {
// Enqueueing actually started a new playback session from all songs.
parent = null
internalPlayer.loadSong(queue.currentSong, true)
notifyNewPlayback()
}

View file

@ -102,7 +102,7 @@ class Queue {
// Since we are re-shuffling existing songs, we use the previous mapping size
// instead of the total queue size.
shuffledMapping = MutableList(orderedMapping.size) { it }.apply { shuffle() }
shuffledMapping = orderedMapping.shuffled().toMutableList()
shuffledMapping.add(0, shuffledMapping.removeAt(shuffledMapping.indexOf(trueIndex)))
index = 0
} else if (shuffledMapping.isNotEmpty()) {
@ -130,11 +130,11 @@ class Queue {
// Add the new songs in front of the current index in the shuffled mapping and in front
// of the analogous list song in the ordered mapping.
val orderedIndex = orderedMapping.indexOf(shuffledMapping[index])
orderedMapping.addAll(orderedIndex, heapIndices)
shuffledMapping.addAll(index, heapIndices)
orderedMapping.addAll(orderedIndex + 1, heapIndices)
shuffledMapping.addAll(index + 1, heapIndices)
} else {
// Add the new song in front of the current index in the ordered mapping.
orderedMapping.addAll(index, heapIndices)
orderedMapping.addAll(index + 1, heapIndices)
}
return ChangeResult.MAPPING
}
@ -207,7 +207,7 @@ class Queue {
orderedMapping.removeAt(orderedMapping.indexOf(shuffledMapping[at]))
shuffledMapping.removeAt(at)
} else {
// Remove the spe
// Remove the specified index in the shuffled mapping
orderedMapping.removeAt(at)
}