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.

210 lines
6.7KB

  1. /*
  2. * Carla LADSPA utils
  3. * Copyright (C) 2011-2014 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_LADSPA_UTILS_HPP_INCLUDED
  18. #define CARLA_LADSPA_UTILS_HPP_INCLUDED
  19. #include "CarlaUtils.hpp"
  20. #include "ladspa/ladspa.h"
  21. #include "ladspa_rdf.hpp"
  22. #include <cmath>
  23. // -----------------------------------------------------------------------
  24. // Copy RDF object
  25. static inline
  26. const LADSPA_RDF_Descriptor* ladspa_rdf_dup(const LADSPA_RDF_Descriptor* const oldDescriptor)
  27. {
  28. CARLA_SAFE_ASSERT_RETURN(oldDescriptor != nullptr, nullptr);
  29. LADSPA_RDF_Descriptor* const newDescriptor(new LADSPA_RDF_Descriptor());
  30. newDescriptor->Type = oldDescriptor->Type;
  31. newDescriptor->UniqueID = oldDescriptor->UniqueID;
  32. newDescriptor->PortCount = oldDescriptor->PortCount;
  33. if (oldDescriptor->Title != nullptr)
  34. newDescriptor->Title = carla_strdup(oldDescriptor->Title);
  35. if (oldDescriptor->Creator != nullptr)
  36. newDescriptor->Creator = carla_strdup(oldDescriptor->Creator);
  37. if (newDescriptor->PortCount > 0)
  38. {
  39. newDescriptor->Ports = new LADSPA_RDF_Port[newDescriptor->PortCount];
  40. for (ulong i=0; i < newDescriptor->PortCount; ++i)
  41. {
  42. LADSPA_RDF_Port* const oldPort(&oldDescriptor->Ports[i]);
  43. LADSPA_RDF_Port* const newPort(&newDescriptor->Ports[i]);
  44. newPort->Type = oldPort->Type;
  45. newPort->Hints = oldPort->Hints;
  46. newPort->Default = oldPort->Default;
  47. newPort->Unit = oldPort->Unit;
  48. newPort->ScalePointCount = oldPort->ScalePointCount;
  49. if (oldPort->Label != nullptr)
  50. newPort->Label = carla_strdup(oldPort->Label);
  51. if (oldPort->ScalePointCount > 0)
  52. {
  53. newPort->ScalePoints = new LADSPA_RDF_ScalePoint[oldPort->ScalePointCount];
  54. for (ulong j=0; j < oldPort->ScalePointCount; ++j)
  55. {
  56. LADSPA_RDF_ScalePoint* const oldScalePoint(&oldPort->ScalePoints[j]);
  57. LADSPA_RDF_ScalePoint* const newScalePoint(&newPort->ScalePoints[j]);
  58. newScalePoint->Value = oldScalePoint->Value;
  59. if (oldScalePoint->Label != nullptr)
  60. newScalePoint->Label = carla_strdup(oldScalePoint->Label);
  61. }
  62. }
  63. }
  64. }
  65. return newDescriptor;
  66. }
  67. // -----------------------------------------------------------------------
  68. // Check if 2 ports match types
  69. static inline
  70. bool is_ladspa_port_good(const LADSPA_PortDescriptor port1, const LADSPA_PortDescriptor port2) noexcept
  71. {
  72. if (port1 == 0x0 || port2 == 0x0)
  73. return false;
  74. if (LADSPA_IS_PORT_INPUT(port1) && ! LADSPA_IS_PORT_INPUT(port2))
  75. return false;
  76. if (LADSPA_IS_PORT_OUTPUT(port1) && ! LADSPA_IS_PORT_OUTPUT(port2))
  77. return false;
  78. if (LADSPA_IS_PORT_CONTROL(port1) && ! LADSPA_IS_PORT_CONTROL(port2))
  79. return false;
  80. if (LADSPA_IS_PORT_AUDIO(port1) && ! LADSPA_IS_PORT_AUDIO(port2))
  81. return false;
  82. return true;
  83. }
  84. // -----------------------------------------------------------------------
  85. // Check if rdf data matches descriptor
  86. static inline
  87. bool is_ladspa_rdf_descriptor_valid(const LADSPA_RDF_Descriptor* const rdfDescriptor, const LADSPA_Descriptor* const descriptor) noexcept
  88. {
  89. if (rdfDescriptor == nullptr || descriptor == nullptr)
  90. return false;
  91. if (rdfDescriptor->UniqueID != descriptor->UniqueID)
  92. {
  93. carla_stderr("WARNING - Plugin has wrong UniqueID: %li != %li", rdfDescriptor->UniqueID, descriptor->UniqueID);
  94. return false;
  95. }
  96. if (rdfDescriptor->PortCount > descriptor->PortCount)
  97. {
  98. carla_stderr("WARNING - Plugin has RDF data, but invalid PortCount: %li > %li", rdfDescriptor->PortCount, descriptor->PortCount);
  99. return false;
  100. }
  101. for (ulong i=0; i < rdfDescriptor->PortCount; ++i)
  102. {
  103. // no type set, ignore
  104. if (rdfDescriptor->Ports[i].Type == 0)
  105. continue;
  106. if (! is_ladspa_port_good(rdfDescriptor->Ports[i].Type, descriptor->PortDescriptors[i]))
  107. {
  108. carla_stderr("WARNING - Plugin has RDF data, but invalid PortTypes: %i != %i", rdfDescriptor->Ports[i].Type, descriptor->PortDescriptors[i]);
  109. return false;
  110. }
  111. }
  112. return true;
  113. }
  114. // -----------------------------------------------------------------------
  115. // Get default control port value
  116. static inline
  117. LADSPA_Data get_default_ladspa_port_value(const LADSPA_PortRangeHintDescriptor hintDescriptor, const LADSPA_Data min, const LADSPA_Data max) noexcept
  118. {
  119. if (LADSPA_IS_HINT_HAS_DEFAULT(hintDescriptor))
  120. {
  121. switch (hintDescriptor & LADSPA_HINT_DEFAULT_MASK)
  122. {
  123. case LADSPA_HINT_DEFAULT_MINIMUM:
  124. return min;
  125. case LADSPA_HINT_DEFAULT_MAXIMUM:
  126. return max;
  127. case LADSPA_HINT_DEFAULT_0:
  128. return 0.0f;
  129. case LADSPA_HINT_DEFAULT_1:
  130. return 1.0f;
  131. case LADSPA_HINT_DEFAULT_100:
  132. return 100.0f;
  133. case LADSPA_HINT_DEFAULT_440:
  134. return 440.0f;
  135. case LADSPA_HINT_DEFAULT_LOW:
  136. if (LADSPA_IS_HINT_LOGARITHMIC(hintDescriptor))
  137. {
  138. try {
  139. return std::exp((std::log(min)*0.75f) + (std::log(max)*0.25f));
  140. } CARLA_SAFE_EXCEPTION("exp(log)");
  141. }
  142. return (min*0.75f) + (max*0.25f);
  143. case LADSPA_HINT_DEFAULT_MIDDLE:
  144. if (LADSPA_IS_HINT_LOGARITHMIC(hintDescriptor))
  145. {
  146. try {
  147. return std::sqrt(min*max);
  148. } CARLA_SAFE_EXCEPTION("sqrt");
  149. }
  150. return (min+max)/2;
  151. case LADSPA_HINT_DEFAULT_HIGH:
  152. if (LADSPA_IS_HINT_LOGARITHMIC(hintDescriptor))
  153. {
  154. try {
  155. return std::exp((std::log(min)*0.25f) + (std::log(max)*0.75f));
  156. } CARLA_SAFE_EXCEPTION("exp(log)");
  157. }
  158. return (min*0.25f) + (max*0.75f);
  159. }
  160. }
  161. // no default value
  162. if (min < 0.0f && max > 0.0f)
  163. return 0.0f;
  164. return min;
  165. }
  166. // -----------------------------------------------------------------------
  167. #endif // CARLA_LADSPA_UTILS_HPP_INCLUDED