チュートリアルMPEゾーンの理解
MPE規格で定義されているゾーンの概念とゾーンレイアウトの規約を学びます。MPEシンセサイザーをMPE対応機器に接続します。
レベル:中級
プラットフォーム:Windows, macOS, Linux
クラス: MPEZoneLayoutMPEZoneLayout::Zone、MPEMessages,MPESynthesiser
スタート
このチュートリアルのデモ・プロジェクトのダウンロードはこちらから:PIP|ZIP.プロジェクトを解凍し、最初のヘッダーファイルをProjucerで開く。
このステップにヘルプが必要な場合は、以下を参照してください。Tutorial: Projucer Part 1: Getting started with the Projucer.
を読むと役に立つだろう。Tutorial: Build a multi-polyphonic synthesiserこれは多くの場所で基準点として使われているからだ。
デモ・プロジェクト
デモ・プロジェクトはMPEDemo
のプロジェクトである。JUCE/examples
ディレクトリにある簡略化されたバージョンをベースにしている。Tutorial: Build a multi-polyphonic synthesiser.このチュートリアルを最大限に活用するためには、以下のものが必要です。MPE互換性のあるコントローラー。MPEを表す。MIDIポリフォニック・エクスプレッションオーディオ製品間で多次元データの通信を可能にする仕様。
そのような例をいくつか挙げよう。MPE互換性のある機器は、ROLIのSeaboardシリーズ(例えば、以下のようなもの)である。Seaboard RISEやBLOCKSレンジ(例えばLightpad Block).
を持っている。Lightpad Blockあなたのコンピューターに接続されたデモ・アプリケーションのウィンドウは、以下のスクリーンショットのようになっているはずです:
MIDI入力の一つを有効にする必要があります。Lightpad Blockはオプションとして表示される)。
で演奏されたすべての音符は、その音符に対応する。MPEで説明したように、対応デバイスはウィンドウの下部に表示されます。Tutorial: Build a multi-polyphonic synthesiserチュートリアル
MPE仕様
入門チュートリアルではTutorial: Build a multi-polyphonic synthesiserこのチュートリアルでは、レガシーモードを使用して標準のMPE設定プロセスをバイパスすることで、MPE互換のシンセサイザーを簡単に実装することができます。このチュートリアルでは、最新のMPE標準に記載されている手順に従ってシンセサイザーを構成してみよう。
シンセサイザが MPE モードで動作しているかどうかを判断するためには、MPE ゾーンの概念が必要である。MPE コンフィギュレーション・メッセージ(MCM)を使用して少なくとも1つのゾーンが定義されていれば、MPE モードである。そうでない場合、ゾーンが定義されていなければMPEモードはオフです。では、ゾーンとは何でしょうか?
MPEゾーン
ゾーンの概念はMPE固有の用語で、1つのマスター・チャンネルと1つ以上のメンバー・チャンネルからなる連続したMIDIチャンネルのグループを表す。
マスター・チャンネルはゾーン全体に適用されるメッセージを受信するのに対し、メンバー・チャンネルは個別に適用されるメッセージのみを受信する。
MPEでは、最大2つのゾーンを持つことができ、それらはロワーゾーンとアッパーゾーンとして定義される。
- 下部ゾーン:チャンネル1をマスター・チャンネルとし、チャンネル2から順に1つ以上のメンバー・チャンネルを割り当てる。
- アッパーゾーン:チャンネル16をマスター・チャンネルとし、チャンネル15から順に1つ以上のメンバー・チャンネルを割り当てる。
メンバー・チャンネルは一度に一つのゾーンにしか所属できず、最新のMCMが以前のものより優先される。
例として、Lower Zoneにチャンネル2から10を、Upper Zoneにチャンネル11から15を設定することができる。
また、「下部ゾーン」または「上部ゾーン」のいずれかを使用して、単一のゾーンに制限することもできる。ただし、デフォルトでは「下部ゾーン」を使用することを推奨する。単一ゾーンのシナリオでは、未使用のマスター・チャンネルを 他のゾーンのメンバー・チャンネルとして使用できる。
MPEゾーンは、ゾーンのマスター・チャンネルにメンバー・チャンネルのないMCMを送信することでオフにすることができ、したがってMPEモードは、すべてのゾーンが空になるとオフになる。
JUCEでは、ゾーンの実装はMPEZoneLayout::Zone構造体にカプセル化されており、異なるゾーン設定はMPEZoneLayoutクラスである。
ゾーンは、1つのMPEコントローラーを使用して異なる音色特性を提供する便利な手段であり、マスター・チャンネルを使用してチャンネル・グループにまたがるMIDIメッセージの伝搬を容易にします。
MIDIモード
MPEで サポートされているMIDIモードは、主にMIDIモード3と4の2つです。
- MIDIモード3(ポリモード):ポリ・モードでは、1つのMIDIチャンネルに複数のノートを同時に入力できますが、チャンネル・メッセージはそのチャンネルのすべてのアクティブ・ノートに影響します。新しいMIDIノートが作成されると、コントローラーは可能な限り空のチャンネルに割り当てようとします。
- MIDIモード4(モノ・モード):Monoモードでは、1つのMIDIチャンネルは1つの音符しか保持できず、新しいMIDI音符が作成された場合、他のチャンネルが一杯であれば、コントローラーは既存のアクティブな音符を上書きします。
MPEはMIDIモード3(ポリ・モード)で正しく動作するように設計されていますが、MIDIモード4(モノ・モード)でも使用できます。
ノート・レベルとゾーン・レベルのメッセージ
MIDIメッセージがマスター・チャンネルとメンバー・チャンネルのどちらに送信されるかに応じて、それぞれゾーン・レベル・メッセージまたはノート・レベル・メッセージと呼ぶことにします。ゾーン内のマスター・チャンネルとメンバー・チャンネルの両方に送信されるメッセージもあります。このような場合、受信側のシンセサイザーは両方の情報を適切な方法で組み合わ せなければなりません。
ゾーン・レベルとして送信しなければならないメッセージは以下の通り:
- CC#1、#33:支配権の変更変調.このCCはノート・レベルでも送信できるが、無視される。
- CC7位、39位:支配権の変更ボリューム.このCCはノート・レベルでも送信できるが、無視される。
- CC64号:某企業の支配権変更ダンパーペダル.このCCはノート・レベルでも送信できるが、無視される。
- CC #120:すべてのサウンドをオフにするコントロール・チェンジ。このCCはノート・レベルでも送信できるが、無視される。
- CC127号:すべてのコントローラーをリセットするコントロールチェンジ。このCCはゾーンレベルでしか送信できない。
- ポリフォニック・キー・プレッシャー:PKPは、マスター・チャネルで送信されるMPE仕様の将来の拡張である。
- MPEコンフィギュレーション(MCM):MCMはマスター・チャンネルで送信され、前述のように設定される。
ゾーン・レベルおよびノート・レベルとして送信できるメッセージは以下の通り:
- ピッチベンド:最初の次元のコントロール変更グライド.ピッチベンドの情報は、両方のメッセージレベルで受信された場合、組み合わされなければならない。
- チャンネル圧力:二次元のコントロール変更プレス.チャンネル圧力の情報は、両方のメッセージレベルで受信された場合、組み合わされなければならない。
- スタンプ(CC74号):と呼ばれる3次元のコントロー ル変更。スライド.スタンプの情報は、両方のメッセージレベルで受信された場合、組み合わされなければならない。
- ピッチベンド感度:ノート・レベルとして使用する場合、すべてのメンバー・チャンネルに送られるピッチベンドの強弱を変更するためのコントロール・チェンジ。
- プログラム変更/銀行選択:プログラム・チェンジはマスター・チャンネルで送信されますが、MIDIモード4ではメンバー・チャンネルで送信されます。
通常、ノート・レベルとして送信されるメッセージは以下の通り:
- ノート・オン/オフ:注そしてノートオフメッセージは適切なメンバー・チャネルで送信されるべきであるが、後方互換性のためにマスター・チャネルで許可されている。
- MIDIモード(CC#126、#127):MIDIモード3と4を切り替えるためのコントロール・チェンジは、最下位のメンバー・チャンネルに送られます。
これらのメッセージレベルは、シンセサイザー内のゾーンを定義する際の設計上の決定に影響を与えるので、覚えておくことが重要です。
ゾーンの設定
で実装されているようなレガシー・モードがない場合Tutorial: Build a multi-polyphonic synthesiser少なくとも1つのゾーンを設定するまで、シンセは音を出力しません。
の中でMPESetupComponent
クラスに、ゾー ンの作成と削除を可能にするラムダ関数を使用した3つのボタン・コールバックを追加します。下部と上部のゾーンを作成するか、ゾーン・レイアウトのすべてのゾーンを消去します。
MPESetupComponent()
{
addAndMakeVisible (isLowerZoneButton);
isLowerZoneButton.setToggleState (true, juce::NotificationType::dontSendNotification);
addAndMakeVisible (setZoneButton);
setZoneButton.onClick = [this] { setZoneButtonClicked(); };
addAndMakeVisible (clearAllZonesButton);
clearAllZonesButton.onClick = [this] { clearAllZonesButtonClicked(); };
ユーザーがゾーンの設定を決定するとsetZoneButtonClicked()
関数が呼び出される:
void setZoneButtonClicked()
{
auto isLowerZone = isLowerZoneButton.getToggleState();
auto numMemberChannels = memberChannels.getText().getIntValue();
auto perNotePb = notePitchbendRange.getText().getIntValue();
auto masterPb = masterPitchbendRange.getText().getIntValue();
if (isLowerZone)
zoneLayout.setLowerZone (numMemberChannels, perNotePb, masterPb);
else
zoneLayout.setUpperZone (numMemberChannels, perNotePb, masterPb);
listeners.call ([&] (Listener& l) { l.zoneChanged (isLowerZone, numMemberChannels, perNotePb, masterPb); });
}
まず新しいローカル変数を作成し、ロワー/アッパー・ゾーンの選択、メンバー・チャンネルの数、ゾーン・レベルのピッチベンド、ノート・レベルのピッチベンドを格納する。次にMPEZoneLayoutオブジェクトに対応するsetLowerZone()
またはsetUpperZone()
関数である。
ゾーンをクリアする際のコールバックを処理するには、単純にclearAllZones()
関数を使用する。MPEZoneLayoutオブジェクトは以下のようにすべてのゾーンを削除する:
void clearAllZonesButtonClicked()
{
zoneLayout.clearAllZones();
listeners.call ([] (Listener& l) { l.allZonesCleared(); });
}
シンクの設定
以来MPESetupComponent
クラスはブロードキャスターとして機能するので、リスナーとしてMainComponent
クラスは、ゾーンレイアウトが変更されたときにコールバックを受け取れるようにする。
class MainComponent : public juce::Component,
private juce::AudioIODeviceCallback,
private juce::MidiInputCallback,
private MPESetupComponent::Listener
{
public:
そして、対応する関数をオーバーライドして、それに応じてシンセサイザーを設定することができる。
の中でzoneChanged()
コールバックは、新しく作成されたZoneをMPEZoneLayoutメンバ変数[1].を渡すことができます。MPEZoneLayoutオブジェクトをMPESynthesiser電話でsetZoneLayout()
それについて[2]:
void zoneChanged (bool isLowerZone, int numMemberChannels,
int perNotePitchbendRange, int masterPitchbendRange) override
{
auto* midiOutput = audioDeviceManager.getDefaultMidiOutput();
if (midiOutput != nullptr)
{
if (isLowerZone)
midiOutput->sendBlockOfMessagesNow (juce::MPEMessages::setLowerZone (numMemberChannels, perNotePitchbendRange, masterPitchbendRange));
else
midiOutput->sendBlockOfMessagesNow (juce::MPEMessages::setUpperZone (numMemberChannels, perNotePitchbendRange, masterPitchbendRange));
}
if (isLowerZone)
zoneLayout.setLowerZone (numMemberChannels, perNotePitchbendRange, masterPitchbendRange);
else
zoneLayout.setUpperZone (numMemberChannels, perNotePitchbendRange, masterPitchbendRange);
visualiserInstrument.setZoneLayout (zoneLayout);
synth.setZoneLayout (zoneLayout);
colourPicker.setZoneLayout (zoneLayout);
}
の中でallZonesCleared()
のすべてのゾーンを空にします。MPEZoneLayoutメンバ変数[3].同様にMPEZoneLayoutオブジェクトをMPESynthesiser電話でsetZoneLayout()
それについて[4]:
void allZonesCleared() override
{
auto* midiOutput = audioDeviceManager.getDefaultMidiOutput();
if (midiOutput != nullptr)
midiOutput->sendBlockOfMessagesNow (juce::MPEMessages::clearAllZones());
zoneLayout.clearAllZones();
visualiserInstrument.setZoneLayout (zoneLayout);
synth.setZoneLayout (zoneLayout);
colourPicker.setZoneLayout (zoneLayout);
}
の数が増える。MPESynthesiserVoiceオブジェクトが変更されるとnumberOfVoicesChanged()
コールバックは、それぞれreduceNumVoices()
そしてaddVoice()
の関数である。MPESynthesiserオブジェクトがある:
void numberOfVoicesChanged (int numberOfVoices) override
{
if (numberOfVoices < synth.getNumVoices())
synth.reduceNumVoices (numberOfVoices);
else
while (synth.getNumVoices() < numberOfVoices)
synth.addVoice (new MPEDemoSynthVoice());
}
ピッチベンドの割り当て
シンセサイザーを走らせれば、1ゾーンあたりのメンバー・チャンネル数をカスタマイズしながら、ロ ワーゾーンとアッパーゾーンを追加することができる。
ロワーゾーンとアッパーゾーンに異なるピッチベンド感度を割り当ててみて、異なるゾーンのMIDIチャンネルにアサインされたノートのピッチベンドに与える影響に注目してください。
の下位ゾーンと上位ゾーンに異なるサウンドを割り当てます。MPEDemoSynthVoice
クラスで、三角波形とノコギリ波形の間でクロスフェードする。ベルパラメータが必要だ。
この演習のソースコードはMPEZonesTutorial_02.h
ファイルにある。
概要
このチュートリアルでは、MPEゾーンとノートの管理方法について学びました。特に
- Zoneとnextを設定する際の規約を学ぶ。MPEZoneLayout.
- MPEと互換性のある2つのMIDIモードを理解。
- ノート・レベルとゾーン・レベルのメッセージの違いについて調べました。
- ロワーゾーンとアッパーゾーンに異なるピッチベンド感度を割り当てる。