Skip to content

Instantly share code, notes, and snippets.

@Feodor0090
Last active January 9, 2024 00:30
Show Gist options
  • Save Feodor0090/7e9f9a1d53aeb5445a5fabce03751af2 to your computer and use it in GitHub Desktop.
Save Feodor0090/7e9f9a1d53aeb5445a5fabce03751af2 to your computer and use it in GitHub Desktop.
using System;
using System.IO;
using System.Reflection;
using ManagedBass;
using ManagedBass.Midi;
using osu.Framework.Audio;
using osu.Framework.Audio.Mixing;
using osu.Framework.Audio.Track;
using osu.Framework.Logging;
public class MMAPIAudioStore : AudioCollectionManager<AdjustableAudioComponent>
{
private readonly AudioMixer mixer;
private int counter;
#region Reflection
private readonly ConstructorInfo constructor;
private readonly FieldInfo handleField;
#endregion
private static int midiFont;
private static bool midiInitialized;
public MMAPIAudioStore(AudioManager manager, AudioMixer mixer)
{
this.mixer = mixer;
constructor = typeof(TrackBass).GetConstructor(BindingFlags.NonPublic | BindingFlags.CreateInstance | BindingFlags.Instance, new[] { typeof(Stream), typeof(string), typeof(bool) })!;
handleField = typeof(TrackBass).GetField("activeStream", BindingFlags.Instance | BindingFlags.NonPublic)!;
if (!midiInitialized)
{
// midi is not initialized yet
int result = Bass.PluginLoad("bassmidi");
if (result == 0)
throw new DllNotFoundException("Failed to load bassmidi plugin.");
midiInitialized = true;
}
if (midiFont == 0)
{
// bank is not loaded yet
midiFont = BassMidi.FontInit("S40v5.1.sf2", FontInitFlags.Unicode);
if (midiFont == 0)
throw new FileNotFoundException("Failed to load SF2 font.");
}
manager.AddItem(this);
}
public Track Get(Memory<sbyte> data, string contentType)
{
if (IsDisposed) throw new ObjectDisposedException($"Cannot use disposed {nameof(MMAPIAudioStore)}.");
counter++;
var stream = new MemoryStream(data.ToArray().ToUnsigned());
var track = (TrackBass)constructor.Invoke(new object[] { stream, $"player {counter}".ToString(), false });
mixer.Add(track);
AddItem(track);
bindMidiBank(track);
return track;
}
private void bindMidiBank(TrackBass track)
{
var trackHandle = (int)handleField.GetValue(track)!;
MidiFont mf = new MidiFont { Handle = midiFont, Preset = -1, Bank = 0 };
var fontSet = BassMidi.StreamSetFonts(trackHandle, new[] { mf }, 1);
if (fontSet == 0)
Logger.Log($"Failed to set font at {track.Name}", LoggingTarget.Runtime, LogLevel.Error);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment