LoginSignup
2
0

More than 1 year has passed since last update.

JUCEでPCMシンセサイザープラグイン(VSTi)を作る

Last updated at Posted at 2022-07-13

はじめに

PCMシンセサイザープラグイン(VSTi)を作ってみたいと思い作り方を調べていたところ、JUCEというオーディオアプリケーションを作るためのフレームワークがあることを知りました。

JUCEでPCMシンセサイザープラグイン(VSTi)を作ってみたいと思い作り方を調べていたところ、スタンドアロンのPCMシンセサイザーを作る記事はありましたが、プラグイン(VSTi)形式のPCMシンセサイザーを作る記事があまりありませんでした。

そこで今回は、プラグイン(VSTi)形式のPCMシンセサイザーの作り方について紹介してみようと思います。

作るにあたっては以下の記事を参考にしました。基本的に元記事と流れは同じですが、そのままでは上手くいかない点があったため一部改変・追記しています。
https://vaporsoft.net/creating-a-very-simple-sampler-audio-plugin-in-juce-5/

開発環境

  • Visual Studio 2022
  • JUCE 7.0.1

プロジェクトの準備

プロジェクトの作成

Projucer.exeを開きメニューバーから File -> New Project...を選びます

左のメニューからPlugin -> Basicを選びます。Project NameにSimpleSamplerを入力しCreate Projectを押します。
1.png
保存場所の選択画面が表示されるので、任意のフォルダを選択します。

プロジェクトの設定

左上の歯車マークをクリックしプロジェクトの設定を開きます。
左の一覧のPlugin CharacteristicsのPlugin is a SynthおよびPlugin MIDI Inputにチェックを入れます。
2.png

空のソースファイルの追加

左のメニューのFile Explolerを選択しSourceを表示します。
Sourceを右クリックし、Add New CPP & Header File...をクリックします。
3.png

ファイル名にSimpleSynthを入力し保存します。
4.png

Ctrl+Sを押し、プロジェクトの設定を保存します。

Visual Studio 2022の起動

Select exporterからVisual Studio 2022を選択し、右のVisual Studioのマークをクリックします。
5.png

実装

SimpleSynthクラスの実装

以下のように、SimpleSynth.hにjuceのライブラリを読み込むためにJuceHeader.hをincludeします。次にSynthesiserクラスを継承した新しいクラスSimpleSynthを定義します。

SimpleSynth.h
// SimpleSynth.h

#pragma once
#include <JuceHeader.h>

using namespace juce;

class SimpleSynth : public Synthesiser {
public:
	void setup();
private:
	// manager object that finds an appropriate way to decode various audio files.  Used with SampleSound objects.
	AudioFormatManager audioFormatManager;
};

SimpleSynthのsetup()関数に、シンセサイザーの初期設定を行うための処理を実装します。

SimpleSynth.cpp
// SimpleSynth.cpp

#include "SimpleSynth.h"
#define MAX_VOICES 16

void SimpleSynth::setup() {
	// add voices to our sampler
	for (int i = 0; i < MAX_VOICES; i++) {
		addVoice(new SamplerVoice());
	}

	// set up our AudioFormatManager class as detailed in the API docs
	// we can now use WAV and AIFF files!
	audioFormatManager.registerBasicFormats();

	// now that we have our manager, lets read a simple file so we can pass it to our SamplerSound object.
	File* file = new File("file.wav");
	ScopedPointer<AudioFormatReader> reader = audioFormatManager.createReaderFor(*file);

	// allow our sound to be played on all notes
	BigInteger allNotes;
	allNotes.setRange(0, 128, true);

	// finally, add our sound
	addSound(new SamplerSound("default", *reader, allNotes, 60, 0, 10, 10.0));
}

補足として、ファイルfile.wavのパスは、VSTホストアプリケーションのカレントディレクトリからの相対パスになります。

SimpleSamplerAudioProcessorクラスの実装

DAWからMIDIを受け取りSimpleSynthクラスを操作するためのSimpleSamplerAudioProcessorクラスを実装します。
PluginProcessor.hを開き、以下のように追記します。

PluginProcessor.h

/* 前略 */

#pragma once

#include <JuceHeader.h>
#include "SimpleSynth.h" // 追記1

/* 中略 */

private:
    //==============================================================================
    SimpleSynth synth; // 追記2
    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SimpleSamplerAudioProcessor)
};

次に、SimpleSamplerAudioProcessorクラスのprocessBlock関数内の処理を全て削除します。そして、オーディオをレンダリングするために必要な処理をprocessBlock関数に以下の通り定義します。

PluginProcessor.cpp
void SimpleSamplerAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, juce::MidiBuffer& midiMessages)
{
    juce::ScopedNoDenormals noDenormals;
    auto totalNumInputChannels = getTotalNumInputChannels();
    auto totalNumOutputChannels = getTotalNumOutputChannels();

    for (int i = totalNumInputChannels; i < totalNumOutputChannels; ++i)
        buffer.clear(i, 0, buffer.getNumSamples());

    synth.renderNextBlock(buffer, midiMessages, 0, buffer.getNumSamples());
}

次にSimpleSamplerAudioProcessorクラスの関数prepareToPlayでサンプルレートの設定を行います。以下の通り追記します。

PluginProcessor.cpp
void SimpleSamplerAudioProcessor::prepareToPlay (double sampleRate, int samplesPerBlock)
{
    synth.setCurrentPlaybackSampleRate(sampleRate); // 追記
}

最後にSimpleSamplerAudioProcessorクラスのコンストラクタでシンセサイザーの初期設定を行います。以下の通り追記します。

PluginProcessor.cpp
SimpleSamplerAudioProcessor::SimpleSamplerAudioProcessor()
#ifndef JucePlugin_PreferredChannelConfigurations
     : AudioProcessor (BusesProperties()
                     #if ! JucePlugin_IsMidiEffect
                      #if ! JucePlugin_IsSynth
                       .withInput  ("Input",  juce::AudioChannelSet::stereo(), true)
                      #endif
                       .withOutput ("Output", juce::AudioChannelSet::stereo(), true)
                     #endif
                       )
#endif
{
    synth.setup(); // 追記
}

ビルド

Visual Studio 2022のメニューからビルド -> ソリューションのビルドを実行します。
6.png

以下のように出力されたら成功です。
7.png

vst3およびwavファイルの配置

  1. SimpleSampler\Builds\VisualStudio2022\x64\Debug\VST3にSimpleSampler.vst3ファイルが生成されているので、SimpleSampler.vst3をC:\Program Files\Common Files\VST3にコピーします。
  2. シンセサイザーで再生するwavファイルをfile.wavにリネームし、VSTホストアプリケーションのカレントディレクトリにコピーします。通常はVSTホストアプリケーションの.exeファイルが配置されているディレクトリです。

動作確認

VSTホストアプリケーション(DAW)でSimpleSamplerという名前のプラグインを開いて確認します。VSTホストアプリケーションのカレントディレクトリに配置したwavファイルが再生されれば成功です。

おわりに

VSTi形式のPCMシンセサイザーを作成できました。今回のサンプルでは、.vst3ファイルの他に、シンセサイザーが再生する.wavファイルも適切なパスへ配置する必要がありました。
.wavファイルは.vst3にバイナリとして同梱したほうが使い勝手が良いため、次の記事では.wavファイルをバイナリとして組み込む方法を紹介します。

今回作成したプロジェクトは以下リポジトリに置いているので、興味のある人は見てみてください。

リポジトリ

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0