From de811b897ac08acccfd1dcb58ce50c34fbd111c2 Mon Sep 17 00:00:00 2001
From: Aaron Cuevas Lopez <aacuelo@teleco.upv.es>
Date: Thu, 12 Jan 2017 04:28:03 +0100
Subject: [PATCH] Fix issues in the phase detector

---
 .../Plugins/PhaseDetector/PhaseDetector.cpp   | 77 ++++++++++---------
 Source/Plugins/PhaseDetector/PhaseDetector.h  |  4 +-
 .../PhaseDetector/PhaseDetectorEditor.cpp     | 12 ++-
 Source/Processors/Channel/MetaData.cpp        |  7 +-
 Source/Processors/Channel/MetaData.h          |  1 +
 5 files changed, 59 insertions(+), 42 deletions(-)

diff --git a/Source/Plugins/PhaseDetector/PhaseDetector.cpp b/Source/Plugins/PhaseDetector/PhaseDetector.cpp
index 3447a1272..c1612d792 100644
--- a/Source/Plugins/PhaseDetector/PhaseDetector.cpp
+++ b/Source/Plugins/PhaseDetector/PhaseDetector.cpp
@@ -34,6 +34,7 @@ PhaseDetector::PhaseDetector()
     , fallingNeg            (false)
 {
     setProcessorType (PROCESSOR_TYPE_FILTER);
+	lastNumInputs = 0;
 }
 
 
@@ -51,40 +52,6 @@ AudioProcessorEditor* PhaseDetector::createEditor()
     return editor;
 }
 
-void PhaseDetector::createEventChannels()
-{
-	moduleEventChannels.clear();
-	for (int i = 0; i < modules.size(); i++)
-	{
-		const DataChannel* in = getDataChannel(modules[i].inputChan);
-		EventChannel* ev = new EventChannel(EventChannel::TTL, 8, 1, in->getSampleRate(), this);
-		ev->setName("Phase detector output " + String(i+1));
-		ev->setDescription("Triggers when the input signal mets a given phase condition");
-		String typeDesc;
-		switch (modules[i].type)
-		{
-		case PEAK: typeDesc = "Positive peak"; break;
-		case FALLING_ZERO: typeDesc = "Zero crossing with negative slope"; break;
-		case TROUGH: typeDesc = "Negative peak"; break;
-		case RISING_ZERO: typeDesc = "Zero crossing with positive slope"; break;
-		default: typeDesc = "No phase selected"; break;
-		}
-		MetaDataDescriptor md(MetaDataDescriptor::CHAR, 34, "Phase Type", "Description of the phase condition", "string.extraInfo");
-		MetaDataValue mv(md);
-		mv.setValue(typeDesc);
-		ev->addMetaData(md, mv);
-		md = MetaDataDescriptor(MetaDataDescriptor::UINT16, 3, "Source Channel",
-			"Index at its source, Source processor ID and Sub Processor index of the channel that triggers this event", "source.channel.identifier.full");
-		mv = MetaDataValue(md);
-		uint16 sourceInfo[3];
-		sourceInfo[0] = in->getSourceIndex();
-		sourceInfo[1] = in->getSourceNodeID();
-		sourceInfo[3] = in->getSubProcessorIdx();
-		mv.setValue(static_cast<const uint16*>(sourceInfo));
-		ev->addMetaData(md, mv);
-	}
-}
-
 void PhaseDetector::addModule()
 {
     DetectorModule m = DetectorModule();
@@ -164,9 +131,49 @@ void PhaseDetector::setParameter (int parameterIndex, float newValue)
     }
 }
 
-
+//Usually, to be more ordered, we'd create the event channels overriding the createEventChannels() method.
+//However, since in this case there a couple of things we need to do prior to creating the channels (resetting
+//the modules input channels in case the channel count changes, to reflect the same change on the combo box)
+//we think it's better to do all in this method, that gets always called after all the create*Channels.
 void PhaseDetector::updateSettings()
 {
+	moduleEventChannels.clear();
+	for (int i = 0; i < modules.size(); i++)
+	{
+		if (getNumInputs() != lastNumInputs)
+			modules.getReference(i).inputChan = -1;
+		const DataChannel* in = getDataChannel(modules[i].inputChan);
+		EventChannel* ev = new EventChannel(EventChannel::TTL, 8, 1, (in) ? in->getSampleRate() : CoreServices::getGlobalSampleRate(), this);
+		ev->setName("Phase detector output " + String(i + 1));
+		ev->setDescription("Triggers when the input signal mets a given phase condition");
+		String typeDesc;
+		switch (modules[i].type)
+		{
+		case PEAK: typeDesc = "Positive peak"; break;
+		case FALLING_ZERO: typeDesc = "Zero crossing with negative slope"; break;
+		case TROUGH: typeDesc = "Negative peak"; break;
+		case RISING_ZERO: typeDesc = "Zero crossing with positive slope"; break;
+		default: typeDesc = "No phase selected"; break;
+		}
+		MetaDataDescriptor md(MetaDataDescriptor::CHAR, 34, "Phase Type", "Description of the phase condition", "string.extraInfo");
+		MetaDataValue mv(md);
+		mv.setValue(typeDesc);
+		ev->addMetaData(md, mv);
+		if (in)
+		{
+			md = MetaDataDescriptor(MetaDataDescriptor::UINT16, 3, "Source Channel",
+				"Index at its source, Source processor ID and Sub Processor index of the channel that triggers this event", "source.channel.identifier.full");
+			mv = MetaDataValue(md);
+			uint16 sourceInfo[3];
+			sourceInfo[0] = in->getSourceIndex();
+			sourceInfo[1] = in->getSourceNodeID();
+			sourceInfo[3] = in->getSubProcessorIdx();
+			mv.setValue(static_cast<const uint16*>(sourceInfo));
+			ev->addMetaData(md, mv);
+		}
+		eventChannelArray.add(ev);
+		moduleEventChannels.add(ev);
+	}
 }
 
 
diff --git a/Source/Plugins/PhaseDetector/PhaseDetector.h b/Source/Plugins/PhaseDetector/PhaseDetector.h
index bd5b44954..a3d928484 100644
--- a/Source/Plugins/PhaseDetector/PhaseDetector.h
+++ b/Source/Plugins/PhaseDetector/PhaseDetector.h
@@ -43,7 +43,7 @@ public:
     ~PhaseDetector();
 
     AudioProcessorEditor* createEditor() override;
-    bool hasEditor() const override { return false; }
+    bool hasEditor() const override { return true; }
 
     void process (AudioSampleBuffer& buffer) override;
 
@@ -52,7 +52,6 @@ public:
     bool enable() override;
 
     void updateSettings() override;
-	void createEventChannels() override;
 
     void addModule();
     void setActiveModule (int);
@@ -97,6 +96,7 @@ private:
     bool risingNeg;
     bool fallingPos;
     bool fallingNeg;
+	int lastNumInputs;
 
 	Array<const EventChannel*> moduleEventChannels;
 
diff --git a/Source/Plugins/PhaseDetector/PhaseDetectorEditor.cpp b/Source/Plugins/PhaseDetector/PhaseDetectorEditor.cpp
index e17e188d1..d9ff04ccc 100644
--- a/Source/Plugins/PhaseDetector/PhaseDetectorEditor.cpp
+++ b/Source/Plugins/PhaseDetector/PhaseDetectorEditor.cpp
@@ -74,7 +74,8 @@ PhaseDetectorEditor::PhaseDetectorEditor(GenericProcessor* parentNode, bool useD
     backgroundColours.add(Colours::magenta);
     backgroundColours.add(Colours::blue);
 
-    plusButton->setToggleState(true, sendNotification);
+    //plusButton->setToggleState(true, sendNotification);
+	addDetector();
 
     //interfaces.clear();
 
@@ -126,7 +127,7 @@ void PhaseDetectorEditor::buttonEvent(Button* button)
     {
 
         addDetector();
-
+		CoreServices::updateSignalChain(this);
     }
 
 }
@@ -247,7 +248,7 @@ DetectorInterface::DetectorInterface(PhaseDetector* pd, Colour c, int id) :
     inputSelector = new ComboBox();
     inputSelector->setBounds(140,5,50,20);
     inputSelector->addItem("-",1);
-    inputSelector->setSelectedId(1);
+    inputSelector->setSelectedId(1, dontSendNotification);
     inputSelector->addListener(this);
     addAndMakeVisible(inputSelector);
 
@@ -319,7 +320,10 @@ void DetectorInterface::comboBoxChanged(ComboBox* c)
     }
 
     processor->setParameter(parameterIndex, (float) c->getSelectedId() - 2);
-
+	if (c == inputSelector)
+	{
+		CoreServices::updateSignalChain(processor->getEditor());
+	}
 }
 
 void DetectorInterface::buttonClicked(Button* b)
diff --git a/Source/Processors/Channel/MetaData.cpp b/Source/Processors/Channel/MetaData.cpp
index 7fa9aee1c..b836f14bc 100644
--- a/Source/Processors/Channel/MetaData.cpp
+++ b/Source/Processors/Channel/MetaData.cpp
@@ -170,7 +170,7 @@ MetaDataValue::MetaDataValue(const MetaDataValue& v)
 	m_type(v.m_type), m_length(v.m_length), m_size(v.m_size)
 {
 	allocSpace();
-	setValue(v.m_data.getData());
+	setValue(static_cast<const void*>(v.m_data.getData()));
 }
 
 MetaDataValue& MetaDataValue::operator=(const MetaDataValue& v)
@@ -253,6 +253,11 @@ void MetaDataValue::getValue(Array<T>& data) const
 	data.addArray(reinterpret_cast<const T*>(m_data.getData()), m_length);
 }
 
+void MetaDataValue::setValue(const void* data)
+{
+	memcpy(m_data.getData(), data, m_size);
+}
+
 //Actual template instantiations at the end of the file
 
 //MetaDataInfoObject
diff --git a/Source/Processors/Channel/MetaData.h b/Source/Processors/Channel/MetaData.h
index 5dd992ba3..86edf03e3 100644
--- a/Source/Processors/Channel/MetaData.h
+++ b/Source/Processors/Channel/MetaData.h
@@ -151,6 +151,7 @@ public:
 
 private:
 	MetaDataValue() = delete;
+	void setValue(const void* data);
 	void allocSpace();
 	HeapBlock<char> m_data;
 	MetaDataDescriptor::MetaDataTypes m_type;
-- 
GitLab