Skip to content

Commit

Permalink
Revert "Pause audio while in a TAS for cassettes"
Browse files Browse the repository at this point in the history
This reverts commit 4b91f24.
  • Loading branch information
psyGamer committed Mar 19, 2024
1 parent 4b91f24 commit 829c6a8
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 80 deletions.
80 changes: 7 additions & 73 deletions Source/Audio/Audio.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using Celeste64.TAS;
using FMOD.Studio;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;

Expand All @@ -9,7 +9,7 @@ public static class Audio
{
private class Module : Foster.Framework.Module
{
public override void Update()
public override void Update()
=> Audio.Update();

public override void Shutdown()
Expand All @@ -21,9 +21,6 @@ public override void Shutdown()
private static readonly Dictionary<string, FMOD.GUID> events = [];
private static readonly Dictionary<string, FMOD.GUID> buses = [];

private static FMOD.ChannelGroup masterChannelGroup;
internal static FMOD.DSP dsp;

public static void Init()
{
// live upate allows FMOD UI to interact with sounds in-game in real time
Expand Down Expand Up @@ -53,72 +50,9 @@ public static void Init()
// Initialize FMOD
Check(system.initialize(1024, studioFlags, flags, IntPtr.Zero));

var desc = default(FMOD.DSP_DESCRIPTION);
desc.version = 0x00010000;
desc.numinputbuffers = 1;
desc.numoutputbuffers = 1;
desc.read = BlockCallback;

core.getMasterChannelGroup(out masterChannelGroup);
core.createDSP(ref desc, out dsp);
masterChannelGroup.addDSP(0, dsp);
dsp.setBypass(true);

App.Register<Module>();
}

// Theoretical perfect amount of samples per frame
private const int TargetRecordedSamples = 48000 / 60;
// Blocks the FMOD thread.
internal static bool blockEnabled = false;
// The accumulated overhead, since audio chunks contain more data than 1 frame.
private static int totalRecodedSamplesError = 0;
// Actual amount of samples which were blocked
private static int recordedSamples = 0;

private static unsafe FMOD.RESULT BlockCallback(ref FMOD.DSP_STATE dspState, IntPtr inBuffer, IntPtr outBuffer, uint samples, int inChannels, ref int outChannels) {
float* src = (float*) inBuffer;
float* dst = (float*) outBuffer;

if (inChannels == outChannels) {
NativeMemory.Copy(src, dst, (nuint) (inChannels * samples * Marshal.SizeOf<float>()));
} else if (inChannels > outChannels) {
// Cut the remaining channels off
for (int sample = 0; sample < samples; sample++) {
NativeMemory.Copy(src + sample * inChannels, dst + sample * outChannels, (nuint) (outChannels * Marshal.SizeOf<float>()));
}
} else {
// Repeat the last channel to fill the remaining ones
for (int sample = 0; sample < samples; sample++) {
NativeMemory.Copy(src + sample * inChannels, dst + sample * outChannels, (nuint) (inChannels * Marshal.SizeOf<float>()));
for (int channel = inChannels; channel < outChannels; channel++) {
dst![sample * outChannels + channel] = src![sample * inChannels + inChannels - 1];
}
}
}

recordedSamples += (int) samples;

// Skip a frame to let the video catch up again
if (totalRecodedSamplesError >= TargetRecordedSamples) {
totalRecodedSamplesError -= TargetRecordedSamples;
recordedSamples = 0;
return FMOD.RESULT.OK;
}

if (recordedSamples >= TargetRecordedSamples)
blockEnabled = true;

// Block until the TAS allows resuming. (also blocks the main FMOD thread which is good, since it avoid artifacts)
while (blockEnabled && Manager.Running) { }

// Account for overshooting
totalRecodedSamplesError += recordedSamples - TargetRecordedSamples;
recordedSamples = 0;

return FMOD.RESULT.OK;
}

private static bool isResolverSet = false;

private static void LoadDynamicLibraries()
Expand All @@ -127,11 +61,11 @@ private static void LoadDynamicLibraries()
return;
isResolverSet = true;

var path
= Path.GetDirectoryName(AppContext.BaseDirectory)
var path
= Path.GetDirectoryName(AppContext.BaseDirectory)
?? Directory.GetCurrentDirectory();

NativeLibrary.SetDllImportResolver(typeof(FMOD.Studio.System).Assembly,
NativeLibrary.SetDllImportResolver(typeof(FMOD.Studio.System).Assembly,
(name, assembly, dllImportSearchPath) =>
{
name = Path.GetFileNameWithoutExtension(name);
Expand Down Expand Up @@ -276,7 +210,7 @@ private static AudioHandle Create(in EventDescription desc)
Log.Warning($"Failed to create Audio Event Instance: {result}");
return new AudioHandle();
}

return new AudioHandle(instance);
}

Expand Down Expand Up @@ -375,4 +309,4 @@ public static ulong ParameterIDToU64(PARAMETER_ID id)
return ((ulong)id.data1 << 32) | (id.data2);
}

}
}
3 changes: 0 additions & 3 deletions Source/Game.cs
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,6 @@ public override void Update()
return;
}

// Allow for next audio frame
Audio.blockEnabled = false;

// update top scene
if (scenes.TryPeek(out var scene))
{
Expand Down
4 changes: 0 additions & 4 deletions Source/TAS/Manager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ public static void EnableRun()
Controller.RefreshInputs();

TASLevelRecord.ID = string.Empty;

Audio.dsp.setBypass(false);
}

public static void DisableRun()
Expand All @@ -65,8 +63,6 @@ public static void DisableRun()
NextState = State.Disabled;
AttributeUtils.Invoke<DisableRunAttribute>();
Controller.Stop();

Audio.dsp.setBypass(true);
}

public static void Update()
Expand Down

0 comments on commit 829c6a8

Please sign in to comment.