Improve loudness normalization curve

This commit is contained in:
vfsfitvnm
2022-10-12 11:57:29 +02:00
parent f726d3e934
commit 12f8b6fbcb

View File

@@ -104,10 +104,11 @@ import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.cancellable import kotlinx.coroutines.flow.cancellable
import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.plus import kotlinx.coroutines.plus
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
class PlayerService : InvincibleService(), Player.Listener, PlaybackStatsListener.Callback, class PlayerService : InvincibleService(), Player.Listener, PlaybackStatsListener.Callback,
@@ -398,16 +399,20 @@ class PlayerService : InvincibleService(), Player.Listener, PlaybackStatsListene
player.currentMediaItem?.mediaId?.let { songId -> player.currentMediaItem?.mediaId?.let { songId ->
volumeNormalizationJob?.cancel() volumeNormalizationJob?.cancel()
volumeNormalizationJob = coroutineScope.launch(Dispatchers.IO) { volumeNormalizationJob = coroutineScope.launch(Dispatchers.Main) {
Database.loudnessDb(songId).cancellable().distinctUntilChanged() Database
.collect { loudnessDb -> .loudnessDb(songId)
withContext(Dispatchers.Main) { .cancellable()
player.volume = if (loudnessDb != null && loudnessDb > 0) { .distinctUntilChanged()
(1f - (0.01f + loudnessDb / 14)).coerceIn(0.1f, 1f) .filterNotNull()
} else { .flowOn(Dispatchers.IO)
1f .collect { x ->
} val x2 = x * x
} val x3 = x2 * x
val x4 = x2 * x2
player.volume =
0.0000452661f * x4 - 0.0000870966f * x3 - 0.00251095f * x2 - 0.0336928f * x + 0.427456f
} }
} }
} }
@@ -515,13 +520,16 @@ class PlayerService : InvincibleService(), Player.Listener, PlaybackStatsListene
when (key) { when (key) {
persistentQueueKey -> isPersistentQueueEnabled = persistentQueueKey -> isPersistentQueueEnabled =
sharedPreferences.getBoolean(key, isPersistentQueueEnabled) sharedPreferences.getBoolean(key, isPersistentQueueEnabled)
volumeNormalizationKey -> { volumeNormalizationKey -> {
isVolumeNormalizationEnabled = isVolumeNormalizationEnabled =
sharedPreferences.getBoolean(key, isVolumeNormalizationEnabled) sharedPreferences.getBoolean(key, isVolumeNormalizationEnabled)
maybeNormalizeVolume() maybeNormalizeVolume()
} }
isInvincibilityEnabledKey -> isInvincibilityEnabled = isInvincibilityEnabledKey -> isInvincibilityEnabled =
sharedPreferences.getBoolean(key, isInvincibilityEnabled) sharedPreferences.getBoolean(key, isInvincibilityEnabled)
skipSilenceKey -> player.skipSilenceEnabled = sharedPreferences.getBoolean(key, false) skipSilenceKey -> player.skipSilenceEnabled = sharedPreferences.getBoolean(key, false)
isShowingThumbnailInLockscreenKey -> { isShowingThumbnailInLockscreenKey -> {
isShowingThumbnailInLockscreen = sharedPreferences.getBoolean(key, true) isShowingThumbnailInLockscreen = sharedPreferences.getBoolean(key, true)
@@ -661,10 +669,15 @@ class PlayerService : InvincibleService(), Player.Listener, PlaybackStatsListene
} }
if (mediaItem?.mediaMetadata?.extras?.getString("durationText") == null) { if (mediaItem?.mediaMetadata?.extras?.getString("durationText") == null) {
format.approxDurationMs?.div(1000)?.let(DateUtils::formatElapsedTime)?.removePrefix("0")?.let { durationText -> format.approxDurationMs?.div(1000)
mediaItem?.mediaMetadata?.extras?.putString("durationText", durationText) ?.let(DateUtils::formatElapsedTime)?.removePrefix("0")
Database.updateDurationText(videoId, durationText) ?.let { durationText ->
} mediaItem?.mediaMetadata?.extras?.putString(
"durationText",
durationText
)
Database.updateDurationText(videoId, durationText)
}
} }
query { query {
@@ -676,7 +689,8 @@ class PlayerService : InvincibleService(), Player.Listener, PlaybackStatsListene
itag = format.itag, itag = format.itag,
mimeType = format.mimeType, mimeType = format.mimeType,
bitrate = format.bitrate, bitrate = format.bitrate,
loudnessDb = body.playerConfig?.audioConfig?.loudnessDb?.toFloat()?.plus(7), loudnessDb = body.playerConfig?.audioConfig?.loudnessDb?.toFloat()
?.plus(7),
contentLength = format.contentLength, contentLength = format.contentLength,
lastModified = format.lastModified lastModified = format.lastModified
) )
@@ -685,6 +699,7 @@ class PlayerService : InvincibleService(), Player.Listener, PlaybackStatsListene
format.url format.url
} ?: throw PlayableFormatNotFoundException() } ?: throw PlayableFormatNotFoundException()
"UNPLAYABLE" -> throw UnplayableException() "UNPLAYABLE" -> throw UnplayableException()
"LOGIN_REQUIRED" -> throw LoginRequiredException() "LOGIN_REQUIRED" -> throw LoginRequiredException()
else -> throw PlaybackException( else -> throw PlaybackException(