I’ve been a long time complainer about the build speed of my semi-outdated potato computers. And I’ve always dreamed of having some sort of ultra-fast compilation of my 36 JUCE projects.
Well, that day is today, so I figured I should drop a quick report here.
There are some posts already about the benefits of using Ninja + ccache to optimize build time, so this is nothing particularly new. But… the caveat is usually that it’s quite hard to compile JUCE to ccache and use it across more than one project.
The core issue is “Macro Poisoning”: JUCE embeds project-specific identity—like JucePlugin_Name, JucePlugin_Version, and unique Product IDs—directly into the compilation units of even the most generic modules (like juce_core or juce_graphics). From ccache’s perspective, the juce_core.cpp compiled for each plugin is fundamentally different because the command-line definitions differ, resulting in a 0% cross-project “hit rate.”
To solve this, I implemented a sort of macro sanitization at the CMake level. Instead of trying to hide these macros from ccache using its internal ignore_options (which can be brittle and trigger -Werror warnings for unused arguments), I use a CMake script to intercept the JUCE targets. For generic framework modules, I explicitly override the identity macros to neutral values—neutralizing strings to "" and integers to 0. This forces the compiler command lines to be identical across the entire fleet, allowing ccache to serve a single, global cached version of the JUCE modules to every plugin in the repository.
I am able to break the JUCE files up into two groups: those that only care about functional macros (like JUCE_PLUGINHOST_VST3) and Identity macros (like JucePlugin_Name).
As long as the functional macros don’t change, I get 100% hits for the cache files and building is blazingly fast (since I only need to rebuild the identity-aware parts of JUCE). Since I have several different groups of plugins with several different functional macros, I end up building JUCE a few times (once for the hosts, for example), but still save a ton of time not rebuilding for every plugin.
One major “Gotcha” : since we break the cmake into many target groups (which have to be objects for this to work) that need to know about juce, it is tempting to link them directly to the JUCE targets. However, this leads to “duplicate symbol” errors. You have to be sure to link intermediate libraries using generator expressions to pull the INTERFACE_INCLUDE_DIRECTORIES and INTERFACE_COMPILE_DEFINITIONS from JUCE modules without actually linking the target. Only the final plugin executable “truly” links the JUCE source, ensuring it is compiled exactly once.
Finally, a tip for those setting up ccache on macOS: I found that stability improved dramatically when I stopped using shell-safe wildcards in ccache environment variables and instead relied on explicit CMake-level neutralization. By combining this with OBJECT library isolation, I’ve reached a state where 90% of a “clean” build is served from the cache, even when switching between entirely different plugin projects.
This has turned my deploy cycles from hours into minutes. The entire build of 36 plugins is under 20 minutes now, and with all the signing and notarizing and uploading to the server, the total deploy time is under an hour!!
Hallelujah, praise the great ccache ninja!!
Below are the first few compilations. As you can see, after the first couple, the ccaching has ramped up to 98% overlap, meaning it only needs to compile 2% of the code.
And a very simplified version of cmake:
cmake_minimum_required(VERSION 3.22)
project(MultiPluginFleet)
# 1. THE SURGICAL SANITIZER
# This macro strips identity from JUCE targets so ccache sees identical commands across projects.
macro(sanitize_juce_target target_name)
target_compile_definitions(${target_name} INTERFACE
"JucePlugin_Name=\"\""
"JucePlugin_VersionString=\"0.0.0\""
"JucePlugin_Manufacturer=\"GlobalCache\""
)
endmacro()
# 2. GLOBAL FRAMEWORK SETUP
# We sanitize the generic modules once. Every plugin will now hit the SAME cache for these.
find_package(JUCE CONFIG REQUIRED)
set(GENERIC_MODULES juce_core juce_graphics juce_events juce_dsp)
foreach(mod ${GENERIC_MODULES})
sanitize_juce_target(juce::${mod})
endforeach()
# 3. THE SHARED TIER (Naturally Sanitized)
# We use an OBJECT library so it can be compiled once and shared across binary targets.
add_library(SharedCommon OBJECT shared_source.cpp)
# --- THE SHIELDED INCLUDE PATTERN ---
# We pull headers/definitions WITHOUT linking the target.
# This allows SharedCommon to "know" about JUCE without triggering
# a second compilation of the JUCE .cpp files (which causes duplicate symbols).
foreach(mod ${GENERIC_MODULES})
target_include_directories(SharedCommon SYSTEM PUBLIC
$<TARGET_PROPERTY:juce::${mod},INTERFACE_INCLUDE_DIRECTORIES>)
target_compile_definitions(SharedCommon PRIVATE
$<TARGET_PROPERTY:juce::${mod},INTERFACE_COMPILE_DEFINITIONS>)
endforeach()
# 4. THE IDENTITY TIER (Plugin_A and Plugin_B)
# These targets receive the REAL identity macros.
# Plugin A
juce_add_plugin(Plugin_A
PRODUCT_NAME "Plugin A"
VERSION "1.2.3"
BUNDLE_ID "com.mycompany.plugina"
# ... other JUCE properties
)
# Final Assembly: Links the shared objects + the "real" JUCE modules
target_link_libraries(Plugin_A PRIVATE SharedCommon juce::juce_core juce::juce_graphics)
# Plugin B
juce_add_plugin(Plugin_B
PRODUCT_NAME "Plugin B"
VERSION "2.0.0"
BUNDLE_ID "com.mycompany.pluginb"
)
target_link_libraries(Plugin_B PRIVATE SharedCommon juce::juce_core juce::juce_graphics)
# VERIFICATION:
# ccache will now see the exact same command line for juce_core.cpp
# in both Plugin_A and Plugin_B, resulting in a 100% cross-project hit!
1 post - 1 participant
]]>I’m currently looking for an experienced C++ developer with VST/VST2/VST3 plugin development experience to help work on an upcoming audio plugin project.
This would be project-based work, not a full-time position.
The audio concept, design direction, and UI/UX will be handled separately, so the main focus is on the plugin development and technical implementation.
Requirements:
Scope:
Compensation:
Fixed salary / project-based payment.
If you’re interested, please send:
Feel free to contact me via private message
Thanks.
3 posts - 2 participants
]]>If I also wanted to store a property containing the track height on screen (pixels) into that same ValueTree WITHOUT using UndoManager, will that cause problems? When Undo/Redo is called, what happens to that property? Will it stay in the ValueTree or does it disappear suddenly?
3 posts - 2 participants
]]>The audio engine does not deinitialize properly. It keeps trying to process, whilst being partially deinitialized.
Is this a known issue? What could be wrong here?
Any help is appreciated on this issue!
1 post - 1 participant
]]>2 posts - 2 participants
]]>3 posts - 2 participants
]]>I’ve got an existing project and I’ve just added an iOS exporter for it for AUv3 and standalone.
Fire up the standalone on an iPad and everything works as expected.
But, if I launch the AUv3 with, for example Audiobus, the UI is totally unresponsive - the app is running fine but clicking on anything on the UI has no response.
Anyone come across something similar or have any thoughts? I’ve tried the audioplugindemo and that works fine as expected.
Cheers, Lee
6 posts - 3 participants
]]>When both Standalone and AUv3 are configured as plugin formats for an iOS app, we find that one of the targets (either Standalone or AUv3) is missing from the generated Xcode (26.2) project. This occurs randomly, once every few attempts, and causes both local builds as well as our CI pipeline to fail randomly.
We have a CMake based setup, but we experienced the same issue a while ago with a Projucer project. Our workaround is to re-run the CMake export a few times until both targets appear.
I hope to see this fixed. I’m not sure whether this is a JUCE or Xcode bug.
It happens with JUCE 8.0.12 and Xcode 26.2, but used to happen in older versions of both.
Best,
Jelle
3 posts - 2 participants
]]>All of a sudden in setStateInformation, when this part is executed;
parameters.replaceState (ValueTree::fromXml (*xmlState));
at least one non-ValueTree variable, that is NOT stored in getStateInformation, nor retrieved in setStateInformation, is overwritten. As a matter of fact the particular variable is calculated, not stored or retrieved!
Perhaps a corrupt XML text in Reaper’s preset file, however I deleted every of my synth’s preset file, and still the same issue.
Yes obviously I messed up somewhere, but perhaps someone else have experienced the same issue and can guide me towards where to find the culprit.
3 posts - 2 participants
]]>LookAndFeel changes. Each look and feel implementation calls setDefaultSansSerifTypefaceName with a different font in its constructor, switching the LookAndFeel at runtime results in this:
→ ![]()
I’ve only tested this on macOS 26 but I think it’s likely to be present on other platforms too.
After investigating, Graphics::drawText and Graphics::drawFittedText appear to be using stale glyph arrangements. I’ve applied a fix on a local fork of JUCE that clears the GlyphArrangementCache in Typeface::clearTypefaceCache()and this seems to resolve the issue .
The issue is present on the latest version of JUCE on the develop branch
1 post - 1 participant
]]>Sharing something I’ve been building for my own plugin project: MN Strip Studio, a free browser tool to design and export film strip PNGs (knobs, sliders, buttons, toggles) ready to drop into any film strip based slider. No login, no install, just opens in the browser.
It’s got 3D PBR and 2D rendering, layer based editing, and a random button that spits out fresh designs in one click when you’re short on ideas. Frame indexed PNG export with the size and frame count you configure.
Still experimental but already usable.
https://mnstripstudio-shares.marionietoworld.workers.dev/
1 post - 1 participant
]]>Trouble is I can’t seem to get my sliders to look good. My buttons are OK, but the knobs are poor.
I managed to get highlights and even subtle textures onto the knobs, but there’s something visually lacking for me. (I know my jagged edges layer is the wrong color, highlights could be stronger)
This I drew with JUCE 8 library, its not a SVG. I could go with a simple flat look, but thats not fitting with my retro themed plugin to be honest.
Anyone know of a good source of retro style GUI set?
Or, any tips on getting my existing knob better looking?
UI Mother have some good looking stuff but not many SVG, and the one they offer doesn’t appeal to me.
SVGs have to be simplified too for JUCE, right, to not be too GPU heavy, otherwise they lag?
1 post - 1 participant
]]>Logic / GarageBand AU: dead cells reproduce.
REAPER (its own AU host), standalone, VST3/CLAP/LV2 in other hosts: all cells work. Same plugin binary, same machine, same OS.
Instrumentation: I added a MouseListener on the editor (with wantsEventsForAllNestedChildComponents=true) plus a direct mouseDown log inside the affected child. The user clicked extensively across the dead zone and a working cell adjacent to it. The working cell produces both log entries. Every click in the dead cells produces no log entry of any kind — events never reach JUCE.
What’s different from the existing reports (viennal, moving-window, glitchy-resize, iPlug2): those describe contiguous regions that scale with UI scale. This is a small fixed region at a specific position. Suggests AUHostingService may have a clipping rect or hit-test region with wrong geometry, in addition to (or instead of) the coordinate-transform issue others have hit.
Filed with Apple: FB22477732. If you’ve filed Feedback Assistant reports on related Tahoe AU mouse issues, please reference this FB and reply with yours so we can cross-link.
Questions:
Anyone else seeing geometrically-localized drops at specific positions, rather than scaled bands?
Any known JUCE-side workaround?
Plugin: KR-106 (JUCE-based, AU/AUv3/VST3/CLAP/LV2/Standalone). OS: macOS 26.4 / 26.4.1.
@reuk — flagging in case the specific-cell pattern is useful additional signal.
1 post - 1 participant
]]>I’m building a JUCE app with a manual Xcode project (no Projucer) and hitting 2208 duplicate symbol errors at link time, all originating from SheenBidi.
Setup:
macOS 26.0.1
Xcode 26.2
JUCE: latest stable
Manual Xcode project, no Projucer
What’s happening:
The build fails at link with 2208 duplicate symbols. The error line in the build log is:
Link SCREE_BROOD (arm64) — ✗ 2208 duplicate symbols
The compile step above it shows include_juce_graphics_Sheenbidi.c compiling successfully (0.2s, 1 warning).
What I tried:
The original file was include_juce_graphics_Sheenbidi.mm. I was getting void* cast errors because C++ is stricter than C about these. The suggested fix was to rename it to .cso it compiles as plain C rather than Objective-C++. The cast errors went away but now I get the duplicate symbols.
My suspicion is that another amalgam file (possibly include_juce_graphics.mm) is also including SheenBidi source internally, so the symbols are being defined twice. But I don’t want to start hacking amalgam files without knowing what I’m doing.
What’s the correct way to handle SheenBidi in a manual Xcode project?
Thanks
2 posts - 2 participants
]]>class MyProgressBar : public LookAndFeel_V4
{
public:
MyProgressBar()
{
}
void drawCircularProgressBar (Graphics& g, const ProgressBar& progressBar,
const String& textToShow)
{
const auto background = progressBar.findColour (ProgressBar::backgroundColourId);
const auto foreground = progressBar.findColour (ProgressBar::foregroundColourId);
..................
etc.
8 posts - 4 participants
]]>I am currently migrating one of my Android applications from JUCE 7 to JUCE 8 and have encountered an issue where font styles are not being applied correctly on Android.
Create a new blank GUI project using the Projucer
Add both Xcode (iOS) and Android exporters
In MainComponent.cpp, set the font as follows:
g.setFont(juce::FontOptions().withPointHeight(16.0f).withStyle("Bold"));
Run the project on both iOS and Android devices
The text should render in bold on both platforms.
The bold style is applied correctly on iOS, but has no effect on Android.
JUCE version: 8.0.12
iOS: iOS 26
Android: Android 16, Android 11 (issue reproduced on both)
Unless I am missing something, this does seem like a regression bug introduced in JUCE 8. Could you please take a look?
6 posts - 3 participants
]]>13 posts - 3 participants
]]>juce_audio_plugin_client to store some custom functions for a Unity project. I’m able to set up everything in the Projucer, and I do have a local module that I can edit with my code, but when I build the project, it’s very clear that it’s using the global copy of the module and not the local one.
I have it set up in Projucer like this, where when I first edit the path for the project to be my local module path, it populates the location correctly at first (my Unity Test folder):
But when I save and reset the view, it goes back to the global path (my Downloads folder):
This happens despite whatever local module path I put in, with the juce_audio_plugin_client subdirectory, or a relative path.
As for the actual build, I can tell it’s not looking at local module to build because I can write bogus code on the bottom, and the project builds just fine.
So what I imagine is happening is that it doesn’t like my path for some reason, and it’s defaulting to the global, but I don’t know why, as it’s a legitimate file.
Thank you to anyone who can shed some light onto this!
3 posts - 2 participants
]]>My thought is that, when I hit a key on my MIDI keyboard, that input should be captured by a JUCE Audio Device Manager, and callbacks should send that message to a MIDI Collector and eventually processed by the MIDI buffer in the processBlock, like so:
void AudioProcessorUnityWrapper::create(UnityAudioEffectState* state)
{
…
deviceManager.initialiseWithDefaultDevices(0, 2); midiCollector.reset(state->sampleRate); auto midiInputs = juce::MidiInput::getAvailableDevices(); for (auto& input : midiInputs) { deviceManager.setMidiInputEnabled(input.identifier, true); } deviceManager.addMidiInputDeviceCallback({}, &midiCollector);}
void AudioProcessorUnityWrapper::processBuffers(…)
{
…
MidiBuffer mb;
midiCollector.removeNextBlockOfMessages(mb, bufferSize);
pluginInstance→processBlock(scratchBuffer, mb);
}
juce::AudioDeviceManager deviceManager;
juce::MidiMessageCollector midiCollector;
This all initializes fine and well, but no callbacks are called when I start pressing keys on the MIDI keyboard, the midiCollector never fills up with any messages, and AudioDeviceManager::handleIncomingMidiMessageIntis never called.
So at this point I’m wondering, is this even possible? It would make sense that Unity can only send MIDI messages, which is fine, but I hope there is a less latent solution.
Thank you!
1 post - 1 participant
]]>struct MyAudioBlock
{
MyAudioBlock() = default;
~MyAudioBlock() = default;
double timeStamp;
dsp::AudioBlock<float> audioBuffer;
}
static_assert(std::is_trivially_copyable_v<MyAudioBlock>, "MyAudioBlock must be trivially copyable");
And it works. But I was warned by friend that dsp::AudioBlock<float> is not always trivially copyable because it depends on JUCE version and compilator. Is that true? Or it’s bullshit and I can sleep soundly?
3 posts - 2 participants
]]>When insertDefaultDeviceNames is called with the ASIO device type active, the application crashes with a 0xC0000005 access violation inside the ASIO driver DLL. In my case the crashing driver is asiobtin.dll (Steinberg built-in ASIO Driver), and I only notice it in debug builds. However, this could potentially affect any ASIO driver that spawns internal threads during start().
I believe the bug is reproducible whenever insertDefaultDeviceNames iterates past the Steinberg built-in ASIO Driver to probe the next device.
initialise >> insertDefaultDeviceNames is called to find a valid device pairinsertDefaultDeviceNames calls type->createDevice(...) to construct a temporary ASIOAudioIODevice for each installed ASIO driver. During construction, openDevice() calls start() and stop() on the device - but it doesn’t call disposeBuffers(). Note that disposeBuffers() is guarded by the buffersCreated flag, which is only set to true in open(), not in createDummyBuffers().
See at juce_ASIO_Windows.cpp line 1271:
createDummyBuffers (preferredBufferSize);
// ...
err = asioObject->start();
Thread::sleep (80);
asioObject->stop();
When the temporary device is destroyed, the destructor calls removeCurrentDriver() >> asioObject->Release() without ever having called disposeBuffers() (as required by the ASIO SDK). Because disposeBuffers() is skipped, the driver’s internal audio thread (spawned during start()) is still running when Release() frees the COM object. That thread then dereferences internal state that has just been freed, leading to a null pointer crash inside the driver DLL.
In openDevice(), call asioObject->disposeBuffers() directly after asioObject->stop():
// start and stop because cubase does it
err = asioObject->start();
// ignore an error here, as it might start later after setting other stuff up
JUCE_ASIO_LOG_ERROR ("start", err);
Thread::sleep (80);
asioObject->stop();
Thread::sleep (10); // add: allow stop to settle (10ms is just a guess, but it works for me)
asioObject->disposeBuffers(); // add: complete the required SDK teardown sequence
3 posts - 2 participants
]]>Thanks!
1 post - 1 participant
]]>I’m pleased to introduce AudioDice, a specialized plugin host designed specifically for controlled randomization of third-party plugin parameters.
I have developed this tool, using JUCE, out of a need for a randomization engine that could handle thousands of parameters without compromising the stability of the host DAW. So the main focus was on creating a predictable, stable environment for creative chaos. No vibe coding used!
Key Technical Features:
AudioDice is currently available for free. No strings attached.
You can download it and find more technical details at:
www.sounddevelopment.nl
We are eager to hear feedback from the developer community, especially regarding the hosting implementation and performance across different DAWs.
Best regards,
Sound Development, Marcel Huibers
3 posts - 2 participants
]]>The audio engine pairs that with adaptive editing - crossfade when gaps are small, selective time-stretching (transient preserved, tail stretched) when they’re not.
Looking for someone who’s shipped AU/VST plugins with JUCE and ideally has ARA experience. This is a paid contract starting with a prototype phase. Remote.
If this sounds like an interesting problem, DM me or email [email protected]. Happy to talk through the technical approach before anything formal.
3 posts - 2 participants
]]>More info at GForce Software
Speak soon!
3 posts - 2 participants
]]>Some background:
modules/juce/extras/Build/juce_build_tools/utils/juce_ResourceRc.cpp:63-64
The VS_VERSION_INFO VERSIONINFO block writes:
FILEVERSION 14,0,8,0
But it never writes a PRODUCTVERSION line. In a proper Windows RC file, it should be:
VS_VERSION_INFO VERSIONINFO
FILEVERSION 14,0,8,0
PRODUCTVERSION 14,0,8,0 ← this line is missing
BEGIN
How the version flows:
The Windows VERSIONINFO structure has two binary version fields:
Note that the string values “FileVersion” and “ProductVersion” are both correctly written (lines 81-83),
but those are just display strings in the Details tab — VS_FIXEDFILEINFO.dwProductVersionMS/LS comes exclusively from the binary PRODUCTVERSION statement.
The fix would be adding one line after line 64 in juce_ResourceRc.cpp:
<< "PRODUCTVERSION " << getCommaSeparatedVersionNumber (version) << newLine
3 posts - 2 participants
]]>I’m developing a stereo imaging and modulation plugin that features a step sequencer with 4 tabs (Pan, Volume, Width, Pitch), each with up to 64 steps supporting per-step shapes, multiband values, mirror/invert flags etc. The plugin supports MIDI keyswitch-triggered preset switching, the user stores different sequencer configurations as “motions” and triggers them via MIDI notes during live performance.
The problem: There’s a perceptible audio gap/artifact when switching between motions during playback. I’ve narrowed it down to message thread latency during the switch.
Current architecture:
Motion states are stored internally as std::unique_ptr<juce::XmlElement>. When a MIDI keyswitch fires:
Audio thread: Detects the note, starts a 4ms SmoothedValue fade-out to silence, pushes note to a lock-free FIFO, wakes the message thread via triggerAsyncUpdate()
Message thread (in handleAsyncUpdate):
Auto-saves the current motion: apvts.copyState() + serialises ~3,500 step data fields into the ValueTree as children, then converts to XML
Loads the new motion: ValueTree::fromXml() on the stored XML (~3,600 children), builds a HashMap for step data extraction, iterates all children to apply ~96 global params via setValueNotifyingHost()
Calls forceParamSync() (sets an atomic flag)
Audio thread: Detects the flag, waits for gate < 0.001, resets DSP state (IIR filters, analysis accumulators, delay lines are preserved), snaps all SmoothedValue instances, starts 8ms fade-in
The step data itself was recently moved out of APVTS (it was ~3,584 registered parameters causing listener storms). Step data now lives as a plain StepData[64] array on the processor, written by the UI thread under a SpinLock and read directly by the audio thread. Only ~96 global params remain in APVTS.
The bottleneck: The message thread work between fade-out and fade-in takes ~15-20ms:
serializeStepDataInto(): appends ~3,500 ValueTree children (~5ms)
ValueTree::fromXml(): parses stored XML with ~3,600 elements (~5ms)
deserializeStepDataInto(): HashMap construction from ~3,600 entries (~3ms)
Global param iteration + backward compat scans (~3ms)
This creates a ~20ms silence gap that’s clearly audible during rhythmic playback.
What I’m planning: Cache step data as raw StepData[64] arrays directly in each motion slot (simple memcpy on save/load), and store only the ~96 global params in a lightweight ValueTree, eliminating all XML parsing and large ValueTree construction from the hot path. This should bring message thread work down to ~1-2ms.
My questions:
Is there a better pattern for fast preset switching in JUCE plugins? Plugins like Stutter Edit 2 and CableGuys’ ShaperBox achieve near-instant switches. Are they likely doing the state swap entirely on the audio thread, or is message-thread dispatch with minimal work the standard approach?
For the ~96 global params that go through APVTS: Is setValueNotifyingHost() in a loop the fastest way to apply them, or is there a faster bulk-update path that batches the listener notifications? I’ve already moved from replaceState() to differential application (only touching params that actually changed).
Any concerns with storing the “authoritative” step sequencer state as a plain C struct array on the processor (written by message thread under SpinLock, read locklessly by audio thread), rather than as APVTS parameters? This eliminated the 3,584-parameter overhead but I want to make sure I’m not missing an edge case with host state save/recall, currently I serialise the array into the APVTS ValueTree in getStateInformation() and deserialise in setStateInformation().
triggerAsyncUpdate() dispatch latency: I’m seeing 1-5ms between the audio thread calling triggerAsyncUpdate and the message thread entering handleAsyncUpdate. Is this typical? Is there any way to reduce this, or is moving more of the switch logic to the audio thread the only path to sub-5ms transitions?
Running JUCE 8 on Windows (VS2022), targeting VST3. Any insights from people who’ve built similar performance-oriented switching would be hugely appreciated.
Thanks!
2 posts - 2 participants
]]>Component subclass should either implement the paint method or have children components, but not both” rule? guideline? best practice? so I’ve been trying to figure out the best way to paint a component a certain colour and also add children.
My project UI is fairly simple, the specific part that’s relevant to this question is that I want to add 3 sections to the UI laid horizontally, each taking 1/3 of the window space, which will be resizable with a minimum size. I’m working on the middle section which will be a sort of “control panel”, so I want to paint it a certain colour and add buttons, however I don’t want the buttons to change size as the window is made bigger. I thought of adding a child Rectangle with set width in that section and adding buttons as children of that component.
The only way I know is to implement the paint method and use g.fillAll on the centre control panel, but that would go against that “rule”,
The code in the Parent and child components tutorial doesn’t actually follow this. Is filling the colour of a component considered an exception, or is there actually a better way? In terms of code maintenance I don’t see a problem with considering this use case an exception however there might be other implications I’m not aware of.
TIA
13 posts - 6 participants
]]>my-plugin_vst3.cpp I have made a very minor modification to the Projucer in our JUCE fork to allow this, but the equivalent behavior via CMake seems to be more involved.
For some of our legacy, pre-JUCE plug-ins I need to have a lot of code for handling session state loads and don’t want to pull all of the logic and dependencies in to every plug-in format (e.g. needing to pull AAX SDK headers in to the VST3 binary).
I understand there’s a risk of breaking existing projects with a change like this, so perhaps adding an option to the `juce_add_modules function which defaults to the existing behaviour would allow this feature to be added safely?
6 posts - 3 participants
]]>I’ve done some testing with the HostPluginDemo example and it has the same issue (JUCE 8.0.12).
To reproduce:
I noticed after the first call to resized() in the host window, a second call with smaller bounds is invoked by the OS through this method:
addMethod (NSViewComponentPeer::frameChangedSelector, [] (id self, SEL, NSNotification*) { callOnOwner (self, &NSViewComponentPeer::redirectMovedOrResized); });
This second call is what causing the host window to become smaller in size.
P.S.
I just found out this only exists in AUDistortion, it might only be a problem for this specific plugin?
1 post - 1 participant
]]>