3 * Copyright (C) 2012-2022 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 #include "CarlaDefines.h"
20 #include "CarlaMathUtils.hpp"
21 #include "CarlaNativeExtUI.hpp"
23 #include "water/maths/MathsFunctions.h"
25 using water::roundToIntAccurate
;
27 // -----------------------------------------------------------------------
29 class BigMeterPlugin
: public NativePluginAndUiClass
32 BigMeterPlugin(const NativeHostDescriptor
* const host
)
33 : NativePluginAndUiClass(host
, "bigmeter-ui"),
41 // -------------------------------------------------------------------
42 // Plugin parameter calls
44 uint32_t getParameterCount() const override
49 const NativeParameter
* getParameterInfo(const uint32_t index
) const override
51 CARLA_SAFE_ASSERT_RETURN(index
< 4, nullptr);
53 static NativeParameter param
;
54 static NativeParameterScalePoint scalePoints
[3];
56 int hints
= NATIVE_PARAMETER_IS_ENABLED
|NATIVE_PARAMETER_IS_AUTOMATABLE
;
60 param
.ranges
.def
= 0.0f
;
61 param
.ranges
.min
= 0.0f
;
62 param
.ranges
.max
= 1.0f
;
63 param
.ranges
.step
= 1.0f
;
64 param
.ranges
.stepSmall
= 1.0f
;
65 param
.ranges
.stepLarge
= 1.0f
;
66 param
.scalePointCount
= 0;
67 param
.scalePoints
= nullptr;
72 hints
|= NATIVE_PARAMETER_IS_INTEGER
|NATIVE_PARAMETER_USES_SCALEPOINTS
;
74 param
.ranges
.def
= 1.0f
;
75 param
.ranges
.min
= 1.0f
;
76 param
.ranges
.max
= 2.0f
;
77 scalePoints
[0].value
= 1.0f
;
78 scalePoints
[0].label
= "Green";
79 scalePoints
[1].value
= 2.0f
;
80 scalePoints
[1].label
= "Blue";
81 param
.scalePointCount
= 2;
82 param
.scalePoints
= scalePoints
;
85 hints
|= NATIVE_PARAMETER_IS_INTEGER
|NATIVE_PARAMETER_USES_SCALEPOINTS
;
87 param
.ranges
.def
= 1.0f
;
88 param
.ranges
.min
= 1.0f
;
89 param
.ranges
.max
= 3.0f
;
90 scalePoints
[0].value
= 1.0f
;
91 scalePoints
[0].label
= "Default";
92 scalePoints
[1].value
= 2.0f
;
93 scalePoints
[1].label
= "OpenAV";
94 scalePoints
[2].value
= 3.0f
;
95 scalePoints
[2].label
= "RNCBC";
96 param
.scalePointCount
= 3;
97 param
.scalePoints
= scalePoints
;
100 hints
|= NATIVE_PARAMETER_IS_OUTPUT
;
101 param
.name
= "Out Left";
104 hints
|= NATIVE_PARAMETER_IS_OUTPUT
;
105 param
.name
= "Out Right";
109 param
.hints
= static_cast<NativeParameterHints
>(hints
);
114 float getParameterValue(const uint32_t index
) const override
119 return float(fColor
);
121 return float(fStyle
);
131 // -------------------------------------------------------------------
132 // Plugin state calls
134 void setParameterValue(const uint32_t index
, const float value
) override
139 fColor
= roundToIntAccurate(value
);
142 fStyle
= roundToIntAccurate(value
);
149 // -------------------------------------------------------------------
150 // Plugin process calls
152 void activate() override
158 void process(const float* const* inputs
, float**, const uint32_t frames
,
159 const NativeMidiEvent
* const, const uint32_t) override
161 fOutLeft
= carla_findMaxNormalizedFloat(inputs
[0], frames
);
162 fOutRight
= carla_findMaxNormalizedFloat(inputs
[1], frames
);
164 bool needsInlineRender
= fInlineDisplay
.pending
< 0;
166 if (carla_isNotEqual(fOutLeft
, fInlineDisplay
.lastLeft
))
168 fInlineDisplay
.lastLeft
= fOutLeft
;
169 needsInlineRender
= true;
172 if (carla_isNotEqual(fOutRight
, fInlineDisplay
.lastRight
))
174 fInlineDisplay
.lastRight
= fOutRight
;
175 needsInlineRender
= true;
178 if (needsInlineRender
&& fInlineDisplay
.pending
!= 1 && fInlineDisplay
.pending
!= 2)
180 fInlineDisplay
.pending
= 1;
185 // -------------------------------------------------------------------
186 // Plugin dispatcher calls
190 if (fInlineDisplay
.pending
== 1)
192 fInlineDisplay
.pending
= 2;
193 hostQueueDrawInlineDisplay();
197 const NativeInlineDisplayImageSurface
* renderInlineDisplay(const uint32_t rwidth
, const uint32_t height
) override
199 CARLA_SAFE_ASSERT_RETURN(rwidth
> 0 && height
> 0, nullptr);
201 const uint32_t width
= rwidth
== height
? height
/ 6 : rwidth
;
202 const size_t stride
= width
* 4;
203 const size_t dataSize
= stride
* height
;
205 uchar
* data
= fInlineDisplay
.data
;
207 if (fInlineDisplay
.dataSize
< dataSize
|| data
== nullptr)
210 data
= new uchar
[dataSize
];
211 std::memset(data
, 0, dataSize
);
212 fInlineDisplay
.data
= data
;
213 fInlineDisplay
.dataSize
= dataSize
;
216 std::memset(data
, 0, dataSize
);
218 fInlineDisplay
.width
= static_cast<int>(width
);
219 fInlineDisplay
.height
= static_cast<int>(height
);
220 fInlineDisplay
.stride
= static_cast<int>(stride
);
222 const uint heightValueLeft
= static_cast<uint
>(fInlineDisplay
.lastLeft
* static_cast<float>(height
));
223 const uint heightValueRight
= static_cast<uint
>(fInlineDisplay
.lastRight
* static_cast<float>(height
));
225 for (uint h
=0; h
< height
; ++h
)
227 for (uint w
=0; w
< width
; ++w
)
229 // data[h * stride + w * 4 + 0] = 0;
230 // data[h * stride + w * 4 + 1] = 255;
231 // data[h * stride + w * 4 + 2] = 0;
232 data
[h
* stride
+ w
* 4 + 3] = 160;
236 for (uint h
=0; h
< heightValueLeft
; ++h
)
238 const uint h2
= height
- h
- 1;
240 for (uint w
=0; w
< width
/ 2; ++w
)
242 data
[h2
* stride
+ w
* 4 + 0] = 200;
243 data
[h2
* stride
+ w
* 4 + 1] = 0;
244 data
[h2
* stride
+ w
* 4 + 2] = 0;
245 data
[h2
* stride
+ w
* 4 + 3] = 255;
249 for (uint h
=0; h
< heightValueRight
; ++h
)
251 const uint h2
= height
- h
- 1;
253 for (uint w
=width
/ 2; w
< width
; ++w
)
255 data
[h2
* stride
+ w
* 4 + 0] = 200;
256 data
[h2
* stride
+ w
* 4 + 1] = 0;
257 data
[h2
* stride
+ w
* 4 + 2] = 0;
258 data
[h2
* stride
+ w
* 4 + 3] = 255;
263 for (uint w
=0; w
< width
; ++w
)
265 // data[w * 4 + 0] = 0;
266 // data[w * 4 + 1] = 0;
267 // data[w * 4 + 2] = 255;
268 data
[w
* 4 + 3] = 120;
270 // data[(height - 1) * stride + w * 4 + 0] = 0;
271 // data[(height - 1) * stride + w * 4 + 1] = 0;
272 // data[(height - 1) * stride + w * 4 + 2] = 255;
273 data
[(height
- 1) * stride
+ w
* 4 + 3] = 120;
276 for (uint h
=0; h
< height
; ++h
)
278 // data[h * stride + 0] = 0;
279 // data[h * stride + 1] = 0;
280 // data[h * stride + 2] = 255;
281 data
[h
* stride
+ 3] = 120;
283 data
[h
* stride
+ (width
/ 2) * 4 + 0] = 0;
284 data
[h
* stride
+ (width
/ 2) * 4 + 1] = 0;
285 data
[h
* stride
+ (width
/ 2) * 4 + 2] = 0;
286 data
[h
* stride
+ (width
/ 2) * 4 + 3] = 160;
288 // data[h * stride + (width - 1) * 4 + 0] = 0;
289 // data[h * stride + (width - 1) * 4 + 1] = 0;
290 // data[h * stride + (width - 1) * 4 + 2] = 255;
291 data
[h
* stride
+ (width
- 1) * 4 + 3] = 120;
294 fInlineDisplay
.pending
= rwidth
== height
? -1 : 0;
295 return (NativeInlineDisplayImageSurface
*)(NativeInlineDisplayImageSurfaceCompat
*)&fInlineDisplay
;
300 float fOutLeft
, fOutRight
;
302 struct InlineDisplay
: NativeInlineDisplayImageSurfaceCompat
{
305 volatile int pending
;
308 : NativeInlineDisplayImageSurfaceCompat(),
322 CARLA_DECLARE_NON_COPYABLE(InlineDisplay
)
323 CARLA_PREVENT_HEAP_ALLOCATION
326 PluginClassEND(BigMeterPlugin
)
327 CARLA_DECLARE_NON_COPYABLE(BigMeterPlugin
)
330 // -----------------------------------------------------------------------
332 static const NativePluginDescriptor bigmeterDesc
= {
333 /* category */ NATIVE_PLUGIN_CATEGORY_UTILITY
,
334 /* hints */ static_cast<NativePluginHints
>(NATIVE_PLUGIN_IS_RTSAFE
335 |NATIVE_PLUGIN_HAS_INLINE_DISPLAY
336 |NATIVE_PLUGIN_HAS_UI
337 |NATIVE_PLUGIN_REQUESTS_IDLE
),
338 /* supports */ NATIVE_PLUGIN_SUPPORTS_NOTHING
,
345 /* name */ "Big Meter",
346 /* label */ "bigmeter",
347 /* maker */ "falkTX",
348 /* copyright */ "GNU GPL v2+",
349 PluginDescriptorFILL(BigMeterPlugin
)
352 // -----------------------------------------------------------------------
355 void carla_register_native_plugin_bigmeter();
358 void carla_register_native_plugin_bigmeter()
360 carla_register_native_plugin(&bigmeterDesc
);
363 // -----------------------------------------------------------------------