RAM2118 commited on
Commit
362db70
·
verified ·
1 Parent(s): 5f757c7

Sprint 2: Update PluginBridgeProcessor.cpp \u2014 route audio through hosted plugin

Browse files
Files changed (1) hide show
  1. Source/PluginBridgeProcessor.cpp +32 -14
Source/PluginBridgeProcessor.cpp CHANGED
@@ -5,9 +5,8 @@ PluginBridgeProcessor::PluginBridgeProcessor()
5
  : AudioProcessor(BusesProperties()
6
  .withInput("Input", juce::AudioChannelSet::stereo(), true)
7
  .withOutput("Output", juce::AudioChannelSet::stereo(), true)),
8
- mcpServer(kDefaultMcpPort)
9
  {
10
- // Start MCP server in background thread
11
  mcpServer.start();
12
  }
13
 
@@ -16,30 +15,29 @@ PluginBridgeProcessor::~PluginBridgeProcessor()
16
  mcpServer.stop();
17
  }
18
 
19
- void PluginBridgeProcessor::prepareToPlay(double /*sampleRate*/, int /*samplesPerBlock*/)
20
  {
21
- // Phase 2: prepare hosted plugin + analyser here
22
  }
23
 
24
  void PluginBridgeProcessor::releaseResources()
25
  {
26
- // Phase 2: release hosted plugin + analyser here
27
  }
28
 
29
  void PluginBridgeProcessor::processBlock(juce::AudioBuffer<float>& buffer,
30
- juce::MidiBuffer& /*midiMessages*/)
31
  {
32
  juce::ScopedNoDenormals noDenormals;
33
 
34
- // Clear any extra output channels
35
  auto totalNumInputChannels = getTotalNumInputChannels();
36
  auto totalNumOutputChannels = getTotalNumOutputChannels();
37
  for (auto i = totalNumInputChannels; i < totalNumOutputChannels; ++i)
38
  buffer.clear(i, 0, buffer.getNumSamples());
39
 
40
- // Sprint 1: Pure passthrough — audio goes in, audio goes out unchanged
41
- // Phase 2: analyser.processBlock(buffer)
42
- // Phase 2: hostedPlugin->processBlock(buffer, midi)
43
  }
44
 
45
  juce::AudioProcessorEditor* PluginBridgeProcessor::createEditor()
@@ -47,14 +45,29 @@ juce::AudioProcessorEditor* PluginBridgeProcessor::createEditor()
47
  return new PluginBridgeEditor(*this);
48
  }
49
 
50
- void PluginBridgeProcessor::getStateInformation(juce::MemoryBlock& /*destData*/)
51
  {
52
- // Phase 2: save which plugin is loaded + its state
 
 
 
 
 
53
  }
54
 
55
- void PluginBridgeProcessor::setStateInformation(const void* /*data*/, int /*sizeInBytes*/)
56
  {
57
- // Phase 2: restore hosted plugin from saved state
 
 
 
 
 
 
 
 
 
 
58
  }
59
 
60
  bool PluginBridgeProcessor::isMcpServerRunning() const
@@ -67,6 +80,11 @@ int PluginBridgeProcessor::getMcpServerPort() const
67
  return mcpServer.getPort();
68
  }
69
 
 
 
 
 
 
70
  // JUCE plugin entry point
71
  juce::AudioProcessor* JUCE_CALLTYPE createPluginFilter()
72
  {
 
5
  : AudioProcessor(BusesProperties()
6
  .withInput("Input", juce::AudioChannelSet::stereo(), true)
7
  .withOutput("Output", juce::AudioChannelSet::stereo(), true)),
8
+ mcpServer(kDefaultMcpPort, hostManager)
9
  {
 
10
  mcpServer.start();
11
  }
12
 
 
15
  mcpServer.stop();
16
  }
17
 
18
+ void PluginBridgeProcessor::prepareToPlay(double sampleRate, int samplesPerBlock)
19
  {
20
+ hostManager.prepareToPlay(sampleRate, samplesPerBlock);
21
  }
22
 
23
  void PluginBridgeProcessor::releaseResources()
24
  {
25
+ hostManager.releaseResources();
26
  }
27
 
28
  void PluginBridgeProcessor::processBlock(juce::AudioBuffer<float>& buffer,
29
+ juce::MidiBuffer& midiMessages)
30
  {
31
  juce::ScopedNoDenormals noDenormals;
32
 
33
+ // Clear extra output channels
34
  auto totalNumInputChannels = getTotalNumInputChannels();
35
  auto totalNumOutputChannels = getTotalNumOutputChannels();
36
  for (auto i = totalNumInputChannels; i < totalNumOutputChannels; ++i)
37
  buffer.clear(i, 0, buffer.getNumSamples());
38
 
39
+ // Route audio through hosted plugin
40
+ hostManager.processBlock(buffer, midiMessages);
 
41
  }
42
 
43
  juce::AudioProcessorEditor* PluginBridgeProcessor::createEditor()
 
45
  return new PluginBridgeEditor(*this);
46
  }
47
 
48
+ void PluginBridgeProcessor::getStateInformation(juce::MemoryBlock& destData)
49
  {
50
+ // Save the path of the hosted plugin so it reloads on session restore
51
+ juce::ValueTree state("PluginBridgeState");
52
+ state.setProperty("hostedPluginPath", hostManager.getLoadedPluginPath(), nullptr);
53
+
54
+ juce::MemoryOutputStream stream(destData, false);
55
+ state.writeToStream(stream);
56
  }
57
 
58
+ void PluginBridgeProcessor::setStateInformation(const void* data, int sizeInBytes)
59
  {
60
+ auto state = juce::ValueTree::readFromData(data, (size_t)sizeInBytes);
61
+ if (state.isValid())
62
+ {
63
+ auto path = state.getProperty("hostedPluginPath").toString();
64
+ if (path.isNotEmpty())
65
+ {
66
+ juce::File pluginFile(path);
67
+ if (pluginFile.exists())
68
+ loadPluginFromFile(pluginFile);
69
+ }
70
+ }
71
  }
72
 
73
  bool PluginBridgeProcessor::isMcpServerRunning() const
 
80
  return mcpServer.getPort();
81
  }
82
 
83
+ void PluginBridgeProcessor::loadPluginFromFile(const juce::File& file)
84
+ {
85
+ hostManager.loadPlugin(file, getSampleRate(), getBlockSize());
86
+ }
87
+
88
  // JUCE plugin entry point
89
  juce::AudioProcessor* JUCE_CALLTYPE createPluginFilter()
90
  {