Browse Source

Scraped a layer of crusty old code from some audio plugin host files

tags/2021-05-28
jules 8 years ago
parent
commit
c6da067ac3
8 changed files with 285 additions and 395 deletions
  1. +32
    -38
      examples/audio plugin host/Source/FilterGraph.cpp
  2. +3
    -3
      examples/audio plugin host/Source/FilterGraph.h
  3. +207
    -281
      examples/audio plugin host/Source/GraphEditorPanel.cpp
  4. +10
    -10
      examples/audio plugin host/Source/GraphEditorPanel.h
  5. +9
    -25
      examples/audio plugin host/Source/InternalFilters.cpp
  6. +14
    -30
      examples/audio plugin host/Source/InternalFilters.h
  7. +9
    -7
      examples/audio plugin host/Source/MainHostWindow.cpp
  8. +1
    -1
      examples/audio plugin host/Source/MainHostWindow.h

+ 32
- 38
examples/audio plugin host/Source/FilterGraph.cpp View File

@@ -34,18 +34,18 @@
//============================================================================== //==============================================================================
const int FilterGraph::midiChannelNumber = 0x1000; const int FilterGraph::midiChannelNumber = 0x1000;
FilterGraph::FilterGraph (AudioPluginFormatManager& formatManager_)
FilterGraph::FilterGraph (AudioPluginFormatManager& fm)
: FileBasedDocument (filenameSuffix, : FileBasedDocument (filenameSuffix,
filenameWildcard, filenameWildcard,
"Load a filter graph", "Load a filter graph",
"Save a filter graph"), "Save a filter graph"),
formatManager (formatManager_), lastUID (0)
formatManager (fm)
{ {
InternalPluginFormat internalFormat; InternalPluginFormat internalFormat;
addFilter (internalFormat.getDescriptionFor (InternalPluginFormat::audioInputFilter), 0.5f, 0.1f);
addFilter (internalFormat.getDescriptionFor (InternalPluginFormat::midiInputFilter), 0.25f, 0.1f);
addFilter (internalFormat.getDescriptionFor (InternalPluginFormat::audioOutputFilter), 0.5f, 0.9f);
addFilter (internalFormat.audioInDesc, { 0.5, 0.1 });
addFilter (internalFormat.midiInDesc, { 0.25, 0.1 });
addFilter (internalFormat.audioOutDesc, { 0.5, 0.9 });
graph.addListener (this); graph.addListener (this);
@@ -69,12 +69,12 @@ int FilterGraph::getNumFilters() const noexcept
return graph.getNumNodes(); return graph.getNumNodes();
} }
AudioProcessorGraph::Node::Ptr FilterGraph::getNode (const int index) const noexcept
AudioProcessorGraph::Node::Ptr FilterGraph::getNode (int index) const noexcept
{ {
return graph.getNode (index); return graph.getNode (index);
} }
AudioProcessorGraph::Node::Ptr FilterGraph::getNodeForId (const uint32 uid) const
AudioProcessorGraph::Node::Ptr FilterGraph::getNodeForId (uint32 uid) const
{ {
return graph.getNodeForId (uid); return graph.getNodeForId (uid);
} }
@@ -90,31 +90,27 @@ AudioProcessorGraph::Node::Ptr FilterGraph::getNodeForName (const String& name)
return nullptr; return nullptr;
} }
void FilterGraph::addFilter (const PluginDescription* desc, double x, double y)
void FilterGraph::addFilter (const PluginDescription& desc, Point<double> p)
{ {
if (desc != nullptr)
struct AsyncCallback : public AudioPluginFormat::InstantiationCompletionCallback
{ {
struct AsyncCallback : public AudioPluginFormat::InstantiationCompletionCallback
{
AsyncCallback (FilterGraph* myself, double inX, double inY)
: owner (myself), posX (inX), posY (inY)
{}
AsyncCallback (FilterGraph& g, Point<double> pos) : owner (g), position (pos)
{}
void completionCallback (AudioPluginInstance* instance, const String& error) override
{
owner->addFilterCallback (instance, error, posX, posY);
}
void completionCallback (AudioPluginInstance* instance, const String& error) override
{
owner.addFilterCallback (instance, error, position);
}
FilterGraph* owner;
double posX, posY;
};
FilterGraph& owner;
Point<double> position;
};
formatManager.createPluginInstanceAsync (*desc, graph.getSampleRate(), graph.getBlockSize(),
new AsyncCallback (this, x, y));
}
formatManager.createPluginInstanceAsync (desc, graph.getSampleRate(), graph.getBlockSize(),
new AsyncCallback (*this, p));
} }
void FilterGraph::addFilterCallback (AudioPluginInstance* instance, const String& error, double x, double y)
void FilterGraph::addFilterCallback (AudioPluginInstance* instance, const String& error, Point<double> pos)
{ {
if (instance == nullptr) if (instance == nullptr)
{ {
@@ -125,12 +121,11 @@ void FilterGraph::addFilterCallback (AudioPluginInstance* instance, const String
else else
{ {
instance->enableAllBuses(); instance->enableAllBuses();
AudioProcessorGraph::Node* node = graph.addNode (instance);
if (node != nullptr)
if (auto* node = graph.addNode (instance))
{ {
node->properties.set ("x", x);
node->properties.set ("y", y);
node->properties.set ("x", pos.x);
node->properties.set ("y", pos.y);
changed(); changed();
} }
} }
@@ -167,11 +162,11 @@ void FilterGraph::setNodePosition (const uint32 nodeId, double x, double y)
Point<double> FilterGraph::getNodePosition (const uint32 nodeId) const Point<double> FilterGraph::getNodePosition (const uint32 nodeId) const
{ {
if (AudioProcessorGraph::Node::Ptr n = graph.getNodeForId (nodeId))
return Point<double> (static_cast<double> (n->properties ["x"]),
static_cast<double> (n->properties ["y"]));
if (auto n = graph.getNodeForId (nodeId))
return { static_cast<double> (n->properties ["x"]),
static_cast<double> (n->properties ["y"]) };
return Point<double>();
return {};
} }
//============================================================================== //==============================================================================
@@ -245,14 +240,13 @@ String FilterGraph::getDocumentTitle()
void FilterGraph::newDocument() void FilterGraph::newDocument()
{ {
clear(); clear();
setFile (File());
setFile ({});
InternalPluginFormat internalFormat; InternalPluginFormat internalFormat;
addFilter (internalFormat.getDescriptionFor (InternalPluginFormat::audioInputFilter), 0.5f, 0.1f);
addFilter (internalFormat.getDescriptionFor (InternalPluginFormat::midiInputFilter), 0.25f, 0.1f);
addFilter (internalFormat.getDescriptionFor (InternalPluginFormat::audioOutputFilter), 0.5f, 0.9f);
addFilter (internalFormat.audioInDesc, { 0.5, 0.1 });
addFilter (internalFormat.midiInDesc, { 0.25, 0.1 });
addFilter (internalFormat.audioOutDesc, { 0.5, 0.9 });
setChangedFlag (false); setChangedFlag (false);
} }


+ 3
- 3
examples/audio plugin host/Source/FilterGraph.h View File

@@ -52,9 +52,9 @@ public:
AudioProcessorGraph::Node::Ptr getNodeForId (uint32 uid) const; AudioProcessorGraph::Node::Ptr getNodeForId (uint32 uid) const;
AudioProcessorGraph::Node::Ptr getNodeForName (const String& name) const; AudioProcessorGraph::Node::Ptr getNodeForName (const String& name) const;
void addFilter (const PluginDescription*, double x, double y);
void addFilter (const PluginDescription&, Point<double>);
void addFilterCallback (AudioPluginInstance* instance, const String& error, double x, double y);
void addFilterCallback (AudioPluginInstance*, const String& error, Point<double> pos);
void removeFilter (const uint32 filterUID); void removeFilter (const uint32 filterUID);
void disconnectFilter (const uint32 filterUID); void disconnectFilter (const uint32 filterUID);
@@ -113,7 +113,7 @@ private:
AudioPluginFormatManager& formatManager; AudioPluginFormatManager& formatManager;
AudioProcessorGraph graph; AudioProcessorGraph graph;
uint32 lastUID;
uint32 lastUID = 0;
uint32 getNextUID() noexcept; uint32 getNextUID() noexcept;
void createNodeFromXml (const XmlElement& xml); void createNodeFromXml (const XmlElement& xml);


+ 207
- 281
examples/audio plugin host/Source/GraphEditorPanel.cpp View File

@@ -32,12 +32,9 @@
//============================================================================== //==============================================================================
class PluginWindow;
static Array <PluginWindow*> activePluginWindows;
static Array<PluginWindow*> activePluginWindows;
PluginWindow::PluginWindow (Component* const pluginEditor,
AudioProcessorGraph::Node* const o,
WindowFormatType t)
PluginWindow::PluginWindow (AudioProcessorEditor* pluginEditor, AudioProcessorGraph::Node* o, WindowFormatType t)
: DocumentWindow (pluginEditor->getName(), : DocumentWindow (pluginEditor->getName(),
LookAndFeel::getDefaultLookAndFeel().findColour (ResizableWindow::backgroundColourId), LookAndFeel::getDefaultLookAndFeel().findColour (ResizableWindow::backgroundColourId),
DocumentWindow::minimiseButton | DocumentWindow::closeButton), DocumentWindow::minimiseButton | DocumentWindow::closeButton),
@@ -79,8 +76,8 @@ void PluginWindow::closeAllCurrentlyOpenWindows()
} }
//============================================================================== //==============================================================================
class ProcessorProgramPropertyComp : public PropertyComponent,
private AudioProcessorListener
struct ProcessorProgramPropertyComp : public PropertyComponent,
private AudioProcessorListener
{ {
public: public:
ProcessorProgramPropertyComp (const String& name, AudioProcessor& p) ProcessorProgramPropertyComp (const String& name, AudioProcessor& p)
@@ -95,21 +92,18 @@ public:
owner.removeListener (this); owner.removeListener (this);
} }
void refresh() { }
void audioProcessorChanged (AudioProcessor*) { }
void audioProcessorParameterChanged (AudioProcessor*, int, float) { }
void refresh() override {}
void audioProcessorChanged (AudioProcessor*) override {}
void audioProcessorParameterChanged (AudioProcessor*, int, float) override {}
private:
AudioProcessor& owner; AudioProcessor& owner;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProcessorProgramPropertyComp) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProcessorProgramPropertyComp)
}; };
class ProgramAudioProcessorEditor : public AudioProcessorEditor
struct ProgramAudioProcessorEditor : public AudioProcessorEditor
{ {
public:
ProgramAudioProcessorEditor (AudioProcessor* const p)
: AudioProcessorEditor (p)
ProgramAudioProcessorEditor (AudioProcessor* p) : AudioProcessorEditor (p)
{ {
jassert (p != nullptr); jassert (p != nullptr);
setOpaque (true); setOpaque (true);
@@ -118,17 +112,17 @@ public:
Array<PropertyComponent*> programs; Array<PropertyComponent*> programs;
const int numPrograms = p->getNumPrograms();
auto numPrograms = p->getNumPrograms();
int totalHeight = 0; int totalHeight = 0;
for (int i = 0; i < numPrograms; ++i) for (int i = 0; i < numPrograms; ++i)
{ {
String name (p->getProgramName (i).trim());
auto name = p->getProgramName (i).trim();
if (name.isEmpty()) if (name.isEmpty())
name = "Unnamed"; name = "Unnamed";
ProcessorProgramPropertyComp* const pc = new ProcessorProgramPropertyComp (name, *p);
auto pc = new ProcessorProgramPropertyComp (name, *p);
programs.add (pc); programs.add (pc);
totalHeight += pc->getPreferredHeight(); totalHeight += pc->getPreferredHeight();
} }
@@ -165,7 +159,7 @@ PluginWindow* PluginWindow::getWindowFor (AudioProcessorGraph::Node* const node,
&& activePluginWindows.getUnchecked(i)->type == type) && activePluginWindows.getUnchecked(i)->type == type)
return activePluginWindows.getUnchecked(i); return activePluginWindows.getUnchecked(i);
AudioProcessor* processor = node->getProcessor();
auto* processor = node->getProcessor();
AudioProcessorEditor* ui = nullptr; AudioProcessorEditor* ui = nullptr;
if (type == Normal) if (type == Normal)
@@ -178,17 +172,14 @@ PluginWindow* PluginWindow::getWindowFor (AudioProcessorGraph::Node* const node,
if (ui == nullptr) if (ui == nullptr)
{ {
if (type == Generic || type == Parameters)
ui = new GenericAudioProcessorEditor (processor);
else if (type == Programs)
ui = new ProgramAudioProcessorEditor (processor);
else if (type == AudioIO)
ui = new FilterIOConfigurationWindow (processor);
if (type == Generic || type == Parameters) ui = new GenericAudioProcessorEditor (processor);
else if (type == Programs) ui = new ProgramAudioProcessorEditor (processor);
else if (type == AudioIO) ui = new FilterIOConfigurationWindow (processor);
} }
if (ui != nullptr) if (ui != nullptr)
{ {
if (AudioPluginInstance* const plugin = dynamic_cast<AudioPluginInstance*> (processor))
if (auto* plugin = dynamic_cast<AudioPluginInstance*> (processor))
ui->setName (plugin->getName()); ui->setName (plugin->getName());
return new PluginWindow (ui, node, type); return new PluginWindow (ui, node, type);
@@ -216,19 +207,14 @@ void PluginWindow::closeButtonPressed()
} }
//============================================================================== //==============================================================================
class PinComponent : public Component,
public SettableTooltipClient
struct PinComponent : public Component,
public SettableTooltipClient
{ {
public:
PinComponent (FilterGraph& graph_,
const uint32 filterID_, const int index_, const bool isInput_)
: filterID (filterID_),
index (index_),
isInput (isInput_),
busIdx (0),
graph (graph_)
PinComponent (FilterGraph& g, uint32 id, int i, bool isIn)
: graph (g), pluginID (id),
index (i), isInput (isIn)
{ {
if (const AudioProcessorGraph::Node::Ptr node = graph.getNodeForId (filterID_))
if (auto node = graph.getNodeForId (pluginID))
{ {
String tip; String tip;
@@ -239,17 +225,14 @@ public:
} }
else else
{ {
const AudioProcessor& processor = *node->getProcessor();
int channel;
channel = processor.getOffsetInBusBufferForAbsoluteChannelIndex (isInput, index, busIdx);
auto& processor = *node->getProcessor();
auto channel = processor.getOffsetInBusBufferForAbsoluteChannelIndex (isInput, index, busIdx);
if (const AudioProcessor::Bus* bus = processor.getBus (isInput, busIdx))
tip = bus->getName() + String (": ")
+ AudioChannelSet::getAbbreviatedChannelTypeName (bus->getCurrentLayout().getTypeOfChannel (channel));
if (auto* bus = processor.getBus (isInput, busIdx))
tip = bus->getName() + ": " + AudioChannelSet::getAbbreviatedChannelTypeName (bus->getCurrentLayout().getTypeOfChannel (channel));
else else
tip = (isInput ? "Main Input: " tip = (isInput ? "Main Input: "
: "Main Output: ") + String (index + 1);
: "Main Output: ") + String (index + 1);
} }
@@ -277,10 +260,8 @@ public:
void mouseDown (const MouseEvent& e) override void mouseDown (const MouseEvent& e) override
{ {
getGraphPanel()->beginConnectorDrag (isInput ? 0 : filterID,
index,
isInput ? filterID : 0,
index,
getGraphPanel()->beginConnectorDrag (isInput ? 0 : pluginID, index,
isInput ? pluginID : 0, index,
e); e);
} }
@@ -294,38 +275,26 @@ public:
getGraphPanel()->endDraggingConnector (e); getGraphPanel()->endDraggingConnector (e);
} }
const uint32 filterID;
const int index;
const bool isInput;
int busIdx;
private:
FilterGraph& graph;
GraphEditorPanel* getGraphPanel() const noexcept GraphEditorPanel* getGraphPanel() const noexcept
{ {
return findParentComponentOfClass<GraphEditorPanel>(); return findParentComponentOfClass<GraphEditorPanel>();
} }
FilterGraph& graph;
const uint32 pluginID;
const int index;
const bool isInput;
int busIdx = 0;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PinComponent) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PinComponent)
}; };
//============================================================================== //==============================================================================
class FilterComponent : public Component
struct FilterComponent : public Component
{ {
public:
FilterComponent (FilterGraph& graph_,
const uint32 filterID_)
: graph (graph_),
filterID (filterID_),
numInputs (0),
numOutputs (0),
pinSize (16),
font (13.0f, Font::bold),
numIns (0),
numOuts (0)
FilterComponent (FilterGraph& g, uint32 id) : graph (g), pluginID (id)
{ {
shadow.setShadowProperties (DropShadow (Colours::black.withAlpha (0.5f), 3, Point<int> (0, 1)));
shadow.setShadowProperties (DropShadow (Colours::black.withAlpha (0.5f), 3, { 0, 1 }));
setComponentEffect (&shadow); setComponentEffect (&shadow);
setSize (150, 60); setSize (150, 60);
@@ -336,6 +305,9 @@ public:
deleteAllChildren(); deleteAllChildren();
} }
FilterComponent (const FilterComponent&) = delete;
FilterComponent& operator= (const FilterComponent&) = delete;
void mouseDown (const MouseEvent& e) override void mouseDown (const MouseEvent& e) override
{ {
originalPos = localPointToGlobal (Point<int>()); originalPos = localPointToGlobal (Point<int>());
@@ -355,22 +327,22 @@ public:
m.addItem (6, "Configure Audio I/O"); m.addItem (6, "Configure Audio I/O");
m.addItem (7, "Test state save/load"); m.addItem (7, "Test state save/load");
const int r = m.show();
auto r = m.show();
if (r == 1) if (r == 1)
{ {
graph.removeFilter (filterID);
graph.removeFilter (pluginID);
return; return;
} }
else if (r == 2) else if (r == 2)
{ {
graph.disconnectFilter (filterID);
graph.disconnectFilter (pluginID);
} }
else else
{ {
if (AudioProcessorGraph::Node::Ptr f = graph.getNodeForId (filterID))
if (auto f = graph.getNodeForId (pluginID))
{ {
AudioProcessor* const processor = f->getProcessor();
auto* processor = f->getProcessor();
jassert (processor != nullptr); jassert (processor != nullptr);
if (r == 7) if (r == 7)
@@ -393,7 +365,7 @@ public:
default: break; default: break;
}; };
if (PluginWindow* const w = PluginWindow::getWindowFor (f, type))
if (auto* w = PluginWindow::getWindowFor (f, type))
w->toFront (true); w->toFront (true);
} }
} }
@@ -405,12 +377,12 @@ public:
{ {
if (! e.mods.isPopupMenu()) if (! e.mods.isPopupMenu())
{ {
Point<int> pos (originalPos + Point<int> (e.getDistanceFromDragStartX(), e.getDistanceFromDragStartY()));
auto pos = originalPos + e.getOffsetFromDragStart();
if (getParentComponent() != nullptr) if (getParentComponent() != nullptr)
pos = getParentComponent()->getLocalPoint (nullptr, pos); pos = getParentComponent()->getLocalPoint (nullptr, pos);
graph.setNodePosition (filterID,
graph.setNodePosition (pluginID,
(pos.getX() + getWidth() / 2) / (double) getParentWidth(), (pos.getX() + getWidth() / 2) / (double) getParentWidth(),
(pos.getY() + getHeight() / 2) / (double) getParentHeight()); (pos.getY() + getHeight() / 2) / (double) getParentHeight());
@@ -426,8 +398,8 @@ public:
} }
else if (e.getNumberOfClicks() == 2) else if (e.getNumberOfClicks() == 2)
{ {
if (const AudioProcessorGraph::Node::Ptr f = graph.getNodeForId (filterID))
if (PluginWindow* const w = PluginWindow::getWindowFor (f, PluginWindow::Normal))
if (auto f = graph.getNodeForId (pluginID))
if (auto* w = PluginWindow::getWindowFor (f, PluginWindow::Normal))
w->toFront (true); w->toFront (true);
} }
} }
@@ -459,54 +431,46 @@ public:
void resized() override void resized() override
{ {
if (AudioProcessorGraph::Node::Ptr f = graph.getNodeForId (filterID))
if (auto f = graph.getNodeForId (pluginID))
{ {
if (AudioProcessor* const processor = f->getProcessor())
if (auto* processor = f->getProcessor())
{ {
for (int i = 0; i < getNumChildComponents(); ++i) for (int i = 0; i < getNumChildComponents(); ++i)
{ {
if (PinComponent* const pc = dynamic_cast<PinComponent*> (getChildComponent(i)))
if (auto* pin = dynamic_cast<PinComponent*> (getChildComponent(i)))
{ {
const bool isInput = pc->isInput;
int busIdx, channelIdx;
channelIdx =
processor->getOffsetInBusBufferForAbsoluteChannelIndex (isInput, pc->index, busIdx);
const bool isInput = pin->isInput;
int busIdx = 0;
processor->getOffsetInBusBufferForAbsoluteChannelIndex (isInput, pin->index, busIdx);
const int total = isInput ? numIns : numOuts; const int total = isInput ? numIns : numOuts;
const int index = pc->index == FilterGraph::midiChannelNumber ? (total - 1) : pc->index;
const int index = pin->index == FilterGraph::midiChannelNumber ? (total - 1) : pin->index;
const float totalSpaces = static_cast<float> (total) + (static_cast<float> (jmax (0, processor->getBusCount (isInput) - 1)) * 0.5f);
const float indexPos = static_cast<float> (index) + (static_cast<float> (busIdx) * 0.5f);
auto totalSpaces = static_cast<float> (total) + (static_cast<float> (jmax (0, processor->getBusCount (isInput) - 1)) * 0.5f);
auto indexPos = static_cast<float> (index) + (static_cast<float> (busIdx) * 0.5f);
pc->setBounds (proportionOfWidth ((1.0f + indexPos) / (totalSpaces + 1.0f)) - pinSize / 2,
pc->isInput ? 0 : (getHeight() - pinSize),
pinSize, pinSize);
pin->setBounds (proportionOfWidth ((1.0f + indexPos) / (totalSpaces + 1.0f)) - pinSize / 2,
pin->isInput ? 0 : (getHeight() - pinSize),
pinSize, pinSize);
} }
} }
} }
} }
} }
void getPinPos (const int index, const bool isInput, float& x, float& y)
Point<float> getPinPos (int index, bool isInput) const
{ {
for (int i = 0; i < getNumChildComponents(); ++i) for (int i = 0; i < getNumChildComponents(); ++i)
{
if (PinComponent* const pc = dynamic_cast<PinComponent*> (getChildComponent(i)))
{
if (pc->index == index && isInput == pc->isInput)
{
x = getX() + pc->getX() + pc->getWidth() * 0.5f;
y = getY() + pc->getY() + pc->getHeight() * 0.5f;
break;
}
}
}
if (auto* pin = dynamic_cast<PinComponent*> (getChildComponent(i)))
if (pin->index == index && isInput == pin->isInput)
return getPosition().toFloat() + pin->getBounds().getCentre().toFloat();
return {};
} }
void update() void update()
{ {
const AudioProcessorGraph::Node::Ptr f (graph.getNodeForId (filterID));
const AudioProcessorGraph::Node::Ptr f (graph.getNodeForId (pluginID));
if (f == nullptr) if (f == nullptr)
{ {
@@ -537,7 +501,7 @@ public:
setName (f->getProcessor()->getName()); setName (f->getProcessor()->getName());
{ {
Point<double> p = graph.getNodePosition (filterID);
Point<double> p = graph.getNodePosition (pluginID);
setCentreRelative ((float) p.x, (float) p.y); setCentreRelative ((float) p.x, (float) p.y);
} }
@@ -550,117 +514,93 @@ public:
int i; int i;
for (i = 0; i < f->getProcessor()->getTotalNumInputChannels(); ++i) for (i = 0; i < f->getProcessor()->getTotalNumInputChannels(); ++i)
addAndMakeVisible (new PinComponent (graph, filterID, i, true));
addAndMakeVisible (new PinComponent (graph, pluginID, i, true));
if (f->getProcessor()->acceptsMidi()) if (f->getProcessor()->acceptsMidi())
addAndMakeVisible (new PinComponent (graph, filterID, FilterGraph::midiChannelNumber, true));
addAndMakeVisible (new PinComponent (graph, pluginID, FilterGraph::midiChannelNumber, true));
for (i = 0; i < f->getProcessor()->getTotalNumOutputChannels(); ++i) for (i = 0; i < f->getProcessor()->getTotalNumOutputChannels(); ++i)
addAndMakeVisible (new PinComponent (graph, filterID, i, false));
addAndMakeVisible (new PinComponent (graph, pluginID, i, false));
if (f->getProcessor()->producesMidi()) if (f->getProcessor()->producesMidi())
addAndMakeVisible (new PinComponent (graph, filterID, FilterGraph::midiChannelNumber, false));
addAndMakeVisible (new PinComponent (graph, pluginID, FilterGraph::midiChannelNumber, false));
resized(); resized();
} }
} }
FilterGraph& graph;
const uint32 filterID;
int numInputs, numOutputs;
private:
int pinSize;
Point<int> originalPos;
Font font;
int numIns, numOuts;
DropShadowEffect shadow;
GraphEditorPanel* getGraphPanel() const noexcept GraphEditorPanel* getGraphPanel() const noexcept
{ {
return findParentComponentOfClass<GraphEditorPanel>(); return findParentComponentOfClass<GraphEditorPanel>();
} }
FilterComponent (const FilterComponent&);
FilterComponent& operator= (const FilterComponent&);
FilterGraph& graph;
const uint32 pluginID;
int numInputs = 0, numOutputs = 0;
int pinSize = 16;
Point<int> originalPos;
Font font { 13.0f, Font::bold };
int numIns = 0, numOuts = 0;
DropShadowEffect shadow;
}; };
//============================================================================== //==============================================================================
class ConnectorComponent : public Component,
public SettableTooltipClient
struct ConnectorComponent : public Component,
public SettableTooltipClient
{ {
public:
ConnectorComponent (FilterGraph& graph_)
: sourceFilterID (0),
destFilterID (0),
sourceFilterChannel (0),
destFilterChannel (0),
graph (graph_),
lastInputX (0),
lastInputY (0),
lastOutputX (0),
lastOutputY (0)
ConnectorComponent (FilterGraph& g) : graph (g)
{ {
setAlwaysOnTop (true); setAlwaysOnTop (true);
} }
void setInput (const uint32 sourceFilterID_, const int sourceFilterChannel_)
void setInput (uint32 newSourceID, int newSourceChannel)
{ {
if (sourceFilterID != sourceFilterID_ || sourceFilterChannel != sourceFilterChannel_)
if (sourceFilterID != newSourceID || sourceFilterChannel != newSourceChannel)
{ {
sourceFilterID = sourceFilterID_;
sourceFilterChannel = sourceFilterChannel_;
sourceFilterID = newSourceID;
sourceFilterChannel = newSourceChannel;
update(); update();
} }
} }
void setOutput (const uint32 destFilterID_, const int destFilterChannel_)
void setOutput (uint32 newDestID, int newDestChannel)
{ {
if (destFilterID != destFilterID_ || destFilterChannel != destFilterChannel_)
if (destFilterID != newDestID || destFilterChannel != newDestChannel)
{ {
destFilterID = destFilterID_;
destFilterChannel = destFilterChannel_;
destFilterID = newDestID;
destFilterChannel = newDestChannel;
update(); update();
} }
} }
void dragStart (int x, int y)
void dragStart (Point<float> pos)
{ {
lastInputX = (float) x;
lastInputY = (float) y;
lastInputPos = pos;
resizeToFit(); resizeToFit();
} }
void dragEnd (int x, int y)
void dragEnd (Point<float> pos)
{ {
lastOutputX = (float) x;
lastOutputY = (float) y;
lastOutputPos = pos;
resizeToFit(); resizeToFit();
} }
void update() void update()
{ {
float x1, y1, x2, y2;
getPoints (x1, y1, x2, y2);
Point<float> p1, p2;
getPoints (p1, p2);
if (lastInputX != x1
|| lastInputY != y1
|| lastOutputX != x2
|| lastOutputY != y2)
{
if (lastInputPos != p1 || lastOutputPos != p2)
resizeToFit(); resizeToFit();
}
} }
void resizeToFit() void resizeToFit()
{ {
float x1, y1, x2, y2;
getPoints (x1, y1, x2, y2);
Point<float> p1, p2;
getPoints (p1, p2);
const Rectangle<int> newBounds ((int) jmin (x1, x2) - 4,
(int) jmin (y1, y2) - 4,
(int) std::abs (x1 - x2) + 8,
(int) std::abs (y1 - y2) + 8);
auto newBounds = Rectangle<float> (p1, p2).expanded (4.0f).getSmallestIntegerContainer();
if (newBounds != getBounds()) if (newBounds != getBounds())
setBounds (newBounds); setBounds (newBounds);
@@ -670,20 +610,18 @@ public:
repaint(); repaint();
} }
void getPoints (float& x1, float& y1, float& x2, float& y2) const
void getPoints (Point<float>& p1, Point<float>& p2) const
{ {
x1 = lastInputX;
y1 = lastInputY;
x2 = lastOutputX;
y2 = lastOutputY;
p1 = lastInputPos;
p2 = lastOutputPos;
if (GraphEditorPanel* const hostPanel = getGraphPanel())
if (auto* hostPanel = getGraphPanel())
{ {
if (FilterComponent* srcFilterComp = hostPanel->getComponentForFilter (sourceFilterID))
srcFilterComp->getPinPos (sourceFilterChannel, false, x1, y1);
if (auto* src = hostPanel->getComponentForFilter (sourceFilterID))
p1 = src->getPinPos (sourceFilterChannel, false);
if (FilterComponent* dstFilterComp = hostPanel->getComponentForFilter (destFilterID))
dstFilterComp->getPinPos (destFilterChannel, true, x2, y2);
if (auto* dest = hostPanel->getComponentForFilter (destFilterID))
p2 = dest->getPinPos (destFilterChannel, true);
} }
} }
@@ -704,10 +642,12 @@ public:
bool hitTest (int x, int y) override bool hitTest (int x, int y) override
{ {
if (hitPath.contains ((float) x, (float) y))
auto pos = Point<int> (x, y).toFloat();
if (hitPath.contains (pos))
{ {
double distanceFromStart, distanceFromEnd; double distanceFromStart, distanceFromEnd;
getDistancesFromEnds (x, y, distanceFromStart, distanceFromEnd);
getDistancesFromEnds (pos, distanceFromStart, distanceFromEnd);
// avoid clicking the connector when over a pin // avoid clicking the connector when over a pin
return distanceFromStart > 7.0 && distanceFromEnd > 7.0; return distanceFromStart > 7.0 && distanceFromEnd > 7.0;
@@ -734,7 +674,7 @@ public:
graph.removeConnection (sourceFilterID, sourceFilterChannel, destFilterID, destFilterChannel); graph.removeConnection (sourceFilterID, sourceFilterChannel, destFilterID, destFilterChannel);
double distanceFromStart, distanceFromEnd; double distanceFromStart, distanceFromEnd;
getDistancesFromEnds (e.x, e.y, distanceFromStart, distanceFromEnd);
getDistancesFromEnds (e.position, distanceFromStart, distanceFromEnd);
const bool isNearerSource = (distanceFromStart < distanceFromEnd); const bool isNearerSource = (distanceFromStart < distanceFromEnd);
getGraphPanel()->beginConnectorDrag (isNearerSource ? 0 : sourceFilterID, getGraphPanel()->beginConnectorDrag (isNearerSource ? 0 : sourceFilterID,
@@ -753,24 +693,20 @@ public:
void resized() override void resized() override
{ {
float x1, y1, x2, y2;
getPoints (x1, y1, x2, y2);
Point<float> p1, p2;
getPoints (p1, p2);
lastInputX = x1;
lastInputY = y1;
lastOutputX = x2;
lastOutputY = y2;
lastInputPos = p1;
lastOutputPos = p2;
x1 -= getX();
y1 -= getY();
x2 -= getX();
y2 -= getY();
p1 -= getPosition().toFloat();
p2 -= getPosition().toFloat();
linePath.clear(); linePath.clear();
linePath.startNewSubPath (x1, y1);
linePath.cubicTo (x1, y1 + (y2 - y1) * 0.33f,
x2, y1 + (y2 - y1) * 0.66f,
x2, y2);
linePath.startNewSubPath (p1);
linePath.cubicTo (p1.x, p1.y + (p2.y - p1.y) * 0.33f,
p2.x, p1.y + (p2.y - p1.y) * 0.66f,
p2.x, p2.y);
PathStrokeType wideStroke (8.0f); PathStrokeType wideStroke (8.0f);
wideStroke.createStrokedPath (hitPath, linePath); wideStroke.createStrokedPath (hitPath, linePath);
@@ -778,8 +714,8 @@ public:
PathStrokeType stroke (2.5f); PathStrokeType stroke (2.5f);
stroke.createStrokedPath (linePath, linePath); stroke.createStrokedPath (linePath, linePath);
const float arrowW = 5.0f;
const float arrowL = 4.0f;
auto arrowW = 5.0f;
auto arrowL = 4.0f;
Path arrow; Path arrow;
arrow.addTriangle (-arrowL, arrowW, arrow.addTriangle (-arrowL, arrowW,
@@ -787,44 +723,40 @@ public:
arrowL, 0.0f); arrowL, 0.0f);
arrow.applyTransform (AffineTransform() arrow.applyTransform (AffineTransform()
.rotated (float_Pi * 0.5f - (float) atan2 (x2 - x1, y2 - y1))
.translated ((x1 + x2) * 0.5f,
(y1 + y2) * 0.5f));
.rotated (float_Pi * 0.5f - (float) atan2 (p2.x - p1.x, p2.y - p1.y))
.translated ((p1 + p2) * 0.5f));
linePath.addPath (arrow); linePath.addPath (arrow);
linePath.setUsingNonZeroWinding (true); linePath.setUsingNonZeroWinding (true);
} }
uint32 sourceFilterID, destFilterID;
int sourceFilterChannel, destFilterChannel;
private:
FilterGraph& graph;
float lastInputX, lastInputY, lastOutputX, lastOutputY;
Path linePath, hitPath;
bool dragging;
GraphEditorPanel* getGraphPanel() const noexcept GraphEditorPanel* getGraphPanel() const noexcept
{ {
return findParentComponentOfClass<GraphEditorPanel>(); return findParentComponentOfClass<GraphEditorPanel>();
} }
void getDistancesFromEnds (int x, int y, double& distanceFromStart, double& distanceFromEnd) const
void getDistancesFromEnds (Point<float> p, double& distanceFromStart, double& distanceFromEnd) const
{ {
float x1, y1, x2, y2;
getPoints (x1, y1, x2, y2);
Point<float> p1, p2;
getPoints (p1, p2);
distanceFromStart = juce_hypot (x - (x1 - getX()), y - (y1 - getY()));
distanceFromEnd = juce_hypot (x - (x2 - getX()), y - (y2 - getY()));
distanceFromStart = p1.getDistanceFrom (p);
distanceFromEnd = p2.getDistanceFrom (p);
} }
FilterGraph& graph;
uint32 sourceFilterID = 0, destFilterID = 0;
int sourceFilterChannel = 0, destFilterChannel = 0;
Point<float> lastInputPos, lastOutputPos;
Path linePath, hitPath;
bool dragging = false;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ConnectorComponent) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ConnectorComponent)
}; };
//============================================================================== //==============================================================================
GraphEditorPanel::GraphEditorPanel (FilterGraph& graph_)
: graph (graph_)
GraphEditorPanel::GraphEditorPanel (FilterGraph& g) : graph (g)
{ {
graph.addChangeListener (this); graph.addChangeListener (this);
setOpaque (true); setOpaque (true);
@@ -848,28 +780,29 @@ void GraphEditorPanel::mouseDown (const MouseEvent& e)
{ {
PopupMenu m; PopupMenu m;
if (MainHostWindow* const mainWindow = findParentComponentOfClass<MainHostWindow>())
if (auto* mainWindow = findParentComponentOfClass<MainHostWindow>())
{ {
mainWindow->addPluginsToMenu (m); mainWindow->addPluginsToMenu (m);
const int r = m.show();
auto r = m.show();
createNewPlugin (mainWindow->getChosenType (r), e.x, e.y);
if (auto* desc = mainWindow->getChosenType (r))
createNewPlugin (*desc, e.position.toInt());
} }
} }
} }
void GraphEditorPanel::createNewPlugin (const PluginDescription* desc, int x, int y)
void GraphEditorPanel::createNewPlugin (const PluginDescription& desc, Point<int> position)
{ {
graph.addFilter (desc, x / (double) getWidth(), y / (double) getHeight());
graph.addFilter (desc, position.toDouble() / Point<double> ((double) getWidth(), (double) getHeight()));
} }
FilterComponent* GraphEditorPanel::getComponentForFilter (const uint32 filterID) const FilterComponent* GraphEditorPanel::getComponentForFilter (const uint32 filterID) const
{ {
for (int i = getNumChildComponents(); --i >= 0;) for (int i = getNumChildComponents(); --i >= 0;)
{ {
if (FilterComponent* const fc = dynamic_cast<FilterComponent*> (getChildComponent (i)))
if (fc->filterID == filterID)
if (auto* fc = dynamic_cast<FilterComponent*> (getChildComponent (i)))
if (fc->pluginID == filterID)
return fc; return fc;
} }
@@ -880,7 +813,7 @@ ConnectorComponent* GraphEditorPanel::getComponentForConnection (const AudioProc
{ {
for (int i = getNumChildComponents(); --i >= 0;) for (int i = getNumChildComponents(); --i >= 0;)
{ {
if (ConnectorComponent* const c = dynamic_cast<ConnectorComponent*> (getChildComponent (i)))
if (auto* c = dynamic_cast<ConnectorComponent*> (getChildComponent (i)))
if (c->sourceFilterID == conn.sourceNodeId if (c->sourceFilterID == conn.sourceNodeId
&& c->destFilterID == conn.destNodeId && c->destFilterID == conn.destNodeId
&& c->sourceFilterChannel == conn.sourceChannelIndex && c->sourceFilterChannel == conn.sourceChannelIndex
@@ -891,17 +824,12 @@ ConnectorComponent* GraphEditorPanel::getComponentForConnection (const AudioProc
return nullptr; return nullptr;
} }
PinComponent* GraphEditorPanel::findPinAt (const int x, const int y) const
PinComponent* GraphEditorPanel::findPinAt (Point<float> pos) const
{ {
for (int i = getNumChildComponents(); --i >= 0;) for (int i = getNumChildComponents(); --i >= 0;)
{
if (FilterComponent* fc = dynamic_cast<FilterComponent*> (getChildComponent (i)))
{
if (PinComponent* pin = dynamic_cast<PinComponent*> (fc->getComponentAt (x - fc->getX(),
y - fc->getY())))
if (auto* fc = dynamic_cast<FilterComponent*> (getChildComponent (i)))
if (auto* pin = dynamic_cast<PinComponent*> (fc->getComponentAt (pos.toInt() - fc->getPosition())))
return pin; return pin;
}
}
return nullptr; return nullptr;
} }
@@ -920,13 +848,13 @@ void GraphEditorPanel::updateComponents()
{ {
for (int i = getNumChildComponents(); --i >= 0;) for (int i = getNumChildComponents(); --i >= 0;)
{ {
if (FilterComponent* const fc = dynamic_cast<FilterComponent*> (getChildComponent (i)))
if (auto* fc = dynamic_cast<FilterComponent*> (getChildComponent (i)))
fc->update(); fc->update();
} }
for (int i = getNumChildComponents(); --i >= 0;) for (int i = getNumChildComponents(); --i >= 0;)
{ {
ConnectorComponent* const cc = dynamic_cast<ConnectorComponent*> (getChildComponent (i));
auto* cc = dynamic_cast<ConnectorComponent*> (getChildComponent (i));
if (cc != nullptr && cc != draggingConnector) if (cc != nullptr && cc != draggingConnector)
{ {
@@ -944,11 +872,11 @@ void GraphEditorPanel::updateComponents()
for (int i = graph.getNumFilters(); --i >= 0;) for (int i = graph.getNumFilters(); --i >= 0;)
{ {
const AudioProcessorGraph::Node::Ptr f (graph.getNode (i));
auto f = graph.getNode (i);
if (getComponentForFilter (f->nodeId) == 0) if (getComponentForFilter (f->nodeId) == 0)
{ {
FilterComponent* const comp = new FilterComponent (graph, f->nodeId);
auto* comp = new FilterComponent (graph, f->nodeId);
addAndMakeVisible (comp); addAndMakeVisible (comp);
comp->update(); comp->update();
} }
@@ -956,11 +884,11 @@ void GraphEditorPanel::updateComponents()
for (int i = graph.getNumConnections(); --i >= 0;) for (int i = graph.getNumConnections(); --i >= 0;)
{ {
const AudioProcessorGraph::Connection* const c = graph.getConnection (i);
auto* c = graph.getConnection (i);
if (getComponentForConnection (*c) == 0) if (getComponentForConnection (*c) == 0)
{ {
ConnectorComponent* const comp = new ConnectorComponent (graph);
auto* comp = new ConnectorComponent (graph);
addAndMakeVisible (comp); addAndMakeVisible (comp);
comp->setInput (c->sourceNodeId, c->sourceChannelIndex); comp->setInput (c->sourceNodeId, c->sourceChannelIndex);
@@ -989,46 +917,43 @@ void GraphEditorPanel::beginConnectorDrag (const uint32 sourceFilterID, const in
void GraphEditorPanel::dragConnector (const MouseEvent& e) void GraphEditorPanel::dragConnector (const MouseEvent& e)
{ {
const MouseEvent e2 (e.getEventRelativeTo (this));
auto e2 = e.getEventRelativeTo (this);
if (draggingConnector != nullptr) if (draggingConnector != nullptr)
{ {
draggingConnector->setTooltip (String());
draggingConnector->setTooltip ({});
int x = e2.x;
int y = e2.y;
auto pos = e2.position;
if (PinComponent* const pin = findPinAt (x, y))
if (auto* pin = findPinAt (pos))
{ {
uint32 srcFilter = draggingConnector->sourceFilterID;
int srcChannel = draggingConnector->sourceFilterChannel;
uint32 dstFilter = draggingConnector->destFilterID;
int dstChannel = draggingConnector->destFilterChannel;
auto srcFilter = draggingConnector->sourceFilterID;
auto srcChannel = draggingConnector->sourceFilterChannel;
auto dstFilter = draggingConnector->destFilterID;
auto dstChannel = draggingConnector->destFilterChannel;
if (srcFilter == 0 && ! pin->isInput) if (srcFilter == 0 && ! pin->isInput)
{ {
srcFilter = pin->filterID;
srcFilter = pin->pluginID;
srcChannel = pin->index; srcChannel = pin->index;
} }
else if (dstFilter == 0 && pin->isInput) else if (dstFilter == 0 && pin->isInput)
{ {
dstFilter = pin->filterID;
dstFilter = pin->pluginID;
dstChannel = pin->index; dstChannel = pin->index;
} }
if (graph.canConnect (srcFilter, srcChannel, dstFilter, dstChannel)) if (graph.canConnect (srcFilter, srcChannel, dstFilter, dstChannel))
{ {
x = pin->getParentComponent()->getX() + pin->getX() + pin->getWidth() / 2;
y = pin->getParentComponent()->getY() + pin->getY() + pin->getHeight() / 2;
pos = (pin->getParentComponent()->getPosition() + pin->getBounds().getCentre()).toFloat();
draggingConnector->setTooltip (pin->getTooltip()); draggingConnector->setTooltip (pin->getTooltip());
} }
} }
if (draggingConnector->sourceFilterID == 0) if (draggingConnector->sourceFilterID == 0)
draggingConnector->dragStart (x, y);
draggingConnector->dragStart (pos);
else else
draggingConnector->dragEnd (x, y);
draggingConnector->dragEnd (pos);
} }
} }
@@ -1037,25 +962,25 @@ void GraphEditorPanel::endDraggingConnector (const MouseEvent& e)
if (draggingConnector == nullptr) if (draggingConnector == nullptr)
return; return;
draggingConnector->setTooltip (String());
draggingConnector->setTooltip ({});
const MouseEvent e2 (e.getEventRelativeTo (this));
auto e2 = e.getEventRelativeTo (this);
uint32 srcFilter = draggingConnector->sourceFilterID;
int srcChannel = draggingConnector->sourceFilterChannel;
uint32 dstFilter = draggingConnector->destFilterID;
int dstChannel = draggingConnector->destFilterChannel;
auto srcFilter = draggingConnector->sourceFilterID;
auto srcChannel = draggingConnector->sourceFilterChannel;
auto dstFilter = draggingConnector->destFilterID;
auto dstChannel = draggingConnector->destFilterChannel;
draggingConnector = nullptr; draggingConnector = nullptr;
if (PinComponent* const pin = findPinAt (e2.x, e2.y))
if (auto* pin = findPinAt (e2.position))
{ {
if (srcFilter == 0) if (srcFilter == 0)
{ {
if (pin->isInput) if (pin->isInput)
return; return;
srcFilter = pin->filterID;
srcFilter = pin->pluginID;
srcChannel = pin->index; srcChannel = pin->index;
} }
else else
@@ -1063,7 +988,7 @@ void GraphEditorPanel::endDraggingConnector (const MouseEvent& e)
if (! pin->isInput) if (! pin->isInput)
return; return;
dstFilter = pin->filterID;
dstFilter = pin->pluginID;
dstChannel = pin->index; dstChannel = pin->index;
} }
@@ -1073,10 +998,9 @@ void GraphEditorPanel::endDraggingConnector (const MouseEvent& e)
//============================================================================== //==============================================================================
class TooltipBar : public Component,
private Timer
struct TooltipBar : public Component,
private Timer
{ {
public:
TooltipBar() TooltipBar()
{ {
startTimer (100); startTimer (100);
@@ -1091,13 +1015,12 @@ public:
void timerCallback() override void timerCallback() override
{ {
Component* const underMouse = Desktop::getInstance().getMainMouseSource().getComponentUnderMouse();
TooltipClient* const ttc = dynamic_cast<TooltipClient*> (underMouse);
String newTip; String newTip;
if (ttc != nullptr && ! (underMouse->isMouseButtonDown() || underMouse->isCurrentlyBlockedByAnotherModalComponent()))
newTip = ttc->getTooltip();
if (auto* underMouse = Desktop::getInstance().getMainMouseSource().getComponentUnderMouse())
if (auto* ttc = dynamic_cast<TooltipClient*> (underMouse))
if (! (underMouse->isMouseButtonDown() || underMouse->isCurrentlyBlockedByAnotherModalComponent()))
newTip = ttc->getTooltip();
if (newTip != tip) if (newTip != tip)
{ {
@@ -1106,21 +1029,19 @@ public:
} }
} }
private:
String tip; String tip;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TooltipBar) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TooltipBar)
}; };
//============================================================================== //==============================================================================
GraphDocumentComponent::GraphDocumentComponent (AudioPluginFormatManager& formatManager,
AudioDeviceManager* deviceManager_)
: graph (new FilterGraph (formatManager)), deviceManager (deviceManager_),
GraphDocumentComponent::GraphDocumentComponent (AudioPluginFormatManager& fm, AudioDeviceManager& dm)
: graph (new FilterGraph (fm)), deviceManager (dm),
graphPlayer (getAppProperties().getUserSettings()->getBoolValue ("doublePrecisionProcessing", false)) graphPlayer (getAppProperties().getUserSettings()->getBoolValue ("doublePrecisionProcessing", false))
{ {
addAndMakeVisible (graphPanel = new GraphEditorPanel (*graph)); addAndMakeVisible (graphPanel = new GraphEditorPanel (*graph));
deviceManager->addChangeListener (graphPanel);
deviceManager.addChangeListener (graphPanel);
graphPlayer.setProcessor (&graph->getGraph()); graphPlayer.setProcessor (&graph->getGraph());
@@ -1131,8 +1052,8 @@ GraphDocumentComponent::GraphDocumentComponent (AudioPluginFormatManager& format
addAndMakeVisible (statusBar = new TooltipBar()); addAndMakeVisible (statusBar = new TooltipBar());
deviceManager->addAudioCallback (&graphPlayer);
deviceManager->addMidiInputCallback (String(), &graphPlayer.getMidiMessageCollector());
deviceManager.addAudioCallback (&graphPlayer);
deviceManager.addMidiInputCallback (String(), &graphPlayer.getMidiMessageCollector());
graphPanel->updateComponents(); graphPanel->updateComponents();
} }
@@ -1154,9 +1075,9 @@ void GraphDocumentComponent::resized()
keyboardComp->setBounds (0, getHeight() - keysHeight, getWidth(), keysHeight); keyboardComp->setBounds (0, getHeight() - keysHeight, getWidth(), keysHeight);
} }
void GraphDocumentComponent::createNewPlugin (const PluginDescription* desc, int x, int y)
void GraphDocumentComponent::createNewPlugin (const PluginDescription& desc, Point<int> pos)
{ {
graphPanel->createNewPlugin (desc, x, y);
graphPanel->createNewPlugin (desc, pos);
} }
void GraphDocumentComponent::unfocusKeyboardComponent() void GraphDocumentComponent::unfocusKeyboardComponent()
@@ -1166,12 +1087,17 @@ void GraphDocumentComponent::unfocusKeyboardComponent()
void GraphDocumentComponent::releaseGraph() void GraphDocumentComponent::releaseGraph()
{ {
deviceManager->removeAudioCallback (&graphPlayer);
deviceManager->removeMidiInputCallback (String(), &graphPlayer.getMidiMessageCollector());
deviceManager->removeChangeListener (graphPanel);
deviceManager.removeAudioCallback (&graphPlayer);
deviceManager.removeMidiInputCallback (String(), &graphPlayer.getMidiMessageCollector());
deviceManager.removeChangeListener (graphPanel);
deleteAllChildren(); deleteAllChildren();
graphPlayer.setProcessor (nullptr); graphPlayer.setProcessor (nullptr);
graph = nullptr; graph = nullptr;
} }
void GraphDocumentComponent::setDoublePrecision (bool doublePrecision)
{
graphPlayer.setDoublePrecisionProcessing (doublePrecision);
}

+ 10
- 10
examples/audio plugin host/Source/GraphEditorPanel.h View File

@@ -28,9 +28,9 @@
#include "FilterGraph.h" #include "FilterGraph.h"
class FilterComponent;
class ConnectorComponent;
class PinComponent;
struct FilterComponent;
struct ConnectorComponent;
struct PinComponent;
//============================================================================== //==============================================================================
@@ -47,11 +47,11 @@ public:
void paint (Graphics& g); void paint (Graphics& g);
void mouseDown (const MouseEvent& e); void mouseDown (const MouseEvent& e);
void createNewPlugin (const PluginDescription* desc, int x, int y);
void createNewPlugin (const PluginDescription&, Point<int> position);
FilterComponent* getComponentForFilter (uint32 filterID) const; FilterComponent* getComponentForFilter (uint32 filterID) const;
ConnectorComponent* getComponentForConnection (const AudioProcessorGraph::Connection& conn) const; ConnectorComponent* getComponentForConnection (const AudioProcessorGraph::Connection& conn) const;
PinComponent* findPinAt (int x, int y) const;
PinComponent* findPinAt (Point<float>) const;
void resized(); void resized();
void changeListenerCallback (ChangeBroadcaster*); void changeListenerCallback (ChangeBroadcaster*);
@@ -84,12 +84,12 @@ class GraphDocumentComponent : public Component
public: public:
//============================================================================== //==============================================================================
GraphDocumentComponent (AudioPluginFormatManager& formatManager, GraphDocumentComponent (AudioPluginFormatManager& formatManager,
AudioDeviceManager* deviceManager);
AudioDeviceManager& deviceManager);
~GraphDocumentComponent(); ~GraphDocumentComponent();
//============================================================================== //==============================================================================
void createNewPlugin (const PluginDescription* desc, int x, int y);
inline void setDoublePrecision (bool doublePrecision) { graphPlayer.setDoublePrecisionProcessing (doublePrecision); }
void createNewPlugin (const PluginDescription&, Point<int> position);
void setDoublePrecision (bool doublePrecision);
//============================================================================== //==============================================================================
ScopedPointer<FilterGraph> graph; ScopedPointer<FilterGraph> graph;
@@ -105,7 +105,7 @@ public:
private: private:
//============================================================================== //==============================================================================
AudioDeviceManager* deviceManager;
AudioDeviceManager& deviceManager;
AudioProcessorPlayer graphPlayer; AudioProcessorPlayer graphPlayer;
MidiKeyboardState keyState; MidiKeyboardState keyState;
@@ -134,7 +134,7 @@ public:
NumTypes NumTypes
}; };
PluginWindow (Component* pluginEditor, AudioProcessorGraph::Node*, WindowFormatType);
PluginWindow (AudioProcessorEditor*, AudioProcessorGraph::Node*, WindowFormatType);
~PluginWindow(); ~PluginWindow();
static PluginWindow* getWindowFor (AudioProcessorGraph::Node*, WindowFormatType); static PluginWindow* getWindowFor (AudioProcessorGraph::Node*, WindowFormatType);


+ 9
- 25
examples/audio plugin host/Source/InternalFilters.cpp View File

@@ -54,17 +54,13 @@ void InternalPluginFormat::createPluginInstance (const PluginDescription& desc,
void* userData, void* userData,
void (*callback) (void*, AudioPluginInstance*, const String&)) void (*callback) (void*, AudioPluginInstance*, const String&))
{ {
AudioPluginInstance* retval = nullptr;
if (desc.name == audioOutDesc.name)
retval = new AudioProcessorGraph::AudioGraphIOProcessor (AudioProcessorGraph::AudioGraphIOProcessor::audioOutputNode);
AudioPluginInstance* p = nullptr;
if (desc.name == audioInDesc.name)
retval = new AudioProcessorGraph::AudioGraphIOProcessor (AudioProcessorGraph::AudioGraphIOProcessor::audioInputNode);
if (desc.name == audioOutDesc.name) p = new AudioProcessorGraph::AudioGraphIOProcessor (AudioProcessorGraph::AudioGraphIOProcessor::audioOutputNode);
if (desc.name == audioInDesc.name) p = new AudioProcessorGraph::AudioGraphIOProcessor (AudioProcessorGraph::AudioGraphIOProcessor::audioInputNode);
if (desc.name == midiInDesc.name) p = new AudioProcessorGraph::AudioGraphIOProcessor (AudioProcessorGraph::AudioGraphIOProcessor::midiInputNode);
if (desc.name == midiInDesc.name)
retval = new AudioProcessorGraph::AudioGraphIOProcessor (AudioProcessorGraph::AudioGraphIOProcessor::midiInputNode);
callback (userData, retval, retval == nullptr ? NEEDS_TRANS ("Invalid internal filter name") : String());
callback (userData, p, p == nullptr ? NEEDS_TRANS ("Invalid internal filter name") : String());
} }
bool InternalPluginFormat::requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const noexcept bool InternalPluginFormat::requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const noexcept
@@ -72,21 +68,9 @@ bool InternalPluginFormat::requiresUnblockedMessageThreadDuringCreation (const P
return false; return false;
} }
const PluginDescription* InternalPluginFormat::getDescriptionFor (const InternalFilterType type)
{
switch (type)
{
case audioInputFilter: return &audioInDesc;
case audioOutputFilter: return &audioOutDesc;
case midiInputFilter: return &midiInDesc;
default: break;
}
return 0;
}
void InternalPluginFormat::getAllTypes (OwnedArray <PluginDescription>& results)
void InternalPluginFormat::getAllTypes (OwnedArray<PluginDescription>& results)
{ {
for (int i = 0; i < (int) endOfFilterTypes; ++i)
results.add (new PluginDescription (*getDescriptionFor ((InternalFilterType) i)));
results.add (new PluginDescription (audioInDesc));
results.add (new PluginDescription (audioOutDesc));
results.add (new PluginDescription (midiInDesc));
} }

+ 14
- 30
examples/audio plugin host/Source/InternalFilters.h View File

@@ -41,41 +41,25 @@ public:
~InternalPluginFormat() {} ~InternalPluginFormat() {}
//============================================================================== //==============================================================================
enum InternalFilterType
{
audioInputFilter = 0,
audioOutputFilter,
midiInputFilter,
PluginDescription audioInDesc, audioOutDesc, midiInDesc;
endOfFilterTypes
};
const PluginDescription* getDescriptionFor (const InternalFilterType type);
void getAllTypes (OwnedArray <PluginDescription>& results);
void getAllTypes (OwnedArray<PluginDescription>&);
//============================================================================== //==============================================================================
String getName() const override { return "Internal"; }
bool fileMightContainThisPluginType (const String&) override { return true; }
FileSearchPath getDefaultLocationsToSearch() override { return FileSearchPath(); }
bool canScanForPlugins() const override { return false; }
void findAllTypesForFile (OwnedArray <PluginDescription>&, const String&) override {}
bool doesPluginStillExist (const PluginDescription&) override { return true; }
String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) override { return fileOrIdentifier; }
bool pluginNeedsRescanning (const PluginDescription&) override { return false; }
StringArray searchPathsForPlugins (const FileSearchPath&, bool, bool) override { return StringArray(); }
String getName() const override { return "Internal"; }
bool fileMightContainThisPluginType (const String&) override { return true; }
FileSearchPath getDefaultLocationsToSearch() override { return {}; }
bool canScanForPlugins() const override { return false; }
void findAllTypesForFile (OwnedArray <PluginDescription>&, const String&) override {}
bool doesPluginStillExist (const PluginDescription&) override { return true; }
String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) override { return fileOrIdentifier; }
bool pluginNeedsRescanning (const PluginDescription&) override { return false; }
StringArray searchPathsForPlugins (const FileSearchPath&, bool, bool) override { return {}; }
private: private:
//============================================================================== //==============================================================================
void createPluginInstance (const PluginDescription& description,
double initialSampleRate,
int initialBufferSize,
void* userData,
void (*callback) (void*, AudioPluginInstance*, const String&)) override;
void createPluginInstance (const PluginDescription&, double initialSampleRate, int initialBufferSize,
void* userData, void (*callback) (void*, AudioPluginInstance*, const String&)) override;
bool requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const noexcept override; bool requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const noexcept override;
private:
//==============================================================================
PluginDescription audioInDesc;
PluginDescription audioOutDesc;
PluginDescription midiInDesc;
}; };

+ 9
- 7
examples/audio plugin host/Source/MainHostWindow.cpp View File

@@ -91,7 +91,7 @@ MainHostWindow::MainHostWindow()
setResizeLimits (500, 400, 10000, 10000); setResizeLimits (500, 400, 10000, 10000);
centreWithSize (800, 600); centreWithSize (800, 600);
setContentOwned (new GraphDocumentComponent (formatManager, &deviceManager), false);
setContentOwned (new GraphDocumentComponent (formatManager, deviceManager), false);
restoreWindowStateFromString (getAppProperties().getUserSettings()->getValue ("mainWindowPos")); restoreWindowStateFromString (getAppProperties().getUserSettings()->getValue ("mainWindowPos"));
@@ -294,9 +294,10 @@ void MainHostWindow::menuItemSelected (int menuItemID, int /*topLevelMenuIndex*/
} }
else else
{ {
createPlugin (getChosenType (menuItemID),
proportionOfWidth (0.3f + Random::getSystemRandom().nextFloat() * 0.6f),
proportionOfHeight (0.3f + Random::getSystemRandom().nextFloat() * 0.6f));
if (auto* desc = getChosenType (menuItemID))
createPlugin (*desc,
{ proportionOfWidth (0.3f + Random::getSystemRandom().nextFloat() * 0.6f),
proportionOfHeight (0.3f + Random::getSystemRandom().nextFloat() * 0.6f) });
} }
} }
@@ -307,10 +308,10 @@ void MainHostWindow::menuBarActivated (bool isActivated)
graphEditor->unfocusKeyboardComponent(); graphEditor->unfocusKeyboardComponent();
} }
void MainHostWindow::createPlugin (const PluginDescription* desc, int x, int y)
void MainHostWindow::createPlugin (const PluginDescription& desc, Point<int> pos)
{ {
if (auto* graphEditor = getGraphEditor()) if (auto* graphEditor = getGraphEditor())
graphEditor->createNewPlugin (desc, x, y);
graphEditor->createNewPlugin (desc, pos);
} }
void MainHostWindow::addPluginsToMenu (PopupMenu& m) const void MainHostWindow::addPluginsToMenu (PopupMenu& m) const
@@ -555,7 +556,8 @@ void MainHostWindow::filesDropped (const StringArray& files, int x, int y)
auto pos = graphEditor->getLocalPoint (this, Point<int> (x, y)); auto pos = graphEditor->getLocalPoint (this, Point<int> (x, y));
for (int i = 0; i < jmin (5, typesFound.size()); ++i) for (int i = 0; i < jmin (5, typesFound.size()); ++i)
createPlugin (typesFound.getUnchecked(i), pos.x, pos.y);
if (auto* desc = typesFound.getUnchecked(i))
createPlugin (*desc, pos);
} }
} }
} }


+ 1
- 1
examples/audio plugin host/Source/MainHostWindow.h View File

@@ -83,7 +83,7 @@ public:
bool tryToQuitApplication(); bool tryToQuitApplication();
void createPlugin (const PluginDescription*, int x, int y);
void createPlugin (const PluginDescription&, Point<int> pos);
void addPluginsToMenu (PopupMenu&) const; void addPluginsToMenu (PopupMenu&) const;
const PluginDescription* getChosenType (int menuID) const; const PluginDescription* getChosenType (int menuID) const;


Loading…
Cancel
Save