summaryrefslogtreecommitdiff
path: root/muse2/muse/midictrl.cpp
diff options
context:
space:
mode:
authorRobert Jonsson <spamatica@gmail.com>2010-10-13 19:34:22 +0000
committerRobert Jonsson <spamatica@gmail.com>2010-10-13 19:34:22 +0000
commit8a2c2824a59d7644e13bc52c9a0ecbd641f21f95 (patch)
tree064ad3f2bf8daab0ad27b128abd86a9bbdb1e496 /muse2/muse/midictrl.cpp
parenta27706d9629e8b592cca4659f865b70adef24e6d (diff)
new branch muse2, first checkin
Diffstat (limited to 'muse2/muse/midictrl.cpp')
-rw-r--r--muse2/muse/midictrl.cpp781
1 files changed, 781 insertions, 0 deletions
diff --git a/muse2/muse/midictrl.cpp b/muse2/muse/midictrl.cpp
new file mode 100644
index 00000000..3994fe90
--- /dev/null
+++ b/muse2/muse/midictrl.cpp
@@ -0,0 +1,781 @@
+//=========================================================
+// MusE
+// Linux Music Editor
+// $Id: midictrl.cpp,v 1.17.2.10 2009/06/10 00:34:59 terminator356 Exp $
+//
+// (C) Copyright 2001-2004 Werner Schweer (ws@seh.de)
+//=========================================================
+
+#include <assert.h>
+#include <stdio.h>
+
+#include <qobject.h>
+#include "midictrl.h"
+#include "xml.h"
+#include "globals.h"
+
+static const char* ctrlName[] = {
+ "BankSelMSB", "Modulation", "BreathCtrl", "Control 3", "Foot Ctrl",
+ "Porta Time", "DataEntMSB", "MainVolume", "Balance", "Control 9",
+/*10*/ "Pan", "Expression", "Control 12", "Control 13", "Control 14",
+ "Control 15", "Gen.Purp.1", "Gen.Purp.2", "Gen.Purp.3", "Gen.Purp.4",
+/*20*/ "Control 20", "Control 21", "Control 22", "Control 23", "Control 24",
+ "Control 25", "Control 26", "Control 27", "Control 28", "Control 29",
+/*30*/ "Control 30", "Control 31", "BankSelLSB", "Modul. LSB", "BrthCt.LSB",
+ "Control 35", "FootCt.LSB", "Port.T LSB", "DataEntLSB", "MainVolLSB",
+ "BalanceLSB", "Control 41", "Pan LSB", "Expr. LSB", "Control 44",
+ "Control 45", "Control 46", "Control 47", "Gen.P.1LSB", "Gen.P.2LSB",
+/*50*/ "Gen.P.3LSB", "Gen.P.4LSB", "Control 52", "Control 53", "Control 54",
+ "Control 55", "Control 56", "Control 57", "Control 58", "Control 59",
+ "Control 60", "Control 61", "Control 62", "Control 63", "Sustain",
+ "Porta Ped", "Sostenuto", "Soft Pedal", "Control 68", "Hold 2",
+ "Control 70", "HarmonicCo", "ReleaseTime", "Attack Time", "Brightness",
+ "Control 75", "Control 76", "Control 77", "Control 78", "Control 79",
+ "Gen.Purp.5", "Gen.Purp.6", "Gen.Purp.7", "Gen.Purp.8", "Porta Ctrl",
+ "Control 85", "Control 86", "Control 87", "Control 88", "Control 89",
+ "Control 90", "Effect1Dep", "Effect2Dep", "Effect3Dep", "Effect4Dep",
+ "Phaser Dep", "Data Incr", "Data Decr", "NRPN LSB", "NRPN MSB",
+/*100*/ "RPN LSB", "RPN MSB", "Control102", "Control103", "Control104",
+ "Control105", "Control106", "Control107", "Control108", "Control109",
+ "Control110", "Control111", "Control112", "Control113", "Control114",
+ "Control115", "Control116", "Control117", "Control118", "Control119",
+ "AllSndOff", "Reset Ctrl", "Local Ctrl", "AllNoteOff", "OmniModOff",
+ "OmniModeOn", "MonoModeOn", "PolyModeOn"
+ };
+
+#if 0
+static const char* ctrl14Name[] = {
+ "BankSel", "Modulation", "BreathCtrl",
+ "Control 3", "Foot Ctrl", "Porta Time", "DataEntry",
+ "MainVolume", "Balance", "Control 9", "Pan",
+ "Expression", "Control 12", "Control 13", "Control 14",
+ "Control 15", "Gen.Purp.1", "Gen.Purp.2", "Gen.Purp.3",
+ "Gen.Purp.4", "Control 20", "Control 21", "Control 22",
+ "Control 23", "Control 24", "Control 25", "Control 26",
+ "Control 27", "Control 28", "Control 29", "Control 30",
+ "Control 31",
+ };
+#endif
+
+enum {
+ COL_NAME = 0, COL_TYPE,
+ COL_HNUM, COL_LNUM, COL_MIN, COL_MAX
+ };
+
+MidiControllerList defaultMidiController;
+//
+// some global controller which are always available:
+//
+MidiController veloCtrl("Velocity", CTRL_VELOCITY, 0, 127, 0);
+static MidiController pitchCtrl("PitchBend", CTRL_PITCH, -8192, +8191, 0);
+static MidiController programCtrl("Program", CTRL_PROGRAM, 0, 0xffffff, 0);
+// Removed p3.3.37
+//static MidiController mastervolCtrl("MasterVolume", CTRL_MASTER_VOLUME, 0, 0x3fff, 0x3000);
+static MidiController volumeCtrl("MainVolume", CTRL_VOLUME, 0, 127, 100);
+static MidiController panCtrl("Pan", CTRL_PANPOT, -64, 63, 0);
+
+
+//---------------------------------------------------------
+// ctrlType2Int
+// int2ctrlType
+//---------------------------------------------------------
+
+static struct {
+ MidiController::ControllerType type;
+ QString name;
+ } ctrlTypes[] = {
+ { MidiController::Controller7, QString("Control7") },
+ { MidiController::Controller14, QString("Control14") },
+ { MidiController::RPN, QString("RPN") },
+ { MidiController::NRPN, QString("NRPN") },
+ { MidiController::RPN14, QString("RPN14") },
+ { MidiController::NRPN14, QString("NRPN14") },
+ { MidiController::Pitch, QString("Pitch") },
+ { MidiController::Program, QString("Program") },
+ { MidiController::Controller7, QString("Control") }, // alias
+ };
+
+//---------------------------------------------------------
+// ctrlType2Int
+//---------------------------------------------------------
+
+MidiController::ControllerType ctrlType2Int(const QString& s)
+ {
+ int n = sizeof(ctrlTypes)/sizeof(*ctrlTypes);
+ for (int i = 0; i < n; ++i) {
+ if (ctrlTypes[i].name == s)
+ return ctrlTypes[i].type;
+ }
+ return MidiController::ControllerType(0);
+ }
+
+//---------------------------------------------------------
+// int2ctrlType
+//---------------------------------------------------------
+
+const QString& int2ctrlType(int n)
+ {
+ static QString dontKnow("?T?");
+ int size = sizeof(ctrlTypes)/sizeof(*ctrlTypes);
+ for (int i = 0; i < size; ++i) {
+ if (ctrlTypes[i].type == n)
+ return ctrlTypes[i].name;
+ }
+ return dontKnow;
+ }
+
+//---------------------------------------------------------
+// initMidiController
+//---------------------------------------------------------
+
+void initMidiController()
+ {
+ defaultMidiController.add(&veloCtrl);
+ defaultMidiController.add(&pitchCtrl);
+ defaultMidiController.add(&programCtrl);
+ // Removed p3.3.37
+ //defaultMidiController.add(&mastervolCtrl);
+ defaultMidiController.add(&volumeCtrl);
+ defaultMidiController.add(&panCtrl);
+ }
+
+//---------------------------------------------------------
+// midiCtrlName
+//---------------------------------------------------------
+
+QString midiCtrlName(int ctrl)
+ {
+ if (ctrl < 0x10000)
+ return QString(ctrlName[ctrl]);
+ return QString("?N?");
+ }
+
+//---------------------------------------------------------
+// MidiController
+//---------------------------------------------------------
+
+MidiController::MidiController()
+ : _name(QString(QT_TR_NOOP("Velocity")))
+ {
+ _num = CTRL_VELOCITY;
+ _minVal = 0;
+ _maxVal = 127;
+ _initVal = 0;
+ updateBias();
+ }
+
+MidiController::MidiController(const QString& s, int n, int min, int max, int init)
+ : _name(s), _num(n), _minVal(min), _maxVal(max), _initVal(init)
+ {
+ updateBias();
+ }
+
+MidiController::MidiController(const MidiController& mc)
+{
+ copy(mc);
+}
+
+//---------------------------------------------------------
+// copy
+//---------------------------------------------------------
+
+void MidiController::copy(const MidiController &mc)
+{
+ _name = mc._name;
+ _num = mc._num;
+ _minVal = mc._minVal;
+ _maxVal = mc._maxVal;
+ _initVal = mc._initVal;
+ //updateBias();
+ _bias = mc._bias;
+}
+
+//---------------------------------------------------------
+// operator =
+//---------------------------------------------------------
+
+MidiController& MidiController::operator=(const MidiController &mc)
+{
+ copy(mc);
+ return *this;
+}
+
+//---------------------------------------------------------
+// type
+//---------------------------------------------------------
+
+MidiController::ControllerType midiControllerType(int num)
+ {
+ // p3.3.37
+ //if (num < 0x10000)
+ if (num < CTRL_14_OFFSET)
+ return MidiController::Controller7;
+ //if (num < 0x20000)
+ if (num < CTRL_RPN_OFFSET)
+ return MidiController::Controller14;
+ //if (num < 0x30000)
+ if (num < CTRL_NRPN_OFFSET)
+ return MidiController::RPN;
+ //if (num < 0x40000)
+ if (num < CTRL_INTERNAL_OFFSET)
+ return MidiController::NRPN;
+ if (num == CTRL_PITCH)
+ return MidiController::Pitch;
+ if (num == CTRL_PROGRAM)
+ return MidiController::Program;
+ if (num == CTRL_VELOCITY)
+ return MidiController::Velo;
+ //if (num < 0x60000)
+ if (num < CTRL_NRPN14_OFFSET)
+ return MidiController::RPN14;
+ //if (num < 0x70000)
+ if (num < CTRL_NONE_OFFSET)
+ return MidiController::NRPN14;
+ return MidiController::Controller7;
+ }
+
+//---------------------------------------------------------
+// updateBias
+//---------------------------------------------------------
+
+void MidiController::updateBias()
+{
+ // If the specified minimum value is negative, we will
+ // translate to a positive-biased range.
+ // Cue: A controller like 'coarse tuning', is meant to be displayed
+ // as -24/+24, but really is centered on 64 and goes from 40 to 88.
+ int b;
+ int mn, mx;
+ ControllerType t = midiControllerType(_num);
+ switch (t)
+ {
+ case RPN:
+ case NRPN:
+ case Controller7:
+ b = 64;
+ mn = 0;
+ mx = 127;
+ break;
+ case Controller14:
+ case RPN14:
+ case NRPN14:
+ b = 8192;
+ mn = 0;
+ mx = 16383;
+ break;
+ case Program:
+ b = 0x800000;
+ mn = 0;
+ mx = 0xffffff;
+ break;
+ case Pitch:
+ b = 0;
+ mn = -8192;
+ mx = 8191;
+ break;
+ //case Velo: // cannot happen
+ default:
+ b = 64;
+ mn = 0;
+ mx = 127;
+ break;
+ }
+
+ // Special handling of pan: Only thing to do is force the range!
+ //if(_num == CTRL_PANPOT)
+ //{
+ // _minVal = -64;
+ // _maxVal = 63;
+ // _initVal = 0;
+ //}
+
+ // TODO: Limit _minVal and _maxVal to range.
+
+ if(_minVal >= 0)
+ _bias = 0;
+ else
+ {
+ _bias = b;
+
+ if(t != Program && t != Pitch)
+ {
+ // Adjust bias to fit desired range.
+ if(_minVal + _bias < mn)
+ //_minVal = mn - _bias;
+ _bias += mn - _minVal + _bias;
+ else
+ if(_maxVal + _bias > mx)
+ //_maxVal = mx - _bias;
+ _bias -= _maxVal + _bias - mx;
+ }
+ }
+}
+
+
+//---------------------------------------------------------
+// MidiController::write
+//---------------------------------------------------------
+
+void MidiController::write(int level, Xml& xml) const
+{
+ ControllerType t = midiControllerType(_num);
+ if(t == Velo)
+ return;
+
+ QString type(int2ctrlType(t));
+
+ int h = (_num >> 8) & 0x7f;
+ int l = _num & 0x7f;
+
+ QString sl;
+ if ((_num & 0xff) == 0xff)
+ sl = "pitch";
+ else
+ sl.setNum(l);
+
+ xml.nput(level, "<Controller name=\"%s\"", Xml::xmlString(_name).latin1());
+ if(t != Controller7)
+ xml.nput(" type=\"%s\"", type.latin1());
+
+ int mn = 0;
+ int mx = 0;
+ switch (t)
+ {
+ case RPN:
+ case NRPN:
+ xml.nput(" h=\"%d\"", h);
+ xml.nput(" l=\"%s\"", sl.latin1());
+ mx = 127;
+ break;
+ case Controller7:
+ xml.nput(" l=\"%s\"", sl.latin1());
+ mx = 127;
+ break;
+ case Controller14:
+ case RPN14:
+ case NRPN14:
+ xml.nput(" h=\"%d\"", h);
+ xml.nput(" l=\"%s\"", sl.latin1());
+ mx = 16383;
+ break;
+ case Pitch:
+ mn = -8192;
+ mx = 8191;
+ break;
+ case Program:
+ case Velo: // Cannot happen
+ break;
+ }
+
+ if(t == Program)
+ {
+ if(_initVal != CTRL_VAL_UNKNOWN && _initVal != 0xffffff)
+ xml.nput(" init=\"0x%x\"", _initVal);
+ }
+ else
+ {
+ if(_minVal != mn)
+ xml.nput(" min=\"%d\"", _minVal);
+ if(_maxVal != mx)
+ xml.nput(" max=\"%d\"", _maxVal);
+
+ if(_initVal != CTRL_VAL_UNKNOWN)
+ xml.nput(" init=\"%d\"", _initVal);
+ }
+ //xml.put(level, " />");
+ xml.put(" />");
+}
+
+//---------------------------------------------------------
+// MidiController::read
+//---------------------------------------------------------
+
+void MidiController::read(Xml& xml)
+ {
+ ControllerType t = Controller7;
+ _initVal = CTRL_VAL_UNKNOWN;
+ static const int NOT_SET = 0x100000;
+ _minVal = NOT_SET;
+ _maxVal = NOT_SET;
+ int h = 0;
+ int l = 0;
+ bool ok;
+ int base = 10;
+
+ for (;;) {
+ Xml::Token token = xml.parse();
+ const QString& tag = xml.s1();
+ switch (token) {
+ case Xml::Error:
+ case Xml::End:
+ return;
+ case Xml::Attribut:
+ {
+ QString s = xml.s2();
+ if (s.left(2) == "0x")
+ base = 16;
+ if (tag == "name")
+ _name = xml.s2();
+ else if (tag == "type")
+ t = ctrlType2Int(xml.s2());
+ else if (tag == "h")
+ h = xml.s2().toInt(&ok, base);
+ else if (tag == "l") {
+ // By T356 08/16/08. Changed wildcard to '*'.
+ // Changed back to 'pitch' again.
+ // Support instrument files with '*' as wildcard.
+ if ((xml.s2() == "*") || (xml.s2() == "pitch"))
+ l = 0xff;
+ else
+ l = xml.s2().toInt(&ok, base);
+ }
+ else if (tag == "min")
+ _minVal = xml.s2().toInt(&ok, base);
+ else if (tag == "max")
+ _maxVal = xml.s2().toInt(&ok, base);
+ else if (tag == "init")
+ _initVal = xml.s2().toInt(&ok, base);
+ }
+ break;
+ case Xml::TagStart:
+ xml.unknown("MidiController");
+ break;
+ case Xml::TagEnd:
+ if (tag == "Controller") {
+ _num = (h << 8) + l;
+ switch (t) {
+ case RPN:
+ if (_maxVal == NOT_SET)
+ _maxVal = 127;
+ // p3.3.37
+ //_num |= 0x20000;
+ _num |= CTRL_RPN_OFFSET;
+ break;
+ case NRPN:
+ if (_maxVal == NOT_SET)
+ _maxVal = 127;
+ //_num |= 0x30000;
+ _num |= CTRL_NRPN_OFFSET;
+ break;
+ case Controller7:
+ if (_maxVal == NOT_SET)
+ _maxVal = 127;
+ break;
+ case Controller14:
+ //_num |= 0x10000;
+ _num |= CTRL_14_OFFSET;
+ if (_maxVal == NOT_SET)
+ _maxVal = 16383;
+ break;
+ case RPN14:
+ if (_maxVal == NOT_SET)
+ _maxVal = 16383;
+ //_num |= 0x50000;
+ _num |= CTRL_RPN14_OFFSET;
+ break;
+ case NRPN14:
+ if (_maxVal == NOT_SET)
+ _maxVal = 16383;
+ //_num |= 0x60000;
+ _num |= CTRL_NRPN14_OFFSET;
+ break;
+ case Pitch:
+ if (_maxVal == NOT_SET)
+ _maxVal = 8191;
+ if (_minVal == NOT_SET)
+ _minVal = -8192;
+ _num = CTRL_PITCH;
+ break;
+ case Program:
+ if (_maxVal == NOT_SET)
+ _maxVal = 0xffffff;
+ _num = CTRL_PROGRAM;
+ break;
+ case Velo: // cannot happen
+ break;
+ }
+ if (_minVal == NOT_SET)
+ _minVal = 0;
+
+ updateBias();
+ return;
+ }
+ default:
+ break;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// genNum
+//---------------------------------------------------------
+
+int MidiController::genNum(MidiController::ControllerType t, int h, int l)
+ {
+ int val = (h << 8) + l;
+ switch(t) {
+ case Controller7:
+ return l;
+ case Controller14:
+ return val + CTRL_14_OFFSET;
+ case RPN:
+ //return l + CTRL_RPN_OFFSET;
+ return val + CTRL_RPN_OFFSET;
+ case NRPN:
+ //return l + CTRL_NRPN_OFFSET;
+ return val + CTRL_NRPN_OFFSET;
+ case RPN14:
+ return val + CTRL_RPN14_OFFSET;
+ case NRPN14:
+ return val + CTRL_NRPN14_OFFSET;
+ case Pitch:
+ return CTRL_PITCH;
+ case Program:
+ return CTRL_PROGRAM;
+ default:
+ return -1;
+ }
+ }
+
+//---------------------------------------------------------
+// MidiCtrlValList
+//---------------------------------------------------------
+
+MidiCtrlValList::MidiCtrlValList(int c)
+ {
+ ctrlNum = c;
+ _hwVal = CTRL_VAL_UNKNOWN;
+ _lastValidHWVal = CTRL_VAL_UNKNOWN;
+ }
+
+//---------------------------------------------------------
+// clearDelete
+//---------------------------------------------------------
+
+void MidiCtrlValListList::clearDelete(bool deleteLists)
+{
+ for(iMidiCtrlValList imcvl = begin(); imcvl != end(); ++imcvl)
+ {
+ if(imcvl->second)
+ {
+ imcvl->second->clear();
+ if(deleteLists)
+ delete imcvl->second;
+ }
+ }
+ if(deleteLists)
+ clear();
+}
+
+//---------------------------------------------------------
+// setHwVal
+// Returns false if value is already equal, true if value is changed.
+//---------------------------------------------------------
+
+bool MidiCtrlValList::setHwVal(const int v)
+{
+ if(_hwVal == v)
+ return false;
+
+ _hwVal = v;
+ if(_hwVal != CTRL_VAL_UNKNOWN)
+ _lastValidHWVal = _hwVal;
+
+ return true;
+}
+
+//---------------------------------------------------------
+// setHwVals
+// Sets current and last HW values.
+// Handy for forcing labels to show 'off' and knobs to show specific values
+// without having to send two messages.
+// Returns false if both values are already set, true if either value is changed.
+//---------------------------------------------------------
+
+bool MidiCtrlValList::setHwVals(const int v, int const lastv)
+{
+ if(_hwVal == v && _lastValidHWVal == lastv)
+ return false;
+
+ _hwVal = v;
+ // Don't want to break our own rules - _lastValidHWVal can't be unknown while _hwVal is valid...
+ // But _hwVal can be unknown while _lastValidHWVal is valid...
+ if(lastv == CTRL_VAL_UNKNOWN)
+ _lastValidHWVal = _hwVal;
+ else
+ _lastValidHWVal = lastv;
+
+ return true;
+}
+
+//---------------------------------------------------------
+// partAtTick
+//---------------------------------------------------------
+
+Part* MidiCtrlValList::partAtTick(int tick) const
+{
+ // Determine (first) part at tick. Return 0 if none found.
+
+ ciMidiCtrlVal i = lower_bound(tick);
+ if (i == end() || i->first != tick) {
+ if (i == begin())
+ return 0;
+ --i;
+ }
+ return i->second.part;
+}
+
+//---------------------------------------------------------
+// iValue
+//---------------------------------------------------------
+
+iMidiCtrlVal MidiCtrlValList::iValue(int tick)
+{
+ // Determine value at tick, using values stored by ANY part...
+
+ iMidiCtrlVal i = lower_bound(tick);
+ if (i == end() || i->first != tick) {
+ if (i == begin())
+ return end();
+ --i;
+ }
+ return i;
+}
+
+//---------------------------------------------------------
+// value
+//---------------------------------------------------------
+
+int MidiCtrlValList::value(int tick) const
+{
+ // Determine value at tick, using values stored by ANY part...
+
+ ciMidiCtrlVal i = lower_bound(tick);
+ if (i == end() || i->first != tick) {
+ if (i == begin())
+ return CTRL_VAL_UNKNOWN;
+ --i;
+ }
+ return i->second.val;
+}
+
+int MidiCtrlValList::value(int tick, Part* part) const
+{
+ // Determine value at tick, using values stored by the SPECIFIC part...
+
+ // Get the first value found with with a tick equal or greater than specified tick.
+ ciMidiCtrlVal i = lower_bound(tick);
+ // Since values from different parts can have the same tick, scan for part in all values at that tick.
+ for(ciMidiCtrlVal j = i; j != end() && j->first == tick; ++j)
+ {
+ if(j->second.part == part)
+ return j->second.val;
+ }
+ // Scan for part in all previous values, regardless of tick.
+ while(i != begin())
+ {
+ --i;
+ if(i->second.part == part)
+ return i->second.val;
+ }
+ // No previous values were found belonging to the specified part.
+ return CTRL_VAL_UNKNOWN;
+}
+
+//---------------------------------------------------------
+// add
+// return true if new controller value added or replaced
+//---------------------------------------------------------
+
+// Changed by T356.
+//bool MidiCtrlValList::add(int tick, int val)
+bool MidiCtrlValList::addMCtlVal(int tick, int val, Part* part)
+ {
+ iMidiCtrlVal e = findMCtlVal(tick, part);
+
+ if (e != end()) {
+ if(e->second.val != val)
+ {
+ e->second.val = val;
+ return true;
+ }
+ return false;
+ }
+
+ MidiCtrlVal v;
+ v.val = val;
+ v.part = part;
+ insert(std::pair<const int, MidiCtrlVal> (tick, v));
+ return true;
+ }
+
+//---------------------------------------------------------
+// del
+//---------------------------------------------------------
+
+// Changed by T356.
+//void MidiCtrlValList::del(int tick)
+void MidiCtrlValList::delMCtlVal(int tick, Part* part)
+{
+ iMidiCtrlVal e = findMCtlVal(tick, part);
+ if (e == end()) {
+ if(debugMsg)
+ printf("MidiCtrlValList::delMCtlVal(%d): not found (size %zd)\n", tick, size());
+ return;
+ }
+ erase(e);
+}
+
+//---------------------------------------------------------
+// find
+//---------------------------------------------------------
+
+// Changed by T356.
+//iMidiCtrlVal MidiCtrlValList::find(int tick, Part* part)
+iMidiCtrlVal MidiCtrlValList::findMCtlVal(int tick, Part* part)
+{
+ MidiCtrlValRange range = equal_range(tick);
+ for(iMidiCtrlVal i = range.first; i != range.second; ++i)
+ {
+ if(i->second.part == part)
+ return i;
+ }
+ return end();
+}
+
+//---------------------------------------------------------
+// MidiControllerList
+//---------------------------------------------------------
+
+MidiControllerList::MidiControllerList(const MidiControllerList& mcl) : std::map<int, MidiController*>()
+{
+ //copy(mcl);
+
+ for(ciMidiController i = mcl.begin(); i != mcl.end(); ++i)
+ {
+ MidiController* mc = i->second;
+ add(new MidiController(*mc));
+ }
+}
+
+//---------------------------------------------------------
+// copy
+//---------------------------------------------------------
+//void MidiControllerList::copy(const MidiControllerList &mcl)
+//{
+// clear();
+// for(ciMidiController i = mcl.begin(); i != mcl.end(); ++i)
+// {
+// MidiController* mc = *i;
+// push_back(new MidiController(*mc));
+// }
+//}
+
+//---------------------------------------------------------
+// operator =
+//---------------------------------------------------------
+//MidiControllerList& MidiControllerList::operator= (const MidiControllerList &mcl)
+//{
+// copy(mcl);
+// return *this;
+//}