From 2a8d0efc561554e81bbf698737c83d5943cf1e15 Mon Sep 17 00:00:00 2001
From: jsiegle <jsiegle@mit.edu>
Date: Sun, 4 Mar 2012 20:20:49 -0500
Subject: [PATCH] Individual channel parameters are editable in SignalGenerator

Problem:
- There's not yet a way to get the parameters for each channel
after it's clicked
---
 Builds/Linux/Makefile                         |  4 +-
 .../open-ephys.xcodeproj/project.pbxproj      |  2 +
 Source/Processors/Editors/GenericEditor.cpp   | 31 +++++++++--
 Source/Processors/Editors/GenericEditor.h     |  2 +
 .../Editors/SignalGeneratorEditor.cpp         | 21 ++++++--
 Source/Processors/GenericProcessor.cpp        | 11 +++-
 Source/Processors/GenericProcessor.h          |  7 ++-
 Source/Processors/SignalGenerator.cpp         | 54 ++++++++++++-------
 Source/Processors/SignalGenerator.h           | 12 +++--
 open-ephys.jucer                              |  3 +-
 10 files changed, 111 insertions(+), 36 deletions(-)

diff --git a/Builds/Linux/Makefile b/Builds/Linux/Makefile
index 03ddd617d..151287fe1 100644
--- a/Builds/Linux/Makefile
+++ b/Builds/Linux/Makefile
@@ -19,7 +19,7 @@ ifeq ($(CONFIG),Debug)
   OUTDIR := build
   CPPFLAGS := $(DEPFLAGS) -D "LINUX=1" -D "DEBUG=1" -D "_DEBUG=1" -D "JUCER_LINUX_MAKE_7346DA2A=1" -I "/usr/include" -I "/usr/include/freetype2"
   CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g -ggdb -O0
-  CXXFLAGS += $(CFLAGS) -D__STDC_LIMIT_MACROS
+  CXXFLAGS += $(CFLAGS) -export-dynamic
   LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -L"/usr/X11R6/lib/" -L"../../JuceLibraryCode/bin" -lfreetype -lpthread -lrt -lX11 -lGL -lGLU -lXinerama -lasound -lftdi -lftgl
   LDDEPS :=
   RESFLAGS :=  -D "LINUX=1" -D "DEBUG=1" -D "_DEBUG=1" -D "JUCER_LINUX_MAKE_7346DA2A=1" -I "/usr/include" -I "/usr/include/freetype2"
@@ -34,7 +34,7 @@ ifeq ($(CONFIG),Release)
   OUTDIR := build
   CPPFLAGS := $(DEPFLAGS) -D "LINUX=1" -D "NDEBUG=1" -D "JUCER_LINUX_MAKE_7346DA2A=1" -I "/usr/include" -I "/usr/include/freetype2"
   CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -O3
-  CXXFLAGS += $(CFLAGS) -D__STDC_LIMIT_MACROS
+  CXXFLAGS += $(CFLAGS) -export-dynamic
   LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -L"/usr/X11R6/lib/" -L"../../JuceLibraryCode/bin" -lfreetype -lpthread -lrt -lX11 -lGL -lGLU -lXinerama -lasound -lftdi -lftgl
   LDDEPS :=
   RESFLAGS :=  -D "LINUX=1" -D "NDEBUG=1" -D "JUCER_LINUX_MAKE_7346DA2A=1" -I "/usr/include" -I "/usr/include/freetype2"
diff --git a/Builds/MacOSX/open-ephys.xcodeproj/project.pbxproj b/Builds/MacOSX/open-ephys.xcodeproj/project.pbxproj
index 0489fc54f..e6dfea255 100644
--- a/Builds/MacOSX/open-ephys.xcodeproj/project.pbxproj
+++ b/Builds/MacOSX/open-ephys.xcodeproj/project.pbxproj
@@ -325,6 +325,7 @@
 		1640CC946EDFD5EC9A321954 = { isa = PBXGroup; children = (
 				2D8E1C366F21D3C8FE662382,
 				4E8DA551A1B5D7A2B1229181 ); name = Resources; sourceTree = "<group>"; };
+		21721C7CD4451993F10354CB = { isa = PBXGroup; children = (  ); name = Plugins; sourceTree = "<group>"; };
 		8F98BACF97340868397BA4BB = { isa = PBXGroup; children = (
 				673778A175624FC9F52E7A15,
 				2EAE0475B719C3233AD8BB35 ); name = Network; sourceTree = "<group>"; };
@@ -479,6 +480,7 @@
 				2A78F719BAFBDCD63AE9A88A,
 				DB605BA15852F367DF625300 ); name = UI; sourceTree = "<group>"; };
 		98D3BECE25EB3CF1F64F54B4 = { isa = PBXGroup; children = (
+				21721C7CD4451993F10354CB,
 				CA0A1584725D21237DBCD70A,
 				63992CB3AC42F91A51135EAC,
 				8F98BACF97340868397BA4BB,
diff --git a/Source/Processors/Editors/GenericEditor.cpp b/Source/Processors/Editors/GenericEditor.cpp
index 842b46e2e..a6d26414e 100644
--- a/Source/Processors/Editors/GenericEditor.cpp
+++ b/Source/Processors/Editors/GenericEditor.cpp
@@ -83,6 +83,11 @@ GenericEditor::GenericEditor (GenericProcessor* owner)//, FilterViewport* vp)
 		backgroundColor = Colour(255, 89, 0);//Colour(int(1.0*255.0f),int(0.5*255.0f),int(0.0*255.0f));
 
 
+	paramsChannels.clear();
+	audioChannels.clear();
+	recordChannels.clear();
+
+
 	fadeIn();
 }
 
@@ -311,25 +316,25 @@ bool GenericEditor::checkChannelSelectors(Button* button)
 		if (button == channelSelectorButtons[n])
 		{
 
-			String type;
+		//	String type;
 
 			if (audioButton->getToggleState())
 			{
 				audioChannels.set(n,button->getToggleState());
-				type = "Audio ";
+				//type = "Audio ";
 			}
 			else if (recordButton->getToggleState())
 			{
 				recordChannels.set(n,button->getToggleState());	
-				type = "Record ";
+				//type = "Record ";
 			}		
 			else if (paramsButton->getToggleState())
 			{
 				paramsChannels.set(n,button->getToggleState());
-				type = "Params ";	
+				//type = "Params ";	
 			}
 			
-			std::cout << type << "button " << n << " clicked." << std::endl;
+			//std::cout << type << "button " << n << " clicked." << std::endl;
 			return true;
 			
 		}
@@ -401,6 +406,22 @@ bool GenericEditor::checkChannelSelectors(Button* button)
 
 }
 
+Array<int> GenericEditor::getActiveChannels()
+{
+	Array<int> chans;
+
+	for (int n = 0; n < paramsChannels.size(); n++)
+	{
+		if (paramsChannels[n])
+		{
+			chans.add(n);
+		}
+
+	}
+
+	return chans;
+}
+
 void GenericEditor::createRadioButtons(int x, int y, int w, StringArray values, const String& groupName)
 {
 	int numButtons = values.size();
diff --git a/Source/Processors/Editors/GenericEditor.h b/Source/Processors/Editors/GenericEditor.h
index a6c3f7028..fd961afb6 100644
--- a/Source/Processors/Editors/GenericEditor.h
+++ b/Source/Processors/Editors/GenericEditor.h
@@ -99,6 +99,8 @@ public:
 
 	bool checkDrawerButton(Button* button);
 	bool checkChannelSelectors(Button* button);
+
+	Array<int> getActiveChannels();
 	
 private:
 
diff --git a/Source/Processors/Editors/SignalGeneratorEditor.cpp b/Source/Processors/Editors/SignalGeneratorEditor.cpp
index 4e3fc1efb..ccf5a351e 100644
--- a/Source/Processors/Editors/SignalGeneratorEditor.cpp
+++ b/Source/Processors/Editors/SignalGeneratorEditor.cpp
@@ -55,9 +55,22 @@ SignalGeneratorEditor::~SignalGeneratorEditor()
 void SignalGeneratorEditor::sliderValueChanged (Slider* slider)
 {
 
-	if (slider == amplitudeSlider)
-		getAudioProcessor()->setParameter(0,slider->getValue());
-	else 
-		getAudioProcessor()->setParameter(1,slider->getValue());
+	Array<int> chans = getActiveChannels();
+	
+	//std::cout << chans.size() << " channels selected." << std::endl;
+
+	GenericProcessor* p = (GenericProcessor*) getAudioProcessor();
+
+	for (int n = 0; n < chans.size(); n++) {
+		
+		p->setCurrentChannel(chans[n]);
+
+		if (slider == amplitudeSlider)
+			p->setParameter(0,slider->getValue());
+		else 
+			p->setParameter(1,slider->getValue());
+
+	}
+
 
 }
\ No newline at end of file
diff --git a/Source/Processors/GenericProcessor.cpp b/Source/Processors/GenericProcessor.cpp
index 1fe7db01d..cd622da74 100644
--- a/Source/Processors/GenericProcessor.cpp
+++ b/Source/Processors/GenericProcessor.cpp
@@ -26,7 +26,7 @@
 
 GenericProcessor::GenericProcessor(const String& name_) : name(name_),
 	sourceNode(0), destNode(0), editor(0), isEnabled(true), saveOrder(-1), loadOrder(-1),
-	nextAvailableChannel(0), wasConnected(false)
+	nextAvailableChannel(0), wasConnected(false), currentChannel(-1)
 	
 {
 
@@ -81,7 +81,7 @@ int GenericProcessor::getDefaultNumOutputs()
 {
 	if (!isSink())
 	{
-		return 16;
+		return 10;
 	} else {
 		return 0;
 	}
@@ -294,6 +294,13 @@ void GenericProcessor::updateSettings()
 
 	setPlayConfigDetails(getNumInputs(), getNumOutputs(), 44100.0, 128);
 
+	updateParameters();
+
+}
+
+void GenericProcessor::updateParameters()
+{
+	
 }
 
 
diff --git a/Source/Processors/GenericProcessor.h b/Source/Processors/GenericProcessor.h
index 9c159be66..1612abe31 100644
--- a/Source/Processors/GenericProcessor.h
+++ b/Source/Processors/GenericProcessor.h
@@ -137,7 +137,10 @@ public:
 	virtual int getNextChannel(bool);
 	virtual void resetConnections();
 	
-	virtual void updateSettings();
+	virtual void updateSettings(); // updates sample rate and number of channels
+	virtual void updateParameters(); // called in updateSettings() to update params
+
+	virtual void setCurrentChannel(int chan) {currentChannel = chan;}
 
 	int getNodeId() {return nodeId;}
 	void setNodeId(int id) {nodeId = id;}
@@ -188,6 +191,8 @@ public:
 	int saveOrder;
 	int loadOrder;
 
+	int currentChannel;
+
 
 	// Getting and setting:
 
diff --git a/Source/Processors/SignalGenerator.cpp b/Source/Processors/SignalGenerator.cpp
index a016c9d17..08093b35b 100644
--- a/Source/Processors/SignalGenerator.cpp
+++ b/Source/Processors/SignalGenerator.cpp
@@ -29,15 +29,12 @@
 SignalGenerator::SignalGenerator()
 	: GenericProcessor("Signal Generator"),
 
-	  frequency(10.0),
-	  sampleRate (44100.0),
-	  currentPhase (0.0),
-	  phasePerSample (0.0),
-	  amplitude (0.02f)
+	  defaultFrequency(10.0),
+	  defaultAmplitude (0.02f)
 	
 {
 
-	setNumOutputs(16);
+	setNumOutputs(10);
 	setNumInputs(0);
 
 
@@ -73,25 +70,44 @@ AudioProcessorEditor* SignalGenerator::createEditor( )
 	return ed;
 }
 
+void SignalGenerator::updateParameters()
+{
+
+	std::cout << "Signal generator updating parameters" << std::endl;
+
+	frequencies.clear();
+	amplitudes.clear();
+	currentPhase.clear();
+	phasePerSample.clear();
+
+	for (int n = 0; n < getNumOutputs(); n++)
+	{
+		frequencies.add(defaultFrequency*n);
+		amplitudes.add(defaultAmplitude);
+		currentPhase.add(0);
+		phasePerSample.add(double_Pi * 2.0 / (getSampleRate() / frequencies[n]));
+	}
+
+}
 
 void SignalGenerator::setParameter (int parameterIndex, float newValue)
 {
 	//std::cout << "Message received." << std::endl;
 
-	if (parameterIndex == 0)
-		amplitude = newValue;
-	else
-		frequency = newValue;
-
-	phasePerSample = double_Pi * 2.0 / (sampleRate / frequency);
+	if (currentChannel > -1) {
+		if (parameterIndex == 0) {
+			amplitudes.set(currentChannel,newValue);
+		} else {
+			frequencies.set(currentChannel,newValue);
+			phasePerSample.set(currentChannel, double_Pi * 2.0 / (sampleRate / frequencies[currentChannel]));
+		}
+	}
 
 }
 
 
 bool SignalGenerator::enable () {
 
-	phasePerSample = double_Pi * 2.0 / (getSampleRate() / frequency);
-
 	std::cout << "Signal generator received enable signal." << std::endl;
 	return true;
 }
@@ -112,11 +128,13 @@ void SignalGenerator::process(AudioSampleBuffer &buffer,
 	
     for (int i = 0; i < nSamps; ++i)
     {
-        const float sample = amplitude * (float) std::sin (currentPhase);
-        currentPhase += phasePerSample;
+        for (int j = buffer.getNumChannels(); --j >= 0;) {
+        	
+        	const float sample = amplitudes[j] * (float) std::sin (currentPhase[j]);
+       		currentPhase.set(j,currentPhase[j] + phasePerSample[j]);
 
-        for (int j = buffer.getNumChannels(); --j >= 0;)
-        	// dereference pointer to one of the buffer's samples
+       		// dereference pointer to one of the buffer's samples
             *buffer.getSampleData (j, i) = sample;
+        }
     }
 }
diff --git a/Source/Processors/SignalGenerator.h b/Source/Processors/SignalGenerator.h
index 9da2f8939..abf1036ed 100644
--- a/Source/Processors/SignalGenerator.h
+++ b/Source/Processors/SignalGenerator.h
@@ -61,11 +61,17 @@ public:
 
 	bool isSource() {return true;}
 
+	void updateParameters();
+
 private:
 	
-	double frequency, sampleRate;
-	double currentPhase, phasePerSample;
-	float amplitude;
+	double defaultFrequency;
+	double defaultAmplitude;
+
+	Array<double> frequencies;
+	Array<double> amplitudes;
+	Array<double> currentPhase;
+	Array<double> phasePerSample;
 
 
 	JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SignalGenerator);
diff --git a/open-ephys.jucer b/open-ephys.jucer
index 13b88c879..2768d9df5 100644
--- a/open-ephys.jucer
+++ b/open-ephys.jucer
@@ -12,7 +12,7 @@
     <XCODE_MAC targetFolder="Builds/MacOSX" vstFolder="~/SDKs/vstsdk2.4" rtasFolder="~/SDKs/PT_80_SDK"
                juceFolder="JuceLibraryCode" extraLinkerFlags="-lftdi -lftgl"/>
     <LINUX_MAKE targetFolder="Builds/Linux" vstFolder="~/SDKs/vstsdk2.4" juceFolder="JuceLibraryCode"
-                extraLinkerFlags="-lftdi -lftgl" extraCompilerFlags="-D__STDC_LIMIT_MACROS"/>
+                extraLinkerFlags="-lftdi -lftgl" extraCompilerFlags="-export-dynamic"/>
   </EXPORTFORMATS>
   <CONFIGURATIONS>
     <CONFIGURATION name="Debug" isDebug="1" optimisation="1" targetName="open-ephys"
@@ -74,6 +74,7 @@
       </GROUP>
     </GROUP>
     <GROUP id="ZMfWAFj" name="Source">
+      <GROUP id="C4YiLUg" name="Plugins"/>
       <FILE id="AXFRUPT" name="AccessClass.cpp" compile="1" resource="0"
             file="Source/AccessClass.cpp"/>
       <FILE id="2ViPrE" name="AccessClass.h" compile="0" resource="0" file="Source/AccessClass.h"/>
-- 
GitLab