C++
audio
MIDI
JUCE
ROLI
JUCEDay 1

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

本記事はJUCE Advent Calendar 2017 の12月1日向けに投稿した記事です。

JUCEって何?

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

JUCEの特徴は?

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

スクリーンショット 2017-11-26 15.08.22.png

JUCEライブラリ と Projucer

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

JUCE_Projucer.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

ライセンスタイプ 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

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

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

GitHubリポジトリ

GitHub.PNG

JUCEをはじめよう

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

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

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

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

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

get juce.PNG

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

filer.png

・Projucerを起動、ROLIアカウントでサインイン

ROLIアカウントが未登録なら、アカウントを作成します。

image.png

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

image.png


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

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

image.png

・Projucerを自分の環境でビルドしてください

ディレクトリ: JUCE/extras/Projucer

image.png

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

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

▼GPL版で免除される事項

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

image.png

JUCEでHello Sine!

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

新規プロジェクトを作成

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

NewProject_AudioApp.png

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

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

NewAudio.PNG

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

CreatedFiles.png

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

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

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

Exporterss.PNG

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

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

"MainComponent.cpp"

class MainContentComponent   : public AudioAppComponent
{
public:

~~~中略~~~

    void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) override
    {
        bufferToFill.clearActiveBufferRegion();

    #define M_PI 3.14159265358979323846
    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(M_PI * 2 * sample / buffer->getNumSamples() * 2) * level;
        }
    }
    }

~~~中略~~~

    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainContentComponent)
};

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

スライド3.PNG

ビルドと動作確認

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

HelloSine.PNG

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

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

JUCE Demoをビルドしてみよう

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

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

image.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シンセサイザ

  • オシレータ×3
  • エンベロープ×3
  • LFO×3
  • フィルタ×2
  • エフェクタ×4 (ディレイ、コーラス/フランジャ、ローファイ、クリッパー)
  • ステップシーケンサ

image.png

dexed

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

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

image.png

個人開発者

Aogiri-m2d... JUCE_Osc-AmpEnv-Polyphonic他
AkiyukiOkayasu... JUCE-AudioFilePlayer他
COx2... JUCE_JAPAN_DEMO他
delatetei... Backwards他
hotwatermorning... LevelMeter他
kawaCat... MidSide-Vst3他