Last active
January 9, 2024 00:30
-
-
Save Feodor0090/7e9f9a1d53aeb5445a5fabce03751af2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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