From 8c97b09d834e6d844a1ac2ad34f82717a0f135d7 Mon Sep 17 00:00:00 2001 From: reuk Date: Tue, 21 Mar 2023 17:17:46 +0000 Subject: [PATCH] AUv3: Avoid calling setFullState: on the superclass during state restoration On some platforms, the superclass implementation can throw if it detects that the preset data is malformed, but it's not clear exactly how the system determines this. We now apply only the JUCE state. --- .../juce_audio_plugin_client_AUv3.mm | 53 ++++++------------- 1 file changed, 16 insertions(+), 37 deletions(-) diff --git a/modules/juce_audio_plugin_client/juce_audio_plugin_client_AUv3.mm b/modules/juce_audio_plugin_client/juce_audio_plugin_client_AUv3.mm index fef366b52f..2fc72cefc4 100644 --- a/modules/juce_audio_plugin_client/juce_audio_plugin_client_AUv3.mm +++ b/modules/juce_audio_plugin_client/juce_audio_plugin_client_AUv3.mm @@ -245,16 +245,8 @@ public: if (state.getSize() > 0) { - NSData* ourState = [[NSData alloc] initWithBytes: state.getData() - length: state.getSize()]; - - NSString* nsKey = [[NSString alloc] initWithUTF8String: JUCE_STATE_DICTIONARY_KEY]; - - [retval setObject: ourState - forKey: nsKey]; - - [nsKey release]; - [ourState release]; + [retval setObject: [[NSData alloc] initWithBytes: state.getData() length: state.getSize()] + forKey: @JUCE_STATE_DICTIONARY_KEY]; } return [retval autorelease]; @@ -265,39 +257,26 @@ public: if (state == nullptr) return; - NSMutableDictionary* modifiedState = [[NSMutableDictionary alloc] init]; - [modifiedState addEntriesFromDictionary: state]; + NSObject* obj = [state objectForKey: @JUCE_STATE_DICTIONARY_KEY]; - NSString* nsPresetKey = [[NSString alloc] initWithUTF8String: kAUPresetDataKey]; - [modifiedState removeObjectForKey: nsPresetKey]; - [nsPresetKey release]; + if (obj == nullptr || ! [obj isKindOfClass: [NSData class]]) + return; - ObjCMsgSendSuper (au, @selector (setFullState:), state); + auto* data = reinterpret_cast (obj); + const auto numBytes = static_cast ([data length]); - NSString* nsKey = [[NSString alloc] initWithUTF8String: JUCE_STATE_DICTIONARY_KEY]; - NSObject* obj = [modifiedState objectForKey: nsKey]; - [nsKey release]; + if (numBytes <= 0) + return; - if (obj != nullptr) - { - if ([obj isKindOfClass:[NSData class]]) - { - NSData* data = reinterpret_cast (obj); - const int numBytes = static_cast ([data length]); - const juce::uint8* const rawBytes = reinterpret_cast< const juce::uint8* const> ([data bytes]); + auto* rawBytes = reinterpret_cast ([data bytes]); - if (numBytes > 0) - { - #if JUCE_AU_WRAPPERS_SAVE_PROGRAM_STATES - getAudioProcessor().setCurrentProgramStateInformation (rawBytes, numBytes); - #else - getAudioProcessor().setStateInformation (rawBytes, numBytes); - #endif - } - } - } + ScopedKeyChange scope (au, @"allParameterValues"); - [modifiedState release]; + #if JUCE_AU_WRAPPERS_SAVE_PROGRAM_STATES + getAudioProcessor().setCurrentProgramStateInformation (rawBytes, numBytes); + #else + getAudioProcessor().setStateInformation (rawBytes, numBytes); + #endif } AUParameterTree* getParameterTree() const