** 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