diff --git a/source/backend/carla_native.hpp b/source/backend/carla_native.hpp new file mode 100644 index 000000000..65c622289 --- /dev/null +++ b/source/backend/carla_native.hpp @@ -0,0 +1,408 @@ +/* + * Carla Native Plugin API + * Copyright (C) 2012-2013 Filipe Coelho + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * For a full copy of the GNU General Public License see the COPYING file + */ + +#ifndef __CARLA_NATIVE_HPP__ +#define __CARLA_NATIVE_HPP__ + +#include "carla_native.h" +#include "carla_utils.hpp" + +/*! + * @defgroup CarlaNativeAPI Carla Native API + * @{ + */ + +class PluginDescriptorClass +{ +public: + PluginDescriptorClass(const HostDescriptor* const host) + : m_host(host) + { + } + + virtual ~PluginDescriptorClass() + { + } + + // ------------------------------------------------------------------- + // Host calls + + const HostDescriptor* getHostHandle() const + { + return m_host; + } + + uint32_t getBufferSize() const + { + CARLA_ASSERT(m_host); + + if (m_host) + return m_host->get_buffer_size(m_host->handle); + + return 0; + } + + double getSampleRate() const + { + CARLA_ASSERT(m_host); + + if (m_host) + return m_host->get_sample_rate(m_host->handle); + + return 0.0; + } + + const TimeInfo* getTimeInfo() const + { + CARLA_ASSERT(m_host); + + if (m_host) + return m_host->get_time_info(m_host->handle); + + return nullptr; + } + + void writeMidiEvent(const MidiEvent* const event) + { + CARLA_ASSERT(m_host); + + if (m_host) + m_host->write_midi_event(m_host->handle, event); + } + + void uiParameterChanged(const uint32_t index, const float value) + { + CARLA_ASSERT(m_host); + + if (m_host) + m_host->ui_parameter_changed(m_host->handle, index, value); + } + + void uiMidiProgramChanged(const uint32_t bank, const uint32_t program) + { + CARLA_ASSERT(m_host); + + if (m_host) + m_host->ui_midi_program_changed(m_host->handle, bank, program); + } + + void uiCustomDataChanged(const char* const key, const char* const value) + { + CARLA_ASSERT(m_host); + + if (m_host) + m_host->ui_custom_data_changed(m_host->handle, key, value); + } + + void uiClosed() + { + CARLA_ASSERT(m_host); + + if (m_host) + m_host->ui_closed(m_host->handle); + } + +protected: + // ------------------------------------------------------------------- + // Plugin parameter calls + + virtual uint32_t getParameterCount() + { + return 0; + } + + virtual const Parameter* getParameterInfo(const uint32_t index) + { + CARLA_ASSERT(index < getParameterCount()); + + return nullptr; + + // unused + Q_UNUSED(index); + } + + virtual float getParameterValue(const uint32_t index) + { + CARLA_ASSERT(index < getParameterCount()); + + return 0.0f; + + // unused + Q_UNUSED(index); + } + + virtual const char* getParameterText(const uint32_t index) + { + CARLA_ASSERT(index < getParameterCount()); + + return nullptr; + + // unused + Q_UNUSED(index); + } + + // ------------------------------------------------------------------- + // Plugin midi-program calls + + virtual uint32_t getMidiProgramCount() + { + return 0; + } + + virtual const MidiProgram* getMidiProgramInfo(const uint32_t index) + { + CARLA_ASSERT(index < getMidiProgramCount()); + + return nullptr; + + // unused + Q_UNUSED(index); + } + + // ------------------------------------------------------------------- + // Plugin state calls + + virtual void setParameterValue(const uint32_t index, const float value) + { + CARLA_ASSERT(index < getParameterCount()); + + return; + + // unused + Q_UNUSED(index); + Q_UNUSED(value); + } + + virtual void setMidiProgram(const uint32_t bank, const uint32_t program) + { + return; + + // unused + Q_UNUSED(bank); + Q_UNUSED(program); + } + + virtual void setCustomData(const char* const key, const char* const value) + { + CARLA_ASSERT(key); + CARLA_ASSERT(value); + + return; + + // unused + CARLA_ASSERT(key); + CARLA_ASSERT(value); + } + + // ------------------------------------------------------------------- + // Plugin process calls + + virtual void activate() + { + } + + virtual void deactivate() + { + } + + virtual void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t midiEventCount, const MidiEvent* const midiEvents) = 0; + + // ------------------------------------------------------------------- + // Plugin UI calls + + virtual void uiShow(const bool show) + { + return; + + // unused + Q_UNUSED(show); + } + + virtual void uiIdle() + { + } + + virtual void uiSetParameterValue(const uint32_t index, const float value) + { + CARLA_ASSERT(index < getParameterCount()); + + return; + + // unused + Q_UNUSED(value); + } + + virtual void uiSetMidiProgram(const uint32_t bank, const uint32_t program) + { + return; + + // unused + Q_UNUSED(bank); + Q_UNUSED(program); + } + + virtual void uiSetCustomData(const char* const key, const char* const value) + { + CARLA_ASSERT(key); + CARLA_ASSERT(value); + + return; + + // unused + Q_UNUSED(key); + Q_UNUSED(value); + } + + // ------------------------------------------------------------------- + +private: + const HostDescriptor* const m_host; + + // ------------------------------------------------------------------- + +#ifndef DOXYGEN +public: + #define handlePtr ((PluginDescriptorClass*)handle) + + static uint32_t _get_parameter_count(PluginHandle handle) + { + return handlePtr->getParameterCount(); + } + + static const Parameter* _get_parameter_info(PluginHandle handle, uint32_t index) + { + return handlePtr->getParameterInfo(index); + } + + static float _get_parameter_value(PluginHandle handle, uint32_t index) + { + return handlePtr->getParameterValue(index); + } + + static const char* _get_parameter_text(PluginHandle handle, uint32_t index) + { + return handlePtr->getParameterText(index); + } + + static uint32_t _get_midi_program_count(PluginHandle handle) + { + return handlePtr->getMidiProgramCount(); + } + + static const MidiProgram* _get_midi_program_info(PluginHandle handle, uint32_t index) + { + return handlePtr->getMidiProgramInfo(index); + } + + static void _set_parameter_value(PluginHandle handle, uint32_t index, float value) + { + return handlePtr->setParameterValue(index, value); + } + + static void _set_midi_program(PluginHandle handle, uint32_t bank, uint32_t program) + { + return handlePtr->setMidiProgram(bank, program); + } + + static void _set_custom_data(PluginHandle handle, const char* key, const char* value) + { + return handlePtr->setCustomData(key, value); + } + + static void _ui_show(PluginHandle handle, bool show) + { + return handlePtr->uiShow(show); + } + + static void _ui_idle(PluginHandle handle) + { + return handlePtr->uiIdle(); + } + + static void _ui_set_parameter_value(PluginHandle handle, uint32_t index, float value) + { + return handlePtr->uiSetParameterValue(index, value); + } + + static void _ui_set_midi_program(PluginHandle handle, uint32_t bank, uint32_t program) + { + return handlePtr->uiSetMidiProgram(bank, program); + } + + static void _ui_set_custom_data(PluginHandle handle, const char* key, const char* value) + { + return handlePtr->uiSetCustomData(key, value); + } + + static void _activate(PluginHandle handle) + { + handlePtr->activate(); + } + + static void _deactivate(PluginHandle handle) + { + handlePtr->deactivate(); + } + + static void _process(PluginHandle handle, float** inBuffer, float** outBuffer, const uint32_t frames, uint32_t midiEventCount, const MidiEvent* midiEvents) + { + return handlePtr->process(inBuffer, outBuffer, frames, midiEventCount, midiEvents); + } + + #undef handlePtr + + CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginDescriptorClass) +#endif +}; + +/**@}*/ + +// ----------------------------------------------------------------------- + +#define PluginDescriptorClassEND(className) \ +public: \ + static PluginHandle _instantiate(const PluginDescriptor*, HostDescriptor* host) \ + { \ + return new className(host); \ + } \ + static void _cleanup(PluginHandle handle) \ + { \ + delete (className*)handle; \ + } + +#define PluginDescriptorFILL(className) \ + className::_instantiate, \ + className::_cleanup, \ + className::_get_parameter_count, \ + className::_get_parameter_info, \ + className::_get_parameter_value, \ + className::_get_parameter_text, \ + className::_get_midi_program_count, \ + className::_get_midi_program_info, \ + className::_set_parameter_value, \ + className::_set_midi_program, \ + className::_set_custom_data, \ + className::_ui_show, \ + className::_ui_idle, \ + className::_ui_set_parameter_value, \ + className::_ui_set_midi_program, \ + className::_ui_set_custom_data, \ + className::_activate, \ + className::_deactivate, \ + className::_process + +#endif // __CARLA_NATIVE_HPP__ diff --git a/source/backend/native/3bandeq/DistrhoPlugin3BandEQ.cpp b/source/backend/native/3bandeq/DistrhoPlugin3BandEQ.cpp index e85ac5784..1afb599ae 100644 --- a/source/backend/native/3bandeq/DistrhoPlugin3BandEQ.cpp +++ b/source/backend/native/3bandeq/DistrhoPlugin3BandEQ.cpp @@ -1,7 +1,7 @@ /* * DISTRHO 3BandEQ Plugin, based on 3BandEQ by Michael Gruhn * Copyright (C) 2007 Michael Gruhn - * Copyright (C) 2012 Filipe Coelho + * Copyright (C) 2012-2013 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -9,7 +9,7 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * For a full copy of the license see the LGPL.txt file diff --git a/source/backend/native/3bandeq/DistrhoPlugin3BandEQ.hpp b/source/backend/native/3bandeq/DistrhoPlugin3BandEQ.hpp index 19b8af08b..70fa419a7 100644 --- a/source/backend/native/3bandeq/DistrhoPlugin3BandEQ.hpp +++ b/source/backend/native/3bandeq/DistrhoPlugin3BandEQ.hpp @@ -1,7 +1,7 @@ /* * DISTRHO 3BandEQ Plugin, based on 3BandEQ by Michael Gruhn * Copyright (C) 2007 Michael Gruhn - * Copyright (C) 2012 Filipe Coelho + * Copyright (C) 2012-2013 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -9,7 +9,7 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * For a full copy of the license see the LGPL.txt file diff --git a/source/backend/native/3bandeq/DistrhoUI3BandEQ.cpp b/source/backend/native/3bandeq/DistrhoUI3BandEQ.cpp index 79d554ead..ba6039caa 100644 --- a/source/backend/native/3bandeq/DistrhoUI3BandEQ.cpp +++ b/source/backend/native/3bandeq/DistrhoUI3BandEQ.cpp @@ -1,6 +1,6 @@ /* * DISTRHO 3BandEQ Plugin, based on 3BandEQ by Michael Gruhn - * Copyright (C) 2012 Filipe Coelho + * Copyright (C) 2012-2013 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -8,7 +8,7 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * For a full copy of the license see the LGPL.txt file diff --git a/source/backend/native/3bandeq/DistrhoUI3BandEQ.hpp b/source/backend/native/3bandeq/DistrhoUI3BandEQ.hpp index 6082a445c..a3d05dcc0 100644 --- a/source/backend/native/3bandeq/DistrhoUI3BandEQ.hpp +++ b/source/backend/native/3bandeq/DistrhoUI3BandEQ.hpp @@ -1,6 +1,6 @@ /* * DISTRHO 3BandEQ Plugin, based on 3BandEQ by Michael Gruhn - * Copyright (C) 2012 Filipe Coelho + * Copyright (C) 2012-2013 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -8,7 +8,7 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * For a full copy of the license see the LGPL.txt file diff --git a/source/backend/native/3bandsplitter/DistrhoPlugin3BandSplitter.cpp b/source/backend/native/3bandsplitter/DistrhoPlugin3BandSplitter.cpp index ced55e10b..5aedc71d0 100644 --- a/source/backend/native/3bandsplitter/DistrhoPlugin3BandSplitter.cpp +++ b/source/backend/native/3bandsplitter/DistrhoPlugin3BandSplitter.cpp @@ -1,7 +1,7 @@ /* * DISTRHO 3BandSplitter Plugin, based on 3BandSplitter by Michael Gruhn * Copyright (C) 2007 Michael Gruhn - * Copyright (C) 2012 Filipe Coelho + * Copyright (C) 2012-2013 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/source/backend/native/3bandsplitter/DistrhoPlugin3BandSplitter.hpp b/source/backend/native/3bandsplitter/DistrhoPlugin3BandSplitter.hpp index fa3b75f20..7ce8117cd 100644 --- a/source/backend/native/3bandsplitter/DistrhoPlugin3BandSplitter.hpp +++ b/source/backend/native/3bandsplitter/DistrhoPlugin3BandSplitter.hpp @@ -1,7 +1,7 @@ /* * DISTRHO 3BandSplitter Plugin, based on 3BandSplitter by Michael Gruhn * Copyright (C) 2007 Michael Gruhn - * Copyright (C) 2012 Filipe Coelho + * Copyright (C) 2012-2013 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -9,7 +9,7 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * For a full copy of the license see the LGPL.txt file diff --git a/source/backend/native/3bandsplitter/DistrhoPluginInfo.h b/source/backend/native/3bandsplitter/DistrhoPluginInfo.h index 21b02cacd..41840f799 100644 --- a/source/backend/native/3bandsplitter/DistrhoPluginInfo.h +++ b/source/backend/native/3bandsplitter/DistrhoPluginInfo.h @@ -1,6 +1,6 @@ /* * DISTRHO 3BandSplitter Plugin, based on 3BandSplitter by Michael Gruhn - * Copyright (C) 2012 Filipe Coelho + * Copyright (C) 2012-2013 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -8,7 +8,7 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * For a full copy of the license see the LGPL.txt file diff --git a/source/backend/native/3bandsplitter/DistrhoUI3BandSplitter.cpp b/source/backend/native/3bandsplitter/DistrhoUI3BandSplitter.cpp index 6937d8f3d..b39135ae6 100644 --- a/source/backend/native/3bandsplitter/DistrhoUI3BandSplitter.cpp +++ b/source/backend/native/3bandsplitter/DistrhoUI3BandSplitter.cpp @@ -1,6 +1,6 @@ /* * DISTRHO 3BandSplitter Plugin, based on 3BandSplitter by Michael Gruhn - * Copyright (C) 2012 Filipe Coelho + * Copyright (C) 2012-2013 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -8,7 +8,7 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * For a full copy of the license see the LGPL.txt file diff --git a/source/backend/native/3bandsplitter/DistrhoUI3BandSplitter.hpp b/source/backend/native/3bandsplitter/DistrhoUI3BandSplitter.hpp index 2e7490e41..e85d1d593 100644 --- a/source/backend/native/3bandsplitter/DistrhoUI3BandSplitter.hpp +++ b/source/backend/native/3bandsplitter/DistrhoUI3BandSplitter.hpp @@ -1,6 +1,6 @@ /* * DISTRHO 3BandSplitter Plugin, based on 3BandSplitter by Michael Gruhn - * Copyright (C) 2012 Filipe Coelho + * Copyright (C) 2012-2013 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -8,7 +8,7 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * For a full copy of the license see the LGPL.txt file diff --git a/source/backend/native/Makefile b/source/backend/native/Makefile index 329823706..143637eff 100644 --- a/source/backend/native/Makefile +++ b/source/backend/native/Makefile @@ -18,7 +18,7 @@ LINK_FLAGS += $(shell pkg-config --libs QtCore QtGui) ifeq ($(HAVE_ZYN_DEPS),true) ZYN_CXX_FLAGS = $(BUILD_CXX_FLAGS) ZYN_CXX_FLAGS += $(shell pkg-config --cflags fftw3 mxml) -LINK_FLAGS += $(shell pkg-config --libs fftw3 mxml) +LINK_FLAGS += $(shell pkg-config --libs fftw3 mxml) -lpthread endif # -------------------------------------------------------------- @@ -73,9 +73,6 @@ distrho-3bandsplitter.cpp.o: distrho-3bandsplitter.cpp distrho-pingpongpan.cpp.o: distrho-pingpongpan.cpp $(CXX) $< $(BUILD_CXX_FLAGS) -Ipingpongpan -DDISTRHO_NAMESPACE=DISTRHO_PingPongPan -c -o $@ -# distrho-pugl.o: distrho-pugl.cpp -# $(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ - zynaddsubfx.cpp.o: zynaddsubfx.cpp $(CXX) $< $(ZYN_CXX_FLAGS) -c -o $@ diff --git a/source/backend/native/distrho/DistrhoPluginCarla.cpp b/source/backend/native/distrho/DistrhoPluginCarla.cpp index 43f9d1ef8..f44cc5afb 100644 --- a/source/backend/native/distrho/DistrhoPluginCarla.cpp +++ b/source/backend/native/distrho/DistrhoPluginCarla.cpp @@ -16,8 +16,9 @@ */ #include "carla_native.hpp" +#include "carla_utils.hpp" -#include +#include #include "DistrhoPluginMain.cpp" @@ -33,17 +34,20 @@ START_NAMESPACE_DISTRHO // ----------------------------------------------------------------------- // Carla UI -class UICarla : public QDialog +class UICarla : public QMainWindow { public: - UICarla(const HostDescriptor* const host, PluginInternal* const plugin) - : QDialog(nullptr), - m_host(host), - m_plugin(plugin), - ui(this, (intptr_t)winId(), setParameterCallback, setStateCallback, uiEditParameterCallback, uiSendNoteCallback, uiResizeCallback) - { + UICarla(const HostDescriptor* const host_, PluginInternal* const plugin_) + : QMainWindow(nullptr), + host(host_), + plugin(plugin_), + widget(this), + ui(this, (intptr_t)widget.winId(), setParameterCallback, setStateCallback, uiEditParameterCallback, uiSendNoteCallback, uiResizeCallback) + { + setCentralWidget(&widget); setFixedSize(ui.getWidth(), ui.getHeight()); setWindowTitle(DISTRHO_PLUGIN_NAME); + } ~UICarla() @@ -84,15 +88,15 @@ public: // --------------------------------------------- protected: - void setParameterValue(uint32_t index, float value) + void setParameterValue(uint32_t rindex, float value) { - m_host->ui_parameter_changed(m_host->handle, index, value); + host->ui_parameter_changed(host->handle, rindex, value); } # if DISTRHO_PLUGIN_WANT_STATE void setState(const char* key, const char* value) { - m_host->ui_custom_data_changed(m_host->handle, key, value); + host->ui_custom_data_changed(host->handle, key, value); } # endif @@ -115,14 +119,19 @@ protected: void closeEvent(QCloseEvent* event) { - m_host->ui_closed(m_host->handle); - QDialog::closeEvent(event); + host->ui_closed(host->handle); + + // FIXME - ignore event? + QMainWindow::closeEvent(event); } private: // Plugin stuff - const HostDescriptor* const m_host; - PluginInternal* const m_plugin; + const HostDescriptor* const host; + PluginInternal* const plugin; + + // Qt4 stuff + QWidget widget; // UI UIInternal ui; @@ -179,6 +188,8 @@ private: if (UICarla* _this_ = (UICarla*)ptr) _this_->uiResize(width, height); } + + CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(UICarla) }; #endif @@ -199,8 +210,7 @@ public: ~PluginCarla() { #if DISTRHO_PLUGIN_HAS_UI - if (uiPtr) - delete uiPtr; + uiPtr = nullptr; #endif } @@ -215,14 +225,18 @@ protected: const ::Parameter* getParameterInfo(const uint32_t index) { + CARLA_ASSERT(index < getParameterCount()); + static ::Parameter param; // reset param.hints = ::PARAMETER_IS_ENABLED; + param.scalePointCount = 0; + param.scalePoints = nullptr; { - const uint32_t paramHints = plugin.parameterHints(index); int nativeparamHints = 0; + const uint32_t paramHints = plugin.parameterHints(index); if (paramHints & PARAMETER_IS_AUTOMABLE) nativeparamHints |= ::PARAMETER_IS_AUTOMABLE; @@ -252,17 +266,18 @@ protected: param.ranges.stepLarge = ranges.stepLarge; } - param.scalePointCount = 0; - param.scalePoints = nullptr; - return ¶m; } float getParameterValue(const uint32_t index) { + CARLA_ASSERT(index < getParameterCount()); + return plugin.parameterValue(index); } + // getParameterText unused + // ------------------------------------------------------------------- // Plugin midi-program calls @@ -274,10 +289,17 @@ protected: virtual const ::MidiProgram* getMidiProgramInfo(const uint32_t index) { + CARLA_ASSERT(index < getMidiProgramCount()); + + if (index >= plugin.programCount()) + return nullptr; + static ::MidiProgram midiProgram; + midiProgram.bank = index / 128; midiProgram.program = index % 128; midiProgram.name = plugin.programName(index); + return &midiProgram; } #endif @@ -287,6 +309,8 @@ protected: void setParameterValue(const uint32_t index, const float value) { + CARLA_ASSERT(index < getParameterCount()); + plugin.setParameterValue(index, value); } @@ -305,10 +329,51 @@ protected: #if DISTRHO_PLUGIN_WANT_STATE void setCustomData(const char* const key, const char* const value) { + CARLA_ASSERT(key); + CARLA_ASSERT(value); + plugin.setState(key, value); } #endif + // ------------------------------------------------------------------- + // Plugin process calls + + void activate() + { + plugin.activate(); + } + + void deactivate() + { + plugin.deactivate(); + } + +#if DISTRHO_PLUGIN_IS_SYNTH + void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t midiEventCount, const ::MidiEvent* const midiEvents) + { + uint32_t i; + + for (i=0; i < midiEventCount && i < MAX_MIDI_EVENTS; i++) + { + const ::MidiEvent* const midiEvent = &midiEvents[i]; + MidiEvent* const realMidiEvent = &realMidiEvents[i]; + + realMidiEvent->buffer[0] = midiEvent->data[0]; + realMidiEvent->buffer[1] = midiEvent->data[1]; + realMidiEvent->buffer[2] = midiEvent->data[2]; + realMidiEvent->frame = midiEvent->time; + } + + plugin.run(inBuffer, outBuffer, frames, i, realMidiEvents); + } +#else + void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t, const ::MidiEvent* const) + { + plugin.run(inBuffer, outBuffer, frames, 0, nullptr); + } +#endif + // ------------------------------------------------------------------- // Plugin UI calls @@ -318,28 +383,38 @@ protected: if (show) createUiIfNeeded(); - if (uiPtr) + if (uiPtr != nullptr) uiPtr->carla_show(show); } void uiIdle() { - if (uiPtr) + CARLA_ASSERT(uiPtr); + + if (uiPtr != nullptr) uiPtr->carla_idle(); } void uiSetParameterValue(const uint32_t index, const float value) { - if (uiPtr) + CARLA_ASSERT(uiPtr); + CARLA_ASSERT(index < getParameterCount()); + + if (uiPtr != nullptr) uiPtr->carla_setParameterValue(index, value); } # if DISTRHO_PLUGIN_WANT_PROGRAMS void uiSetMidiProgram(const uint32_t bank, const uint32_t program) { + CARLA_ASSERT(uiPtr); + uint32_t realProgram = bank * 128 + program; - if (uiPtr) + if (realProgram >= plugin.programCount()) + return; + + if (uiPtr != nullptr) uiPtr->carla_setMidiProgram(realProgram); } # endif @@ -347,49 +422,17 @@ protected: # if DISTRHO_PLUGIN_WANT_STATE void uiSetCustomData(const char* const key, const char* const value) { - if (uiPtr) + CARLA_ASSERT(uiPtr); + CARLA_ASSERT(key); + CARLA_ASSERT(value); + + if (uiPtr != nullptr) uiPtr->carla_setCustomData(key, value); } # endif #endif // ------------------------------------------------------------------- - // Plugin process calls - - void activate() - { - plugin.activate(); - } - - void deactivate() - { - plugin.deactivate(); - } - -#if DISTRHO_PLUGIN_IS_SYNTH - void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t midiEventCount, const ::MidiEvent* const midiEvents) - { - for (uint32_t i=0; i < midiEventCount && i < MAX_MIDI_EVENTS; i++) - { - const ::MidiEvent* midiEvent = &midiEvents[i]; - MidiEvent* realEvent = &realMidiEvents[i]; - - realEvent->buffer[0] = midiEvent->data[0]; - realEvent->buffer[1] = midiEvent->data[1]; - realEvent->buffer[2] = midiEvent->data[2]; - realEvent->frame = midiEvent->time; - } - - plugin.run(inBuffer, outBuffer, frames, midiEventCount, realMidiEvents); - } -#else - void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t, const ::MidiEvent* const) - { - plugin.run(inBuffer, outBuffer, frames, 0, nullptr); - } -#endif - - // ------------------------------------------------------------------- private: PluginInternal plugin; @@ -400,11 +443,11 @@ private: #if DISTRHO_PLUGIN_HAS_UI // UI - UICarla* uiPtr; + ScopedPointer uiPtr; void createUiIfNeeded() { - if (! uiPtr) + if (uiPtr == nullptr) { d_lastUiSampleRate = getSampleRate(); uiPtr = new UICarla(getHostHandle(), &plugin); @@ -412,6 +455,8 @@ private: } #endif + CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginCarla) + // ------------------------------------------------------------------- public: diff --git a/source/backend/native/pingpongpan/DistrhoPluginPingPongPan.cpp b/source/backend/native/pingpongpan/DistrhoPluginPingPongPan.cpp index 08a785a40..dcba61488 100644 --- a/source/backend/native/pingpongpan/DistrhoPluginPingPongPan.cpp +++ b/source/backend/native/pingpongpan/DistrhoPluginPingPongPan.cpp @@ -1,7 +1,7 @@ /* * DISTRHO PingPongPan Plugin, based on PingPongPan by Michael Gruhn * Copyright (C) 2007 Michael Gruhn - * Copyright (C) 2012 Filipe Coelho + * Copyright (C) 2012-2013 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -9,7 +9,7 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * For a full copy of the license see the LGPL.txt file diff --git a/source/backend/native/pingpongpan/DistrhoPluginPingPongPan.hpp b/source/backend/native/pingpongpan/DistrhoPluginPingPongPan.hpp index 8d3cc12d6..9e674f795 100644 --- a/source/backend/native/pingpongpan/DistrhoPluginPingPongPan.hpp +++ b/source/backend/native/pingpongpan/DistrhoPluginPingPongPan.hpp @@ -1,7 +1,7 @@ /* * DISTRHO PingPongPan Plugin, based on PingPongPan by Michael Gruhn * Copyright (C) 2007 Michael Gruhn - * Copyright (C) 2012 Filipe Coelho + * Copyright (C) 2012-2013 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -9,7 +9,7 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * For a full copy of the license see the LGPL.txt file diff --git a/source/backend/native/pingpongpan/DistrhoUIPingPongPan.cpp b/source/backend/native/pingpongpan/DistrhoUIPingPongPan.cpp index f4faaccc9..bd6908dde 100644 --- a/source/backend/native/pingpongpan/DistrhoUIPingPongPan.cpp +++ b/source/backend/native/pingpongpan/DistrhoUIPingPongPan.cpp @@ -1,6 +1,6 @@ /* * DISTRHO PingPongPan Plugin, based on PingPongPan by Michael Gruhn - * Copyright (C) 2012 Filipe Coelho + * Copyright (C) 2012-2013 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -8,7 +8,7 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * For a full copy of the license see the LGPL.txt file diff --git a/source/backend/native/pingpongpan/DistrhoUIPingPongPan.hpp b/source/backend/native/pingpongpan/DistrhoUIPingPongPan.hpp index 2c5c2c332..fca10628f 100644 --- a/source/backend/native/pingpongpan/DistrhoUIPingPongPan.hpp +++ b/source/backend/native/pingpongpan/DistrhoUIPingPongPan.hpp @@ -1,6 +1,6 @@ /* * DISTRHO PingPongPan Plugin, based on PingPongPan by Michael Gruhn - * Copyright (C) 2012 Filipe Coelho + * Copyright (C) 2012-2013 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -8,7 +8,7 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * For a full copy of the license see the LGPL.txt file diff --git a/source/libs/distrho-plugin-toolkit/src/DistrhoPluginLADSPA+DSSI.cpp b/source/libs/distrho-plugin-toolkit/src/DistrhoPluginLADSPA+DSSI.cpp index b0f9f8af6..921aab52c 100644 --- a/source/libs/distrho-plugin-toolkit/src/DistrhoPluginLADSPA+DSSI.cpp +++ b/source/libs/distrho-plugin-toolkit/src/DistrhoPluginLADSPA+DSSI.cpp @@ -44,9 +44,8 @@ START_NAMESPACE_DISTRHO class PluginLadspaDssi { public: - PluginLadspaDssi() - : lastBufferSize(d_lastBufferSize), - lastSampleRate(d_lastSampleRate), + PluginLadspaDssi(const double sampleRate) + : lastSampleRate(sampleRate), portAudioIns{nullptr}, portAudioOuts{nullptr} { @@ -143,9 +142,11 @@ public: return nullptr; static DSSI_Program_Descriptor desc; + desc.Bank = index / 128; desc.Program = index % 128; desc.Name = plugin.programName(index); + return &desc; } @@ -292,9 +293,8 @@ private: PluginInternal plugin; // Temporary data - const unsigned long lastBufferSize; - const double lastSampleRate; - LADSPA_DataVector lastControlValues; + const double lastSampleRate; + LADSPA_DataVector lastControlValues; #if DISTRHO_PLUGIN_IS_SYNTH MidiEvent midiEvents[MAX_MIDI_EVENTS]; @@ -346,7 +346,7 @@ static LADSPA_Handle ladspa_instantiate(const LADSPA_Descriptor*, unsigned long d_lastBufferSize = 2048; d_lastSampleRate = sampleRate; - return new PluginLadspaDssi(); + return new PluginLadspaDssi(sampleRate); } static void ladspa_connect_port(LADSPA_Handle instance, unsigned long port, LADSPA_Data* dataLocation) diff --git a/source/libs/distrho-plugin-toolkit/src/DistrhoUIDSSI.cpp b/source/libs/distrho-plugin-toolkit/src/DistrhoUIDSSI.cpp index bfa6da036..fc9d57d21 100644 --- a/source/libs/distrho-plugin-toolkit/src/DistrhoUIDSSI.cpp +++ b/source/libs/distrho-plugin-toolkit/src/DistrhoUIDSSI.cpp @@ -86,51 +86,36 @@ void osc_send_exiting(const OscData* oscData) lo_send(oscData->addr, targetPath, ""); } -// stuff that we might receive while waiting for sample-rate -static bool globalShow = false; - class UIDssi : public QMainWindow { public: UIDssi(const OscData* oscData_, const char* title) : QMainWindow(nullptr), + oscData(oscData_), widget(this), - settings("DISTRHO", DISTRHO_PLUGIN_NAME), - ui(this, widget.winId(), setParameterCallback, setStateCallback, nullptr, uiSendNoteCallback, uiResizeCallback), - oscData(oscData_) + ui(this, (intptr_t)widget.winId(), setParameterCallback, setStateCallback, nullptr, uiSendNoteCallback, uiResizeCallback) { setCentralWidget(&widget); setFixedSize(ui.getWidth(), ui.getHeight()); setWindowTitle(title); + // idle timer uiTimer = startTimer(30); // load settings - restoreGeometry(settings.value("Global/Geometry", QByteArray()).toByteArray()); - -#if DISTRHO_PLUGIN_WANT_STATE - for (size_t i=0; i < globalConfigures.size(); i++) - dssiui_configure(globalConfigures.at(i).key, globalConfigures.at(i).value); -#endif - -#if DISTRHO_PLUGIN_WANT_PROGRAMS - if (globalProgram[0] >= 0 && globalProgram[1] >= 0) - dssiui_program(globalProgram[0], globalProgram[1]); -#endif + QSettings settings("DISTRHO", DISTRHO_PLUGIN_NAME); - for (size_t i=0; i < globalControls.size(); i++) - dssiui_control(i, globalControls.at(i)); - - if (globalShow) - show(); + restoreGeometry(settings.value("Global/Geometry", QByteArray()).toByteArray()); } ~UIDssi() { // save settings + QSettings settings("DISTRHO", DISTRHO_PLUGIN_NAME); + settings.setValue("Global/Geometry", saveGeometry()); - if (uiTimer) + if (uiTimer != 0) { killTimer(uiTimer); osc_send_exiting(oscData); @@ -154,8 +139,9 @@ public: #if DISTRHO_PLUGIN_WANT_PROGRAMS void dssiui_program(unsigned long bank, unsigned long program) { - unsigned long index = bank * 128 + program; - ui.programChanged(index); + unsigned long realProgram = bank * 128 + program; + + ui.programChanged(realProgram); } #endif @@ -183,13 +169,24 @@ public: } #endif + void dssiui_show() + { + show(); + } + + void dssiui_hide() + { + hide(); + } + void dssiui_quit() { - if (uiTimer) + if (uiTimer != 0) { killTimer(uiTimer); uiTimer = 0; } + close(); qApp->quit(); } @@ -238,35 +235,34 @@ protected: } private: + // OSC Stuff + const OscData* const oscData; + // Qt4 stuff int uiTimer; QWidget widget; - QSettings settings; // Plugin UI UIInternal ui; - const OscData* const oscData; - // --------------------------------------------- // Callbacks static void setParameterCallback(void* ptr, uint32_t rindex, float value) { - UIDssi* _this_ = (UIDssi*)ptr; - assert(_this_); - - _this_->setParameterValue(rindex, value); + if (UIDssi* _this_ = (UIDssi*)ptr) + _this_->setParameterValue(rindex, value); } static void setStateCallback(void* ptr, const char* key, const char* value) { #if DISTRHO_PLUGIN_WANT_STATE - UIDssi* _this_ = (UIDssi*)ptr; - assert(_this_); - - _this_->setState(key, value); + if (UIDssi* _this_ = (UIDssi*)ptr) + _this_->setState(key, value); #else + return; + + // unused Q_UNUSED(ptr); Q_UNUSED(key); Q_UNUSED(value); @@ -276,11 +272,12 @@ private: static void uiSendNoteCallback(void* ptr, bool onOff, uint8_t channel, uint8_t note, uint8_t velocity) { #if DISTRHO_PLUGIN_IS_SYNTH - UIDssi* _this_ = (UIDssi*)ptr; - assert(_this_); - - _this_->uiSendNote(onOff, channel, note, velocity); + if (UIDssi* _this_ = (UIDssi*)ptr) + _this_->uiSendNote(onOff, channel, note, velocity); #else + return; + + // unused Q_UNUSED(ptr); Q_UNUSED(onOff); Q_UNUSED(channel); @@ -291,10 +288,8 @@ private: static void uiResizeCallback(void* ptr, unsigned int width, unsigned int height) { - UIDssi* _this_ = (UIDssi*)ptr; - assert(_this_); - - _this_->uiResize(width, height); + if (UIDssi* _this_ = (UIDssi*)ptr) + _this_->uiResize(width, height); } }; diff --git a/source/libs/distrho-plugin-toolkit/src/DistrhoUIInternal.h b/source/libs/distrho-plugin-toolkit/src/DistrhoUIInternal.h index daf3f7b6a..e9c82d8f7 100644 --- a/source/libs/distrho-plugin-toolkit/src/DistrhoUIInternal.h +++ b/source/libs/distrho-plugin-toolkit/src/DistrhoUIInternal.h @@ -22,7 +22,9 @@ #ifdef DISTRHO_UI_OPENGL # include "DistrhoUIOpenGL.h" +START_NAMESPACE_DISTRHO # include "pugl/pugl.h" +END_NAMESPACE_DISTRHO #else # include "DistrhoUIQt4.h" # include @@ -82,6 +84,13 @@ struct UIPrivateData { // UI void* ptr; NativeWidget* widget; + /* ^this: + * Under Qt4 it points to the UI itself (in this case Qt4UI), + * It's set right on the Qt4UI constructor. + * + * Under OpenGL it starts NULL and its created in createWindow(). + * It points to a puglView. + */ // Callbacks setParamFunc setParamCallbackFunc; diff --git a/source/libs/distrho-plugin-toolkit/src/DistrhoUIOpenGL.cpp b/source/libs/distrho-plugin-toolkit/src/DistrhoUIOpenGL.cpp index 673f369f6..410912ef3 100644 --- a/source/libs/distrho-plugin-toolkit/src/DistrhoUIOpenGL.cpp +++ b/source/libs/distrho-plugin-toolkit/src/DistrhoUIOpenGL.cpp @@ -67,16 +67,18 @@ void OpenGLUI::d_uiIdle() // ------------------------------------------------- -END_NAMESPACE_DISTRHO - -#ifndef DISTRHO_NAMESPACE -# if DISTRHO_OS_WINDOWS -# include "pugl/pugl_win.cpp" -# elif DISTRHO_OS_MAC -# include "pugl/pugl_osx.m" -# else -# include "pugl/pugl_x11.c" -# endif +#if DISTRHO_OS_WINDOWS +# include "pugl/pugl_win.cpp" +#elif DISTRHO_OS_MAC +# include "pugl/pugl_osx.m" +#elif DISTRHO_OS_LINUX +# include "pugl/pugl_x11.c" +#else +# error Unsupported platform! #endif +// ------------------------------------------------- + +END_NAMESPACE_DISTRHO + #endif // DISTRHO_UI_OPENGL diff --git a/source/libs/distrho-plugin-toolkit/src/DistrhoUIOpenGLExt.cpp b/source/libs/distrho-plugin-toolkit/src/DistrhoUIOpenGLExt.cpp index 703f03c7d..7292d69f7 100644 --- a/source/libs/distrho-plugin-toolkit/src/DistrhoUIOpenGLExt.cpp +++ b/source/libs/distrho-plugin-toolkit/src/DistrhoUIOpenGLExt.cpp @@ -25,12 +25,12 @@ #include #include +START_NAMESPACE_DISTRHO + #if DISTRHO_OS_LINUX # include "pugl/pugl_x11.h" #endif -START_NAMESPACE_DISTRHO - // ------------------------------------------------- // Point diff --git a/source/libs/pugl/pugl.h b/source/libs/pugl/pugl.h index ecba5a2f1..5ec611dbd 100644 --- a/source/libs/pugl/pugl.h +++ b/source/libs/pugl/pugl.h @@ -54,9 +54,7 @@ # define PUGL_API #endif -#ifdef __cplusplus -extern "C" { -#else +#ifndef __cplusplus # include #endif @@ -95,7 +93,7 @@ typedef enum { PUGL_CHAR_ESCAPE = 0x1B, PUGL_CHAR_DELETE = 0x7F } PuglChar; - + /** Special (non-Unicode) keyboard keys. */ @@ -131,12 +129,12 @@ typedef enum { Keyboard modifier flags. */ typedef enum { - PUGL_MOD_SHIFT = 1, /**< Shift key */ + PUGL_MOD_SHIFT = 1, /**< Shift key */ PUGL_MOD_CTRL = 1 << 1, /**< Control key */ PUGL_MOD_ALT = 1 << 2, /**< Alt/Option key */ PUGL_MOD_SUPER = 1 << 3, /**< Mod4/Command/Windows key */ } PuglMod; - + /** Handle for opaque user data. */ @@ -205,7 +203,7 @@ typedef void (*PuglScrollFunc)(PuglView* view, float dx, float dy); A function called when a special key is pressed or released. This callback allows the use of keys that do not have unicode points. Note - that some non-printable keys + that some non-printable keys @param view The view the event occured in. @param press True if the key was pressed, false if released. @param key The key pressed. @@ -340,8 +338,4 @@ puglDestroy(PuglView* view); @} */ -#ifdef __cplusplus -} /* extern "C" */ -#endif - #endif /* PUGL_H_INCLUDED */ diff --git a/source/libs/pugl/pugl_x11.h b/source/libs/pugl/pugl_x11.h index 469007416..3d592a792 100644 --- a/source/libs/pugl/pugl_x11.h +++ b/source/libs/pugl/pugl_x11.h @@ -19,6 +19,9 @@ @file pugl_x11.h X11 Pugl Implementation (PuglInternalsImpl only). */ +#ifndef PUGL_X11_H_INCLUDED +#define PUGL_X11_H_INCLUDED + #include "pugl.h" #include @@ -39,3 +42,5 @@ typedef struct PuglInternalsImpl PuglInternals; PuglInternals* puglGetInternalsImpl(PuglView* view); + +#endif /* PUGL_X11_H_INCLUDED */ diff --git a/source/utils/carla_utils.hpp b/source/utils/carla_utils.hpp index e59339e39..60f4ed550 100644 --- a/source/utils/carla_utils.hpp +++ b/source/utils/carla_utils.hpp @@ -172,14 +172,14 @@ void carla_zeroMem(void* const memory, const size_t numBytes) { CARLA_ASSERT(memory); - memset(memory, 0, numBytes); + std::memset(memory, 0, numBytes); } template static inline void carla_zeroStruct(T& structure) { - memset(&structure, 0, sizeof(T)); + std::memset(&structure, 0, sizeof(T)); } // -------------------------------------------------