JUCE ハンズオン 〜JUCEをはじめよう〜

本記事は[JUCE Advent Calendar 2017](https://qiita.com/advent-calendar/2017/juce) の12月1日向けに投稿した記事です。

# JUCEって何？

JUCE (Jules' Utility Class Extensions)は、C++言語によるマルチメディア系アプリケーションの開発を支援するフレームワークです。クロスプラットフォーム設計のライブラリと、付属されているプロジェクトジェネレータ『Projucer』から各種IDE(VisualStudio, Xcode, Makefile)向けにプロジェクトファイルを出力することで、ワンソースからWindows, macOS, Linux, iOS, Android で動作するアプリケーションを作成することができます。
[公式サイト](https://juce.com/)

## JUCEの特徴は？

JUCEの最大の特徴として、オーディオプラグインを開発するためのテンプレートが充実していることが挙げられます。VST/AudioUnit/AAX/RTASプラグインといった、DTMユーザーにはお馴染みのプラグインフォーマットを開発するのに長けており、日本国内外で多くの採用事例があります。
[公式サイトによる採用事例の紹介](https://juce.com/made-with-juce)

<img width="694" alt="スクリーンショット 2017-11-26 15.08.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/93566/6c8bdc2f-10f4-2153-31de-5eec7181ebff.png">


## JUCEライブラリ と Projucer

JUCEフレームワークは、各種機能を提供する『JUCEライブラリ』と、各種プラットフォーム向けのプロジェクトを出力するジェネレータ『Projucer』によって構成されます。
『JUCEライブラリ』には機能別に『モジュール』という単位で構成が分かれており、『Projucer』はプロジェクトに必要なモジュールを取り込んで、IDE用のプロジェクトファイルやビルドスクリプトに紐付ける作業を担当します。

![JUCE_Projucer.png](https://qiita-image-store.s3.amazonaws.com/0/93566/5c54d93e-2345-7ac9-6041-6b82d4731fd9.png)

以下がJUCEライブラリのモジュール一覧です。(JUCE 5.2時点)
オーディオデバイスとの接続を処理するモジュールや、オーディオプラグインフォーマットの定義を持つモジュール、オーディオファイルを読み込む機能を持つモジュール、OSC（Open Sound Control）の機能を抽象化したモジュールなど、モダンなオーディオアプリケーションを実装するのに十分な程の機能を提供します。

|モジュール名|提供する機能|
|:------|:-----------------------|
| juce_analytics | ユーザーの利用情報を収集して送信するクラス |
| juce_audio_basics | オーディオバッファの操作、MIDIメッセージ処理、シンセサイザーなどのクラス |
| juce_audio_devices | オーディオインターフェースおよびMIDIインターフェースの制御や、再生と録音をするクラス |
| juce_audio_formats | 	さまざまなオーディオファイル形式を読み込み・書き込みするクラス |
| juce_audio_plugin_client | VST、VST3、AudioUnit、AAX、RTASプラグインを構築するためのクラス|
| juce_audio_processors | VST、AU、または内部で生成されたオーディオプロセッサのロードおよび再生をするクラス |
| juce_audio_utils | オーディオ関連のGUIおよびその他のタスク（MIDI over BLE含む）を処理するクラス |
| juce_blocks_basics | ROLI BLOCKSデバイスを低レベルで制御するためのJUCEラッパー |
| juce_box2d | 	Box2D物理エンジンといくつかのユーティリティクラス |
| juce_core	 | 他のJUCEモジュールが必要とする基本的な必須セット、コアモジュール |
| juce_cryptography | RSA、Blowfish、MD5、SHAなどのさまざまな基本暗号化機能を持つクラス |
| juce_data_structures | アンドゥ/リドゥなどを管理する、スマートなデータ構造を操作するクラス |
| juce_dsp | オーディオバッファ操作、デジタルオーディオ処理、フィルタリング、オーバーサンプリング、数学関数などを高速に実行するクラス |
| juce_events | アプリケーションのメインイベントループを実行し、メッセージ、タイマーなどを送受信するためのクラス |
| juce_graphics	 | 2Dベクトルグラフィックス、画像読み込み/保存、フォント処理などをするためのクラス |
| juce_gui_basics | 基本的なユーザーインターフェイスを作成するコンポーネントおよび関連するクラス |
| juce_gui_extra | 特別なタスクを処理するためのGUIクラス拡張 |
| juce_opengl | JUCEウィンドウでOpenGLをレンダリングするためのクラス |
| juce_osc	 | OSC(Open Sound Control)を実装したクラス |
| juce_product_unlocking | オンライン製品認証を実装するクラス |
| juce_video	 | ビデオ再生と、カメラ入力をキャプチャするためのクラス |


## ライセンス

JUCEには無償で商用アプリケーションに使用することができるPersonalライセンスとGPLv3ライセンスが設定されています（Personalには所定の条件あり）。Unityと類似したライセンス形態であるため、馴染みのある開発者も多いと思われます。

Personalライセンスは、JUCE5から新設されたライセンスです。以前から無償利用できるFreeライセンスは存在していましたが、GPLが適用されるという条件に同意する必要があったため、プロジェクトをオープンソースにしたくない開発者は有償ライセンスを購入する必要がありました。Personalライセンスを利用するには、以下の条件を満たす必要があります。

+ 起動時のスプラッシュスクリーンを表示すること。 
+ アプリケーションの利用情報を送信することに同意すること。 
+ 年間の収入または資本金額が$50k未満であること。

利用条件を満たさない場合には、JUCE 5 End User License Agreement の 1.8.に記載されている通り、有償ライセンスを購入する若しくはGPLライセンスが適用される点には注意しておいた方がいいでしょう。
逆に、プロジェクト自体をオープンソースにすることでコミュニティの支援を受けたい、教育目的でソースコードを開示したいなど、GPLv3を選択する方が好ましい場合もあるので、開発者の目的に合わせてライセンスを選択すると良いでしょう。
[公式: JUCE5 EULA](https://juce.com/juce-5-license)

| ライセンスタイプ| JUCE Personal| JUCE Indie| JUCE Pro| Education| GPL v3|
|:------|:------|:------|:------|:------|:------|
|スプラッシュスクリーン| “made with JUCE” 表示必須| 変更可・非表示可|変更可・非表示可| “made with JUCE” 表示必須|-|
|年間の収入または資本金額の限度| $50k	| $200k| No limit| No limit |-|
|最低契約期間 | -  |	12ヵ月 | 12ヵ月|-|-|
|サブスクリプションライセンス料金 | 無料 | $35/月 | $65/月 | 無料 |-|
|永続ライセンス料金 | - | $700 | $1,300 | - |-| 


![License.PNG](https://qiita-image-store.s3.amazonaws.com/0/93566/7b23eec3-93d8-edb4-05cb-0cd1557f540f.png)


## JUCEライブラリはオープンソース

JUCEはGitHubリポジトリで開発が行われており、ソースコードも全て開示されています。IssueやPull requestを送ることで不具合報告や機能改善の要望、修正の提案などのプロジェクトに貢献することができます。また、developブランチをチェックアウトすることで、将来的に実装される機能を試すこともできます。

[GitHubリポジトリ](https://github.com/WeAreROLI/JUCE.git)

![GitHub.PNG](https://qiita-image-store.s3.amazonaws.com/0/93566/c038ea94-b6bd-5203-2432-541e011bbf1d.png)

# JUCEをはじめよう

JUCEを入手するには２つの方法があります

+ 公式サイトからダウンロード
+ GitHubリポジトリをクローン

## 1. 公式サイトからダウンロード

URL: https://www.juce.com/get-juce

### ・プラットフォームごとに用意されたリンクからダウンロード

![get juce.PNG](https://qiita-image-store.s3.amazonaws.com/0/93566/3c7649e5-ae8d-bbaa-1903-fb841bd20460.png)


### ・プラットフォーム用にビルド済みのProjucerが同梱されています

![filer.png](https://qiita-image-store.s3.amazonaws.com/0/93566/c6aec0b1-4fb8-26b4-07ce-d4c80a5b5428.png)

### ・Projucerを起動、ROLIアカウントでサインイン
ROLIアカウントが未登録なら、アカウントを作成します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/93566/b317f882-4d26-4c1f-26c4-8464749fb63c.png)


サインインが成功すると、Projucerが使えるようになります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/93566/cc2413a7-e432-88c7-e1d6-83423070acd5.png)


---

## 2. GitHubリポジトリをクローン

```bash

$ git clone https://github.com/WeAreROLI/JUCE.git

```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/93566/d2720865-1b88-0ba1-a00c-f7fda00d30a5.png)


### ・Projucerを自分の環境でビルドしてください
ディレクトリ: JUCE/extras/Projucer

![image.png](https://qiita-image-store.s3.amazonaws.com/0/93566/614c8661-cdaf-f357-0741-43125ec17970.png)


## 補足：GPLライセンスで使う方法

Projucerプロジェクトの AppConfig.h にあるGPLモードフラグを有効にしてからビルドすることで、JCUEフレームワークをGPLライセンスで使用することに同意したとみなされ、Personalライセンスに設定されていた利用条件や一部機能を免除することができます。

▼GPL版で免除される事項

+ Projucerを使用する際のROLIアカウントサインイン免除
+ スプラッシュスクリーン表示義務の免除
+ アプリケーションの利用情報を送信する義務の免除

![image.png](https://qiita-image-store.s3.amazonaws.com/0/93566/819d6bc7-5792-0e58-92e3-da7533657596.png)

# Projucerのセットアップ

## Pathのセッティング
1. Projucerを起動する
2. [File]→[Global Paths...]メニューをクリックして『Global paths』ダイアログを開く
3. 『Path to JUCE』欄に、JUCEのルートディレクトリを入力する
  - 公式サイトからDLした場合はZIPの解凍先ディレクトリ
  - git cloneした場合はリポジトリのルートディレクトリ
4. 『JUCE Modules』欄に、JUCEディレクトリの直下に置かれた『modules』ディレクトリを入力する

■ Projucerのメニューから『Global Paths...』を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93566/198e1161-fa83-518d-1200-d420168a1c9b.png)

↓

■ JUCEのルートディレクトリとmodulesディレクトリを設定する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93566/832a9e9e-1428-7c84-93cd-fa558b75b28d.png)

## JUCE DemoRunner

JUCEライブラリのパッケージに含まれているデモアプリケーション『JUCE DemoRunner』をビルドすることができれば、JUCEとProjucerのセットアップは完了です。

1. Projucerのメニューから[File]→[Open Example]→[Launch Demo Runner]をクリック
    - 公式サイトからDLした場合、ビルド済みのDemoRunnerバイナリが同梱されているため、ビルドをスキップしてDemoRunnerが起動する
    - git cloneした場合、DemoRunnerを新規にビルドする必要がある。ProjucerからIDEでプロジェクトを開くかどうか尋ねられるので、それにしたがってプロジェクトを開いてビルドを実行する
2. DemoRunnerの実行ファイルの用意が済んだら、Projucerの[File]→[Open Example]→[Launch Demo Runner]からDemoRunnerを起動する

■ Projucerのメニューから『Launch Demo Runner』を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93566/85a4bfe3-f5b5-2a94-0aaa-fd6471fcc719.png)

↓ビルド実行後に起動 or ビルド不要の場合はそのまま起動

■ JUCE DemoRunner
DemoRunnerのブラウジングメニューから様々なデモプログラムを起動してみましょう。
各デモプログラムからJUCEライブラリのリファレンス実装を確認することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93566/293482a2-0915-9d4b-534e-8863a2ae5398.png)



# JUCEでHello Sine!

JUCEライブラリとProjucerの準備が完了したら、アプリケーションを作成してみましょう。

## 新規プロジェクトを作成

 Projucerを起動したら、[File] → [New Project...]をクリックして、テンプレートを選択する画面を開きます。
今回は、"Audio Application"テンプレートから新規プロジェクトを作成します。

![NewProject_AudioApp.png](https://qiita-image-store.s3.amazonaws.com/0/93566/9c182ee4-c4c9-1841-a98d-aa8327efe4a0.png)



新規作成メニューでは、[Target Platforms]の項目を確認します。ここを自身の開発環境に合わせてチェックを入れます。
1. macOSでの開発なら、Xcodeにチェックを入れます。
2. Windowsでの開発なら、VisualStudioにチェックを入れます（2013, 2015, 2017に対応）。
3. Linuxでの開発なら、Linux Makefileにチェックを入れます。

※Linux MakefileはmacOSのmakeコマンドでもビルドできます。

![NewAudio.PNG](https://qiita-image-store.s3.amazonaws.com/0/93566/0651ab9f-392f-acc6-8a1f-924e63b4b260.png)



新規プロジェクトを作成すると、"Main.cpp"と"MainComponent.cpp"の2つのソースファイルが作成されます。

![CreatedFiles.png](https://qiita-image-store.s3.amazonaws.com/0/93566/7c7119b8-065b-ccb9-0bda-ddc8ec0a8f08.png)

## プロジェクトの保存とIDEを開く

Projucerで新規プロジェクトの保存と、IDE（VisualStudio、Xcode）でプロジェクトを開きます。
1. Projucer上部のコンボボックスから、起動したいIDEを選択します。
2. IDEのアイコンが表示されているボタンをクリックします。
3. プロジェクトの保存とIDEの起動が行われます。

※Linux Makefileの場合は、ソースファイルをエディタで編集しましょう。

![Exporterss.PNG](https://qiita-image-store.s3.amazonaws.com/0/93566/63525be7-eca1-3f05-75b9-577bfdc6fe5d.png)



## サイン波を鳴らしてみよう


プロジェクトを開いたら、サイン波を鳴らす処理を実装してみましょう。"MainComponent.cpp"を次のように編集します。関数"void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) override"は、予め記述されているので、関数の内部を編集します。



```cpp

"MainComponent.cpp"

class MainContentComponent   : public AudioAppComponent
{
public:

~~~中略~~~

    void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) override
    {
        bufferToFill.clearActiveBufferRegion();
		
	const float level = 0.5f;
	
	auto buffer = bufferToFill.buffer;
	for (int channel = 0; channel < buffer->getNumChannels(); ++channel)
	{
		float* channelData = buffer->getWritePointer(channel);

		for (int sample = 0; sample < buffer->getNumSamples(); ++sample)
		{
			channelData[sample] = sinf(juce::MathConstants<float>::twoPi * sample / buffer->getNumSamples() * 2) * level;
		}
	}
    }

~~~中略~~~

    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainContentComponent)
};
```


このソースコードを記述すると、オーディオバッファを更新する度に、オーディオバッファ全体でサイン波一周分（360°=2π）を書き込む処理が実行されます。

![スライド3.PNG](https://qiita-image-store.s3.amazonaws.com/0/93566/bba31b9b-fcf7-eba4-b37f-0b5c9821fd36.png)



## ビルドと動作確認

上記のソースコードを記述したら、ビルドを実行します。
ビルドが成功したらアプリケーションを起動してみましょう。
アプリケーションを起動すると、ウインドウが表示されるとともに、オーディオデバイスとの連携が正常にできていれば、サイン波が鳴っているのが聞こえるはずです。

![HelloSine.PNG](https://qiita-image-store.s3.amazonaws.com/0/93566/f1921c14-739e-71a8-82b9-a4a9175c3277.png)




# JUCEのことをもっと知りたい

JUCEライブラリはモダンなアプリケーションを開発するのに十分すぎるほどの機能を提してくれますが、その反面、公式のチュートリアルがあまり充実しているとは言えません。特に2017年は数ヶ月ごとに新しい機能を提供することもあって、各モジュールを使いこなすための情報収集は欠かせません。
特に、モジュールの機能を把握するために付属の『JUCE Demo』プロジェクトや各種サンプルプロジェクトのソースコードを読むことが１番の近道です。

## JUCE Demoをビルドしてみよう

ディレクトリ: JUCE/examples/Demo

GUIコンポーネント、グラフィックス、OpenGL、オーディオ関係、各種ユーティリティ（XML、JavaScript）の動作と、実装コードを確認することができます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/93566/3798e721-a951-4a05-92e0-aecf2b7d567e.png)


## ドキュメントを読んでみよう
・チュートリアル
https://www.juce.com/tutorials

・APIモジュール
https://www.juce.com/doc/modules

・APIクラスリファレンス
https://www.juce.com/doc/classes

## フォーラムサイトを覗いてみよう

公式でフォーラムサイトを提供しています。
https://forum.juce.com/

ユーザーからの疑問・質問にJUCE開発者が回答してくれたり、ユーザー間でやりとりをすることができます。
英語でやりとりされていますが、Chromeブラウザのページ翻訳機能を使うと良いでしょう。
チュートリアルに掲載されていない機能やトリッキーな実装テクニック、プラットフォームの拡大などの議論が日々交わされています。
私もこちらのフォーラムを参考にして、RaspberryPiでJUCEをビルドする手順などを知ることができました。



# JUCEを使ったオープンソースプロジェクト

JUCEを利用したオープンソースなプロジェクトを紹介します。様々なプロジェクトのソースコードを読むことで、他の開発者による実装例や、JUCEならではの実装テクニックについても触れることができるでしょう。

## synister

GitHubリポジトリ：http://github.com/the-synister/the-source

全部入りなVAシンセサイザ

+ オシレータ×３
+ エンベロープ×３
+ LFO×３
+ フィルタ×２
+ エフェクタ×４ （ディレイ、コーラス/フランジャ、ローファイ、クリッパー）
+ ステップシーケンサ

![image.png](https://qiita-image-store.s3.amazonaws.com/0/93566/06aecdc4-4758-8b07-7b5f-b2cf4903a1a0.png)


## dexed

GitHubリポジトリ：http://github.com/asb2m10/dexed

DX7/TX7をエミュレートしたFMシンセサイザ
DX7/TX7のSysExメッセージにも対応

![image.png](https://qiita-image-store.s3.amazonaws.com/0/93566/713918e2-c620-14bb-f643-23acf5a39727.png)

## 個人開発者

[Aogiri-m2d](https://github.com/Aogiri-m2d)... JUCE_Osc-AmpEnv-Polyphonic他
[AkiyukiOkayasu](https://github.com/AkiyukiOkayasu)... JUCE-AudioFilePlayer他
[COx2](https://github.com/COx2)... JUCE_JAPAN_DEMO他
[delatetei](https://github.com/delatetei)... Backwards他
[hotwatermorning](https://github.com/hotwatermorning)... LevelMeter他
[kawaCat](https://github.com/kawaCat)... MidSide-Vst3他