「ファイルを開く」ダイアログの実装
VSTでファイルを読み込む際に必要なファイル読み込み用の”「ファイルを開く」ダイアログ”の実装方法を説明いたします。
なお、VST GUIの基本的な作成方法として下記をご理解いただいている前提で進めさせていただきます。
また、こちらのTipsで紹介している各コントロールを作成する関数も使用しています。
「ファイルを開く」ダイアログを開くにはCNewFileSelectorクラスとnotify()関数を使用します。
まず、VST GUIクラスにnotfy()関数を定義します。あわせて、「ファイルを開く」ダイアログを開くためのキックボタン用のメンバー変数も定義します。
【guieditor.h】
1 2 3 4 5 6 7 8 9 10 |
class MyVSTGUIEditor : public VSTGUIEditor, public IControlListener { protected: CKickButton* kickbutton; public: ~~ 中略 ~~ CMessageResult notify(CBaseObject *sender, const char *message) } |
キックボタンはVST GUIクラスのopen()関数内で作成します。キックボタンの作成は「キックボタンの実装方法」で説明しています。
タグは実際にパラメーターと関連付ける必要はないので、適当な値を指定します。(むしろ関連付けてしまうとそのパラメーター値が変わるので、使用していないタグ番号を割り当てます。)
【guieditor.cpp】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
bool PLUGIN_API MyVSTGUIEditor::open(void* parent, const PlatformType& platformType) { // GUIウィンドウが開かれたときに、UIを作成する ~~ 中略 ~~ // --------------------------------------------- // ここから各コントロールの作成 kickbutton = createKickButton(100, 10, 60); ~~ 中略 ~~ // GUIウィンドウのオープンに成功した場合はtrueを返す return true; } |
GUIでキックボタンが押された際に「ファイルを開く」ダイアログを開くよう処理を追加します。
valueChanged()関数でキックボタンが押されたかどうかをチェックします。キックボタンが押された場合、CNewFileSelectorクラスを作成して「ファイルを開く」ダイアログを開きます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
void MyVSTGUIEditor::valueChanged(CControl* pControl) { // キックボタンが押された場合のみ反応するようにする if (pControl == kickbutton) { if (pControl->getValueNormalized() > 0.5f) { // 「ファイルを開く」ダイアログのクラスを作成する CNewFileSelector* selector = CNewFileSelector::create(getFrame(), CNewFileSelector::kSelectFile); if (selector) { // 「ファイルを開く」ダイアログに必要な設定を行う。 // 「ファイルを開く」ダイアログのタイトルを設定する。 selector->setTitle("Choose An Audio File"); // 「ファイルを開く」ダイアログで表示する拡張子を設定する // 拡張子設定にはCFileExtensionクラスを使用し、第1引数に拡張子の説明文字列、 // 表示させたい拡張子を指定する。「*」でワイルドカードを指定できる。 selector->addFileExtension(CFileExtension("png files(.png)", "png")); selector->addFileExtension(CFileExtension("all Files(*.*)", "*")); selector->setDefaultExtension(CFileExtension("all Files(*.*)", "*")); // ダイアログが開いた後、VST GUIのフォーカスを切る // フォーカスを切らないと、「開く」や「キャンセル」ボタンをエンターキーで押したときに、 // 直前にフォーカスのあったGUIでonKeyUp()が呼ばれ、例外処理が発生する。 getFrame()->setFocusView(nullptr); // 「ファイルを開く」ダイアログのクラスを表示する selector->run(this); // 「ファイルを開く」ダイアログが閉じられた後はforget()関数で解放する selector->forget(); } } } } |
「ファイルを開く」ダイアログのタイトルや拡張子の設定は下記の通りとなります。
「ファイルを開く」ダイアログでファイルのパスが取得できた場合、VST GUIクラスのnotify()関数が呼び出されます。
notify()関数でメッセージの内容を確認し、「ファイルを開く」ダイアログのパス取得メッセージであった場合にファイルの読込などの処理を行います。
【guieditor.cpp】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
CMessageResult MyVSTGUIEditor::notify(CBaseObject *sender, const char *message) { // 「ファイルを開く」ダイアログでファイルのパスを取得した場合、messageはkSelectEndMessageとなる if (message == CNewFileSelector::kSelectEndMessage) { // senderはCNewFileSelectorクラスのポインタとなるのでキャストして利用する CNewFileSelector* sel = dynamic_cast<CNewFileSelector*>(sender); if (sel) { // getNumSelectedFiles()関数で選択されたファイルの数を確認する。 // ( 「ファイルを開く」ダイアログでは複数選択が可能なため) for(int i = 0; i<sel->getNumSelectedFiles(); i++) { // 選択されたファイルのパスを取得する UTF8StringPtr str = sel->getSelectedFile(i); // ここでパスを使用してファイルの読込などを行う // 今回は省略 } // メッセージが処理された場合、kMessageNotifiedを返す return kMessageNotified; } } // 該当するメッセージがない場合は、継承元のnotify()関数を呼び出して終了する。 return VSTGUIEditor::notify(sender, message); } |
以上でファイル読み込み用の「ファイルを開く」ダイアログの利用ができます。
上記以外にもVST3.6についての情報があります。下記をご参照ください。
また、質問やご指摘はコメント欄や掲示板、Twitterでいただけばとおもいます。
■掲示板
■Twitterアカウント:@vstcpp URL:https://twitter.com/vstcpp
うつぼかずら様
大変お世話になっております。超初歩的な質問で大変失礼いたします(CもC++も素人です。)。
ここで紹介いただいた方法で、ファイルのパス(UTF8StringPtr str)を取得し、「Wavファイルのフォーマットと読込」で紹介いただいているreadWavFileでwavファイルデータを読み込みたいと考えております。その際、readWavFile(str, …)とすると、「VSTGUI::UTF8StringPtrからchar[]へ変換できません」というコンパイルエラーが発生します。UTF8StringPtrからchar[]に変換するにはどのようにすればよいでしょうか?
お手すきの時間がございましたらご教示いただけますと幸いです。
sagamatさん
UTF8StringPtrはconst char*なので、いくつか方法があるかと思います。
1.strcpyなどでconst char*からchar*にコピーしてからreadWavFile()に渡す。
2.readWavFile()の引数を「const char filename[]」にする。
(合わせてCRiffLoaderのコンストラクタの引数も「const char filename[]」にする。)
うつぼかずら様
ご対応いただきまして、感謝申し上げます。後者のご提案を採用してみることにいたします。読み込み自体はまだうまくいっておりませんが、少なくともコンパイルエラーはなくなりました。お手数をおかけして申し訳ございません。ありがとうございました。