** Added the void keyword to TypedInControl DoControl to correct the
CascadingTypedInControl bug.
** Ported MIDI Sink and MIDI Source adn MIDIController to TypedControls.
MIDI Sink uses CascadingTypedInControl.
** Added the MIDINote2Freq processing that transforms MIDI Notes into
Frequencies and Amplitude.
** Added operator== and operator != to the MIDIMessage class.

I'have done a screencast with a CLAM Network usefully used to reproduce a
sequence (using an external sequencer) with the SimpleOscillator.
Here is the link: http://www.youtube.com/watch?v=WBfsYZnloo0
Index: plugins/MIDI/src/MIDISource.cxx
===================================================================
--- plugins/MIDI/src/MIDISource.cxx	(revision 12511)
+++ plugins/MIDI/src/MIDISource.cxx	(working copy)
@@ -21,10 +21,7 @@
 	}
 
 	MIDISource::MIDISource(const Config& config) 
-		: mMIDIMessage("MIDI Message", this),
-			mMIDIData1("MIDI Data 1", this),
-			mMIDIData2("MIDI Data 2", this),
-			mTrigger("Trigger", this)
+		: mMIDIMessage("MIDI Message Out", this)
 	{
 		// Create RtMidiIn Object
 		try {
Index: plugins/MIDI/src/MIDIController.cxx
===================================================================
--- plugins/MIDI/src/MIDIController.cxx	(revision 12511)
+++ plugins/MIDI/src/MIDIController.cxx	(working copy)
@@ -15,11 +15,8 @@
 }
 
 	MIDIController::MIDIController() 
-		: mMIDIMessage("MIDI Message", this),
-			mMIDIData1("MIDI Data 1", this),
-			mMIDIData2("MIDI Data 2", this),
-			mTrigger("Trigger", this),
-			mMIDIControllerValue("Control Output", this)
+		: mMIDIMessage("MIDI Message Input", this, &MIDIController::DoCallback),
+			mMIDIControlValue("Control Output", this)
 	{
 		Configure( mConfig );
 	}
@@ -28,20 +25,20 @@
 
 	bool MIDIController::Do()
 	{ 
-		if(mTrigger.GetLastValue())
+		return true;
+	}
+	
+	int MIDIController::DoCallback(MIDI::Message inMessage){
+		std::bitset<CHAR_BIT> statusByte;
+		statusByte = (std::bitset<CHAR_BIT>)((unsigned char)inMessage[0]);
+		if(statusByte[7] == 1 && statusByte[6] == 0 && statusByte[5] == 1 && statusByte[4] == 1)
 		{
-			std::bitset<CHAR_BIT> statusByte;
-			statusByte = (std::bitset<CHAR_BIT>)((unsigned char)mMIDIMessage.GetLastValue());
-			if(statusByte[7] == 1 && statusByte[6] == 0 && statusByte[5] == 1 && statusByte[4] == 1)
-			{
-				if(((int)mMIDIData1.GetLastValue()) == mConfig.GetControlNumber()){
-					mMIDIControllerValue.SendControl((float)mMIDIData2.GetLastValue());
-				}
+			if(((int)inMessage[1]) == mConfig.GetControlNumber()){
+				mMIDIControlValue.SendControl((float)inMessage[3]);
 			}
-		}		
-		return true;
-		 }
-
+		}
+		
+	}
 	bool MIDIController::ConcreteConfigure(const ProcessingConfig& c)
 	{
 		CopyAsConcreteConfig(mConfig, c);
Index: plugins/MIDI/src/MIDISink.cxx
===================================================================
--- plugins/MIDI/src/MIDISink.cxx	(revision 12511)
+++ plugins/MIDI/src/MIDISink.cxx	(working copy)
@@ -1,6 +1,5 @@
 #include "MIDISink.hxx"
 #include <CLAM/ProcessingFactory.hxx>
-
 namespace CLAM
 {
 
@@ -15,10 +14,7 @@
 }
 
 	MIDISink::MIDISink(const Config& config) 
-		: mMIDIMessage("MIDI Message", this),
-			mMIDIData1("MIDI Data 1", this),
-			mMIDIData2("MIDI Data 2", this),
-			mTrigger("Trigger", this)
+		: mMIDIMessage("MIDI Message In", this, &MIDISink::DoCallback)
 	{
 		// Create RtMidiIn Object
 		try {
@@ -36,6 +32,9 @@
 		catch ( RtError &error ) {
 			error.printMessage();
 		}
+		
+		// Make default message
+		mLastMessage.Update(0,0,0,0);
 		Configure( config );
 	}
 
@@ -44,4 +43,19 @@
 			delete mMIDIout;
 	}
 
+	int MIDISink::DoCallback(MIDI::Message inMessage){
+		inMessage = mMIDIMessage.GetLastValue();
+		
+		std::vector< unsigned char > message;
+		
+		message.push_back((inMessage)[0]);
+		message.push_back((inMessage)[1]);
+		message.push_back((inMessage)[2]);
+		message.push_back((inMessage)[3]);
+
+		mMIDIout->sendMessage( &message );
+			
+		return 0;
+	};
+
 }
Index: plugins/MIDI/src/MIDISource.hxx
===================================================================
--- plugins/MIDI/src/MIDISource.hxx	(revision 12511)
+++ plugins/MIDI/src/MIDISource.hxx	(working copy)
@@ -1,8 +1,9 @@
 #ifndef MIDISource_hxx
 #define MIDISource_hxx
 
-#include <CLAM/OutControl.hxx>
 #include <CLAM/Processing.hxx>
+#include <CLAM/TypedOutControl.hxx>
+#include <CLAM/MIDIMessage.hxx>
 
 #include "../RtMidi.hxx"
 
@@ -11,15 +12,8 @@
 	class MIDISource : public CLAM::Processing
 	{ 
 		/** Controls **/
-		FloatOutControl mMIDIMessage;
-		FloatOutControl mMIDIData1;
-		FloatOutControl mMIDIData2;
-
-		/**
-		* mTrigger should be connected to an InControlTmpl to inform that all MIDI Data is placed and can be used.
-		*/
-		FloatOutControl mTrigger; 
-
+		TypedOutControl<MIDI::Message> mMIDIMessage;
+		
 		RtMidiIn *mMIDIin;
 
 		static void RtMidiCallback( double deltatime, std::vector< unsigned char > *message, void *userData );
@@ -40,10 +34,9 @@
 			unsigned int nBytes = message->size();
 			if (nBytes>0)
 			{
-				mMIDIMessage.SendControl((float) ( (*message)[0]) );
-				mMIDIData1.SendControl((float) ( (*message)[1]));
-				mMIDIData2.SendControl((float) ( (*message)[2]));
-				mTrigger.SendControl(1);
+				// Send Message
+				MIDI::Message tmpMessage( (*message)[0] , (*message)[1] , (*message)[2] , (*message)[3] );
+				mMIDIMessage.SendControl(tmpMessage);
 			}
 			return true;
 		}
Index: plugins/MIDI/src/MIDINote2Freq.cxx
===================================================================
--- plugins/MIDI/src/MIDINote2Freq.cxx	(revision 0)
+++ plugins/MIDI/src/MIDINote2Freq.cxx	(revision 0)
@@ -0,0 +1,49 @@
+#include "MIDINote2Freq.hxx"
+#include <CLAM/ProcessingFactory.hxx>
+#include <cmath>
+namespace CLAM
+{
+
+namespace Hidden
+{
+	static const char * metadata[] = {
+		"key", "MIDINote2Freq",
+		"category", "MIDI",
+		0
+		};
+	static CLAM::FactoryRegistrator<CLAM::ProcessingFactory, MIDINote2Freq> registrator(metadata);	
+}
+
+	MIDINote2Freq::MIDINote2Freq() 
+		: mMIDIMessage("MIDI Message Input", this, &MIDINote2Freq::DoCallback),
+		mFreq("Frequency Output", this),
+		mAmplitude("Amplitude Output", this)
+	{
+		Configure( mConfig );
+	}
+
+	MIDINote2Freq::~MIDINote2Freq() {}
+
+	bool MIDINote2Freq::Do()
+	{ 
+		return true;
+	}
+	
+	int MIDINote2Freq::DoCallback(MIDI::Message inMessage){
+		std::bitset<CHAR_BIT> statusByte;
+		statusByte = (std::bitset<CHAR_BIT>)((unsigned char)inMessage[0]);
+		if(statusByte[7] == 1 && statusByte[6] == 0 && statusByte[5] == 0 && statusByte[4] == 1)
+		{
+			float frequency;
+			frequency = 440 * pow(2.0,((float)(inMessage[1])-69.0)/12.0);
+			mFreq.SendControl(frequency);
+			mAmplitude.SendControl(inMessage[2] * mConfig.GetScaleAmplitude() / 127.0); 
+		}
+		return 0;
+	}
+	bool MIDINote2Freq::ConcreteConfigure(const ProcessingConfig& c)
+	{
+		CopyAsConcreteConfig(mConfig, c);
+		return true;
+	}
+}
Index: plugins/MIDI/src/MIDIController.hxx
===================================================================
--- plugins/MIDI/src/MIDIController.hxx	(revision 12511)
+++ plugins/MIDI/src/MIDIController.hxx	(working copy)
@@ -1,9 +1,10 @@
 #ifndef MIDIController_hxx
 #define MIDIController_hxx
 
+#include <CLAM/Processing.hxx>
+#include <CLAM/TypedInControl.hxx>
 #include <CLAM/OutControl.hxx>
-#include <CLAM/InControl.hxx>
-#include <CLAM/Processing.hxx>
+#include <CLAM/MIDIMessage.hxx>
 #include <bitset>
 
 namespace CLAM {
@@ -27,12 +28,9 @@
 	class MIDIController : public CLAM::Processing
 	{ 
 	protected:
-		FloatInControl mMIDIMessage;
-		FloatInControl mMIDIData1;
-		FloatInControl mMIDIData2;
-		FloatInControl mTrigger;
+		CascadingTypedInControl<MIDI::Message, MIDIController> mMIDIMessage;
 
-		FloatOutControl mMIDIControllerValue;
+		FloatOutControl mMIDIControlValue;
 
 		MIDIControllerConfig mConfig;
 		
@@ -46,6 +44,8 @@
 		~MIDIController();
 
 		bool Do();
+		
+		int DoCallback(MIDI::Message inMessage);
 	};
 	
 } // End namespace
Index: plugins/MIDI/src/MIDISink.hxx
===================================================================
--- plugins/MIDI/src/MIDISink.hxx	(revision 12511)
+++ plugins/MIDI/src/MIDISink.hxx	(working copy)
@@ -1,29 +1,20 @@
 #ifndef MIDISink_hxx
 #define MIDISink_hxx
 
-#include <CLAM/OutControl.hxx>
 #include <CLAM/Processing.hxx>
-
+#include <CLAM/TypedInControl.hxx>
+#include <CLAM/MIDIMessage.hxx>
 #include "../RtMidi.hxx"
-
+#include <iostream>
 namespace CLAM {
 
 	class MIDISink : public CLAM::Processing
 	{ 
 		/** Controls **/
-		FloatInControl mMIDIMessage;
-		FloatInControl mMIDIData1;
-		FloatInControl mMIDIData2;
-
-		/*
-		* TODO: mTrigger should be an InControlTmpl 
-		*/
-		FloatInControl mTrigger; 
-
+		CascadingTypedInControl< MIDI::Message, MIDISink > mMIDIMessage;
+		MIDI::Message mLastMessage;
 		RtMidiOut *mMIDIout;
 
-		//static void RtMidiCallback( double deltatime, std::vector< unsigned char > *message, void *userData );
-
 	public:
 		const char* GetClassName() const { return "MIDISink"; }
 
@@ -31,24 +22,9 @@
 
 		~MIDISink();
 
-		bool Do()
-		{
-			std::vector< unsigned char > message;
-			if((bool)(mTrigger.GetLastValue())){
-				message.push_back(mMIDIMessage.GetLastValue());
-				message.push_back(mMIDIData1.GetLastValue());
-				message.push_back(mMIDIData2.GetLastValue());
-				
-				mMIDIout->sendMessage( &message );
-				
-				mMIDIMessage.DoControl(0);
-				mMIDIData1.DoControl(0);
-				mMIDIData2.DoControl(0);
-				mTrigger.DoControl(0);
-			}
-			return true;
-		}
+		bool Do() {};
+		
+		int MIDISink::DoCallback(MIDI::Message inMessage);
 	};
-	
 } // End namespace
 #endif // MIDISink_hxx
Index: plugins/MIDI/src/MIDINote2Freq.hxx
===================================================================
--- plugins/MIDI/src/MIDINote2Freq.hxx	(revision 0)
+++ plugins/MIDI/src/MIDINote2Freq.hxx	(revision 0)
@@ -0,0 +1,53 @@
+#ifndef MIDINote2Freq_hxx
+#define MIDINote2Freq_hxx
+
+#include <CLAM/Processing.hxx>
+#include <CLAM/TypedInControl.hxx>
+#include <CLAM/OutControl.hxx>
+#include <CLAM/MIDIMessage.hxx>
+#include <bitset>
+
+namespace CLAM {
+
+	class MIDINote2FreqConfig: public ProcessingConfig
+	{
+	public:
+		DYNAMIC_TYPE_USING_INTERFACE (MIDINote2FreqConfig, 1, ProcessingConfig);
+		DYN_ATTRIBUTE (0, public, int, ScaleAmplitude);
+
+	protected:
+		void DefaultInit(void)
+		{
+			AddAll();
+			UpdateData();
+			SetScaleAmplitude(1);
+		}
+
+	};
+	
+	class MIDINote2Freq : public CLAM::Processing
+	{ 
+	protected:
+		CascadingTypedInControl<MIDI::Message, MIDINote2Freq> mMIDIMessage;
+
+		FloatOutControl mFreq;
+		FloatOutControl	mAmplitude;
+		
+		MIDINote2FreqConfig mConfig;
+		
+	public:
+		const char* GetClassName() const { return "MIDINote2Freq"; }
+		
+		bool ConcreteConfigure(const ProcessingConfig& c);
+		const ProcessingConfig &GetConfig() const { return mConfig;}
+		
+		MIDINote2Freq();
+		~MIDINote2Freq();
+
+		bool Do();
+		
+		int DoCallback(MIDI::Message inMessage);
+	};
+	
+} // End namespace
+#endif // MIDINote2Freq_hxx
Index: src/Tools/MIDIIO/File/MIDIMessage.hxx
===================================================================
--- src/Tools/MIDIIO/File/MIDIMessage.hxx	(revision 12511)
+++ src/Tools/MIDIIO/File/MIDIMessage.hxx	(working copy)
@@ -53,6 +53,14 @@
 
 		Byte operator [] (int i) const { return mVal[i]; }
 
+		bool operator== (Message message) const { 
+			return (( mData.mStatus == message[0] ) && ( mData.mData1 == message[1] ) && ( mData.mData2 == message[2] ) && ( mData.mData3 == message[3] ));
+		};
+	
+		bool operator!= (Message message) const { 
+			return ( ( message[0] != mData.mStatus) || ( message[1] != mData.mData1 ) || ( message[2] != mData.mData2 ) || ( message[3] != mData.mData3 ) );
+		};
+
 		void Update(Byte status = 0,Byte data1 = 0,Byte data2 = 0,Byte data3 = 0)
 		{
 			if(status) {mData.mStatus = status;}
Index: src/Flow/Controls/TypedInControl.hxx
===================================================================
--- src/Flow/Controls/TypedInControl.hxx	(revision 12511)
+++ src/Flow/Controls/TypedInControl.hxx	(working copy)
@@ -24,8 +24,8 @@
 	public:
 		TypedInControl(const std::string &name = "unnamed in control", Processing * proc = 0);
 		
-		void DoControl(const TypedControlData& val);
-		const TypedControlData& GetLastValue() const;
+		virtual void DoControl(const TypedControlData& val) { mLastValue = val; };
+		const TypedControlData& GetLastValue() const { return mLastValue; };
 		/** ONLY TO USE WHEN TypedControlData == float. Returns the last TypedControlData (float) received interpreted as a bool. */
 		bool GetLastValueAsBoolean() const 
 		{ 
@@ -44,20 +44,7 @@
 		: InControlBase(name,proc)
 	{
 	}
-	
-	template<class TypedControlData>
-	void TypedInControl<TypedControlData>::DoControl(const TypedControlData& val)
-	{
-		mLastValue = val;
-	}
 
-	template<class TypedControlData>
-	const TypedControlData& TypedInControl<TypedControlData>::GetLastValue() const
-	{
-		return mLastValue;
-	}
-
-	
 	/**
 	* Subclass of TypedInControl that provides the typedincontrol with a callback method
 	* The method must be defined inside the parent \c Processing class.
_______________________________________________
Clam-devel mailing list
[email protected]
https://llistes.projectes.lafarga.org/cgi-bin/mailman/listinfo/clam-devel

Reply via email to