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

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

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

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

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は差し替え無しで組み込んだまま(リソースとして組み込む?)
・それ以外は変更なし(サンプルのフィルタ部、アンプ部、同時発音数などはそのまま効果が出るように残したい)

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

109管理人★:2015/08/14(金) 20:12:15
猫十さん

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

私のVSTiサンプルは「http://www39.atwiki.jp/vst_prog/pages/84.html」だと
思いますので、これをを前提として簡単に説明させていただきます。

■MySynthSampleVSTのコンストラクタ
 まず、wavファイルから波形をすべて読み込む。
 読み込みを行うのはファイルでもリソースからでもどちらでもよい。

 次にMIDIノートと再生すべき波形の対応テーブルを作成する。
 対応テーブルは下記のような情報を持つ。
  MIDIノートNo69(A5)の時 … 波形1(440Hz)をそのまま再生
  MIDIノートNo70(A#5)の時 … 波形1(440Hz)を466.2Hzになるように早送りで再生
  MIDIノートNo71(B5)の時 … 波形1(440Hz)を493.2Hzになるように早送りで再生
    :
  MIDIノートNo81(A6)の時 … 波形2(880Hz)をそのまま再生
    :

 ※読み込むwavファイルが固定のためコンストラクタで読み込んでいる。
  サンプラーのように途中で読み込みが必要な場合は読み込みスレッド等を作成する必要あり。

■MySynthSampleVST::onMidiKeyOn()
 OFF状態のオシレータをONにする際に、波形の対応テーブルの情報(使用する波形と再生速度)を
 オシレータに渡すようにする。
 (オシレータに波形の対応テーブル情報引き渡し関数等を追加する必要あり。)

■CVoice::amplitude()
 まず、経過時間から波形の読み込み位置を計算する。
 読み込み位置は、
  経過時間 × (再生したい周波数 ÷ 波形自体の周波数)
 で求められる。
 例えば、波形1(440Hz)で466.2Hzとなるように再生するには、
  経過時間 × (466.2 ÷ 440)
 となる。

 読み込んだ波形は配列に保存されていると思うので計算した読み込み位置が整数でない場合、
 切り捨てたり前後の値から補完する。
 なお、経過時間が波形のサイズより長い場合は0を返す。


Waveテーブルシンセサイザにするには上記のような手順となります。

なお、wavファイルをリソースにするにはrcファイルとヘッダファイルを作れば
リソースに出来ますが、読み込みの部分で一工夫必要となります。
まずはwavファイルで試してみることをお勧めいたします。
(FindResource()やLockResource()等を使う必要が出てくると思います。)

お盆のため、すぐに確認できず記憶で書いている部分があります…
間違いがある可能性がありますが、ご了承ください…

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

110専門学生:2015/08/15(土) 14:56:23
管理人さん。


先日は返信をありがとうございました。書き込みをさせていただいた際、説明不足があり、お手数をかけてしまってすみませんでした。
詳しい内容を再度記述いたします。

現在、此方のサイト様のmythynthSamleVSTのソースコードをお借りしてサンプラーのVSTを作成使用と考えております。
wavの音源ファイルを読み込もうとしていて、ifstreamのライブラリを使用してwavファイルを入れ込む方法を見つけました。
その際に入れ込んだwavのサンプリングレート等の表示、変更することができるようになりました

ですが、mytynthsampleVSTのprocessreplacingのInputs[]の中にPCMを入れ込むとうまく回ると考え、for文でまわしたところ、エラーはないもののDAWが応答なしで止まってしまいました。
現在そこで頓挫してしまい、質問をさせていただきました。

その際に利用したソースコードがprocessreplacingの最初に
WAVE wav1;
WAVE_FORMAT fmt1;
vector<short> ch1;

//ファイルから読み込み
wav1.load_from_file("C:/Users/k012c1117/desktop/ositeru.wav");

//フォーマット情報とデータを取り出す
fmt1 = wav1.get_format();
wav1.get_channel(ch1, 0);
for (long i = 0; i<wav1.data_size; i++){
inputs[0, i] = (float*)ch1[i];
inputs[1, i] = (float*)ch1[i];
outputs[0, i] = (float*)ch1[i];
outputs[1, i] = (float*)ch1[i];
}
を追加したものです。

何度も質問ばかりして申し訳ございませんが 回答をお願いいたします・・・。

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”の実装ですね。

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


新着レスの表示


名前: E-mail(省略可)

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

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

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

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