From aa355f0d44c8a6fd657c6b9452fa5db43421f6eb Mon Sep 17 00:00:00 2001 From: Dominic Aglialoro Date: Fri, 10 Mar 2023 16:54:20 -0800 Subject: [PATCH] WaveformProcessor --- .../Editor/SequenceEditor.cs | 18 +++---- SRXDCustomVisuals.Plugin/Patches.cs | 45 ++-------------- .../SRXDCustomVisuals.Plugin.csproj | 1 + .../Visuals/VisualsBackgroundManager.cs | 6 +-- .../Visuals/WaveformProcessor.cs | 52 +++++++++++++++++++ 5 files changed, 68 insertions(+), 54 deletions(-) create mode 100644 SRXDCustomVisuals.Plugin/Visuals/WaveformProcessor.cs diff --git a/SRXDCustomVisuals.Plugin/Editor/SequenceEditor.cs b/SRXDCustomVisuals.Plugin/Editor/SequenceEditor.cs index 8052d93..74c0c19 100644 --- a/SRXDCustomVisuals.Plugin/Editor/SequenceEditor.cs +++ b/SRXDCustomVisuals.Plugin/Editor/SequenceEditor.cs @@ -253,9 +253,11 @@ private void ChangeType(int direction) { } } - private void ChangeValue(int direction, bool largeAmount) { + private void ChangeValue(int direction, bool largeAmount, bool smallAmount) { if (largeAmount) - direction *= 16; + direction *= 64; + else if (!smallAmount) + direction *= 8; var selectedIndicesPerColumn = state.SelectedIndicesPerColumn; @@ -938,8 +940,7 @@ private bool CheckInputs() { direction--; if (direction != 0) { - MoveTime( - direction, + MoveTime(direction, Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt), Input.GetKey(KeyCode.F), Input.GetKey(KeyCode.D), @@ -956,8 +957,7 @@ private bool CheckInputs() { direction--; if (direction != 0) { - MoveColumn( - direction, + MoveColumn(direction, Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt), state.Selecting, Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl)); @@ -975,9 +975,9 @@ private bool CheckInputs() { if (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl)) ChangeType(direction); else { - ChangeValue( - direction, - Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt)); + ChangeValue(direction, + Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt), + Input.GetKey(KeyCode.F)); } return true; diff --git a/SRXDCustomVisuals.Plugin/Patches.cs b/SRXDCustomVisuals.Plugin/Patches.cs index a939add..c0162ae 100644 --- a/SRXDCustomVisuals.Plugin/Patches.cs +++ b/SRXDCustomVisuals.Plugin/Patches.cs @@ -15,21 +15,14 @@ namespace SRXDCustomVisuals.Plugin; public class Patches { - private const int WAVEFORM_BUFFER_SIZE = 256; - private const int WAVEFORM_BUFFER_SAMPLES_PER_INDEX = 16; - private const long CHUNK_SIZE = 8192L; - private const float WAVEFORM_APPROACH_RATE = 128f; - private static readonly int SPECTRUM_BANDS_CUSTOM = Shader.PropertyToID("_SpectrumBandsCustom"); - private static readonly int WAVEFORM_CUSTOM = Shader.PropertyToID("_WaveformCustom"); private static VisualsInfoAccessor visualsInfoAccessor = new(); private static VisualsBackgroundManager visualsBackgroundManager = new(); private static TrackVisualsEventPlayback eventPlayback = new(); private static SequenceEditor sequenceEditor; private static NoteEventController noteEventController = new(11); - private static ComputeBuffer waveformBuffer = new(WAVEFORM_BUFFER_SIZE, UnsafeUtility.SizeOf()); - private static float2[] waveformArray = new float2[WAVEFORM_BUFFER_SIZE]; + private static WaveformProcessor waveformProcessor = new(); private static void UpdateComputeBuffers(SpectrumProcessor spectrumProcessor, ComputeBuffer buffer) { var background = visualsBackgroundManager.CurrentBackground; @@ -252,41 +245,9 @@ private static bool SpectrumProcessor_Disable_Prefix(ref bool __result) { [HarmonyPatch(typeof(SpectrumProcessor), nameof(SpectrumProcessor.ProcessFromAudioSource)), HarmonyPostfix] private static void SpectrumProcessor_ProcessFromAudioSource_Postfix(TrackPlaybackHandle audioSources) { var background = visualsBackgroundManager.CurrentBackground; - - if (background == null || !background.UseAudioWaveform) - return; - - const int waveformBufferSamples = WAVEFORM_BUFFER_SIZE * WAVEFORM_BUFFER_SAMPLES_PER_INDEX; - const float scale = 2f / WAVEFORM_BUFFER_SAMPLES_PER_INDEX; - - long sampleAtTime = 2L * (long) (48000 * audioSources.GetCurrentTime()); - long chunkIndex = sampleAtTime / CHUNK_SIZE; - int firstSampleInChunk = (int) (sampleAtTime % CHUNK_SIZE / waveformBufferSamples * waveformBufferSamples); - var chunk = audioSources.OutputStream.GetLoadedFloatsForChunk(chunkIndex); - float interp = 1f - Mathf.Exp(-WAVEFORM_APPROACH_RATE * Time.deltaTime); - - if (sampleAtTime < 0 || chunk.Length == 0) { - for (int i = 0; i < WAVEFORM_BUFFER_SIZE; i++) - waveformArray[i] = float2.zero; - } - else { - for (int i = 0; i < WAVEFORM_BUFFER_SIZE; i++) { - var sum = float2.zero; - int startIndex = firstSampleInChunk + WAVEFORM_BUFFER_SAMPLES_PER_INDEX * i; - int endIndex = firstSampleInChunk + WAVEFORM_BUFFER_SAMPLES_PER_INDEX * (i + 1); - - if (endIndex > chunk.Length) - endIndex = chunk.Length; - - for (int j = startIndex; j < endIndex; j += 2) - sum += new float2(Mathf.Clamp(chunk[j], -1f, 1f), Mathf.Clamp(chunk[j + 1], -1f, 1f)); - - waveformArray[i] += interp * (scale * sum - waveformArray[i]); - } - } - waveformBuffer.SetData(waveformArray); - Shader.SetGlobalBuffer(WAVEFORM_CUSTOM, waveformBuffer); + if (background != null && background.UseAudioWaveform) + waveformProcessor.AnalyzeWaveform(audioSources); } [HarmonyPatch(typeof(SpectrumProcessor), nameof(SpectrumProcessor.CompleteTrackAnalasis)), HarmonyTranspiler] diff --git a/SRXDCustomVisuals.Plugin/SRXDCustomVisuals.Plugin.csproj b/SRXDCustomVisuals.Plugin/SRXDCustomVisuals.Plugin.csproj index f4b2865..6d5400a 100644 --- a/SRXDCustomVisuals.Plugin/SRXDCustomVisuals.Plugin.csproj +++ b/SRXDCustomVisuals.Plugin/SRXDCustomVisuals.Plugin.csproj @@ -134,6 +134,7 @@ + diff --git a/SRXDCustomVisuals.Plugin/Visuals/VisualsBackgroundManager.cs b/SRXDCustomVisuals.Plugin/Visuals/VisualsBackgroundManager.cs index f2c71ff..6f01d48 100644 --- a/SRXDCustomVisuals.Plugin/Visuals/VisualsBackgroundManager.cs +++ b/SRXDCustomVisuals.Plugin/Visuals/VisualsBackgroundManager.cs @@ -29,15 +29,15 @@ public void LoadBackground(string backgroundName) { CurrentBackground.Unload(); CurrentBackground = null; } - - var mainCamera = MainCamera.Instance.GetComponent(); - + if (!backgroundExists) { ResetCameraSettings(); return; } + var mainCamera = MainCamera.Instance.GetComponent(); + if (background.DisableBaseBackground) { mainCamera.clearFlags = CameraClearFlags.SolidColor; mainCamera.backgroundColor = Color.black; diff --git a/SRXDCustomVisuals.Plugin/Visuals/WaveformProcessor.cs b/SRXDCustomVisuals.Plugin/Visuals/WaveformProcessor.cs new file mode 100644 index 0000000..c3bd9ab --- /dev/null +++ b/SRXDCustomVisuals.Plugin/Visuals/WaveformProcessor.cs @@ -0,0 +1,52 @@ +using GameSystems.TrackPlayback; +using Unity.Collections; +using Unity.Collections.LowLevel.Unsafe; +using Unity.Mathematics; +using UnityEngine; + +namespace SRXDCustomVisuals.Plugin; + +public class WaveformProcessor { + private const int BUFFER_SIZE = 256; + private const int SAMPLES_PER_INDEX = 8; + private const int SAMPLE_RATE = 48000; + private const long CHUNK_SIZE = 8192L; + private const float APPROACH_RATE = 42f; + + private static readonly int WAVEFORM_CUSTOM = Shader.PropertyToID("_WaveformCustom"); + + private ComputeBuffer waveformBuffer = new(BUFFER_SIZE, UnsafeUtility.SizeOf()); + private float2[] waveformArray = new float2[BUFFER_SIZE]; + + public void AnalyzeWaveform(TrackPlaybackHandle playbackHandle) { + const int waveformBufferSamples = BUFFER_SIZE * SAMPLES_PER_INDEX; + const float scale = 2f / SAMPLES_PER_INDEX; + + long sampleAtTime = 2L * (long) (SAMPLE_RATE * playbackHandle.GetCurrentTime()); + var chunk = playbackHandle.OutputStream.GetLoadedFloatsForChunk(sampleAtTime / CHUNK_SIZE); + float interp = 1f - Mathf.Exp(-APPROACH_RATE * Time.deltaTime); + + if (sampleAtTime < 0L || chunk.Length == 0) { + for (int i = 0; i < BUFFER_SIZE; i++) + waveformArray[i] = float2.zero; + } + else { + for (int i = 0, startSample = (int) (sampleAtTime % CHUNK_SIZE / waveformBufferSamples * waveformBufferSamples); + i < BUFFER_SIZE; i++, startSample += SAMPLES_PER_INDEX) { + var sum = float2.zero; + int endSample = startSample + SAMPLES_PER_INDEX; + + if (endSample > chunk.Length) + endSample = chunk.Length; + + for (int j = startSample; j < endSample; j += 2) + sum += math.clamp(new float2(chunk[j], chunk[j + 1]), -1f, 1f); + + waveformArray[i] += interp * (scale * sum - waveformArray[i]); + } + } + + waveformBuffer.SetData(waveformArray); + Shader.SetGlobalBuffer(WAVEFORM_CUSTOM, waveformBuffer); + } +} \ No newline at end of file