RAM2118 commited on
Commit
48e03fd
·
verified ·
1 Parent(s): b195f66

Fix crash on load: Add try/catch around findAllTypesForFile + createPluginInstance, use async path

Browse files
Files changed (1) hide show
  1. Source/HostedPluginManager.cpp +49 -44
Source/HostedPluginManager.cpp CHANGED
@@ -2,7 +2,6 @@
2
 
3
  HostedPluginManager::HostedPluginManager()
4
  {
5
- // Register VST3 and AU formats explicitly (addDefaultFormats() removed in JUCE 8)
6
  #if JUCE_PLUGINHOST_VST3
7
  formatManager.addFormat(new juce::VST3PluginFormat());
8
  #endif
@@ -19,7 +18,6 @@ HostedPluginManager::~HostedPluginManager()
19
  void HostedPluginManager::loadPlugin(const juce::File& pluginFile,
20
  double sampleRate, int blockSize)
21
  {
22
- // Unload existing plugin first
23
  unloadPlugin();
24
 
25
  currentSampleRate = sampleRate;
@@ -28,57 +26,66 @@ void HostedPluginManager::loadPlugin(const juce::File& pluginFile,
28
  juce::String errorMessage;
29
  juce::OwnedArray<juce::PluginDescription> typesFound;
30
 
31
- // Scan the file to find plugin descriptions
32
- for (int i = 0; i < formatManager.getNumFormats(); ++i)
33
  {
34
- auto* format = formatManager.getFormat(i);
35
- format->findAllTypesForFile(typesFound, pluginFile.getFullPathName());
36
- if (typesFound.size() > 0)
37
- break;
 
 
 
38
  }
39
-
40
- if (typesFound.isEmpty())
41
  {
42
- DBG("PluginBridge: No plugin found in file: " + pluginFile.getFullPathName());
43
  return;
44
  }
45
 
46
- // Use the first plugin description found
47
- auto& desc = *typesFound[0];
48
-
49
- // Create plugin instance (synchronous — safe here since we're on message thread)
50
- auto instance = formatManager.createPluginInstance(
51
- desc, sampleRate, blockSize, errorMessage);
52
-
53
- if (instance == nullptr)
54
  {
55
- DBG("PluginBridge: Failed to create plugin: " + errorMessage);
56
  return;
57
  }
58
 
59
- // Enable all buses before use
60
- instance->enableAllBuses();
61
-
62
- // Match bus layout: stereo in/out
63
- auto layout = juce::AudioProcessor::BusesLayout();
64
- layout.inputBuses.add(juce::AudioChannelSet::stereo());
65
- layout.outputBuses.add(juce::AudioChannelSet::stereo());
66
-
67
- if (instance->checkBusesLayoutSupported(layout))
68
- instance->setBusesLayout(layout);
69
-
70
- // Prepare for playback
71
- instance->prepareToPlay(sampleRate, blockSize);
72
 
73
- // Store
74
- {
75
- const juce::ScopedLock sl(pluginLock);
76
- hostedPlugin = std::move(instance);
77
- loadedPluginPath = pluginFile.getFullPathName();
78
- }
79
-
80
- DBG("PluginBridge: Loaded plugin: " + getPluginName()
81
- + " (" + juce::String(getParameterCount()) + " params)");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  }
83
 
84
  void HostedPluginManager::unloadPlugin()
@@ -160,7 +167,6 @@ std::vector<HostedPluginManager::ParamInfo> HostedPluginManager::searchParams(
160
  info.displayText = param->getText(param->getValue(), 64);
161
  info.automatable = param->isAutomatable();
162
 
163
- // Try to get stable ID from HostedParameter
164
  if (auto* hosted = dynamic_cast<juce::AudioPluginInstance::HostedParameter*>(param))
165
  info.id = hosted->getParameterID();
166
  else
@@ -169,7 +175,6 @@ std::vector<HostedPluginManager::ParamInfo> HostedPluginManager::searchParams(
169
  results.push_back(info);
170
  }
171
 
172
- // Cap results to avoid token bloat
173
  if (results.size() >= 20)
174
  break;
175
  }
 
2
 
3
  HostedPluginManager::HostedPluginManager()
4
  {
 
5
  #if JUCE_PLUGINHOST_VST3
6
  formatManager.addFormat(new juce::VST3PluginFormat());
7
  #endif
 
18
  void HostedPluginManager::loadPlugin(const juce::File& pluginFile,
19
  double sampleRate, int blockSize)
20
  {
 
21
  unloadPlugin();
22
 
23
  currentSampleRate = sampleRate;
 
26
  juce::String errorMessage;
27
  juce::OwnedArray<juce::PluginDescription> typesFound;
28
 
29
+ // Wrap in try/catch — some plugins throw or show dialogs that cause exceptions
30
+ try
31
  {
32
+ for (int i = 0; i < formatManager.getNumFormats(); ++i)
33
+ {
34
+ auto* format = formatManager.getFormat(i);
35
+ format->findAllTypesForFile(typesFound, pluginFile.getFullPathName());
36
+ if (typesFound.size() > 0)
37
+ break;
38
+ }
39
  }
40
+ catch (...)
 
41
  {
42
+ DBG("PluginBridge: Exception during plugin scan for: " + pluginFile.getFullPathName());
43
  return;
44
  }
45
 
46
+ if (typesFound.isEmpty())
 
 
 
 
 
 
 
47
  {
48
+ DBG("PluginBridge: No plugin found in file: " + pluginFile.getFullPathName());
49
  return;
50
  }
51
 
52
+ auto desc = *typesFound[0];
 
 
 
 
 
 
 
 
 
 
 
 
53
 
54
+ // Use async creation — safer for AU plugins and plugins that need message thread
55
+ formatManager.createPluginInstanceAsync(desc, sampleRate, blockSize,
56
+ [this, pluginFile](std::unique_ptr<juce::AudioPluginInstance> instance,
57
+ const juce::String& error)
58
+ {
59
+ if (instance == nullptr)
60
+ {
61
+ DBG("PluginBridge: Failed to create plugin: " + error);
62
+ return;
63
+ }
64
+
65
+ // Enable all buses
66
+ instance->enableAllBuses();
67
+
68
+ // Match bus layout: stereo in/out
69
+ auto layout = juce::AudioProcessor::BusesLayout();
70
+ layout.inputBuses.add(juce::AudioChannelSet::stereo());
71
+ layout.outputBuses.add(juce::AudioChannelSet::stereo());
72
+
73
+ if (instance->checkBusesLayoutSupported(layout))
74
+ instance->setBusesLayout(layout);
75
+
76
+ // Prepare for playback
77
+ instance->prepareToPlay(currentSampleRate, currentBlockSize);
78
+
79
+ // Store
80
+ {
81
+ const juce::ScopedLock sl(pluginLock);
82
+ hostedPlugin = std::move(instance);
83
+ loadedPluginPath = pluginFile.getFullPathName();
84
+ }
85
+
86
+ DBG("PluginBridge: Loaded plugin: " + getPluginName()
87
+ + " (" + juce::String(getParameterCount()) + " params)");
88
+ });
89
  }
90
 
91
  void HostedPluginManager::unloadPlugin()
 
167
  info.displayText = param->getText(param->getValue(), 64);
168
  info.automatable = param->isAutomatable();
169
 
 
170
  if (auto* hosted = dynamic_cast<juce::AudioPluginInstance::HostedParameter*>(param))
171
  info.id = hosted->getParameterID();
172
  else
 
175
  results.push_back(info);
176
  }
177
 
 
178
  if (results.size() >= 20)
179
  break;
180
  }