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.

361 lines
10KB

  1. /*
  2. * DISTRHO Cardinal Plugin
  3. * Copyright (C) 2021-2022 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 3 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 LICENSE file.
  16. */
  17. #include <juce_audio_processors/juce_audio_processors.h>
  18. #define createPlugin createStaticPlugin
  19. #include "src/DistrhoPluginInternal.hpp"
  20. #include "src/DistrhoUIInternal.hpp"
  21. START_NAMESPACE_DISTRHO
  22. #if 0
  23. // -----------------------------------------------------------------------------------------------------------
  24. class ParameterForDPF : public juce::AudioProcessorParameter
  25. {
  26. PluginExporter& plugin;
  27. const uint index;
  28. public:
  29. ParameterForDPF(PluginExporter& plugin_, const uint index_)
  30. : plugin(plugin_),
  31. index(index_) {}
  32. protected:
  33. float getValue() const override
  34. {
  35. return plugin.getParameterRanges(index).getNormalizedValue(plugin.getParameterValue(index));
  36. }
  37. void setValue(const float newValue) override
  38. {
  39. plugin.setParameterValue(index, plugin.getParameterRanges(index).getUnnormalizedValue(newValue));
  40. }
  41. float getDefaultValue() const override
  42. {
  43. return plugin.getParameterDefault(index);
  44. }
  45. juce::String getName(int) const override
  46. {
  47. return plugin.getParameterName(index).buffer();
  48. }
  49. juce::String getLabel() const override
  50. {
  51. return plugin.getParameterUnit(index).buffer();
  52. }
  53. float getValueForText(const juce::String& text) const override
  54. {
  55. return 0.0f;
  56. }
  57. };
  58. #endif
  59. // -----------------------------------------------------------------------------------------------------------
  60. class CardinalWrapperProcessor : public juce::AudioProcessor
  61. {
  62. friend class CardinalWrapperEditor;
  63. PluginExporter plugin;
  64. TimePosition timePosition;
  65. static bool writeMidi(void* ptr, const MidiEvent& midiEvent)
  66. {
  67. return false;
  68. }
  69. static bool requestParameterValueChange(void* ptr, uint32_t index, float value)
  70. {
  71. return false;
  72. }
  73. static bool updateStateValue(void* ptr, const char* key, const char* value)
  74. {
  75. return false;
  76. }
  77. public:
  78. CardinalWrapperProcessor()
  79. : plugin(this, writeMidi, requestParameterValueChange, updateStateValue)
  80. {
  81. if (const double sampleRate = getSampleRate())
  82. plugin.setSampleRate(sampleRate);
  83. if (const int blockSize = getBlockSize())
  84. plugin.setBufferSize(blockSize);
  85. // for (uint i=0; i<plugin.getParameterCount(); ++i)
  86. // addParameter(new ParameterForDPF(plugin, i));
  87. }
  88. ~CardinalWrapperProcessor() override
  89. {
  90. }
  91. const juce::String getName() const override
  92. {
  93. return plugin.getName();
  94. }
  95. juce::StringArray getAlternateDisplayNames() const override
  96. {
  97. return juce::StringArray(plugin.getLabel());
  98. }
  99. void prepareToPlay(double sampleRate, int samplesPerBlock) override
  100. {
  101. plugin.deactivateIfNeeded();
  102. plugin.setSampleRate(sampleRate);
  103. plugin.setBufferSize(samplesPerBlock);
  104. plugin.activate();
  105. }
  106. void releaseResources() override
  107. {
  108. plugin.deactivateIfNeeded();
  109. }
  110. void processBlock(juce::AudioBuffer<float>& buffer, juce::MidiBuffer& midiMessages) override
  111. {
  112. midiMessages.clear();
  113. juce::AudioPlayHead* const playhead = getPlayHead();
  114. juce::AudioPlayHead::CurrentPositionInfo posInfo;
  115. if (playhead != nullptr && playhead->getCurrentPosition(posInfo))
  116. {
  117. timePosition.playing = posInfo.isPlaying;
  118. timePosition.bbt.valid = true;
  119. // ticksPerBeat is not possible with JUCE
  120. timePosition.bbt.ticksPerBeat = 1920.0;
  121. if (posInfo.timeInSamples >= 0)
  122. timePosition.frame = posInfo.timeInSamples;
  123. else
  124. timePosition.frame = 0;
  125. timePosition.bbt.beatsPerMinute = posInfo.bpm;
  126. const double ppqPos = std::abs(posInfo.ppqPosition);
  127. const int ppqPerBar = posInfo.timeSigNumerator * 4 / posInfo.timeSigDenominator;
  128. const double barBeats = (std::fmod(ppqPos, ppqPerBar) / ppqPerBar) * posInfo.timeSigNumerator;
  129. const double rest = std::fmod(barBeats, 1.0);
  130. timePosition.bbt.bar = static_cast<int32_t>(ppqPos) / ppqPerBar + 1;
  131. timePosition.bbt.beat = static_cast<int32_t>(barBeats - rest + 0.5) + 1;
  132. timePosition.bbt.tick = rest * timePosition.bbt.ticksPerBeat;
  133. timePosition.bbt.beatsPerBar = posInfo.timeSigNumerator;
  134. timePosition.bbt.beatType = posInfo.timeSigDenominator;
  135. if (posInfo.ppqPosition < 0.0)
  136. {
  137. --timePosition.bbt.bar;
  138. timePosition.bbt.beat = posInfo.timeSigNumerator - timePosition.bbt.beat + 1;
  139. timePosition.bbt.tick = timePosition.bbt.ticksPerBeat - timePosition.bbt.tick - 1;
  140. }
  141. timePosition.bbt.barStartTick = timePosition.bbt.ticksPerBeat*
  142. timePosition.bbt.beatsPerBar*
  143. (timePosition.bbt.bar-1);
  144. }
  145. else
  146. {
  147. timePosition.frame = 0;
  148. timePosition.playing = false;
  149. timePosition.bbt.valid = false;
  150. }
  151. plugin.setTimePosition(timePosition);
  152. const int numSamples = buffer.getNumSamples();
  153. DISTRHO_SAFE_ASSERT_INT_RETURN(numSamples > 0, numSamples,);
  154. DISTRHO_SAFE_ASSERT_RETURN(buffer.getNumChannels() == 2,);
  155. const float* audioBufferIn[2];
  156. float* audioBufferOut[2];
  157. audioBufferIn[0] = buffer.getReadPointer(0);
  158. audioBufferIn[1] = buffer.getReadPointer(1);
  159. audioBufferOut[0] = buffer.getWritePointer(0);
  160. audioBufferOut[1] = buffer.getWritePointer(1);
  161. plugin.run(audioBufferIn, audioBufferOut, numSamples, nullptr, 0);
  162. }
  163. double getTailLengthSeconds() const override
  164. {
  165. return 0.0;
  166. }
  167. bool acceptsMidi() const override
  168. {
  169. return true;
  170. }
  171. bool producesMidi() const override
  172. {
  173. return true;
  174. }
  175. juce::AudioProcessorEditor* createEditor() override;
  176. bool hasEditor() const override
  177. {
  178. return true;
  179. }
  180. int getNumPrograms() override
  181. {
  182. return 0;
  183. }
  184. int getCurrentProgram() override
  185. {
  186. return 0;
  187. }
  188. void setCurrentProgram(int) override
  189. {
  190. }
  191. const juce::String getProgramName(int) override
  192. {
  193. return {};
  194. }
  195. void changeProgramName(int, const juce::String&) override
  196. {
  197. }
  198. void getStateInformation(juce::MemoryBlock& destData) override
  199. {
  200. }
  201. void setStateInformation(const void* data, int sizeInBytes) override
  202. {
  203. }
  204. };
  205. // -----------------------------------------------------------------------------------------------------------
  206. class CardinalWrapperEditor : public juce::AudioProcessorEditor
  207. {
  208. UIExporter* ui;
  209. void* const dspPtr;
  210. static void editParamFunc(void* ptr, uint32_t rindex, bool started) {}
  211. static void setParamFunc(void* ptr, uint32_t rindex, float value) {}
  212. static void setStateFunc(void* ptr, const char* key, const char* value) {}
  213. static void sendNoteFunc(void* ptr, uint8_t channel, uint8_t note, uint8_t velo) {}
  214. static void setSizeFunc(void* ptr, uint width, uint height)
  215. {
  216. CardinalWrapperEditor* const editor = static_cast<CardinalWrapperEditor*>(ptr);
  217. DISTRHO_SAFE_ASSERT_RETURN(editor != nullptr,);
  218. #ifdef DISTRHO_OS_MAC
  219. UIExporter* const ui = editor->ui;
  220. DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,);
  221. const double scaleFactor = ui->getScaleFactor();
  222. width /= scaleFactor;
  223. height /= scaleFactor;
  224. #endif
  225. editor->setSize(width, height);
  226. }
  227. static bool fileRequestFunc(void* ptr, const char* key) { return false; }
  228. public:
  229. CardinalWrapperEditor(CardinalWrapperProcessor& cardinalProcessor)
  230. : juce::AudioProcessorEditor(cardinalProcessor),
  231. ui(nullptr),
  232. dspPtr(cardinalProcessor.plugin.getInstancePointer())
  233. {
  234. setOpaque(true);
  235. setResizable(true, false);
  236. // setResizeLimits(648, 538, -1, -1);
  237. setSize(1228, 666);
  238. }
  239. ~CardinalWrapperEditor() override
  240. {
  241. delete ui;
  242. }
  243. void paint(juce::Graphics&)
  244. {
  245. if (ui == nullptr)
  246. {
  247. auto peer = getPeer();
  248. d_stdout("peer is %p", peer);
  249. auto handle = peer->getNativeHandle();
  250. d_stdout("handle is %p", handle);
  251. auto proc = getAudioProcessor();
  252. d_stdout("proc is %p", proc);
  253. ui = new UIExporter(this,
  254. (uintptr_t)handle,
  255. proc->getSampleRate(),
  256. editParamFunc,
  257. setParamFunc,
  258. setStateFunc,
  259. sendNoteFunc,
  260. setSizeFunc,
  261. fileRequestFunc,
  262. nullptr, // bundlePath
  263. dspPtr,
  264. 0.0 // scaleFactor
  265. );
  266. }
  267. ui->plugin_idle();
  268. repaint();
  269. }
  270. };
  271. juce::AudioProcessorEditor* CardinalWrapperProcessor::createEditor()
  272. {
  273. return new CardinalWrapperEditor(*this);
  274. }
  275. // -----------------------------------------------------------------------------------------------------------
  276. END_NAMESPACE_DISTRHO
  277. // -----------------------------------------------------------------------------------------------------------
  278. juce::AudioProcessor* createPluginFilter()
  279. {
  280. // set valid but dummy values
  281. d_nextBufferSize = 512;
  282. d_nextSampleRate = 48000.0;
  283. return new DISTRHO_NAMESPACE::CardinalWrapperProcessor;
  284. }
  285. // -----------------------------------------------------------------------------------------------------------