JUCEで作るASIO対応アプリ -VSTプレイヤー編-

前回の記事に引き続き、JUCEからASIOドライバ対応のアプリケーションを作る手順を紹介します。本記事では、Projucerの”Audio Plug-In”テンプレートから作ることができるスタンドアローン形式のVSTプレイヤーを利用します。

■本記事の概要

1. ASIO SDKをダウンロードする
2. ASIO SDKのzipファイルを解凍する
3. Projucerで “Audio Plug-In”のテンプレートから新規プロジェクトを作成する
4. プロジェクト設定を開き、[Build Standalone Plug-In]を “Enabled”にする
5. [Modules] → [juce_audio_devices] → [JUCE_ASIO]を “Enabled”にする
6. [Exporters] → [Header Search paths]にASIO SDKのパスを入力する
7. プロジェクトを保存し、IDE (Visual Studio)でビルドする
8. ビルドしたアプリを起動し、オーディオ設定パネルからASIOを有効にする


1.ASIO SDKをダウンロードする

Steinbergの開発者向けページからダウンロードすることができます。
URL:https://www.steinberg.net/en/company/developers.html

 


2.zipファイルを解凍する

ASIO SDKをダウンロードしたら、zipファイルを解凍しておきましょう。
本記事では、”C:/SDKs/Steinberg SDK/ASIOSDK2.3″に解凍しておきます。
ASIO SDKにはソースコード、サンプルプロジェクト、ドキュメントが含まれています。

 


3.Projucerで新規プロジェクトを作成

本記事では、Projucerの”Audio Plug-In”テンプレートを元に作成したアプリケーションをASIOに対応させていきます。
“Audio Plug-In”テンプレートを利用することで、DAW等のホストアプリケーション上で実行することのできるVST/AUプラグインを簡単に作成することができます。
また、プラグイン形式だけでなく、スタンドアローン形式として、オーディオデバイスからの音声入力・出力やMIDI入出力を行うことができるアプリケーションを出力することができるのも大きな特徴です。

 


4.プロジェクト設定でスタンドアローン形式を有効にする

①[Projece Settings]ボタンをクリックし、プラグイン形式の選択画面を表示します。
②[Build Standalone Plug-In]を “Enabled”にしておきます。
※デフォルト値で”Enabled”になっています。

 


5.JUCEモジュール設定でASIO対応を有効にする

①プロジェクト設定から[Modules]→[juce_audio_devices]を選択します。
②[JUCE_ASIO]を “Enabled”に変更します。

 


6.エクスポート設定でASIO SDKのヘッダーファイルパスを追加する

①[Exporters]から、ビルドを実行するIDEのビルド設定アイテムを選択します。
②[Header Search Paths]欄に、上記(2)の作業で配置したASIO SDKのソースコードへのパスを入力します。
本記事では “C:/SDKs/Steinberg SDK/ASIOSDK2.3/common” を入力しました。
※画像ではReleaseビルドの設定項目にパスを追加していますが、DebugビルドでもASIO対応させたい場合は、同様にDebugビルドの設定項目にパスを追加してください。

 


7.プロジェクトの保存とIDE (Visual Studio)でビルド

Projucerでの作業が完了したら、プロジェクトを保存し、IDE(Visual Studio)でプロジェクトを開きます。
AppConfig.h内の”JUCE_ASIO”定義が有効になっていること、ASIO SDKのヘッダーファイルが参照されていることが確認できたら、ビルドを実行します。

 


8.ビルドしたアプリケーションの起動とASIOの有効化

アプリケーションの実装例として、JUCE JAPAN vol.2 で紹介したパラメトリックEQをスタンドアローン形式でビルドした場合を示します。
GitHub: https://github.com/COx2/JUCE_JAPAN_DEMO
VSTプラグイン版DL:  Windows (64bit+32bit) ,   macOS (64bit+32bit)

▼アプリケーションを起動する
ビルドしたアプリケーション “[プロジェクト名].exe” を起動すると、以下のような画面が 表示されます。

 

▼オーディオデバイス設定パネルを開く
ウインドウ左上の[Options]→ [Audio/MIDI Settings]をクリックしてオーディオデバイス設定パネルを開きます。

 

▼オーディオデバイス設定パネル
各項目の意味については、前回の記事の表の通りです。
なお、前回の記事には無かった[Feedback Loop]が追加されていますが、これはマイク入力とスピーカー出力との間でフィードバックループが発生してしまうのを防ぐために予めテンプレート側で実装されているスペシャルな機能です。

 

▼ASIOの設定を行う
[Audio device type]のコンボボックスから”ASIO”を選択すると、ドライバモードがASIOに切り替わり、GUIも変更されます。
[Device]のコンボボックスにASIO対応のデバイス一覧が表示されるので、使用するオーディオデバイスを選択します。
[Control Panel]ボタンをクリックすると、ASIOデバイス毎に設けられたコントロールパネルが開きます。

これで、ASIOに対応したスタンドアローンVSTプレイヤーが完成しました。
本記事で紹介した “Audio Plug-In”のテンプレートからASIO対応アプリを作ることで、低レイテンシーなオーディオ入出力機能を持ったアプリを作ることができます。

 

おまけ.

今回の記事を試してみたい…でもVSTプラグインのDSPとGUIの実装が面倒だ…、と思われた方には、JUCEのサンプルプロジェクト”JuceDemoPlugin”を改造するのがお勧めです。
“JUCE/examples/audio plugin demo”にある.jucerファイルを開き、上記手順の通りに設定を行うことで試すことができます。
VSTiの実装の参考にもなるでしょう。

JUCEでASIO対応アプリケーションを作る

JUCEの公式チュートリアルでもあまり触れられていませんが、JUCEの機能を使うことで、ASIOドライバ対応のアプリケーションを簡単に作ることができます。
本記事では、ASIO対応アプリケーションの作成におけるチュートリアルとしてサンプルプロジェクト”Plugin Host”をASIOに対応させる作業を紹介します。
新規プロジェクトから作成したアプリケーションをASIO対応させるまでの作業については後日投稿予定です。

■本記事の概要

1. ASIO SDKをダウンロードする
2. ASIO SDKのzipファイルを解凍する
3. Projucerでサンプルプロジェクト”Plugin Host”のjucerファイルを開く
4. [Modules] → [juce_audio_devices] → [JUCE_ASIO]を “Enabled”にする
5. [Exporters] → [Header Search paths]にASIO SDKのパスを入力する
6. プロジェクトを保存し、IDE (Visual Studio)でビルドする
7. ビルドしたアプリケーションを起動し、オーディオ設定パネルを開く
8. オーディオドライバ一覧から”ASIO”を選択する
9. ASIO対応デバイスのオーディオ入出力を設定する

■ASIOとは?


出典:https://www.steinberg.net/en/company/technologies.html
ASIO(Audio Stream Input Output)は、低遅延、高同期性、高いスループットを特徴とする、オーディオデバイスのドライバインタフェースです。
Windowsにも予めオーディオドライバ(DirectSound、WASAPI)は存在しますが、ASIOはそれよりもレイテンシー(データ送信から音声が出力されるまでの遅延時間)を低く抑えることができるので、例えばMIDI入力を受けてから実際に音が耳に届くまでの時間はOS標準のドライバよりも圧倒的に短くすることができます。
ASIOではマシンの処理速度が許す限りはあらゆるチャンネル数の入出力、標本化周波数、量子化ビット数のデータを扱うことができるので、マルチチャンネルシステムの構築を実現することができます。
つまり、DAWやハイレゾオーディオプレーヤーに代表されるASIO対応のアプリケーションの土台部分を簡単に作ることができます。そう、JUCEなら。

 


1.ASIO SDKをダウンロードする

Steinbergの開発者向けページからダウンロードすることができます。
URL:https://www.steinberg.net/en/company/developers.html

 


2.zipファイルを解凍する

ASIO SDKをダウンロードしたら、zipファイルを解凍しておきましょう。
本記事では、”C:/SDKs/Steinberg SDK/ASIOSDK2.3″に解凍しておきます。
ASIO SDKにはソースコード、サンプルプロジェクト、ドキュメントが含まれています。

 


3.Projucerでプロジェクトを開く

本記事では、JUCEフレームワークに付属されたサンプルプロジェクト”Plugin Host”を事例に、ASIOに対応させる手順を紹介します。
このサンプルプロジェクトは、DAWのようにオーディオデバイスからの音声入力・出力やMIDI入出力を行うことができるアプリケーションです。また、VSTプラグインをロードすることができるので、オーディオ入力にエフェクトを掛けたり、MIDI入力からプラグインを操作することができます。

◆今回使用するサンプルプロジェクト”JUCE/examples/audio plugin host”

◆ “Plugin Host.jucer”をProjucerで読み込みます

 


4.JUCEモジュール設定でASIO対応を有効にする

①プロジェクト設定から[Modules]→[juce_audio_devices]を選択します。
②[JUCE_ASIO]を “Enabled”に変更します。

 


5.エクスポート設定でASIO SDKのヘッダーファイルパスを追加する

①[Exporters]から、ビルドを実行するIDEのビルド設定アイテムを選択します。
②[Header Search Paths]欄に、上記(2)の作業で配置したASIO SDKのソースコードへのパスを入力します。
本記事では “C:/SDKs/Steinberg SDK/ASIOSDK2.3/common” を入力しました。
※画像ではReleaseビルドの設定項目にパスを追加していますが、DebugビルドでもASIO対応させたい場合は、同様にDebugビルドの設定項目にパスを追加してください。

 


6.プロジェクトの保存とIDE (Visual Studio)でビルド

Projucerでの作業が完了したら、プロジェクトを保存し、IDE(Visual Studio)でプロジェクトを開きます。
AppConfig.h内の”JUCE_ASIO”定義が有効になっていることと、ASIO SDKのヘッダーファイルが参照されていることが確認できたら、ビルドを実行します。

◆ AppConfig.h

◆ ASIO SDKへの参照

 


7.ビルドしたアプリケーションの起動とASIOの有効化

▼アプリケーションを起動する
ビルドした”Plugin Host.exe”を起動すると、以下のウインドウが表示されます。

▼オーディオデバイス設定パネルを開く
メニュー項目の[Options] → [Change the audio device settings]をクリックまたは、ショートカットキーの[Ctrl + A]から、オーディオデバイス設定パネルを開きます

▼オーディオデバイス設定パネル
オーディオデバイス設定パネルを開いた際に、Windows Audio(WASAPI)で動作している場合の例を以下に示します。

Audio device type オーディオドライバの形式(WASAPI/DirectSound/ASIO)を選択
Output オーディオ出力先の有効/無効
Input オーディオ入力元の有効/無効
[Test]ボタン [Output]デバイスから動作確認用のサイン波を鳴らします
Audio buffer size オーディオデバイスのバッファサイズ(サンプル数/バッファ)
Active MIDI Inputs .MIDI機器ごとの入力の有効/無効
MIDI Output MIDI信号を出力するデバイス・ポートを選択

 

▼オーディオデバイスドライバをASIOに切り替える
[Audio device type]のコンボボックスから”ASIO”を選択します。

▼ASIO対応デバイスの設定を行う
[Device]のコンボボックス、[Control Panel]ボタン、[Reset Device]ボタンが追加されます。
[Device]のコンボボックスにASIO対応のデバイス一覧が表示されるので、使用するオーディオデバイスを選択します。
[Control Panel]ボタンをクリックすると、ASIOデバイス毎に設けられたコントロールパネルが開きます。

▼ASIO対応で低レイテンシーの快適なVSTホストが完成しました。

 

今回はASIO対応アプリケーションを作成するために最低限必要な設定項目を説明するため、サンプルプロジェクトを改造する手順で紹介しました。新規プロジェクトを作成した場合は、これ以外に必要なコードの記述もありますので、別記事にて掲載予定です。

Raspberry Pi でJUCEをビルドする -Raspbian Jessie対応-

Raspberry Pi (Raspbian)でJUCEのプロジェクトをビルドしたので、レシピを紹介します。

同梱のVSTプラグイン/ ホストのサンプルプロジェクトをビルドしました。
PCと遜色なく快適に動きますし、MIDI入出力、音声入出力が可能なので、省電力なVSTシンセサイザ/エフェクトとして使用することができます。

レシピ

ROLI社のFabianがJUCE Forumにレシピをポストしてくれました。
ターミナルから以下のコマンドを実行するとビルドします。
※cdコマンドのディレクトリは各自の環境に合わせて入力してください。

// JUCEリポジトリをクローン 
$ git clone https://github.com/WeAreROLI/JUCE.git 

// 依存パッケージをインストール
$ sudo apt-get install clang freeglut3-dev g++ 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

// 作業ディレクトリに移動
$ cd JUCE/extras/Projucer/Builds/LinuxMakefile

// GCCでコンパイルする場合
$ make CXX=g++ "TARGET_ARCH=-march=armv7-a" -j4

// LLVM-Clangでコンパイルする場合
$ make CXX=clang++ -j4

1.準備

先ずはJUCEをダウンロードしましょう。公式ダウンロードサイト、Windows/macOS/Linuxから選択することができますが、Linux向けを選択すれば良いです。
※Linux用のProjucerが同梱されていますがx86をターゲットにしているため、CPUアーキテクチャが異なるRaspberry Pi (ARM)上では動作しません。Raspberry Pi用のProjucerは上記レシピでビルドすることができます。

GitHubからクローンする場合は、ターミナルを開いて次のコマンドを実行します。

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

 

2. 依存パッケージのインストール

$ sudo apt-get install clang freeglut3-dev g++ 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ライブラリのビルドに必要な依存パッケージをインストールします。ついでにLLVM-Clangコンパイラをインストールしています。なお、GCCでもコンパイルできることを確認しています。
※GCCでビルドする場合、こちらのバグに当たってしまうことを確認しています。GCCでビルドする際は”make”コマンドのオプションに “TARGET_ARCH=-march=armv7-a” を追加すると正常にビルドが実行されます。

 

 3.作業ディレクトリへの移動

$ cd JUCE/extras/Projucer/Builds/LinuxMakefile

LinuxMakefileが置かれたディレクトリに移動します。
※ディレクトリは各自の環境に合わせて入力してください。
※サンプルプロジェクトの一部に”LinuxMakefile”用プロジェクトが同梱されています。

 

4. コンパイル

4-1.GCCでコンパイルする場合

 $ make CXX=g++ "TARGET_ARCH=-march=armv7-a" -j4

LinuxMakefileからビルドを実行します。
ビルドモードは”Debug”がデフォルトです。
各種オプションについては以下の通りです。

CXX=g++
LinuxMakefileオプションです。C++コンパイラにg++を使用します

・ -j4
… makeコマンドのオプションです。同時に実行できるジョブの数(並行処理の数)を指定します。必須ではありませんが、CPUのコア数を有効利用できます。

※Raspbian Jessieの場合は、こちらのバグに当たるためアーキテクチャをコマンドから指定する必要があります。Raspbian Stretchでは解消されたようです。

4-2.LLVM-Clangでコンパイルする場合

$ make CXX=clang++ -j4

LinuxMakefileからビルドを実行します。
ビルドモードは”Debug”がデフォルトです。
各種オプションについては以下の通りです。

・CXX=clang++
… LinuxMakefileオプションです。C++コンパイラにclang++を使用します

・ -j4
… makeコマンドのオプションです。同時に実行できるジョブの数(並行処理の数)を指定します。必須ではありませんが、Raspberry Piのコア数を有効利用できます。

 

5.補足:Releaseビルド時のコマンド

// GCCでコンパイルする場合
$ make CXX=g++ -j4 CONFIG=Release

// LLVM-Clangでコンパイルする場合
$ make CXX=clang++ "TARGET_ARCH=-march=armv7-a" -j4 CONFIG=Release

・CONFIG=Release
… LinuxMakefileオプションです。”Release”モードでビルドします。

筆者にて動作確認した環境

◆ハードウェア
・Raspberry Pi 2 Model B
・Raspberry Pi 3 Model B

◆OS
・Raspbian Jessie With Pixel (Debian 8系)

◆JUCE バージョン
・JUCE 5.3.2

glslEditor for VST サンプルコード

MIDI CC入力のサンプルコード

MIDI CC入力を受信していることを確認する実装例です。

varying vec4 destinationColour;
varying vec2 textureCoordOut;

#extension GL_OES_standard_derivatives : enable

uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;
uniform float midiCC[128];
uniform float wave[256];
uniform float spectrum[256];

#define pi 3.1415

void main()
{
    vec2 position = (gl_FragCoord.xy / resolution.xy);
 
    float power = midiCC[position.x * 128];

    float r = position.y * 1.0;
    float g = 1-position.y * 1.0;
    float b = 0.;

    if(position.y < power * 0.01)
    {
        gl_FragColor = vec4(r, g, b, 1.0);
    }
    else
    { 
        gl_FragColor = vec4(0, 0, 0, 0.0);
    }
}

A GLSL editor running on VST / AU plug-in has been released

※2017/03/06 Update: Add the distribution of Windows installer version.

 

Download (free)

VST for Windows (64bit&32bit):
・Installer(64bit)

インストーラー版 for Windows(64bit)

・Installer(32bit)

インストーラー版 for Windows(32bit)

・ZIP(64bit&32bit)

ZIP版 for Windows(64bit&32bit)

 

VST/AU for macOS (64bit&32bit):

for macOS (64bit&32bit)

 

What is this?

It is an editor that describes a shader language called GLSL (OpenGL Shading Language) and a VST / AU plugin that displays a window to execute OpenGL drawing. Using the plug-in form, we have implemented the following distinctive functions.

  • Supports audio input from DAW (VST host)
  • Supports MIDI CC input from DAW (VST host)
  • Full screen display with multi display is also possible

By using these functions, you can control the shader in conjunction with DAW’s voice and MIDI automation. It may be used for VJ applications.
The shader that can be edited with this plug-in is “fragment shader” only.

What is GLSL?

For details, refer to the Wikipedia article.
I think that it would be nice if you could catch the article of “WebGL Honkyama” for more detailed information and fun illustrations.

Usage / compatibility with GLSL Sandbox

The GLSL editor of this plugin is designed to be compatible with GLSL Sandbox. By typing the same code as the GLSL Sandbox gallery into the editor you can draw in the same way.
Attention: Please properly operate / use shader code based on the existence of copyright. Especially, do not steal others’s code, or misrepresent others’ code as yourself.

Usage / uniform variables

Some uniform variables are specific to the GLSL Sandbox and others are provided by this plugin.

▼ GLSL Sandbox Specific

uniform float time:
 Get current time. Real-time animation can be realized by using this.
 * Ver 1.0 gives the frame counter every 0.2.

uniform vec2 mouse:
 While mouse dragging in the rendering window, you can get mouse coordinates. Both the X and Y directions range from 0 to 1.

uniform vec2 resolution:
 You can get the resolution of the current rendering window.

uniform vec2 surfacePosition:
 You can get the coordinates of the current surface (like billboard).

▼ This plug-in original implements

uniform float midiCC[128]:
 You can obtain MIDI CC events from the DAW (VST host). Get MIDI CC events as an array. "MidiCC [0]" means the value of "CC 0".
 The range of values ​​stored in each array is roughly 0 to 127, depending on the DAW.
 * For MIDI CC specifications, refer to the article of Wikipedia.

uniform float wave[256]:
 You can acquire voice waveform from DAW's mixer. Acquires 256 speech waveforms as an array. "Wave [0]" means the value of the "first sample" of the waveform.
 The range of values ​​stored in each array is roughly 0 to 1, depending on the DAW.

uniform float spectrum[256]:
 It is possible to obtain the value obtained by converting the speech waveform on the mixer of the DAW into the frequency spectrum. Acquire the frequency spectrum of 256 resolution as an array. "Spectrum [0]" means the value of the "lowest frequency" counted from the lower frequency in the frequency spectrum.
 The range of values ​​stored in each array is roughly 0 to 1, depending on the DAW.

License / source code

This software is distributed under “GPL v3” license.
The source code repository (GitHub) can be accessed from the following link.
GitHub