Ident audio to one standard; Paul's sonic identities; quiet and reduced-motion idents
Ported from release-0.108 (0.108.100), with the delivery script and updated sessions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -42,6 +42,12 @@ private val IdentVideos = mapOf(108 to R.raw.ident_108, 109 to R.raw.ident_109,
|
||||
* Every channel's ident has a sound of its own (Paul, 7 November 2026; design/channels/sound), played with Ident sound on, at
|
||||
* most once every 20 minutes a channel, so a run of short programmes doesn't repeat it every few minutes. Tots keeps its jingle.
|
||||
*/
|
||||
/**
|
||||
* Every ident's sound is delivered to one standard (design/channels/sound/deliver.py: -23 LUFS, -2 dBTP, its loudest moment
|
||||
* at most 6 LU above), so normal plays it as delivered, level with programmes; quiet plays it about 8 dB under them.
|
||||
*/
|
||||
internal fun identVolume(quiet: Boolean) = if (quiet) .4f else 1f
|
||||
|
||||
internal object IdentStings {
|
||||
private val last = HashMap<Int, Long>()
|
||||
const val GAP_MS = 20 * 60_000L
|
||||
@@ -113,9 +119,11 @@ internal fun IdentOverlay(session: EmbySampleSession, channel: SampleChannel, ne
|
||||
val fade = remember { Animatable(0f) }
|
||||
LaunchedEffect(Unit) { fade.animateTo(1f, tween(mood?.fadeMs ?: 400)) }
|
||||
Box(Modifier.fillMaxSize().graphicsLayer { alpha = fade.value }.background(NightNavy)) {
|
||||
val video = if (cameo != null) null else block?.video ?: identVideo(channel.number, next.startMs)
|
||||
// Reduce motion: the still card (the logo over the next show's picture) instead of a moving ident, so no sting either
|
||||
// (Paul, 7 November 2026: sensory settings shape the ident, sound included). Tots keeps its still goodbye.
|
||||
val video = if (cameo != null || (settings.reduceMotion && mood == null)) null else block?.video ?: identVideo(channel.number, next.startMs)
|
||||
// With idents off, Tots still says goodbye with a picture that doesn't move.
|
||||
if (mood != null && !settings.idents) Image(cachedPainter(mood.still), null, Modifier.fillMaxSize())
|
||||
if (mood != null && (!settings.idents || settings.reduceMotion)) Image(cachedPainter(mood.still), null, Modifier.fillMaxSize())
|
||||
// Every third Tots changeover, a drawn bumper with the cast instead of the filmed ident.
|
||||
else if (mood != null && !early && block == null && totsBumper(next.startMs)) TotsBumper(mood)
|
||||
else if (video != null && !(early && !settings.idents)) {
|
||||
@@ -131,8 +139,8 @@ internal fun IdentOverlay(session: EmbySampleSession, channel: SampleChannel, ne
|
||||
}
|
||||
seekTo(startedLateMs.coerceIn(0, identMs))
|
||||
volume = if (block != null) (if (settings.blockIdentSound) 1f else 0f)
|
||||
else if (mood != null && settings.identSound && TotsJingle.take(mood, System.currentTimeMillis())) 1f
|
||||
else if (mood == null && settings.identSound && IdentStings.take(channel.number, System.currentTimeMillis())) 1f else 0f
|
||||
else if (mood != null && settings.identSound && !settings.reduceMotion && TotsJingle.take(mood, System.currentTimeMillis())) identVolume(settings.identSoundQuiet)
|
||||
else if (mood == null && settings.identSound && IdentStings.take(channel.number, System.currentTimeMillis())) identVolume(settings.identSoundQuiet) else 0f
|
||||
prepare(); playWhenReady = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,6 +94,10 @@ internal class OrbitSettings(context: Context) {
|
||||
var identSound: Boolean
|
||||
get() = saved.getBoolean("ident_sound", true)
|
||||
set(value) { saved.edit().putBoolean("ident_sound", value).apply() }
|
||||
/** Ident sound played softly, for quiet evenings (Paul, 7 November 2026: separate normal and quiet playback). */
|
||||
var identSoundQuiet: Boolean
|
||||
get() = saved.getBoolean("ident_sound_quiet", false)
|
||||
set(value) { saved.edit().putBoolean("ident_sound_quiet", value).apply() }
|
||||
var driveInIntro: Boolean
|
||||
get() = saved.getBoolean("drive_in_intro", true)
|
||||
set(value) { saved.edit().putBoolean("drive_in_intro", value).apply() }
|
||||
@@ -260,6 +264,7 @@ private fun ViewingDetail(firstSwitch: FocusRequester, modifier: Modifier, top:
|
||||
var channelLogo by remember { mutableStateOf(settings.channelLogo) }
|
||||
var idents by remember { mutableStateOf(settings.idents) }
|
||||
var identSound by remember { mutableStateOf(settings.identSound) }
|
||||
var identSoundQuiet by remember { mutableStateOf(settings.identSoundQuiet) }
|
||||
var driveInIntro by remember { mutableStateOf(settings.driveInIntro) }
|
||||
var reduceMotion by remember { mutableStateOf(settings.reduceMotion) }
|
||||
var squeezeBack by remember { mutableStateOf(settings.squeezeBack) }
|
||||
@@ -284,6 +289,9 @@ private fun ViewingDetail(firstSwitch: FocusRequester, modifier: Modifier, top:
|
||||
SettingLine("Ident sound", "Each channel's ident plays its own short sound, at most every 20 minutes a channel; Tots plays its jingle.") {
|
||||
OnOff(identSound, Modifier, onClick = { identSound = !identSound; settings.identSound = identSound })
|
||||
}
|
||||
SettingLine("Quiet ident sound", "Play the ident sounds softly, well under the programmes. Reduce motion shows idents as a still card, with no sound.") {
|
||||
OnOff(identSoundQuiet, Modifier, enabled = identSound, onClick = { identSoundQuiet = !identSoundQuiet; settings.identSoundQuiet = identSoundQuiet })
|
||||
}
|
||||
SettingLine("Special idents", "Give named blocks and events their own ident as they begin, such as Riot Laughs or PPV Sunday. Off uses each channel's usual ident.") {
|
||||
OnOff(specialIdents, Modifier, onClick = { specialIdents = !specialIdents; settings.specialIdents = specialIdents })
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -31,4 +31,9 @@ class CollectionRefreshTest {
|
||||
assertTrue(IdentStings.take(9001, t)); assertFalse(IdentStings.take(9001, t + 60_000)); assertTrue(IdentStings.take(9002, t + 60_000))
|
||||
assertTrue(IdentStings.take(9001, t + IdentStings.GAP_MS))
|
||||
}
|
||||
|
||||
// One delivery standard for every ident (7 November 2026): normal plays it as delivered, level with programmes; quiet sits under.
|
||||
@Test fun quietIdentSoundSitsWellUnderNormal() {
|
||||
assertEquals(1f, identVolume(false)); assertTrue(identVolume(true) in .3f..(.5f))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user