implement VST midi-output
[ardour.git] / libs / ardour / session_vst.cc
index 461934b5f4e31392681d8049c5b26e07d9bf3a58..845293de7caf084c2284b16111cb67736173438f 100644 (file)
@@ -28,6 +28,9 @@
 #include "ardour/windows_vst_plugin.h"
 #include "ardour/vestige/aeffectx.h"
 #include "ardour/vst_types.h"
+#ifdef WINDOWS_VST_SUPPORT
+#include <fst.h>
+#endif
 
 #include "i18n.h"
 
@@ -42,6 +45,17 @@ static int debug_callbacks = -1;
 
 using namespace ARDOUR;
 
+int Session::vst_current_loading_id = 0;
+const char* Session::vst_can_do_strings[] = {
+       X_("supplyIdle"),
+       X_("sendVstTimeInfo"),
+       X_("sendVstEvents"),
+       X_("sendVstMidiEvent"),
+       X_("supportShell"),
+       X_("shellCategory")
+};
+const int Session::vst_can_do_string_count = sizeof (vst_can_do_strings) / sizeof (char*);
+
 intptr_t Session::vst_callback (
        AEffect* effect,
        int32_t opcode,
@@ -90,36 +104,18 @@ intptr_t Session::vst_callback (
        case audioMasterVersion:
                SHOW_CALLBACK ("amc: audioMasterVersion\n");
                // vst version, currently 2 (0 for older)
-               return 2; // XXX 2400
+               return 2400;
 
        case audioMasterCurrentId:
                SHOW_CALLBACK ("amc: audioMasterCurrentId\n");
-               // returns the unique id of a plug that's currently
-               // loading
-               return 0;
+               // returns the unique id of a plug that's currently loading
+               return vst_current_loading_id;
 
        case audioMasterIdle:
                SHOW_CALLBACK ("amc: audioMasterIdle\n");
-               // call application idle routine (this will
-               // call effEditIdle for all open editors too)
-
-#if 0 // TODO -> emit to GUI OR better delegete to fst/fst
-
-               // This allows the main GUI window to update if needed.
-               // Some plugins take over the GUI event loop
-               // which causes the main GUI to freeze while the plugin GUI continues to run. This code
-               // prevents the main GUI from being frozen.
-
-               do {
-#ifdef GDK_WINDOWING_X11
-                       gtk_main_iteration_do(false);
-#else
-                       gtk_main_iteration()
+#ifdef WINDOWS_VST_SUPPORT
+               fst_audio_master_idle();
 #endif
-               } while (gtk_events_pending());
-#endif
-               printf("audioMasterIdle\n");
-
                if (effect) {
                        effect->dispatcher(effect, effEditIdle, 0, 0, NULL, 0.0f);
                }
@@ -262,6 +258,15 @@ intptr_t Session::vst_callback (
        case audioMasterProcessEvents:
                SHOW_CALLBACK ("amc: audioMasterProcessEvents\n");
                // VstEvents* in <ptr>
+               if (plug->midi_buffer()) {
+                       VstEvents* v = (VstEvents*)ptr;
+                       for (int n = 0 ; n < v->numEvents; ++n) {
+                               VstMidiEvent *vme = (VstMidiEvent*) (v->events[n]->dump);
+                               if (vme->type == kVstMidiType) {
+                                       plug->midi_buffer()->push_back(vme->deltaFrames, 3, (uint8_t*)vme->midiData);
+                               }
+                       }
+               }
                return 0;
 
        case audioMasterSetTime:
@@ -422,6 +427,11 @@ intptr_t Session::vst_callback (
        case audioMasterCanDo:
                SHOW_CALLBACK ("amc: audioMasterCanDo\n");
                // string in ptr,  (const char*)ptr
+               for (int i = 0; i < vst_can_do_string_count; i++) {
+                       if (! strcmp(vst_can_do_strings[i], (const char*)ptr)) {
+                               return 1;
+                       }
+               }
                return 0;
 
        case audioMasterGetLanguage: