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.

188 lines
5.5KB

  1. /*
  2. * Carla JSFX utils
  3. * Copyright (C) 2021 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. #ifndef CARLA_JSFX_UTILS_HPP_INCLUDED
  18. #define CARLA_JSFX_UTILS_HPP_INCLUDED
  19. #include "CarlaUtils.hpp"
  20. #include "water/files/File.h"
  21. #include "water/xml/XmlElement.h"
  22. #include "water/xml/XmlDocument.h"
  23. #include "water/streams/MemoryOutputStream.h"
  24. #pragma GCC diagnostic push
  25. #pragma GCC diagnostic ignored "-Wunused-parameter"
  26. #pragma GCC diagnostic ignored "-Wignored-attributes"
  27. #include "jsusfx.h"
  28. #include "jsusfx_file.h"
  29. #include "jsusfx_serialize.h"
  30. #pragma GCC diagnostic pop
  31. #include <memory>
  32. class CarlaJsusFx : public JsusFx
  33. {
  34. public:
  35. explicit CarlaJsusFx(JsusFxPathLibrary &pathLibrary)
  36. : JsusFx(pathLibrary)
  37. {
  38. }
  39. void setQuiet(bool quiet)
  40. {
  41. fQuiet = quiet;
  42. }
  43. void displayMsg(const char* fmt, ...) override
  44. {
  45. if (!fQuiet)
  46. {
  47. char msgBuf[256];
  48. ::va_list args;
  49. ::va_start(args, fmt);
  50. std::vsnprintf(msgBuf, sizeof(msgBuf), fmt, args);
  51. msgBuf[255] = 0;
  52. ::va_end(args);
  53. carla_stdout("%s", msgBuf);
  54. }
  55. }
  56. void displayError(const char* fmt, ...) override
  57. {
  58. if (!fQuiet)
  59. {
  60. char msgBuf[256];
  61. ::va_list args;
  62. ::va_start(args, fmt);
  63. std::vsnprintf(msgBuf, sizeof(msgBuf), fmt, args);
  64. msgBuf[255] = 0;
  65. ::va_end(args);
  66. carla_stderr("%s", msgBuf);
  67. }
  68. }
  69. private:
  70. bool fQuiet = false;
  71. };
  72. // -------------------------------------------------------------------------------------------------------------------
  73. class CarlaJsusFxPathLibrary : public JsusFxPathLibrary_Basic
  74. {
  75. public:
  76. explicit CarlaJsusFxPathLibrary(const water::File &file)
  77. : JsusFxPathLibrary_Basic(determineDataRoot(file).c_str())
  78. {
  79. }
  80. private:
  81. static std::string determineDataRoot(const water::File &file)
  82. {
  83. return file.getParentDirectory().getFullPathName().toRawUTF8();
  84. }
  85. };
  86. // -------------------------------------------------------------------------------------------------------------------
  87. class CarlaJsusFxFileAPI : public JsusFxFileAPI_Basic
  88. {
  89. public:
  90. };
  91. // -------------------------------------------------------------------------------------------------------------------
  92. class CarlaJsusFxSerializer : public JsusFxSerializer_Basic
  93. {
  94. public:
  95. explicit CarlaJsusFxSerializer(JsusFxSerializationData& data)
  96. : JsusFxSerializer_Basic(data)
  97. {
  98. }
  99. static water::String convertDataToString(const JsusFxSerializationData& data)
  100. {
  101. water::XmlElement root("JSFXState");
  102. std::size_t numSliders = data.sliders.size();
  103. for (std::size_t i = 0; i < numSliders; ++i)
  104. {
  105. water::XmlElement *slider = new water::XmlElement("Slider");
  106. slider->setAttribute("index", data.sliders[i].index);
  107. slider->setAttribute("value", data.sliders[i].value);
  108. root.addChildElement(slider);
  109. }
  110. std::size_t numVars = data.vars.size();
  111. for (std::size_t i = 0; i < numVars; ++i)
  112. {
  113. water::XmlElement *var = new water::XmlElement("Var");
  114. var->setAttribute("value", data.vars[i]);
  115. root.addChildElement(var);
  116. }
  117. water::MemoryOutputStream stream;
  118. root.writeToStream(stream, water::StringRef(), true);
  119. return stream.toUTF8();
  120. }
  121. static bool convertStringToData(const water::String& string, JsusFxSerializationData& data)
  122. {
  123. std::unique_ptr<water::XmlElement> root(water::XmlDocument::parse(string));
  124. CARLA_SAFE_ASSERT_RETURN(root != nullptr, false);
  125. CARLA_SAFE_ASSERT_RETURN(root->getTagName() == "JSFXState", false);
  126. data = JsusFxSerializationData();
  127. int numChildren = root->getNumChildElements();
  128. for (int i = 0; i < numChildren; ++i)
  129. {
  130. water::XmlElement* child = root->getChildElement(i);
  131. CARLA_SAFE_ASSERT_CONTINUE(child != nullptr);
  132. if (child->getTagName() == "Slider")
  133. {
  134. CARLA_SAFE_ASSERT_CONTINUE(child->hasAttribute("index"));
  135. CARLA_SAFE_ASSERT_CONTINUE(child->hasAttribute("value"));
  136. JsusFxSerializationData::Slider slider;
  137. slider.index = child->getIntAttribute("index");
  138. slider.value = child->getDoubleAttribute("value");
  139. data.sliders.push_back(slider);
  140. }
  141. else if (child->getTagName() == "Var")
  142. {
  143. CARLA_SAFE_ASSERT_CONTINUE(child->hasAttribute("value"));
  144. float value = child->getDoubleAttribute("value");
  145. data.vars.push_back(value);
  146. }
  147. else
  148. {
  149. CARLA_SAFE_ASSERT_CONTINUE(false);
  150. }
  151. }
  152. return true;
  153. }
  154. };
  155. // -------------------------------------------------------------------------------------------------------------------
  156. #endif // CARLA_JSFX_UTILS_HPP_INCLUDED