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

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

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

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

111管理人★:2015/08/15(土) 20:17:01
専門学生さん

load_from_file()関数はおそらくwavファイルを読み込む関数だと思います。

processReplacing()関数は数十ミリ秒ごとに何度も呼び出される関数のため、
load_from_file()関数をprocessReplacing()関数の中で呼び出すと、
数十ミリ秒間隔で何度もwavファイルへアクセスすることになります。

これにより作成したVSTiから応答が返らなくなり、結果としてDAW側で応答が
なくなるものと考えられます。

対応としては
 1.事前にコンストラクタ等でwavファイル読み込む
 2.wavファイルの読み込みを別スレッドで行う
が考えられます。

不明点がございましたら再度 ご質問いただければと思います。

なお、コードの中で気になった点がありましたので記載させていただきます。
 ・inputs[]は入力信号が入ったバッファなので、値を代入するのはまずい
 ・short型のch1[]をそのままinput[]、output[]に代入しているが
  -1.0〜1.0の範囲に変更するのが望ましい。
 ・for分の中で、iを波形データのサイズ(wav1.data_size)までとしているが、
  output[]やinput[]の配列サイズよりwav1.data_sizeが大きい場合、
  メモリ破壊につながるので、小さいほうに合わせるほうがよい。

112管理人★:2015/08/19(水) 01:15:22
専門学生さん

あれから少し確認しましたが別スレッドを使用しなくても、「ファイルの非同期読み込み」でも
wavファイルを読み込むことは対応できそうです。

Windows APIのReadFile()関数とGetOverlappedResult()関数を使い、
読み込み状態の管理を行うようプログラムすれば読み込めます。

サンプルについては作成してみようと思いますが、
去年の末からずっと忙しく、なかなか時間が取れないため
いつになるかはわかりません。

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

113管理人★:2015/08/30(日) 02:43:05
専門学生さん
猫十さん

遅くなりましたが、「wavファイルを非同期読み込みする方法」と「WAVEテーブルシンセサイザー」の
簡単なサンプルを作成いたしました。ご参考になれば幸いです。

・サンプルコード ダウンロードページ
 http://vstcpp.wpblog.jp/?page_id=776

 ■wavファイル非同期読み込み 
   20150829_MyWavTableSynthVST.zip

 ■WAVEテーブルシンセサイザー
   20150829_MyAsyncFileLoadVST.zip

114専門学生:2015/09/17(木) 12:32:51
管理人さん、
大切お時間いただいて、お返事とソースコード作成ありがとう存じます。
ソースコードをお借りして、読み解きと実装を試みてみます。

丁寧にご説明いただいてありがとうございました。
またわからなくなったらお邪魔するかもしれませんがその際にはよろしくお願いいたします。

115管理人★:2015/09/17(木) 23:44:14
専門学生さん

参考になればと思います。
またよろしくお願いします。

116<削除>:<削除>
<削除>

117管理人★:2015/10/01(木) 19:20:55
ヒーローゲーマーさん

創作小説は当サイトの掲示板とは無関係です。
他の掲示板等にもスパム的に投稿されているようなので削除いたしました。

続けるようであればブロック等の必要な処置をいたします。

118sym:2016/05/23(月) 14:59:29
「C++でVST作り」を拝見させていただいております。
日本語で解説されたサイトが少ないので重宝しております。ありがとうございます。

一点質問させていただきたいのですが、
以前作ったVSTプラグインを改良するため、新たにパラメータの数を増やそうとしているのですが、
増やした新しいパラメータの標準値が、コンストラクタでの初期化の値にかかわらず0.000000になってしまう現象に見舞われてしまいました。
前に作ったVSTとの互換性を保ちたい場合、新たに増やすパラメータは値が0.000000のときに前のバージョンと同じ挙動をするようにすること以外に方法はないのでしょうか。

動作確認に使っているVSTホストはACID Music Studio 10.0で、調べてみるとどうやら前のVSTに存在しなかったパラメータについても
プロジェクトファイルを開いたタイミングでsetParameter関数が設定値0.000000で呼ばれているようです(コンストラクタ内では値は1.000000で初期化しています)。

何か方法があれば教えていただけるとありがたいです。よろしくお願いします。

119管理人★:2016/05/25(水) 07:28:37
symさん
書き込みありがとうございます

詳しくはわからないのですが、
setChunk()、getChunk()関数あたりを使えばうまくできるかもしれません。
(VST SDK 2.4の場合です。)

setChunk()、getChunk()関数はVSTプラグイン独自のパラメータ形式で
保存したい場合に使用する関数です。

setChunk()、getChunk()関数をオーバーライドし、
「自作VSTのパラメーター + バージョン情報」を保存しておけば、
自作VSTのバージョンに合わせて前バージョンから値を引き継ぐパラメータと
初期化するパラメーターで分けれるのではないかと思います。

詳しい使い方は正直わからないので私もこれから試してみます。
何かわかればお伝えいたしますが、少しお時間をください。

120管理人★:2016/05/28(土) 10:18:44
symさん

setChunk()、getChunk関数の使用方法がわかりましたので
サンプルソースコードを下記にアップロードしました。

・サンプルコード ダウンロードページ
 http://vstcpp.wpblog.jp/?page_id=776

 ■ファイル名
   20160528_MyChunkTestVST.zip

setChunk()、getChunk関数をオーバーライドするとともに
コンストラクタでprogramsAreChunks()を呼び出す必要があります。

>>119で書いたように「自作VSTのパラメーター + バージョン情報」を
保存しておけば、実装できると思いますので一度試していただけますでしょうか?

121sym:2016/05/30(月) 22:19:21
>>120
管理人さん

まさかサンプルまで作っていただけるとは、非常に助かります!
今から試してみて、また書き込ませていただきます。ありがとうございます。

122sym:2016/05/31(火) 11:15:38
管理人さん

作っていただいたサンプルをもとに試したところ、
希望通りの挙動をしてくれるようになりました。
丁寧にコメントを付けてくださっていたので助かりました。

programsAreChunks関数を呼んでいない状態のVSTで作られたfxpファイルやDAWのプロジェクトファイルを
programsAreChunksでtrueとした状態のVSTで読み込む際は、どうやらsetChunk関数が呼び出されないようだったので、
今回のバージョンに限ってこれをもとにChunkを使っていない旧バージョンであるかどうかを判定することにしました。
ご教示いただいたとおり見えないパラメータとしてバージョン情報を書き込むようにしたので、次回バージョンからそちらでバージョン判定をしようと思います。

サンプラーでのファイル名であったり、Glitchなど可変長のデータを扱うようなVSTをいくつか見てきてこれまで疑問に思っていたので、そういった点でも非常に参考になりました。
今回はありがとうございました。

123管理人★:2016/05/31(火) 20:34:54
symさん

無事解決してよかったです。
また何かありましたら可能な範囲で調べてみます。

124名無しさん:2017/03/17(金) 23:39:29
https://www39.atwiki.jp/vst_prog/pages/79.html

こちらの CMidiMsgの addMidiMsg と getMidiMsg の処理中での キュー処理 問題があるのでは?
add add get get add get の順に呼び出すと、未格納なバッファにアクセスすることになるかと思います。

125管理人★:2017/03/20(月) 02:13:38
>>124さん
ご指摘ありがとうございます。

たしかにaddMidiMsg()の途中でgetMidiMsg()を呼び出すと
何が格納されているか分からない領域にアクセスしますね…
(buf[]領域内なのでVSTが落ちるようなことはないと思いますが…)

VST2.4だと「processEvents()→processReplacing()」の順に呼び出され、
基本的には「clearMidiMsg()→addMidiMsg()×n回→getMidiMsg()×n回」
の順になるのであまり問題はないと考えています。

本来なら修正すべきですが、少し手間なのでそのままにしたいと思います。
他のアプリでCMidiMsgクラスを流用する場合は修正する必要があります。

126らいか:2017/09/21(木) 14:35:57
初めまして。
ここ数日このサイトにお世話になっているVST初心者です。

質問なのですが、管理人さんが作成した手順「VST3.6勉強中 2 – VST3作成の準備」から「VST3.6勉強中 6 – VST3プラグインのパラメーター実装方法2」までを実装し、
processor.cppのtypeに自分で新たに作成したものを追加しながらVSTを学んでいたのですが、先日ソースを弄り、ビルドを行いVST3PluginTestHostで動作を確認しようとしたところ、
急にVST3PluginTestHostでファイルを認識しなくなってしまいました・・・

手順通りプロジェクトを作成しなおしてみたのですが、結果は同じでした。辛うじてVST3PluginTestHostが読み込んでくれるVSTファイル(VST3.6勉強中 6 – VST3プラグインのパラメーター実装方法2まで実装したもの)が見つかったので、
それと作成しなおしたVSTファイルと比較ツールにかけたところ、ある程度書かれている内容は同じなのですが書かれているアドレスが異なっていることファイルになっていました・・・

コンパイル自体は通っているのですが正しいVST3ファイルとしてホストに認識されていない状態です。また自分で追加していた内容もVST3ファイルがきちんとホスト側で認識されていた時は問題なく動いたので、
プロジェクトの環境を無意識に弄ったのかもしれませんがお手上げ状態です

とりとめのない質問で申し訳ないのですが、よろしければ管理人さんのお力を貸してください

使用している環境は
win10
Visual Studio2015
VST3.6.7(最新版)
です

127管理人★:2017/09/21(木) 21:59:29
らいかさん

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

考えられるのは
 何かの拍子にビルドがDebugからReleaseになってしまった
ぐらいです…

他に何か思いつけば再度返信させていただきますが、
いただいた状況になったことがないので、原因については正直わからないです…

あまりご協力出来ず申し訳ありません。

128らいか:2017/09/22(金) 09:41:22
>>127 管理人さん

おはようございます。

SDK等使用したソースをDLしなおして解決できました!
原因はVST3_SDKのdllmain.cpp内の
extern bool InitModdule();
extern bool DeinitModule();
をコメントアウトしてました・・・

SDKからコピーしてソースファイルを使用していたつもりでしたが、どうやらコピー元のSDKを取り込んで作業を行っていたみたいです・・・(そりゃ作り直してもおかしいわけだ)

その後色々見なおしていたところ、factory.ccp(20141209_vst3版)のDLLファイルの初期化、終了関数のコメントを歪曲して理解していたらしく、
基本的に何もする必要がない→何もしていない→必要ない っと理解してコメントアウトしたみたいです(だんだん思い出してきた)

最近鎮痛剤を服用しているのでそのせいで半分寝ぼけてコード弄ってたんでしょうね・・・

ともあれお騒がせしました<(_ _)>

VST関係の日本語の情報が少ないためまたお世話になると思いますがその時はよろしくお願いします!

129管理人★:2017/09/22(金) 20:44:00
らいかさん

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

http://vstcpp.wpblog.jp/?p=694 に記載している内容が
おそらく最小構成なので2つの関数を消してしまうと
確かに動かなくなりますね…

いろいろ試すのはいいことだと思います。

私は最近別のことに興味を持っており更新が滞っていて申し訳ありません。
内容的に不十分な点(パラメーターの保存方法やGUIがない 等)がありますので、
引き続きご質問いただければわかる範囲で答えさせていただきます。
(場合によってはサイト更新もいたします。)

130Low:2017/10/20(金) 03:44:24
初めまして。ここ最近サイトの方を拝見させていただいています。

VST3.6.7を使っているのですが、VST3の基本ライブラリの作成、というところで、
base_vc10.vcxprojや、それに近い名前のファイルが見当たりません。
VisualStudio2017を使用しているのですが、
この場合、どのようにして、基本ライブラリを作成すればよろしいでしょうか?

ご協力いただけると助かります。よろしくお願いします。

131管理人★:2017/10/20(金) 22:36:00
Lowさん

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

下記に記載している基本ライブラリ作成の手順は
3.6.0での手順となっています。

 http://vstcpp.wpblog.jp/?p=683

3.6.7ではまず「CMakeLists.txt」をもとに
プロジェクトファイルを作成するところから始まるようです。

私も今から試すのですが、
おそらく手順としては下記になります。

 http://www.wakayama-u.ac.jp/~chen/cmake/cmakecxx.html

上記のツールはここからダウンロードできるようです。

 https://cmake.org/download/

私も試したことのないやり方です。
上記のサイトからダウンロード等する際は十分ご注意ください。

何かわかりましたら改めてご連絡いたします。

132Low:2017/10/21(土) 00:50:42
ご返信ありがとうございます。
今、試してみています。

133管理人★:2017/10/22(日) 14:17:18
Lowさん

私の試した手順で基本ライブラリらしきものができました。
試してみてください。

1.CMAKEを下記からダウンロードし、インストールする

 https://cmake.org/download/

2.VST SDK 3.6.7を任意のフォルダに解凍する

3.解凍したフォルダの「VST_SDK\VST3_SDK」配下に「build」フォルダを新規作成

4.cmakeを起動し、下記の通り設定

 ・where is the sorce code
    →「VST_SDK\VST3_SDK」を指定
・where to build the binaries
    →「VST_SDK\VST3_SDK/build」を指定

5.cmake下側の「Configure」ボタンを押し、下記を設定し
 「Finish」ボタンを押す

  Specify the generator for this project
    →「Visual Studio 14 2015 Win64」を指定
  (他はそのまま)

6.cmakeの設定が自動始まり、中央部分に情報(赤字)が表示される
 「Configure」ボタンの下側のログにエラーがないことを確認する

7.「Generate」ボタンを押し、Visual Studioのプロジェクトを作成する
 「VST_SDK\VST3_SDK/build」配下に「ALL_BUILD.vcxproj」が
 作成されていることを確認する

8.「ALL_BUILD.vcxproj」を開き、Visual Studioでビルドを行う
 「VST_SDK\VST3_SDK/build/lib」配下にライブラリが作成される
 (おそらく「base.lib」が基本ライブラリだと思います。)

ここから不確定ですが、3.6.7では下記の変更点があるようです。
・64bitのみの対応
・プロジェクトのプロパティでマルチスレッド(/MT、/MTd)ではなく
 マルチスレッドDLL(/MD、/MDd)を使用する必要がある

134Low:2017/10/23(月) 17:59:20
再三失礼します。この方法で行ったのですが、5の後に、

CMake Error at CMakeLists.txt:24 (project):
Failed to run MSBuild command:

MSBuild.exe

to get the value of VCTargetsPath:

とエラーが出てしまいます。
また、このエラーを調べたのですが、自分のVisualStudioと違うものを指定した場合に出るといったことが書かれていたため、
5の設定を、Visual Studio 14 2017 Win64
で試してみたのですが、今度は、

CMake Error at CMakeLists.txt:24 (project):
Failed to run MSBuild command:

C:\Program Files (x86)\Microsoft Visual Studio\2017\Community/MSBuild/15.0/Bin/MSBuild.exe

to get the value of VCTargetsPath:

.NET Framework 向け Microsoft (R) Build Engine バージョン 15.4.8.50001

Copyright (C) Microsoft Corporation.All rights reserved.



2017/10/23 17:44:59 にビルドを開始しました。

ノード 1 上のプロジェクト "C:\vstsdk367_03_03_2017_build_352\VST_SDK\VST3_SDK\build\CMakeFiles\3.9.4\VCTargetsPath.vcxproj" (既定のターゲット)。

C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\VC\VCTargets\Platforms\x64\PlatformToolsets\v141\Toolset.targets(36,5): error MSB8036: Windows SDK バージョン 10.0.15063.0 が見つかりませんでした。必要なバージョンの Windows SDK をインストールするか、プロジェクト プロパティ ページで SDK バージョンを変更するか、ソリューションを右クリックして [ソリューションの再ターゲット] を選択してください。 [C:\vstsdk367_03_03_2017_build_352\VST_SDK\VST3_SDK\build\CMakeFiles\3.9.4\VCTargetsPath.vcxproj]

プロジェクト "C:\vstsdk367_03_03_2017_build_352\VST_SDK\VST3_SDK\build\CMakeFiles\3.9.4\VCTargetsPath.vcxproj" (既定のターゲット) のビルドが終了しました -- 失敗。



ビルドに失敗しました。



"C:\vstsdk367_03_03_2017_build_352\VST_SDK\VST3_SDK\build\CMakeFiles\3.9.4\VCTargetsPath.vcxproj" (既定のターゲット) (1) ->

(Desktop_PlatformPrepareForBuild ターゲット) ->

C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\VC\VCTargets\Platforms\x64\PlatformToolsets\v141\Toolset.targets(36,5): error MSB8036: Windows SDK バージョン 10.0.15063.0 が見つかりませんでした。必要なバージョンの Windows SDK をインストールするか、プロジェクト プロパティ ページで SDK バージョンを変更するか、ソリューションを右クリックして [ソリューションの再ターゲット] を選択してください。 [C:\vstsdk367_03_03_2017_build_352\VST_SDK\VST3_SDK\build\CMakeFiles\3.9.4\VCTargetsPath.vcxproj]



0 個の警告

1 エラー



経過時間 00:00:00.16



Exit code: 1

といったエラーが出てしまいます。
そこで、プロジェクトのプロパティを変更し、ソリューションの再ターゲットを行ったのですが、やはり同様のエラーが出てしまいます。
これらの原因はわかりますでしょうか?

135管理人★:2017/10/23(月) 21:32:23
Lowさん

CMAKEについては詳しくないのですが、エラーで
「Windows SDK バージョン 10.0.15063.0 が見つかりませんでした」
とあります。

「Visual Studio 2017 バージョン 15.3 の既知の問題」(下記)には
特定の条件下で「Win32 C++ デスクトップ プロジェクトに必要なヘッダー/ライブラリが
インストールされません。」とあります。

  https://msdn.microsoft.com/ja-jp/vs-knownissues/vs2017-knownissues

  ※「Windows 10 Creators Update SDK (10.0.15063.0) をインストールした後、
   新しく作成した C++ Win32 デスクトップ プロジェクトをビルドできない」の項目です。

回避策としてはインストーラーで [C++ によるデスクトップ開発] ワークロードの
[デスクトップ C++ x86 および x64 用 Windows 10 SDK (10.0.15063.0)] 機能を
選択する必要があるようです。

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

136管理人★:2017/10/23(月) 21:53:28
Lowさん

どうしてもCMAKEがうまくいかない場合、
古いバージョンのものを利用してみてはいかがでしょうか?

■VST SDK 3.6.6
http://www.steinberg.net/sdk_downloads/vstsdk366_27_06_2016_build_61.zip

■VST SDK 3.6.5
http://www.steinberg.net/sdk_downloads/vstsdk365_12_11_2015_build_67.zip

なお、上記リンクのファイルについては安全かどうかわかりませんので十分ご注意ください。
(ドメインがwww.steinberg.netなので大丈夫だと思いますが…)

また、リンクがいつ切れるかわかりませんのでご了承ください。
(2017年10月23日の時点では生きているようです。)

137Low:2017/10/24(火) 11:16:50
ありがとうございます。
[デスクトップ C++ x86 および x64 用 Windows 10 SDK (10.0.15063.0)] 機能を選択して、何度か追加しようとしたのですが、なぜかチェックを入れて変更をしても追加されなかったため、
(他のバージョンのものは選択したらちゃんと追加されたのですが、なぜかこれだけ。)
VSTSDK3.6.6を試してみたところ、ライブラリファイルが作成でき、また、
サンプルに入っていたものをビルドしてみたところ、それらしき者ができたため、動作が確認できたものと思われます。

138管理人★:2017/10/24(火) 22:15:03
Lowさん

CMAKEが解決できなかったのは残念ですが、
3.6.6でVSTを作れそうなのは良かったです。

また何か有りましたらよろしくお願いします。

139らいか:2017/10/31(火) 14:35:42
お久しぶりです、早速ですが質問したいことがあります。

会社にあるVSTプラグインのソースをたどっているのですが、処理等を行っている関数の呼び出しがないものが多く、
実際に動いている関数なのか、動いていない関数なのかよくわかりません。何か判断する方法はありますでしょうか?

http://vstcpp.wpblog.jp/?page_id=437
例えば上記のコード(管理人さん作)の23〜35行目で関数の宣言をしていて、40行目〜167行目まで関数の定義がされていると思います。
この中で関数createEffectInstanceはVSTのSDKの内容から呼び出されていているのはわかるのですが、
それ以外の関数はどのように呼び出されているかわかりますでしょうか?

140らいか:2017/11/01(水) 16:55:06
>>139

お騒がせしました。解決しました。

継承元のAudioEffectXクラスに記載されているメンバー関数をオーバーライドって書いてありましたね(-_-;)

141管理人★:2017/11/01(水) 20:56:37
らいかさん

お久しぶり(?)です。書き込みありがとうございます。

無事解決してよかったです。
また何かありましたらよろしくお願いします。

142らいか:2017/11/14(火) 11:07:52
更新お疲れ様です。いっぱい更新が来ててびっくりしました。
とりあえず更新分を試したのですが躓いたので質問です。

まず http://vstcpp.wpblog.jp/?p=1095 を参考にVST_SDK3.6.7の基本ライブラリの作成を行いました。

次に http://vstcpp.wpblog.jp/?p=683 を参考にプロジェクトの作成を行いました。
プロジェクトのプロパティの設定
C/C++ コード生成 ランライムライブラリ マルチスレッドデバッグ(/MTd)
リンカー 入力 追加の依存ファイル base_vc10.lib (デバッグ版)
上記の記載内容は基本ライブラリに合わせて
マルチスレッドDLL(/MD、/MDd)
base.lib
に変更して設定しました。

次に http://vstcpp.wpblog.jp/?p=1016 のソースファイル一式を作成したプロジェクトに追加してビルドしたのですが、
未解決の外部シンボル系のエラー(LNK2001,LNK2019)が16個ほど出てしまい、うまく実行できません。

少しググって入力しているライブラリとプロジェクトの文字コードの設定が違うとこのエラーが出るとあったので、
試したのですが解決はしませんでした。

何か他に設定し忘れている内容ってありますでしょうか?

143管理人★:2017/11/14(火) 18:32:25
らいかさん

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

VST SDK 3.6.7はまだ試していないので詳細まではわからないです。
(そろそろ触ってみようと思うのですが、Windows10の環境がないので
ちょっと時間かかりそうです…)

そのエラーだと何らかのcppファイルがプロジェクトに必要な感じですね…
エラー詳細があれば何かわかるかもしれません。

あまり役に立てなくて申し訳ないです。

144管理人★:2017/11/14(火) 22:19:55
らいかさん

軽く確認してみました。
 C:\VST3_SDK\pluginterfaces\base\funknown.cpp
をプロジェクトに追加して確認してもらえるでしょうか?

145らいか:2017/11/15(水) 08:21:37
管理人さん

おはようございます。早速試してみました。

ドンピシャですね。無事ビルド&動作できました。

昨日書き込んだ後、入力するlibを増やしたりしてビルドはできたけどホストから
音が出ないなど色々沼にはまっていたので助かりました。ありがとうございます。

146管理人★:2017/11/15(水) 22:25:03
らいかさん
無事解決してよかったです。

147霧林:2017/12/05(火) 02:51:52
初めまして。VST プラグインの制作を試みている学生です。
VST 開発について詳細に解説しているサイトは少ないので、
「C++でVST作り」は大変参考になっています。貴重なサイトをありがとうございます。
プログラミング及び VST 初心者なのでわけのわからないことを書いてしまうかもしれませんが、質問をしてもよろしいでしょうか。

簡単なエフェクターを作成してみる - http://vstcpp.wpblog.jp/?page_id=314
こちらの記事を始まりとした、VST2.4 で実装しているトレモロエフェクトについての質問です。
このトレモロエフェクトに、「入力信号にトレモロ効果がかかるまでの時間(ディレイ)」
というパラメータを実装したい場合、どのようにすればよろしいでしょうか?

管理人様が実装イメージとして書かれているプログラムでは、
for(int i = 0; i < wavelength; i++)
この for 文内で入力信号の長さ分、信号処理を行っていることがわかります。
なので、例えばサンプリング周波数 44100Hz の入力信号に対して、
トレモロ効果がかかるまで1秒間あけたい場合は、単純に考えると

for(int i = 0; i < wavelength; i++)
{
 if(i <= 44099) {
  output[i] = input[i];
 }
 else if(i >= 44100) {
  //トレモロの計算…省略
  output[i] = b * input[i];
 }
}

このように実装すればよいと考えました(数値がダイレクトなのはご容赦ください)。
i が 0〜44099 の間(1秒間)は入力信号をそのまま出力信号に代入して、
i が 44100 以降は入力信号にトレモロ処理を施した値を出力信号に代入するといった具合です。

しかし、実際に prosessReplacing 関数内で上記イメージのように書き直してもうまく動いてくれません。
ビルドはできますが、実際に使用してみるとトレモロ処理に移らない感じです。
これを望みの挙動にするためには、どのようにすればよろしいでしょうか。

また、prosessReplacing 関数では、実装イメージの wavelength が sampleFrames という変数になっていますが、
この sampleFrames という変数がよく理解できていません。そのためにうまくプログラムが書けないのだと思いますが…
これは、入力信号の長さという単純なものとは違うのでしょうか?

現在 VST3 について意欲的に更新されている最中、旧バージョンの話題で申し訳ありません。
お時間のある時にでもご回答いただければ幸いです。

148管理人★:2017/12/05(火) 20:30:31
霧林さん

書き込みありがとうございます。ST2.4でも全然問題ありません。

簡単に言うとsampleFramesは「入力信号の一部の長さ」になります。

ホストアプリ(DAWなど)は入力信号を数ミリ秒ずつ順番にVSTに渡していきます。
音声処理をリアルタイムに行うためにこのような方法がとられます。

1回に渡す入力信号は数ミリ秒ですので、sampleFramesはだいたい50〜200ぐらいになります。
1秒分の長さを処理するためにホストアプリ(DAWなど)はprosessReplacing関数を200〜1000回ぐらい呼び出します。
(sampleFramesや何回呼び出されるかは環境によって異なります。)

いただいた例の「VSTを読み込んでから1秒後にトレモロがかかるようにする」で、
ずっとトレモロがかからなかったのは、「 if(i <= 44099) 」の条件に合致していたからだと思います。
(for文のint iは毎回 0 になりますし、sampleFramesは大きくても200ぐらいですので)

ですので、実際に例の通りに動かそうとすると、VSTが読み込まれてからの時間(サンプル数)を
保持しておく必要があります。実装例としては下記となるとおもいます。

①メンバー変数としてVSTが読み込まれてからのサンプル数を保持する変数を追加。
【例】
VstInt32 totalSample;

②上記変数をコンストラクタ等で 0 に初期化しておく。
【例】
totalSample = 0;

③prosessReplacing関数のfor文内で処理を行う。
 経過したsampleFrames分はtotalSampleに加えていく。
【例】
for(int i = 0; i < sampleFrames; i++)
{
 if(totalSample < 44100) {
  output[i] = input[i];
totalSample++;
 }
 else {
  //トレモロの計算…省略
  output[i] = b * input[i];
 }
}

149霧林:2017/12/06(水) 03:41:54
管理人様

迅速なご回答ありがとうございます。わかりやすい解説で助かります!
無事トレモロ効果がかかるまでの時間を設定することができました。
いくつか気になる点があるので、また質問させていただきます。
(ちなみにホストアプリは VSTHost (http://www.hermannseib.com/vsthost.htm) を使用しています。
その他の環境は Windows 7 (64bit), Visual Studio 2015 Community です)


ご教示いただいた実装例でそのまま実装してみたところ、
「信号が入力されてから1秒後」ではなく、「VST を読み込んでから1秒後」になるようですね。
VSTHost でビルドした VST を読み込んだところ、
読み込み1秒後からは入力信号に常時トレモロがかかる状態になりました(普通のトレモロエフェクトと同じ状態)。
信号の入出力を全くしなくても、設定した時間が経過次第この状態になるので、
processReplacing 関数は信号の入力がない状態でも呼び出され続けているのでしょうか?

今回私が目指しているものは
「VST 読み込みから n 秒後」ではなく、
「毎回、エフェクトに信号が入力されてから n 秒後」なので(わかりにくくて申し訳ありません)、
管理人様のコードを下記のようにしてみました。

if (inputs[L][0] == 0 && inputs[R][0] == 0){ //入力信号の先頭が 0 の時
 totalSample = 0; //totalSample を 0 に固定しておく
}
else{
 for (int i = 0; i < sampleFrames; i++){
  if (totalSample < 44100){
   outputs[L][i] = inputs[L][i];
   outputs[R][i] = inputs[R][i];
   totalSample++;
  }
  else{
   //トレモロの計算…省略
   outputs[L][i] = b * inputs[L][i];
   outputs[R][i] = b * inputs[R][i];
  }
 }
}

時間は例として 44100=1秒 としています。

VST を読み込んでから1秒経つと、それ以降の入力信号にトレモロがかかりっぱなしの状態になるのは、
processReplacing 関数が呼び出され続け、totalSample がリセットされないことが原因だと推察し、
for 文に移る前に上記のような if 文を書いてみました。

このように実装すると、毎音入力から1秒後にはトレモロがかかるようになりました。
しかし、最初 if 文の条件を「入力信号のバッファ(?)の先頭が 0 」としているため、
入力信号のリリースがわずかでも残っていると、その次に入力した信号にもトレモロがかかってしまいます。
文章だと少しわかりにくいので、今回のトレモロを録音してみました。

http://up.cool-sound.net/src/cool53865.mp3

ド〜、ミ〜、ソ〜 | ド〜ミ〜ソ〜
と鳴らしています。

前半のように各音きちんと区切って鳴らす分には問題ありませんが、
後半のレガートのような演奏をすると、入力信号が 0 にならないため、
totalSample がリセットされず継続してトレモロがかかってしまいます。

これを信号が入力(ノートオン)される度に、
1秒経ってからトレモロがかかるようにするには、どのようにすればよろしいでしょうか。
ノートオンという言葉の通り、MIDI 信号の処理も必要になりますかね?

面倒くさい質問になってしまい申し訳ありません(汗

150管理人★:2017/12/06(水) 22:19:18
霧林さん

いつ入力信号があるか分からないので、processReplacing関数は
信号の入力がない状態でも呼び出され続けます。


「毎回、エフェクトに信号が入力されてからn秒後」とするにはなかなか難しいです。

信号が入力されたという状態をどう考えるか?や
エフェクターをかける対象をどんなものにするか?で変わってくると思います。

記載いただいているサンプルだとおそらくノイズが少しでも乗ると
「信号が入力された」という状態になってしまいます。

信号が入力されたかどうかを判断する方法の一つに音圧をもとにするものがあります。
コンプレッサーでアタックやリリースを出すときに使われる方法です。
RMS(2乗平均平方根)を使えば音圧を取得できるので、RMS値が一定値を超えたら
入力があったとみなす方法です。
ただし、小さい音やオルガンなどの減衰のない音に対してはあまり効果がないと思います。

他にも音程が変わったら入力があったとみなす方法もあると思います。
音圧と組み合わせてみるのもいいかもしれません。

エフェクトをかける対象がシンセで必ずMIDIメッセージを取得できるなら
MIDIノートオンメッセージを条件にすると簡単で正確だと思います。

回答になっていないですが、ご参考になればと思います。

151霧林:2017/12/12(火) 01:46:15
管理人様

返信が遅くなってしまい申し訳ございません。ご回答ありがとうございます。
processReplacing 関数、信号の入力がない状態でも呼び出されているのですね。

なるほど、信号が入力される度に…となると難しいのですね。
私がエフェクトをかける対象として考えているのは、今のところソフト音源(VSTi)のみなので、
MIDI ノートオンメッセージを条件にしてみる方法で挑戦してみます。

今回、エフェクト効果がかかるまでの時間の実装方法について質問をした理由を一応説明しておくと、
時間機能を付けたビブラートの VST エフェクトを作りたいなと思っているからです。
イメージとしては、MIDI のビブラート系の CC にある
Vibrato Rate, Depth, Delay のうちの”Delay”の実装ですね。

また何かわからないことがあれば質問するかもしれませんが、
その時はよろしくお願いいたします。

152管理人★:2017/12/12(火) 20:45:12
霧林さん

とりあえずは解決してよかったです。
また何かあればよろしくお願いします。

153SNRER:2018/02/09(金) 16:56:10
管理人さま

はじめまして
VST作成に役立つ資料いつも参考にさせていただいております。
オーディオFxのVSTを作成中なのですが、
ホスト側で違うチャンネルに2つ以上自作VSTを起動した際に、コントローラの値が
同期してしまい、一つのVSTの値を変更すると起動しているVST全ての同コントローラの値が変わってしまっております。

複数起動の場合には何か特別な処置を施す必要がありますでしょうか。
初歩的な質問で申し訳ないです。。

154管理人★:2018/02/10(土) 21:56:11
SNRERさん

書き込みありがとうございます。
複数のVSTプラグインを起動する際に特別な処理は必要なかったと思います。

考えられるとすれば…
コントローラの値を保存する変数をグローバル変数にしたり、staticで定義したりすると
複数のスレッドで値が共有されてしまったと思います。

状況がわかればもう少し詳細に回答できるかもしれません…。

155SNRER:2018/02/13(火) 16:54:37
管理人さま

GUI、コントローラ、プロセッサで値を共有するため、グローバル変数を使用しております。
GUIがオートメーションに対応して自動で動けなかったのをなんとかしようと、
グローバル変数に頼っておりました。
ここが問題ですね。力技になってしまっているので、複数スレッドの事まで考慮できていませんでした。

SDKのサンプルコードをみていると、バインディングする記述があったので、
もう少し試してみようと思います。

もし簡単な解決法があればご教示いただけますと幸いですが、
 特別は処理は必要ないこと
 全ての値が変わってしまう原因が分かった
ことで、大変助かりました。

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

156管理人★:2018/02/13(火) 21:47:28
SNRERさん

とりあえず解決(?)してよかったです。

> SDKのサンプルコードをみていると、バインディングする記述があった
というのがすごく気になります…
どのサンプルなのか教えていただけると助かります。

またオートメーションの際にGUIに値を更新する方法ですが、
実は私もよくわかっていません。

VST GUIには標準でタイマーがあるので、タイマーを使うと比較的簡単にできるのでは?
と考えていますが、正しい実装ではないような気がしています。

157管理人★:2018/02/13(火) 21:57:22
ちなみに…
タイマーの使い方はVSTGUIEditorクラスのnotify関数をオーバライドして使います。

下記のような方法で実装すればオートメーションに伴ってGUIが更新されるはずです。
(動作確認したわけではないので、動かなかったら教えてください。)
なお、インデントは全角スペースになっているのでご注意ください。

①VST GUIクラス(VSTGUIEditorを継承したクラス)でコントロール用の変数を定義
 (ここではつまみ(ノブ)コントロールとしています。)
【例】
CKnob* knob1;

②notify関数をオーバーライド
【例】
public:
 CMessageResult notify(CBaseObject *sender, const char *message);

③open関数でコントロールを作成した際にポインタを保存しておく
【例】
bool PLUGIN_API MyVSTGUIEditor::open(void* parent, const PlatformType& platformType)
{
// GUIウィンドウが開かれたときに、UIを作成する
  〜〜 中略 〜〜

  // つまみ(ノブ)コントロールを作成( createKnob関数は http://vstcpp.wpblog.jp/?p=1550 参照)
  knob1 = (CKnob*)createKnob(1, 20, 20);

  〜〜 中略 〜〜
}

④notify関数でタイマーイベントを受け取り、コントロールを更新
 (コントロールの更新はsetDirty関数を使います。)
【例】
CMessageResult MyVSTGUIEditor::notify(CBaseObject *sender, const char *message)
{
  if (message == CVSTGUITimer::kMsgTimer)
  {
    if (knob1 != nullptr)
    {
      knob1 ->setDirty(); // 表示を更新
    }
  }

  return VSTGUIEditor::notify(sender, message);
}

158管理人★:2018/02/13(火) 22:15:27
すいません…。
「④notify関数でタイマーイベントを受け取り、コントロールを更新」で
パラメーターの値を取得する必要がありそうです。

CMessageResult MyVSTGUIEditor::notify(CBaseObject *sender, const char *message)
{
  if (message == CVSTGUITimer::kMsgTimer)
  {
    if (knob1 != nullptr)
    {
       // 現在の値をパラメーター操作クラスから取得し反映する
      ParamID tag = 1;
      ParamValue value = controller->getParamNormalized(tag);
      knob1->setValueNormalized(value);

      knob1->setDirty(); // 表示を更新
    }
  }

  return VSTGUIEditor::notify(sender, message);
}

159SNRER:2018/02/14(水) 18:38:32
管理人さま

詳しいご説明誠にありがとうございました。
私はまだプログラミング初心者ですが、サイトも今回の解説もとても分かり易く感謝しております。

GUIクラスで常に呼ばれる系の関数が見つけられずにいましたが、notifyがまさにそれなのですね。
解説いただいた通りでオートメーションが追従しました。さすが管理人さまです!

バインディングについてですが、「note_expression_synth_ui」を見ておりました。
実際に使用してみるとGUIを使ったVSTで、オートメーションに追従していたので、
この中にヒントがあると思い探っておりましたが、「setValueNormalized」は見つかっておりません。
やはり何か実装が違うのでしょうか。。

また、
「#include "vstgui/plugin-bindings/vst3editor.h"」の中の

//-----------------------------------------------------------------------------
//! @brief VST3 Editor with automatic parameter binding
//! @ingroup new_in_4_0
//-----------------------------------------------------------------------------

からの部分が怪しい気がしましたが、勉強不足で理解できておりません。。。。

加えて、大変不躾ではございますが、
今回ご教示いただいた「kMsgTimer」ですと、再生バーを動かしただけでは反応しませんが、
「note_expression_synth_ui」では再生開始しなくても、
バーを違う地点に動かすだけで、その地点のオートメーションの値がGUIに反映されておりました。
(私が作っているのはエフェクトで、このVSTはインストゥルメントという違いはありますが・・・)

できれば「note_expression_synth_ui」同様に再生開始前に追従したいのですが、
kMsgTimer以外のメッセージ種別は何かありますでしょうか?
(探してはみたのですが、みつからず・・)

大変お手間をとらせて申し訳ありません。

160管理人★:2018/02/14(水) 22:57:52
SNRERさん

バインディングの情報ありがとうございます。

私もオートメーションと再生バーの追従はまだ試していないのでもう少し確認してみます。

kMsgTimer以外のメッセージもたしかあったのですが、再生やバー移動などの関連の
メッセージはなかったと思います。

「note_expression_synth」で再生バーの追従が出来ているということは
おそらく、notify関数でkMsgTimerを使うのはあまりいい方法ではないと思います。

あいまいな回答で申し訳ありません。

161SNRER:2018/02/15(木) 10:01:08
管理人さま

ご返答ありがとうございます。
こんな素人の質問に付き合っていただき本当に感謝しております。
私も引き続き調べてみようと思います!

162管理人★:2018/02/15(木) 23:04:52
SNRERさん

私も>>157-158の方法を試してみました。

つまみ(ノブ)等の実装方法(下記)をベースにnotify関数
で更新する方法をとりましたが、再生バーを移動させた際も
コントロールの状態は更新されました。

http://vstcpp.wpblog.jp/?p=1230

SDKは3.6.8を動かせるDAWがないので使用したSDKは3.6.0になります。
DAWはSteinberg Sequel 3です。

可能であれば使用しているSDKやDAWなどを教えていただけますでしょうか?

また、動かないのであれば、setDirty関数をinvalid関数に変えて
試していただけますでしょうか?
(インデントは全角スペースになっているのでご注意ください。)

④notify関数でタイマーイベントを受け取り、コントロールを更新
CMessageResult MyVSTGUIEditor::notify(CBaseObject *sender, const char *message)
{
  if (message == CVSTGUITimer::kMsgTimer)
  {
    if (knob1 != nullptr)
    {
       // 現在の値をパラメーター操作クラスから取得し反映する
      ParamID tag = 1;
      ParamValue value = controller->getParamNormalized(tag);
      knob1->setValueNormalized(value);

      knob1->invalid(); // 表示を更新
    }
  }

  return VSTGUIEditor::notify(sender, message);
}

なお、「note_expression_synth」の中身を確認しましたが、
オートメーションと再生バーの追従方法は自前でクラスを用意していました。

サンプルの実装方法を見る限りでは、
notify関数のkMsgTimerで更新する方法でも問題なさそうです。

163SNRER:2018/02/16(金) 15:27:56
管理人さま

ご返信ありがとうございます!
本当に丁寧に考えていただき、とても嬉しいです。

まず、私の環境についてですが、
DAW SONAR Platinum(つい先日開発中止になってしまいましたが・・・・)
SDK 3.6.8

となります。

ご教示いただいた「invalid」についてですが、
「setValueNormalized」の行までだけで表示は更新されている様で、
「invalid」「setDirty」
どちらをコメントアウトしても動作しております。
また、「invalid」を試してみましたが、こちらの環境では再生バーに追従できませんでした。

その後に、VisualStadio からSONARにアタッチしてデバッグをしていて
 再生バーを動かしただけでもnotify内のif分の中まで入ってきているが
 getPramで取得してくる値が再生バーを動かす前の値がそのまま残っている。
という事がわかりました。

しかし、再生バーを動かしてプロセッサ関数に来た時に
「getPoint」で取得するvalueは再生バーを動かした後の最新の値がホストから提供されていました。

この最新の値をコントローラ側でも把握できればいけそうですが、
EditController* controller
のパラメータがどのタイミングにどの様に更新されているのかを理解できておりません。

ちなみに先日のバインディングの件ですが、
怪しいと思っていたところはVST上でエディターを起動する事ができて、
それ上でのバインドの事を指している様な感じでしょうか。
実際VST上で起動してエディターの中身も見てみましたが、用意されたテンプレート以外の自分で作った絵を使う事が出来ない感じに見えましたので、
今回の自分がやりたい事にはマッチしない感じでした。
お騒がせしてすみません。。

引き続きいろいろと試してみます!

164管理人★:2018/02/16(金) 22:09:16
SNRERさん

ご確認ありがとうございます。少し整理のために、私の理解している動作を記載させていただきます。

まず、オートメーションや再生バーを動かした時、DAWからは状態とGUIを反映するため下記が行われる

 A)音声処理クラス(AudioEffectを継承したクラス)へは
  process関数の引数ProcessData& dataに値を設定し反映する。
  音声処理クラスは渡された値で内部状態を更新する。

 B)パラメータ操作クラス(EditControllerを継承したクラス)へは
  setParamNormalized関数を呼び出して変更を通知・反映する。(値を更新する)
  パラメータ操作クラスはsetParamNormalized関数のtagで指定された
  パラメータの値を更新する。

上記とは別にVST GUIクラス(VSTGUIEditoを継承したクラス)はタイマーを使って
0.1秒ごと(デフォルト時)にnotifyを呼び出している。

 C)notifyでは、パラメータ操作クラスから現在の値をgetParamNormalized関数で取得し、
  コントロール(ノブなど)の値を更新している。
  値更新後はsetDirty関数で画面UIの更新をDAWに通知し、DAWに再描画させる。(0.1秒ごと)

VST GUIクラスのEditController* controllerはパラメータ操作クラスへのポインタなので
B)のタイミングで値は更新されている。

C)は0.1秒ごとに呼び出されるので、どこかのタイミングでコントロールは更新される
再生バーを動かした時でも0.1秒以内には更新される。

以上が私の理解している動作になります。

いま、A)とC)は呼び出されていることが確認できており、B)が確認できていない状況で
間違いないでしょうか?

B)が呼び出されない可能性はDAWの実装に原因があるように思えます。
(ただ、サンプルVSTで動いているのが気になります…)

再生バーを動かしたときにB)が確認できるか?(DAWからsetParamNormalized関数が呼ばれているか?)
を確認してもらえますでしょうか?

また、呼び出されていても反映されていない状況もあるかと思います。
たとえばParameterクラスを継承して自作Parameterクラスを作っていて、そのクラスの実装が
間違っている場合などです。
自作Parameterクラス等は作っていないでしょうか?

最後にバインディングの件ですが、VST SDK 3.6.8からサンプルのVST GUIが
Inline UI Editor(VST3Editorクラス)を使うようになったようです。
このInline UI Editorはコード書かなくても、マウスでUIを作れる方法のようです
バインディングというのは、
 「マウスでコントロール(ノブなど)を作っても自動で割り当てしてくれる」
という意味だと私は理解しています。

長文失礼しました。以上よろしくお願いします。

165SNRER:2018/02/20(火) 10:03:14
管理人さま

ご返信ありがとうございます!
作業できる環境から少し離れておりました。

 再生バーを動かしたときにB)が確認できるか
など確認して追ってご報告いたします。

166SNRER:2018/02/20(火) 15:22:56
管理人さま

改めまして、パラメータ共有の流れについてご説明誠にありがとうございました!
いつも本当に丁寧なご回答助かっております。

まず、

いま、A)とC)は呼び出されていることが確認できており、B)が確認できていない状況で
間違いないでしょうか?

についてはその通りでございます。

vsteditcontroller.cpp
内の

tresult PLUGIN_API EditController::setParamNormalized (ParamID tag, ParamValue value)
{
Parameter* parameter = getParameterObject (tag);
if (parameter)
{
parameter->setNormalized (value);
return kResultTrue;
}
return kResultFalse;
}

のあたりでブレイクしてみましたが、
再生開始時には通っている様で、再生バーを動かしただけの場合には通りませんでした。

やはり再生していない場合では最新の値がセットされない事で、GUIの値が更新されないと思われます。

また、自作Parameterクラスなどは作っておりません。
バインディングについてもご説明いただきありがとうございました。

サンプルで動くという事は何かしらホストから発信はあるはずなので、
もう少しサンプルのソースを見てみようと思います。

167管理人★:2018/02/20(火) 21:43:34
SNRERさん

ご確認ありがとうございます。

EditController::setParamNormalized関数の「parameter->setNormalized (value);」
が呼び出されていないのですね…。

「note_expression_synth」サンプルソースもParameterクラスのsetNormalized関数から
更新するタイミングを受け取っているようなので、本来なら動かない気がします…。

「note_expression_synth」と同じ方法でGUIを更新する方法は今私も試しているところです。
なにか分かりましたら、また共有させていただきます。

あと、「つまみ(ノブ)等の実装方法」( http://vstcpp.wpblog.jp/?p=1230 )を元に
私がnotify試したサンプルを下記に保存しておりますので、よければご参考にしていただければと思います。

http://vstcpp.wpblog.jp/wp-content/uploads/2018/02/20180220_vst3.zip

168SNRER:2018/02/21(水) 16:06:14
管理人さま

ご返信ありがとうございます!

ご指摘の通り、setParamNormalizedが呼ばれない事で、
「parameter->setNormalized (value);」
が実行されていないという感じでした。

「note_expression_synth」の
「note_expression_synth_controller.cpp」
でオーバーライドされている setParamNormalized でブレイクしてみましたが、
再生バーを動かすだけ、というか、SONARをアクティブにした時点でブレイクしました。

こちらは正常にsetParamNormalizedが呼ばれている様です。
何が違うのか・・・現状まだ分かりませんが、ホストは正しく動作している様です。

また、頂いたソースで試してみたのですが、
VST起動の際、 Sample32* inL = data.inputs[0].channelBuffers32[0]; がnullでエラーになったので、
変数への格納を
  for (int32 i = 0; i < data.numSamples; i++)
の中で行う事で動作しました。

ただし、簡易デバッグとして使っております 
 「Vst3HostDemo_x64.exe」
というソフトではそのままで問題無く起動しておりますので、
未再生状態でプロセッサを呼んでしまう様なSONAR独自の動きのせいでエラーになるのかもしれません。

続いて動作内容ですが、
再生開始からは同期しますが、バーを動かすだけでは追従しませんでした。

なぜ「note_expression_synth」では
 setParamNormalized
が再生バー移動でもコールされているのかが肝だと思いますので、
自分も引き続き調べてみます。
何か気付きがあればまたご報告いたします。

169管理人★:2018/02/21(水) 21:17:59
SNRERさん

何度もご確認ありがとうございます。

やはり私のサンプルでも動かなかったのですね…。
となると後は下記ぐらいの内容しか思いつきません…。

1.再生バーの動作ではsetState関数やsetComponentState関数が呼ばれている
 →setState関数やsetComponentState関数からsetParamNormalized関数が
  呼び出されている可能性があります。

2.パラメータ操作クラスで初期化時に何らかのフラグを立てている
 →パラメータ変更時にホストからsetParamNormalized関数を呼び出すような
  設定をしている可能性があります。
  (サンプルを見た感じではありませんでしたが…)

3.音声処理クラスから、パラメータ更新を受け取っている
 →音声処理クラスのprocessでdata.outputParameterChangesをセットし、
  パラメータの更新を通知している可能性があります。
  (たぶんこの可能性はないと思いますが…)

可能性としては以上になります。
上記の可能性でない場合、正直分からないというのが現状です。

170SNRER:2018/02/26(月) 10:01:55
管理人さま

可能性についてピックアップありがとうございます!
1.2.3.について自分なりに見てみましたが、
現状答えにはたどり着けておりません。

方向性は変わりますが、
VST上でのエディターについてもう少し調べておりました。
どうもエディターで作った内容はリソースファイルとして出力される様で、
その中に各コントローラとタグを結びつける記述がありました。

自分で作ったPNGもエディターから使用する方法が分かりましたので、
ひとまずこちらで試してみようと思います。
(エディター上で、何故か他ドライブからPNGをインポートすると落ちるのですが、
 Cドライブからインポートなら落ちないという事が分かるまでに時間がかかりました)

また発見がありましたら共有させていただきます。

171管理人★:2018/02/26(月) 23:40:49
SNRERさん

ご確認ありがとうございます。原因が分からず残念です。

Inline UI Editor(VST3Editorクラス)の情報ありがとうございます。
どうもSDK 3.6.8からこのエディターが推奨されているようですが、
私はまだ試せていないので情報頂けると非常にたすかります。
(全部のサンプルがこのエディターになっていたのでそう考えています。)

また、試したわけではありませんが、私が分かっている範囲で
Inline UI Editor(VST3Editorクラス)でのUI更新方法について
分かる内容を記載させていただこうと思います。
本日はまだ整理できていないので近日中に記載させていただきます。

172管理人★:2018/03/02(金) 20:11:36
SNRERさん

遅くなりすいません。
Inline UI Editor(VST3Editorクラス)でのUI更新方法について
分かる内容を記載させていただきます。

Inline UI Editor(VST3Editorクラス)ではParameterクラスと依存関係を作成して、
Parameterクラスが変更されたとき(setNormalized関数が呼ばれたとき)に
コントローラを更新できるようにしているようです。

具体的にはvst3editor.cppのParameterChangeListenerクラスで実装されています。

①ParameterクラスのaddDependent関数を呼び出して依存関係にあるクラスを登録する。
 (VST3EditorクラスではコンストラクタでParameterChangeListener自身を登録)

②ParameterクラスのsetNormalized関数が呼び出されると変更されたことを
 依存関係にあるクラスに通知するためchanged関数が呼び出される。

③changed関数が呼び出されるとVST内部でいったんキューイングされた後、
 ParameterChangeListenerクラスのupdate関数が呼び出される。

④ParameterChangeListenerクラスのupdate関数内で関連付けられた
 コントロール(CControlクラス)の値を更新(setValueNormalized関数の呼び出し)し、
 再描画(invalid関数の呼び出し)する。

以上がInline UI Editor(VST3Editorクラス)の更新方法のようです。
ご参考までに。

173SNRER:2018/03/12(月) 17:35:03
管理人さま

大変お返事遅くなりました。
申し訳ないです。

Inline UI Editorで進めていきたいのですが、
うまくバインドされずにまた困っておりました。

ご教示いただいた内容を紐解きつつ確認してみます!
また進捗あればご報告させていただきます。

174管理人★:2018/03/12(月) 22:18:33
SNRERさん

ご確認ありがとうございます。

私も最近Inline UI Editorを試しました。
慣れるまでちょっと大変なツールですね…。

バインドされないとのことですが、「Control-tag」の項目に
パラメーターのタグを設定してもバインドされないでしょうか…?

175SNRER:2018/04/02(月) 17:19:30
管理人さま

ご無沙汰しております。
多忙により少しコードを触れずにおりました。

Control-tagにはタグ名称、その下のエリアで、ラベルとタグの記載をしているのですが、
それによって作られたコントローラが何の反応もなく(動かす事はできるのですが)
つまんで動かしてもvalueChangedにも来ていない状況です。

今、UI Editorの記事を拝見しました。まず、この記事に沿って構築し直してみようと思います。
貴重な記事大変感謝致します。

176管理人★:2018/04/02(月) 20:21:39
SNRERさん

こちらこそいろいろ情報を頂きありがとうございます。
valueChanged()が呼び出されていないとなるとちょっと分からないですね…

Inline UI Editorの記事がご参考になればと思います。

177SNRER:2018/04/04(水) 10:41:47
管理人さま

parameters.addParameter(STR16("●●"), STR16("●●"), 0, 0, ParameterInfo::kCanAutomate, TAG, kRootUnitId);

の様に設定しておりましたが、ここをノートエクスプレッションに合わせて

Parameter* param;
param = new RangeParameter(STR16("●●"), TAG, STR16("●●"), 0, 100, 100);
param->setPrecision(1);
parameters.addParameter(param);

の様に変更する事で、オートメーション追従まではできました。

引き続き改めてコードとにらめっこしていますが、
UIエディターを使って作った場合は、そもそも「guieditor.cpp」などに相当する部分は必要なく、
「guieditor.cpp」に作った valueChanged なども必要無いという事になるでしょうか?(通っていなくて動いているので)


但し、再生バーの地点を動かしただけの場合にはやはり、
setPramNomalized が呼ばれておらず、表示も更新されません。

引き続き自分なりに調べてみますが、ひとまず動いたという事でご報告させていただきました。

178管理人★:2018/04/04(水) 21:30:12
SNRERさん

一つ問題が解決してよかったです。

Inline UI Editorで「guieditor.cpp」に相当するものは
VST SDK内にある「vst3editor.cpp」になります。
valueChanged関数もこの「vst3editor.cpp」で定義されています。

また、Sonarの再生バーを動かした場合、
パラメータ操作クラス(EditController)のsetComponentState関数が
呼び出されているのではないかと思っています。

ノートエクスプレッションのサンプルでは、setComponentState関数から
setParamNormalized関数が呼び出されていますのでこれによって
UIの状態が更新されていると考えています。

179あると:2018/04/17(火) 18:59:40
管理人様

お世話になります.私,貴サイトを参考にVST3プラグインを作成しようとしているものです.
現在,貴サイトの「最小構成のVST3」の手順を行い,ビルドを行ったところなのですが,
問題が生じたので,もし何か解決の糸口が見つからないかと考え書き込ませていただきます.

現在,
Windows10(64bit)
Visual Studio 2017 community
VST SDK3.6.8
という貴サイトでの環境を構築し,
手順通り進めることでビルドが成功しました.
ソースコードは全て貴サイトのものを使用させていただきました.
生成された.vst3ファイルを動作確認するため,.vst3を
C:ProgramFiles\Common Files\VST3に入れました.

しかし,現在使用しているDAW「StudioOne3.5 professional」
でインサートプラグインとして使用したところ,
VSTプラグイン一覧上で自作VST3は見えるのですが,
インサートしてもインサート欄に追加されず,何も起きません.
ちなみに,他のVST2,3プラグインは正常にインサート欄に追加されて使用できます.

このような現象に心当たりはありますでしょうか?
DAWとの相性などもあるのでしょうか?.

辿々しい説明でわかりづらいとは思いますが,はじめの一歩でつまずいてしまい
大変困窮しておりますので,何卒ご返信いただければ幸いです.

180管理人★:2018/04/17(火) 20:06:42
あるとさん

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

頂いた事象についての心当たりはないのですが、
「最小構成のVST3」では何か足りないのかもしれませんね…
(説明しやすいようにかなり無理して削っている部分があるので…)

もし可能であれば、他のDAWで動作確認していただけないでしょうか?

VST SDKにもテスト用ホストが「VST3_SDK\bin\Windows 64 bit」にあります。
「VST3PluginTestHost_x64_Installer_2.6.0.zip」を解凍すればインストーラーがあります。
(私はこちらで動作確認しております。)

テスト用ホストで動くのであれば、パラメーター実装方法等で少し機能を追加してから、
再度Studio Oneで動作確認いただけますでしょうか?
(「最小構成のVST3」にはパラメーター操作クラスがないので、おそらくこのあたりで
はじかれているのではないかと推測しています。)

181あると:2018/04/20(金) 10:19:16
管理人様

ご返信ありがとうございます!
返信が遅くなってしまい申し訳ございません.

テスト用ホストの存在を知らなかったので,
その情報だけでも有難いです!

テスト用ホストをDLしてみたところ,
サンプルコードのvst3プラグインは認識されました.
しかし,本当に信号処理が出来ているかわからなかったので,
出力を1/4にするようにコードを書き換えて実行したのですが,
バイパス機能が実装されていないため,オンオフで確認することが出来ませんでした.
ということで,バイパス機能を実装してみたいと思います.
パラメータ実装の方も試してみます.

また,他のDAWでも試してみたほうがいいというアドバイスを受け,
知り合いのCubase使いのDTMerにプラグインを渡して試してもらったのですが,
そもそも認識されなかったそうです.おそらくCubase pro9.5です.
REAPERもDLしてみましたが,vst3を読み込んだら落ちました.

とりあえず解決できそうな糸口は色々と見つかったので試してみます.
ご回答ありがとうございました.何か進展があった際はご報告いたします.

182管理人★:2018/04/21(土) 19:33:24
あるとさん

ご連絡ありがとうございます。

他のDAWでも駄目でしたか…
ちなみに私のサイトに記載されている環境構築方法の場合
Windows 7だとたしか動きません…。
機能追加した結果等を教えていただけると幸いです。

183猫十:2018/06/29(金) 03:46:30
WavetableSynthとAsyncFileLoadのサンプルありがとうございます。
すっかりご無沙汰してしまい、大変恐縮しております。

3.6.10への移行はちょっと保留にしまして(汗)、遅ればせながらGUI有りの拙作にWavetableSynthとAsyncFileLoadを混ぜる形で組み込んでみています。
WavetableSynthとAsyncFileLoadの信号処理部が相互に干渉しない形でなら混ぜ合わせはできたのですが、
wavbufをsetWaveして打鍵に沿わせようとすると途端にうまく行きません。

現状は添付のtest.wavをwavbufに読み込ませた後にfloatに変換したものと取得したサイズ(51528)をsetWaveに渡しています。
もしよろしければこのあたりの手順についてご教示いただければ幸いです。
何卒宜しくお願いいたします。

184管理人★:2018/06/29(金) 21:15:13
猫十さん

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

昔のコードなので読み返しながらになりますが、作られたプログラムの処理の流れや
setWave()等に渡している引数等を教えていただけると助かります。

また、「うまく行かない」というのはどういう状況なのかも教えてください。

185猫十:2018/06/30(土) 00:22:25
管理人様

お世話になります。猫十です。
ご返信ありがとうございます。

現在の手順なのですが、

コンストラクタで管理人様のtest.wavを読み込んだ後、

>wavbuf = new short[wavsize];
のあとに
f_wavbuf = new float[wavsize];
としまして、

>memcpy_s(wavbuf, wavsize * sizeof(short), buf + sizeof(MyWAVEHEADER), wh.datasize);
のあとに


for (int i = 0; i < wavsize; i++)
{
f_wavbuf[i] = (float)(wavbuf[i]) / 32768.0f;
}
こんな感じでfloatに変換し(汗)
これでkeytableに紐づけできる状況が整ったと(私が勝手に)判断しまして、

for (int i = 0; i < 128; i++)
{
keytable[i] = f_wavbuf;
}
としてます。

setWaveは

onMidiKeyOnで

cvoice[i].setWave(keytable[noteNo], wavsize, 44100.0f / wavsize);

のようにしてます。

この状況で鍵盤を弾くと打鍵に合わせて音階付きでノイズが鳴ります。

以上が現在の流れです。

お手数をおかけいたしますが何卒よろしくお願いいたします。

186管理人★:2018/06/30(土) 10:38:51
猫十さん

2.4の環境がもうないので試せていませんが
onMidiKeyOn()でsetWave()の第3引数を、440.0fぐらいで
試していただけますでしょうか?

 cvoice[i].setWave(keytable[noteNo], wavsize, 440.0f);

187猫十:2018/06/30(土) 13:21:52
管理人様

ご返信ありがとうございます。

さっそく試してみました。

...ドラム鳴ってます(驚)
打鍵(NoteNo=60)で再生速度こそオリジナルと違いますがドラムが聴こえてきます。
NoteNoに追従して再生速度も変わっています。

ありがとうございます!

ちなみにこれはどういうことなんでしょうか?
もしよろしければぜひご教示いただきたく存じます。

188管理人★:2018/06/30(土) 13:51:02
猫十さん

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

setWave()の第3引数は単純な「サンプルレート÷サイズ」ではなく「波形データ自体の音程(周波数)」になります。

今回のように「44,100÷51,528」とすると波形データの周波数は「約0.85Hz」となるので
例えばA4の音(440Hz)で鳴らそうとすると、517倍(440Hz÷0.85Hz)のスピードで波形データを
再生することになります。

MyWavTableSynthサンプルプログラムは「波形データサイズ=1周期分」なので
単純に「44,100÷8」で周波数(=5,512Hz)を計算していますが、wavファイル等から波形データを読み込んだ場合、
「波形データサイズ=1周期分」とならないので、別途指定してあげる必要があります。

 // 第三引数の周波数を設定するにはwavファイルが何Hzかあらかじめ調べておく必要がある。
 (onMidiKeyOn()のこの部分のコメントです。改めてみると分かりにくいコメントで恐縮です。)

今回はリズム音だったのでピッチ自体が不明なため、とりあえずA4キーを押したときに
そのまま再生されるよう440Hzとしました。
ピアノ等の音程のあるwavサンプルの場合はその音程に合わせた周波数を設定すれば大丈夫だと思います。

189猫十:2018/06/30(土) 22:28:26
管理人様

お世話になっております。

こちらこそサンプリング周波数とデータサイズの関係に考えがいたらず、お手数をおかけいたしました。

まだまだ課題は山積みですが引き続き頑張ります。
またお尋ねさせていただくこともあるかと思いますが何卒よろしくお願いいたします。

190猫十:2018/07/15(日) 22:14:17
管理人様

こんばんは。
またまた書き込み失礼します。

2.4でWAVファイルを読み込むサンプラーもどきを作っています。
VSTクラス(AudioEffectX)で読み込んだWAVファイルの情報を文字列としてGUIクラス(AEffGUIEditor)に送りたいのですが方法がわかりません。

VSTクラス(AudioEffectX)とGUIクラス(AEffGUIEditor)間で相互に文字列を受け渡すにはどうすればよいのでしょうか?

いつも質問ばかりですいません。
何卒よろしくお願いいたします。

猫十

191管理人★:2018/07/16(月) 13:53:10
猫十さん

2.4ではやったことがなく、すでに開発環境もないので試せませんが、
下記の方法で出来るのではないでしょうか?
(コードのイメージは全角スペースになっているのでご注意ください。)

①音声処理クラス側(AudioEffectXを継承したクラス側)で文字列を受け取る関数を定義する

class MyVST : public AudioEffectX
{
public:
  // 引数の文字列 fileをメンバー変数のfilepathに設定する関数
  void setFilePath(char* file) { strcpy(file, filepath); };

  〜〜以下略〜〜
protected:
  char filepath[256]; // ファイルパス用の文字列
};

②GUIクラス(AEffGUIEditorを継承したクラス側。MyGUIとする)で
 CTextEditコントロールなどから文字列をうけとった際に通知する処理を追加する

void MyGUI::valueChanged (CDrawContext *pContext, CControl *pControl)
{
  // どのパラメーターが操作されたかを取得する。
  VstInt32 index = pControl->getTag();

  // 操作されたパラメーターを確認。
  // ファイル名入力用のパラメーターなら音声処理クラスに文字列を渡す
  if ( index == MYVST_FILENAME )
  {
    char filepath[256];

    // テキストエディットから文字列を取得
    // (SDK 2.4のテキストエディットの文字列の長さは256固定なので注意)
    ((CTextEdit*)pControl)->getText(filepath);

    // 音声処理クラスに文字列を渡す
    ((MyVST*)effect)->setFilePath(filepath);
  }
  〜〜以下略〜〜
}

以上です。CTextEditの作成方法は下記とほぼ同じだったと思います。
http://vstcpp.wpblog.jp/?p=1722

なお、音声処理クラスのfilepathに書き込む際は排他処理等がいるかもしれません。

192管理人★:2018/07/16(月) 15:45:38
猫十さん

すいません。今質問を読み返して逆方向だということに気付きました

やりかたは>>191と同様で出来ると思います。
(コードのイメージは全角スペースになっているのでご注意ください。)

①GUIクラス側(AEffGUIEditorを継承したクラス側)で文字列を受け取る関数を定義する

class MyGUI : public AEffGUIEditor, CControlListener
{
public:
  // 引数の文字列 fileをメンバー変数のfilepathに設定する関数
  void setFilePath(char* file) { strcpy(file, filepath); };

  〜〜以下略〜〜
protected:
  char filepath[256]; // ファイルパス用の文字列
};

②音声処理クラス側(AudioEffectXを継承したクラス側 MyVSTとする)で
 CTextEditコントロールなどから文字列をうけとった際に通知する処理を追加する

void MyVST::processReplacing(float** inputs, float** outputs, VstInt32 sampleFrames)
{
  〜〜以下略〜〜

  // wavファイルのパスが変更された場合だけ、MyGUI側に新しいファイルパスを渡す
  // (条件式は省略。プログラムに合わせてください。)
  if(〜〜〜〜)
  {
    // たぶん排他処理が必要
    ((MyGUI*)editor)->setFilePath(newfilepath);
  }
}

③GUIクラス側(AEffGUIEditorを継承したクラス側)でテキストラベル等に文字列を反映させる
 (ここではidle関数を利用。参考→https://www39.atwiki.jp/vst_prog/pages/93.html)

void VstGui5::idle ()
{
  // まずは継承元の関数を呼び出す(必須)
  AEffGUIEditor::idle ();

  // このVSTGUI固有の処理を記載する

  // テキストラベルの文字を設定する
  // setText()処理中にfilepathが更新ないように排他処理がいるかもしれません。
  textLabel->setText (filepath);

  // テキストラベルの描画を更新する
  textLabel->setDirty();
}

193管理人★:2018/07/16(月) 15:49:25
>>192
誤記がありました…。

【誤】
②音声処理クラス側(AudioEffectXを継承したクラス側 MyVSTとする)で
 CTextEditコントロールなどから文字列をうけとった際に通知する処理を追加する

【正】
②音声処理クラス側(AudioEffectXを継承したクラス側 MyVSTとする)で
 ファイルパスを渡す処理を追加する。

194猫十:2018/07/18(水) 01:46:05
管理人様

頂きました回答をもとにさっそく試してみたところ、
AudioEffectX側からAEffGUIEditor側へ文字列を送ることができました。(その逆もできました。)

具体的には
AEffGUIEditor側でFileSelector経由で読み込んだファイルのフルパスをAudioEffectX側に送り、
AudioEffectX側でWAVを読み込んで発音部にセット、
読み込んだWAVのサンプリング周波数やビットレートその他の情報(デバッグ用にチャンク位置とか)をAEffGUIEditor側に送って表示
です。(VSTiなサンプラーとしてこのやり方が合っているのかどうかわかりませんが・・・。)

排他処理は入れていないのですが基本的な動作はOKっぽくなってきましたので
実際の曲で市販のプラグインと混ぜて使ってみようと思ってます。

いつも本当にありがとうございます。

また何かありましたら何卒よろしくお願いいたします。


猫十

195管理人★:2018/07/19(木) 22:37:42
猫十さん

動いてよかったです。

VSTのサンプラーとしてやり方があってるかどうかはわかりませんが、
私はプログラムに正解はないと思っています。
想定通り動いたのであればそのやり方でいいと思います。

196pylab:2018/10/03(水) 22:06:37
こんばんわ
最近VSTに興味をもち始めたものです。

VST3.6開発01 – VST3開発環境の準備にて

「VST SDK 3.6.10の場合、下記のエラー LNK1104でビルドが失敗しますが、サンプルプラグインなので上記のライブラリファイルが生成されていれば、
次に進んで頂いても大丈夫です。(サンプルプラグインの動作を見ることはできませんが…)」

とありますが、
https://github.com/steinbergmedia/vst3sdk/issues/17
にて
SMTG_CREATE_BUNDLE_FOR_WINDOWSをオンにすればよいという
情報がありました。

CMAKEの画面の中ほど(赤いところ)で「SMTG_CREATE_BUNDLE_FOR_WINDOWS」のチェックボックスが
ありましたのでオンにしてビルドしましたら
リンカのLNK1104エラーが出なくなりました。

ですが警告でNo snapshot in Bundle は出ています。

確認お願いします。

197管理人★:2018/10/03(水) 23:20:17
pylabさん

情報ありがとうございます。
内容確認して再度ご連絡いたします。

198管理人★:2018/10/04(木) 22:47:39
pylabさん

確認いたしました。

「SMTG_CREATE_BUNDLE_FOR_WINDOWS」をオンにすると
VST 3.6.9以前のフォルダ構成でサンプルを配置するので
確かにエラーはなくなるようです。

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

199らく:2020/02/03(月) 10:47:03
はじめまして。
VSTに関して全くの初心者であり、調べていたら、あらゆるところからここへ導かれました。非常に参考にさせて頂いております。

早速ですが、質問させて頂きます。
「はじめてのVST3.6プラグインの作り」の手順通りに「パラメータの保存方法」まで進みました。
ここに至るまでにもVST3プラグインができ、REAPER上で動作しています。
ところが、別のPC(開発環境的なものは一切入っておりません)にプラグインを持って行くと、同じREAPERですが、VSTプラグイン(.vst3ファイル)が見えません。
原因はどこにあると推測されますか?
ちなみに、VSTプラグインを作成した環境は
 VDT_SDK:Version 3.6.14
 Visual Studio:2019 Version 16.4.2
です。

宜しくお願い致します。

200管理人★:2020/02/04(火) 00:12:56
らくさん

書き込みありがとうございます。
マシュマロと同じ質問だと思いますので、Twitterにて回答させていただきました。
https://twitter.com/vstcpp/status/1224347122364862466

201hiro:2020/05/08(金) 08:19:05
初めましてです。
VSTを作ってみたいと思いまして今日vst_sdkをダウンロードしてhttps://vstcpp.wpblog.jp/?page_id=21の進めたのですが
audioeffectx.hを開くとソースファイルを開けません"pluginterfaces/vst2.x/aeffectx.h"とエラーが出ます。
ダウンロードしたフォルダを見てもaeffectx.hは見つからず、入手できる他のサイトも見つかりません。
解決策を教えてください。VS 2019です。

202管理人★:2020/05/12(火) 13:57:00
hiroさん

書き込みありがとうございます。
お返事が遅くなり申し訳ありません

そちらの方法は、古いバージョンのSDKを使ったものになり、もう実施することができません。
新しいバージョンのSDKを使った方法はこちらになりますのでこちらの方法でご確認いただけますでしょうか。
https://vstcpp.wpblog.jp/?p=1287

203hiro:2020/05/13(水) 10:35:59
解決しました!ありがとうございます。
原因はCMAKEが(ブラウザのバグなのか?)何故かダウンロードできなくて手こずってました...
今日はダウンロードができ、送って頂いたURLの手順通りに進めることができています。
ご丁寧な説明をありがとうございました。

204管理人★:2020/05/13(水) 20:25:13
hiroさん
無事解決できてよかったです。

205ank:2020/07/05(日) 00:35:13
はじめまして。
本、VSTプラグインを読み進めているのですが、GUIのところでつまづいています。
myEditor.uidescのパスを修正した後にテストホストで読み込むとノブ等が表示されるはずですが、黒い画面のままです。
管理人様のサイトを見ると本に記述されていないresource.rcに関する記述があるのですが、このファイルの作成が必要なのでしょうか。

206管理人★:2020/07/09(木) 23:31:30
ankさん

書き込みありがとうございます。
ご連絡が遅れて申し訳ありません。もう少し内容確認にお時間をください。

207管理人★:2020/07/10(金) 00:02:18
ankさん

書籍のResourcesフォルダの配置位置に誤記がありました。申し訳ありません。
MyVstProject.vst3フォルダの配下ではなく、Contentsフォルダの配下にResourcesフォルダを移動させていただけますでしょうか?

208ank:2020/07/14(火) 21:31:39
返事が遅れまして申し訳ございません。
無事にリリース版までVSTの作成が進めることができました。
とても丁寧に書かれた本でC++に慣れていない人間にとって大変ありがたい存在です。続編の予定はあるのでしょうか。
VST作成の第一歩が踏み出せてとても感謝しております。

209管理人★:2020/07/15(水) 22:55:40
ankさん

無事進めることができてよかったです。

続編の予定ですが、今のところありません。
より高度なVSTを作成する際は、SDKのマニュアルか私のサイトなどを
ご確認いただければと思います。

210てつ:2021/02/18(木) 21:07:40
管理人さん、はじめまして。
著書VSTプラグインならびにホームページからこちらの掲示板にたどり着いた初心者です。

プロジェクトの設定を行い、その後、ビルドの実行を行ったのですが、下記のエラーが出ます。
リビルドを開始しました...
1>------ すべてのリビルド開始: プロジェクト:MyVstProject, 構成: Debug x64 ------
1>dllmain.cpp
1>myvst3.cpp
1>コードを生成中...
1> ライブラリ C:\Users\***\source\repos\MyVstProject\x64\Debug\MyVstProject.lib とオブジェクト C:\Users\***\source\repos\MyVstProject\x64\Debug\MyVstProject.exp を作成中
1>MSVCRTD.lib(exe_main.obj) : error LNK2019: 未解決の外部シンボル main が関数 "int __cdecl invoke_main(void)" (?invoke_main@@YAHXZ) で参照されました
1>C:\Users\***\source\repos\MyVstProject\x64\Debug\MyVstProject.vst3 : fatal error LNK1120: 1 件の未解決の外部参照
1>プロジェクト "MyVstProject.vcxproj" のビルドが終了しました -- 失敗。
========== すべてリビルド: 0 正常終了、1 失敗、0 スキップ ==========

ネットで自分なりに探したところ、プロパティのリンカー - システム ー サブシステムを
コンソールからWINDOWSに変えると解決したというサイトがあったので
試してみましたが、上記エラーの「未解決の外部シンボル main」が「未解決の外部シンボル WinMain」に変わるだけで同じエラーが出ます。

dllmain.cppは記載通りに追加したつもりです。

環境はWIN10, VisualStudio2019, VST-SDK3.6.14です。

解決方法をご教授いただけると幸いです。

長文で失礼いたしました。


新着レスの表示


名前: E-mail(省略可)

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

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

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

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