SMF変換ツール(Smf2GoFMML)
スタンダードMIDIファイル(SMF)を読み込み、go-fmmlのMML仕様に変換して
.mmlファイルを出力する、独立したコマンドラインツールです。
概要
Smf2GoFMMLは、go-fmmlのコア(FM/PCM合成エンジンやMML再生機能)本体とは別に、
tools/smf2gofmml配下に置かれたスタンドアロンのコマンドラインアプリです。手持ちの
スタンダードMIDIファイル(Format 1を想定)を読み込み、トラックごとのノート・テンポ・トラック名など
を解析して、go-fmmlのMML仕様に沿った.mmlテキストへ変換・出力します。実行にgo-fmmlの
音声エンジン自体(oto/v3等)は不要で、ファイル変換のみを行います。
変換結果はそのまま使える完成品というより、叩き台です。音色ID・ミュート・リバーブセンド・ ループ設定・コンダクターパートなど、SMFから読み取れない情報はデフォルト値で埋められるため、変換後 にMMLファイル構成仕様・MMLコマンド仕様 を参照しながら手動で編集することを前提としています。
ビルド方法
リポジトリのtools/smf2gofmmlディレクトリで、実行ファイルを
cmdサブフォルダへ直接ビルドします(ツールは自分自身の実行ファイルの場所を基準に入出力
フォルダを解決するため、この配置が前提です)。
cd tools/smf2gofmml
go build -o cmd/Smf2GoFMML.exe .
使用方法
ビルドした実行ファイル(cmd/Smf2GoFMML.exe)と同じ階層に、入力用の
smfフォルダと出力用のconvertフォルダ(無ければ自動作成)が置かれます。
# cmd フォルダに移動して実行
cd tools/smf2gofmml/cmd
# ファイル名のみを指定した場合、同階層の smf フォルダから探索する
Smf2GoFMML.exe bgm1.mid # 実体は ./smf/bgm1.mid
# 絶対パスを指定した場合はそのまま読み込む
Smf2GoFMML.exe C:\path\to\bgm1.mid
| 項目 | 内容 |
|---|---|
| 起動引数 | 変換対象のSMFファイルパス。フルパス指定、または実行ファイルと同階層の
smfフォルダ内のファイル名指定のいずれか。 |
| 出力先 | 実行ファイルと同階層のconvertフォルダ(無ければ自動作成)。 |
| 出力ファイル名 | <曲名>.mml。曲名はSMFのシーケンス名/トラック名
メタイベントから取得(Windowsのファイル名として使えない文字は_に置換、取得できない
場合はuntitled)。 |
| エラー時 | コンソールに理由を出力して終了(読み込み失敗、SMF自体が不正、ノートを含む トラックが1つもない、等)。 |
| 警告時 | 変換は継続し、コンソールにwarning:付きで内容を出力(例: パート
上限超過によるトラックスキップ)。 |
トラック名埋め込み文字列(タグ)
各トラックのトラック名(シーケンス/トラック名メタイベント)の先頭に、以下のタグ文字列を付けて おくことで、変換後にどの種類のパートになるかを指定できます。
| タグ | 変換先パート種別 |
|---|---|
[FM] | FM音色パート([partN]) |
[PCM long] | PCM音色パート・longタイプ([pcmPartX]、
partType: long) |
[PCM oneShot] | PCM音色パート・oneShotタイプ([pcmPartX]、
partType: oneShot) |
| タグなし | FM音色パート扱い(デフォルト) |
タグの判定は大文字小文字を区別せず、
[ ]内部の空白([PCM oneShot ]や
[ PCM oneShot ]など)は無視して比較されるため、手入力で多少ゆらいでいても正しく認識
されます。ただし単語自体のスペルは一致させる必要があります(PCM / long /
oneShot)。出力される.mmlの各パート設定・パート本体の直前には、タグを
除いた残りのトラック名がコメント(#)として自動的に書き出されます。
# トラック名の例
[FM]Lead
[PCM long]Strings
[PCM oneShot]Drums
Bass # タグ無し → FM音色パート扱い
データ変換内容
[global]セクション
| 項目 | 変換内容 |
|---|---|
tempo | SMF内で最初に見つかったテンポメタイベントの値(小数点以下切り
捨て)。見つからない場合はデフォルト120。 |
sequenceID | SMF内で最初に見つかったトラック名(シーケンス名)。ダブル
クォーテーションは除去。見つからない場合はuntitled。 |
loop | 常にfalse(固定デフォルト)。 |
volume | 常に100(固定デフォルト)。 |
reverb | 常にfalse(固定デフォルト)。 |
reverbType | 常にnormal(固定デフォルト)。 |
reverbTime | 常に2.0(固定デフォルト)。 |
reverbLevel | 常に100(固定デフォルト)。 |
パート割り当て
- SMFのトラック順に、各パートタグに応じてFM音色パートは1, 2, 3...16、PCM音色パートは A, B, C...Pの順に採番されます(FM用とPCM用のカウンタはそれぞれ独立)。
- ノートデータを1つも含まないトラックはスキップされます(変換対象になりません)。
- 各種別のパート上限(FM16、PCM16)を超えるトラックは、警告を出した上でそのトラックごとスキップ されます(変換全体は中断しません)。
- 各パートの
voiceIDは常に0、muteは常にfalseで出力されます(音色そのものはSMFに含まれないため)。
パート音量・パン
- 各トラックの先頭付近にCC(コントロールチェンジ)7番(ボリューム)が存在する場合、その
値(0-127)がそのままパートの
volumeに設定されます。無ければ100。 - 各トラックの先頭付近にCC10番(パン)が存在する場合、MIDIの0-127段階からgo-fmmlの
-16(左)〜16(右)の32段階へ変換して
panに設定されます。無ければ0(中央)。 - トラック中盤以降のボリューム/パン変化、エクスプレッション、ピッチベンド、ポルタメント等の その他コントロールデータは無視されます(先頭付近の値のみを採用)。
ノート→MMLコマンド変換(FM / PCM long)
- SMFの時間分解能(division)は、go-fmml内部のtick分解能へスケール変換されます。
- 同一発音タイミングの複数ノートはコード(和音、
[ ])としてまとめられます。コード 内で符割(長さ)が異なるノートが含まれる場合は最長の音に統一され、それ以外のノートの長さ情報は 無視されます。 - 各ノート(またはコード)の長さは、次のノートが始まるまでの間隔にもとづき、go-fmmlのMML音符長
トークン(全音符・2分音符・4分音符…32分音符、付点、3連符)へ、最長のトークンから貪欲法で分解され
ます。1トークンで表現しきれない長さはタイ(
&)で複数トークンに分割されます。 32分音符未満の端数は切り捨てられます。 - 実際に音が鳴っている長さ(ノートオン〜ノートオフ)と、次のノートまでの間隔の比率から、スタッ
カート(
Q)が4段階(Q1=25%、Q2=50%、Q3=75%、Q4=100%)に吸着されます。 - 音が鳴っていない区間は休符(
R)として出力されます。 - ベロシティは無視され、常に
V127固定で出力されます。
ノート→MMLコマンド変換(PCM oneShot)
- oneShotトラックは、通常のFM/PCM longとは異なる専用書式に変換されます:使用されている音階
(ピッチ)ごとに、それぞれ独立した
ノート名{ ... }ブロックへ分解され、各ブロックは 時間軸0起点から並行して進行するタイムラインとして書き出されます (PCM(oneShot)パート コマンド参照)。 - 各ブロック内は、そのピッチの発音(
X)と休符(R)の並びとして、発音 タイミングの間隔にもとづき同様にMML音符長トークンへ分解されます。 - 各ピッチの最後のトリガー長は、そのトラック全体の最終発音タイミングに揃えられます(ピッチごと にバラバラの余白を追加しないため、曲全体のループ長がピッチ単位の端数で不必要に延びません)。
注意事項
出力はあくまで下書きです。 音色(
voiceID)、ミュート、ソロ、トランスポーズ、
リバーブセンド、コンダクターパート、ループ設定などSMFに存在しない情報は一切変換されず、固定の
デフォルト値のまま出力されます。実際の楽曲として仕上げるには、出力された.mmlを
MMLファイル構成仕様にもとづいて手動編集し、
FM音色パラメータ仕様 / PCM音色パラメータ仕様
で作成した音色ファイルと組み合わせる必要があります。
- SMPTE形式のタイムディビジョン(フレーム/秒ベース)を使用したSMFファイルはサポートされません。
- 仕様上はFormat 1のSMFを対象としています。他フォーマットのファイルでも構造上読み込める場合が ありますが、動作確認・サポート対象はFormat 1のみです。
- 実行ファイルは自分自身のパスを基準に
smf/convertフォルダを解決する ため、実行ファイルを単体でコピーして別の場所から実行する場合は、同じ階層にこの2フォルダ構成を 用意する必要があります。 - 変換元の曲名にファイル名として使用できない文字(
\ / : * ? " < > |等)が 含まれる場合は、出力ファイル名内でアンダースコア(_)に置換されます。