Skip to content

Commit 50b51f5

Browse files
committed
juce_audio_processors_headless: Remove juce_graphics dependency
1 parent 86123ae commit 50b51f5

File tree

12 files changed

+170
-136
lines changed

12 files changed

+170
-136
lines changed

BREAKING_CHANGES.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,28 @@
22

33
# Version 8.0.9
44

5+
## Change
6+
7+
AudioProcessor::TrackProperties::colour has been removed. It is replaced by a
8+
new data member, colourARGB.
9+
10+
**Possible Issues**
11+
12+
Code that references this data member will fail to compile.
13+
14+
**Workaround**
15+
16+
Use the new colourARGB field, which holds the raw ARGB values packed in a
17+
uint32, instead. In order to convert to a Colour instance, pass the value held
18+
by colourARGB to the constructor of Colour.
19+
20+
**Rationale**
21+
22+
This change removes the dependency between the juce_audio_processors_headless
23+
and juce_graphics. It is now possible to build programs that work with headless
24+
AudioProcessors without needing to include juce_graphics.
25+
26+
527
## Change
628

729
The function AudioPluginFormatManager::addDefaultFormats() has been removed.

examples/Plugins/ARAPluginDemo.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1440,7 +1440,7 @@ class PlaybackRegionView final : public Component,
14401440

14411441
void paint (Graphics& g) override
14421442
{
1443-
g.fillAll (convertOptionalARAColour (playbackRegion.getEffectiveColor(), Colours::black));
1443+
g.fillAll (Colour { convertOptionalARAColour (playbackRegion.getEffectiveColor()) });
14441444

14451445
const auto* audioModification = playbackRegion.getAudioModification<ARADemoPluginAudioModification>();
14461446
g.setColour (audioModification->isDimmed() ? Colours::darkgrey.darker() : Colours::darkgrey.brighter());
@@ -1827,7 +1827,7 @@ class TrackHeader final : public Component,
18271827

18281828
if (auto colour = regionSequence.getColor())
18291829
{
1830-
g.setColour (convertARAColour (colour));
1830+
g.setColour (Colour { convertARAColourARGB (colour) });
18311831
g.fillRect (getLocalBounds().removeFromTop (16).reduced (6));
18321832
g.fillRect (getLocalBounds().removeFromBottom (16).reduced (6));
18331833
}

examples/Plugins/AudioPluginDemo.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -468,10 +468,10 @@ class JuceDemoPluginAudioProcessor final : public AudioProcessor
468468

469469
void updateTrackProperties()
470470
{
471-
auto trackColour = getProcessor().getTrackProperties().colour;
471+
auto trackColour = getProcessor().getTrackProperties().colourARGB;
472472
auto& lf = getLookAndFeel();
473473

474-
backgroundColour = (trackColour.has_value() ? trackColour->withAlpha (1.0f).withBrightness (0.266f)
474+
backgroundColour = (trackColour.has_value() ? Colour { *trackColour }.withAlpha (1.0f).withBrightness (0.266f)
475475
: lf.findColour (ResizableWindow::backgroundColourId));
476476
repaint();
477477
}

modules/juce_audio_plugin_client/juce_audio_plugin_client_VST3.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,8 +1158,7 @@ class JuceVST3EditController final : public Vst::EditController,
11581158
{
11591159
Steinberg::int64 colour;
11601160
if (list->getInt (Vst::ChannelContext::kChannelColorKey, colour) == kResultTrue)
1161-
trackProperties.colour = std::make_optional (Colour (Vst::ChannelContext::GetRed ((uint32) colour), Vst::ChannelContext::GetGreen ((uint32) colour),
1162-
Vst::ChannelContext::GetBlue ((uint32) colour), Vst::ChannelContext::GetAlpha ((uint32) colour)));
1161+
trackProperties.colourARGB.emplace ((uint32) colour);
11631162
}
11641163

11651164

modules/juce_audio_processors/format_types/juce_LV2PluginFormat.cpp

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,125 @@ namespace juce
4343
namespace lv2_host
4444
{
4545

46+
class UiFeaturesData
47+
{
48+
public:
49+
UiFeaturesData (PhysicalResizeListener& rl,
50+
TouchListener& tl,
51+
LV2_Handle instanceIn,
52+
LV2UI_Widget parentIn,
53+
Instance::GetExtensionData getExtensionData,
54+
const Ports& ports,
55+
SymbolMap& symapIn,
56+
const UiFeaturesDataOptions& optIn)
57+
: opts (optIn),
58+
resizeListener (rl),
59+
touchListener (tl),
60+
instance (instanceIn),
61+
parent (parentIn),
62+
symap (symapIn),
63+
dataAccess { getExtensionData },
64+
portIndices (makePortIndices (ports))
65+
{
66+
}
67+
68+
const LV2_Feature* const* getFeatureArray() const noexcept { return features.pointers.data(); }
69+
70+
Rectangle<int> getLastRequestedBounds() const { return { lastRequestedWidth, lastRequestedHeight }; }
71+
72+
private:
73+
int resizeCallback (int width, int height)
74+
{
75+
lastRequestedWidth = width;
76+
lastRequestedHeight = height;
77+
resizeListener.viewRequestedResizeInPhysicalPixels (width, height);
78+
return 0;
79+
}
80+
81+
static int resizeCallback (LV2UI_Feature_Handle handle, int width, int height)
82+
{
83+
return static_cast<UiFeaturesData*> (handle)->resizeCallback (width, height);
84+
}
85+
86+
uint32_t portIndexCallback (const char* symbol) const
87+
{
88+
const auto it = portIndices.find (symbol);
89+
return it != portIndices.cend() ? it->second : LV2UI_INVALID_PORT_INDEX;
90+
}
91+
92+
static uint32_t portIndexCallback (LV2UI_Feature_Handle handle, const char* symbol)
93+
{
94+
return static_cast<const UiFeaturesData*> (handle)->portIndexCallback (symbol);
95+
}
96+
97+
void touchCallback (uint32_t portIndex, bool grabbed) const
98+
{
99+
touchListener.controlGrabbed (portIndex, grabbed);
100+
}
101+
102+
static void touchCallback (LV2UI_Feature_Handle handle, uint32_t index, bool b)
103+
{
104+
return static_cast<const UiFeaturesData*> (handle)->touchCallback (index, b);
105+
}
106+
107+
static std::map<String, uint32_t> makePortIndices (const Ports& ports)
108+
{
109+
std::map<String, uint32_t> result;
110+
111+
ports.forEachPort ([&] (const PortHeader& header)
112+
{
113+
[[maybe_unused]] const auto emplaced = result.emplace (header.symbol, header.index);
114+
115+
// This will complain if there are duplicate port symbols.
116+
jassert (emplaced.second);
117+
});
118+
119+
return result;
120+
}
121+
122+
const UiFeaturesDataOptions opts;
123+
PhysicalResizeListener& resizeListener;
124+
TouchListener& touchListener;
125+
LV2_Handle instance{};
126+
LV2UI_Widget parent{};
127+
SymbolMap& symap;
128+
const UsefulUrids urids { symap };
129+
Log log { &urids };
130+
int lastRequestedWidth = 0, lastRequestedHeight = 0;
131+
std::vector<LV2_Options_Option> options { { LV2_OPTIONS_INSTANCE,
132+
0,
133+
symap.map (LV2_UI__scaleFactor),
134+
sizeof (float),
135+
symap.map (LV2_ATOM__Float),
136+
&opts.initialScaleFactor },
137+
{ LV2_OPTIONS_INSTANCE,
138+
0,
139+
symap.map (LV2_PARAMETERS__sampleRate),
140+
sizeof (float),
141+
symap.map (LV2_ATOM__Float),
142+
&opts.sampleRate },
143+
{ LV2_OPTIONS_INSTANCE, 0, 0, 0, 0, nullptr } }; // The final entry must be nulled out
144+
LV2UI_Resize resize { this, resizeCallback };
145+
LV2_URID_Map map = symap.getMapFeature();
146+
LV2_URID_Unmap unmap = symap.getUnmapFeature();
147+
LV2UI_Port_Map portMap { this, portIndexCallback };
148+
LV2UI_Touch touch { this, touchCallback };
149+
LV2_Extension_Data_Feature dataAccess;
150+
std::map<String, uint32_t> portIndices;
151+
Features features { UiFeatureUris::makeFeatures (&resize,
152+
parent,
153+
instance,
154+
&dataAccess,
155+
&map,
156+
&unmap,
157+
&portMap,
158+
&touch,
159+
options.data(),
160+
log.getLogFeature()) };
161+
162+
JUCE_LEAK_DETECTOR (UiFeaturesData)
163+
};
164+
46165
/*
47166
Creates and holds a UI instance for a plugin with a specific URI, using the provided descriptor.
48167
*/

modules/juce_audio_processors_headless/format_types/juce_LV2PluginFormatImpl.h

Lines changed: 2 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -2613,38 +2613,14 @@ class UiFeaturesDataOptions
26132613
}
26142614
};
26152615

2616-
class UiFeaturesData
2616+
class UiFeatureUris
26172617
{
26182618
public:
2619-
UiFeaturesData (PhysicalResizeListener& rl,
2620-
TouchListener& tl,
2621-
LV2_Handle instanceIn,
2622-
LV2UI_Widget parentIn,
2623-
Instance::GetExtensionData getExtensionData,
2624-
const Ports& ports,
2625-
SymbolMap& symapIn,
2626-
const UiFeaturesDataOptions& optIn)
2627-
: opts (optIn),
2628-
resizeListener (rl),
2629-
touchListener (tl),
2630-
instance (instanceIn),
2631-
parent (parentIn),
2632-
symap (symapIn),
2633-
dataAccess { getExtensionData },
2634-
portIndices (makePortIndices (ports))
2635-
{
2636-
}
2637-
2638-
const LV2_Feature* const* getFeatureArray() const noexcept { return features.pointers.data(); }
2639-
26402619
static std::vector<String> getFeatureUris()
26412620
{
26422621
return Features::getUris (makeFeatures ({}, {}, {}, {}, {}, {}, {}, {}, {}, {}));
26432622
}
26442623

2645-
Rectangle<int> getLastRequestedBounds() const { return { lastRequestedWidth, lastRequestedHeight }; }
2646-
2647-
private:
26482624
static std::vector<LV2_Feature> makeFeatures (LV2UI_Resize* resize,
26492625
LV2UI_Widget parent,
26502626
LV2_Handle handle,
@@ -2668,97 +2644,6 @@ class UiFeaturesData
26682644
LV2_Feature { LV2_OPTIONS__options, options },
26692645
LV2_Feature { LV2_LOG__log, log } };
26702646
}
2671-
2672-
int resizeCallback (int width, int height)
2673-
{
2674-
lastRequestedWidth = width;
2675-
lastRequestedHeight = height;
2676-
resizeListener.viewRequestedResizeInPhysicalPixels (width, height);
2677-
return 0;
2678-
}
2679-
2680-
static int resizeCallback (LV2UI_Feature_Handle handle, int width, int height)
2681-
{
2682-
return static_cast<UiFeaturesData*> (handle)->resizeCallback (width, height);
2683-
}
2684-
2685-
uint32_t portIndexCallback (const char* symbol) const
2686-
{
2687-
const auto it = portIndices.find (symbol);
2688-
return it != portIndices.cend() ? it->second : LV2UI_INVALID_PORT_INDEX;
2689-
}
2690-
2691-
static uint32_t portIndexCallback (LV2UI_Feature_Handle handle, const char* symbol)
2692-
{
2693-
return static_cast<const UiFeaturesData*> (handle)->portIndexCallback (symbol);
2694-
}
2695-
2696-
void touchCallback (uint32_t portIndex, bool grabbed) const
2697-
{
2698-
touchListener.controlGrabbed (portIndex, grabbed);
2699-
}
2700-
2701-
static void touchCallback (LV2UI_Feature_Handle handle, uint32_t index, bool b)
2702-
{
2703-
return static_cast<const UiFeaturesData*> (handle)->touchCallback (index, b);
2704-
}
2705-
2706-
static std::map<String, uint32_t> makePortIndices (const Ports& ports)
2707-
{
2708-
std::map<String, uint32_t> result;
2709-
2710-
ports.forEachPort ([&] (const PortHeader& header)
2711-
{
2712-
[[maybe_unused]] const auto emplaced = result.emplace (header.symbol, header.index);
2713-
2714-
// This will complain if there are duplicate port symbols.
2715-
jassert (emplaced.second);
2716-
});
2717-
2718-
return result;
2719-
}
2720-
2721-
const UiFeaturesDataOptions opts;
2722-
PhysicalResizeListener& resizeListener;
2723-
TouchListener& touchListener;
2724-
LV2_Handle instance{};
2725-
LV2UI_Widget parent{};
2726-
SymbolMap& symap;
2727-
const UsefulUrids urids { symap };
2728-
Log log { &urids };
2729-
int lastRequestedWidth = 0, lastRequestedHeight = 0;
2730-
std::vector<LV2_Options_Option> options { { LV2_OPTIONS_INSTANCE,
2731-
0,
2732-
symap.map (LV2_UI__scaleFactor),
2733-
sizeof (float),
2734-
symap.map (LV2_ATOM__Float),
2735-
&opts.initialScaleFactor },
2736-
{ LV2_OPTIONS_INSTANCE,
2737-
0,
2738-
symap.map (LV2_PARAMETERS__sampleRate),
2739-
sizeof (float),
2740-
symap.map (LV2_ATOM__Float),
2741-
&opts.sampleRate },
2742-
{ LV2_OPTIONS_INSTANCE, 0, 0, 0, 0, nullptr } }; // The final entry must be nulled out
2743-
LV2UI_Resize resize { this, resizeCallback };
2744-
LV2_URID_Map map = symap.getMapFeature();
2745-
LV2_URID_Unmap unmap = symap.getUnmapFeature();
2746-
LV2UI_Port_Map portMap { this, portIndexCallback };
2747-
LV2UI_Touch touch { this, touchCallback };
2748-
LV2_Extension_Data_Feature dataAccess;
2749-
std::map<String, uint32_t> portIndices;
2750-
Features features { makeFeatures (&resize,
2751-
parent,
2752-
instance,
2753-
&dataAccess,
2754-
&map,
2755-
&unmap,
2756-
&portMap,
2757-
&touch,
2758-
options.data(),
2759-
log.getLogFeature()) };
2760-
2761-
JUCE_LEAK_DETECTOR (UiFeaturesData)
27622647
};
27632648

27642649
struct RequiredFeatures
@@ -4602,7 +4487,7 @@ class LV2PluginFormatHeadless::Pimpl
46024487
};
46034488

46044489
const auto missingUiFeatures = findMissingFeatures (queryUi (LV2_CORE__requiredFeature),
4605-
lv2_host::UiFeaturesData::getFeatureUris());
4490+
lv2_host::UiFeatureUris::getFeatureUris());
46064491

46074492
return missingUiFeatures.empty() ? bestMatch : nullptr;
46084493
}();

modules/juce_audio_processors_headless/format_types/juce_VST3PluginFormatImpl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2680,7 +2680,7 @@ class VST3PluginInstanceHeadless : public AudioPluginInstance
26802680
if (! std::strcmp (Vst::ChannelContext::kChannelNameLengthKey, id))
26812681
value = props.name.value_or (String{}).length();
26822682
else if (! std::strcmp (Vst::ChannelContext::kChannelColorKey, id))
2683-
value = static_cast<Steinberg::int64> (props.colour.value_or (Colours::transparentBlack).getARGB());
2683+
value = static_cast<Steinberg::int64> (props.colourARGB.value_or (0));
26842684
else
26852685
return kResultFalse;
26862686

modules/juce_audio_processors_headless/juce_audio_processors_headless.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
license: AGPLv3/Commercial
5252
minimumCppStandard: 17
5353
54-
dependencies: juce_audio_basics, juce_graphics
54+
dependencies: juce_audio_basics juce_events
5555
OSXFrameworks: CoreAudio CoreMIDI AudioToolbox
5656
iOSFrameworks: AudioToolbox
5757
@@ -64,7 +64,7 @@
6464
#define JUCE_AUDIO_PROCESSORS_HEADLESS_H_INCLUDED
6565

6666
#include <juce_audio_basics/juce_audio_basics.h>
67-
#include <juce_graphics/juce_graphics.h>
67+
#include <juce_events/juce_events.h>
6868

6969
#include <juce_audio_processors_headless/processors/juce_AudioProcessorListener.h>
7070
#include <juce_audio_processors_headless/utilities/juce_AAXClientExtensions.h>

modules/juce_audio_processors_headless/processors/juce_AudioProcessor.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1313,13 +1313,14 @@ class JUCE_API AudioProcessor : private AAXClientExtensions
13131313
/** Returns a textual description of a WrapperType value */
13141314
static const char* getWrapperTypeDescription (AudioProcessor::WrapperType) noexcept;
13151315

1316-
13171316
/** A struct containing information about the DAW track inside which your
1318-
AudioProcessor is loaded. */
1317+
AudioProcessor is loaded.
1318+
*/
13191319
struct TrackProperties
13201320
{
1321-
std::optional<String> name; // The name of the track - this will be empty if the track name is not known
1322-
std::optional<Colour> colour; // The colour of the track - this will be empty if the colour is not known
1321+
std::optional<String> name; ///< The name of the track - this will be empty if the track name is not known
1322+
std::optional<uint32> colourARGB; ///< The colour of the track - The format of this number is: ((alpha << 24) | (red << 16) | (green << 8) | blue).
1323+
///< You can pass this to the constructor of Colour to create a matching colour instance.
13231324

13241325
// other properties may be added in the future
13251326
};

0 commit comments

Comments
 (0)