| @@ -12,6 +12,7 @@ | |||
| + supports dynamically loaded plugin DLLs | |||
| - the plugin.dll files are _not_ binary compatible with the VCV Rack plugins ! | |||
| - there's a [plugin SDK](#dynamically-loaded-plugins-via-plugin-sdk) (for Microsoft Visual Studio 2017 Community Edition) which can be used to build new plugins without checking out this entire GIT repository | |||
| + supports internal oversampling (up to 16x with configurable quality) | |||
| Tested in | |||
| - Eureka (my own work-in-progress VST host) | |||
| @@ -28,7 +29,7 @@ Tested in | |||
| # Downloads | |||
| The current release can be found in the [vst2_bin/](vst2_bin/) folder. | |||
| Here's a snapshot of it: [veeseevstrack_0_6_1_win64_bin-09Aug2018.7z](dist/veeseevstrack_0_6_1_win64_bin-09Aug2018.7z) (64bit) | |||
| Here's a snapshot of it: [veeseevstrack_0_6_1_win64_bin-11Aug2018.7z](dist/veeseevstrack_0_6_1_win64_bin-11Aug2018.7z) (64bit) | |||
| Note: The effect plugin can used be as an instrument, too. You just have to send it MIDI events ! | |||
| @@ -14,8 +14,15 @@ | |||
| #ifdef USE_VST2 | |||
| extern void vst2_set_shared_plugin_tls_globals(void); | |||
| #ifdef RACK_HOST | |||
| extern void vst2_oversample_set (int _factor, int _quality); | |||
| extern void vst2_oversample_get (int *_factor, int *_quality); | |||
| #endif // RACK_HOST | |||
| #endif // USE_VST2 | |||
| namespace rack { | |||
| @@ -250,6 +257,28 @@ json_t *RackWidget::toJson() { | |||
| json_t *versionJ = json_string(global_ui->app.gApplicationVersion.c_str()); | |||
| json_object_set_new(rootJ, "version", versionJ); | |||
| #ifdef USE_VST2 | |||
| #ifdef RACK_HOST | |||
| { | |||
| int oversampleFactor; | |||
| int oversampleQuality; | |||
| vst2_oversample_get(&oversampleFactor, &oversampleQuality); | |||
| // Oversample factor | |||
| { | |||
| json_t *oversampleJ = json_real(oversampleFactor); | |||
| json_object_set_new(rootJ, "oversampleFactor", oversampleJ); | |||
| } | |||
| // Oversample quality (0..10) | |||
| { | |||
| json_t *oversampleJ = json_real(oversampleQuality); | |||
| json_object_set_new(rootJ, "oversampleQuality", oversampleJ); | |||
| } | |||
| } | |||
| #endif // RACK_HOST | |||
| #endif // USE_VST2 | |||
| // modules | |||
| json_t *modulesJ = json_array(); | |||
| std::map<ModuleWidget*, int> moduleIds; | |||
| @@ -323,6 +352,29 @@ void RackWidget::fromJson(json_t *rootJ) { | |||
| info("Loading patch using legacy mode %d", legacy); | |||
| } | |||
| #ifdef RACK_HOST | |||
| int oversampleFactor = -1; | |||
| int oversampleQuality = -1; | |||
| // Oversample factor | |||
| { | |||
| json_t *oversampleJ = json_object_get(rootJ, "oversampleFactor"); | |||
| if (oversampleJ) { | |||
| oversampleFactor = int(json_number_value(oversampleJ)); | |||
| } | |||
| } | |||
| // Oversample quality (0..10) | |||
| { | |||
| json_t *oversampleJ = json_object_get(rootJ, "oversampleQuality"); | |||
| if (oversampleJ) { | |||
| oversampleQuality = int(json_number_value(oversampleJ)); | |||
| } | |||
| } | |||
| vst2_oversample_set(oversampleFactor, oversampleQuality); | |||
| #endif // RACK_HOST | |||
| // modules | |||
| std::map<int, ModuleWidget*> moduleWidgets; | |||
| json_t *modulesJ = json_object_get(rootJ, "modules"); | |||
| @@ -6,6 +6,10 @@ | |||
| #include "global.hpp" | |||
| #include "global_ui.hpp" | |||
| #ifdef RACK_HOST | |||
| extern void vst2_oversample_set (int _factor, int _quality); | |||
| extern void vst2_oversample_get (int *_factor, int *_quality); | |||
| #endif // RACK_HOST | |||
| namespace rack { | |||
| @@ -116,6 +120,41 @@ struct SampleRateItem : MenuItem { | |||
| } | |||
| }; | |||
| #ifdef RACK_HOST | |||
| struct OversampleSetting { | |||
| const char *name; | |||
| int factor; | |||
| int quality; | |||
| }; | |||
| static OversampleSetting oversample_settings[] = { | |||
| /* 0 */ { "No oversampling", 1, 0 }, | |||
| /* 1 */ { "Oversample x2 (low)", 2, 4 }, | |||
| /* 2 */ { "Oversample x2 (medium)", 2, 7 }, | |||
| /* 3 */ { "Oversample x2 (high)", 2, 10 }, | |||
| /* 4 */ { "Oversample x4 (low)", 4, 4 }, | |||
| /* 5 */ { "Oversample x4 (medium)", 4, 7 }, | |||
| /* 6 */ { "Oversample x4 (high)", 4, 10 }, | |||
| /* 7 */ { "Oversample x6 (low)", 6, 4 }, | |||
| /* 8 */ { "Oversample x6 (medium)", 6, 7 }, | |||
| /* 9 */ { "Oversample x6 (high)", 6, 10 }, | |||
| /* 10 */ { "Oversample x8 (low)", 8, 4 }, | |||
| /* 11 */ { "Oversample x8 (medium)", 8, 7 }, | |||
| /* 12 */ { "Oversample x8 (high)", 8, 10 }, | |||
| }; | |||
| #define NUM_OVERSAMPLE_SETTINGS (sizeof(oversample_settings) / sizeof(OversampleSetting)) | |||
| struct OversampleItem : MenuItem { | |||
| const OversampleSetting *setting; | |||
| void onAction(EventAction &e) override { | |||
| vst2_oversample_set(setting->factor, setting->quality); | |||
| global->gPaused = false; | |||
| } | |||
| }; | |||
| #endif // RACK_HOST | |||
| struct SampleRateButton : TooltipIconButton { | |||
| SampleRateButton() { | |||
| setSVG(SVG::load(assetGlobal("res/icons/noun_1240789_cc.svg"))); | |||
| @@ -132,6 +171,24 @@ struct SampleRateButton : TooltipIconButton { | |||
| pauseItem->text = global->gPaused ? "Resume engine" : "Pause engine"; | |||
| menu->addChild(pauseItem); | |||
| #ifdef USE_VST2 | |||
| { | |||
| int factor; | |||
| int quality; | |||
| vst2_oversample_get(&factor, &quality); | |||
| for(unsigned int overIdx = 0u; overIdx < NUM_OVERSAMPLE_SETTINGS; overIdx++) | |||
| { | |||
| const OversampleSetting *overSetting = &oversample_settings[overIdx]; | |||
| OversampleItem *item = new OversampleItem(); | |||
| item->text = overSetting->name; | |||
| item->rightText = CHECKMARK( (overSetting->factor == factor) && (overSetting->quality == quality) ); | |||
| item->setting = overSetting; | |||
| menu->addChild(item); | |||
| } | |||
| } | |||
| #else | |||
| std::vector<float> sampleRates = {44100, 48000, 88200, 96000, 176400, 192000}; | |||
| for (float sampleRate : sampleRates) { | |||
| SampleRateItem *item = new SampleRateItem(); | |||
| @@ -140,6 +197,7 @@ struct SampleRateButton : TooltipIconButton { | |||
| item->sampleRate = sampleRate; | |||
| menu->addChild(item); | |||
| } | |||
| #endif // USE_VST2 | |||
| } | |||
| }; | |||
| @@ -12,6 +12,10 @@ | |||
| extern void vst2_window_size_set (int _width, int _height); | |||
| extern void vst2_refresh_rate_set (float _hz); | |||
| #ifdef RACK_HOST | |||
| extern void vst2_oversample_set (int _factor, int _quality); | |||
| #endif // RACK_HOST | |||
| namespace rack { | |||
| extern bool b_touchkeyboard_enable; | |||
| @@ -190,6 +194,29 @@ static void settingsFromJson(json_t *rootJ, bool bWindowSizeOnly) { | |||
| } | |||
| #endif // USE_VST2 | |||
| #ifdef RACK_HOST | |||
| int oversampleFactor = -1; | |||
| int oversampleQuality = -1; | |||
| // Oversample factor | |||
| { | |||
| json_t *oversampleJ = json_object_get(rootJ, "oversampleFactor"); | |||
| if (oversampleJ) { | |||
| oversampleFactor = int(json_number_value(oversampleJ)); | |||
| } | |||
| } | |||
| // Oversample quality (0..10) | |||
| { | |||
| json_t *oversampleJ = json_object_get(rootJ, "oversampleQuality"); | |||
| if (oversampleJ) { | |||
| oversampleQuality = int(json_number_value(oversampleJ)); | |||
| } | |||
| } | |||
| vst2_oversample_set(oversampleFactor, oversampleQuality); | |||
| #endif // RACK_HOST | |||
| // lastPath | |||
| json_t *lastPathJ = json_object_get(rootJ, "lastPath"); | |||
| if (lastPathJ) | |||
| @@ -17,7 +17,7 @@ | |||
| /// | |||
| /// created: 25Jun2018 | |||
| /// changed: 26Jun2018, 27Jun2018, 29Jun2018, 01Jul2018, 02Jul2018, 06Jul2018, 13Jul2018 | |||
| /// 26Jul2018, 04Aug2018, 05Aug2018, 06Aug2018, 07Aug2018, 09Aug2018 | |||
| /// 26Jul2018, 04Aug2018, 05Aug2018, 06Aug2018, 07Aug2018, 09Aug2018, 11Aug2018 | |||
| /// | |||
| /// | |||
| /// | |||
| @@ -74,6 +74,7 @@ namespace rack { | |||
| #include "../include/window.hpp" | |||
| #include "../dep/include/osdialog.h" | |||
| #include "../include/app.hpp" | |||
| #include <speex/speex_resampler.h> | |||
| // using namespace rack; | |||
| // extern void rack::windowRun(void); | |||
| @@ -389,7 +390,8 @@ public: | |||
| static const uint32_t MIN_SAMPLE_RATE = 8192u; | |||
| static const uint32_t MAX_SAMPLE_RATE = 384000u; | |||
| static const uint32_t MIN_BLOCK_SIZE = 64u; | |||
| static const uint32_t MAX_BLOCK_SIZE = 65536u; | |||
| static const uint32_t MAX_BLOCK_SIZE = 16384u; | |||
| static const uint32_t MAX_OVERSAMPLE_FACTOR = 16u; | |||
| public: | |||
| rack::Global rack_global; | |||
| @@ -399,8 +401,19 @@ protected: | |||
| PluginString dllname; | |||
| PluginString cwd; | |||
| public: | |||
| struct { | |||
| sSI factor; // 1=no SR conversion, 2=oversample x2, 4=oversample x4, .. | |||
| int quality; // SPEEX_RESAMPLER_QUALITY_xxx | |||
| SpeexResamplerState *srs_in; | |||
| SpeexResamplerState *srs_out; | |||
| sF32 in_buffers[NUM_INPUTS * MAX_BLOCK_SIZE * MAX_OVERSAMPLE_FACTOR]; | |||
| sF32 out_buffers[NUM_OUTPUTS * MAX_BLOCK_SIZE]; | |||
| } oversample; | |||
| protected: | |||
| float sample_rate; // e.g. 44100.0 | |||
| uint32_t block_size; // e.g. 64 | |||
| uint32_t block_size; // e.g. 64 | |||
| PluginMutex mtx_audio; | |||
| public: | |||
| @@ -519,6 +532,20 @@ public: | |||
| redraw_ival_ms = sUI(1000.0f / _hz); | |||
| } | |||
| void destroyResamplerStates(void) { | |||
| if(NULL != oversample.srs_in) | |||
| { | |||
| speex_resampler_destroy(oversample.srs_in); | |||
| oversample.srs_in = NULL; | |||
| } | |||
| if(NULL != oversample.srs_out) | |||
| { | |||
| speex_resampler_destroy(oversample.srs_out); | |||
| oversample.srs_out = NULL; | |||
| } | |||
| } | |||
| void openEditor(void *_hwnd) { | |||
| printf("xxx vstrack_plugin: openEditor() parentHWND=%p\n", _hwnd); | |||
| setGlobals(); | |||
| @@ -575,6 +602,10 @@ public: | |||
| printf("xxx vstrack_plugin: vst2_exit() done\n"); | |||
| destroyResamplerStates(); | |||
| printf("xxx vstrack_plugin: destroyResamplerStates() done\n"); | |||
| #ifdef USE_CONSOLE | |||
| // FreeConsole(); | |||
| #endif // USE_CONSOLE | |||
| @@ -598,6 +629,29 @@ public: | |||
| return _vstPlugin.numOutputs; | |||
| } | |||
| void setOversample(int _factor, int _quality) { | |||
| if(_factor < 0) | |||
| _factor = oversample.factor; // keep | |||
| if(_quality < 0) | |||
| _quality = oversample.quality; // keep | |||
| if(_factor < 1) | |||
| _factor = 1; | |||
| else if(_factor > MAX_OVERSAMPLE_FACTOR) | |||
| _factor = MAX_OVERSAMPLE_FACTOR; | |||
| if(_quality < SPEEX_RESAMPLER_QUALITY_MIN/*0*/) | |||
| _quality = SPEEX_RESAMPLER_QUALITY_MIN; | |||
| else if(_quality > SPEEX_RESAMPLER_QUALITY_MAX/*10*/) | |||
| _quality = SPEEX_RESAMPLER_QUALITY_MAX; | |||
| oversample.factor = sUI(_factor); | |||
| oversample.quality = _quality; | |||
| setSampleRate(sample_rate); | |||
| } | |||
| bool setSampleRate(float _rate) { | |||
| bool r = false; | |||
| @@ -606,7 +660,31 @@ public: | |||
| setGlobals(); | |||
| lockAudio(); | |||
| sample_rate = _rate; | |||
| vst2_set_samplerate(sample_rate); | |||
| vst2_set_samplerate(sample_rate * oversample.factor); // see engine.cpp | |||
| destroyResamplerStates(); | |||
| // Lazy-alloc resampler state | |||
| if(oversample.factor > 1u) | |||
| { | |||
| int err; | |||
| oversample.srs_in = speex_resampler_init(NUM_INPUTS, | |||
| sUI(sample_rate), // in rate | |||
| sUI(sample_rate * oversample.factor), // out rate | |||
| oversample.quality, | |||
| &err | |||
| ); | |||
| oversample.srs_out = speex_resampler_init(NUM_OUTPUTS, | |||
| sUI(sample_rate * oversample.factor), // in rate | |||
| sUI(sample_rate), // out rate | |||
| oversample.quality, | |||
| &err | |||
| ); | |||
| } | |||
| unlockAudio(); | |||
| r = true; | |||
| } | |||
| @@ -781,7 +859,7 @@ sSI VSTPluginWrapper::instance_count = 0; | |||
| */ | |||
| void VSTPluginProcessReplacingFloat32(VSTPlugin *vstPlugin, | |||
| float **_inputs, | |||
| float **outputs, | |||
| float **_outputs, | |||
| VstInt32 sampleFrames | |||
| ) { | |||
| if(sUI(sampleFrames) > VSTPluginWrapper::MAX_BLOCK_SIZE) | |||
| @@ -803,34 +881,118 @@ void VSTPluginProcessReplacingFloat32(VSTPlugin *vstPlugin, | |||
| //printf("xxx vstrack_plugin: VSTPluginProcessReplacingFloat32: wrapper=%p\n", wrapper); | |||
| #ifdef HAVE_WINDOWS | |||
| _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); | |||
| #endif // HAVE_WINDOWS | |||
| sUI chIdx; | |||
| // (note) Cubase (tested with 9.5.30) uses the same buffer(s) for both input&output | |||
| // => back up the inputs before clearing the outputs | |||
| sF32 *inputs[NUM_INPUTS]; | |||
| sUI k = 0u; | |||
| for(chIdx = 0u; chIdx < NUM_INPUTS; chIdx++) | |||
| if( (wrapper->oversample.factor > 1u) && | |||
| (NULL != wrapper->oversample.srs_in) && | |||
| (NULL != wrapper->oversample.srs_out) | |||
| ) | |||
| { | |||
| inputs[chIdx] = &wrapper->tmp_input_buffers[k]; | |||
| ::memcpy((void*)inputs[chIdx], _inputs[chIdx], sizeof(sF32)*sampleFrames); | |||
| k += sampleFrames; | |||
| } | |||
| sF32 *inputs[NUM_INPUTS]; | |||
| sF32 *outputs[NUM_INPUTS]; | |||
| sUI hostNumFrames = sampleFrames; | |||
| sUI overNumFrames = sampleFrames * wrapper->oversample.factor; | |||
| // Clear output buffers | |||
| // (note) AudioInterface instances accumulate samples in the output buffer | |||
| for(chIdx = 0u; chIdx < NUM_OUTPUTS; chIdx++) | |||
| { | |||
| ::memset((void*)outputs[chIdx], 0, sizeof(sF32)*sampleFrames); | |||
| } | |||
| // Up-sample inputs | |||
| { | |||
| sUI inNumFrames = hostNumFrames; | |||
| sUI outNumFrames = overNumFrames; | |||
| sF32 *d = wrapper->oversample.in_buffers; | |||
| for(chIdx = 0u; chIdx < NUM_INPUTS; chIdx++) | |||
| { | |||
| sF32 *s = _inputs[chIdx]; | |||
| if(1 && wrapper->b_processing) | |||
| int err = speex_resampler_process_float(wrapper->oversample.srs_in, | |||
| chIdx, | |||
| s, | |||
| &inNumFrames, | |||
| d, | |||
| &outNumFrames | |||
| ); | |||
| inputs[chIdx] = d; | |||
| // Next input channel | |||
| d += outNumFrames; | |||
| } | |||
| } | |||
| // Clear output buffers | |||
| // (note) AudioInterface instances accumulate samples in the output buffer | |||
| { | |||
| sF32 *d = wrapper->oversample.out_buffers; | |||
| ::memset((void*)d, 0, (sizeof(sF32) * NUM_OUTPUTS * overNumFrames)); | |||
| for(chIdx = 0u; chIdx < NUM_OUTPUTS; chIdx++) | |||
| { | |||
| outputs[chIdx] = d; | |||
| d += overNumFrames; | |||
| } | |||
| } | |||
| // Process rack modules | |||
| if(wrapper->b_processing) | |||
| { | |||
| vst2_engine_process(inputs, outputs, overNumFrames); | |||
| } | |||
| // Down-sample outputs | |||
| { | |||
| sF32 *s = wrapper->oversample.out_buffers; | |||
| sUI inNumFrames = overNumFrames; | |||
| sUI outNumFrames = hostNumFrames; | |||
| for(chIdx = 0u; chIdx < NUM_INPUTS; chIdx++) | |||
| { | |||
| sF32 *d = _outputs[chIdx]; | |||
| int err = speex_resampler_process_float(wrapper->oversample.srs_out, | |||
| chIdx, | |||
| s, | |||
| &inNumFrames, | |||
| d, | |||
| &outNumFrames | |||
| ); | |||
| // Next output channel | |||
| s += inNumFrames; | |||
| } | |||
| } | |||
| } | |||
| else | |||
| { | |||
| // No oversampling | |||
| #ifdef HAVE_WINDOWS | |||
| _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); | |||
| #endif // HAVE_WINDOWS | |||
| // (note) Cubase (tested with 9.5.30) uses the same buffer(s) for both input&output | |||
| // => back up the inputs before clearing the outputs | |||
| sF32 *inputs[NUM_INPUTS]; | |||
| sUI k = 0u; | |||
| for(chIdx = 0u; chIdx < NUM_INPUTS; chIdx++) | |||
| { | |||
| inputs[chIdx] = &wrapper->tmp_input_buffers[k]; | |||
| ::memcpy((void*)inputs[chIdx], _inputs[chIdx], sizeof(sF32)*sampleFrames); | |||
| k += sampleFrames; | |||
| } | |||
| vst2_engine_process(inputs, outputs, sampleFrames); | |||
| // Clear output buffers | |||
| // (note) AudioInterface instances accumulate samples in the output buffer | |||
| for(chIdx = 0u; chIdx < NUM_OUTPUTS; chIdx++) | |||
| { | |||
| ::memset((void*)_outputs[chIdx], 0, sizeof(sF32)*sampleFrames); | |||
| } | |||
| if(wrapper->b_processing) | |||
| { | |||
| vst2_engine_process(inputs, _outputs, sampleFrames); | |||
| } | |||
| } | |||
| // // rack::global->engine.vipMutex.unlock(); | |||
| @@ -838,7 +1000,6 @@ void VSTPluginProcessReplacingFloat32(VSTPlugin *vstPlugin, | |||
| wrapper->unlockAudio(); | |||
| //printf("xxx vstrack_plugin: VSTPluginProcessReplacingFloat32: LEAVE\n"); | |||
| // // glfwSetInstance(NULL); // xxxx test TLS (=> not working in mingw64!) | |||
| } | |||
| @@ -1374,6 +1535,10 @@ VSTPluginWrapper::VSTPluginWrapper(audioMasterCallback vstHostCallback, | |||
| // report latency | |||
| _vstPlugin.initialDelay = 0; | |||
| oversample.factor = 1; | |||
| oversample.quality = SPEEX_RESAMPLER_QUALITY_DEFAULT; | |||
| oversample.srs_in = NULL; | |||
| oversample.srs_out = NULL; | |||
| sample_rate = 44100.0f; | |||
| block_size = 64u; | |||
| b_processing = true; | |||
| @@ -1433,7 +1598,7 @@ void vst2_window_size_set(int _width, int _height) { | |||
| rack::global->vst2.wrapper->setWindowSize(_width, _height); | |||
| } | |||
| void vst2_refresh_rate_set (float _hz) { | |||
| void vst2_refresh_rate_set(float _hz) { | |||
| rack::global->vst2.wrapper->setRefreshRate(_hz); | |||
| } | |||
| @@ -1447,6 +1612,15 @@ extern "C" void lglw_redraw_cbk(lglw_t _lglw) { | |||
| wrapper->redraw(); | |||
| } | |||
| void vst2_oversample_set(int _factor, int _quality) { | |||
| rack::global->vst2.wrapper->setOversample(_factor, _quality); | |||
| } | |||
| void vst2_oversample_get(int *_factor, int *_quality) { | |||
| *_factor = int(rack::global->vst2.wrapper->oversample.factor); | |||
| *_quality = int(rack::global->vst2.wrapper->oversample.quality); | |||
| } | |||
| /** | |||
| * Implementation of the main entry point of the plugin | |||
| @@ -1,3 +1,10 @@ | |||
| ** August 11th, 2018 | |||
| - add settings.json:"oversampleFactor" option (1..16) | |||
| - add settings.json:"oversampleQuality" option (0..10) | |||
| - oversample settings are also saved / restored with the patch | |||
| - oversample settings can be configured via toolbar button menu | |||
| ** August 9th, 2018 | |||
| - add settings.json:"touchKbd" option | |||
| - show / hide virtual keyboard when textfield is clicked | |||
| @@ -1,5 +1,5 @@ | |||
| VeeSeeVST Rack VST 2.4 Plugin -- August 9th, 2018 | |||
| ================================================= | |||
| VeeSeeVST Rack VST 2.4 Plugin -- August 11th, 2018 | |||
| ================================================== | |||
| !!!------------------------------------------------------------------------------ | |||
| !!! ***** THIS IS NOT AN OFFICIAL VCV RACK RELEASE ***** !!! | |||
| @@ -16,6 +16,7 @@ This is a quick'n'dirty adaption of VCV Rack 0.6.1 for the VST2 format. | |||
| + supports VST program chunks (=> patches are saved with the DAW's project file or as .fxp files) | |||
| + supports VST host timing (audioMasterGetTime / kVstTempoValid / kVstTransportPlaying, see Core.MIDI-1 module) | |||
| + supports VST parameters (send / recv) | |||
| + supports internal oversampling (up to 16x with configurable quality) | |||
| Here's a demo video of it: https://vimeo.com/277703414 | |||
| @@ -4,7 +4,7 @@ | |||
| [0.000 info src/plugin.cpp:673] vcvrack: Loaded static plugin Alikins 0.6.1 | |||
| [0.000 info src/plugin.cpp:673] vcvrack: Loaded static plugin AS 0.6.1 | |||
| [0.000 info src/plugin.cpp:673] vcvrack: Loaded static plugin AudibleInstruments 0.6.1 | |||
| [0.000 info src/plugin.cpp:673] vcvrack: Loaded static plugin BaconMusic 0.6.1 | |||
| [0.001 info src/plugin.cpp:673] vcvrack: Loaded static plugin BaconMusic 0.6.1 | |||
| [0.001 info src/plugin.cpp:673] vcvrack: Loaded static plugin Befaco 0.6.1 | |||
| [0.001 info src/plugin.cpp:673] vcvrack: Loaded static plugin Bidoo 0.6.1 | |||
| [0.002 info src/plugin.cpp:673] vcvrack: Loaded static plugin Bogaudio 0.6.1 | |||
| @@ -13,7 +13,7 @@ | |||
| [0.002 info src/plugin.cpp:673] vcvrack: Loaded static plugin DrumKit 0.6.1 | |||
| [0.002 info src/plugin.cpp:673] vcvrack: Loaded static plugin ErraticInstruments 0.6.1 | |||
| [0.002 info src/plugin.cpp:673] vcvrack: Loaded static plugin ESeries 0.6.1 | |||
| [0.002 info src/plugin.cpp:673] vcvrack: Loaded static plugin FrozenWasteland 0.6.1 | |||
| [0.003 info src/plugin.cpp:673] vcvrack: Loaded static plugin FrozenWasteland 0.6.1 | |||
| [0.003 info src/plugin.cpp:673] vcvrack: Loaded static plugin Fundamental 0.6.1 | |||
| [0.003 info src/plugin.cpp:673] vcvrack: Loaded static plugin Gratrix 0.6.1 | |||
| [0.003 info src/plugin.cpp:673] vcvrack: Loaded static plugin HetrickCV 0.6.1 | |||
| @@ -28,7 +28,7 @@ | |||
| [0.004 info src/plugin.cpp:673] vcvrack: Loaded static plugin mscHack 0.6.1 | |||
| [0.004 info src/plugin.cpp:673] vcvrack: Loaded static plugin mtsch-plugins 0.6.1 | |||
| [0.004 info src/plugin.cpp:673] vcvrack: Loaded static plugin NauModular 0.6.1 | |||
| [0.004 info src/plugin.cpp:673] vcvrack: Loaded static plugin Ohmer 0.6.1 | |||
| [0.005 info src/plugin.cpp:673] vcvrack: Loaded static plugin Ohmer 0.6.1 | |||
| [0.005 info src/plugin.cpp:673] vcvrack: Loaded static plugin Qwelk 0.6.1 | |||
| [0.005 info src/plugin.cpp:673] vcvrack: Loaded static plugin RJModules 0.6.1 | |||
| [0.005 info src/plugin.cpp:673] vcvrack: Loaded static plugin SerialRacker 0.6.1 | |||
| @@ -41,25 +41,25 @@ | |||
| [0.006 info src/plugin.cpp:673] vcvrack: Loaded static plugin unless_modules 0.6.1 | |||
| [0.006 info src/plugin.cpp:673] vcvrack: Loaded static plugin Valley 0.6.1 | |||
| [0.006 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/Alikins/plugin.dll does not exist | |||
| [0.006 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/AS/plugin.dll does not exist | |||
| [0.007 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/AS/plugin.dll does not exist | |||
| [0.007 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/AudibleInstruments/plugin.dll does not exist | |||
| [0.007 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/BaconMusic/plugin.dll does not exist | |||
| [0.007 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/Befaco/plugin.dll does not exist | |||
| [0.007 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/Bidoo/plugin.dll does not exist | |||
| [0.007 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/Bogaudio/plugin.dll does not exist | |||
| [0.007 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/BOKONTEPByteBeatMachine/plugin.dll does not exist | |||
| [0.007 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/cf/plugin.dll does not exist | |||
| [0.008 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/cf/plugin.dll does not exist | |||
| [0.008 info src/plugin.cpp:155] Loaded plugin dBiz 0.6.1 from f:\git\VeeSeeVSTRack\vst2_bin\/plugins/dBiz/plugin.dll | |||
| [0.008 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/DHE-Modules/plugin.dll does not exist | |||
| [0.008 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/DrumKit/plugin.dll does not exist | |||
| [0.008 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/ErraticInstruments/plugin.dll does not exist | |||
| [0.009 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/ErraticInstruments/plugin.dll does not exist | |||
| [0.009 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/ESeries/plugin.dll does not exist | |||
| [0.009 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/FrozenWasteland/plugin.dll does not exist | |||
| [0.009 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/Fundamental/plugin.dll does not exist | |||
| [0.009 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/Gratrix/plugin.dll does not exist | |||
| [0.009 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/HetrickCV/plugin.dll does not exist | |||
| [0.009 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/huaba/plugin.dll does not exist | |||
| [0.009 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/JW-Modules/plugin.dll does not exist | |||
| [0.010 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/JW-Modules/plugin.dll does not exist | |||
| [0.010 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/Koralfx-Modules/plugin.dll does not exist | |||
| [0.010 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/LindenbergResearch/plugin.dll does not exist | |||
| [0.010 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/LOGinstruments/plugin.dll does not exist | |||
| @@ -67,55 +67,58 @@ | |||
| [0.010 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/moDllz/plugin.dll does not exist | |||
| [0.010 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/modular80/plugin.dll does not exist | |||
| [0.010 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/mscHack/plugin.dll does not exist | |||
| [0.010 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/mtsch-plugins/plugin.dll does not exist | |||
| [0.011 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/mtsch-plugins/plugin.dll does not exist | |||
| [0.011 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/NauModular/plugin.dll does not exist | |||
| [0.011 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/Ohmer/plugin.dll does not exist | |||
| [0.011 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/Qwelk/plugin.dll does not exist | |||
| [0.011 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/RJModules/plugin.dll does not exist | |||
| [0.011 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/SerialRacker/plugin.dll does not exist | |||
| [0.011 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/SonusModular/plugin.dll does not exist | |||
| [0.011 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/Southpole-parasites/plugin.dll does not exist | |||
| [0.012 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/Southpole-parasites/plugin.dll does not exist | |||
| [0.012 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/squinkylabs-plug1/plugin.dll does not exist | |||
| [0.012 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/SubmarineFree/plugin.dll does not exist | |||
| [0.012 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/Template/plugin.dll does not exist | |||
| [0.012 info src/plugin.cpp:155] Loaded plugin Template_shared 0.6.1 from f:\git\VeeSeeVSTRack\vst2_bin\/plugins/Template_shared/plugin.dll | |||
| [0.013 info src/plugin.cpp:155] Loaded plugin Template_shared 0.6.1 from f:\git\VeeSeeVSTRack\vst2_bin\/plugins/Template_shared/plugin.dll | |||
| [0.013 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/trowaSoft/plugin.dll does not exist | |||
| [0.013 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/unless_modules/plugin.dll does not exist | |||
| [0.013 warn src/plugin.cpp:86] Plugin file f:\git\VeeSeeVSTRack\vst2_bin\/plugins/Valley/plugin.dll does not exist | |||
| [0.013 info src/settings.cpp:235] Loading settings f:\git\VeeSeeVSTRack\vst2_bin\/settings.json | |||
| [0.013 info src/settings.cpp:262] Loading settings f:\git\VeeSeeVSTRack\vst2_bin\/settings.json | |||
| [0.030 info src/window.cpp:599] Loaded font f:\git\VeeSeeVSTRack\vst2_bin\/res/fonts/DejaVuSans.ttf | |||
| [0.030 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/icons/noun_146097_cc.svg | |||
| [0.031 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/icons/noun_31859_cc.svg | |||
| [0.030 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/icons/noun_31859_cc.svg | |||
| [0.031 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/icons/noun_1343816_cc.svg | |||
| [0.031 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/icons/noun_1343811_cc.svg | |||
| [0.032 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/icons/noun_1084369_cc.svg | |||
| [0.032 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/icons/noun_1745061_cc.svg | |||
| [0.031 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/icons/noun_1084369_cc.svg | |||
| [0.031 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/icons/noun_1745061_cc.svg | |||
| [0.032 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/icons/noun_1240789_cc.svg | |||
| [0.032 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/icons/noun_305536_cc.svg | |||
| [0.033 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/icons/noun_468341_cc.svg | |||
| [0.033 info src/settings.cpp:235] Loading settings f:\git\VeeSeeVSTRack\vst2_bin\/settings.json | |||
| [0.036 info src/app/RackWidget.cpp:196] Loading patch from string | |||
| [0.038 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/Core/AudioInterface.svg | |||
| [0.038 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/ComponentLibrary/ScrewSilver.svg | |||
| [0.039 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/ComponentLibrary/PJ301M.svg | |||
| [0.039 info src/window.cpp:599] Loaded font f:\git\VeeSeeVSTRack\vst2_bin\/res/fonts/ShareTechMono-Regular.ttf | |||
| [0.041 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/Core/MIDIToCVInterface.svg | |||
| [0.044 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Bogaudio/res/XCO.svg | |||
| [0.045 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Bogaudio/res/knob_68px.svg | |||
| [0.045 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Bogaudio/res/knob_16px.svg | |||
| [0.045 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Bogaudio/res/button_9px_0.svg | |||
| [0.045 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Bogaudio/res/button_9px_1.svg | |||
| [0.046 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Bogaudio/res/knob_38px.svg | |||
| [0.046 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Bogaudio/res/slider_switch_2_14px_0.svg | |||
| [0.046 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Bogaudio/res/slider_switch_2_14px_1.svg | |||
| [0.047 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Bogaudio/res/port.svg | |||
| [0.048 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Fundamental/res/VCA.svg | |||
| [0.049 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/ComponentLibrary/RoundLargeBlackKnob.svg | |||
| [0.050 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Fundamental/res/VCF.svg | |||
| [0.051 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/ComponentLibrary/RoundHugeBlackKnob.svg | |||
| [0.052 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/AS/res/ADSR.svg | |||
| [0.053 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/AS/res/as-hexscrew.svg | |||
| [0.053 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/AS/res/as-SlidePot.svg | |||
| [0.054 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/AS/res/as-SlidePotHandle.svg | |||
| [0.054 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/AS/res/as-PJ301M.svg | |||
| [4.171 info src/app/RackWidget.cpp:158] Saving patch to string | |||
| [0.032 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/icons/noun_468341_cc.svg | |||
| [0.032 info src/settings.cpp:262] Loading settings f:\git\VeeSeeVSTRack\vst2_bin\/settings.json | |||
| [0.034 info src/app/RackWidget.cpp:203] Loading patch from string | |||
| [0.036 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/Core/AudioInterface.svg | |||
| [0.037 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/ComponentLibrary/ScrewSilver.svg | |||
| [0.037 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/ComponentLibrary/PJ301M.svg | |||
| [0.037 info src/window.cpp:599] Loaded font f:\git\VeeSeeVSTRack\vst2_bin\/res/fonts/ShareTechMono-Regular.ttf | |||
| [0.039 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/Core/MIDIToCVInterface.svg | |||
| [0.042 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Bogaudio/res/XCO.svg | |||
| [0.043 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Bogaudio/res/knob_68px.svg | |||
| [0.043 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Bogaudio/res/knob_16px.svg | |||
| [0.043 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Bogaudio/res/button_9px_0.svg | |||
| [0.044 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Bogaudio/res/button_9px_1.svg | |||
| [0.044 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Bogaudio/res/knob_38px.svg | |||
| [0.044 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Bogaudio/res/slider_switch_2_14px_0.svg | |||
| [0.045 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Bogaudio/res/slider_switch_2_14px_1.svg | |||
| [0.045 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Bogaudio/res/port.svg | |||
| [0.046 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Fundamental/res/VCA.svg | |||
| [0.047 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/ComponentLibrary/RoundLargeBlackKnob.svg | |||
| [0.048 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Fundamental/res/VCF.svg | |||
| [0.049 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/ComponentLibrary/RoundHugeBlackKnob.svg | |||
| [0.051 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/AS/res/ADSR.svg | |||
| [0.051 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/AS/res/as-hexscrew.svg | |||
| [0.051 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/AS/res/as-SlidePot.svg | |||
| [0.052 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/AS/res/as-SlidePotHandle.svg | |||
| [0.052 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/AS/res/as-PJ301M.svg | |||
| [0.055 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\plugins/Fundamental/res/VCO-1.svg | |||
| [0.055 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/ComponentLibrary/CKSS_0.svg | |||
| [0.056 info src/window.cpp:654] Loaded SVG f:\git\VeeSeeVSTRack\vst2_bin\/res/ComponentLibrary/CKSS_1.svg | |||
| [15.988 info src/app/RackWidget.cpp:165] Saving patch to string | |||
| @@ -17,6 +17,8 @@ | |||
| "touchInput": false, | |||
| "touchKbd": false, | |||
| "sampleRate": 44100.0, | |||
| "oversampleFactor": 1.0, | |||
| "oversampleQuality": 7.0, | |||
| "lastPath": "", | |||
| "moduleBrowser": { | |||
| "favorites": [ | |||
| @@ -98,12 +100,16 @@ | |||
| }, | |||
| { | |||
| "plugin": "Fundamental", | |||
| "model": "VCA" | |||
| "model": "VCO-1" | |||
| }, | |||
| { | |||
| "plugin": "Fundamental", | |||
| "model": "VCF" | |||
| }, | |||
| { | |||
| "plugin": "Fundamental", | |||
| "model": "VCA" | |||
| }, | |||
| { | |||
| "plugin": "Fundamental", | |||
| "model": "VCMixer" | |||