Impulse Response(IR)から応答特性のシステム同定を行って、同等の特性のエフェクトを作ってみる話の第3弾で、いよいよVST Pluginを生成した。
###前の記事
[MATLABでIR(Impulse Response) Speaker Simulator VST Plugin 1]
(https://qiita.com/SacredTubes/items/7ddc99edf33e91ef6c0e)
MATLABでIR(Impulse Response) Speaker Simulator VST Plugin 2
##MATLAB Class
MATLABからVST Plugin生成するにはクラスファイルを作成する必要がある。これは通常の関数型のMATLABファイルではなく、オブジェクト指向で書いたコードで、propertiers, methodsに各種属性があったり、文法が若干異なったりしてちょっと難しい。
親クラスを継承して、機能を引き継ぐという概念があって、それを行頭に書く。
例えば信号処理用のクラスSystem ObjectとVST Plugin生成に必要なaudioPluginを継承するとこんな感じ。
classdef IRSpeakerSim < matlab.System & audioPlugin
end
System ObjectはSimulinkに取り込むことができたり、中でSystem Objectクラス(dsp.FIRFilter)を使っていたり、setup/step/resetといったメソッドが予め定義されていて使いやすいため使っている。
処理用のコードはたった1行
out = step(obj.hFilter, in, temp)*10^(obj.inputVol/20);
だけだけど、VST Pluginにしたときのパラメータ等々入れるとこんなコードになった。
classdef IRSpeakerSim < matlab.System & audioPlugin
properties
SpeakerType = 'VHTVintage2x12';
inputVol = 0;
end
properties (Constant)
PluginInterface = audioPluginInterface(...
'PluginName', 'IR Speaker Simulator', ...
'InputChannels', 1, ...
'OutputChannels', 1, ...
'VendorName', 'SacredTubes', ...
'VendorVersion', '1.0.0', ...
audioPluginParameter('SpeakerType','DisplayName', 'Speaker Type', 'Label', 'Type', 'Mapping',...
{'enum', 'VHTVintage2x12', 'BoogieRectiVintage2x12', 'BoogieRectiModern2x12', 'SealedVintage4x12',...
'OpenVintage2x12'},'Layout',[2,2], 'DisplayNameLocation','Left'),...
audioPluginParameter('inputVol','DisplayName', 'Input Volume', ...
'Label', 'dB', 'Mapping', {'lin',-20,+20},...
'Style','rotaryknob', 'Layout',[4, 2], 'DisplayNameLocation','Left'),...
audioPluginGridLayout('RowHeight',[20,20 20 150 10],...
'ColumnWidth',[100 200])...
)
end
properties(Access = private)
hFilter
num
end
methods
% Constructor
function obj = IRSpeakerSim(varargin)
% Support name-value pair arguments when constructing object
setProperties(obj,nargin,varargin{:})
end
end
methods(Access = protected)
%% Common functions
function setupImpl(obj)
% Perform one-time calculations, such as computing constants
obj.hFilter = dsp.FIRFilter('NumeratorSource', 'Input port');
temp = coder.load('filterCoef.mat');
% temp.num = [ones(5,1) zeros(5, 10)]; % for test
obj.num = temp.num;
end
function out = stepImpl(obj,in)
% Implement algorithm. Calculate y as a function of input u and
% discrete states.
switch obj.SpeakerType
case 'VHTVintage2x12'
spSel = 1;
case 'BoogieRectiVintage2x12'
spSel = 2;
case 'BoogieRectiModern2x12'
spSel = 3;
case 'SealedVintage4x12'
spSel = 4;
case 'OpenVintage2x12'
spSel = 5;
otherwise
spSel = 1;
end
temp = obj.num(spSel, :);
out = step(obj.hFilter, in, temp)*10^(obj.inputVol/20);
end
function resetImpl(obj)
% Initialize / reset discrete-state properties
reset(obj.hFilter);
end
end
end
##オーディオ信号を入力してテスト
まずはこれに音楽信号を入力してテストする。
テストは
>> audioTestBench
でテストベンチを起動。下のようなGUIが出てきて、入出力ファイル/デバイスを設定してテストできる。
##VST Plugin生成
ちゃんと動作したらいよいよプラグイン生成。たったこれだけでVST Effectが作れてしまう。。。
>> generateAudioPlugin('IRSpeakerSim')
コードにエラーが無ければフォルダにVST Pluginのファイル*.dllが生成されているので、それをDAWのEffect用フォルダにコピーすれば使える。
MATLABで実行しているのと見た目は変わらないが、こっちはDAW上で自動生成されたVSTでエフェクトをかけている。
終わり