The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
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.

199 lines
6.2KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2017 - ROLI Ltd.
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 5 End-User License
  8. Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
  9. 27th April 2017).
  10. End User License Agreement: www.juce.com/juce-5-licence
  11. Privacy Policy: www.juce.com/juce-5-privacy-policy
  12. Or: You may also use this code under the terms of the GPL v3 (see
  13. www.gnu.org/licenses).
  14. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  15. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  16. DISCLAIMED.
  17. ==============================================================================
  18. */
  19. #pragma once
  20. #include "../JuceLibraryCode/JuceHeader.h"
  21. using namespace dsp;
  22. //==============================================================================
  23. struct DSPDemoParameterBase : public ChangeBroadcaster
  24. {
  25. DSPDemoParameterBase (const String& labelName) : name (labelName) {}
  26. virtual ~DSPDemoParameterBase() {}
  27. virtual Component* getComponent() = 0;
  28. virtual int getPreferredHeight() = 0;
  29. virtual int getPreferredWidth() = 0;
  30. String name;
  31. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DSPDemoParameterBase)
  32. };
  33. //==============================================================================
  34. struct SliderParameter : public DSPDemoParameterBase,
  35. private Slider::Listener
  36. {
  37. SliderParameter (Range<double> range, double skew, double initialValue,
  38. const String& labelName, const String& suffix = {})
  39. : DSPDemoParameterBase (labelName)
  40. {
  41. slider.setRange (range.getStart(), range.getEnd(), 0.01);
  42. slider.setSkewFactor (skew);
  43. slider.setValue (initialValue);
  44. if (suffix.isNotEmpty())
  45. slider.setTextValueSuffix (suffix);
  46. slider.addListener (this);
  47. }
  48. Component* getComponent() override { return &slider; }
  49. int getPreferredHeight() override { return 40; }
  50. int getPreferredWidth() override { return 500; }
  51. double getCurrentValue() const { return slider.getValue(); }
  52. private:
  53. Slider slider;
  54. void sliderValueChanged (Slider*) override { sendChangeMessage(); }
  55. };
  56. //==============================================================================
  57. struct ChoiceParameter : public DSPDemoParameterBase,
  58. private ComboBox::Listener
  59. {
  60. ChoiceParameter (const StringArray& options, int initialId, const String& labelName)
  61. : DSPDemoParameterBase (labelName)
  62. {
  63. parameterBox.addItemList (options, 1);
  64. parameterBox.addListener (this);
  65. parameterBox.setSelectedId (initialId);
  66. }
  67. Component* getComponent() override { return &parameterBox; }
  68. int getPreferredHeight() override { return 25; }
  69. int getPreferredWidth() override { return 250; }
  70. int getCurrentSelectedID() const { return parameterBox.getSelectedId(); }
  71. private:
  72. ComboBox parameterBox;
  73. void comboBoxChanged (ComboBox*) override { sendChangeMessage(); }
  74. };
  75. //==============================================================================
  76. // This is just a base class for the demos which exposes them as an AudioSource with
  77. // an array of parameters
  78. struct DSPDemoBase : public AudioSource
  79. {
  80. virtual const std::vector<DSPDemoParameterBase*>& getParameters() = 0;
  81. AudioSource* inputSource = nullptr;
  82. };
  83. //==============================================================================
  84. template <typename DemoType>
  85. struct DSPDemo : public DSPDemoBase,
  86. public ProcessorWrapper<DemoType>,
  87. private ChangeListener
  88. {
  89. DSPDemo()
  90. {
  91. for (auto* p : getParameters())
  92. p->addChangeListener (this);
  93. }
  94. void prepareToPlay (int blockSize, double sampleRate) override
  95. {
  96. inputSource->prepareToPlay (blockSize, sampleRate);
  97. this->prepare ({ sampleRate, (uint32) blockSize, 2 });
  98. }
  99. void releaseResources() override
  100. {
  101. inputSource->releaseResources();
  102. }
  103. void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) override
  104. {
  105. jassert (bufferToFill.buffer != nullptr);
  106. inputSource->getNextAudioBlock (bufferToFill);
  107. dsp::AudioBlock<float> block (*bufferToFill.buffer,
  108. (size_t) bufferToFill.startSample);
  109. ScopedLock audioLock (audioCallbackLock);
  110. this->process (ProcessContextReplacing<float> (block));
  111. }
  112. const std::vector<DSPDemoParameterBase*>& getParameters() override
  113. {
  114. return this->processor.parameters;
  115. }
  116. void changeListenerCallback (ChangeBroadcaster*) override
  117. {
  118. ScopedLock audioLock (audioCallbackLock);
  119. static_cast<DemoType&> (this->processor).updateParameters();
  120. }
  121. CriticalSection audioCallbackLock;
  122. };
  123. //==============================================================================
  124. struct Demo
  125. {
  126. using CreateDemoFn = std::function<DSPDemoBase*(AudioSource&)>;
  127. String name, code;
  128. CreateDemoFn createDemo;
  129. Demo (const char* nameToUse, const char* codeToUse, CreateDemoFn create)
  130. : name (nameToUse), code (codeToUse), createDemo (create)
  131. {
  132. code = code.fromFirstOccurrenceOf ("// @@ START_DEMO", false, false)
  133. .upToLastOccurrenceOf ("// @@ END_DEMO", false, false)
  134. .trim();
  135. getList().add (this);
  136. }
  137. static Array<const Demo*>& getList()
  138. {
  139. static Array<const Demo*> demos;
  140. return demos;
  141. }
  142. };
  143. template <typename DemoType>
  144. struct RegisterDSPDemo : public Demo
  145. {
  146. RegisterDSPDemo (const char* nameToUse, const char* codeToUse)
  147. : Demo (nameToUse, codeToUse, [](AudioSource& input) { auto* demo = new DSPDemo<DemoType>(); demo->inputSource = &input; return demo; })
  148. {}
  149. };