diff --git a/DirectMusic/Native.cs b/DirectMusic/Native.cs
index af534a4..8bbe2ec 100644
--- a/DirectMusic/Native.cs
+++ b/DirectMusic/Native.cs
@@ -40,6 +40,9 @@ internal static class Native
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void DmLogHandler(IntPtr ctx, LogLevel lvl, string message);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ public delegate uint DmRng(IntPtr ctx);
+
private const string DllName = "dmusic";
[DllImport(DllName)]
@@ -100,6 +103,9 @@ public static extern DmResult DmPerformance_playTransition(IntPtr slf, IntPtr sg
[DllImport(DllName)]
public static extern DmResult DmPerformance_renderPcm(IntPtr slf, float[] buf, ulong len, DmRenderOptions opts);
+ [DllImport(DllName)]
+ public static extern void Dm_setRandomNumberGenerator(DmRng rng, IntPtr ctx);
+
public class Structs
{
}
diff --git a/DirectMusic/RandomNumberGenerator.cs b/DirectMusic/RandomNumberGenerator.cs
new file mode 100644
index 0000000..200c313
--- /dev/null
+++ b/DirectMusic/RandomNumberGenerator.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Runtime.InteropServices;
+using DirectMusic.Util;
+
+namespace DirectMusic
+{
+ public class RandomNumberGenerator
+ {
+ private static GCHandle? _handler;
+ private static readonly Native.DmRng NativeHandler = _nativeCallbackHandler;
+
+ ///
+ ///
+ ///
+ public delegate int Callback();
+
+ ///
+ ///
+ ///
+ public static void Set(Callback cb)
+ {
+ var handler = GCHandle.Alloc(cb);
+ Native.Dm_setRandomNumberGenerator(NativeHandler, GCHandle.ToIntPtr(handler));
+
+ _handler?.Free();
+ _handler = handler;
+ }
+
+ [MonoPInvokeCallback]
+ private static uint _nativeCallbackHandler(IntPtr ctx)
+ {
+ var gcHandle = GCHandle.FromIntPtr(ctx);
+ var cb = (Callback)gcHandle.Target;
+ return (uint) (cb() % uint.MaxValue);
+ }
+ }
+}
\ No newline at end of file