音量コントロールの処理を行う、GainProcessorを実装していきます。
DSPモジュールを利用して実装するみたいだね。
JUCEプログラミングで、音声処理を数珠繋ぎするプラグインを作成しています。今回は、DSP処理部分のゲイン処理クラスを追加していきます。以前のゲインプラグインとは違い、今回はDSPモジュールを利用してゲインをコントロールするようです。
行っているチュートリアルページは次の「Implementing a gain control」の項目になります。
こんな人の役に立つかも
・JUCEフレームワークに入門したい人
・VST、AUプラグイン開発の最初の一歩を踏み出したい人
・JUCEのチュートリアルをやっている人
ゲインの実装
ゲインは、音量調整を担う音声処理となります。
「PluginProcessor.h」に以下のクラスを追加します。前回記事で作成したOscillatorProcessorクラスのすぐ下に実装しました。
class GainProcessor : public ProcessorBase
{
public:
//...
//処理名を返すgetName関数をオーバーライドします。
const juce::String getName() const override { return "Gain"; }
private:
//dsp::Gainクラスのオブジェクト、gainを定義します。
juce::dsp::Gain<float> gain;
};
以前のゲインプラグインを作成したときは、processBlock関数にて、オーディオバッファを変更することでゲイン値を変化させていましたが、dspのgainクラスを利用して実現していきます。
privateなメンバ変数として「gain」オブジェクトを定義しておきます。
コンストラクタ
コンストラクタで、gainオブジェクトの「setGainDecibels」関数を利用して、-6デシベル音量を減らすようにしています。
GainProcessor()
{
gain.setGainDecibels (-6.0f);
}
デシベルの目安については、以下のサイトがとても参考になります。デシベルの感覚がわからない方は、以下のサイトの表をご参考にされるととてもイメージがしやすいです。
https://macasakr.sakura.ne.jp/decibel.htmlprepareToPlay関数
dspモジュールを利用するときの「prepare」関数を呼び出しています。前回のOscillatorProcessorと同様に、ProcessSpecクラスの「spec」オブジェクトにサンプルレートとオーディオバッファ数などを設定して、prepare関数の引数とします。
void prepareToPlay (double sampleRate, int samplesPerBlock) override
{
juce::dsp::ProcessSpec spec { sampleRate, static_cast<juce::uint32> (samplesPerBlock), 2 };
gain.prepare (spec);
}
processBlock関数
ProcessBlockも、OscillatorProcessorと同様に、オーディオバッファをAudioBlockクラスに格納し、さっらにcontextに格納して、dspモジュールであるgainに渡しています。
void processBlock (juce::AudioSampleBuffer& buffer, juce::MidiBuffer&) override
{
juce::dsp::AudioBlock<float> block (buffer);
juce::dsp::ProcessContextReplacing<float> context (block);
gain.process (context);
}
reset関数
reset関数は、dspモジュールのreset関数を呼び出しておきます。
void reset() override
{
gain.reset();
}
だいたいOscillatorProcessorと同じ流れでくむことができます。しかも処理内容はほぼDSPモジュールの中に定義されているようです。
完成したゲインコントロールクラス
gainというDSPモジュールを利用することで、外からパラメータを操作するようにgainをコントロールすることができるようです。
完成したGainProcessorクラスの全体は次のようになりました。
class GainProcessor : public ProcessorBase
{
public:
GainProcessor()
{
gain.setGainDecibels(-6.0f);
}
void prepareToPlay(double sampleRate, int samplesPerBlock) override
{
juce::dsp::ProcessSpec spec{ sampleRate, static_cast<juce::uint32> (samplesPerBlock), 2 };
gain.prepare(spec);
}
void processBlock(juce::AudioSampleBuffer& buffer, juce::MidiBuffer&) override
{
juce::dsp::AudioBlock<float> block(buffer);
juce::dsp::ProcessContextReplacing<float> context(block);
gain.process(context);
}
void reset() override
{
gain.reset();
}
const juce::String getName() const override { return "Gain"; }
private:
juce::dsp::Gain<float> gain;
};
音声処理をするクラスの基本的な構造は、すべて同じように記述できそう。