Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

juce-patchbay.cpp 8.1KB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. /*
  2. * Carla Native Plugins
  3. * Copyright (C) 2012-2014 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the doc/GPL.txt file.
  16. */
  17. #include "CarlaNative.hpp"
  18. #include "juce_audio_processors.h"
  19. #include "juce_gui_extra.h"
  20. // -----------------------------------------------------------------------
  21. namespace juce {
  22. #include "jucepluginhost/juce_MidiKeyboardComponent.h"
  23. #include "jucepluginhost/juce_MidiKeyboardComponent.cpp"
  24. }
  25. using namespace juce;
  26. // -----------------------------------------------------------------------
  27. #include "jucepluginhost/FilterGraph.h"
  28. #include "jucepluginhost/InternalFilters.h"
  29. #include "jucepluginhost/GraphEditorPanel.h"
  30. #include "jucepluginhost/MainHostWindow.h"
  31. // -----------------------------------------------------------------------
  32. class JucePatchbayPlugin : public NativePluginClass
  33. {
  34. public:
  35. JucePatchbayPlugin(const NativeHostDescriptor* const host)
  36. : NativePluginClass(host),
  37. fFormatManager(),
  38. fGraph(fFormatManager),
  39. fAudioBuffer(1, 0),
  40. fMidiKeyState(nullptr)
  41. {
  42. PropertiesFile::Options options;
  43. options.applicationName = "Juce Audio Plugin Host";
  44. options.filenameSuffix = "settings";
  45. options.osxLibrarySubFolder = "Preferences";
  46. fAppProperties = new ApplicationProperties();
  47. fAppProperties->setStorageParameters(options);
  48. fFormatManager.addDefaultFormats();
  49. fFormatManager.addFormat(new InternalPluginFormat());
  50. fGraph.ready(fAppProperties);
  51. fGraph.getGraph().setPlayConfigDetails(2, 2, getSampleRate(), static_cast<int>(getBufferSize()));
  52. fMidiBuffer.ensureSize(512*2);
  53. fMidiBuffer.clear();
  54. }
  55. ~JucePatchbayPlugin() override
  56. {
  57. fGraph.clear();
  58. fAppProperties = nullptr;
  59. }
  60. protected:
  61. // -------------------------------------------------------------------
  62. // Plugin process calls
  63. void activate() override
  64. {
  65. fGraph.getGraph().prepareToPlay(getSampleRate(), static_cast<int>(getBufferSize()));
  66. fAudioBuffer.setSize(2, static_cast<int>(getBufferSize()));
  67. {
  68. const ScopedLock csl(fMidiKeyMutex);
  69. if (fMidiKeyState != nullptr)
  70. fMidiKeyState->reset();
  71. }
  72. }
  73. void deactivate() override
  74. {
  75. fGraph.getGraph().releaseResources();
  76. }
  77. void process(float** inBuffer, float** const outBuffer, const uint32_t frames, const NativeMidiEvent* const midiEvents, const uint32_t midiEventCount) override
  78. {
  79. fMidiBuffer.clear();
  80. for (uint32_t i=0; i < midiEventCount; ++i)
  81. {
  82. const NativeMidiEvent* const midiEvent(&midiEvents[i]);
  83. fMidiBuffer.addEvent(midiEvent->data, midiEvent->size, midiEvent->time);
  84. }
  85. {
  86. const ScopedLock csl(fMidiKeyMutex);
  87. if (fMidiKeyState != nullptr)
  88. fMidiKeyState->processNextMidiBuffer(fMidiBuffer, 0, static_cast<int>(frames), true);
  89. }
  90. FloatVectorOperations::copy(outBuffer[0], inBuffer[0], static_cast<int>(frames));
  91. FloatVectorOperations::copy(outBuffer[1], inBuffer[1], static_cast<int>(frames));
  92. AudioSampleBuffer audioBuf(outBuffer, 2, static_cast<int>(frames));
  93. fGraph.getGraph().processBlock(audioBuf, fMidiBuffer);
  94. MidiBuffer::Iterator outBufferIterator(fMidiBuffer);
  95. const uint8_t* midiData;
  96. int numBytes;
  97. int sampleNumber;
  98. NativeMidiEvent tmpEvent;
  99. tmpEvent.port = 0;
  100. for (; outBufferIterator.getNextEvent(midiData, numBytes, sampleNumber);)
  101. {
  102. if (numBytes <= 0 || numBytes > 4)
  103. continue;
  104. tmpEvent.size = numBytes;
  105. tmpEvent.time = sampleNumber;
  106. std::memcpy(tmpEvent.data, midiData, sizeof(uint8_t)*tmpEvent.size);
  107. writeMidiEvent(&tmpEvent);
  108. }
  109. }
  110. // -------------------------------------------------------------------
  111. // Plugin UI calls
  112. void uiShow(const bool show) override
  113. {
  114. const MessageManagerLock mmLock;
  115. if (show)
  116. {
  117. if (fWindow == nullptr)
  118. {
  119. fWindow = new MainHostWindow(fFormatManager, fGraph, *fAppProperties);
  120. fWindow->setName(getUiName());
  121. }
  122. {
  123. const ScopedLock csl(fMidiKeyMutex);
  124. fMidiKeyState = fWindow->getMidiState();
  125. }
  126. fWindow->toFront(true);
  127. }
  128. else if (fWindow != nullptr)
  129. {
  130. {
  131. const ScopedLock csl(fMidiKeyMutex);
  132. fMidiKeyState = nullptr;
  133. }
  134. fWindow->setVisible(false);
  135. fWindow = nullptr;
  136. }
  137. }
  138. void uiIdle() override
  139. {
  140. if (fWindow == nullptr)
  141. return;
  142. if (fWindow->wasClosedByUser())
  143. {
  144. uiShow(false);
  145. uiClosed();
  146. }
  147. }
  148. // -------------------------------------------------------------------
  149. // Plugin state calls
  150. char* getState() const override
  151. {
  152. ScopedPointer<XmlElement> xml(fGraph.createXml());
  153. MemoryOutputStream stream;
  154. xml->writeToStream(stream, String::empty);
  155. return strdup(stream.toUTF8().toRawUTF8());
  156. }
  157. void setState(const char* const data) override
  158. {
  159. CARLA_SAFE_ASSERT_RETURN(data != nullptr,);
  160. String sdata(data);
  161. XmlDocument doc(sdata);
  162. ScopedPointer<XmlElement> xml(doc.getDocumentElement());
  163. if (xml != nullptr && xml->hasTagName("FILTERGRAPH"))
  164. fGraph.restoreFromXml(*xml);
  165. }
  166. // -------------------------------------------------------------------
  167. // Plugin dispatcher calls
  168. void uiNameChanged(const char* const uiName) override
  169. {
  170. CARLA_SAFE_ASSERT_RETURN(uiName != nullptr,);
  171. if (fWindow == nullptr)
  172. return;
  173. const MessageManagerLock mmLock;
  174. fWindow->setName(uiName);
  175. }
  176. private:
  177. AudioPluginFormatManager fFormatManager;
  178. FilterGraph fGraph;
  179. AudioSampleBuffer fAudioBuffer;
  180. MidiBuffer fMidiBuffer;
  181. ScopedPointer<ApplicationProperties> fAppProperties;
  182. ScopedPointer<MainHostWindow> fWindow;
  183. MidiKeyboardState* fMidiKeyState;
  184. CriticalSection fMidiKeyMutex;
  185. PluginClassEND(JucePatchbayPlugin)
  186. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(JucePatchbayPlugin)
  187. };
  188. // -----------------------------------------------------------------------
  189. static const NativePluginDescriptor jucepatchbayDesc = {
  190. /* category */ PLUGIN_CATEGORY_UTILITY,
  191. /* hints */ static_cast<NativePluginHints>(PLUGIN_IS_SYNTH|PLUGIN_HAS_UI|PLUGIN_NEEDS_FIXED_BUFFERS|PLUGIN_NEEDS_UI_JUCE|PLUGIN_USES_STATE/*|PLUGIN_USES_TIME*/),
  192. /* supports */ static_cast<NativePluginSupports>(0x0),
  193. /* audioIns */ 2,
  194. /* audioOuts */ 2,
  195. /* midiIns */ 1,
  196. /* midiOuts */ 1,
  197. /* paramIns */ 0,
  198. /* paramOuts */ 0,
  199. /* name */ "Juce Patchbay",
  200. /* label */ "jucepatchbay",
  201. /* maker */ "falkTX, Raw Material Software Ltd.",
  202. /* copyright */ "GNU GPL v2+",
  203. PluginDescriptorFILL(JucePatchbayPlugin)
  204. };
  205. // -----------------------------------------------------------------------
  206. CARLA_EXPORT
  207. void carla_register_native_plugin_jucepatchbay()
  208. {
  209. carla_register_native_plugin(&jucepatchbayDesc);
  210. }
  211. // -----------------------------------------------------------------------
  212. #include "jucepluginhost/FilterGraph.cpp"
  213. #include "jucepluginhost/InternalFilters.cpp"
  214. #include "jucepluginhost/GraphEditorPanel.cpp"
  215. #include "jucepluginhost/MainHostWindow.cpp"
  216. // -----------------------------------------------------------------------