carla.h 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. /*
  2. * carla.h - Carla for LMMS
  3. *
  4. * Copyright (C) 2014-2018 Filipe Coelho <falktx@falktx.com>
  5. *
  6. * This file is part of LMMS - https://lmms.io
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public
  10. * License as published by the Free Software Foundation; either
  11. * version 2 of the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public
  19. * License along with this program (see COPYING); if not, write to the
  20. * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  21. * Boston, MA 02110-1301 USA.
  22. *
  23. */
  24. #ifndef CARLA_H
  25. #define CARLA_H
  26. #define CARLA_SETTING_PREFIX "PARAM_KNOB_"
  27. #define CARLA_MIN_PARAM_VERSION 0x020090
  28. #define CARLA_VERSION_HEX_3 0x30000
  29. // qt
  30. #include <QCloseEvent>
  31. #include <QCompleter>
  32. #include <QGridLayout>
  33. #include <QLineEdit>
  34. #include <QScrollArea>
  35. #include <QStringListModel>
  36. #include <QtCore/QMutex>
  37. // carla/source/includes
  38. #include "carlabase_export.h"
  39. #if CARLA_VERSION_HEX >= 0x010911
  40. #include "CarlaNativePlugin.h"
  41. #else
  42. #include "CarlaBackend.h"
  43. #include "CarlaNative.h"
  44. #include "CarlaUtils.h"
  45. CARLA_EXPORT
  46. const NativePluginDescriptor* carla_get_native_patchbay_plugin();
  47. CARLA_EXPORT
  48. const NativePluginDescriptor* carla_get_native_rack_plugin();
  49. #endif
  50. // lmms/include/
  51. #include "EffectControls.h"
  52. #include "Instrument.h"
  53. #include "InstrumentView.h"
  54. #include "Knob.h"
  55. #include "SubWindow.h"
  56. class QPushButton;
  57. class QComboBox;
  58. class CarlaParamsView;
  59. class CarlaParamFloatModel : public FloatModel
  60. {
  61. public:
  62. CarlaParamFloatModel(Model * parent):
  63. FloatModel(0.0, 0.0, 1.0, 0.001, parent, "Unused"),
  64. m_isOutput(false),
  65. m_isEnabled(false)
  66. {
  67. }
  68. // From AutomatableModel.h, it's private there.
  69. inline static bool mustQuoteName(const QString &name)
  70. {
  71. QRegExp reg("^[A-Za-z0-9._-]+$");
  72. return !reg.exactMatch(name);
  73. }
  74. inline virtual void loadSettings(const QDomElement& element, const QString& name = QString("value")) override
  75. {
  76. AutomatableModel::loadSettings(element, name);
  77. bool mustQuote = mustQuoteName(name);
  78. QDomElement me = element.firstChildElement(mustQuote ? QString("automatablemodel") : name);
  79. if (!me.isNull()) {
  80. m_isOutput = (bool)me.attribute("output", "0").toInt();
  81. m_groupName = QString(me.attribute("groupName", ""));
  82. }
  83. }
  84. inline virtual void saveSettings(QDomDocument& doc, QDomElement& element,
  85. const QString& name = QString( "value" )) override
  86. {
  87. if (m_isEnabled)
  88. {
  89. AutomatableModel::saveSettings(doc, element, name);
  90. bool mustQuote = mustQuoteName(name);
  91. QDomElement me = element.firstChildElement(mustQuote ? QString("automatablemodel") : name);
  92. if (!me.isNull())
  93. {
  94. me.setAttribute("output", m_isOutput);
  95. me.setAttribute("groupName", m_groupName);
  96. }
  97. }
  98. }
  99. inline const bool enabled()
  100. {
  101. return m_isEnabled;
  102. }
  103. inline const bool isOutput()
  104. {
  105. return m_isOutput;
  106. }
  107. inline void setOutput(bool state = true)
  108. {
  109. m_isOutput = state;
  110. }
  111. inline void setEnabled(bool state = true)
  112. {
  113. m_isEnabled = state;
  114. }
  115. inline void setGroupName(QString groupName)
  116. {
  117. m_groupName = groupName;
  118. }
  119. inline void setGroupId(uint8_t groupId)
  120. {
  121. m_groupId = groupId;
  122. }
  123. virtual QString groupName() const
  124. {
  125. return m_groupName;
  126. }
  127. virtual uint8_t groupId() const
  128. {
  129. return m_groupId;
  130. }
  131. private:
  132. bool m_isOutput;
  133. bool m_isEnabled;
  134. uint8_t m_groupId;
  135. QString m_groupName;
  136. };
  137. // -------------------------------------------------------------------
  138. class CarlaParamsSubWindow : public SubWindow
  139. {
  140. Q_OBJECT
  141. signals:
  142. void uiClosed();
  143. void resized();
  144. public:
  145. CarlaParamsSubWindow(QWidget * _parent, Qt::WindowFlags windowFlags) :
  146. SubWindow(_parent)
  147. {
  148. setAttribute(Qt::WA_DeleteOnClose, false);
  149. setWindowFlags(windowFlags);
  150. }
  151. virtual void resizeEvent(QResizeEvent * event) override
  152. {
  153. if (mousePress) {
  154. resizing = true;
  155. }
  156. SubWindow::resizeEvent(event);
  157. }
  158. virtual void mousePressEvent(QMouseEvent * event) override
  159. {
  160. mousePress = true;
  161. SubWindow::mousePressEvent(event);
  162. }
  163. virtual void mouseReleaseEvent(QMouseEvent * event) override
  164. {
  165. if (resizing) {
  166. resizing = false;
  167. mousePress = false;
  168. emit resized();
  169. }
  170. SubWindow::mouseReleaseEvent(event);
  171. }
  172. virtual void closeEvent(QCloseEvent * event) override
  173. {
  174. emit uiClosed();
  175. event->accept();
  176. }
  177. private:
  178. bool resizing = false;
  179. bool mousePress = false;
  180. };
  181. // -------------------------------------------------------------------
  182. class CARLABASE_EXPORT CarlaInstrument : public Instrument
  183. {
  184. Q_OBJECT
  185. public:
  186. static const uint32_t kMaxMidiEvents = 512;
  187. CarlaInstrument(InstrumentTrack* const instrumentTrack, const Descriptor* const descriptor, const bool isPatchbay);
  188. virtual ~CarlaInstrument();
  189. // Carla NativeHostDescriptor functions
  190. uint32_t handleGetBufferSize() const;
  191. double handleGetSampleRate() const;
  192. bool handleIsOffline() const;
  193. const NativeTimeInfo* handleGetTimeInfo() const;
  194. void handleUiParameterChanged(const uint32_t index, const float value) const;
  195. void handleUiClosed();
  196. intptr_t handleDispatcher(const NativeHostDispatcherOpcode opcode, const int32_t index, const intptr_t value, void* const ptr, const float opt);
  197. // LMMS functions
  198. virtual Flags flags() const;
  199. virtual QString nodeName() const;
  200. virtual void saveSettings(QDomDocument& doc, QDomElement& parent);
  201. virtual void loadSettings(const QDomElement& elem);
  202. virtual void play(sampleFrame* workingBuffer);
  203. virtual bool handleMidiEvent(const MidiEvent& event, const TimePos& time, f_cnt_t offset);
  204. virtual PluginView* instantiateView(QWidget* parent);
  205. signals:
  206. void uiClosed();
  207. void paramsUpdated();
  208. private slots:
  209. void sampleRateChanged();
  210. void refreshParams(bool init = false);
  211. void clearParamModels();
  212. void paramModelChanged(uint32_t index);
  213. void updateParamModel(uint32_t index);
  214. private:
  215. const bool kIsPatchbay;
  216. NativePluginHandle fHandle;
  217. NativeHostDescriptor fHost;
  218. const NativePluginDescriptor* fDescriptor;
  219. uint32_t fMidiEventCount;
  220. NativeMidiEvent fMidiEvents[kMaxMidiEvents];
  221. NativeTimeInfo fTimeInfo;
  222. // this is only needed because note-offs are being sent during play
  223. QMutex fMutex;
  224. uint8_t m_paramGroupCount;
  225. QList<CarlaParamFloatModel*> m_paramModels;
  226. QDomElement m_settingsElem;
  227. QCompleter* m_paramsCompleter;
  228. QStringListModel* m_completerModel;
  229. friend class CarlaInstrumentView;
  230. friend class CarlaParamsView;
  231. };
  232. // -------------------------------------------------------------------
  233. class CarlaInstrumentView : public InstrumentViewFixedSize
  234. {
  235. Q_OBJECT
  236. public:
  237. CarlaInstrumentView(CarlaInstrument* const instrument, QWidget* const parent);
  238. virtual ~CarlaInstrumentView();
  239. private slots:
  240. void toggleUI(bool);
  241. void uiClosed();
  242. void toggleParamsWindow();
  243. void paramsUiClosed();
  244. private:
  245. virtual void modelChanged();
  246. virtual void timerEvent(QTimerEvent*);
  247. NativePluginHandle fHandle;
  248. const NativePluginDescriptor* fDescriptor;
  249. int fTimerId;
  250. CarlaInstrument* const m_carlaInstrument;
  251. QWidget* const m_parent;
  252. QMdiSubWindow* m_paramsSubWindow;
  253. CarlaParamsView* m_paramsView;
  254. QPushButton* m_toggleUIButton;
  255. QPushButton* m_toggleParamsWindowButton;
  256. friend class CarlaParamsView;
  257. };
  258. // -------------------------------------------------------------------
  259. class CarlaParamsView : public InstrumentView
  260. {
  261. Q_OBJECT
  262. public:
  263. CarlaParamsView(CarlaInstrumentView* const instrumentView, QWidget* const parent);
  264. virtual ~CarlaParamsView();
  265. signals:
  266. void uiClosed();
  267. private slots:
  268. void refreshKnobs();
  269. void filterKnobs();
  270. void clearFilterText();
  271. void windowResized();
  272. private:
  273. void adjustWindowWidth();
  274. void addKnob(uint32_t index);
  275. void clearKnobs();
  276. CarlaInstrument* const m_carlaInstrument;
  277. CarlaInstrumentView* const m_carlaInstrumentView;
  278. QList<Knob*> m_knobs;
  279. // Keep track of the biggest knob width per group
  280. QList<uint16_t> m_maxKnobWidthPerGroup;
  281. uint32_t m_maxColumns;
  282. uint32_t m_curColumn;
  283. uint32_t m_curRow;
  284. uint32_t m_curOutColumn;
  285. uint32_t m_curOutRow;
  286. QScrollArea* m_inputScrollArea;
  287. QGridLayout* m_inputScrollAreaLayout;
  288. QWidget* m_inputScrollAreaWidgetContent;
  289. QScrollArea* m_outputScrollArea;
  290. QGridLayout* m_outputScrollAreaLayout;
  291. QWidget* m_outputScrollAreaWidgetContent;
  292. QHBoxLayout* m_toolBarLayout;
  293. QLineEdit* m_paramsFilterLineEdit;
  294. QPushButton* m_clearFilterButton;
  295. QPushButton* m_automatedOnlyButton;
  296. QComboBox* m_groupFilterCombo;
  297. QStringListModel* m_groupFilterModel;
  298. };
  299. #endif