Fix last commit
[carla.git] / source / utils / CarlaLadspaUtils.hpp
blob74803821ac7321f94aa58547d86dc5beb90f49f6
1 /*
2 * Carla LADSPA utils
3 * Copyright (C) 2011-2014 Filipe Coelho <falktx@falktx.com>
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.
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.
15 * For a full copy of the GNU General Public License see the doc/GPL.txt file.
18 #ifndef CARLA_LADSPA_UTILS_HPP_INCLUDED
19 #define CARLA_LADSPA_UTILS_HPP_INCLUDED
21 #include "CarlaUtils.hpp"
23 #include "ladspa/ladspa.h"
24 #include "ladspa_rdf.hpp"
26 #include <cmath>
28 // -----------------------------------------------------------------------
29 // Copy RDF object
31 static inline
32 const LADSPA_RDF_Descriptor* ladspa_rdf_dup(const LADSPA_RDF_Descriptor* const oldDescriptor)
34 CARLA_SAFE_ASSERT_RETURN(oldDescriptor != nullptr, nullptr);
36 LADSPA_RDF_Descriptor* const newDescriptor(new LADSPA_RDF_Descriptor());
38 newDescriptor->Type = oldDescriptor->Type;
39 newDescriptor->UniqueID = oldDescriptor->UniqueID;
40 newDescriptor->PortCount = oldDescriptor->PortCount;
42 if (oldDescriptor->Title != nullptr)
43 newDescriptor->Title = carla_strdup(oldDescriptor->Title);
45 if (oldDescriptor->Creator != nullptr)
46 newDescriptor->Creator = carla_strdup(oldDescriptor->Creator);
48 if (newDescriptor->PortCount > 0)
50 newDescriptor->Ports = new LADSPA_RDF_Port[newDescriptor->PortCount];
52 for (ulong i=0; i < newDescriptor->PortCount; ++i)
54 LADSPA_RDF_Port* const oldPort(&oldDescriptor->Ports[i]);
55 LADSPA_RDF_Port* const newPort(&newDescriptor->Ports[i]);
57 newPort->Type = oldPort->Type;
58 newPort->Hints = oldPort->Hints;
59 newPort->Default = oldPort->Default;
60 newPort->Unit = oldPort->Unit;
61 newPort->ScalePointCount = oldPort->ScalePointCount;
63 if (oldPort->Label != nullptr)
64 newPort->Label = carla_strdup(oldPort->Label);
66 if (oldPort->ScalePointCount > 0)
68 newPort->ScalePoints = new LADSPA_RDF_ScalePoint[oldPort->ScalePointCount];
70 for (ulong j=0; j < oldPort->ScalePointCount; ++j)
72 LADSPA_RDF_ScalePoint* const oldScalePoint(&oldPort->ScalePoints[j]);
73 LADSPA_RDF_ScalePoint* const newScalePoint(&newPort->ScalePoints[j]);
75 newScalePoint->Value = oldScalePoint->Value;
77 if (oldScalePoint->Label != nullptr)
78 newScalePoint->Label = carla_strdup(oldScalePoint->Label);
84 return newDescriptor;
87 // -----------------------------------------------------------------------
88 // Check if 2 ports match types
90 static inline
91 bool is_ladspa_port_good(const LADSPA_PortDescriptor port1, const LADSPA_PortDescriptor port2) noexcept
93 if (port1 == 0x0 || port2 == 0x0)
94 return false;
95 if (LADSPA_IS_PORT_INPUT(port1) && ! LADSPA_IS_PORT_INPUT(port2))
96 return false;
97 if (LADSPA_IS_PORT_OUTPUT(port1) && ! LADSPA_IS_PORT_OUTPUT(port2))
98 return false;
99 if (LADSPA_IS_PORT_CONTROL(port1) && ! LADSPA_IS_PORT_CONTROL(port2))
100 return false;
101 if (LADSPA_IS_PORT_AUDIO(port1) && ! LADSPA_IS_PORT_AUDIO(port2))
102 return false;
103 return true;
106 // -----------------------------------------------------------------------
107 // Check if rdf data matches descriptor
109 static inline
110 bool is_ladspa_rdf_descriptor_valid(const LADSPA_RDF_Descriptor* const rdfDescriptor, const LADSPA_Descriptor* const descriptor) noexcept
112 if (rdfDescriptor == nullptr || descriptor == nullptr)
113 return false;
115 if (rdfDescriptor->UniqueID != descriptor->UniqueID)
117 carla_stderr("WARNING - Plugin has wrong UniqueID: %li != %li", rdfDescriptor->UniqueID, descriptor->UniqueID);
118 return false;
121 if (rdfDescriptor->PortCount > descriptor->PortCount)
123 carla_stderr("WARNING - Plugin has RDF data, but invalid PortCount: %li > %li", rdfDescriptor->PortCount, descriptor->PortCount);
124 return false;
127 for (ulong i=0; i < rdfDescriptor->PortCount; ++i)
129 // no type set, ignore
130 if (rdfDescriptor->Ports[i].Type == 0)
131 continue;
133 if (! is_ladspa_port_good(rdfDescriptor->Ports[i].Type, descriptor->PortDescriptors[i]))
135 carla_stderr("WARNING - Plugin has RDF data, but invalid PortTypes: %i != %i", rdfDescriptor->Ports[i].Type, descriptor->PortDescriptors[i]);
136 return false;
140 return true;
143 // -----------------------------------------------------------------------
144 // Get default control port value
146 static inline
147 LADSPA_Data get_default_ladspa_port_value(const LADSPA_PortRangeHintDescriptor hintDescriptor, const LADSPA_Data min, const LADSPA_Data max) noexcept
149 if (LADSPA_IS_HINT_HAS_DEFAULT(hintDescriptor))
151 switch (hintDescriptor & LADSPA_HINT_DEFAULT_MASK)
153 case LADSPA_HINT_DEFAULT_MINIMUM:
154 return min;
156 case LADSPA_HINT_DEFAULT_MAXIMUM:
157 return max;
159 case LADSPA_HINT_DEFAULT_0:
160 return 0.0f;
162 case LADSPA_HINT_DEFAULT_1:
163 return 1.0f;
165 case LADSPA_HINT_DEFAULT_100:
166 return 100.0f;
168 case LADSPA_HINT_DEFAULT_440:
169 return 440.0f;
171 case LADSPA_HINT_DEFAULT_LOW:
172 if (LADSPA_IS_HINT_LOGARITHMIC(hintDescriptor))
174 try {
175 return std::exp((std::log(min)*0.75f) + (std::log(max)*0.25f));
176 } CARLA_SAFE_EXCEPTION("exp(log)");
178 return (min*0.75f) + (max*0.25f);
180 case LADSPA_HINT_DEFAULT_MIDDLE:
181 if (LADSPA_IS_HINT_LOGARITHMIC(hintDescriptor))
183 try {
184 return std::sqrt(min*max);
185 } CARLA_SAFE_EXCEPTION("sqrt");
187 return (min+max)/2;
189 case LADSPA_HINT_DEFAULT_HIGH:
190 if (LADSPA_IS_HINT_LOGARITHMIC(hintDescriptor))
192 try {
193 return std::exp((std::log(min)*0.25f) + (std::log(max)*0.75f));
194 } CARLA_SAFE_EXCEPTION("exp(log)");
196 return (min*0.25f) + (max*0.75f);
200 // no default value
201 if (min < 0.0f && max > 0.0f)
202 return 0.0f;
204 return min;
207 // -----------------------------------------------------------------------
209 #endif // CARLA_LADSPA_UTILS_HPP_INCLUDED