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.

186 lines
5.4KB

  1. /*
  2. * Carla JSFX utils
  3. * Copyright (C) 2021 Jean Pierre Cimalando
  4. * Copyright (C) 2021-2022 Filipe Coelho <falktx@falktx.com>
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License as
  8. * published by the Free Software Foundation; either version 2 of
  9. * the License, or any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * For a full copy of the GNU General Public License see the doc/GPL.txt file.
  17. */
  18. #ifndef CARLA_JSFX_UTILS_HPP_INCLUDED
  19. #define CARLA_JSFX_UTILS_HPP_INCLUDED
  20. #include "CarlaDefines.h"
  21. #include "CarlaBackend.h"
  22. #include "CarlaUtils.hpp"
  23. #include "CarlaJuceUtils.hpp"
  24. #include "water/files/File.h"
  25. #include "water/text/String.h"
  26. #ifdef YSFX_API
  27. # error YSFX_API is not private
  28. #endif
  29. #include "ysfx/include/ysfx.h"
  30. #include <memory>
  31. CARLA_BACKEND_START_NAMESPACE
  32. // --------------------------------------------------------------------------------------------------------------------
  33. struct CarlaJsfxLogging
  34. {
  35. static void logAll(intptr_t, const ysfx_log_level level, const char* const message)
  36. {
  37. switch (level)
  38. {
  39. case ysfx_log_info:
  40. carla_stdout("%s: %s", ysfx_log_level_string(level), message);
  41. break;
  42. case ysfx_log_warning:
  43. carla_stderr("%s: %s", ysfx_log_level_string(level), message);
  44. break;
  45. case ysfx_log_error:
  46. carla_stderr2("%s: %s", ysfx_log_level_string(level), message);
  47. break;
  48. }
  49. };
  50. static void logErrorsOnly(intptr_t, const ysfx_log_level level, const char* const message)
  51. {
  52. switch (level)
  53. {
  54. case ysfx_log_info:
  55. break;
  56. case ysfx_log_warning:
  57. carla_stderr("%s: %s", ysfx_log_level_string(level), message);
  58. break;
  59. case ysfx_log_error:
  60. carla_stderr2("%s: %s", ysfx_log_level_string(level), message);
  61. break;
  62. }
  63. };
  64. };
  65. // --------------------------------------------------------------------------------------------------------------------
  66. struct CarlaJsfxCategories
  67. {
  68. static PluginCategory getFromEffect(ysfx_t* effect)
  69. {
  70. PluginCategory category = PLUGIN_CATEGORY_OTHER;
  71. if (const uint32_t tagCount = ysfx_get_tags(effect, nullptr, 0))
  72. {
  73. std::vector<const char*> tags;
  74. tags.resize(tagCount);
  75. ysfx_get_tags(effect, tags.data(), tagCount);
  76. for (uint32_t i=0; i<tagCount && category == PLUGIN_CATEGORY_OTHER; ++i)
  77. {
  78. water::CharPointer_UTF8 tag(tags[i]);
  79. PluginCategory current = getFromTag(tag);
  80. if (current != PLUGIN_CATEGORY_NONE)
  81. category = current;
  82. }
  83. }
  84. return category;
  85. }
  86. static PluginCategory getFromTag(const water::CharPointer_UTF8 tag)
  87. {
  88. if (tag.compareIgnoreCase(water::CharPointer_UTF8("synthesis")) == 0)
  89. return PLUGIN_CATEGORY_SYNTH;
  90. if (tag.compareIgnoreCase(water::CharPointer_UTF8("delay")) == 0)
  91. return PLUGIN_CATEGORY_DELAY;
  92. if (tag.compareIgnoreCase(water::CharPointer_UTF8("equalizer")) == 0)
  93. return PLUGIN_CATEGORY_EQ;
  94. if (tag.compareIgnoreCase(water::CharPointer_UTF8("filter")) == 0)
  95. return PLUGIN_CATEGORY_FILTER;
  96. if (tag.compareIgnoreCase(water::CharPointer_UTF8("distortion")) == 0)
  97. return PLUGIN_CATEGORY_DISTORTION;
  98. if (tag.compareIgnoreCase(water::CharPointer_UTF8("dynamics")) == 0)
  99. return PLUGIN_CATEGORY_DYNAMICS;
  100. if (tag.compareIgnoreCase(water::CharPointer_UTF8("modulation")) == 0)
  101. return PLUGIN_CATEGORY_MODULATOR;
  102. if (tag.compareIgnoreCase(water::CharPointer_UTF8("utility")) == 0)
  103. return PLUGIN_CATEGORY_UTILITY;
  104. return PLUGIN_CATEGORY_NONE;
  105. }
  106. };
  107. // --------------------------------------------------------------------------------------------------------------------
  108. class CarlaJsfxUnit
  109. {
  110. static water::String createFileId(const water::File& rootPath, const water::File& filePath)
  111. {
  112. water::String fileId(filePath.getRelativePathFrom(rootPath));
  113. #ifdef CARLA_OS_WIN
  114. fileId.replaceCharacter('\\', '/');
  115. #endif
  116. return fileId;
  117. }
  118. public:
  119. CarlaJsfxUnit() noexcept
  120. : fFileId(),
  121. fFilePath(),
  122. fRootPath() {}
  123. CarlaJsfxUnit(const water::File& rootPath, const water::File& filePath)
  124. : fFileId(createFileId(rootPath, filePath)),
  125. fFilePath(rootPath.getChildFile(fFileId).getFullPathName()),
  126. fRootPath(rootPath.getFullPathName()) {}
  127. explicit operator bool() const noexcept
  128. {
  129. return fFileId.isNotEmpty();
  130. }
  131. const water::String& getFileId() const noexcept
  132. {
  133. return fFileId;
  134. }
  135. const water::String& getFilePath() const noexcept
  136. {
  137. return fFilePath;
  138. }
  139. const water::String& getRootPath() const noexcept
  140. {
  141. return fRootPath;
  142. }
  143. private:
  144. water::String fFileId;
  145. water::String fFilePath;
  146. water::String fRootPath;
  147. };
  148. // --------------------------------------------------------------------------------------------------------------------
  149. CARLA_BACKEND_END_NAMESPACE
  150. #endif // CARLA_JSFX_UTILS_HPP_INCLUDED