Skip to content

Instantly share code, notes, and snippets.

@aosoft
Created March 2, 2020 16:43
Show Gist options
  • Save aosoft/3c6461e827aed52057abcb1d2198c43b to your computer and use it in GitHub Desktop.
Save aosoft/3c6461e827aed52057abcb1d2198c43b to your computer and use it in GitHub Desktop.
ストリームからの MML コンパイル、曲ロードの API イメージ
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace ConsoleApp1
{
class Program
{
/// <summary>
/// ストリームから MML を読み込んでストリームにコンパイル結果を書き出す
/// </summary>
static void Compile(Stream sourceMML, Stream dest, Func<string, Stream> appendFileReaderCallback)
{
var compiledBin = Compile(ReadAllBytes(sourceMML), appendFileReaderCallback);
dest.Write(compiledBin, 0, compiledBin.Length);
}
/// <summary>
/// 配列で MML を渡してコンパイル結果を配列で返す
/// </summary>
static byte[] Compile(byte[] sourceMML, Func<string, Stream> appendFileReaderCallback)
{
// MML ヘッダ解析 -> 参照音色ファイル名が確定
var voiceFilename = "voice.dat";
// 音色ファイルを読み込む疑似コード
byte[] voice = null;
using (var s = appendFileReaderCallback?.Invoke(voiceFilename))
{
if (s != null)
{
voice = ReadAllBytes(s);
}
}
byte[] compiled = null;
// コンパイルして結果を返す
return compiled;
}
/// <summary>
/// ストリームから曲データーを読み込む
/// </summary>
static void LoadMub(Stream mub, Func<string, Stream> appendFileReaderCallback)
{
LoadMub(ReadAllBytes(mub), appendFileReaderCallback);
}
/// <summary>
/// 配列から曲データーを読み込む
/// </summary>
static void LoadMub(byte[] mub, Func<string, Stream> appendFileReaderCallback)
{
// 曲データーヘッダ解析 -> 使用 PCM ファイル名が確定
var pcmFileName = "mucompcm.bin";
// PCM ファイルを読み込む疑似コード
byte[] pcm = null;
using (var s = appendFileReaderCallback?.Invoke(pcmFileName))
{
if (s != null)
{
pcm = ReadAllBytes(s);
}
}
// 初期化
}
/// <summary>
/// ストリームから一括でバイナリを読み込む
/// </summary>
static byte[] ReadAllBytes(Stream stream)
{
var buf = new byte[8192];
using (var ms = new MemoryStream())
{
while (true)
{
var r = stream.Read(buf, 0, buf.Length);
if (r < 1)
{
break;
}
ms.Write(buf, 0, r);
}
return ms.ToArray();
}
}
/// <summary>
/// ファイルから MML を読み込んでファイルに書き出し、ファイルから曲データーを読み出す例
/// </summary>
static void SampleFile()
{
var mmlFileName = @"C:\MUCOM\sampl2.muc";
var dir = Path.GetDirectoryName(Path.GetFullPath(mmlFileName));
var mubPath = Path.Combine(dir, Path.Combine(Path.GetFileNameWithoutExtension(mmlFileName), ".mub"));
// 追加ファイルは MML と同一パスから読み込む
Func<string, Stream> appendFileReaderCallback = (filename) =>
{
return new FileStream(Path.Combine(dir, filename), FileMode.Open, FileAccess.Read);
};
// ファイルからコンパイル -> ファイルへ書き出し
using (var source = new FileStream(mmlFileName, FileMode.Open, FileAccess.Read))
using (var dest = new FileStream(mubPath, FileMode.Create, FileAccess.Write))
{
Compile(source, dest, appendFileReaderCallback);
}
// ファイルから読み込み
using (var mub = new FileStream(mubPath, FileMode.Open, FileAccess.Read))
{
LoadMub(mub, appendFileReaderCallback);
}
}
/// <summary>
/// メモリから MML を読み込んでメモリに書き出し、メモリから曲データーを読み出す例
/// </summary>
static void SampleMemory()
{
// 音色、 PCM などはテーブル保持
var appendFiles = new Dictionary<string, byte[]>();
appendFiles.Add("voice.dat", new byte[1024]);
appendFiles.Add("mucompcm.bin", new byte[65536]);
Func<string, Stream> appendFileReaderCallback = (filename) =>
{
if (appendFiles.ContainsKey(filename))
{
// テーブルにあったらストリームで返す
return new MemoryStream(appendFiles[filename], false);
}
return null;
};
// 文字列からコンパイル -> 配列出力
string mml = "";
var mub = Compile(Encoding.GetEncoding("shift_jis").GetBytes(mml), appendFileReaderCallback);
// 配列から読み込み
LoadMub(mub, appendFileReaderCallback);
}
static void Main(string[] args)
{
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment