JUCEを使ってVSTプラグインをMacで開発する

#JUCEとは
**J**ules' **U**tility **C**lass **E**xtensionsの略です。詳しくは[@COx2さんの記事](https://qiita.com/COx2/items/430e07bc1e65d1485868#_reference-523145dd4cd5ee6f2423)に日本語で分かりやすく解説されています。
一言で表すと、**OSに依存せずC++のビルドを楽に行う開発環境**、だと思います。(まだ経験は浅いですが…)
JUCEで立ち上げたプロジェクトをxcode上でビルドしたら簡単にビルドできました。
VSTやAUなどのDAWソフト向けのファイルに対応しており、そのような自作の音源ソフトなどを開発したい人にはもってこいだと思います。

##はじめに
インストール方法等は[@COx2さんの記事](https://qiita.com/COx2/items/430e07bc1e65d1485868#_reference-523145dd4cd5ee6f2423)を見てください。
この記事では、より先の内容である、MIDI信号を入力としwavファイルを出力する音源作成のチュートリアルを扱っていこうと思います。
参考にするのは[公式チュートリアル(2019年6月参照)](https://docs.juce.com/master/tutorial_code_basic_plugin.html)。こいつを日本語で解説できればな、と思います。

##Orientation ~コードについて軽い解説~
JUCEで「Audio Plug-In」を選ぶと自動で生成されるファイルについて解説。

- PluginProcessorはwavやmidiファイルを扱うクラス
- PluginEditorはGUIを扱うクラス

イメージとしてはProcessorはEditorの親分らしい。
一つのProcessorに対して複数のEditorが存在する。
Editorで設定したツマミをいじればProcessorの中のパラメータが変化するのかしら。

Processorクラスの中で特にいじる箇所はprocessBlock()関数の中です。この関数でmidi信号を受け取ったりwavファイルを出力します。
Editorクラスの中で特にいじる箇所はコンストラクタ部分とpaint()関数です。

例えば以下はEditorクラスのコンストラクタの中のプラグインの画面の大きさを決定するsetSize (縦のピクセル, 横のピクセル)関数です。

```c++:PluginEditor.cpp
TutorialPluginAudioProcessorEditor::TutorialPluginAudioProcessorEditor (TutorialPluginAudioProcessor& p)
    : AudioProcessorEditor (&p), processor (p)
{
    // ここでプラグインの画面の大きさを決定するよ！
    setSize (200, 200);
}
```

##Create a simple GUI control ~簡単なコントローラつくってみよう~
このチュートリアルでつくるのはmidiの音量を変えられるフェーダーです。
`Slider midiVolume;`ってPluginEditor.h上で定義し、これに対して様々な記述を行なっていく。

```c++:PluginEditor.h
class TutorialPluginAudioProcessorEditor : public AudioProcessorEditor
{
public:
    TutorialPluginAudioProcessorEditor (TutorialPluginAudioProcessor&);
    ~TutorialPluginAudioProcessorEditor();
    //===================================================================
    void paint (Graphics&) override;
    void resized() override;
private:
    // This reference is provided as a quick way for your editor to
    // access the processor object that created it.
    TutorialPluginAudioProcessor& processor;
    Slider midiVolume; // これを追加！
    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TutorialPluginAudioProcessorEditor)
};
```

次にフェーダーのデザインの詳細を記述。

```c++:PluginEditor.cpp
TutorialPluginAudioProcessorEditor::TutorialPluginAudioProcessorEditor (TutorialPluginAudioProcessor& p)
    : AudioProcessorEditor (&p), processor (p)
{
    // ここでプラグインの画面の大きさを決定するよ！
    setSize (200, 200);
    // フェーダーの詳細をここで決定。
    midiVolume.setSliderStyle (Slider::LinearBarVertical);
    midiVolume.setRange(0.0, 127.0, 1.0);
    midiVolume.setTextBoxStyle (Slider::NoTextBox, false, 90, 0);
    midiVolume.setPopupDisplayEnabled (true, false, this);
    midiVolume.setTextValueSuffix (" Volume");
    midiVolume.setValue(1.0);
    // 下記で上記で設定したフェーダーを追加。
    addAndMakeVisible (&midiVolume);
}
```

次にresized()関数に位置情報を記載。
ユーザーがウィンドウをいじっても、これならGUIが崩れないらしい。

```c++:PluginEditor.cpp
void TutorialPluginAudioProcessorEditor::resized()
{
    // 位置情報を記載。
    midiVolume.setBounds (40, 30, 20, getHeight() - 60);
}
```

最後にGUI部を設定。

```c++:PluginEditor.cpp
void TutorialPluginAudioProcessorEditor::paint (Graphics& g)
{
    // fill the whole window white
    g.fillAll (Colours::white);
    // set the current drawing colour to black
    g.setColour (Colours::black);
    // set the font size and draw text to the screen
    g.setFont (15.0f);
    g.drawFittedText ("Midi Volume", 0, 0, getWidth(), 30, Justification::centred, 1);
}
```
##Pass control information to the processor class ~パラメータの調整~
フェーダーのデザインはできたけど、このフェーダーを上下に動かしても現状なにもパラメータは変わらない。
Processorクラスをいじることで実際にmidiボリュームを変化させられるようにしていきましょう！

まずnoteOnVelというfloat変数をProcessorクラスのヘッダー上、publicの中で定義しましょう。

```c++:PluginProcessor.h
class TutorialPluginAudioProcessor  : public AudioProcessor
{
    public:
    float noteOnVel; // これを追加！
    // 以下略
```

次にフェーダーの値を逐次noteOnVelという値に代入する設定を行います。
これを行うのがsliderValueChanged関数です。
sliderValueChanged関数はどのクラスからも継承することが可能ですが、今回はEditorクラスで継承します。

```c++:PluginEditor.h
class TutorialPluginAudioProcessorEditor : public 
                                           // 下記を追加！
                                           private Slider::Listener
AudioProcessorEditor
{
public:
    TutorialPluginAudioProcessorEditor (TutorialPluginAudioProcessor&);
    ~TutorialPluginAudioProcessorEditor();
    //===================================================================
    void paint (Graphics&) override;
    void resized() override;
private:
    void sliderValueChanged (Slider* slider) override; // sliderValueChanged関数の定義
    // This reference is provided as a quick way for your editor to
    // access the processor object that created it.
    TutorialPluginAudioProcessor& processor;
    Slider midiVolume;
    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TutorialPluginAudioProcessorEditor)
};
```

ヘッダーに記入したらmidiVolumeにslider listener関数を追加しましょう。

```c++:PluginEditor.cpp
TutorialPluginAudioProcessorEditor::TutorialPluginAudioProcessorEditor (TutorialPluginAudioProcessor& p)
    : AudioProcessorEditor (&p), processor (p)
{
    // 上は省略
    // add the listener to the slider
    midiVolume.addListener (this);
}
```

最後にsliderValueChanged関数の内容を記述します。

```c++:PluginEditor.cpp
void TutorialPluginAudioProcessorEditor::sliderValueChanged (Slider* slider)
{
    processor.noteOnVel = midiVolume.getValue();
}
```

##完成！
Logicで表示した画像を下に添付します。Cubaseでも確認済みです。
ただ、パラメータがうまく設定されているかは分かりません。
Logicでこのエフェクターを挟むと音量が消えてるってことは、なんか動いているんだろうけど期待通りには動いていない気が…。
今後、プラグイン音源を実装していくにあたってコードの内容を理解していきます。
<img width="211" alt="スクリーンショット 2019-06-11 14.13.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208979/88139a45-ade9-d291-b023-e4dfa26f4635.png">