Skip to content

Instantly share code, notes, and snippets.

@silenciocorner
Created April 8, 2021 11:08
Show Gist options
  • Save silenciocorner/6b872075ad74f48b2de9868d263a74bd to your computer and use it in GitHub Desktop.
Save silenciocorner/6b872075ad74f48b2de9868d263a74bd to your computer and use it in GitHub Desktop.
Script BeatSystem.cs from Alessandro Fama article "Beat and Marker system with FMOD in Unity"
using System;
using System.Runtime.InteropServices;
using UnityEngine;
class BeatSystem : MonoBehaviour
{
[StructLayout(LayoutKind.Sequential)]
class TimelineInfo
{
public int currentMusicBeat = 0;
public FMOD.StringWrapper lastMarker = new FMOD.StringWrapper();
}
TimelineInfo timelineInfo;
GCHandle timelineHandle;
FMOD.Studio.EVENT_CALLBACK beatCallback;
public static int beat;
public static string marker;
public void AssignBeatEvent(FMOD.Studio.EventInstance instance)
{
timelineInfo = new TimelineInfo();
timelineHandle = GCHandle.Alloc(timelineInfo, GCHandleType.Pinned);
beatCallback = new FMOD.Studio.EVENT_CALLBACK(BeatEventCallback);
instance.setUserData(GCHandle.ToIntPtr(timelineHandle));
instance.setCallback(beatCallback, FMOD.Studio.EVENT_CALLBACK_TYPE.TIMELINE_BEAT | FMOD.Studio.EVENT_CALLBACK_TYPE.TIMELINE_MARKER);
}
public void StopAndClear(FMOD.Studio.EventInstance instance)
{
instance.setUserData(IntPtr.Zero);
instance.stop(FMOD.Studio.STOP_MODE.ALLOWFADEOUT);
instance.release();
timelineHandle.Free();
}
[AOT.MonoPInvokeCallback(typeof(FMOD.Studio.EVENT_CALLBACK))]
static FMOD.RESULT BeatEventCallback(FMOD.Studio.EVENT_CALLBACK_TYPE type, FMOD.Studio.EventInstance instance, IntPtr parameterPtr)
{
IntPtr timelineInfoPtr;
FMOD.RESULT result = instance.getUserData(out timelineInfoPtr);
if (result != FMOD.RESULT.OK)
{
Debug.LogError("Timeline Callback error: " + result);
}
else if (timelineInfoPtr != IntPtr.Zero)
{
GCHandle timelineHandle = GCHandle.FromIntPtr(timelineInfoPtr);
TimelineInfo timelineInfo = (TimelineInfo)timelineHandle.Target;
switch (type)
{
case FMOD.Studio.EVENT_CALLBACK_TYPE.TIMELINE_BEAT:
{
var parameter = (FMOD.Studio.TIMELINE_BEAT_PROPERTIES)Marshal.PtrToStructure(parameterPtr, typeof(FMOD.Studio.TIMELINE_BEAT_PROPERTIES));
timelineInfo.currentMusicBeat = parameter.beat;
beat = timelineInfo.currentMusicBeat;
}
break;
case FMOD.Studio.EVENT_CALLBACK_TYPE.TIMELINE_MARKER:
{
var parameter = (FMOD.Studio.TIMELINE_MARKER_PROPERTIES)Marshal.PtrToStructure(parameterPtr, typeof(FMOD.Studio.TIMELINE_MARKER_PROPERTIES));
timelineInfo.lastMarker = parameter.name;
marker = timelineInfo.lastMarker;
}
break;
}
}
return FMOD.RESULT.OK;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment