今回は、地味に機能的な部分を改良してみました
当たり前の機能を追加することは大事だよね
ディレイプラグインの開発で、機能的な部分を追加をしました。パラメータの保持、アンドゥ、リドゥの機能を実装していきます。
パラメータの保持については、以前の記事で詳細に記載しております。
また、アンドゥ、リドゥの機能についても以下の記事もご参照ください。
AudioProcessorValueTreeStateでアンドゥ、リドゥ機能を追加する
こんな人の役に立つかも
・JUCEプラグイン開発をしている人
・AudioProcessorValueTreeStateのパラメータを保持したい人
・JUCEでアンドゥ、リドゥの処理を追加したい人
パラメータ保持
まずは、パラメータを保存、読み出しする機能です。これは、DAWプロジェクトを再度開いたとき、以前の設定状態になっているような機能です。この実装をしない場合、DAWプロジェクトを開くたびに、デフォルト値になってしまいます。
既にデフォルトで何も入っていないgetStateInformation関数、setStateInformation関数に以下のようなプログラムを追加します。
void TheDelayAudioProcessor::getStateInformation (juce::MemoryBlock& destData)
{
//以下の内容を追加します。
auto state = parameters.copyState();
std::unique_ptr<juce::XmlElement> xml(state.createXml());
copyXmlToBinary(*xml, destData);
}
void TheDelayAudioProcessor::setStateInformation (const void* data, int sizeInBytes)
{
//以下の内容を追加します。
std::unique_ptr<juce::XmlElement> xmlState(getXmlFromBinary(data, sizeInBytes));
if (xmlState.get() != nullptr)
if (xmlState->hasTagName(parameters.state.getType()))
parameters.replaceState(juce::ValueTree::fromXml(*xmlState));
}
コンボボックスのみ、初期値が反映されない現象が起きますので、コンストラクタで初期値を入れるようにします。
TheDelayAudioProcessorEditor::TheDelayAudioProcessorEditor (TheDelayAudioProcessor& p, juce::AudioProcessorValueTreeState& vts)//add second param
: AudioProcessorEditor (&p), audioProcessor (p), valueTreeState(vts)//add param
{
//...略...
//コンボボックスの初期化を追加します。
DelayNumerator.setSelectedId(*(vts.getRawParameterValue("delayNumerator")));
setSize (400, 300);
}
保存されたパラメータから値を取得するためには、APVTSクラスのgetRawParameterValue関数が利用できます。引数には、パラメータIDを指定すればOKです。
アンドゥ・リドゥ機能
Undo、Redoボタンを追加して、パラメータの変更の後戻りなどができるようになります。APVTSにUndoManagerクラスを連携させることで実現ができます。
プロセッサ側
AudioProcessorクラス内に、publicなメンバとして、利用するUndoManagerを定義します。
class TheDelayAudioProcessor : public juce::AudioProcessor, private juce::Timer
{
public:
//...略...
//アンドゥマネージャをpublicなメンバとして追加しました。
juce::UndoManager undoManager;
コンストラクタにて、APVTSのパラメータ初期化の際に、第二引数にundoManagerの参照を渡します。
TheDelayAudioProcessor::TheDelayAudioProcessor()
//...略...
//第二引数にundoManagerの参照を追加します。
, parameters(*this, &undoManager/*nullptr*/, juce::Identifier("APVTSTutorial"),
エディタ側で利用できるようにするため、createEditor関数で、AudioProcessorEditorクラスへの第三引数としてundoManagerを渡します。
juce::AudioProcessorEditor* TheDelayAudioProcessor::createEditor()
{
//第三引数にundoManagerを追加します。
return new TheDelayAudioProcessorEditor (*this, parameters, undoManager);
}
この状態で、undoManagerのundo関数、redo関数を呼び出すことでパラメータのアンドゥ、リドゥができる状態になりました。
エディタ側
PlugPluginEditor.h内、TheDelayAudioProcessorEditorクラスの内容となります。undo、redo関数は、ボタンから呼び出すため、今回は、テキストボタンを追加することでアンドゥ、リドゥ機能を実行できるようにします。
class TheDelayAudioProcessorEditor : public juce::AudioProcessorEditor
{
public:
//[1]第三引数を追加します。
TheDelayAudioProcessorEditor (TheDelayAudioProcessor&, juce::AudioProcessorValueTreeState& vts, juce::UndoManager& um);
//...略...
//[2]privateなメンバとしてボタンとundoManagerを追加します。
juce::TextButton undoButton, redoButton;
juce::UndoManager& undoManager;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TheDelayAudioProcessorEditor)
};
次に、PluginEditor.cppのコンストラクタを次のように変更しました。
//[1]コンストラクタの第三引数を追加します。
TheDelayAudioProcessorEditor::TheDelayAudioProcessorEditor (TheDelayAudioProcessor& p, juce::AudioProcessorValueTreeState& vts, juce::UndoManager& um)
: AudioProcessorEditor (&p), audioProcessor (p), valueTreeState(vts)
//[2]ボタン、アンドゥマネジャを初期化します。
, undoButton("Undo"), redoButton("Redo")
, undoManager(um)
{
//...略...
//[3]ボタンの初期化をします。
addAndMakeVisible(undoButton);
addAndMakeVisible(redoButton);
undoButton.onClick = [this] {
undoManager.undo();//[1]undo処理です。
DBG("undo");
};
redoButton.onClick = [this] {
undoManager.redo();//[2]redo処理です。
DBG("redo");
};
setSize (400, 300);
}
最後に、ボタンをGUIに配置して完了です。
void TheDelayAudioProcessorEditor::resized()
{
//...略...
//ボタンを配置します。
undoButton.setBounds(10, 200, 50, 30);
redoButton.setBounds(60, 200, 50, 30);
}