音声の入出力設定、とても地味なところですが、土台部分ですね~
前回に引き続き、入出力設定を行っていくんだね!
前回の記事では、プラグインのバスレイアウトとして、コンストラクタでプラグインの音声入力と出力を設定する方法を学びました。今回は、プログラムの中で、DAWからの入力信号がモノラルか、ステレオかなどの情報によって音声の入出力をプラグインが受け入れるかどうか、という部分の構築を進めていきます。
公式のチュートリアルページはこちらの「Configureing the BusesLayout」になります。
こんな人の役に立つかも
・JUCEフレームワークに入門したい人
・VST、AUプラグイン開発の最初の一歩を踏み出したい人
・JUCEのチュートリアルをやっている人
バスレイアウトの構成について
プラグインをDAWに挿していると、DAW側でチャンネルをステレオにしたり、モノラルに切り替えることができます。チュートリアルでは、プラグインは、ホストに常に「翻弄される」という表現がされています。
プラグイン側では、特定のAudioChannelSetの構成のみを受け入れるようにすることができます。
isBusesLayoutSupported()コールバック関数
返り値がbool型のisBusesLayoutSupportedコールバック関数です。falseを返すことで音声入出力が無効になるようです。
Producerで生成したプラグインプロジェクトには、すでに「isBusesLayoutSuportedコールバック関数」がオーバーライドされた状態で生成されています。
今まで作成してきたGainPluginの「PluginProcessor.cpp」には、すでに次のような記載が標準で存在していました。
//Projucerで生成される基本的なisBusesLayoutSupporterコールバック関数
bool GainPluginAudioProcessor::isBusesLayoutSupported (const BusesLayout& layouts) const
{
#if JucePlugin_IsMidiEffect
//①MIDIプラグインを作成する場合は、layoutを利用しません。
juce::ignoreUnused (layouts);
return true;
#else
//②出力がモノラル、ステレオ以外の時はfalseを返します。
if (layouts.getMainOutputChannelSet() != juce::AudioChannelSet::mono()
&& layouts.getMainOutputChannelSet() != juce::AudioChannelSet::stereo())
return false;
#if ! JucePlugin_IsSynth
//③出力と入力が同じレイアウトでないと受け付けません。(入力ステレオ、出力ステレオなど)
if (layouts.getMainOutputChannelSet() != layouts.getMainInputChannelSet())
return false;
#endif
return true;
#endif
}
#ifや#elseは、C言語のプリプロセッサディレクティブなので、あらかじめ「JucePlugin_IsMidiEffect」変数や「JucePlugin_IsSynth」変数を0または1とすることで、基本的な音声入力の設定ができるようになっていました。
実際には、①でMIDIプラグイン(JucePlugin_IsMidiEffectをTrue)として定義した場合は、バスレイアウトを無効として、音声の入出力を扱わないようにしています。
②では、プラグインの出力がモノラルまたはステレオでないとプラグインの音声が有効でないような設定にしています。DAWのレイアウトがモノラルまたはステレオではないとプラグインが利用できないような設定になっています。
③では、JucePluin_IsSynthという変数が0(False)に設定されていると条件文が真(!で反転)で実行されますが、IsSynthとは、音声のエフェクト処理であるというフラグでしょうか?デフォルトではこのフラグが設定されていないようなので、どうなっているのでしょうか??一般的には、入力と出力が同じ構成になると思います。
この処理が実行される場合、入力と出力が同じAudioChannelSetの設定(入力モノラル、出力モノラルなど)でないとプラグインの音声入出力がオフになるようになっています。
手厚いサポート!
isBusesLayoutSupportの帰り値がflaseのときどうなるの?
isusesLayoutSupportがFlaseを返したとき、どうなるのかを検証してみました。
if (layouts.getMainOutputChannelSet() != juce::AudioChannelSet::mono()
)//←「)」を追加しました。
//&& layouts.getMainOutputChannelSet() != juce::AudioChannelSet::stereo())
return false;
先ほどのデフォルトのプログラムの一部である↑のプログラムのように、DAW側のトラックがモノラル信号でないと「isBusesLayoutSupport関数がfalseを返す」ような設定としました。
この状態でDAWにてプラグインを実行したところ、今までのステレオトラックで、プラグインがオンになっていても音声が出力されませんでしたので、音声信号自体がプラグインを通らなくなっているのだと考えられます。
isBusesLayoutSupportのバリエーション
チュートリアルでは、いくつかのisBusesLayoutSupportコールバック関数の設定例が記載されていますので、見ていきたいと思います。
常に受け入れる設定
bool isBusesLayoutSupported (const BusesLayout& layouts) const
{
return true;
}
この場合は常にtureを返しますので、バスレイアウトの変化によって特に何も制限をかけないような設定です。この設定にすることは、あるのでしょうか・・・
入力と出力への条件
次に、入力信号と出力信号を同様のAudioChannelSetにする設定です。一般的には入力がステレオなら出力もステレオというような設定になります。次のような条件を設定することで、そのようなチェックをしています。
bool isBusesLayoutSupported (const BusesLayout& layouts) const
{
return layouts.getMainInputChannelSet() == layouts.getMainOutputChannelSet();
}
バスが無効になっている場合のチェック
バスが無効になっている、という場合の「disabled」という状態があるとのことです。このような場合も入力または、出力のAudioChannelSetが無効でないことをチェックしておきます。
bool isBusesLayoutSupported (const BusesLayout& layouts) const
{
if (layouts.getMainInputChannelSet() == juce::AudioChannelSet::disabled()
|| layouts.getMainOutputChannelSet() == juce::AudioChannelSet::disabled())
return false;
//先の例と同様に入力と出力のAudioChannnelSetが同一であるかを判定します。
return layouts.getMainInputChannelSet() == layouts.getMainOutputChannelSet();
}
プラグインの音声入出力の判定完成形
Projucerで生成したものとは少し異なりますが、次のような判定式で、プラグインの音声入出力を判定するのが現実的なものとなりそうです。
※オーディオに対するプラグインを作成したい場合。
bool isBusesLayoutSupported (const BusesLayout& layouts) const
{
//入力または、出力のAudioChannelSetが無効ではないことを確認しています。
if (layouts.getMainInputChannelSet() == juce::AudioChannelSet::disabled()
|| layouts.getMainOutputChannelSet() == juce::AudioChannelSet::disabled())
return false;
//出力がモノラルかステレオであることのチェックを行っています。
if (layouts.getMainOutputChannelSet() != juce::AudioChannelSet::mono()
&& layouts.getMainOutputChannelSet() != juce::AudioChannelSet::stereo())
return false;
//returnの判定式として、入力と出力が同じAudioChannelSetであるかどうかをチェックしています。
return layouts.getMainInputChannelSet() == layouts.getMainOutputChannelSet();
}
ということで、ゲインプラグインのisBusesLayoutSupportedの中身を↑のプログラムと変更しておきました。
現状での結論
isBusesLayoutSupportedの内容をまとめました。
MIDIプラグインを作成する場合
bool isBusesLayoutSupported (const BusesLayout& layouts) const
{
juce::ignoreUnused (layouts);
return true;
}
音声はすべて無効にすることにします。
オーディオプラグインを作成する場合
先ほど完成したチュートリアルでの条件をもとに、入出力を設定します。
bool isBusesLayoutSupported (const BusesLayout& layouts) const
{
//入力または、出力のAudioChannelSetが無効ではないことを確認しています。
if (layouts.getMainInputChannelSet() == juce::AudioChannelSet::disabled()
|| layouts.getMainOutputChannelSet() == juce::AudioChannelSet::disabled())
return false;
//出力がモノラルかステレオであることのチェックを行っています。
if (layouts.getMainOutputChannelSet() != juce::AudioChannelSet::mono()
&& layouts.getMainOutputChannelSet() != juce::AudioChannelSet::stereo())
return false;
//returnの判定式として、入力と出力が同じAudioChannelSetであるかどうかをチェックしています。
return layouts.getMainInputChannelSet() == layouts.getMainOutputChannelSet();
}