Skip to content

Instantly share code, notes, and snippets.

@otya128
Last active December 21, 2017 15:41
Show Gist options
  • Save otya128/0961c96b1f9035cdd33d7c1f92cb56c9 to your computer and use it in GitHub Desktop.
Save otya128/0961c96b1f9035cdd33d7c1f92cb56c9 to your computer and use it in GitHub Desktop.
MIDI+SF2=>MP3
using System;
using System.Collections.Generic;
using System.Linq;
using Un4seen.Bass.AddOn.Midi;
using Un4seen.Bass;
using static Un4seen.Bass.AddOn.Midi.BassMidi;
using static Un4seen.Bass.Bass;
using NAudio.Lame;
using NAudio.Wave;
public class SoundFont : IDisposable
{
int Handle;
int Bank = 0;
int Preset = -1;
public SoundFont(string file)
{
Handle = BASS_MIDI_FontInit(file);
}
internal BASS_MIDI_FONT Internal
{
get
{
return new BASS_MIDI_FONT(Handle, Preset, Bank);
}
}
#region IDisposable Support
private bool disposedValue = false; // 重複する呼び出しを検出するには
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
// TODO: マネージ状態を破棄します (マネージ オブジェクト)。
}
// TODO: アンマネージ リソース (アンマネージ オブジェクト) を解放し、下のファイナライザーをオーバーライドします。
// TODO: 大きなフィールドを null に設定します。
if (Handle != 0)
BASS_MIDI_FontFree(Handle);
disposedValue = true;
}
}
// TODO: 上の Dispose(bool disposing) にアンマネージ リソースを解放するコードが含まれる場合にのみ、ファイナライザーをオーバーライドします。
~SoundFont()
{
// このコードを変更しないでください。クリーンアップ コードを上の Dispose(bool disposing) に記述します。
Dispose(false);
}
// このコードは、破棄可能なパターンを正しく実装できるように追加されました。
public void Dispose()
{
// このコードを変更しないでください。クリーンアップ コードを上の Dispose(bool disposing) に記述します。
Dispose(true);
// TODO: 上のファイナライザーがオーバーライドされる場合は、次の行のコメントを解除してください。
GC.SuppressFinalize(this);
}
#endregion
}
public class MIDi : IDisposable
{
int HStream;
public MIDi(string file)
{
if (!BASS_Init(-1, 48000, 0, IntPtr.Zero))
{
throw new Exception(BASS_ErrorGetCode().ToString());
}
HStream = BASS_MIDI_StreamCreateFile(file, 0, 0, BASSFlag.BASS_STREAM_DECODE, 0);
if (HStream == 0)
{
throw new Exception(BASS_ErrorGetCode().ToString());
}
}
public void SetSoundFonts(IEnumerable<SoundFont> sfs)
{
var ary = sfs.Select(x => x.Internal).ToArray();
if (!BASS_MIDI_StreamSetFonts(HStream, ary, ary.Length))
{
throw new Exception(BASS_ErrorGetCode().ToString());
}
}
public void WriteMP3(string file)
{
var buffer = new byte[1024 * 1024];
var info = BASS_ChannelGetInfo(HStream);
if (info == null)
{
throw new Exception(BASS_ErrorGetCode().ToString());
}
using (var w = new LameMP3FileWriter(file, new WaveFormat(info.freq, 16, info.chans), 128))
{
while (true)
{
var count = BASS_ChannelGetData(HStream, buffer, buffer.Length);
if (count == -1)
break;
w.Write(buffer, 0, count);
}
}
}
#region IDisposable Support
private bool disposedValue = false; // 重複する呼び出しを検出するには
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
// TODO: マネージ状態を破棄します (マネージ オブジェクト)。
}
// TODO: アンマネージ リソース (アンマネージ オブジェクト) を解放し、下のファイナライザーをオーバーライドします。
// TODO: 大きなフィールドを null に設定します。
if (HStream != 0)
BASS_StreamFree(HStream);
disposedValue = true;
}
}
// TODO: 上の Dispose(bool disposing) にアンマネージ リソースを解放するコードが含まれる場合にのみ、ファイナライザーをオーバーライドします。
~MIDi() {
// このコードを変更しないでください。クリーンアップ コードを上の Dispose(bool disposing) に記述します。
Dispose(false);
}
// このコードは、破棄可能なパターンを正しく実装できるように追加されました。
public void Dispose()
{
// このコードを変更しないでください。クリーンアップ コードを上の Dispose(bool disposing) に記述します。
Dispose(true);
// TODO: 上のファイナライザーがオーバーライドされる場合は、次の行のコメントを解除してください。
GC.SuppressFinalize(this);
}
#endregion
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment