MIDI Pianoの入力や演奏の様子を鍵盤上で「見る」だけの手頃でシンプルなVisualizer Pluginがなかったので、久しぶりにC++の復習も兼ねて作ってみた。
【C++の復習】juce::MidiKeyboardStateはPluginProcessor.hでインスタンス化し、その他のComponentではその参照を利用する。
// PluginProcessor.h
class SimplePianoVisualizerAudioProcessor : public juce::AudioProcessor
{
public:
// 省略
juce::MidiKeyboardState& getKeyboardState() {
return keyboardState;
} //インスタンスへの参照をゲットするpublic関数
private:
//==============================================================================
juce::MidiKeyboardState keyboardState; // ここでインスタンス化
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SimplePianoVisualizerAudioProcessor)
};
// PluginEditor.cpp
SimplePianoVisualizerAudioProcessorEditor::SimplePianoVisualizerAudioProcessorEditor (SimplePianoVisualizerAudioProcessor& p)
: AudioProcessorEditor (&p), audioProcessor (p), keyboardState(p.getKeyboardState())
{
setSize (400, 300);
}
【C++の復習】keyboardComponentはPluginEditor.hでインスタンス化し、initialization listでイニシャライズする。
//PluginEditor.h
class SimplePianoVisualizerAudioProcessorEditor : public juce::AudioProcessorEditor
{
public:
SimplePianoVisualizerAudioProcessorEditor (SimplePianoVisualizerAudioProcessor&);
~SimplePianoVisualizerAudioProcessorEditor() override;
//==============================================================================
void paint (juce::Graphics&) override;
void resized() override;
private:
SimplePianoVisualizerAudioProcessor& audioProcessor;
juce::MidiKeyboardState& keyboardState;
juce::MidiKeyboardComponent keyboardComponent;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SimplePianoVisualizerAudioProcessorEditor)
};
//PluginEditor.cpp
SimplePianoVisualizerAudioProcessorEditor::SimplePianoVisualizerAudioProcessorEditor (SimplePianoVisualizerAudioProcessor& p)
: AudioProcessorEditor (&p), audioProcessor (p), keyboardState(p.getKeyboardState()), keyboardComponent(p.getKeyboardState(), juce::KeyboardComponentBase::horizontalKeyboard)
{
setSize (400, 300);
}
【JUCEの復習】PluginEditor.cppのコンストラクタとresized()に記述し、画面上に表示する。
// Constructor
{
addAndMakeVisible(keyboardComponent);
setSize (400, 100);
setResizable(true, false);
}
// resized()
void SimplePianoVisualizerAudioProcessorEditor::resized()
{
auto area = getLocalBounds();
keyboardComponent.setBounds(area);
}
これを実行すると、以下のように表示されます。縦・横を自由に表示されるようにするには、Sliderなどでサイズを可変にすると良いです。
void SimplePianoVisualizerAudioProcessorEditor::sliderValueChanged(juce::Slider *slider)
{
horizontalSliderValue = horizontalSlider.getValue();
verticalSliderValue = verticalSlider.getValue();
// making sure the resized() (UI changes) are made on the UI thread
(new SliderValueChangedCallback(this))->post();
}
void SimplePianoVisualizerAudioProcessorEditor::resized()
{
auto area = getLocalBounds();
auto verticalMargin = area.getHeight()/2.8;
auto keyboardArea = area.removeFromBottom(verticalMargin).reduced(30, 0);
keyWidth = 32 * (horizontalSliderValue/10);
keyboardComponent.setKeyWidth(keyWidth);
keyboardComponent.setBounds(keyboardArea.getX(), keyboardArea.getY(), keyboardArea.getWidth(), keyboardArea.getHeight()*(verticalSliderValue/10));
}
PluginProcessorのprocessBlockで下のように処理をすると、キーボードを弾くとスクリーン上のキーボードが反応するようになります。
void SimplePianoVisualizerAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, juce::MidiBuffer& midiMessages)
{
for(const auto m: midiMessages) {
keyboardState.processNextMidiEvent(m.getMessage());
}
}