したらばTOP ■掲示板に戻る■ 全部 1-100 最新50 | |

C++でVST作りの指摘・質問

1管理人:2010/12/10(金) 18:06:52
「C++でVST作り」内の誤記やサンプルコードのバグ、指摘・質問等がございましたらこちらへお願いいたします。

C++でVST作り→http://www39.atwiki.jp/vst_prog/

9ちあ.dat:2011/04/23(土) 12:03:40
こんにちは。
DLLを作成するときに使う、「vstplug.def ファイル」についての質問がございます。
よろしくお願いいたします。


このファイルの中身は、最初は、

EXPORTS
VSTPluginMain
main=VSTPluginMain

ってなってますよね。

そこで気になったのですが、
「最小構成のVST作成方法」→「AudioEffect* createEffectInstance()関数の作成」 の項目に記述されている、
AudioEffect* createEffectInstance()
を、VSTホストから使用するためには、自分で vstplug.defファイル の中身を

EXPORTS
VSTPluginMain
main=VSTPluginMain
createEffectInstance

と、書き換える必要があるのでしょうか。


それとも、VSTホストは、
最初からdefファイルに記述されている「VSTPluginMain」メソッド を利用することによって、
VSTプラグインを使用するのでしょうか?


ちなみに、
vstpluginmain.cppファイルにて、VSTPluginMainメソッド は、次のように定義されていました。

VST_EXPORT AEffect* VSTPluginMain (audioMasterCallback audioMaster)
{
// Get VST Version of the Host
if (!audioMaster (0, audioMasterVersion, 0, 0, 0, 0))
return 0; // old version

// Create the AudioEffect
AudioEffect* effect = createEffectInstance (audioMaster);
if (!effect)
return 0;

// Return the VST AEffect structur
return effect->getAeffect ();
}

これを見ると、VSTホストアプリケーションは、
AEffect構造体を利用するのだろうか?
とも思えます。
しかしその場合、new した AudioEffectインスタンスは、いつ解放されるの?
放っておいて、メモリーリークは起こらないの?
等と、心配事があります。


VSTホストアプリケーション(SonarとかCubase等)は、
どのようにして、VSTプラグインを使っているのでしょう。

今、色々試して、試行錯誤している最中です。

お時間がございます時で構いません。
管理人様が、ご存知のことがございましたらアドバイス頂けないでしょうか?

よろしくお願い致します。

10管理人:2011/04/23(土) 12:28:12
ちあ.datさんありがとうございます。

書き込みが少ないのでお礼や指摘は素直にうれしいです。

自分のページをよりよくしていきたいと思いますので
ご質問や指摘は大歓迎です。

これからもよろしくお願いいたします。

11管理人:2011/04/23(土) 12:29:51
書き込みに気づかず書き込んでしまった…

12管理人:2011/04/23(土) 12:41:19
私自身も詳しくはないですが、

> と、書き換える必要があるのでしょうか。
> 最初からdefファイルに記述されている「VSTPluginMain」メソッド を利用することによって、
> VSTプラグインを使用するのでしょうか?
vstplug.defは書き換える必要はないと思います。
ご認識のとおりだと思われます。

> これを見ると、VSTホストアプリケーションは、
> AEffect構造体を利用するのだろうか?
AEffectクラスを継承した自作のVSTクラスを利用することとなります。
C++のクラスの「継承」「オーバーライド」といった機能を調べていただけると
ご理解いただけるかと思います。

なおnewしたAudioEffectインスタンスの解放は
ホストアプリケーション側で行われていると思います。

13管理人:2011/04/23(土) 12:49:20
> C++のクラスの「継承」「オーバーライド」といった機能を調べていただけると
> ご理解いただけるかと思います。
「仮想関数」が抜けていました。

14ちあ.dat:2011/04/23(土) 13:13:40
管理人様、すばやいご回答ありがとうございます!

なるほど!
AEffectクラスを継承した自作クラスを作成することが基本方針なのですね!

このクラスの中身はまだわからないことが多いのですが、色々調べたり試したりして
がんばってみようと思います。

本日、こちらのサイトを発見してから、長い間の疑問が色々解決しました!
今後のサイトの更新を、楽しみにしております。

ありがとうございました!

15管理人:2011/04/23(土) 14:08:38
ちあ.datさん

無事解決してよかったです。

ここに書かれている以外のことでも可能な範囲で答えますので
よければまたご質問ください。

ありがとうございました。

16nobu:2011/08/15(月) 11:09:11
> AudioEffectインスタンスは、いつ解放されるの?

>なおnewしたAudioEffectインスタンスの解放は
> ホストアプリケーション側で行われていると思います。

本当にそうか気になったのでざっとSDKとサンプルのコードを見てみました。

VST hostが受け取れるのは AudioEffect の持っている AEffect 構造体。

AEffect::object は そのAEffect自身を持っている AudioEffect へのポインタ。

AudioEffect::dispatchEffectClass で effClose がきた時に引数として受け取った AEffect構造体のメンバ AEffect::object (= AudioEffectのインスタンス) に対して delete している。

AudioEffect::dispatchEffectClass は AudioEffect のコンストラクタで、AEffect の dispatcher に設定されている。

minihostのサンプルを見ると、VST hostは終了処理として
> effect->dispatcher (effect, effClose, 0, 0, 0, 0);
のように effClose を投げる

ということで、当初の予想通り、AudioEffectのインスタンスの解放はVST hostの責任で、VST pluginを作る人は気にする必要はありませんでした。
情報共有まで。

17管理人:2011/08/17(水) 01:32:42
nobuさん情報提供ありがとうございました。

有益な情報をいただけて助かりました。
これからもよろしくお願いいたします。

18<削除>:<削除>
<削除>

19<削除>:<削除>
<削除>

20ken:2012/01/27(金) 00:17:33
初めまして、kenと申します。
「C++でVST作り」と拝見させていただいております。

Microsoft Visual C++ (2008 Express Edition)とVST SDK 2.4をインストールし、
VC++ プロジェクトの準備のNo.1〜No.5を読みながら、まずビルドまでを挑戦しています。
手順どおりの操作を行ったつもりなのですが、以下のようなエラーが出てしまいます。

------ ビルド開始: プロジェクト: MyTremoloVST, 構成: Release Win32 ------
リンクしています...
ライブラリ C:\Documents and Settings\ken\デスクトップ\MyTremoloVST\Release\MyTremoloVST.lib とオブジェクト C:\Documents and Settings\ken\デスクトップ\MyTremoloVST\Release\MyTremoloVST.exp を作成中
vstplugmain.obj : error LNK2001: 外部シンボル ""class AudioEffect * __cdecl createEffectInstance(int (__cdecl*)(struct AEffect *,int,int,int,void *,float))" (?createEffectInstance@@YAPAVAudioEffect@@P6AHPAUAEffect@@HHHPAXM@Z@Z)" は未解決です。
C:\Documents and Settings\ken\デスクトップ\MyTremoloVST\Release\MyTremoloVST.dll : fatal error LNK1120: 外部参照 1 が未解決です。
ビルドログは "file://c:\Documents and Settings\ken\デスクトップ\MyTremoloVST\MyTremoloVST\Release\BuildLog.htm" に保存されました。
MyTremoloVST - エラー 2、警告 0
========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========


Microsoft Visual C++ (2010 Express Edition)でも試したのですが、同様のエラーが出てしまいます。
------ ビルド開始: プロジェクト: MyTremoloVST, 構成: Release Win32 ------
ライブラリ C:\Documents and Settings\ken\デスクトップ\MyTremoloVST\Release\MyTremoloVST.lib とオブジェクト C:\Documents and Settings\ken\デスクトップ\MyTremoloVST\Release\MyTremoloVST.exp を作成中
vstplugmain.obj : error LNK2001: 外部シンボル ""class AudioEffect * __cdecl createEffectInstance(int (__cdecl*)(struct AEffect *,int,int,int,void *,float))" (?createEffectInstance@@YAPAVAudioEffect@@P6AHPAUAEffect@@HHHPAXM@Z@Z)" は未解決です。
C:\Documents and Settings\ken\デスクトップ\MyTremoloVST\Release\MyTremoloVST.dll : fatal error LNK1120: 外部参照 1 が未解決です。
========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========


単純なミスなのかも知れませんが、このエラーから何か設定すべきこと等わかりましたら、教えていただければ幸いです。
よろしくお願いいたします。

21管理人:2012/01/28(土) 04:05:20
kenさんはじめまして

おそらくプロジェクトの準備だけしてすぐにビルドしたのでは無いでしょうか?

残念ながらプロジェクトの準備だけではビルドすることができません。
ビルドするには.cppファイルを作成し、最低限の関数とクラスを
定義する必要があります。

ビルドするための最低限必要な定義については
「最小構成のVST作成方法」に記載しております。

・最小構成のVST作成方法
  http://www39.atwiki.jp/vst_prog/pages/70.html

・最小構成のVST(ソースコード全体)
  http://www39.atwiki.jp/vst_prog/pages/73.html

22ken:2012/01/28(土) 12:28:53
早速のご教示ありがとうございました。
「簡単な音源(VSTi)の作成」ページのMySynthSampleVSTをビルドすることができました。
これからソースコードの内容を勉強させていただきたいと思います。

VST、VSTiに関してはこれから学ぶところですが、
私もまた違ったアプローチでバーチャルアナログ音源を作っています。
よろしければ見てみてください。

・What is Flageoboard?
  http://mbed.org/users/kentasaito/notebook/what-is-flageoboard/

・Me playing Flageoboard (YouTube)
  http://www.youtube.com/watch?v=chereNrys5Q

23管理人:2012/01/29(日) 11:20:45
kenさん

無事解決してよかったです。

すでにマイコンを使って作られたことがあるんですね.
VSTの規格自体はあまり難しく無いと思いますので
すぐに作成できると思います。

ほかに不明点がありましたらいつでもご質問ください。
また、書けていない内容(MIDI処理とかフィルタとか…)も
ありますのでそちらもわかる範囲で答えさせていただきます。

これからもよろしくお願いいたします。

24ken:2012/01/30(月) 00:12:22
お返事ありがとうございます。
「VST GUIの作成」ページのつまみやスライダーも拝見させていただいています。
VSTiは学べば学ぶほどやってみたいことが増えそうな気がします。

今後ともよろしくお願いいたします。

25<削除>:<削除>
<削除>

26<削除>:<削除>
<削除>

28名無しさん:2012/11/20(火) 12:20:46
管理人様、はじめまして。
自作のVstHostアプリを開発中の者です。
ホームページに載っている色々な情報を参考にさせていただいています。
ありがとうございます。

上記の通りVstHostアプリを開発中なのですが、
嵌ってしまっておりましてアドバイスをいただけたらと思い、書き込みさせていただきました。

現在vsti(Synth1)をホストアプリにloadして
processEvents()とprocessReplaceing()を実行するコードを書き、
エラー無しでコンパイルされること、
また、プログラムを実行すると正常終了するところまでは確認できているのですが、
肝心の音が鳴らない状況です。

vstiのdllの中でトレースすることも出来ず困っているのですが、
自分の書いたコードをご覧いただき、おかしなところがあればご指摘いただけたら幸いと思っている次第です。
以下の様な感じになります。
http://codepad.org/m52oPA93

またトレースの仕方についても良い方法がありましたらご教示いただけましたら幸いです。

ご回答いただけますと嬉しいです。
どうぞ宜しくお願いします。

29管理人:2012/11/21(水) 02:13:31
書き込みありがとうございます。

VSTHostについてはあまり詳しくありませんので
見当違いかもしれませんが、AEffect構造体ではなく
AudioEffectXクラスを利用されてはいかがでしょうか?

dispatcher()関数でMIDIメッセージをセットし、
音を鳴らそうとしているようですが、AEffect構造体(AudioEffectクラス)の
dispatcher()関数にはopcodeがeffProcessEventsの場合の処理が
記載されていないようです。
(aeffect.h、audioeffect.cppを見た限りですが…)

AudioEffectXクラスはAudioEffectクラスのdispatcher関数を
オーバーライドしており、opcodeがeffProcessEventsの場合に
processEvents()関数を呼び出すようになっています。
(aeffectx.h、audioeffectx.cppに記載があります。)

こちらで試されてみてはいかがでしょうか?

またトレースの方法ですが、本格的な開発をしたことが無く
こちらはまったくわかりません…

30らい:2012/11/21(水) 16:34:21
初めまして.
卒業研究でVSTを制作しており,毎日そちらのサイトで勉強させていただいてます.

サンプルコードのトレモロは無事実装でき,それに対するGUIを実装したいと思い
まずはウィンドウを表示するだけのサンプルプログラムの実装を試みているのですが
なかなか思うようにいかず苦戦しております.
vstcontrols.cpp,vstgui.cpp,aeffguieditor.cppのソースファイルもプロジェクトに入れ,実行しても以下のようなメッセージが出てきました.

1>------ ビルド開始: プロジェクト: GUI, 構成: Release Win32 ------
1> vstcontrols.cpp
1>C:\vstsdk2.4\pluginterfaces/vst2.x/aeffect.h(296): warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\string.h(188) : 'strncpy' の宣言を確認してください。
1>C:\vstsdk2.4\pluginterfaces/vst2.x/aeffect.h(306): warning C4996: 'strncat': This function or variable may be unsafe. Consider using strncat_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\string.h(175) : 'strncat' の宣言を確認してください。
1>..\..\..\..\..\..\..\vstsdk2.4\vstgui.sf\vstgui\vstcontrols.cpp(707): warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\stdio.h(371) : 'sprintf' の宣言を確認してください。
1>..\..\..\..\..\..\..\vstsdk2.4\vstgui.sf\vstgui\vstcontrols.cpp(1408): error C2664: 'CreateWindowExW' : 2 番目の引数を 'const char [5]' から 'LPCWSTR' に変換できません。(新しい機能 ; ヘルプを参照)
1> 指示された型は関連がありません。変換には reinterpret_cast、C スタイル キャストまたは関数スタイルのキャストが必要です。
1>..\..\..\..\..\..\..\vstsdk2.4\vstgui.sf\vstgui\vstcontrols.cpp(1420): error C2664: 'strcpy' : 1 番目の引数を 'WCHAR [32]' から 'char *' に変換できません。(新しい機能 ; ヘルプを参照)
1> 指示された型は関連がありません。変換には reinterpret_cast、C スタイル キャストまたは関数スタイルのキャストが必要です。
1>..\..\..\..\..\..\..\vstsdk2.4\vstgui.sf\vstgui\vstcontrols.cpp(1864): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\string.h(105) : 'strcpy' の宣言を確認してください。
1>..\..\..\..\..\..\..\vstsdk2.4\vstgui.sf\vstgui\vstcontrols.cpp(1868): error C2664: 'GetWindowTextW' : 2 番目の引数を 'char [255]' から 'LPWSTR' に変換できません。(新しい機能 ; ヘルプを参照)
1> 指示された型は関連がありません。変換には reinterpret_cast、C スタイル キャストまたは関数スタイルのキャストが必要です。
1>..\..\..\..\..\..\..\vstsdk2.4\vstgui.sf\vstgui\vstcontrols.cpp(1869): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\string.h(105) : 'strcpy' の宣言を確認してください。
1>..\..\..\..\..\..\..\vstsdk2.4\vstgui.sf\vstgui\vstcontrols.cpp(3098): error C2664: 'AppendMenuW' : 4 番目の引数を 'char *' から 'LPCWSTR' に変換できません。(新しい機能 ; ヘルプを参照)
1> 指示された型は関連がありません。変換には reinterpret_cast、C スタイル キャストまたは関数スタイルのキャストが必要です。
1> MyVstGui2.cpp
========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========

C++を勉強してまだ半年ほどのものですが,ご指南頂けたらと思います.
何卒よろしくお願いします.

3128:2012/11/21(水) 19:28:18
管理人様

ご返信ありがとうございます!
なるほど、AEffect構造体のdipsatcherを呼んでもだめだったのですね。
重ね重ねになり申し訳ないのですが、またお伺いさせていただけますでしょうか。

ご教示いただいたようにAudioEffectXクラスのdispatcherを呼ぶ形で試してみようとしたのですが、
そもそもsynth1のdllをhostアプリ側で読み込んだ際に、どうやってAudioEffectXクラスのインスタンスのポインタを得ればいいのか
よくわからないのです。

現在、VstEventsTransporter::execute()
の中で使われている
vsti変数の中身 (synth1.dllをloadした際に得られたAEffect*)
は下記のような形で取得しています。
http://codepad.org/cYO1Je5z

mainEntryPoint()では AEffect*が返ってきてしまいますが、
ここでAEffect* ではなくAudioEffectX*を得る方法があるのでしょうか?

その方法を調べてみたのですが分からなかったため、
下記のように
http://codepad.org/SHkfCs6v
無理矢理キャストしてみたのですが、
コンパイルエラー等はでないものの、やはり音が鳴りません。

どこかで間違っているのだと思うのですが、
アドバイスをいただけますと幸いです。

よろしくお願い致します。

32管理人:2012/11/21(水) 23:26:31
>>30
らいさん書き込みありがとうございます。

プロジェクトの文字コードの設定がおそらくUnicodeになっていると思われます。
マルチバイト文字セットにすれば解決すると思います。

変更方法は下記のとおりです。
1.メニューから「プロジェクト」→「【プロジェクト名】のプロパティ」を選び、
 プロパティダイアログを開く
2.開いたダイアログ左側「構成プロパティ」→「全般」を選択
3.ダイアログ右側の「文字セット」を「マルチバイト文字セットを使用する」に変更
4.ダイアログ下側の「OK」を押す

上記内容をWebページのほうに更新いたしましたのでご参考までに。
http://www39.atwiki.jp/vst_prog/pages/61.html

33管理人:2012/11/22(木) 00:28:13
>>28さん

AudioEffectXクラスのポインタを得るには
 > AudioEffect* aex = (AudioEffectX*)vsti->object;
で問題ないと思います。

ただし、aexはAudioEffectクラス型ですので、
 > aex->dispatcher(
の部分ではAudioEffectクラスのdispatcher()関数が
呼ばれていると思います。

AudioEffectXクラスのdispatcher()関数を呼ぶには
  ((AudioEffectX*)aex)->dispatcher(
のようにキャストするか、
そもそもaexをAudioEffectXクラスで定義すればよいと思います。
  AudioEffectX* aex = (AudioEffectX*)vsti->object;

あまり自信がありませんがよろしくお願いします。

34らい:2012/11/22(木) 15:12:55
管理人様

迅速な対応ありがとうございます.
おかげ様で無事にウィンドウとつまみ表示のGUIを構築出来ました.
これをもとに勉強し,まずはトレモロエフェクトに対してGUIを構築することを目標としてやっていきたいと思います.

またこちらで質問させていただくことがあると思いますが
何卒よろしくお願い致します.

35管理人:2012/11/23(金) 01:46:27
らいさん

無事解決してよかったです。

WebページのほうにGUIの情報はあまり乗せていませんが
多少のことであれば知っています。
何かあればまたよろしくお願いします。

3628:2012/11/23(金) 12:55:01
管理人様

レスありがとうございます。
ご指摘ありがとうございます。
>AudioEffect* aex = (AudioEffectX*)vsti->object;
ここの部分なのですが、確かに
>AudioEffectX* aex = (AudioEffectX*)vsti->object;
の間違いでした。

しかし
>AudioEffectX* aex = (AudioEffectX*)vsti->object;
のようにしてもやはり音が鳴らないのです・・

proessReplacing()関数は、
それを実行した瞬間実際に音が鳴るものだと思っていたのですが、
もしかしますと、違うのでしょうか??
(波形を生成してどこかに格納しておくだけだったりしますでしょうか)
もしそうだとすると波形データを読み込んで実際に発音させる仕組みを
host側で持っておく必要があるのでしょうか・・?

2chの方でも色々と質問してみようと思うのですが、
ご教示いただけますと幸いです。

37管理人:2012/11/23(金) 13:34:28
>>28さん

processReplacing()関数はprocessEvents()関数で渡されたVstEventと引数inputsから
outputsに波形を出力するの関数です。

ですので音を出す仕組みはWinAPIのマルチメディア関数(waveOutOpen、waveOutWrite等)や
DirectSound等を利用し作成する必要があります。

processReplacing()関数の前にoutputsを0で初期化しているようですので、
呼び出した後にoutputsに0以外の値が入っているかどうか確認し、
波形が生成されているかまずは確認してみてはいかがでしょうか?

3828:2012/11/26(月) 01:01:32
管理人様

レス有難うございます。
お礼が遅れましてすみません。

>processReplacing()関数はprocessEvents()関数で渡されたVstEventと引数inputsから
>outputsに波形を出力するの関数です。

なるほど、そういうことだったのですね・・色々と勘違いしておりました。
vstiから返って来たデータをもとにwindows上でwaveデータを扱う
構造体を生成する必要があるようですね。
とても勉強になりました。
ひとまずその辺りの仕組みについて色々調べてみることにします。

ご丁寧に対応頂きましてありがとうございました。
また疑問点等が出たときは質問させていただくかもしれませんが、
よろしくお願いいたします。

39管理人:2012/11/27(火) 00:53:32
>>28さん

また何かありましたらわかる範囲で答えさせていただきます
よろしくお願いします。

4028:2012/12/09(日) 22:37:27
お世話になっております。
28です。

先のレスでいただいたアドバイスに従って色々と試行錯誤しているのですが
またよく分からない点が出てきましたので質問させていただけますでしょうか。


//vsti変数 には Synth1のdllをloadした際に得たAEffect*が格納されている

AudioEffect* aex = (AudioEffectX*)vsti->object;
aex->dispatcher(
effProcessEvents,
0,
0,
&vst_events,
0.0f
);
vsti->processReplacing(
vsti,
this->inputs,
this->outputs,
kBlockSize //512
);


このようなコードを書き、this->outputsの中に結果(波形データ?)が入って返ってくることは
確認したのですが、その内容が、processEventsでどんなmidiメッセージを送っても全く
同じになってしまうのです。

例えば 曲を再生して一番最初にドを発音するMidiイベントをvstiに送ると

this->outputs[0][0]; //3.94429e-09
this->outputs[0][1]; //2.08869e-08
this->outputs[0][2]; //3.11984e-08
this->outputs[0][3]; //4.43643e-08
this->outputs[0][508]; //8.25091e-07
this->outputs[0][509]; //8.25096e-07
this->outputs[0][510]; //8.251e-07
this->outputs[0][511]; //8.25104e-07

というデータが返って来ました。

しかし、開発中のVstHostを再起動し、今度はドではなく数オクターブ離れた別の音の
イベントを送信しても、
上と全く同じデータが返ってくるのです。

また、生成し始めて2つ目のイベント、3つ目のイベントなども
再起動してもそれぞれ全く同じになってしまいます。
また、processEvents & processReplacingを数回繰り返すと今度は浮動小数点が全く返ってこなくなり、
全て nan という文字列で埋まった float** this->outputs しか返さなくなってしまうようです。

processEventsでvstiに送っているイベントは大体以下のような感じです

vst_events.numEvents; // 1
vst_events.reserved; // 0
vst_events.events[0]->type; // 1
vst_events.events[0]->byteSize; // 24
vst_events.events[0]->deltaFrames; // 0
vst_events.events[0]->data[0]; // 0xffffff90 (ノートオン)
vst_events.events[0]->data[1]; // 0x3c (真ん中のドの音)
vst_events.events[0]->data[2]; // 0x64 (ベロシティ100)


どこかがおかしいのだと思うのですが、原因としては何が考えられますでしょうか・・
ご教示頂けると嬉しいです。

4128:2012/12/11(火) 01:15:49
度々書き込み失礼致します。

色々と調べておりまして、以下のURLで
http://www.kvraudio.com/forum/viewtopic.php?t=360826#
こう書かれているのを見つけました。

-------------------------------------------------
- all the MIDI events for the next audio buffer will be sent in one processEvents() call, rather than multiple calls.
-------------------------------------------------

VstEventsに複数の必要な分のVstEventを持たせ、processEventsは一回しか呼ばないようにしましょう、
つまり、曲の頭から終わりまでのすべてのVstEventを持ったVstEventsを一気に1回だけvstiに送って、
その後に一回だけprocessReplacingを呼びましょう、という風に読めたのですが、
この解釈で合っていますでしょうか。

管理人様のHPのこちらのページ
http://www39.atwiki.jp/vst_prog/pages/77.html
で、

【ホストアプリケーションの動作】
①processEvents()関数呼び出し
     ↓
②processReplacing()関数呼び出し
     ↓
③いろいろ処理
     ↓
④processEvents()関数呼び出し
     ↓
⑤processReplacing()関数呼び出し
     ↓
・・・・以降繰り返し     
     
のような記述がありましたので、
VstEvent一個につきprocessEventsを毎回発行するということかと思っていたのですが
自分の勘違いでしたでしょうか。
(よくよく考えればprocessEvent's' ですし、deltaframeという領域もあるので
イベントを一個一個送るのはおかしかった気がします)

しかし、この考え方ですと、曲の頭から終わりまでのすべてのwavデータをホスト上でバッファとして持っておく必要があるように思われ、
メモリの容量的に大丈夫なのだろうかなどという懸念が出てきます。

色々と自分が分かっていないのだと思うのですが、
ご指南いただけますと幸いです。

42管理人:2012/12/11(火) 02:19:20
>>28さん

まず気になったのは下記の部分です。
> vst_events.events[0]->data[0]; // 0xffffff90 (ノートオン)
> vst_events.events[0]->data[1]; // 0x3c (真ん中のドの音)
> vst_events.events[0]->data[2]; // 0x64 (ベロシティ100)

VstEvent構造体のdata[0]〜[3]はVstMidiEvent構造体のnoteLengthとなるかと思います。
それぞれの構造体の定義をご確認されてみてはいかがでしょうか?


また、processEvents()関数の呼び出しですが、マニュアルには下記のように記載されておりますので
http://www39.atwiki.jp/vst_prog/pages/77.htmlの解釈で間違いないと考えております。
> Events are always related to the current audio block. For each process cycle,
> processEvents() is called once before a processReplacing() call (if new events are available).


最後に、VST SDK中のminihostサンプルをもとにVSTiを呼び出すサンプルを作成してみましたが
波形は正常に生成されているようです。
http://www39.atwiki.jp/vst_prog/?cmd=upload&act=open&page=sample&file=host.zip

VSTiはこちらのページのものを利用しております。(ファイル名は変更しております。)
http://www39.atwiki.jp/vst_prog/pages/84.html

ご参考にされてみてはいかがでしょうか?

4328:2012/12/15(土) 01:14:06
管理人様

レスいただきありがとうございます。
お礼が遅くなりまして申し訳ございません。

>VstEvent構造体のdata[0]〜[3]はVstMidiEvent構造体のnoteLengthとなるかと思います。
なるほど・・ご指摘ありがとうございます。
(VstEvent*)&vst_midi_event;
このやり方で試してみることにします。

まだ解決していない状況でございまして、諸々調べている途中です。

進捗がありましたらご報告させていただければと思います。

4428:2012/12/15(土) 01:21:44
お礼が抜けておりました。
懇切丁寧にサンプルまで付記していただきましてありがとうございました。
こちらも現在参考にさせていただいております。

45管理人:2012/12/15(土) 14:40:38
>>28さん

確認不足で申し訳ありません。
>>42で作成したサンプルでSynth1を実行するとエラーとなりました。

確認したところいちいちAudioEffectXクラスのポインターを取得する必要は
なさそうです。

ですので当初のコード(http://codepad.org/m52oPA93)のように
> vsti->dispatcher(vsti, effProcessEvents, 0, 0, &vst_events, 0.0f);
という形で呼び出して問題なさそうです。

>>42のサンプルも修正いたしましたのでご参考までに。

4628:2012/12/16(日) 02:47:34
管理人様

ご丁寧にありがとうございます。
確かに手元で試していたところ、synth1だと処理落ちしてしまっておりました。
再度いただいたサンプルと同様の方法で試したところ正常に波形デーがが返って来るようになった感じがします。
ありがとうございます!

重ね重ねで申し訳ないのですがもう一点お伺いさせていただけますでしょうか。

サンプルの中で
for (VstInt32 processCount = 0; processCount < kNumProcessCycles; processCount++)
{
printf ("HOST> Process Replacing...\n");
effect->processReplacing (effect, inputs, outputs, kBlockSize);
}
という処理があるのですが、この意図するところがよく分からないのです。

kNumProcessCycles は5に設定されていますが、1回のprocessEventsの実行に対して
なぜ5回のprocessReplacingが必要になるのでしょうか。
この5という数字はどこから来ているものなのでしょうか。
(もしかするとVstEventsのMidiデータを実際音として鳴らした時の長さと関連があるのか?
などど考えております)

ご存知でしたら教えていただけますと幸いです。

47管理人:2012/12/17(月) 00:28:01
>>28さん

本来は1回のprocessReplacing()関数に対して1回のprocessEvents()関数を呼び出すべきかもしれませんが
今回のサンプルではイベント(ノートオンMIDIメッセージ)を最初にVST(Synth1)に渡した後は、とくにイベントが
ありませんでしたので省略いたしました。

本来であれば下記のようにすべきかと思います。
(このあたりもサンプルに反映させましたのでご参考までに。)

 if( ホストアプリからVSTに渡すイベントがあるか? )
 {
  // ホストアプリからVSTに対して渡すイベントを作成する。
  〜〜何らかの処理を行い、VstEvent構造体(仮にeventとする)を設定する〜〜

  // numEventsを1とし、eventsにイベントのポインタを格納する。
  evs.numEvents=1;
  evs.events[0] = (VstEvent*)&event;
 }
 else
 {
  // ホストアプリからVSTに対して渡すイベントはないので、
  // numEventsは0にする
  evs.numEvents=0;
 }

 // ProcessEvents()関数を呼び出し、VSTにイベントを渡す。
 effect->dispatcher (effect, effProcessEvents, 0, 0, &evs, 0.0f);

 // 波形をkBlockSize分生成し、outputsへ格納する。
 effect->processReplacing (effect, inputs, outputs, kBlockSize);

また、kNumProcessCyclesですが、おそらく生成される波形が短すぎるため、
何度かループで呼び出しているだけだと思います。
(サンプルはSteinbergのVST SDK付属のものをベースにしていますので
真意は分かりません)

processReplacing()関数は1回呼び出されるとkBlockSize分の波形を生成します。
サンプリング周波数44100Hzの場合、512サンプル分ですので約11ミリ秒の
波形を生成しますが、これでは生成された波形を確認しづらいため、
5回(つまり約58ミリ秒分)としているのだと思われます。

4828:2012/12/22(土) 23:24:09
>>管理人様

レスありがとうございます。
またしてもお礼が遅くなりましてすみません。

>また、kNumProcessCyclesですが、おそらく生成される波形が短すぎるため、
>何度かループで呼び出しているだけだと思います。
>(サンプルはSteinbergのVST SDK付属のものをベースにしていますので>
真意は分かりません)
>processReplacing()関数は1回呼び出されるとkBlockSize分の波形を生成します。
>サンプリング周波数44100Hzの場合、512サンプル分ですので約11ミリ秒の
>波形を生成しますが、これでは生成された波形を確認しづらいため、
>5回(つまり約58ミリ秒分)としているのだと思われます。

なるほど・・ご丁寧にありがとうございます。
管理人様のおかけで諸々の疑問点が解消されました。
正しい波形データが返ってくることも確認でき、ちょっとずつ前に進めています。

また書込さみせていただくことがあるかもしれませんがどうぞよろしくお願いします。
ありがとうございましたm(_ _)m

4928:2012/12/23(日) 12:36:10
>>管理人様

1点お聞きし忘れたのですが、
管理人様の開発成果物のvstiはどこかのページで公開されているのでしょうか。
http://www39.atwiki.jp/vst_prog/pages/43.html
こういったサンプルのページは見つけたのですが、
オフィシャルなダウンロードサイトのようなものは見当たりませんでした。
もしお在りでしたらぜひ拝見させていただきたいです。

よろしくお願いいたします。

50管理人:2012/12/23(日) 14:58:25
>>28さん

疑問が解消されてよかったです。

サンプルVSTですが、楽器として使えるほどのものではないので
DLLファイルは特にアップロードしていません。
VSTとして動かしたい場合はビルドしていただければよいかと思います。

VC++ プロジェクトの準備(下記URL参照)にしたがってプロジェクトを作成した後、
サンプルコード一覧(下記参照)でダウンロードしたサンプルをプロジェクトに追加すれば、
コンパイル・ビルドができるはずです。
コンパイル・ビルドができなければご指摘いただければと思います。

VC++ プロジェクトの準備
 No1. http://www39.atwiki.jp/vst_prog/pages/55.html
 No2. http://www39.atwiki.jp/vst_prog/pages/59.html
 No3. http://www39.atwiki.jp/vst_prog/pages/60.html
 No4. http://www39.atwiki.jp/vst_prog/pages/61.html
 No5. http://www39.atwiki.jp/vst_prog/pages/62.html

サンプルコード一覧
 http://www39.atwiki.jp/vst_prog/pages/43.html

5128:2013/01/02(水) 23:57:06
管理人様

あけましておめでとうございます。
レス頂きありがとうございます。
またもお礼が遅くなりましてすみませんでした。

上記了解致しました。
サンプルの方も拝見させて頂きます。

ありがとうございましたm(_ _)m
また書き込みさせていただくやもしませんが
よろしくお願いいたします。

52管理人:2013/01/03(木) 11:01:51
>>28さん

あけましておめでとうございます。
サンプルのほうも不明点等があれば
ご質問いただければと思います。

今後ともよろしくお願いいたします。

5328:2013/04/16(火) 14:17:44
管理人様

お世話になっております。
数ヶ月ほど前、色々と質問させていただきました28です。

簡易daw的なものを作っており、いただいたアドバイスのおかげもありまして
それになりに音を再生できるようになってきていますが、
また分からないことが生じたため質問させていただきに来ました。

vstiが返す波形データについてなのですが、
synth1が返す波形データをざっと眺めたところ -1.0〜1.0 の範囲で収まっているように見えました。
また
http://www13.plala.or.jp/kymats/study/MULTIMEDIA/waveOut_create.html


「16ビットの場合は、-32768〜32767 の範囲で振幅値を表現します。0 が中心(振幅なし)です。」

とあったので、
synth1から帰ってきたサンプルの値それぞれに 32768を掛け、-1を引くというやり方で
波形データを生成してみたのですが、
その波形データをwaveOutWriteで書きだして発音させる際、
音が大きかったり何音も重なっていたりすると音が割れることがあるのに気付きました。
調べてみると、最初はsynth1から返ってくるサンプル値は全部 -1.0〜-1.0に収まっていると思っていたのですが
実際にはたまに -1.0〜1.0に収まらない値 (1.01など)がsynth1から返ってきていることが分かり、
そのサンプルを発音させようとした際に音が割れてしまっているようでした。

そこで2点お伺いしたいのですが、
vstiは基本的に -1.0から1.0までの範囲での値しか返さないようになっているなどの決まりはないのでしょうか?
またvstiから帰ってきたデータを16ビット用のwaveデータに変換する際、
32768を掛けて-1するというやり方は何か間違っている気がするのですが、
他によい方法はありますでしょうか。

ご教示いただけると嬉しいです。
宜しくお願いします。

54管理人:2013/04/16(火) 21:20:15
お久しぶりです。

確認したところ、
「入出力の範囲が-1.0〜+1.0でなければならない」
という決まりはないようです。

私のサイトもSynth1作者のDaichi様のサイトを
非常によく参考にさせていただいており、
その中の一部の記載を勘違いしたものと思います。

また、16ビット用waveデータに変換する方法ですが、
波形データが-1.0〜+1.0であれば、32767を掛けるだけで
よいと思います。

(「32768を掛けて-1する」方法は単純に計算ミスがあり、
最低値の-1.0に対して上記計算を行うと、-32769になり、
16bit整数の場合は負のオーバーフローが発生します。)

VSTについての理解は私もまだまだのところがあり、
DAWとなるとほとんどわかりませんが、VSTやDAWなどにかかわらず
基本的に他者の作ったプログラムやモジュールなどを組み込む際は
「予期せぬ値が合った場合にどのように処理するか?」
が重要になってくると思います。

今回のように-1.0〜+1.0の範囲を超える可能性がある場合は、
掛ける値を30000程度にして余裕を持たせたり、
浮動小数点の値を適正範囲になるよう
「-1.0以下の場合は-1.0に、+1.0以上の場合は+1.0」
と条件処理を付け加えるとよいと思います。

5528:2013/04/21(日) 22:18:11
管理人様

こんばんは。

またしてもお礼が遅れましてすみません。
わかりやすくご丁寧な解説ありがとうございます。

上のレスを拝見させていただき色々と勘違いしていたのが分かりました。
>(「32768を掛けて-1する」方法は単純に計算ミスがあり、
これについてはお恥ずかしい限りです・・・汗

自分はそもそも、windows上では返って来た波形に必ず32768
をかけなければいけないのではないかと思っていました。
色々試してたところ 32768をかけても30000をかけても、1000しかかけなくても、
変わるのは音量だけで音の質は全く変わらないのですね。
かける数を変えると全然違う音色になってしまうのではないかと思っていました。
波形と音の関係性について理解が足りておりませんでした。

また少し音声のデジタル生成について理解が深まりました。
ありがとうございました。

また質問させていただくこともあるかと思いますが、よろしくお願い致します。

56管理人:2013/04/21(日) 22:59:21
>>28さん

無事解決してよかったです。
今後ともよろしくお願いします。

57<削除>:<削除>
<削除>

58<削除>:<削除>
<削除>

59<削除>:<削除>
<削除>

60名無しさん:2013/07/01(月) 03:17:08
初めまして。
趣味でVST作成を始めたのですが、
管理人様のサイトのおかげでなんとかプラグインを作成できるようになってきました。
ありがとうございます。

まだ、ここをご覧になっていらっしゃるかわかりませんが質問させてください。
現在、ステレオトラック2つを入力可能なVSTを作成しようとしています。、
最終的にはトラック1にかける処理をトラック2の信号の情報を使って決める
サイドチェイン搭載エフェクターのようなものを目指しています。

しかし、VSTがHost側から信号を受けとる仕組みがいまいち分からず、困っています。
現在は、Host側のセンドリターン機能を使って、トラック1にトラック2の信号を送っているのですが、
センドで送られてきたトラック2の信号をVST側ではどのように受け取ればいいのでしょうか。
また、上記の方法以外に何か良い実装法があればご教授いただけると助かります。

文章で説明するのが下手で支離滅裂になってしまって申し訳ありません。
もしご覧になっていたらご返信よろしくお願いいたします。

61管理人:2013/07/02(火) 01:05:54
>>60さん始めまして。
書き込みありがとうございます。
今のところほぼ毎日確認しておりますのでご安心ください。

サイドチェインはやったことが無いのでなんともいえませんが、
AudioEffectXを継承した自作クラスのコンストラクタでsetNumInputs()関数を呼び出すときの引数を
「4」にしてみてはいかがでしょうか?

setNumInputs()関数の引数を「4」にしてSonar 8.5 LEで試したところ、参考URLの
設定とほぼ同様のことができそうでした。
(何らかの信号処理をしたわけでは無いのであくまで可能性です。)

 参考:http://tandess.blog121.fc2.com/blog-entry-818.html

 実施内容:
  トラック1のエフェクターとして自作VSTを設定。
  トラック2のセンドに自作VSTの別入力を設定。

また、processReplacing()関数での音声処理は、インプットを4つにすればいいかと思われます。

void MySampleVST::processReplacing (float** inputs, float** outputs, VstInt32 sampleFrames)
{
  float* inL1 = inputs[0]; //入力 左用1(トラック1用。エフェクターに設定したときの入力?)
  float* inR1 = inputs[1]; //入力 右用1(トラック1用。エフェクターに設定したときの入力?)
  float* inL2 = inputs[2]; //入力 左用2(トラック2用。センドに設定したときの入力?)
  float* inR2 = inputs[3]; //入力 右用2(トラック2用。センドに設定したときの入力?)
  float* outL = outputs[0]; //出力 左用
  float* outR = outputs[1]; //出力 右用

  for (int i = 0; i < sampleFrames; i++)
  {
    //ここで何らかの音声処理を行う。
  }
}

私自身やったことがありませんのであくまで推測になります。
調べてみますが、もし結果がわかりましたら、教えていただけると助かります。

62管理人:2013/07/08(月) 00:30:02
>>60さん

遅くなりましたが、>>61の方法で簡単なサイドチェイン付きコンプレッサーの
サンプルを作成してみました。ご参考にしていただければ幸いです。

・サンプルコード ダウンロードページ
 http://www39.atwiki.jp/vst_prog/pages/43.html

不明点等がございましたら書き込みをお願いいたします。

6360:2013/07/10(水) 14:16:33
>>62
管理人様
先週は多忙でこちらを覗いておらず、お返事が遅くなってしまい大変申し訳ありません。
管理人様の方法で、私の環境でも4入力で動作させることができました。
サンプルコードまで添付していただき非常にわかりやすかったです。
この部分の実装で困り果てていたので、本当に助かりました!ありがとうございます!
しかし、入力数をいじるだけで内部で受け取ってもらえるのは意外でした。少し難しく考えすぎていたようです。

教えて頂くばかりで恐縮ですが、また何か疑問が生じたら質問させてください。
ありがとうございました!

64管理人:2013/07/10(水) 22:00:17
>>60さん
無事解決してよかったです。

各トラックからの入力方法については
ホストアプリケーション(Cuabase、Sonar等)ごとに
異なる可能性がありますのでご注意ください。

今回はSonar 8.5 LEで試しましたが他のソフトでは
どうなるかわかりません。
(もしSonar以外で試されて、成功していましたら、
成功したソフトをご教示いただけるとありがたいです。)

なお、サンプルコードのコンプレッサー(CComp::Run()関数)ですが、
計算式はおそらく間違っていますのでこちらもご注意ください。

ほぼ毎日確認しておりますので何かほかに疑問がありましたら
わかる範囲・できる範囲で答えさせていただきます。
書き込みありがとうございました。

65<削除>:<削除>
<削除>

6660:2013/08/19(月) 14:28:03
お久しぶりです。
昨月サイドチェインについて質問させていただいた者です。
別環境で動作させた結果、Reaper、CubaseLEでの動作を確認いたしました。
ご報告が遅くなってしまい申し訳ありません。
お陰様でVSTの制作捗っております。
最近は練習を兼ねていろいろなVSTを作成しています。

現在、FFTを用いた処理を実装しようと試みています。
手始めに単純に入力→FFT→IFFT→出力といったVSTを作成しているのですが、
単体で動作確認済みのFFTプログラムをVSTの処理として組み込むと
DAW側の動作が停止してしまうという問題に悩んでいます。

止まり方としては、音源が読み込まれ再生される前に動作が停止してしまいます。
何となくメモリの確保の仕方がまずいような気がするのですが、いまいち原因がわかりません。
VST開発で、メモリの確保などで気を付けなければならない点などがあるのでしょうか?
また、FFTを用いたVSTの作成経験がおありでしたら、似たような問題が起こった事がありましたでしょうか?

コードを直接張れればいいのですが量が多くなってしまうため張れず、
必然的に前回よりもさらに漠然とした答え辛い質問になってしまっていて大変申し訳ありません。
上記の問題に関して何か思い当たる点がありましたらご教授いただけると幸いです。

67管理人:2013/08/20(火) 00:15:47
>>60さん

情報ありがとうございます。

残念ながらFFTを用いたVSTは作ったことがありません。

コードを見ていないのでなんともいえませんが、
音源(自作VST)が読み込まれてから再生されるまでの間なので
コンストラクタでの処理に問題があるような気がします。

また、一般的な注意事項ですが、
DAWはマルチスレッドのプログラムですので、自作VSTを作成する場合も
頭に入れておく必要があります。

同じメモリ領域へのアクセスを禁止したり、
一定時間処理を返さない処理(たとえば、モーダルダイアログの表示など)には
気をつける必要があります。

最後に、直接関係無いとは思いますが、
processReplacing()関数では下記のような制限があるようです。
・引数のfloat** inputsおよびfloat** outputsはDAWによっては同じポインタが
 渡される可能性がある。
・processReplacing()関数は数ミリ秒程度で応答する必要がある。

もう少し情報があると何かいい答えがあるかもしれません。
よろしくお願いいたします。

68名無しさん:2013/08/20(火) 23:54:28
>>60さん

FFTを用いたVSTのサンプルを作成いたしました。
ご参考になれば幸いです。

・サンプルコード ダウンロードページ
 http://www39.atwiki.jp/vst_prog/pages/43.html
 (「その他」の一番下にあります。)

サンプルではFFTを1から実装する知識・時間がありませんでしたので、
Webで公開されている大浦氏のFFTパッケージを利用しています。
(再配布可能で、比較的簡単に実装できそうなためです。)

・大浦氏 FFTパッケージ
 http://www.kurims.kyoto-u.ac.jp/~ooura/fft-j.html

私がサンプルを作成した際に注意した点としては、
FFT処理を実行するためのバッファと出力用のバッファは
分けた点にあります。

processReplacing()関数内での処理は下記の通りです。

①入力信号(ここではsin波を生成しています。)をFFT用のバッファに保存。
 出力は出力用バッファの内容をコピー。
②FFT用バッファに一定量たまるとFFT/IFFTを実施。
 FFT用バッファと出力バッファをスワップし、FFT/IFFT処理をした結果を
 出力できるようにする。

 ※注意
  入力信号をバッファに保存しているため、遅延が生じます。
  遅延はバッファサイズに影響します。
  サンプル実行時は音量にご注意ください。

なお、大浦氏のFFTパッケージの利用方法は下記URLを参考にいたしました。

・みる きく 考える 進む - 大浦氏のFFTの使い方
 http://geisterchor.blogspot.jp/2011/04/fft_16.html

6960:2013/09/09(月) 17:19:46
管理人様

お返事が大変遅くなってしまい本当に申し訳ありません。
私生活が多忙になり、PCに触れる機会を作ることができず、
お返事できずにおりました。

フリーのFFTでここまで使い勝手がいいものがあることに驚きました。
版権もゆるく、さまざまな用途に使えそうで助かります。

管理人様のFFTサンプルを拝見して、自前のFFTが動作しなかった原因がわかりました。
入力をバッファーに入れずにポインタを直接渡して処理した結果、予期せぬ動作をしていたようです。
また、その他にもメモリの確保がうまくいっておらず、配列のサイズ外の領域を参照したり等、
いろいろなミスが発見できました。
本当に助かりました、ありがとうございます。

お礼が遅くなってしまったことを重ねてお詫びいたします。

70管理人:2013/09/09(月) 22:20:52
>>60さん

無事解決してよかったです。
FFTは窓関数やオーバーラップ処理など私自身、まだまだ勉強すべき点がありますが、
ご参考になれば幸いです。

これからもよろしくお願いいたします。

71<削除>:<削除>
<削除>

72<削除>:<削除>
<削除>

73<削除>:<削除>
<削除>

74<削除>:<削除>
<削除>

75<削除>:<削除>
<削除>

84lyood:2013/12/10(火) 18:04:16
管理人様、はじめまして。
VSTシンセを遊び半分で作り始めてせっかくならGUIをつけよう、ということで情報を探していたところこのサイトにたどり着きました。
GUIの解説、とても参考になっております。ありがとうございます。

ところで、GUI作りで行き詰ってしまったのでひとつ質問をさせてください。
Daichi様のサイトにある「MySynth」を改造しながらシンセを作っているのですが、

ホスト(DAW)を起動、シンセのGUIからパラメタの値をいじる
             ↓
ホストでプロジェクトファイルを保存
             ↓
ホストで上で保存したプロジェクトファイルを読み込む

とすると、音は保存したときの音が出るがGUIはデフォルトの値(初期値)にもどる
という現象が起こります。パラメタの値は保存/復元できているけれどGUIが更新されていない(または下手に更新されている)感じです。
これは、何か処理が足りないために起こるのでしょうか?逆に何か変な処理をしているためでしょうか?

表現力・情報不足ですね…ごめんなさい。。
本当はソースコードを書き込めばいいのでしょうがこれ以上長くなるのもアレなので...
ご教授いただけたらうれしいです。

85管理人:2013/12/11(水) 01:45:50
lyoodさん

書き込みありがとうございます。

私のGUIサンプル(下記)においてもGUIのノブやスライダーの値が0に戻ることを
確認しました。
(私のGUIサンプルの場合、パラメーターの値も保存されておりませんでした。)

 http://www39.atwiki.jp/vst_prog/pages/82.html
 http://www39.atwiki.jp/vst_prog/pages/83.html

同じ事象ではないので原因が異なるかもしれませんが、
おそらく、原因はVSTクラス(AudioEffectXを継承したクラス)で
getParametar()関数をオーバーライドしていないためだと思います。

私のサンプルではGUIクラス(AEffGUIEditor, CControlListenerを継承したクラス)の
open()関数でボタンなどを作成する際、VSTクラスからgetParameter()関数を使って
現在の値を取得します。

 150行目前後の下記コード
 【ノブの場合】
  knobVolumeL->setValue(effect->getParameter(MYVST_VOLUME_L));
 【スライダーの場合】
  sliderVolumeL->setValue(effect->getParameter(MYVST_VOLUME_L));

しかし、VSTクラスでgetParametar()関数がオーバーライドされていないため、
呼び出されても0を返すだけとなります。

そのため、GUIクラスのopen()が呼び出されるたびにノブやスライダーの値が
0に戻ります。

getParameter関数については下記を参考にしていただければと思います。

 http://www39.atwiki.jp/vst_prog/pages/44.html

86lyood:2013/12/11(水) 20:53:37
管理人様
詳しく丁寧、迅速な返答、ありがとうございます。

getParameter()関数はオーバーライドしておりました。(MySynthに最初から書いてあったのでそれを使っていた)
その後、デバックしてみたところ、

ホスト側のGUI呼び出し(GUIクラスopen()関数が実行される)
         ↓
open関数の中でGUIのつまみなどに値をセット(GUIクラスの各パーツクラス->setValue())
         ↓
ホスト側からプログラムのセット要求(VSTクラスのsetProgram())
ここでsetParameter的なことをしている

という流れだということがわかりました。
これでは当然GUIのほうは更新されないので、新しくGUIを更新するだけの関数を作って
VSTクラスsetParameter()関数から呼び出すようにしたところうまくいきました。
(具体的にはsetValue()やらsetText()をしているだけ)

なにせつまみの数が50を超えているので
もうちょっとコンパクトにしたかったのですが、私の知識ではこれが限界…

もっと参考になる書き方をできればいいのですがどう書いていいのかわからずです...

また何かあったらお世話になるかもしれません。重ねてありがとうございました。

87管理人:2013/12/13(金) 00:22:53
lyoodさん

あまり力になれず申し訳ありません。
また何かありましたらよろしくおねがいいたします。

88管理人★:2014/06/21(土) 07:02:05
「C++でVST作り」(http://www39.atwiki.jp/vst_prog/)の更新停止について

本掲示板のもととなっている@wikiのサイト「C++でVST作り」の管理パスワードを
紛失したため、管理・更新を行うことができなくなりました。
よって「C++でVST作り」の更新につきましては停止とさせていただきます。

なお、@wikiの規約上、長期のログインが無い場合、上記サイトは削除される可能性あるとのことです。
移転先サイトも検討しておりますので、詳細は決まり次第記載させていただきます。

91管理人★:2014/06/22(日) 16:18:48
http://vstcpp.wpblog.jp/に移転予定です。
コンテンツについては整理しながら1から作り直しています。

92一条あかり:2014/07/23(水) 13:10:50
はじめまして、最近vst開発に挑戦し始めた一条あかりと申します。
FFTやoffline処理に興味を持って四苦八苦しておりますが、いいプラグインができればと思っています。

サイトのほうを再構築されるとのことで、応援しております!

93管理人★:2014/07/23(水) 23:06:55
一条あかりさん

書き込みありがとうございます。

平日の更新がなかなか難しく、再構築は進んでおりませんが、
応援いただきまして、非常にありがたく思います。

最低週1回は更新しようと考えておりますので、少し時間がかかるかと
思いますが、よろしくお願いいたします。

FFTやoffline処理についてはほとんど知識がありませんが、
技術的なお話は大好きですので、不明点がございましたら、
ご協力できることがあるかもしれません。

今後ともよろしくお願いいたします。

94でぇあ:2014/08/22(金) 12:11:31
こんにちは。でぇあと言います。
このようによく纏まったサイトを参考にさせて頂けるのは本当に助かります。ありがとうございます。
新サイト構築の方も期待しています。

さて本題ですが、毎秒GUIをを更新するサンプルをビルドしようとすると、以下のようなエラーが出ます。

1>MyVSTGUI.cpp(143): error C2259: 'VstGui' : 抽象クラスをインスタンス化できません。
1> 次のメンバーが原因です:
1> 'void CControlListener::valueChanged(VSTGUI::CControl *)' : は抽象型です
1> C:\VST3 SDK\vstgui.sf\vstgui\vstcontrols.h(105) : 'CControlListener::valueChanged' の宣言を確認してください。

もし何が問題なのかわかるようであれば教えて頂けないでしょうか。
よろしくお願い致します。

95管理人★:2014/08/22(金) 23:19:49
でぇあさん

書き込みありがとうございます。
VSTのGUIクラスを定義していると思いますが、メンバー関数の中に
valueChanged()関数がないのではないでしょうか?

VSTのGUIクラスを定義する際はvalueChanged()関数を
必ず継承しなければなりません。

下記サンプルコードの51〜54行目のように、空の関数でもいいので
定義しておく必要があります。

http://www39.atwiki.jp/vst_prog/pages/93.html

96でぇあ:2014/08/23(土) 13:47:18
管理人様

サイトを拝見しながらプロジェクトを最初から構築し直した所、ビルドがうまくいきました。
どうやら、vst2.4でなくvst3のSDKのプログラムを使ってしまっていたのが原因だったようです。
些細な事で質問してしまって申し訳ありません。
回答して頂いてありがとうございました。

97管理人★:2014/08/24(日) 12:04:47
でぇあさん

無事解決してよかったです。
今後ともよろしくお願いいたします。

98猫十:2015/06/19(金) 11:57:00
はじめまして
いつも拝見させていただいています。
とても貴重な情報をありがとうございます。

旧サイトの「毎秒GUIをを更新するGUIのサンプル」をビルドして
DAWにロードしてみたところ0からカウントアップが始まりました。
ここでふともう1つ同じものをロードしたところ先にロードしたものと同じ値からカウントアップが始まりました。
(後からロードしたものは先のとは別に0からカウントアップするものだと思っていました。)

ソースコードに同梱されていたビルド済みのMyGuiVST5.dllでも同じ現象が起きました。
ここで質問なのですが、ロードしたプラグインごとにカウンタが独立して動作するようにしたい場合はどうすればよいのでしょうか?

99管理人★:2015/06/20(土) 14:18:42
猫十さん

書き込みありがとうございます。

VstGui5::idle()内にある変数iがstaticで宣言されているため、
全DLLで共通の変数iを参照することになります。

解決するには変数iをクラスのメンバー変数として定義すればいいと思います。
修正版を下記作成いたしましたのでご参考にしていただければと思います。

 http://vstcpp.wpblog.jp/?page_id=776

 変更点
  ・VstGui5クラスのメンバ変数として「int i;」を定義
  ・VstGui5クラスのコンストラクタで「i = 0;」でiを初期化
  ・VstGui5::idle()関数内の「static int i = 0;」をコメントアウト

サンプルについてはマルチスレッドプログラミングをほとんど意識せず作成していますので、
他にもこのようなことが発生するかもしれません。

100猫十:2015/06/21(日) 03:40:09
管理人様

早速のご回答ありがとうございました。
ご指示頂きました点を変更したところ
複数起動時に独立してカウントアップしましたのでご報告させて頂きます。
マルチスレッドプログラミングに慣れた方なら
尋ねるまでもなかったような件を質問してしまいましてお恥ずかしい限りです・・・


さて大変恐縮なのですが
別件について再び質問させていただきたく存じます。

VSTにおけるパラメータの取り扱いなのですが、
例えば整数で-24〜+24を動くようなパラメータや
7段階切り替えスイッチなどのパラメータの場合はVST開発上はどのように扱うべきでしょうか?

元値→計算してfloatに変換→getParameterで取得→計算して復元、の流れでやってみたものの
端数が出たりして復元後のGUI表示の際の条件分岐や
さらにその後のGUI操作を経てsetParameterでAudioEffectX側に再度渡す際に不都合が生じてしまっています。
これを現状の変換&復元のやり方のまま力技で解決すべきなのか
それとももっと違うやり方があるのかでつまづいております。

もしよろしければどのようなやり方が望ましいのかご教示いただければ幸いです。

101管理人★:2015/06/21(日) 11:16:45
猫十さん無事解決してよかったです。

望ましいやり方…というのはプログラムの書き方はいろいろあるので
正直わからないです。

私は下記のような方法で実装しています。
(7段階切り替えスイッチの例)

■AudioEffectXを継承したクラス(以下VSTクラス)側の処理
1)まずパラメーター用のメンバー変数を定義する
 【例】
  int switch7;

2)VSTクラス setParameter()関数で渡される値を
 パラメータ用に変換
 【例】
 case 0:
  switch7 = (int)(value * 7.0f);
  break;

3)同様にVSTクラス getParameter()関数で返す値を
 0.0〜1.0に変換
 【例】
 case 0:
  return ((float)switch7) / 7.0f;
 
■AEffGUIEditor, CControlListenerを継承したクラス(以下GUIクラス)側の処理
1)GUIクラス setParameter()関数で渡される値を
 7段階にする
 【例】
 case 0:
  // 0.0f 〜 1.0fの7段階に調整
  value = floor(7.0f * value) / 7.0f;

  // 値をノブに設定
  knob->setValue (value);

  // VSTクラス側に値を引き渡し。
  effect->setParameterAutomated(index, value);


-24〜+24の整数パラメータも-24から始まる48段階のスイッチと
考えれば同じ処理で実装できると思います。

102猫十:2015/06/23(火) 03:50:42
管理人様

ご回答ありがとうございました。

早速管理人様の手法を試してみたところバッチリ動きました。
私のへんなやり方より全然いいのでまとめて修正しようと思います。

私自身「これでいいんだろうか?」の繰り返しでVSTプラグインを書いてまして
何かやるたびに壁にぶつかってる次第です。

また書き込みさせていただくかと思います。
その際は何卒よろしくお願いいたします。

103管理人★:2015/06/24(水) 00:17:52
猫十さん
こちらも無事解決してよかったです。

ご質問や指摘は大歓迎ですので
これからもよろしくお願いいたします。

104専門学生:2015/08/10(月) 15:57:22
初めまして
こちらに記載されてたソースコードをお借りしてサンプラーのVSTを作成しようとしています。
WindowsApiで音源を取得することはできるのですが、音源を格納する方法がわかりません
どうすればいいですか。

105管理人★:2015/08/12(水) 01:21:30
専門学生さん

書き込みありがとうございます。

いただいたご質問について不明な点がございますので、下記について確認させてください。

 ・WindowsAPIはどのような関数を利用しているのでしょうか?

 ・"音源"とは何でしょうか?
  (.wavや.mp3等から取得した音声信号(波形)のことでしょうか?)

 ・"格納する"というのはどうしたいのでしょうか?
  ("音声信号をバッファに格納したい"という意味でしょうか?)

106専門学生:2015/08/12(水) 11:06:19
返信ありがとうございます。
情報が不足していてごめんなさい。

ifstreamを使ってます。

音源はwavのことです。

音声信号をバッファに格納したいということです。

お手数をお掛けします。

107管理人★:2015/08/12(水) 21:58:11
専門学生さん

単純に「wavファイルを読み込みたい」ということのようですね。

説明できなくはないのですが、すでに多くのサイト様で記載されている情報ですので、
「wav 読み込み C++」といったキーワードで検索していただければと思います。

なお、他のサイト様ではwavファイルのフォーマットを理解していることを前提としていることが
多いようですので、合わせて「wav ファイルフォーマット」で検索し、wavファイルフォーマットを
理解しておくとよいと思います。

wavファイルを読み込んだ後、VST上で動作させる上で不明な点がございましたら、
再度 ご質問いただければと思います。

ちなみにifstreamはWindows APIではなくC++標準ライブラリですのでお間違いなく。

108猫十:2015/08/14(金) 13:55:06
先日はお世話になりました。
ちょっと便乗なのですが、
管理人様のVSTiのサンプルの発音部分をwav波形直読みにするにはどうすればよいでしょうか?

・wavは5秒程度のピアノ波形
・MIDIノート0から127ので10個くらいのマルチサンプル
・wavは差し替え無しで組み込んだまま(リソースとして組み込む?)
・それ以外は変更なし(サンプルのフィルタ部、アンプ部、同時発音数などはそのまま効果が出るように残したい)

こんな感じで管理人様のサンプルを改造してみようと思っています。
質問ばかりですみませんがよろしくお願いいたします。


新着レスの表示


名前: E-mail(省略可)

※書き込む際の注意事項はこちら

※画像アップローダーはこちら

(画像を表示できるのは「画像リンクのサムネイル表示」がオンの掲示板に限ります)

掲示板管理者へ連絡 無料レンタル掲示板