ボイス・アサイナ (2)

ボイス・アサイナを考える最初の段階として、実現可能性はともかく、プログラムおよびハードウェアのリソース (資源) が制約なく、無限に使える場合について検討してみます。
到着した MIDI ノートオン・メッセージ1個に対応して、1個の音を発音させるのがボイス・アサイナの役目ですから、まずは、可能な MIDI ノートオン・メッセージの総数を数え上げてみます。

  • MIDI チャンネルは 1 〜 16 の 16 種
  • ノート番号は 0 〜 127 の 128 種

ですから、総数は両者の積の 16 × 128 = 2048 通りとなります。
そこで、下の図のように、2048 個のボイス (発音エレメント) を 2 次元配列状に並べれば、無制約資源版のボイス・アサイナの出来上がりです。
正確に言えば、ボイスはすでにアサイン (割り当て) ずみですから、ダイナミック (動的) にアサインすることはなく、単なる「ボイス・アレイ」ということになります。

この「ボイス・アレイ」で行うことといえば、ノートオン/ノートオフ・メッセージ中の MIDI CH と NOTE NO で 2 次元配列上のボイス位置を割り出し、発音エレメントのハードウェアおよびソフトウェアにノートオン/ノートオフ処理を施すだけです。
これで「一件落着」といきたいところですが、ボイスを 2048 個も使っているのにもかかわらず、問題が生じることがあります。
それは、アサイナの問題というよりは、ボイス (発音エレメント) の問題なのですが、「多重ノート」とか、「同音連打」とか呼ばれる、同じチャンネル、同じノート番号のノートオン・メッセージが連続して送られてくる場合です。
まずは、「同音連打」でも問題がない場合の図を下に示します。

上側の赤い線が発音された音のエンベロープを示し、下側の青い線がノートオン/ノートオフ・メッセージをシンセのゲート信号のように示したものです。
「H」レベルが「ゲートオン」、つまり、鍵盤が押された状態、「L」レベルが「ゲートオフ」、つまり、鍵盤が離された状態を示します。
一番下に書いてあるノートオン/ノートオフの末尾の番号、「1,2,3,4」はメッセージの到着する順番を示しているもので、MIDI チャンネルやノート番号ではありません。
上の図の場合には、2番目の音のノートオン・メッセージ (Note_ON3) が来るまでの間に、最初の音の「リリース」が終わって無音になっており、ふたつの音は「独立」と考えられ、両者を同じ発音エレメントで処理しても何の問題もありません。
ノートオン/ノートオフの関係は同一でも、問題が生じる場合を下に示します。

上の場合には、リリース・タイムが長くて、次の音のノートオン時に前の音の発音が終わらず、振動が「残って」いる状態になっています。
図では点線で、前の音のリリースの続きと、後の音のアタック前の状態を示してあります。
ピアノなどの鍵盤楽器では、対応する全音程分の発音機構を保有していますが、ある音程に限れば発音機構は一組だけであり、「同音連打」では、同じ発音機構が振動が減衰し終わらないうちに何回も励起されて、新しい音の「アタック」を作りだすことになります。
ところが、「ソフトウェア/ハードウェア音源」では、この状況をうまく再現できません。
たとえば、PCM 音源では、実際の楽器を「無音」の状態から、発音させたものを「録音」して PCM データとし、音源としては、その録音データを「再生」しているわけですから、実際の「同音連打」の場合の「前の音の振動が残っている状態からの新たなアタック」の音とは一致しません。
無理に出力レベルがゼロでない、アタック途中の位置から PCM テーブルを読み出すようにしても、今度はアタック初期のスペクトラム変化の情報が欠損してしまいます。
FM音源の場合でも、正弦波テーブルの読み出しの「位相」を変調することによって波形を作り出しているわけですから、エンベロープもゼロ、キャリアの位相もゼロ、モジュレータの位相もゼロの状態から発音を始めないと、出てくる音自体が変わってきてしまい、途中の出力レベルから発音を開始することはできません。
この発音エレメントは1個で、前の音を強制的にオフし、次の音を通常通りに発音させる方式を「シングル・アサイン」(single assign) と呼びます。
XG 音源および GS 音源には、後で説明する「マルチ・アサイン」(multi assign) とシングル・アサインのどちらを使うかを、パートごとに選択できるような機能があります。
シングル・アサインの例を下に示します。

この場合では、次の音のノートオンが来ると、前の音の発音を即座に打ち切って、次の音の発音に切り換えていますから、音のエンベロープに図のような鋭い「ディップ」が生じ、聴感上は不自然に感じられることがあります。
その不自然さを軽減する方法として、前の音の発音を即座に打ち切るのではなく、その音色の本来のリリース・タイムとは関係なく、強制的に数 ms で発音をリリースさせて終了させた後に次の音を発音させる方法があります。
この方法では、同音連打の場合だけ、次の音の発音が数 ms 遅れることになってしまいますが、レイテンシーの増加を覚悟すれば、全ての音の発音タイミングを揃えることができます。
それは、普段からすべてのノートオン処理をメッセージ受信から数 ms 遅らせておくのです。
同音連打の前の音の強制ダンプ (damp) 処理だけをメッセージ受信直後から開始すれば、数 ms 後にリリースが終了した時点で通常の処理として次の音のアタックが開始されるので、次の音の発音遅れとはなりません。
次の図は、同音連打の新たなノートオン・メッセージに対し、新たなボイス (発音エレメント) を割り当てる場合で、「マルチ・アサイン」(multi assign) と呼ばれます。

赤で示した前の音にボイスA、緑で示した後の音にボイスBを割り当てます。
ふたつの音それぞれに発音エレメントが割り当てられるので、両者は全く独立で、互いに干渉しません。
このマルチ・アサインの方式では、「同音連打」については、何ら特別な処理をしていないことになります。
新たなノートオンが到着すれば無条件に新たなボイスを割り当てるだけで、それらのノート番号が同一であるかどうかは関与しません。
シングル・アサインでは、到着したノートオン・メッセージと同じノート番号の音がすでに発音中かどうかを調べ、同じであればその (割り当てずみの) ボイスを使って新しい音を発音するという処理が必要になります。
したがって、マルチ・アサイン方式では、ボイスというリソースは多く消費しますが、ボイス・アサイナの処理自体は簡単になります。
この (フル) マルチ・アサイン方式では、前の音が残っている限り、同音連打で新たなボイスが割り当て続けられることになります。
GS 音源では、Limited-Multi アサイン・モードというのが設けられていて、その設定をするエクスクルーシブ・メッセージの説明では、

同じ音を連続して鳴らした場合、前に鳴っている音を新しい音が鳴ってもある程度保持して発音します。

と表記されていますが、「ある程度」というのがどの程度なのかは分かりません。 その程度をコントロールするパラメタもないようです。
この Limited-Multi モードがデフォルトになっていますが、エクスクルーシブでパートごとに Single / Limited-Multi / Full-Multi が切り換えられるようになっています。
最後に、シングル・アサインとマルチ・アサインの中間のような方式を示します。

これは、前の音を強制ダンプするのはシングル・アサインと同じで、次の音に新しいボイスを割り付けるのはマルチ・アサインと同じです。
割り当てられるボイス数は、一時的には増えますが、数 ms 後に前の音の発音が終了すればボイスは解放され、割り当てずみボイス数は元に戻ることになります。
シングル・アサインの場合の次の音の発音遅れ、あるいはレイテンシー増加の欠点はありません。