SlideShare una empresa de Scribd logo
1 de 124
Descargar para leer sin conexión
JUCEハンズオン
@Ableton and Max Community Japan #009
塩澤達矢(COx2)
2020/11/14
Note
・本内容は、JUCEユーザーである発表者個人の感想であり、JUCEの開発元である
Raw Material Software, Ltd.を代表するものではありません
・JUCEの仕様に関わる事項は、発表当日(2020/11/14)のReleaseバージョン(JUCE
6.0.4)に準拠します
・ご紹介する範囲は、JUCEの一部機能や一部APIに留めております
・時間の都合上、C++言語の文法についての説明は割愛させていただきます
・本日のソースコード https://github.com/COx2/amcj009-juce-study
自己紹介
名前: 塩澤達矢(COx2)
属性: JUCE enthusiast
オーディオプログラマー/インデペンデントJUCEプログ
ラマー/JUCE JAPAN編集部代表
JUCE案件を中心に取り扱う個人事業主のソフトウェア
開発者
趣味でVSTプラグインを制作する中でJUCEと出会い、
その強力な開発環境に衝撃を受ける
日本のエンジニアにJUCEの魅力を伝えるべく、2016年
に非公式ガイド「JUCE JAPAN」を発行
@CO_CO_
tatsuya.shiozawa.99
オーディオプラグインを作ってみたいと思っ
たことはありますか?
オーディオプラグイン開発の魅力
・僕の考えた最強のシンセサイザー
・音楽制作ソフトで使える(Cubase, Live, Max...)
・楽器の原理や仕組みが学べる
・楽曲制作に使える
・プラグインビジネス
オーディオプラグインを開発する方法を調
べてみたことはありますか?
オーディオプラグイン開発特有の難しさ
・C/C++プログラミングって難しそう…
・VST SDK? VST3 SDK? AAX SDK?
・プラグイン・インターフェースって何?
・プラグイン・アーキテクチャとは?
・リアルタイムプログラミング、マルチスレッド…
・音を鳴らしたいだけなのに…
 JUCEがその悩みを解決します
JUCEハンズオン
・JUCEとは?
・JUCEをはじめよう!
・Q&A
・JUCEでオーディオプラグイン開発入門
・JUCEで広がるオーディオソフトウェア開発
・Audio Developer Conferenceへのお誘い
・Q&A
JUCEとは?
JUCE
名前の由来 = Jules' Utility Class Extensionsの略称
Julian Storer※が開発したマルチメディア向けの C++フ
レームワーク
※https://github.com/julianstorer
Julian StorerがDAWソフト『Tracktion※』を制作する際
に開発したライブラリが基となっている
※現在の製品名は『WAVEFORM』https://www.tracktion.com/
初期リリースは2004年
最新版は2020年10月リリースのJUCE 6.0.4
Cross-platform
クロスプラットフォーム設計の C++ライブラリ
公式では以下のプラットフォームに対応する
 - Windows
 - macOS
 - Linux
 - iOS
 - Android
抽象化されたクラス群とネイティブ APIをCallするク
ラス群とに分離された設計になっている
任意のネイティブAPI層の実装を追加することで、
ユーザーが独自に対応プラットフォームを追加する
ことが可能
Audio programming
オーディオプログラミングに特化したクラス群が用
意されている
(AudioProcessor, Synthesiser, AudioBuffer,
MidiMessage)
各プラットフォームの主要なネイティブオーディオ
APIとMIDI APIをサポートしている
 - Windows: WASAPI/ASIO/DirectSound
 - macOS/iOS: CoreAudio
 - Linux: ALSA/JACK/Bela
 - Android: OpenSL ES/Oboe
ネイティブオーディオ APIの層と信号処理の層が分
離しており、信号処理のコードがプラットフォーム依
存なく実装することができる
Audio plugin development
VSTをはじめ、DAWでサポートされている主要な
プラグインフォーマットをビルドするためのインター
フェース群とプロジェクトテンプレートが用意されて
いる
サポートするプラグインフォーマット
 - VST
 - VST3
 - AudioUnit
 - AudioUnit v3
 - AAX
 - RTAS
 - Unity
GUI library
JUCE独自のGUIライブラリを提供することにより、
GUIをクロスプラットフォームで実装することができ
る
JUCEのGUIシステムに則ったUIコンポーネントを
作成することで、ユーザー独自に GUIを拡張するこ
とが可能
OpenGLをUIコンポーネントに描画するクラスが用
意されているので、OpenGLを用いたリッチUIを実
装することも可能
Useful modules
アプリケーションの各種機能を実装するのに便利なモジュール群が提供されている
・コアモジュール
 juce_core… JUCEライブラリの基礎となるコアモジュール。 Basicなクラス(String, MemoryBlock他)、プラット
フォーム固有のAPIを抽象化するクラス(Thread, Socket他)が含まれる
・その他モジュール(一部)
 juce_audio_formats... WAV, FLAC等のオーディオファイルを Read, Writeする機能を提供
 juce_data_structures… DynamicObjectを実現するValueTreeクラスなど
 juce_cryptography… RSAなどのさまざまな暗号化機能を持つクラスなど
 juce_osc… OSC(Open Sound Control)の送信受信を実装したクラスなど
 juce_video… ビデオ再生、カメラ入力キャプチャをするためのクラスなど
 juce_product_unlocking… オンライン製品認証を実装するクラスなど
 juce_analytics… GoogleAnalytics等に利用情報を収集して送信するクラスなど
Easy to integration
JUCEは、ソースコード形式で提供されていること、
元はC++ライブラリとして開発が始まったことから、
様々なC++ライブラリと組み合わせ易い設計思想
になっている
既にあるソフトウェア資産を利用することで、リッチ
で多機能なソフトウェアを開発することができる
他のC++ライブラリとの組み合わせ例
・juce_meets_link
JUCEにAbleton Linkを組み込むことで、Link対応
のソフトウェアとテンポ同期ができるプログラム
https://github.com/COx2/juce_meets_link
・juce_meets_ndi
JUCEにNDIを組み込むことで、同一 LAN内のオー
ディオプラグイン間で Video/Audioの送受信ができ
るプログラム
https://github.com/COx2/juce_meets_ndi
Made with JUCE
多数の楽器メーカー、オーディオアプリ /プラグイン
ベンダーによる採用実績がある
Maxの開発にJUCEを採用した件についてのインタ
ビュー記事がある。それによると、 Maxのクロスプ
ラットフォーム化、一部の UIの実装にJUCEを利用
しているらしい
https://juce.com/discover/stories/building-max-with-juce
Development
Github上でオープンに開発が行われている
https://github.com/juce-framework/JUCE
ユーザーからIssueやPull Request※を立てることが
できる
※著作権のコンタミを避けるために Pull Requestをmergeしない運用を取っている
新規機能などの開発が行われているブランチは
Closedな場合がある
License
ProprietaryとOSSのデュアルライセンス方式
・JUCE 6 End User License Agreement
 ・使用料: 無料/有料
 ・ユーザーの組織規模, 事業規模によって価格が設定されている
 ・クローズドソースで製品を販売したい用途向け
・GNU GPL v3
 ・使用料: 無料
 ・製品のプログラムはGPLの派生物とみなされる
 ・製品をOSSとして運用したい(しても気にしない)用途向け
Price
Price
無料版では起動時にスプラッシュスクリーンが表
示される
※GPL版ではスプラッシュスクリーンの表示が免
除される
Support
・JUCE Forum
https://forum.juce.com/
・チュートリアル
https://juce.com/learn/tutorials
JUCEとは…
・クロスプラットフォームなC++フレームワーク
・オーディオプログラミングに便利なクラス群とAPI設計
・オーディオプラグイン開発用のテンプレート
・独自のGUIライブラリでクロスプラットフォームなGUIを実現
・多機能なモジュール群
・継続的な開発とサポート
・音楽系ソフトウェアでの採用実績が多数
・(条件を満たせば)無料で使える
JUCEをはじめよう!
JUCEのはじめかた
JUCEをはじめて触る方に向けて、次の点について解説します
・開発環境の構築
・JUCEの入手方法
・Projucerのセットアップ
・DemoRunnerの解説(実演)
・簡単なオーディオアプリケーションの制作(実演)
JUCEのセットアップ
開発環境の準備
・C++コンパイラとIDE
  ・コンパイラ: GCC, Clang, MSVCをサポート
  ・Windows: Visual Studioをインストールする
  ・macOS: Xcodeをインストールする
  ・Linux: 後述
・JUCEライブラリ
・公式サイトからDLまたはGitHubからCloneする
・Projucer
  ・公式サイトからDLした場合... ZIP内に同梱されています
  ・GitHubからCloneした場合... ローカルでビルドしてください
※JUCE 6からCMakeもサポートされましたが、本内容では触れません。
開発環境の準備
・Linux
 Ubuntu 20.04において、以下の依存ライブラリをインストールすることでビルド出来る
ことを確認しています。
$ sudo apt-get update
$ sudo apt-get install make clang g++ freeglut3-dev libasound2-dev libcurl4-openssl-dev libfreetype6-dev libjack-jackd2-dev
libx11-dev libxcomposite-dev libxcursor-dev libxinerama-dev libxrandr-dev mesa-common-dev webkit2gtk-4.0 ladspa-sdk
JUCEを入手しよう
JUCEを入手するだけであれば購入手続き等は不要
JUCEを入手する方法は主に2通りある
 A. 公式サイトからDLする
 B. GitHubリポジトリからCloneする
B.の方法はProjucerをローカルでビルドする必要があるので、
C++に不慣れな方はA.の方法をおすすめします
JUCE 6からCMakeに対応しているので、CIに組み込む場合はB.の方法が便利
A. 公式サイトからDL
https://juce.com/get-juce
Personal欄のDownloadリンクを選択すると、
プラットフォーム別に DLリンクが表示される
B. GitHubからClone
$ git clone https://github.com/juce-framework/JUCE.git
Cloneした後、Projucerをビルドしておきます
JUCE/extras/Projucer 以下にある各IDE用プロ
ジェクトファイルからプロジェクトを開き、ビルドを実
行しましょう
Projucer
各種プラットフォーム IDE用プロジェクトを生成する
プロジェクトジェネレータ
JUCEライブラリとユーザーが実装するプログラム
とをリンクするための設定を自動で行ってくれる
Projucer自身は独自の.jucerフォーマットでプロ
ジェクトを管理する
他のサードパーティライブラリとのリンクのための
設定をProjucerのプロジェクトで設定することが出
来る
Projucerの準備
1. Projucerを起動する
2. [File]→[Global Paths...]メニューをクリックし
て『Global paths』ダイアログを開く
Projucerの準備
3. 『Path to JUCE』欄に、JUCEのルートディレクトリを
入力する
A. 公式サイトからDLした場合はZIPの解凍先ディレ
クトリ
B. git cloneした場合はリポジトリのルートディレクトリ
4. 『JUCE Modules』欄に、JUCEディレクトリの直下に
置かれた『modules』ディレクトリを入力する
JUCE DemoRunner
Projucerのメニューから[File]→[Open Example]→
[Launch Demo Runner]をクリック
A. 公式サイトからDLした場合、ビルド済みの
DemoRunnerバイナリが同梱されているた
め、ビルドをスキップして DemoRunnerが起
動する
B. git cloneした場合、DemoRunnerを新規にビ
ルドする必要がある。 ProjucerからIDEでプ
ロジェクトを開くかどうか尋ねられるので、そ
れにしたがってプロジェクトを開いてビルドを
実行する
JUCE DemoRunner
DemoRunnerの実行ファイルの用意が済んだら、
Projucerの[File]→[Open Example]→[Launch
Demo Runner]からDemoRunnerを起動する
DemoRunnerのブラウジングメニューから様々な
デモプログラムを起動してみよう
各デモプログラムから JUCEライブラリのリファレン
ス実装を確認することができる
JUCEでアプリ制作
JUCEのワークフロー
JUCEでは次の手順でプログラムを作成します
1. [Projucer] 『Application』テンプレートを選択する
2. [Projucer] 対象プラットフォーム設定、モジュール設定を行う
3. [Projucer] プログラムの基礎となるソースコードが自動生成される
4. [IDE] ソースコードを編集する
5. [IDE] プロジェクトをビルドする
実演
Hello sine wave
Hello sine wave
ToneGenerator系オーディオアプリケーション
プロジェクト作成
Projucerのスタート画面で次の項目を設定
・テンプレートの選択『 Application - Audio』
・プロジェクト名の設定 『HelloSineWave』
・対象プラットフォームにチェック
プロジェクト作成
プログラムの基礎となるソースコードが自動生成さ
れる
Main.cpp
=プログラムのエントリポイント
MainComponent.h/cpp
=UIコンポーネントとオーディオ処理の実装が一
体となったクラス
主に実装を追加する関数
・MainComponent::MainComponent
コンストラクタ
メンバ変数やインスタンスの初期化を実装する
・MainComponent::getNextAudioBlock
オーディオデバイスからのコールバックで(定期的に)呼ばれる関数
引数で受け取るオーディオバッファにサンプルデータを書き込むと、オーディオデバイス
側でサンプルデータの再生が行われる
主に実装を追加する関数
・MainComponent::paint
コンポーネント内の描画処理を実行する関数
引数で受け取るグラフィックコンテキストに対して各種命令を呼ぶことで描画処理を組み
込むことができる
・MainComponent::resized
コンポーネントのサイズが変更された時に呼ばれる関数
Parentコンポーネントのサイズが変更されたことをトリガーとしてChildコンポーネントの
サイズと配置座標を決定することでレスポンシブなGUIを実装することができる
サウンドプログラミング
1. オーディオデバイスからオーディオバッファ
が渡される
2. オーディオバッファ( float配列)にサイン波一
周分(360°=2π)の波形サンプルを書き込む
3. オーディオバッファがオーディオデバイスに
返される
4. オーディオデバイスがオーディオバッファに
書き込まれた波形(サイン波)を再生する
上記のうち、1.3.4.の処理はJUCEライブラリによっ
て予め実装されている
サウンドプログラミング
・MainComponent.cpp - getNextAudioBlock関数にサイン波のサンプルをバッファに渡す処理を実装する
void MainComponent::getNextAudioBlock (const juce::AudioSourceChannelInfo& bufferToFill)
{
bufferToFill.clearActiveBufferRegion();
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)
{
const float phase = juce::MathConstants<float>::twoPi * sample / buffer->getNumSamples() * 2;
channelData[sample] = sinf(phase);
}
}
const float gain = 0.5f;
buffer->applyGain(gain);
}
GUIプログラミング - コントローラ
1. juce::Sliderクラス(UIコンポーネント)のイン
スタンス(sliderGain)を生成する
2. sliderGainをMainComponent(アプリケー
ションウインドウのChildコンポーネント)の
Childに追加する
3. juce::Labelクラス(UIコンポーネント)のイン
スタンス(labelGain)を生成する
4. labelGainをsliderGainに関連付けする
5. sliderGainのサイズと配置座標を決める
6. getNextAudioBlock関数内で、オーディオ
バッファに対して、sliderGainの値を用いて
バッファにゲイン量を適用する
GUIプログラミング - コントローラ
・MainComponent.h - MainComponentクラスにjuce::Sliderを保持するメンバ変数を追加する
class MainComponent : public juce::AudioAppComponent
{
~省略~
private:
// juce::Sliderクラスのポインタ変数
std::unique_ptr<juce::Slider> sliderGain;
// juce::Labelクラスのポインタ変数
std::unique_ptr<juce::Label> labelGain;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainComponent)
};
GUIプログラミング - コントローラ
・MainComponent.cpp - コンストラクタでsliderGainのインスタンス生成と各種設定を行う
// コンストラクタの初期化指定子でjuce::Sliderのインスタンスを生成する
MainComponent::MainComponent()
: sliderGain(std::make_unique<juce::Slider>(juce::Slider::RotaryHorizontalVerticalDrag, juce::Slider::TextBoxBelow))
, labelGain(std::make_unique<juce::Label>("Gain", "GAIN"))
{
// ラベルコンポーネントをスライダーに関連付ける
labelGain->attachToComponent(sliderGain.get(), false);
labelGain->setJustificationType(juce::Justification::centred);
// スライダーの値の範囲を0.0 ~ 1.0に設定する
sliderGain->setRange(0.0, 1.0);
// sliderGainをMainComponentのChildに追加する
addAndMakeVisible(sliderGain.get());
~省略~
}
GUIプログラミング - コントローラ
・MainComponent.cpp - resized関数にコンポーネントのサイズ指定と配置座標の指定を実装する
void MainComponent::resized()
{
// MainComponentの中心座標を取得する
const auto panelCenter = getBounds().getCentre();
// gainSliderのサイズを幅200px, 高さ200pxにする
sliderGain->setSize(200, 200);
// gainSliderの中心座標をMainComponentの中心座標に移動する
sliderGain->setCentrePosition(panelCenter);
}
GUIプログラミング - コントローラ
・MainComponent.cpp - getNextAudioBlock関数にバッファ全体のゲイン変更処理を実装する
void MainComponent::getNextAudioBlock (const juce::AudioSourceChannelInfo& bufferToFill)
{
bufferToFill.clearActiveBufferRegion();
auto* buffer = bufferToFill.buffer;
for (int channel = 0; channel < buffer->getNumChannels(); ++channel)
{
~省略~
}
// バッファ全体のサンプルにゲイン量を適用する(乗算処理)
const float gain = sliderGain->getValue();
bufferToFill.buffer->applyGain(gain);
}
GUIプログラミング - ビジュアライザ
1. オーディオサンプルデータを貯めておくメン
バ変数を追加する
2. MainComponent::paint関数に、サンプル
データからPathを生成して描画する処理を
追加する
3. MainComponentクラスにjuce::Timerクラス
を継承させる
4. juce::Timer::TimerCallback関数をoverride
して関数内でpaint関数のトリガーを実装す
る
5. juce::Timerクラスのタイマーを開始する関数
を呼ぶ
※時間の都合上、簡易的な設計となっています。よりよい設
計は完成版のコードをご確認ください。
GUIプログラミング - ビジュアライザ
・MainComponent.h - MainComponentクラスにオーディオバッファを保持するメンバ変数を追加する
class MainComponent : public juce::AudioAppComponent
{
~省略~
private:
// juce::AudioBufferはfloat配列を保持するオブジェクトとして有効に利用できる
juce::AudioBuffer<float> drawBuffer;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainComponent)
};
GUIプログラミング - ビジュアライザ
・MainComponent.cpp - getNextAudioBlock関数内でサンプルデータをメンバ変数にコピーする
void MainComponent::getNextAudioBlock (const juce::AudioSourceChannelInfo& bufferToFill)
{
bufferToFill.clearActiveBufferRegion();
auto* buffer = bufferToFill.buffer;
for (int channel = 0; channel < buffer->getNumChannels(); ++channel)
{
~省略~
}
const float gain = 0.5f;
buffer->applyGain(gain);
// オーディオバッファ内のサンプルデータをメンバ変数にコピーする
drawBuffer.makeCopyOf(*bufferToFill.buffer);
}
GUIプログラミング - ビジュアライザ
・MainComponent.cpp - サンプルデータから波形パスを生成してパスを描画する関数を追加する
void drawWaveShape(juce::Graphics& g, const juce::Rectangle<float>& drawArea, const float* plotData, const int
numSamples)
{
juce::Path wavePath;
const float x0 = drawArea.getX();
const float cloped_sample0 = juce::jmax<float>(-1.0f, juce::jmin<float>(1.0f, plotData[0]));
const float y0 = juce::jmap<float>(cloped_sample0, -1.0f, 1.0f, drawArea.getBottom(), drawArea.getY());
wavePath.startNewSubPath(x0, y0);
for (int i = 1; i < numSamples; ++i)
{
const float x = juce::jmap<float>(i, 0, numSamples, x0, x0 + drawArea.getWidth());
const float cloped_sample = juce::jmax<float>(-1.0f, juce::jmin<float>(1.0f, plotData[i]));
const float y = juce::jmap<float>(cloped_sample, -1.0f, 1.0f, drawArea.getBottom(), drawArea.getY());
wavePath.lineTo(x, y);
}
g.setColour(juce::Colours::cyan);
g.strokePath(wavePath, juce::PathStrokeType(2.0f));
}
GUIプログラミング - ビジュアライザ
・MainComponent.cpp - paint関数からdrawWaveShape関数を呼んで波形パスを描画する
void MainComponent::paint (juce::Graphics& g)
{
g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId));
const auto bounds = getLocalBounds();
// Draw wave shape background
const juce::Rectangle<float> drawArea = { bounds.getWidth() * 0.1f, bounds.getHeight() * 0.75f,
bounds.getWidth() * 0.8f, bounds.getHeight() * 0.2f };
g.setColour(juce::Colours::darkgrey);
g.fillRect(drawArea);
// Draw wave shape
drawWaveShape(g, drawArea, drawBuffer.getReadPointer(0), drawBuffer.getNumSamples());
}
GUIプログラミング - ビジュアライザ
・MainComponent.h - juce::Timerクラスを継承して仮想関数を overrideする
class MainComponent : public juce::AudioAppComponent, public juce::Timer
{
~省略~
private:
// juce::Timerで宣言されている仮想関数を overrideする
virtual void timerCallback() override;
// juce::AudioBufferはfloat配列を保持するオブジェクトとして有効に利用できる
juce::AudioBuffer<float> drawBuffer;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainComponent)
};
GUIプログラミング - ビジュアライザ
・MainComponent.cpp - timerCallback関数の実装とstartTimerHz関数の実行を追加する
MainComponent::MainComponent()
: sliderGain(std::make_unique<juce::Slider>(juce::Slider::RotaryHorizontalVerticalDrag, juce::Slider::TextBoxBelow))
{
~省略~
// juce::Timerクラス内のタイマーを起動する
// 30Hz間隔でtimerCallback関数が呼ばれるようになる
startTimerHz(30);
}
void MainComponent::timerCallback()
{
// MainComponent::paint関数を呼び出すためのトリガー
repaint();
}
動作確認
完成版
以下の機能を追加
・オシレータ(Square/Saw/Triangle/Noise)
・周波数を変更するスライダー
・オシレータを選択するコンボボックス
・操作パラメータを示すラベル UI
・オシロスコープのトリガ機能
※ソースコード
https://github.com/COx2/amcj009-juce-study/tree/main/HelloSineWave
Building for mobile
モバイルプラットフォームでも動きます
FAQ
オーディオバッファに音声を渡してるのに音が出ない
症状として、JUCEアプリケーションにおけるオーディオの出力先のデバイスが設定され
ていない可能性があります。特に端末によってオーディオデバイスにバラツキがあるプ
ラットフォームで発生しやすいです(Windows, Linux)
特にプロジェクトを新規作成したときなどは、オーディオデバイスの設定が存在しないせ
いで、出力自体が無効化されているケースに遭遇することがあります
次の記事に、上記の対策としてJUCEアプリケーションでのオーディオデバイス設定パネ
ルを表示するためのコードスニペットを示しています
https://qiita.com/COx2/items/c9e87059d349aa8ff707
オーディオバッファに音声を渡してるのに音が出ない
・MainComponent.cpp - オーディオデバイス設定パネルを表示するコードスニペット
void showDeviceSetting()
{
AudioDeviceSelectorComponent selector(deviceManager, 0, 256, 0, 256, true, true, true, false);
selector.setSize(400, 600);
DialogWindow::LaunchOptions dialog;
dialog.content.setNonOwned(&selector);
dialog.dialogTitle = "Audio/MIDI Device Settings";
dialog.componentToCentreAround = this;
dialog.dialogBackgroundColour = getLookAndFeel().findColour(ResizableWindow::backgroundColourId);
dialog.escapeKeyTriggersCloseButton = true;
dialog.useNativeTitleBar = false;
dialog.resizable = false;
dialog.useBottomRightCornerResizer = false;
dialog.runModal();
}
MainComponent::MainComponent()
{
showDeviceSetting();
}
日本語のテキストが文字化けする
次の記事に、JUCEで日本語表示をするためのコードスニペットを示しています
https://qiita.com/COx2/items/c9e87059d349aa8ff707
MainComponent::MainComponent()
{
#if JUCE_WINDOWS
String typeFaceName = "Meiryo UI";
Desktop::getInstance().getDefaultLookAndFeel().setDefaultSansSerifTypefaceName(typeFaceName);
#elif JUCE_MAC
String typeFaceName = "Arial Unicode MS";
Desktop::getInstance().getDefaultLookAndFeel().setDefaultSansSerifTypefaceName(typeFaceName);
#elif JUCE_LINUX
String typeFaceName = "IPAGothic";
Desktop::getInstance().getDefaultLookAndFeel().setDefaultSansSerifTypefaceName(typeFaceName);
#endif
}
Q&A
JUCEでオーディオプラグイン開発入門
JUCEでオーディオプラグインを作る手順
1. [Projucer] 『Plug-In』テンプレートを選択する
2. [Projucer] 対象プラットフォーム設定、モジュール設定を行う
3. [Projucer] プログラムの基本となるソースコードが自動生成される
4. [IDE] ソースコードを編集する
5. [IDE] プロジェクトをビルドする
アプリケーション開発と同様のワークフローで作成することが出来る
実演
Hello audio plugin
Hello audio plugin
ToneGenerator系オーディオプラグイン
プロジェクト作成
Projucerのスタート画面で次の項目を設定
・テンプレートの選択『 Plug-In - Basic』
・プロジェクト名の設定 『HelloAudioPlugin』
・対象プラットフォームにチェック
プロジェクト作成
プログラムの基礎となるソースコードが自動生成さ
れる
PluginProcessor.h/cpp
=プラグインインターフェースと音声処理を実装す
る。Processorと呼ばれる
PluginEditor.h/cpp
=プラグインウインドウに表示する GUIを実装す
る。Editorと呼ばれる
プロジェクト作成
・ProcessorとEditor
VSTをはじめとするオーディオプラグインフォーマッ
トでは、先に説明した ProcessorとEditorと呼ばれ
る2つのコンポーネントを使用するアーキテクチャ
であることが多いです
Processorの実装は必須な一方で、プラグイン
フォーマットによっては Editorの実装は任意な場合
があります
プロジェクト作成
歯車アイコンをクリックするとプロジェクト設が表示
される
対象プラグインフォーマットにチェック
- VST3
- AudioUnit
- Standalone
- Unity
※一部のプラグインフォーマットをビルドするには
別途SDKを用意する必要があります
Processorの実装
プラグイン特有の実装として、プラグインパラメータ
をProcessorに持たせる
juce::AudioProcessorValueTreeStateクラス(通称
APVTS)を用いてプラグインパラメータを実装する
のがモダンで安全
一つのAPVTSで複数のプラグインパラメータの状
態を管理することができる
APVTSを用いると、GUIのコンポーネントとの連携
を短いコードで実装することができる
信号処理のコードは HelloSineWaveの実装をほぼ
そのまま移植する
※プラグインパラメータ = プラグインインターフェー
スを介してホスト⇔プラグイン間で Get/Setすること
ができる状態管理用の変数
Processorの実装
・PluginProcessor.h - ProcessorクラスのメンバにAPVTS変数とその参照を取得する関数を追加する
class HelloAudioPluginAudioProcessor : public juce::AudioProcessor
{
~省略~
// EditorクラスからAPVTSを参照できるように関数を追加する
juce::AudioProcessorValueTreeState& getProcessorState() { return apvts; }
private:
// juce::AudioProcessorValueTreeStateクラスの変数を追加する
juce::AudioProcessorValueTreeState apvts;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainComponent)
};
Processorの実装
・PluginProcessor.cpp - Processorクラスのコンストラクタに APVTSの初期化処理を追加する
// APVTSに持たせるプラグインパラメータのリストを返す関数を追加
juce::AudioProcessorValueTreeState::ParameterLayout createParameterLayout()
{
juce::AudioProcessorValueTreeState::ParameterLayout layout;
layout.add(std::make_unique<juce::AudioParameterFloat>
("Gain", "Gain", juce::NormalisableRange<float>{ 0.0f, 1.0f, 0.01f }, 0.5f));
return layout;
}
// コンストラクタにAPVTSの初期化処理を追加
HelloAudioPluginAudioProcessor::HelloAudioPluginAudioProcessor()
~省略~
, apvts(*this, nullptr, "PARAMETERS", createParameterLayout())
{
};
Processorの実装
・PluginProcessor.cpp - processBlock関数にオーディオバッファの操作処理を実装する
void HelloAudioPluginAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, juce::MidiBuffer& midiMessages)
{
~省略~
for (int channel = 0; channel < buffer.getNumChannels(); ++channel)
{
float* channelData = buffer.getWritePointer(channel);
for (int sample = 0; sample < buffer.getNumSamples(); ++sample)
{
const float phase = juce::MathConstants<float>::twoPi * sample / buffer.getNumSamples() * 2;
channelData[sample] = sinf(phase);
}
}
// パラメータの値をAPVTSのインターフェースから取得すると0.0~1.0の範囲にNormalizedされている
// ここでは、パラメータが保持するjuce::RangeのconvertFrom0to1関数を用いてRangedな値に戻す
const auto* gain_param = apvts.getParameter("Gain");
const float gain = gain_param->getNormalisableRange().convertFrom0to1(gain_param->getValue());
buffer.applyGain(gain);
}
Editorの実装
Processorで実装したAPVTS内のパラメータと
juce::Slider(sliderGain)を連携するコードを追加
する
juce::AudioProcessorValueTreeState::Slider
Attachmentを利用すると、Sliderとプラグインパラ
メータをバインドすることができ、 Sliderとパラメータ
の値の同期処理を短いコードで実装することがで
きる
HelloSineWaveで実装したGUI関連のコードを
Editorに移植する
Editorの実装
・PluginEditor.h - Editorのクラスにjuce::Sliderを保持するメンバ変数を追加する
class HelloAudioPluginAudioProcessorEditor : public juce::AudioProcessorEditor
{
~省略~
private:
// Processorクラスの参照を保持する変数(自動生成)
HelloAudioPluginAudioProcessor& audioProcessor;
// juce::Sliderクラスのポインタ変数
std::unique_ptr<juce::Slider> sliderGain;
// juce::Sliderとプラグインパラメータを自動的に連携してくれるオブジェクト
juce::OwnedArray<juce::AudioProcessorValueTreeState::SliderAttachment> sliderAttachments;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (HelloAudioPluginAudioProcessorEditor)
};
Editorの実装
・PluginEditor.cpp - コンストラクタでsliderGainのインスタンス生成と各種設定を行う
// コンストラクタの初期化指定子でjuce::Sliderのインスタンスを生成する
HelloAudioPluginAudioProcessorEditor::HelloAudioPluginAudioProcessorEditor (HelloAudioPluginAudioProcessor& p)
: AudioProcessorEditor (&p), audioProcessor (p)
, sliderGain(std::make_unique<juce::Slider>(juce::Slider::RotaryHorizontalVerticalDrag, juce::Slider::TextBoxBelow))
{
// APVTS内の”Gain”パラメータとsliderGainとをバインディングする
sliderAttachments.add(std::make_unique<juce::AudioProcessorValueTreeState::SliderAttachment>
(audioProcessor.getProcessorState(), "Gain", *sliderGain));
// sliderGainをこのComponentのChildに追加する
addAndMakeVisible(sliderGain.get());
setSize (400, 300);
}
動作確認
オーディオプラグインの動作確認
プラグインのインストール先
・macOS
 ・AudioUnit
  ・System
    /Library/Audio/Plug-Ins/Components
  ・User    
    ~/(UserName)/Library/Audio/Plug-Ins/Components
 ・VST3
  ・System
    /Library/Audio/Plug-Ins/VST3
  ・User
    ~/(UserName)/Library/Audio/Plug-Ins/VST3
オーディオプラグインの動作確認
プラグインのインストール先
・macOS
 ・VST
  ・System
    /Library/Audio/Plug-Ins/VST
  ・User
    ~/(UserName)/Library/Audio/Plug-Ins/VST
・Windows
 ・VST3
   C:Program FilesCommon FilesVST3
 ・VST
   任意の場所にインストール可能
オーディオプラグインの動作確認
Juce Plug-in Host
JUCEのプラグインホスト機構を利用した軽量なホ
ストアプリケーション
プラグインをノードとして扱い、ノードベースな入出
力接続を行うことができる
場所: JUCE/extras/AudioPluginHost
オーディオプラグインの動作確認
Unity Native Audio Pluginのホスティングについて
は次の記事にまとめています
https://qiita.com/COx2/items/8d2c1441c6e9e00
910c6
完成版
HelloSineWave同様の機能を追加
・パラメータを追加(Frequency/Oscillator)
・オシレータ(Square/Saw/Triangle/Noise)
・周波数を変更するスライダー
・オシレータを選択するコンボボックス
・操作パラメータを示すラベル UI
・オシロスコープのトリガ機能
※ソースコード
https://github.com/COx2/amcj009-juce-study/tree/main/HelloAudioPlugin
FAQ
入力信号にEffectを適用して出力したい
processBlock関数の引数にはミキサー上の入力信号が入っており、その値を取得して変更を適用することで出
力信号が変化する。例えば、サンプルデータの値を取得し、閾値の範囲内に収めるクリップ処理を行ったものを
オーディオバッファに代入すると、簡易的なリミッターを実装することができる
void LimiterAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, juce::MidiBuffer& midiMessages)
{
~省略~
for (int channel = 0; channel < buffer.getNumChannels(); ++channel)
{
float* channelData = buffer.getWritePointer(channel);
for (int sample = 0; sample < buffer.getNumSamples(); ++sample)
{
if(channelData[sample] > 0.7f)
channelData[sample] = 0.7f;
else if(channelData[sample] < -0.7f)
channelData[sample] = -0.7f;
}
}
~省略~
}
EffectとInstrument
プラグイン仕様によってはEffectとInstrumentの2種類の
属性がある
e.g. VST Effect / VST Instrument
Effectプラグイン
= DAWのEffect Rackにインサートするもの
Instrumentプラグイン
= DAWのInstrument Rackにインサートするもの
Projucerのプロジェクト設定内の[Plugin
Characteristics]→[Plugin is a Synth]項目で選択
・チェック有り = Instrument
・チェック無し = Effect
MIDI入出力のサポート
プラグイン仕様によってはMIDI入出力をサポートする。
特にシンセサイザー系のInstrumentプラグインではMIDI
入力のサポートはほぼ必須
Projucerのプロジェクト設定内の[Plugin
Characteristics]で設定を選択
・Plugin MIDI Input = MIDI入力をサポート
・Plugin MIDI Output = MIDI出力をサポート
MIDI出力をサポートするプラグインをDAWにインサート
すると、プラグインからのMIDI出力ポートをトラックの
MIDI入力にルーティングすることができる※
※DAWの実装に依存する
パラメータ状態を保存/復帰したい
・PluginProcessor.cpp - 次の関数の実装を追加します。これらの関数はDAWがプロ
ジェクトをSave/Loadするタイミングで呼ばれます
void XxxAudioProcessor::getStateInformation()
= パラメータ状態を外部ファイル(DAWプロジェクト)にセーブする関数
void XxxAudioProcessor::setStateInformation()
= パラメータ状態を外部ファイル(DAWプロジェクト)からロードする関数
プラグイン開発時の注意点
・ProcessorからEditorのインスタンスに直接アクセスすることは避ける
オーディオプラグインでは、Processorの寿命とEditorの寿命が異なる場合が多いです。具体
的には、Editorはウインドウが表示⇔非表示するびにインスタンスの生成⇔消去が内部で行
われています
この点に注意して実装しないと、Editorのインスタンスが先に消失したにも関わらず
ProcessorがEditorにアクセスしようとしてクラッシュを引き起こす原因になります
・プラグインがクラッシュするとDAW本体も道連れにされてクラッシュするので、自作プラグイ
ンを使用して制作するときはこまめに保存するようにしましょう
※Bitwig Studioはサンドボックス方式を採用しているので DAWを道連れにしないらしい
JUCEで広がるオーディオソフトウェア開発
Tracktion Engine
JUCEライブラリで構築された、 DAWの開発に特化
したフレームワーク
Tracktion WAVEFORMのシーケンサーエンジンと
して開発されたフレームワークがオープン化されて
利用できるようになった
無償/有償プランがある
https://www.tracktion.com/develop/tracktion-engi
ne
https://github.com/Tracktion/tracktion_engine
SOUL
JUCEを開発したJulian Storerがリードする、音声
処理プログラムを作成することに特化したプログラ
ミング言語
SOUL = SOUnd Language
SOUL言語のランタイムライブラリをアプリケーショ
ンに組み込むための JUCE用ライブラリが提供され
ている
https://github.com/soul-lang/SOUL
https://soul.dev/
Made with JUCE
Ben Kuper / Chataigne
メディアアーティスト向けに制作された、モジュラー
ベースのインタラクティブ・システム開発ツール
通信プロトコルのサポート
OSC, MIDI, DMX, HTTP, WebSockets, PJLink…
ハードウェアのサポート
KinectV2, StreamDeck, Gamepad, Wiimote…
ソフトウェア外部コントロールのサポート
Madmapper, Reaper, Resolume, Powerpoint...
http://benjamin.kuperberg.fr/chataigne
https://github.com/benkuper/Chataigne
FigBug / slPlugins
シンプルなUIと機能だけを持つ、無料配布のプラ
グイン・スイート
ToneGenerator, Oscilloscope, ABTestなど、プラ
グイン開発時のテストツールとして重宝
プロジェクトの規模も小さいので JUCEの学習用途
にも向いている
同じ開発者のGinという3rd party JUCEモジュール
にも便利な機能が沢山
https://socalabs.com/
https://github.com/FigBug/slPlugins
ffAudio / PluginGuiMagic
JUCE GUIコンポーネントにリッチ UIとライブ編集
機能を提供するJUCE用ライブラリ
オーディオプロセッサのパラメータからデフォルトの
GUIを自動生成
CSSライクな構造でスタイル化
ドラッグ&ドロップによるレイアウト操作
FFTアナライザーやオシロスコープなど、すぐに使
えるビジュアライザー
https://github.com/ffAudio/PluginGuiMagic
Dreamtonics / Web Synthesizer V
JUCE製プログラムをWASMで実行できるようにす
るプロジェクト
Emscriptenの対応と、Native層にWebプラット
フォームのAPI(OpenAL, Web MIDI等)を組み込む
ことで、Webブラウザ上でもJUCE製アプリケーショ
ンを動かすことを実現した
https://synthesizerv.com/web
https://github.com/Dreamtonics/juce_emscripten
https://github.com/beschulz/juce_emscripten
まだまだあります
hotwatermorning / wahwth
https://github.com/hotwatermorning/wahwth
yokemura / Magical8bitPlug2
https://github.com/yokemura/Magical8bitPlug2
m-masaki72 / SANA_8BIT_VST
https://github.com/m-masaki72/SANA_8BIT_VS
T
chikashimiyama / trevor
https://github.com/chikashimiyama/trevor
GuitarML / SmartGuitarPedal
https://github.com/GuitarML/SmartGuitarPedal
balandinodidonato /MyoMapper
https://github.com/balandinodidonato/MyoMapp
er
jatinchowdhury18 / KlonCentaur
https://github.com/jatinchowdhury18/KlonCentau
r
AustrianAudio / PolarDesigner
https://github.com/AustrianAudio/PolarDesigner
Audio Developer Conferenceへのお誘い
Audio Developer Conference
https://audio.dev/
通称ADC
音楽アプリケーションに興味のある世界各地の開発者がロンドンに集まる
DAW、プラグイン、フレームワーク、プラットフォームの開発者が対象
他のイベントとの違い…
・NAMM - 楽器の展示が中心
・GDC - ゲーム全般 オーディオに関連する話題もある
歴史的な経緯もあってJUCEの話題が多い印象
Audio Developer Conference
ADC is an annual event celebrating all audio development technologies, from
music applications and game audio to audio processing and embedded systems.
ADC’s mission is to help attendees acquire and develop new skills, and build a
network that will support their career development. It is also aimed at showcasing
academic research and facilitating collaborations between research and industry.
- cited from https://audio.dev/
ADCの歴史
2015年: JUCE Summit 2015
2016年: Audio Developer Conference 2016
2017年: Audio Developer Conference 2017
2018年: Audio Developer Conference 2018
2019年: Audio Developer Conference 2019
2020年: Audio Developer Conference 2020
ADCで何が見られるの?
ハンズオン
セッション
ライブパフォーマンス
ブース展示
Drinkup, Open Mic Night (LT大会)
ハンズオン
JUCEオーディオプラグイン作成入門
ELKハードウェアシンセサイザー作成
信号処理
SOUL (SOUnd Language)
深層学習 + Speech Synthesis
JUCE + ReactNative
1 on 1 セッション
・Appleオーディオオフィスアワー
・Androidスタジオセッション
セッション
ADC2018
・SOUL
・AudioKit
・WebAudio (Europa, WAMs)
・C++ std::audio (draft)
・Speech Synthesis
・MPE
・Audio debugging
ADC2019
・MIDI 2.0
・Deep Learning
・リアルタイムオーディオ処理
・デザイン & プロトタイピング
・ゲームオーディオ
・JUCE + React Native
ADC2019 - Live concert (using MI.MU)
Reshaping live performance with MI.MU
ADC2019 - JUCE x React Native x Unity
Developing a rich, consumer experience for
LUMI with JUCE, React Native & Unity
ADC2019 - How to make a multi-track loop sequencer with JUCE
Loopers and bloopers
JUCE Youtubeチャンネル
ADCのセッション動画がアーカイブされている
https://www.youtube.com/channel/UCaF6fKdDrSmPDmi
Zcl9KLnQ
Audio Developer Conference 2020
・オンライン開催
・日時
 11月19-20日 25:00〜31:00 JST
・セッション一覧
 https://audio.dev/schedule
・チケット
 オンライン販売
 価格は例年の1/10
https://audio.dev/news/adc-tickets
Opening keynoteはMax for Live開発にまつわる話
JUCE関連のセッション
Q&A
宣伝
JUCE JAPAN
シリーズ最新『JUCE JAPAN 2018』
・JUCEハンズオン
・シンセサイザーの設計と実装
・ワンショットサンプラーを作ろう
・VAシンセサイザーを作ろう
Amazon Kindleにて販売中
https://www.amazon.co.jp/dp/B07HQHFKX9
JUCEもくもく会
https://juce.connpass.com/
不定期で開催
主な会場は都内コワーキングスペース
遠征開催を計画中
JUCE Advent Calendar 2020
https://qiita.com/advent-calendar/2020/juce
絶賛参加者募集中!!!
END
TEMPLATE: Azusa 3
VERSION 3.0 CREATED AND MAINTAINED BY @SANOGRAPHIX
JUCE は英国 Raw Material Software, Ltd.の登録商標です
VST は独国 Steinberg Media Technologies GmbH の登録商標です
Audio Units は米国Apple Computers Inc. の登録商標です
Unity は米国およびその他の地域でのUnity Technologies またはその関連会社の商標または登録商標です

Más contenido relacionado

La actualidad más candente

Unity dojo amplifyshadereditor101_jpn-jp
Unity dojo amplifyshadereditor101_jpn-jpUnity dojo amplifyshadereditor101_jpn-jp
Unity dojo amplifyshadereditor101_jpn-jp小林 信行
 
xR Developerなら知っておきたいカメラの基礎知識
xR Developerなら知っておきたいカメラの基礎知識xR Developerなら知っておきたいカメラの基礎知識
xR Developerなら知っておきたいカメラの基礎知識Satoshi Maemoto
 
C++ マルチスレッドプログラミング
C++ マルチスレッドプログラミングC++ マルチスレッドプログラミング
C++ マルチスレッドプログラミングKohsuke Yuasa
 
【Unite Tokyo 2018】カスタムシェーダーでモバイルでも最先端グラフィックスな格闘ゲームを!
【Unite Tokyo 2018】カスタムシェーダーでモバイルでも最先端グラフィックスな格闘ゲームを!【Unite Tokyo 2018】カスタムシェーダーでモバイルでも最先端グラフィックスな格闘ゲームを!
【Unite Tokyo 2018】カスタムシェーダーでモバイルでも最先端グラフィックスな格闘ゲームを!UnityTechnologiesJapan002
 
ARM LinuxのMMUはわかりにくい
ARM LinuxのMMUはわかりにくいARM LinuxのMMUはわかりにくい
ARM LinuxのMMUはわかりにくいwata2ki
 
【CEDEC2018】一歩先のUnityでのパフォーマンス/メモリ計測、デバッグ術
【CEDEC2018】一歩先のUnityでのパフォーマンス/メモリ計測、デバッグ術【CEDEC2018】一歩先のUnityでのパフォーマンス/メモリ計測、デバッグ術
【CEDEC2018】一歩先のUnityでのパフォーマンス/メモリ計測、デバッグ術Unity Technologies Japan K.K.
 
Unityでパフォーマンスの良いUIを作る為のTips
Unityでパフォーマンスの良いUIを作る為のTipsUnityでパフォーマンスの良いUIを作る為のTips
Unityでパフォーマンスの良いUIを作る為のTipsUnity Technologies Japan K.K.
 
【Unite 2017 Tokyo】最適化をする前に覚えておきたい技術
【Unite 2017 Tokyo】最適化をする前に覚えておきたい技術【Unite 2017 Tokyo】最適化をする前に覚えておきたい技術
【Unite 2017 Tokyo】最適化をする前に覚えておきたい技術Unity Technologies Japan K.K.
 
クリエイティブワークを支えるHelix Core
クリエイティブワークを支えるHelix Coreクリエイティブワークを支えるHelix Core
クリエイティブワークを支えるHelix CoreSatoshi OKAWARA
 
Redmineとgitの 連携利用事例
Redmineとgitの 連携利用事例Redmineとgitの 連携利用事例
Redmineとgitの 連携利用事例Tomohisa Kusukawa
 
ARM Trusted FirmwareのBL31を単体で使う!
ARM Trusted FirmwareのBL31を単体で使う!ARM Trusted FirmwareのBL31を単体で使う!
ARM Trusted FirmwareのBL31を単体で使う!Mr. Vengineer
 
Android™組込み開発基礎コース BeagleBoard編
Android™組込み開発基礎コース BeagleBoard編Android™組込み開発基礎コース BeagleBoard編
Android™組込み開発基礎コース BeagleBoard編OESF Education
 
[UE4]マテリアルの注意すべきこと!~テクスチャロードとSwitch~
[UE4]マテリアルの注意すべきこと!~テクスチャロードとSwitch~[UE4]マテリアルの注意すべきこと!~テクスチャロードとSwitch~
[UE4]マテリアルの注意すべきこと!~テクスチャロードとSwitch~com044
 
Try new transport protocol SRT (ver. 2)
Try new transport protocol SRT  (ver. 2)Try new transport protocol SRT  (ver. 2)
Try new transport protocol SRT (ver. 2)Tetsuyuki Kobayashi
 
Nginx Unitを試してみた話
Nginx Unitを試してみた話Nginx Unitを試してみた話
Nginx Unitを試してみた話Takehiro Torigaki
 

La actualidad más candente (20)

Unity dojo amplifyshadereditor101_jpn-jp
Unity dojo amplifyshadereditor101_jpn-jpUnity dojo amplifyshadereditor101_jpn-jp
Unity dojo amplifyshadereditor101_jpn-jp
 
xR Developerなら知っておきたいカメラの基礎知識
xR Developerなら知っておきたいカメラの基礎知識xR Developerなら知っておきたいカメラの基礎知識
xR Developerなら知っておきたいカメラの基礎知識
 
C++ マルチスレッドプログラミング
C++ マルチスレッドプログラミングC++ マルチスレッドプログラミング
C++ マルチスレッドプログラミング
 
【Unite Tokyo 2018】カスタムシェーダーでモバイルでも最先端グラフィックスな格闘ゲームを!
【Unite Tokyo 2018】カスタムシェーダーでモバイルでも最先端グラフィックスな格闘ゲームを!【Unite Tokyo 2018】カスタムシェーダーでモバイルでも最先端グラフィックスな格闘ゲームを!
【Unite Tokyo 2018】カスタムシェーダーでモバイルでも最先端グラフィックスな格闘ゲームを!
 
ARM LinuxのMMUはわかりにくい
ARM LinuxのMMUはわかりにくいARM LinuxのMMUはわかりにくい
ARM LinuxのMMUはわかりにくい
 
【CEDEC2018】一歩先のUnityでのパフォーマンス/メモリ計測、デバッグ術
【CEDEC2018】一歩先のUnityでのパフォーマンス/メモリ計測、デバッグ術【CEDEC2018】一歩先のUnityでのパフォーマンス/メモリ計測、デバッグ術
【CEDEC2018】一歩先のUnityでのパフォーマンス/メモリ計測、デバッグ術
 
Unityでパフォーマンスの良いUIを作る為のTips
Unityでパフォーマンスの良いUIを作る為のTipsUnityでパフォーマンスの良いUIを作る為のTips
Unityでパフォーマンスの良いUIを作る為のTips
 
バイキング流UE4活用術 ~BPとお別れするまでの18ヶ月~
バイキング流UE4活用術 ~BPとお別れするまでの18ヶ月~バイキング流UE4活用術 ~BPとお別れするまでの18ヶ月~
バイキング流UE4活用術 ~BPとお別れするまでの18ヶ月~
 
【Unite 2017 Tokyo】最適化をする前に覚えておきたい技術
【Unite 2017 Tokyo】最適化をする前に覚えておきたい技術【Unite 2017 Tokyo】最適化をする前に覚えておきたい技術
【Unite 2017 Tokyo】最適化をする前に覚えておきたい技術
 
レシピの作り方入門
レシピの作り方入門レシピの作り方入門
レシピの作り方入門
 
クリエイティブワークを支えるHelix Core
クリエイティブワークを支えるHelix Coreクリエイティブワークを支えるHelix Core
クリエイティブワークを支えるHelix Core
 
Redmineとgitの 連携利用事例
Redmineとgitの 連携利用事例Redmineとgitの 連携利用事例
Redmineとgitの 連携利用事例
 
ARM Trusted FirmwareのBL31を単体で使う!
ARM Trusted FirmwareのBL31を単体で使う!ARM Trusted FirmwareのBL31を単体で使う!
ARM Trusted FirmwareのBL31を単体で使う!
 
Android™組込み開発基礎コース BeagleBoard編
Android™組込み開発基礎コース BeagleBoard編Android™組込み開発基礎コース BeagleBoard編
Android™組込み開発基礎コース BeagleBoard編
 
UE4 Performance and Profiling | Unreal Dev Day Montreal 2017 (日本語訳)
UE4 Performance and Profiling | Unreal Dev Day Montreal 2017 (日本語訳)UE4 Performance and Profiling | Unreal Dev Day Montreal 2017 (日本語訳)
UE4 Performance and Profiling | Unreal Dev Day Montreal 2017 (日本語訳)
 
UE4における大規模背景制作事例 描画特殊表現編
UE4における大規模背景制作事例 描画特殊表現編UE4における大規模背景制作事例 描画特殊表現編
UE4における大規模背景制作事例 描画特殊表現編
 
[UE4]マテリアルの注意すべきこと!~テクスチャロードとSwitch~
[UE4]マテリアルの注意すべきこと!~テクスチャロードとSwitch~[UE4]マテリアルの注意すべきこと!~テクスチャロードとSwitch~
[UE4]マテリアルの注意すべきこと!~テクスチャロードとSwitch~
 
Try new transport protocol SRT (ver. 2)
Try new transport protocol SRT  (ver. 2)Try new transport protocol SRT  (ver. 2)
Try new transport protocol SRT (ver. 2)
 
Nginx Unitを試してみた話
Nginx Unitを試してみた話Nginx Unitを試してみた話
Nginx Unitを試してみた話
 
Photonのサービス選択の勘どころ
Photonのサービス選択の勘どころPhotonのサービス選択の勘どころ
Photonのサービス選択の勘どころ
 

Similar a JUCEハンズオン@Ableton and Max Community Japan #009

Osc2012 appinventor のその後
Osc2012 appinventor のその後Osc2012 appinventor のその後
Osc2012 appinventor のその後Katsumi Honda
 
Code igniterでテスト駆動開発 資料作成中
Code igniterでテスト駆動開発 資料作成中Code igniterでテスト駆動開発 資料作成中
Code igniterでテスト駆動開発 資料作成中Takako Miyagawa
 
Eclipse PDT + MakeGoodによるPHPコードのテスト
Eclipse PDT + MakeGoodによるPHPコードのテストEclipse PDT + MakeGoodによるPHPコードのテスト
Eclipse PDT + MakeGoodによるPHPコードのテストAtsuhiro Kubo
 
JUCEではじめるBLOCKS開発_TOKYO BLOCKS HACKATHON 2018
JUCEではじめるBLOCKS開発_TOKYO BLOCKS HACKATHON 2018JUCEではじめるBLOCKS開発_TOKYO BLOCKS HACKATHON 2018
JUCEではじめるBLOCKS開発_TOKYO BLOCKS HACKATHON 2018Tatsuya Shiozawa
 
Audio Unit Extensions 〜オーディオエフェクトのアプリ間共有〜
Audio Unit Extensions 〜オーディオエフェクトのアプリ間共有〜Audio Unit Extensions 〜オーディオエフェクトのアプリ間共有〜
Audio Unit Extensions 〜オーディオエフェクトのアプリ間共有〜Shuichi Tsutsumi
 
スマホキャンプサマー2012:ANEとアプリ内課金に挑戦
スマホキャンプサマー2012:ANEとアプリ内課金に挑戦スマホキャンプサマー2012:ANEとアプリ内課金に挑戦
スマホキャンプサマー2012:ANEとアプリ内課金に挑戦Tetsuya Shiraishi
 
第8回 HoloLens 参考書 読書会
第8回 HoloLens 参考書 読書会第8回 HoloLens 参考書 読書会
第8回 HoloLens 参考書 読書会Masashi Eguchi
 
C#版人狼知能エージェントの作り方~Visual Studio編~(AIWolf.NET 1.0.6版)
C#版人狼知能エージェントの作り方~Visual Studio編~(AIWolf.NET 1.0.6版)C#版人狼知能エージェントの作り方~Visual Studio編~(AIWolf.NET 1.0.6版)
C#版人狼知能エージェントの作り方~Visual Studio編~(AIWolf.NET 1.0.6版)takots
 
Appsody でnodejsのアプリを立ち上げよう!
Appsody でnodejsのアプリを立ち上げよう!Appsody でnodejsのアプリを立ち上げよう!
Appsody でnodejsのアプリを立ち上げよう!Daisuke Hiraoka
 
The Basic of How to build LibreOffice / LibreOffice開発版ビルドの基礎 for Windows
The Basic of How to build LibreOffice / LibreOffice開発版ビルドの基礎 for WindowsThe Basic of How to build LibreOffice / LibreOffice開発版ビルドの基礎 for Windows
The Basic of How to build LibreOffice / LibreOffice開発版ビルドの基礎 for WindowsNaruhiko Ogasawara
 
まっつんチャレンジ OSC出張編 45分でわかる PHP+Eclipseによるテスト駆動開発環境の構築
まっつんチャレンジ OSC出張編 45分でわかる PHP+Eclipseによるテスト駆動開発環境の構築まっつんチャレンジ OSC出張編 45分でわかる PHP+Eclipseによるテスト駆動開発環境の構築
まっつんチャレンジ OSC出張編 45分でわかる PHP+Eclipseによるテスト駆動開発環境の構築Hideharu MATSUFUJI
 
Android Studio First Step Guide
Android Studio First Step GuideAndroid Studio First Step Guide
Android Studio First Step GuideMasahiro Hidaka
 
The Twelve-Factor (A|M)pp with C#
The Twelve-Factor (A|M)pp with C#The Twelve-Factor (A|M)pp with C#
The Twelve-Factor (A|M)pp with C#Yuta Matsumura
 
オープン・ソースで構築するARMマイコン開発環境 ―― GCC,Eclipse,OpenOCDで統合開発環境,JTAGデバッグもできる!
オープン・ソースで構築するARMマイコン開発環境 ―― GCC,Eclipse,OpenOCDで統合開発環境,JTAGデバッグもできる!オープン・ソースで構築するARMマイコン開発環境 ―― GCC,Eclipse,OpenOCDで統合開発環境,JTAGデバッグもできる!
オープン・ソースで構築するARMマイコン開発環境 ―― GCC,Eclipse,OpenOCDで統合開発環境,JTAGデバッグもできる!Masaki Muranaka
 
会津IT秋フォーラム2012での講演資料
会津IT秋フォーラム2012での講演資料会津IT秋フォーラム2012での講演資料
会津IT秋フォーラム2012での講演資料Shigeru Kobayashi
 
ロボットシステムのつくりかた 〜Robot Operating Systemというアプローチ〜
ロボットシステムのつくりかた 〜Robot Operating Systemというアプローチ〜ロボットシステムのつくりかた 〜Robot Operating Systemというアプローチ〜
ロボットシステムのつくりかた 〜Robot Operating Systemというアプローチ〜Hideki Takase
 
Yocto Project ハンズオン / 参加者用資料
Yocto Project ハンズオン / 参加者用資料Yocto Project ハンズオン / 参加者用資料
Yocto Project ハンズオン / 参加者用資料Nobuhiro Iwamatsu
 
Softlayer無制限ストレージを ownCloudで使う
Softlayer無制限ストレージを ownCloudで使うSoftlayer無制限ストレージを ownCloudで使う
Softlayer無制限ストレージを ownCloudで使うTetsurou Yano
 

Similar a JUCEハンズオン@Ableton and Max Community Japan #009 (20)

Osc2012 appinventor のその後
Osc2012 appinventor のその後Osc2012 appinventor のその後
Osc2012 appinventor のその後
 
Code igniterでテスト駆動開発 資料作成中
Code igniterでテスト駆動開発 資料作成中Code igniterでテスト駆動開発 資料作成中
Code igniterでテスト駆動開発 資料作成中
 
Eclipse PDT + MakeGoodによるPHPコードのテスト
Eclipse PDT + MakeGoodによるPHPコードのテストEclipse PDT + MakeGoodによるPHPコードのテスト
Eclipse PDT + MakeGoodによるPHPコードのテスト
 
JUCEではじめるBLOCKS開発_TOKYO BLOCKS HACKATHON 2018
JUCEではじめるBLOCKS開発_TOKYO BLOCKS HACKATHON 2018JUCEではじめるBLOCKS開発_TOKYO BLOCKS HACKATHON 2018
JUCEではじめるBLOCKS開発_TOKYO BLOCKS HACKATHON 2018
 
Audio Unit Extensions 〜オーディオエフェクトのアプリ間共有〜
Audio Unit Extensions 〜オーディオエフェクトのアプリ間共有〜Audio Unit Extensions 〜オーディオエフェクトのアプリ間共有〜
Audio Unit Extensions 〜オーディオエフェクトのアプリ間共有〜
 
スマホキャンプサマー2012:ANEとアプリ内課金に挑戦
スマホキャンプサマー2012:ANEとアプリ内課金に挑戦スマホキャンプサマー2012:ANEとアプリ内課金に挑戦
スマホキャンプサマー2012:ANEとアプリ内課金に挑戦
 
第8回 HoloLens 参考書 読書会
第8回 HoloLens 参考書 読書会第8回 HoloLens 参考書 読書会
第8回 HoloLens 参考書 読書会
 
C#版人狼知能エージェントの作り方~Visual Studio編~(AIWolf.NET 1.0.6版)
C#版人狼知能エージェントの作り方~Visual Studio編~(AIWolf.NET 1.0.6版)C#版人狼知能エージェントの作り方~Visual Studio編~(AIWolf.NET 1.0.6版)
C#版人狼知能エージェントの作り方~Visual Studio編~(AIWolf.NET 1.0.6版)
 
Appsody でnodejsのアプリを立ち上げよう!
Appsody でnodejsのアプリを立ち上げよう!Appsody でnodejsのアプリを立ち上げよう!
Appsody でnodejsのアプリを立ち上げよう!
 
Node-RED v2.0新機能紹介
Node-RED v2.0新機能紹介Node-RED v2.0新機能紹介
Node-RED v2.0新機能紹介
 
The Basic of How to build LibreOffice / LibreOffice開発版ビルドの基礎 for Windows
The Basic of How to build LibreOffice / LibreOffice開発版ビルドの基礎 for WindowsThe Basic of How to build LibreOffice / LibreOffice開発版ビルドの基礎 for Windows
The Basic of How to build LibreOffice / LibreOffice開発版ビルドの基礎 for Windows
 
まっつんチャレンジ OSC出張編 45分でわかる PHP+Eclipseによるテスト駆動開発環境の構築
まっつんチャレンジ OSC出張編 45分でわかる PHP+Eclipseによるテスト駆動開発環境の構築まっつんチャレンジ OSC出張編 45分でわかる PHP+Eclipseによるテスト駆動開発環境の構築
まっつんチャレンジ OSC出張編 45分でわかる PHP+Eclipseによるテスト駆動開発環境の構築
 
Android Studio First Step Guide
Android Studio First Step GuideAndroid Studio First Step Guide
Android Studio First Step Guide
 
The Twelve-Factor (A|M)pp with C#
The Twelve-Factor (A|M)pp with C#The Twelve-Factor (A|M)pp with C#
The Twelve-Factor (A|M)pp with C#
 
オープン・ソースで構築するARMマイコン開発環境 ―― GCC,Eclipse,OpenOCDで統合開発環境,JTAGデバッグもできる!
オープン・ソースで構築するARMマイコン開発環境 ―― GCC,Eclipse,OpenOCDで統合開発環境,JTAGデバッグもできる!オープン・ソースで構築するARMマイコン開発環境 ―― GCC,Eclipse,OpenOCDで統合開発環境,JTAGデバッグもできる!
オープン・ソースで構築するARMマイコン開発環境 ―― GCC,Eclipse,OpenOCDで統合開発環境,JTAGデバッグもできる!
 
会津IT秋フォーラム2012での講演資料
会津IT秋フォーラム2012での講演資料会津IT秋フォーラム2012での講演資料
会津IT秋フォーラム2012での講演資料
 
ロボットシステムのつくりかた 〜Robot Operating Systemというアプローチ〜
ロボットシステムのつくりかた 〜Robot Operating Systemというアプローチ〜ロボットシステムのつくりかた 〜Robot Operating Systemというアプローチ〜
ロボットシステムのつくりかた 〜Robot Operating Systemというアプローチ〜
 
Yocto Project ハンズオン / 参加者用資料
Yocto Project ハンズオン / 参加者用資料Yocto Project ハンズオン / 参加者用資料
Yocto Project ハンズオン / 参加者用資料
 
Softlayer無制限ストレージを ownCloudで使う
Softlayer無制限ストレージを ownCloudで使うSoftlayer無制限ストレージを ownCloudで使う
Softlayer無制限ストレージを ownCloudで使う
 
Ide env
Ide envIde env
Ide env
 

JUCEハンズオン@Ableton and Max Community Japan #009