audio

12-10 サウンドフォント


サウンドフォントとは / MIDI音色とは

MIDIにはプログラム・チェンジ(C[n]h)やバンク・セレクト(B[n]h 00 [val])というメッセージがあり、これを受け取ったMIDI楽器はそのチャネルの音色を指定された番号のものに変更します。バンク・セレクトはプログラム・チェンジの前に設定する「音色のバンクナンバー」であり、複数の音色がひとつのプログラムに割り当てられている場合に有用です。

ソフトウェアによってMIDI楽器を実現している場合、音色はデータで表現されます(ハードウェアが専用メモリにロードして処理する場合もありますが、音色がRAM上のデータで表現されることに変わりはありません)。音色はPCMデータで表現できます。音には音色・音量・音程がありますが、原理的には音量も音程も音声の加工によって対応可能です。つまり、PCMデータにプログラムおよびバンクナンバーを関連付けて、指定されたPCMデータをノート命令で再生できるようにすれば、MIDI楽器をソフトウェアで実現できるのです。

これがサウンドフォントという仕組みの、ごく大まかな原理です。サウンドフォントは複数のPCMファイルをパッケージしたものであり、これがGeneral MIDIの想定する音色番号と合致していれば、それはMIDI楽器としてソフトウェアで利用できるものになります。timidity++やfluidsynthはこの仕組みを利用しています。


パラメーターによる波形の切り替え

実際には、サウンドフォントはそこまで単純な仕組みではありません。ピアノのような楽器では、鍵盤の位置(大まかにいえばオクターブ)によって音の出方が大きく異なります。管楽器では、息の吹き込み方で音量が大きく変わり、かつ音の出方も大きく変わります。MIDIメッセージでいえば、ノートのベロシティによって音色が変わるといえるでしょう。

サウンドフォントでは、音色が変化する可能性のある「ジェネレーター」「モジュレーター」に応じて波形を切り替えられるようなゾーニング機構を備えており、状況に応じて最適な音色を選択できるようになっています。(モジュレーターによる波形合成がソフトウェア的に大きな負荷なく行える現代において、どれだけ意味があるものなのかとは思いますが。)


sfz、あるいはサウンドフォント以外の音色バンク構造

サウンドフォントにはいくつか種類がありますが、まず基本形としてsf2形式について説明します。sf2の構造は、大まかには次のようになります。

- サウンドフォント

- プリセット定義
- インストゥルメント
- ゾーン配列
- モジュレーター配列
- ジェネレーター配列
- 種別
- サンプルヘッダー(ID)
- サンプルヘッダー定義(オフセットなど)
- サンプルデータ(単一)

「ジェネレーター」でどのようなパラメーターが考慮されているかは、NAudio(後述)のこのソースコードの列挙値を見ると分かりやすいかと思います。

https://github.com/naudio/NAudio/blob/master/NAudio/FileFormats/SoundFont/GeneratorEnum.cs

sf3はsf2では非圧縮だったサンプルデータを圧縮して格納するものです。

sf2/sf3とは互換性のない形式としてsfzというものがあります。これは類似の発想に基づいているものですが、オープンに仕様が開発されたもので、その後Calkwalkでメンテナンスが行われています。どのようなパラメーターが発音に影響を与えるか等の情報を詳細にまとめたサイトがあります。

http://drealm.info/sfz/plj-sfz.xhtml

wikipediaでは、sfzと類似した形式でNational InstrumentsのKontaktの.nki.nkmなどがデータを保存しているようです。

サウンドフォントとは異なる形式ですが面白いのはサンプリングを使ったトラッカーのようなエディターであるRenoiseが使用しているXRNI形式です。

筆者はsf2形式のファイルからXRNI音色バンクを作成するsf2xrniという軽量ツールを作成して公開したことがあります。Renoise自体あまりユーザーが多くはなさそうなのですが、未だに使われることがたまにあるようです。

https://github.com/atsushieno/sf2xrni


サウンドフォントを扱うライブラリ


  • sf2cute : C++で書かれたサウンドフォントの読み書きと構築ができるAPIです。

  • NAudio : これ自体は主にWindowsしか考慮していないオーディオI/OのAPIを中心とするライブラリですが、この中にSoundfontの読み書きと構築ができるAPIが含まれており、これはクロスプラットフォームで利用可能です。筆者は前述のsf2xrniでこのAPIを利用しています。

  • juicysfplugin - sf2/sf3をそのままinstrumentにするVSTです。JUCEで作られています。