Browse Source

AUv3: Fix race on factoryPresets

Some AUv3 presets crash when querying the set of presets in Loopy Pro.
The issue seems to be because `addPresets` may end up being called
concurrently with the host's queries.
pull/22/head
reuk 3 years ago
parent
commit
45a5235298
No known key found for this signature in database GPG Key ID: 9ADCD339CFC98A11
1 changed files with 40 additions and 16 deletions
  1. +40
    -16
      modules/juce_audio_plugin_client/AU/juce_AUv3_Wrapper.mm

+ 40
- 16
modules/juce_audio_plugin_client/AU/juce_AUv3_Wrapper.mm View File

@@ -133,7 +133,7 @@ public:
//============================================================================== //==============================================================================
virtual AUAudioUnitPreset* getCurrentPreset() = 0; virtual AUAudioUnitPreset* getCurrentPreset() = 0;
virtual void setCurrentPreset(AUAudioUnitPreset*) = 0;
virtual void setCurrentPreset (AUAudioUnitPreset*) = 0;
virtual NSArray<AUAudioUnitPreset*>* getFactoryPresets() = 0; virtual NSArray<AUAudioUnitPreset*>* getFactoryPresets() = 0;
virtual NSDictionary<NSString*, id>* getFullState() virtual NSDictionary<NSString*, id>* getFullState()
@@ -517,22 +517,12 @@ public:
//============================================================================== //==============================================================================
AUAudioUnitPreset* getCurrentPreset() override AUAudioUnitPreset* getCurrentPreset() override
{ {
const int n = static_cast<int> ([factoryPresets.get() count]);
const int idx = static_cast<int> (getAudioProcessor().getCurrentProgram());
if (idx < n)
return [factoryPresets.get() objectAtIndex:static_cast<unsigned int> (idx)];
return nullptr;
return factoryPresets.getAtIndex (getAudioProcessor().getCurrentProgram());
} }
void setCurrentPreset (AUAudioUnitPreset* preset) override void setCurrentPreset (AUAudioUnitPreset* preset) override
{ {
const int n = static_cast<int> ([factoryPresets.get() count]);
const int idx = static_cast<int> ([preset number]);
if (isPositiveAndBelow (idx, n))
getAudioProcessor().setCurrentProgram (idx);
getAudioProcessor().setCurrentProgram (static_cast<int> ([preset number]));
} }
NSArray<AUAudioUnitPreset*>* getFactoryPresets() override NSArray<AUAudioUnitPreset*>* getFactoryPresets() override
@@ -1185,6 +1175,38 @@ private:
juce::AudioBuffer<float> scratchBuffer; juce::AudioBuffer<float> scratchBuffer;
}; };
class FactoryPresets
{
public:
using Presets = std::unique_ptr<NSMutableArray<AUAudioUnitPreset*>, NSObjectDeleter>;
void set (Presets newPresets)
{
std::lock_guard<std::mutex> lock (mutex);
std::swap (presets, newPresets);
}
NSArray* get() const
{
std::lock_guard<std::mutex> lock (mutex);
return presets.get();
}
AUAudioUnitPreset* getAtIndex (int index) const
{
std::lock_guard<std::mutex> lock (mutex);
if (index < (int) [presets.get() count])
return [presets.get() objectAtIndex: (unsigned int) index];
return nullptr;
}
private:
Presets presets;
mutable std::mutex mutex;
};
//============================================================================== //==============================================================================
void addAudioUnitBusses (bool isInput) void addAudioUnitBusses (bool isInput)
{ {
@@ -1428,7 +1450,7 @@ private:
void addPresets() void addPresets()
{ {
factoryPresets.reset ([[NSMutableArray<AUAudioUnitPreset*> alloc] init]);
FactoryPresets::Presets newPresets { [[NSMutableArray<AUAudioUnitPreset*> alloc] init] };
const int n = getAudioProcessor().getNumPrograms(); const int n = getAudioProcessor().getNumPrograms();
@@ -1440,8 +1462,10 @@ private:
[preset.get() setName: juceStringToNS (name)]; [preset.get() setName: juceStringToNS (name)];
[preset.get() setNumber: static_cast<NSInteger> (idx)]; [preset.get() setNumber: static_cast<NSInteger> (idx)];
[factoryPresets.get() addObject: preset.get()];
[newPresets.get() addObject: preset.get()];
} }
factoryPresets.set (std::move (newPresets));
} }
//============================================================================== //==============================================================================
@@ -1804,7 +1828,7 @@ private:
std::unique_ptr<AUParameterTree, NSObjectDeleter> paramTree; std::unique_ptr<AUParameterTree, NSObjectDeleter> paramTree;
std::unique_ptr<NSMutableArray<NSNumber*>, NSObjectDeleter> overviewParams, channelCapabilities; std::unique_ptr<NSMutableArray<NSNumber*>, NSObjectDeleter> overviewParams, channelCapabilities;
std::unique_ptr<NSMutableArray<AUAudioUnitPreset*>, NSObjectDeleter> factoryPresets;
FactoryPresets factoryPresets;
ObjCBlock<AUInternalRenderBlock> internalRenderBlock; ObjCBlock<AUInternalRenderBlock> internalRenderBlock;


Loading…
Cancel
Save