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.

129 lines
3.9KB

  1. #pragma once
  2. #include <JuceHeader.h>
  3. #include <optional>
  4. #include "XmlConsts.hpp"
  5. #include "WEFilters/ModulationSource.h"
  6. enum class MODULATION_TYPE {
  7. MACRO,
  8. LFO,
  9. ENVELOPE,
  10. RANDOM
  11. };
  12. class ModulationSourceDefinition {
  13. public:
  14. int id;
  15. MODULATION_TYPE type;
  16. ModulationSourceDefinition(int newID, MODULATION_TYPE newType) : id(newID), type(newType) {}
  17. bool operator==(const ModulationSourceDefinition& other) const {
  18. return id == other.id && type == other.type;
  19. }
  20. /**
  21. * Returns an optional containing a ModulationSourceDefinition if one can be constructed from
  22. * the provided juce::var, otherwise empty.
  23. */
  24. static std::optional<ModulationSourceDefinition> fromVariant(juce::var variant) {
  25. std::optional<ModulationSourceDefinition> retVal;
  26. if (variant.isArray() && variant.size() == 2 && variant[0].isInt() && variant[1].isString()) {
  27. const int newId = variant[0];
  28. const juce::String typeString = variant[1].toString();
  29. const MODULATION_TYPE newType = _stringToModulationType(typeString);
  30. retVal.emplace(newId, newType);
  31. }
  32. return retVal;
  33. }
  34. juce::var toVariant() const {
  35. // Encode the members as items in the variant's array
  36. juce::var retVal;
  37. retVal.append(id);
  38. retVal.append(_modulationTypeToString(type));
  39. return retVal;
  40. }
  41. void restoreFromXml(juce::XmlElement* element) {
  42. if (element->hasAttribute(XML_MODULATION_SOURCE_ID)) {
  43. id = element->getIntAttribute(XML_MODULATION_SOURCE_ID);
  44. } else {
  45. juce::Logger::writeToLog("Missing attribute " + juce::String(XML_MODULATION_SOURCE_ID));
  46. }
  47. if (element->hasAttribute(XML_MODULATION_SOURCE_TYPE)) {
  48. type = _stringToModulationType(element->getStringAttribute(XML_MODULATION_SOURCE_TYPE));
  49. } else {
  50. juce::Logger::writeToLog("Missing attribute " + juce::String(XML_MODULATION_SOURCE_TYPE));
  51. }
  52. }
  53. void writeToXml(juce::XmlElement* element) const {
  54. element->setAttribute(XML_MODULATION_SOURCE_ID, id);
  55. element->setAttribute(XML_MODULATION_SOURCE_TYPE, _modulationTypeToString(type));
  56. }
  57. private:
  58. static juce::String _modulationTypeToString(MODULATION_TYPE type) {
  59. switch (type) {
  60. case MODULATION_TYPE::MACRO:
  61. return "macro";
  62. case MODULATION_TYPE::LFO:
  63. return "lfo";
  64. case MODULATION_TYPE::ENVELOPE:
  65. return "envelope";
  66. case MODULATION_TYPE::RANDOM:
  67. return "random";
  68. default:
  69. return "";
  70. }
  71. }
  72. static MODULATION_TYPE _stringToModulationType(juce::String typeString) {
  73. if (typeString == "macro") {
  74. return MODULATION_TYPE::MACRO;
  75. } else if (typeString == "lfo") {
  76. return MODULATION_TYPE::LFO;
  77. } else if (typeString == "envelope") {
  78. return MODULATION_TYPE::ENVELOPE;
  79. } else /*(typeString == "random")*/ {
  80. return MODULATION_TYPE::RANDOM;
  81. }
  82. }
  83. };
  84. /**
  85. * Provides a way for sources (LFOs, envelopes) to lookup the modulation values for sources assigned
  86. * to their parameters.
  87. */
  88. class ModulationSourceProvider : public WECore::ModulationSource<double> {
  89. public:
  90. ModulationSourceDefinition definition;
  91. ModulationSourceProvider(
  92. ModulationSourceDefinition newDefinition,
  93. std::function<float(int, MODULATION_TYPE)> getModulationValueCallback):
  94. definition(newDefinition), _getModulationValueCallback(getModulationValueCallback) { }
  95. double getLastOutput() const override {
  96. return _getModulationValueCallback(definition.id, definition.type);
  97. }
  98. private:
  99. std::function<float(int, MODULATION_TYPE)> _getModulationValueCallback;
  100. virtual double _getNextOutputImpl(double /*inSample*/) override { return 0.0; }
  101. virtual void _resetImpl() override {}
  102. };