newlon/scripts/audio/AudioSequencer.cs
2025-07-11 03:44:06 +05:00

87 lines
2 KiB
C#

using Godot;
using Godot.Collections;
public partial class AudioSequencer : Node
{
private static AudioSequencer instance;
private Dictionary<string, AudioStreamPlayer> channels = [];
private Dictionary<string, bool> channelProcess = [];
private Dictionary<string, ChannelSettings> channelSettings = [];
[Export]
private ChannelSettings standardSettings;
public override void _Ready()
{
instance = this;
}
public static bool IsChannelPlaying(string id)
{
if (instance.channels.ContainsKey(id) == false)
{
instance.InitiateChannel(id);
return false;
}
if (instance.channelSettings[id].restartTreshold == 0)
return false;
if (instance.channelSettings[id].restartTreshold < 0)
return instance.channelProcess[id];
return instance.channelProcess[id] && instance.channels[id].GetPlaybackPosition() < instance.channelSettings[id].restartTreshold / Engine.TimeScale;
}
public static void Play(string id, AudioStream what, ChannelSettings settings = null)
{
if (IsChannelPlaying(id)) return;
if (settings != null) ChangeSettings(id, settings);
instance.PlayAtChannel(id, what);
}
public static void ChangeSettings(string id, ChannelSettings settings)
{
if (instance.channels.ContainsKey(id) == false)
{
instance.InitiateChannel(id, settings);
return;
}
instance.channelSettings[id] = settings;
}
private AudioStreamPlayer InitiateChannel(string id, ChannelSettings settings = null)
{
AudioStreamPlayer player = new();
AddChild(player);
channels.Add(id, player);
channelProcess.Add(id, false);
player.Name = id;
player.MaxPolyphony = 5;
player.Finished += () => { MarkChannel(id, false); };
if (settings != null)
{
channelSettings.Add(id, settings);
}
else
{
channelSettings.Add(id, standardSettings);
}
return player;
}
private void PlayAtChannel(string id, AudioStream what)
{
channels[id].Stream = what;
channels[id].Play();
MarkChannel(id, true);
}
private void MarkChannel(string id, bool how)
{
channelProcess[id] = how;
}
}