Slopeパラメータって、プルダウンとか、コンボボックスで管理するようなインターフェースが普通な気がしました。
すでにある項目を選択する、というようなものがいいよね〜
ハイパスフィルターのSlopeパラメータをスライダーで制御していましたが、スライダーだとイマイチ使いづらかったので、この部分をコンボボックスで指定できるように変更しました。
LogicのEQでは、上下にドラッグすると、数値が切り替わるようなUIですが、いくつかの項目を選択するというようなものでした。
JUCEにはコンボボックスクラスがありますので、これを利用してみました。AudioProcessorValueTreeStateのパラメータとひもづけるのが初でしたので、その点も動作するか試してみたかったのです。
※-24dbとなっていますが、本当は-18dbの間違いです^^;
AudioProcessorValueTreeState(APVTS)による、汎用的なパラメータの追加につきましては、こちらの記事もご参照ください。
AudioProcessorValueTreeState(APVTS)の設定手順
こんな人の役にたつかも
・AudioProcessorValueTree(APVTS)クラスでコンボボックスのパラメータを作成したい人
・JUCEでコンボボックスのコンポーネントを利用したい人
・当ブログのシンプルなハイパスフィルタープラグイン記事を読んでいる人
実装
早速前回までで作成してきた「01_panda_filter」のslopeパラメータのUIをスライダーからコンボボックスへ変更していきます。
APVTS自体のパラメータは、「AudioParameterFloat」のままとして、ひもづけるコンポーネントをコンボボックスにする、というような変更を加えました。そのため、エディタ側の変更のみで対応しました。
PluginEditor.h
次のように、メンバを追加、変更しました。
class _01_panda_filterAudioProcessorEditor : public juce::AudioProcessorEditor, private juce::Timer
{
public:
//...略...
typedef juce::AudioProcessorValueTreeState::SliderAttachment SliderAttachment;
//[1]アタッチメントクラスをtypedefします。
typedef juce::AudioProcessorValueTreeState::ComboBoxAttachment ComboBoxAttachment;
//...略...
private:
//...略...
//juce::Slider SlopeSlider;
//std::unique_ptr<SliderAttachment> SlopeSliderAttachment;
//[2]slopeを操作するコンポーネントをコンボボックスに変更します。
juce::ComboBox SlopeComboBox;
std::unique_ptr<ComboBoxAttachment> SlopeComboAttachment;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (_01_panda_filterAudioProcessorEditor)
};
[1]で、今回は、コンボボックスクラスのオブジェクトを紐付けしたいので、このようにComboBoxAttachmentをtypedefしておきます。typedefすることで、今後「juce::Audio・・・::ComboBoxAttachment」と長く記載しなくてもBomboBoxAttachmentと短く表現することができるようになります。
[2]で、配置するコンボボックスのオブジェクトをメンバとして宣言しました。「SlopeComboBox」という名前をつけました。同様に先ほどtypedefしたコンボボックスアタッチメントのクラスのオブジェクトをメンバに加えます。
PluginEditor.cpp
コンストラクタで、今までslopeパラメータと紐付けをしていたスライダーを初期化していた部分をコメントアウト(削除)しました。
_01_panda_filterAudioProcessorEditor::_01_panda_filterAudioProcessorEditor (_01_panda_filterAudioProcessor& p, juce::AudioProcessorValueTreeState& vts)
: AudioProcessorEditor (&p), valueTreeState(vts)
, forwardFFT(p.fftOrder),
window(p.fftSize, juce::dsp::WindowingFunction<float>::hann)
,audioProcessor(p)
{
//...略...
//スライダーのときのslopeをコメントアウトしました。
/*addAndMakeVisible(SlopeSlider);
SlopeSliderAttachment.reset(new SliderAttachment(valueTreeState, "slope", SlopeSlider));
SlopeSlider.setSliderStyle(juce::Slider::Rotary);
SlopeSlider.setTextBoxStyle(juce::Slider::TextBoxBelow, true, 100, 20);
SlopeSlider.setLookAndFeel(&dialLookAndFeel01);*/
//[1]コンボボックスの初期化を追加しました。
addAndMakeVisible(SlopeComboBox);
SlopeComboAttachment.reset(new ComboBoxAttachment(valueTreeState, "slope", SlopeComboBox));
SlopeComboBox.addItem("-6db", 1);
SlopeComboBox.addItem("-12db", 2);
SlopeComboBox.addItem("-24db", 3);
SlopeComboBox.setSelectedId(1);
setOpaque(true);
startTimerHz(30);
setSize (500, 300);
}
代わりに、[1]のように、コンボボックスの一連の初期化を行い、slopeパラメータをコンボボックス「SlopeComboBox」に紐付けます。reset関数がパラメータの紐付けになります。
それ以降の行で、「addItem」関数で項目を追加しました。addItemの引数として、コンボボックスに表示する文字列を第一引数、第二引数にアイテムのIDを入れます。アイテムのIDは、1から始めます。
最後の「setSelectedId」関数で、コンボボックスの初期値をアイテムID1としています。初期値にha「-6db」が入ることになります。
このコンボボックスが実際どのような値をパラメータに渡しているかは、プロセッサ側のprocessBlock関数の「*slope」の値をDBGで観察するとわかります。
一つ目の「-6db」のパラメータの時、パラメータの数値としては「0」になっていて、その次の「-12db」の時には、「1」の値が、「-24db」の時は、「2」の値となりました。
最後に、でコンストラクタのSlopeSliderの行を削除、そして、resized関数で、SlopeComboBoxを適切なサイズで配置しました。
_01_panda_filterAudioProcessorEditor::~_01_panda_filterAudioProcessorEditor()
{
cutoffSlider.setLookAndFeel(nullptr);
QParamSlider.setLookAndFeel(nullptr);
//SlopeSlider.setLookAndFeel(nullptr);
}
//...略...
void _01_panda_filterAudioProcessorEditor::resized()
{
cutoffSlider.setBounds(10, 10, 100, 100);
QParamSlider.setBounds(150, 10, 100, 100);
//SlopeSlider.setBounds(300, 10, 100, 100);
SlopeComboBox.setBounds(300, 10, 100, 20);
}
このような感じで、スロープが設定できるようになりました。