From f83f2a72ba1f81549aa7d34da38d4393668bdf0b Mon Sep 17 00:00:00 2001 From: ivan tkachenko Date: Sun, 11 Jan 2026 03:17:21 +0200 Subject: [PATCH] Mark AudioClip as nullable --- MuzikaGromche/Exporter.cs | 4 +-- MuzikaGromche/Plugin.cs | 72 ++++++++++++++++++++++++++++++--------- 2 files changed, 58 insertions(+), 18 deletions(-) diff --git a/MuzikaGromche/Exporter.cs b/MuzikaGromche/Exporter.cs index ed28a4c..93e3999 100644 --- a/MuzikaGromche/Exporter.cs +++ b/MuzikaGromche/Exporter.cs @@ -63,8 +63,8 @@ namespace MuzikaGromche ["Beats"] = audioTrack.Beats, ["LoopOffset"] = audioTrack.LoopOffset, ["Ext"] = audioTrack.Ext, - ["FileDurationIntro"] = audioTrack.LoadedIntro.length, - ["FileDurationLoop"] = audioTrack.LoadedLoop.length, + ["FileDurationIntro"] = audioTrack.LoadedIntro?.length ?? 0f, + ["FileDurationLoop"] = audioTrack.LoadedLoop?.length ?? 0f, ["FileNameIntro"] = audioTrack.FileNameIntro, ["FileNameLoop"] = audioTrack.FileNameLoop, ["BeatsOffset"] = audioTrack.BeatsOffset, diff --git a/MuzikaGromche/Plugin.cs b/MuzikaGromche/Plugin.cs index 2a749f9..cb4b5e5 100644 --- a/MuzikaGromche/Plugin.cs +++ b/MuzikaGromche/Plugin.cs @@ -1259,21 +1259,47 @@ namespace MuzikaGromche public float WindUpTimer { get; } // Estimated number of beats per minute. Not used for light show, but might come in handy. - public float Bpm => 60f / (LoadedLoop.length / Beats); + public float Bpm + { + get + { + if (LoadedLoop == null || LoadedLoop.length <= 0f) + { + return 0f; + } + else + { + return 60f / (LoadedLoop.length / Beats); + } + } + } // How many beats the loop segment has. The default strategy is to switch color of lights on each beat. public int Beats { get; } // Number of beats between WindUpTimer and where looped segment starts (not the loop audio). public int LoopOffset { get; } - public float LoopOffsetInSeconds => (float)LoopOffset / (float)Beats * LoadedLoop.length; + public float LoopOffsetInSeconds + { + get + { + if (LoadedLoop == null || LoadedLoop.length <= 0f) + { + return 0f; + } + else + { + return (float)LoopOffset / (float)Beats * LoadedLoop.length; + } + } + } // MPEG is basically mp3, and it can produce gaps at the start. // WAV is OK, but takes a lot of space. Try OGGVORBIS instead. public AudioType AudioType { get; } - public AudioClip LoadedIntro { get; internal set; } - public AudioClip LoadedLoop { get; internal set; } + public AudioClip? LoadedIntro { get; internal set; } + public AudioClip? LoadedLoop { get; internal set; } public string FileNameIntro { get; } public string FileNameLoop { get; } @@ -1290,7 +1316,20 @@ namespace MuzikaGromche public float BeatsOffset { get; } // Offset of beats, in seconds. Bigger offset => colors will change later. - public float BeatsOffsetInSeconds => BeatsOffset / Beats * LoadedLoop.length; + public float BeatsOffsetInSeconds + { + get + { + if (LoadedLoop == null || LoadedLoop.length <= 0f) + { + return 0f; + } + else + { + return BeatsOffset / (float)Beats * LoadedLoop.length; + } + } + } public float FadeOutBeat { get; } public float FadeOutDuration { get; } @@ -1329,8 +1368,8 @@ namespace MuzikaGromche int IAudioTrack.Beats => Track.Beats; int IAudioTrack.LoopOffset => Track.LoopOffset; AudioType IAudioTrack.AudioType => Track.AudioType; - AudioClip IAudioTrack.LoadedIntro { get => Track.LoadedIntro; set => Track.LoadedIntro = value; } - AudioClip IAudioTrack.LoadedLoop { get => Track.LoadedLoop; set => Track.LoadedLoop = value; } + AudioClip? IAudioTrack.LoadedIntro { get => Track.LoadedIntro; set => Track.LoadedIntro = value; } + AudioClip? IAudioTrack.LoadedLoop { get => Track.LoadedLoop; set => Track.LoadedLoop = value; } string IAudioTrack.FileNameIntro => Track.FileNameIntro; string IAudioTrack.FileNameLoop => Track.FileNameLoop; float IAudioTrack.BeatsOffset => Track.BeatsOffset; @@ -1364,8 +1403,8 @@ namespace MuzikaGromche public int LoopOffset { get; init; } = 0; public AudioType AudioType { get; init; } = AudioType.MPEG; - public AudioClip LoadedIntro { get; set; } = null!; - public AudioClip LoadedLoop { get; set; } = null!; + public AudioClip? LoadedIntro { get; set; } = null; + public AudioClip? LoadedLoop { get; set; } = null; private string? FileNameIntroOverride = null; public string FileNameIntro @@ -1442,7 +1481,7 @@ namespace MuzikaGromche void ISelectableTrack.Debug() { - Plugin.Log.LogDebug($"Track \"{Name}\", Intro={LoadedIntro.length:N4}, Loop={LoadedLoop.length:N4}"); + Plugin.Log.LogDebug($"Track \"{Name}\", Intro={LoadedIntro?.length:N4}, Loop={LoadedLoop?.length:N4}"); } } @@ -1472,7 +1511,7 @@ namespace MuzikaGromche Plugin.Log.LogDebug($"Track Group \"{Name}\", Count={Tracks.Length}"); foreach (var (track, index) in Tracks.Select((x, i) => (x, i))) { - Plugin.Log.LogDebug($" Track {index} \"{track.Name}\", Intro={track.LoadedIntro.length:N4}, Loop={track.LoadedLoop.length:N4}"); + Plugin.Log.LogDebug($" Track {index} \"{track.Name}\", Intro={track.LoadedIntro?.length:N4}, Loop={track.LoadedLoop?.length:N4}"); } } } @@ -1839,7 +1878,7 @@ namespace MuzikaGromche float timeSinceStartOfLoop = time - offset; - var adjustedTimeNormalized = timeSinceStartOfLoop / LoopLength; + var adjustedTimeNormalized = (LoopLength <= 0f) ? 0f : timeSinceStartOfLoop / LoopLength; var beat = adjustedTimeNormalized * Beats; @@ -1887,9 +1926,10 @@ namespace MuzikaGromche LyricsRandomPerLoop = LyricsRandom.Next(); } this.track = track; - AudioState = new(track.LoadedIntro.length); - WindUpLoopingState = new(track.WindUpTimer, track.LoadedLoop.length, track.Beats); - LoopLoopingState = new(track.WindUpTimer + track.LoopOffsetInSeconds, track.LoadedLoop.length, track.Beats); + AudioState = new(track.LoadedIntro?.length ?? 0f); + var loadedLoopLength = track.LoadedLoop?.length ?? 0f; + WindUpLoopingState = new(track.WindUpTimer, loadedLoopLength, track.Beats); + LoopLoopingState = new(track.WindUpTimer + track.LoopOffsetInSeconds, loadedLoopLength, track.Beats); } public List Update(AudioSource intro, AudioSource loop) @@ -3074,7 +3114,7 @@ namespace MuzikaGromche var introAudioSource = behaviour.IntroAudioSource; var loopAudioSource = behaviour.LoopAudioSource; - if (behaviour.CurrentTrack == null) + if (behaviour.CurrentTrack == null || behaviour.CurrentTrack.LoadedIntro == null || behaviour.CurrentTrack.LoadedLoop == null) { #if DEBUG Plugin.Log.LogError("CurrentTrack is not set!");