From 46e0b6c0f1c99cee244e075a613ed9037a1d69ac Mon Sep 17 00:00:00 2001 From: MikiraSora Date: Sat, 26 Oct 2024 11:24:02 +0800 Subject: [PATCH] add EnableSoundMultiPlay --- OngekiFumenEditor/App.config | 3 + OngekiFumenEditor/AppBootstrapper.cs | 4 + .../Kernel/Audio/NAudioImpl/NAudioManager.cs | 61 +++++- .../Audio/NAudioImpl/Sound/CachedSound.cs | 5 - .../CommandExecutor/DefaultCommandExecutor.cs | 4 +- .../Audio/Views/AudioSettingView.xaml | 45 +++-- OngekiFumenEditor/OngekiFumenEditor.csproj | 178 +++++++++--------- .../Properties/AudioSetting.Designer.cs | 12 ++ .../Properties/AudioSetting.settings | 3 + OngekiFumenEditor/Startup.cs | 7 - .../Utils/ConsoleWindowHelper.cs | 43 +++++ OngekiFumenEditor/Utils/Log.cs | 6 +- .../Logs/DefaultImpls/ConsoleLogOutput.cs | 1 + .../DefaultImpls/VisualStudioLogOutput.cs | 11 +- 14 files changed, 248 insertions(+), 135 deletions(-) create mode 100644 OngekiFumenEditor/Utils/ConsoleWindowHelper.cs diff --git a/OngekiFumenEditor/App.config b/OngekiFumenEditor/App.config index 54c99aff..9e648332 100644 --- a/OngekiFumenEditor/App.config +++ b/OngekiFumenEditor/App.config @@ -51,6 +51,9 @@ 1 + + True + diff --git a/OngekiFumenEditor/AppBootstrapper.cs b/OngekiFumenEditor/AppBootstrapper.cs index b36ef9a8..f62180a3 100644 --- a/OngekiFumenEditor/AppBootstrapper.cs +++ b/OngekiFumenEditor/AppBootstrapper.cs @@ -205,6 +205,10 @@ public async void OnStartupForGUI(object sender, StartupEventArgs e) { IsGUIMode = true; +#if DEBUG + ConsoleWindowHelper.SetConsoleWindowVisible(true); +#endif + InitExceptionCatcher(); LogBaseInfos(); InitIPCServer(); diff --git a/OngekiFumenEditor/Kernel/Audio/NAudioImpl/NAudioManager.cs b/OngekiFumenEditor/Kernel/Audio/NAudioImpl/NAudioManager.cs index 4d1f59c5..0e383322 100644 --- a/OngekiFumenEditor/Kernel/Audio/NAudioImpl/NAudioManager.cs +++ b/OngekiFumenEditor/Kernel/Audio/NAudioImpl/NAudioManager.cs @@ -1,4 +1,5 @@ using Caliburn.Micro; +using ControlzEx.Standard; using NAudio.CoreAudioApi; using NAudio.Wave; using NAudio.Wave.SampleProviders; @@ -21,6 +22,7 @@ namespace OngekiFumenEditor.Kernel.Audio.NAudioImpl public class NAudioManager : PropertyChangedBase, IAudioManager { private HashSet> ownAudioPlayerRefs = new(); + private bool enableSoundMultiPlay; private int targetSampleRate; private readonly IWavePlayer audioOutputDevice; @@ -28,6 +30,9 @@ public class NAudioManager : PropertyChangedBase, IAudioManager private readonly MixingSampleProvider soundMixer; private readonly MixingSampleProvider musicMixer; + private readonly Dictionary cs2providerMap = new(); + private readonly Dictionary provider2csMap = new(); + private readonly VolumeSampleProvider soundVolumeWrapper; private readonly VolumeSampleProvider musicVolumeWrapper; @@ -65,10 +70,13 @@ public float MusicVolume public NAudioManager() { - var audioOutputType = (AudioOutputType)Properties.AudioSetting.Default.AudioOutputType; - targetSampleRate = Properties.AudioSetting.Default.AudioSampleRate; + var audioOutputType = (AudioOutputType)AudioSetting.Default.AudioOutputType; + enableSoundMultiPlay = AudioSetting.Default.EnableSoundMultiPlay; + targetSampleRate = AudioSetting.Default.AudioSampleRate; + Log.LogDebug($"targetSampleRate: {targetSampleRate}"); Log.LogDebug($"audioOutputType: {audioOutputType}"); + Log.LogDebug($"enableSoundMultiPlay: {enableSoundMultiPlay}"); try { @@ -96,6 +104,7 @@ public NAudioManager() //setup sound soundMixer = new MixingSampleProvider(format); soundMixer.ReadFully = true; + soundMixer.MixerInputEnded += SoundMixer_MixerInputEnded; soundVolumeWrapper = new VolumeSampleProvider(soundMixer); audioMixer.AddMixerInput(soundVolumeWrapper); SoundVolume = AudioSetting.Default.SoundVolume; @@ -110,8 +119,20 @@ public NAudioManager() Log.LogInfo($"Audio implement will use {GetType()}"); } + private void SoundMixer_MixerInputEnded(object sender, SampleProviderEventArgs e) + { + RemoveSoundMixerInput(e.SampleProvider, false); + } + public void PlaySound(CachedSound sound, float volume, TimeSpan init) { + if (!enableSoundMultiPlay) + { + //stop previous + if (cs2providerMap.TryGetValue(sound, out var prevProvider)) + RemoveSoundMixerInput(prevProvider, true); + } + ISampleProvider provider = new VolumeSampleProvider(new CachedSoundSampleProvider(sound)) { Volume = volume @@ -124,17 +145,36 @@ public void PlaySound(CachedSound sound, float volume, TimeSpan init) }; } - AddSoundMixerInput(provider); + AddSoundMixerInput(provider, sound); } - public void AddSoundMixerInput(ISampleProvider input) + public void AddSoundMixerInput(ISampleProvider input, CachedSound cachedSound) { + if (!enableSoundMultiPlay) + { + cs2providerMap[cachedSound] = input; + provider2csMap[input] = cachedSound; + } + soundMixer.AddMixerInput(input); } - public void RemoveSoundMixerInput(ISampleProvider input) + /// + /// + /// + /// + /// mixer是否需要调用RemoveMixerInput() + public void RemoveSoundMixerInput(ISampleProvider input, bool mixerRemove) { - soundMixer.RemoveMixerInput(input); + if (mixerRemove) + soundMixer.RemoveMixerInput(input); + + if (!enableSoundMultiPlay) + { + if (provider2csMap.TryGetValue(input, out var cachedSound)) + cs2providerMap.Remove(cachedSound); + provider2csMap.Remove(input); + } } public async Task LoadAudioAsync(string filePath) @@ -179,6 +219,11 @@ public void Dispose() public ILoopHandle PlayLoopSound(CachedSound sound, float volume, TimeSpan init) { + if (!enableSoundMultiPlay) + { + + } + ISampleProvider provider = new LoopableProvider(new CachedSoundSampleProvider(sound)); if (init.TotalMilliseconds != 0) @@ -193,7 +238,7 @@ public ILoopHandle PlayLoopSound(CachedSound sound, float volume, TimeSpan init) handle.Volume = volume; //add to mixer - AddSoundMixerInput(handle.Provider); + AddSoundMixerInput(handle.Provider, sound); //Log.LogDebug($"handle hashcode = {handle.GetHashCode()}"); return handle; @@ -205,7 +250,7 @@ public void StopLoopSound(ILoopHandle h) return; //Log.LogDebug($"handle hashcode = {handle.GetHashCode()}"); - RemoveSoundMixerInput(handle.Provider); + RemoveSoundMixerInput(handle.Provider, true); } } } diff --git a/OngekiFumenEditor/Kernel/Audio/NAudioImpl/Sound/CachedSound.cs b/OngekiFumenEditor/Kernel/Audio/NAudioImpl/Sound/CachedSound.cs index 7d6f52ec..d06f2ce9 100644 --- a/OngekiFumenEditor/Kernel/Audio/NAudioImpl/Sound/CachedSound.cs +++ b/OngekiFumenEditor/Kernel/Audio/NAudioImpl/Sound/CachedSound.cs @@ -14,11 +14,6 @@ public class CachedSound public WaveFormat WaveFormat { get; init; } public TimeSpan Duration { get; init; } - private CachedSound() - { - //no way - } - public CachedSound(ISampleProvider copySourceProvider) { AudioData = copySourceProvider.ToArray(); diff --git a/OngekiFumenEditor/Kernel/CommandExecutor/DefaultCommandExecutor.cs b/OngekiFumenEditor/Kernel/CommandExecutor/DefaultCommandExecutor.cs index bd8c0a6b..01d9ed18 100644 --- a/OngekiFumenEditor/Kernel/CommandExecutor/DefaultCommandExecutor.cs +++ b/OngekiFumenEditor/Kernel/CommandExecutor/DefaultCommandExecutor.cs @@ -35,7 +35,9 @@ internal class DefaultCommandExecutor : ICommandExecutor private readonly RootCommand rootCommand; public DefaultCommandExecutor() - { + { + Log.Instance.RemoveOutput(); + rootCommand = new RootCommand("CommandLine for OngekiFumenEditor"); rootCommand.AddCommand(GenerateVerbCommands("svg", Resources.ProgramCommandDescriptionSvg, ProcessSvgCommand)); rootCommand.AddCommand(GenerateVerbCommands("convert", Resources.ProgramCommandConvert, ProcessConvertCommand)); diff --git a/OngekiFumenEditor/Kernel/SettingPages/Audio/Views/AudioSettingView.xaml b/OngekiFumenEditor/Kernel/SettingPages/Audio/Views/AudioSettingView.xaml index 0686a2a5..4d31f8c0 100644 --- a/OngekiFumenEditor/Kernel/SettingPages/Audio/Views/AudioSettingView.xaml +++ b/OngekiFumenEditor/Kernel/SettingPages/Audio/Views/AudioSettingView.xaml @@ -35,25 +35,32 @@ - - - - - - - - - -