| @@ -4,29 +4,29 @@ This file describes the available features for each plugin format. | |||
| The limitations could be due to the plugin format itself or within DPF. | |||
| If the limitation is within DPF, a link is provided to a description below on the reason for it. | |||
| | Feature | JACK/Standalone | LADSPA | DSSI | LV2 | VST2 | VST3 | Feature | | |||
| |---------------------|---------------------------------------|-------------------------|---------------------|-------------------------------|--------------------------------|----------------------------------|---------------------| | |||
| | Audio port groups | [Yes*](#jack-audio-port-groups) | No | No | Yes | No | [No*](#vst3-is-work-in-progress) | Audio port groups | | |||
| | Audio port as CV | Yes | No | No | Yes | No | [No*](#vst3-is-work-in-progress) | Audio port as CV | | |||
| | Audio sidechan | Yes | No | No | Yes | [No*](#vst2-potential-support) | [No*](#vst3-is-work-in-progress) | Audio sidechan | | |||
| | Bypass control | No | No | No | Yes | [No*](#vst2-potential-support) | [No*](#vst3-is-work-in-progress) | Bypass control | | |||
| | MIDI input | Yes | No | Yes | Yes | Yes | Yes | MIDI input | | |||
| | MIDI output | Yes | No | No | Yes | Yes | Yes | MIDI output | | |||
| | Parameter changes | Yes | No | No | [No*](#lv2-parameter-changes) | Yes | Yes | Parameter changes | | |||
| | Parameter groups | No | No | No | Yes | Yes | [No*](#vst3-is-work-in-progress) | Parameter groups | | |||
| | Parameter outputs | No | No | No | Yes | No | [No*](#vst3-is-work-in-progress) | Parameter outputs | | |||
| | Parameter triggers | Yes | No | No | Yes | [No*](#parameter-triggers) | [No*](#parameter-triggers) | Parameter triggers | | |||
| | Programs | [Yes*](#jack-parameters-and-programs) | [No*](#ladspa-programs) | [Yes*](#dssi-state) | Yes | [No*](#vst2-programs) | Yes | Programs | | |||
| | States | Yes | No | [Yes*](#dssi-state) | Yes | Yes | Yes | States | | |||
| | Full/internal state | Yes | No | No | Yes | Yes | Yes | Full/internal state | | |||
| | Time position | Yes | No | No | Yes | Yes | Yes | Time position | | |||
| | UI | [Yes*](#jack-custom-ui-only) | No | External only | Yes | Embed only | Embed only | UI | | |||
| | UI bg/fg colors | No | No | No | Yes | No | No? | UI bg/fg colors | | |||
| | UI direct access | Yes | No | No | Yes | Yes | Yes | UI direct access | | |||
| | UI host-filebrowser | No | No | No | Yes | [No*](#vst2-potential-support) | [No*](#vst3-is-work-in-progress) | UI host-filebrowser | | |||
| | UI host-resize | Yes | No | Yes | Yes | No | [No*](#vst3-is-work-in-progress) | UI host-resize | | |||
| | UI remote control | No | No | Yes | Yes | No | Yes | UI remote control | | |||
| | UI send midi note | Yes | No | Yes | Yes | Yes | Yes | UI send midi note | | |||
| | Feature | JACK/Standalone | LADSPA | DSSI | LV2 | VST2 | VST3 | CLAP | Feature | | |||
| |---------------------|---------------------------------------|--------------------|---------------------|-------------------------------|----------------------------|----------------------------|-------------------------------|---------------------| | |||
| | Audio port groups | [Yes*](#jack-audio-port-groups) | No | No | Yes | No | Yes | Yes | Audio port groups | | |||
| | Audio port as CV | Yes | No | No | Yes | No | [Yes*](#vst3-cv) | [No*](#work-in-progress) | Audio port as CV | | |||
| | Audio sidechan | Yes | No | No | Yes | [No*](#vst2-deprecated) | Yes | Yes | Audio sidechan | | |||
| | Bypass control | No | No | No | Yes | [No*](#vst2-deprecated) | Yes | Yes | Bypass control | | |||
| | MIDI input | Yes | No | Yes | Yes | Yes | Yes | Yes | MIDI input | | |||
| | MIDI output | Yes | No | No | Yes | Yes | Yes | Yes | MIDI output | | |||
| | Parameter changes | Yes | No | No | [No*](#lv2-parameter-changes) | Yes | Yes | Yes | Parameter changes | | |||
| | Parameter groups | No | No | No | Yes | Yes | [No*](#work-in-progress) | Yes | Parameter groups | | |||
| | Parameter outputs | No | No | No | Yes | No | Yes | Yes | Parameter outputs | | |||
| | Parameter triggers | Yes | No | No | Yes | [No*](#parameter-triggers) | [No*](#parameter-triggers) | [No*](#parameter-triggers) | Parameter triggers | | |||
| | Programs | [Yes*](#jack-parameters-and-programs) | [No*](#ladspa-rdf) | [Yes*](#dssi-state) | Yes | [No*](#vst2-programs) | Yes | No | Programs | | |||
| | States | Yes | No | [Yes*](#dssi-state) | Yes | Yes | Yes | Yes | States | | |||
| | Full/internal state | Yes | No | No | Yes | Yes | Yes | Yes | Full/internal state | | |||
| | Time position | Yes | No | No | Yes | Yes | Yes | Yes | Time position | | |||
| | UI | [Yes*](#jack-custom-ui-only) | No | External only | Yes | Embed only | Embed only | Yes | UI | | |||
| | UI bg/fg colors | No | No | No | Yes | No | No? | No | UI bg/fg colors | | |||
| | UI direct access | Yes | No | No | Yes | Yes | Yes | Yes | UI direct access | | |||
| | UI host-filebrowser | No | No | No | Yes | [No*](#vst2-deprecated) | [No*](#work-in-progress) | [No*](#work-in-progress) | UI host-filebrowser | | |||
| | UI host-resize | Yes | No | Yes | Yes | No | Yes | Yes | UI host-resize | | |||
| | UI remote control | No | No | Yes | Yes | No | Yes | No | UI remote control | | |||
| | UI send midi note | Yes | No | Yes | Yes | Yes | Yes | Yes | UI send midi note | | |||
| For things that could be unclear: | |||
| @@ -59,7 +59,7 @@ MIDI CCs are used for parameter changes (matching the `midiCC` value you set on | |||
| There is no generic plugin editor view. | |||
| If your plugin has no custom UI, the standalone executable will run but not show any window. | |||
| ## LADSPA programs | |||
| ## LADSPA RDF | |||
| Programs for LADSPA could be done via LRDF but this is not supported in DPF. | |||
| @@ -78,7 +78,7 @@ But if we involve programs, they would need to pass through the UI in order to w | |||
| Although this is already implemented in DPF (through a custom extension), this is not implemented on most hosts. | |||
| So for now you can pretty much treat it as if not supported. | |||
| ## VST2 potential support | |||
| ## VST2 deprecated | |||
| Not supported in DPF at the moment. | |||
| It could eventually be, but likely not due to VST2 being phased out by Steinberg. | |||
| @@ -88,6 +88,11 @@ Contact DPF authors if you require such a feature. | |||
| VST2 program support requires saving state of all programs in memory, which is very expensive and thus not done in DPF. | |||
| ## VST3 is work in progress | |||
| ## VST3 CV | |||
| Although VST3 officially supports CV (Control Voltage) tagged audio ports, | |||
| at the moment no host supports such feature and thus it is not possible to validate it. | |||
| ## Work in progress | |||
| Feature is possible, just not implemented yet in DPF. | |||
| @@ -3,21 +3,21 @@ | |||
| [](https://github.com/DISTRHO/DPF/actions/workflows/cmake.yml) | |||
| [](https://github.com/DISTRHO/DPF/actions/workflows/example-plugins.yml) | |||
| DPF is designed to make development of new plugins an easy and enjoyable task.<br/> | |||
| It allows developers to create plugins with custom UIs using a simple C++ API.<br/> | |||
| The framework facilitates exporting various different plugin formats from the same code-base.<br/> | |||
| DPF is designed to make development of new plugins an easy and enjoyable task. | |||
| It allows developers to create plugins with custom UIs using a simple C++ API. | |||
| The framework facilitates exporting various different plugin formats from the same code-base. | |||
| DPF can build for LADSPA, DSSI, LV2, VST2, VST3 and CLAP formats.<br/> | |||
| All current plugin format implementations are complete.<br/> | |||
| A JACK/Standalone mode is also available, allowing you to quickly test plugins.<br/> | |||
| DPF can build for LADSPA, DSSI, LV2, VST2, VST3 and CLAP formats. | |||
| A JACK/Standalone mode is also available, allowing you to quickly test plugins. | |||
| Plugin DSP and UI communication is done via key-value string pairs.<br/> | |||
| You send messages from the UI to the DSP side, which is automatically saved in the host when required.<br/> | |||
| (You can also store state internally if needed, but this breaks DSSI compatibility).<br/> | |||
| Plugin DSP and UI communication is done via key-value string pairs. | |||
| You send messages from the UI to the DSP side, which is automatically saved in the host when required. | |||
| (You can also store state internally if needed, but this breaks DSSI compatibility). | |||
| Getting time information from the host is possible.<br/> | |||
| It uses the same format as the JACK Transport API, making porting some code easier.<br/> | |||
| Getting time information from the host is possible. | |||
| It uses the same format as the JACK Transport API, making porting some code easier. | |||
| Provided features and implementation status for specific plugin formats can be seen in [FEATURES.md](FEATURES.md). | |||
| ## Licensing | |||
| @@ -31,43 +31,11 @@ Bug reports happen on the [DPF github project](https://github.com/DISTRHO/DPF/is | |||
| Online documentation is available at [https://distrho.github.io/DPF/](https://distrho.github.io/DPF/). | |||
| Online help and discussion about DPF happens in the [kx.studio chat, DPF room](https://chat.kx.studio/). | |||
| Online help and discussion about DPF happens in the [kx.studio chat, DPF room](https://chat.kx.studio/channel/dpf). | |||
| ## List of plugins made with DPF: | |||
| - [DISTRHO glBars](https://github.com/DISTRHO/glBars) | |||
| - [DISTRHO Kars](https://github.com/DISTRHO/Kars) | |||
| - [DISTRHO Mini-Series](https://github.com/DISTRHO/Mini-Series) | |||
| - [DISTRHO MVerb](https://github.com/DISTRHO/MVerb) | |||
| - [DISTRHO ndc Plugs](https://github.com/DISTRHO/ndc-Plugs) | |||
| - [DISTRHO Nekobi](https://github.com/DISTRHO/Nekobi) | |||
| - [DISTRHO ProM](https://github.com/DISTRHO/ProM) | |||
| - [Dragonfly Reverb](https://michaelwillis.github.io/dragonfly-reverb) | |||
| - [Fogpad-port](https://github.com/linuxmao-org/fogpad-port) | |||
| - [master_me](https://github.com/trummerschlunk/master_me) | |||
| - [Ninjas2](https://github.com/rghvdberg/ninjas2) | |||
| - [osamc-lv2-workshop](https://github.com/osamc-lv2-workshop/lv2-workshop) (simple plugins code examples) | |||
| - [QuadraFuzz](https://github.com/jpcima/quadrafuzz) | |||
| - [Regrader-Port](https://github.com/linuxmao-org/regrader-port) | |||
| - [Rezonateur](https://github.com/jpcima/rezonateur) | |||
| - [Spectacle-analyzer](https://github.com/jpcima/spectacle/) | |||
| - [Stone Phaser](https://github.com/jpcima/stone-phaser) | |||
| - [String-machine](https://github.com/jpcima/string-machine) | |||
| - [Uhhyou Plugins](https://github.com/ryukau/LV2Plugins) | |||
| - [VL1-emulator](https://github.com/linuxmao-org/VL1-emulator) | |||
| - [Wolf Shaper](https://github.com/pdesaulniers/wolf-shaper) | |||
| - [Wolf Spectrum](https://github.com/pdesaulniers/wolf-spectrum) | |||
| - [YK Chorus](https://github.com/SpotlightKid/ykchorus) | |||
| - [ZamAudio Suite](https://github.com/zamaudio/zam-plugins) | |||
| ## Work in progress | |||
| - [CV-LFO-blender-LV2](https://github.com/BramGiesen/cv-lfo-blender-lv2) | |||
| - [fverb](https://github.com/jpcima/fverb) | |||
| - [Juice Plugins](https://github.com/DISTRHO/JuicePlugins) | |||
| - [gunshot](https://github.com/soerenbnoergaard/gunshot) | |||
| - [midiomatic](https://github.com/SpotlightKid/midiomatic) | |||
| - [Shiro Plugins](https://github.com/ninodewit/SHIRO-Plugins/) | |||
| - [Shiru Plugins](https://github.com/linuxmao-org/shiru-plugins) | |||
| Checking the [github "DPF" tag](https://github.com/topics/dpf) can potentially bring up other DPF-made plugins. | |||
| Plugin examples are available in the `example/` folder inside this repo. | |||
| See [this wiki page](https://github.com/DISTRHO/DPF/wiki/Plugins-made-with-DPF) for a list of plugins made with DPF. | |||
| Plugin examples are also available in the `example/` folder inside this repo. | |||
| @@ -28,6 +28,17 @@ TopLevelWidget::PrivateData::PrivateData(TopLevelWidget* const s, Window& w) | |||
| selfw(s), | |||
| window(w) | |||
| { | |||
| /* if window already has a top-level-widget, make the new one match the first one in size | |||
| * this is needed because window creation and resize is a synchronous operation in some systems. | |||
| * as such, there's a chance the non-1st top-level-widgets would never get a valid size. | |||
| */ | |||
| if (!window.pData->topLevelWidgets.empty()) | |||
| { | |||
| TopLevelWidget* const first = window.pData->topLevelWidgets.front(); | |||
| selfw->pData->size = first->getSize(); | |||
| } | |||
| window.pData->topLevelWidgets.push_back(self); | |||
| } | |||
| @@ -35,6 +35,16 @@ | |||
| #define PUGL_LOCAL_CLIENT_MSG (WM_USER + 52) | |||
| #define PUGL_USER_TIMER_MIN 9470 | |||
| #ifdef __cplusplus | |||
| # define PUGL_INIT_STRUCT \ | |||
| {} | |||
| #else | |||
| # define PUGL_INIT_STRUCT \ | |||
| { \ | |||
| 0 \ | |||
| } | |||
| #endif | |||
| typedef BOOL(WINAPI* PFN_SetProcessDPIAware)(void); | |||
| typedef HRESULT(WINAPI* PFN_GetProcessDpiAwareness)(HANDLE, DWORD*); | |||
| typedef HRESULT(WINAPI* PFN_GetScaleFactorForMonitor)(HMONITOR, DWORD*); | |||
| @@ -80,7 +90,7 @@ puglRegisterWindowClass(const char* name) | |||
| module = GetModuleHandle(NULL); | |||
| } | |||
| WNDCLASSEX wc = {0}; | |||
| WNDCLASSEX wc = PUGL_INIT_STRUCT; | |||
| if (GetClassInfoEx(module, name, &wc)) { | |||
| return true; // Already registered | |||
| } | |||
| @@ -472,8 +482,8 @@ initKeyEvent(PuglKeyEvent* event, | |||
| } | |||
| } else if (!dead) { | |||
| // Translate unshifted key | |||
| BYTE keyboardState[256] = {0}; | |||
| wchar_t buf[5] = {0}; | |||
| BYTE keyboardState[256] = PUGL_INIT_STRUCT; | |||
| wchar_t buf[5] = PUGL_INIT_STRUCT; | |||
| event->key = puglDecodeUTF16( | |||
| buf, ToUnicode(vkey, vcode, keyboardState, buf, 4, 1 << 2)); | |||
| @@ -689,7 +699,7 @@ handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam) | |||
| pt.y = GET_Y_LPARAM(lParam); | |||
| if (!view->impl->mouseTracked) { | |||
| TRACKMOUSEEVENT tme = {0}; | |||
| TRACKMOUSEEVENT tme = PUGL_INIT_STRUCT; | |||
| tme.cbSize = sizeof(tme); | |||
| tme.dwFlags = TME_LEAVE; | |||
| @@ -72,6 +72,12 @@ static const uint32_t kCVPortHasPositiveUnipolarRange = 0x40; | |||
| */ | |||
| static const uint32_t kCVPortHasScaledRange = 0x80; | |||
| /** | |||
| CV port is optional, allowing hosts that do no CV ports to load the plugin. | |||
| When loaded in hosts that don't support CV, the float* buffer for this port will be null. | |||
| */ | |||
| static const uint32_t kCVPortIsOptional = 0x100; | |||
| /** @} */ | |||
| /* ------------------------------------------------------------------------------------------------------------ | |||
| @@ -14,6 +14,14 @@ | |||
| * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||
| */ | |||
| /* TODO items: | |||
| * CV: write a specification | |||
| * INFO: define url, manual url, support url and string version | |||
| * PARAMETERS: test parameter triggers | |||
| * States: skip DSP/UI only states as appropriate | |||
| * UI: expose external-only UIs | |||
| */ | |||
| #include "DistrhoPluginInternal.hpp" | |||
| #include "extra/ScopedPointer.hpp" | |||
| @@ -1070,8 +1078,7 @@ public: | |||
| fPlugin.run(audioInputs, audioOutputs, frames); | |||
| #endif | |||
| // TODO set last frame | |||
| flushParameters(nullptr, process->out_events); | |||
| flushParameters(nullptr, process->out_events, frames - 1); | |||
| fOutputEvents = nullptr; | |||
| } | |||
| @@ -1210,7 +1217,9 @@ public: | |||
| return true; | |||
| } | |||
| void flushParameters(const clap_input_events_t* const in, const clap_output_events_t* const out) | |||
| void flushParameters(const clap_input_events_t* const in, | |||
| const clap_output_events_t* const out, | |||
| const uint32_t frameOffset) | |||
| { | |||
| if (const uint32_t len = in != nullptr ? in->size(in) : 0) | |||
| { | |||
| @@ -1231,7 +1240,7 @@ public: | |||
| if (out != nullptr) | |||
| { | |||
| clap_event_param_value_t clapEvent = { | |||
| { sizeof(clap_event_param_value_t), 0, 0, CLAP_EVENT_PARAM_VALUE, CLAP_EVENT_IS_LIVE }, | |||
| { sizeof(clap_event_param_value_t), frameOffset, 0, CLAP_EVENT_PARAM_VALUE, CLAP_EVENT_IS_LIVE }, | |||
| 0, nullptr, 0, 0, 0, 0, 0.0 | |||
| }; | |||
| @@ -2336,7 +2345,7 @@ static CLAP_ABI bool clap_plugin_params_text_to_value(const clap_plugin_t* plugi | |||
| static CLAP_ABI void clap_plugin_params_flush(const clap_plugin_t* plugin, const clap_input_events_t* in, const clap_output_events_t* out) | |||
| { | |||
| PluginCLAP* const instance = static_cast<PluginCLAP*>(plugin->plugin_data); | |||
| return instance->flushParameters(in, out); | |||
| return instance->flushParameters(in, out, 0); | |||
| } | |||
| static const clap_plugin_params_t clap_plugin_params = { | |||
| @@ -532,6 +532,9 @@ void lv2_generate_ttl(const char* const basename) | |||
| } | |||
| } | |||
| if ((port.hints & (kAudioPortIsCV|kCVPortIsOptional)) == (kAudioPortIsCV|kCVPortIsOptional)) | |||
| pluginString += " lv2:portProperty lv2:connectionOptional;\n"; | |||
| if (i+1 == DISTRHO_PLUGIN_NUM_INPUTS) | |||
| pluginString += " ] ;\n"; | |||
| else | |||
| @@ -817,11 +820,10 @@ void lv2_generate_ttl(const char* const basename) | |||
| // MIDI CC binding | |||
| if (const uint8_t midiCC = plugin.getParameterMidiCC(i)) | |||
| { | |||
| char midiCCBuf[7]; | |||
| snprintf(midiCCBuf, sizeof(midiCCBuf), "B0%02x00", midiCC); | |||
| pluginString += " midi:binding \""; | |||
| pluginString += midiCCBuf; | |||
| pluginString += "\"^^midi:MidiEvent ;\n"; | |||
| pluginString += " midi:binding [\n"; | |||
| pluginString += " a midi:Controller ;\n"; | |||
| pluginString += " midi:controllerNumber " + String(midiCC) + " ;\n"; | |||
| pluginString += " ] ;\n"; | |||
| } | |||
| // unit | |||
| @@ -14,28 +14,6 @@ | |||
| * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||
| */ | |||
| #include "DistrhoPluginInternal.hpp" | |||
| #include "../DistrhoPluginUtils.hpp" | |||
| #include "../extra/ScopedPointer.hpp" | |||
| #define DPF_VST3_MAX_BUFFER_SIZE 32768 | |||
| #define DPF_VST3_MAX_SAMPLE_RATE 384000 | |||
| #define DPF_VST3_MAX_LATENCY DPF_VST3_MAX_SAMPLE_RATE * 10 | |||
| #if DISTRHO_PLUGIN_HAS_UI | |||
| # include "../extra/RingBuffer.hpp" | |||
| #endif | |||
| #include "travesty/audio_processor.h" | |||
| #include "travesty/component.h" | |||
| #include "travesty/edit_controller.h" | |||
| #include "travesty/factory.h" | |||
| #include "travesty/host.h" | |||
| #include <map> | |||
| #include <string> | |||
| #include <vector> | |||
| /* TODO items: | |||
| * == parameters | |||
| * - test parameter triggers | |||
| @@ -43,7 +21,6 @@ | |||
| * - parameter groups via unit ids | |||
| * - test parameter changes from DSP (aka requestParameterValueChange) | |||
| * - implement getParameterNormalized/setParameterNormalized for MIDI CC params ? | |||
| * - fully implemented parameter stuff and verify | |||
| * - float to int safe casting | |||
| * - verify that latency changes works (with and without DPF_VST3_USES_SEPARATE_CONTROLLER) | |||
| * == MIDI | |||
| @@ -60,6 +37,28 @@ | |||
| * - do something with set_io_mode? | |||
| */ | |||
| #include "DistrhoPluginInternal.hpp" | |||
| #include "../DistrhoPluginUtils.hpp" | |||
| #include "../extra/ScopedPointer.hpp" | |||
| #define DPF_VST3_MAX_BUFFER_SIZE 32768 | |||
| #define DPF_VST3_MAX_SAMPLE_RATE 384000 | |||
| #define DPF_VST3_MAX_LATENCY DPF_VST3_MAX_SAMPLE_RATE * 10 | |||
| #if DISTRHO_PLUGIN_HAS_UI | |||
| # include "../extra/RingBuffer.hpp" | |||
| #endif | |||
| #include "travesty/audio_processor.h" | |||
| #include "travesty/component.h" | |||
| #include "travesty/edit_controller.h" | |||
| #include "travesty/factory.h" | |||
| #include "travesty/host.h" | |||
| #include <map> | |||
| #include <string> | |||
| #include <vector> | |||
| START_NAMESPACE_DISTRHO | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| @@ -2733,7 +2732,7 @@ private: | |||
| } | |||
| if (busId < busInfo.groups) | |||
| return portCountToSpeaker(fPlugin.getAudioPortCountWithGroupId(isInput, busId)); | |||
| return portCountToSpeaker(fPlugin.getAudioPortCountWithGroupId(isInput, portGroupId)); | |||
| if (busInfo.audio != 0 && busId == busInfo.groups) | |||
| return portCountToSpeaker(busInfo.audioPorts); | |||
| @@ -27,7 +27,7 @@ | |||
| START_NAMESPACE_DISTRHO | |||
| #if ! DISTRHO_PLUGIN_WANT_MIDI_INPUT | |||
| static const sendNoteFunc sendNoteCallback = nullptr; | |||
| static constexpr const sendNoteFunc sendNoteCallback = nullptr; | |||
| #endif | |||
| // ----------------------------------------------------------------------- | |||
| @@ -373,13 +373,12 @@ void DistrhoPluginNekobi::run(const float**, float** outputs, uint32_t frames, c | |||
| fSynth.nugget_remains = XSYNTH_NUGGET_SIZE; | |||
| /* process any ready events */ | |||
| while (curEventIndex < midiEventCount && framesDone == midiEvents[curEventIndex].frame) | |||
| for (; curEventIndex < midiEventCount && framesDone == midiEvents[curEventIndex].frame; ++curEventIndex) | |||
| { | |||
| if (midiEvents[curEventIndex].size > MidiEvent::kDataSize) | |||
| continue; | |||
| nekobee_handle_raw_event(&fSynth, midiEvents[curEventIndex].size, midiEvents[curEventIndex].data); | |||
| curEventIndex++; | |||
| } | |||
| /* calculate the sample count (burstSize) for the next nekobee_voice_render() call to be the smallest of: | |||
| @@ -376,7 +376,7 @@ nekobee_voice_render(nekobee_synth_t *synth, nekobee_voice_t *voice, | |||
| osc_index += sample_count; | |||
| if (do_control_update) { | |||
| if (do_control_update || osc_index > MINBLEP_BUFFER_LENGTH - (XSYNTH_NUGGET_SIZE + LONGEST_DD_PULSE_LENGTH)) { | |||
| /* do those things should be done only once per control-calculation | |||
| * interval ("nugget"), such as voice check-for-dead, pitch envelope | |||
| * calculations, volume envelope phase transition checks, etc. */ | |||
| @@ -25,16 +25,6 @@ START_NAMESPACE_DGL | |||
| class ResizeHandle : public TopLevelWidget | |||
| { | |||
| public: | |||
| /** Constructor for placing this handle on top of a window. */ | |||
| explicit ResizeHandle(Window& window) | |||
| : TopLevelWidget(window), | |||
| handleSize(16), | |||
| hasCursor(false), | |||
| isResizing(false) | |||
| { | |||
| resetArea(); | |||
| } | |||
| /** Overloaded constructor, will fetch the window from an existing top-level widget. */ | |||
| explicit ResizeHandle(TopLevelWidget* const tlw) | |||
| : TopLevelWidget(tlw->getWindow()), | |||
| @@ -56,31 +46,27 @@ public: | |||
| protected: | |||
| void onDisplay() override | |||
| { | |||
| // TODO implement gl3 stuff in DPF | |||
| #ifndef DGL_USE_OPENGL3 | |||
| const GraphicsContext& context(getGraphicsContext()); | |||
| const double lineWidth = 1.0 * getScaleFactor(); | |||
| #if defined(DGL_OPENGL) && !defined(DGL_USE_OPENGL3) | |||
| glMatrixMode(GL_MODELVIEW); | |||
| #endif | |||
| glLineWidth(lineWidth); | |||
| // draw white lines, 1px wide | |||
| Color(1.0f, 1.0f, 1.0f).setFor(context); | |||
| l1.draw(context, lineWidth); | |||
| l2.draw(context, lineWidth); | |||
| l3.draw(context, lineWidth); | |||
| glColor3f(1.0f, 1.0f, 1.0f); | |||
| drawLine(l1); | |||
| drawLine(l2); | |||
| drawLine(l3); | |||
| // draw black lines, offset by 1px and 1px wide | |||
| Color(0.0f, 0.0f, 0.0f).setFor(context); | |||
| glColor3f(0.0f, 0.0f, 0.0f); | |||
| Line<double> l1b(l1), l2b(l2), l3b(l3); | |||
| l1b.moveBy(lineWidth, lineWidth); | |||
| l2b.moveBy(lineWidth, lineWidth); | |||
| l3b.moveBy(lineWidth, lineWidth); | |||
| l1b.draw(context, lineWidth); | |||
| l2b.draw(context, lineWidth); | |||
| l3b.draw(context, lineWidth); | |||
| #endif | |||
| drawLine(l1b); | |||
| drawLine(l2b); | |||
| drawLine(l3b); | |||
| } | |||
| bool onMouse(const MouseEvent& ev) override | |||
| @@ -201,6 +187,25 @@ private: | |||
| l3.setEndPos(x + offset, y + linesize + offset); | |||
| } | |||
| void drawLine(const Line<double>& line) | |||
| { | |||
| drawLine(line.getStartPos(), line.getEndPos()); | |||
| } | |||
| void drawLine(const Point<double>& posStart, const Point<double>& posEnd) | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(posStart != posEnd,); | |||
| glBegin(GL_LINES); | |||
| { | |||
| glVertex2d(posStart.getX(), posStart.getY()); | |||
| glVertex2d(posEnd.getX(), posEnd.getY()); | |||
| } | |||
| glEnd(); | |||
| } | |||
| DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ResizeHandle) | |||
| }; | |||