summaryrefslogtreecommitdiff
path: root/muse2/muse/miditransform.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'muse2/muse/miditransform.cpp')
-rw-r--r--muse2/muse/miditransform.cpp1702
1 files changed, 1702 insertions, 0 deletions
diff --git a/muse2/muse/miditransform.cpp b/muse2/muse/miditransform.cpp
new file mode 100644
index 00000000..486f47c5
--- /dev/null
+++ b/muse2/muse/miditransform.cpp
@@ -0,0 +1,1702 @@
+//=========================================================
+// MusE
+// Linux Music Editor
+// $Id: miditransform.cpp,v 1.8.2.3 2009/05/24 21:43:44 terminator356 Exp $
+//
+// (C) Copyright 2001 Werner Schweer (ws@seh.de)
+//=========================================================
+
+#include <stdio.h>
+#include <list>
+#include <qpushbutton.h>
+#include <qlineedit.h>
+#include <qcombobox.h>
+#include <q3listbox.h>
+#include <qspinbox.h>
+#include <q3multilineedit.h>
+#include <qcheckbox.h>
+
+#include "helper.h"
+#include "spinboxFP.h"
+#include "event.h"
+#include "miditransform.h"
+#include "track.h"
+#include "song.h"
+#include "xml.h"
+#include "globals.h"
+#include "comboQuant.h"
+#include "pitchedit.h"
+#include "audio.h"
+#include "gconfig.h"
+#include "midictrl.h"
+
+//
+// Order of events:
+// Note, Poly Pressure, Control, AfterTouch, Pitch Bend, NRPN, RPN
+//
+#define MIDITRANSFORM_NOTE 0
+#define MIDITRANSFORM_POLY 1
+#define MIDITRANSFORM_CTRL 2
+#define MIDITRANSFORM_ATOUCH 3
+#define MIDITRANSFORM_PITCHBEND 4
+#define MIDITRANSFORM_NRPN 5
+#define MIDITRANSFORM_RPN 6
+
+
+static int eventTypeTable[] = {
+ MIDITRANSFORM_NOTE, MIDITRANSFORM_POLY, MIDITRANSFORM_CTRL, MIDITRANSFORM_ATOUCH,
+ MIDITRANSFORM_PITCHBEND, MIDITRANSFORM_NRPN, MIDITRANSFORM_RPN
+ };
+
+static int procVal2Map[] = { 0, 1, 2, 3, 4, 5, 6, 7, 10, 11 };
+
+//---------------------------------------------------------
+// MidiTransformation
+//---------------------------------------------------------
+
+class MidiTransformation {
+ public:
+ QString name;
+ QString comment;
+
+ ValOp selEventOp;
+ EventType selType;
+
+ ValOp selVal1;
+ int selVal1a, selVal1b;
+ ValOp selVal2;
+ int selVal2a, selVal2b;
+ ValOp selLen;
+ int selLenA, selLenB;
+ ValOp selRange;
+ int selRangeA, selRangeB;
+
+ TransformOperator procEvent;
+ EventType eventType;
+ TransformOperator procVal1;
+ int procVal1a, procVal1b;
+ TransformOperator procVal2;
+ int procVal2a, procVal2b;
+ TransformOperator procLen;
+ int procLenA;
+ TransformOperator procPos;
+ int procPosA;
+
+ TransformFunction funcOp;
+ int quantVal;
+ bool selectedTracks;
+ bool insideLoop;
+
+ MidiTransformation(const QString& s) {
+ name = s;
+ selEventOp = All;
+ selType = Note;
+ selVal1 = Ignore;
+ selVal1a = 0;
+ selVal1b = 0;
+ selVal2 = Ignore;
+ selVal2a = 0;
+ selVal2b = 0;
+ selLen = Ignore;
+ selLenA = 0;
+ selLenB = 0;
+ selRange = Ignore;
+ selRangeA = 0;
+ selRangeB = 0;
+ procEvent = Keep;
+ eventType = Note;
+ procVal1 = Keep;
+ procVal1a = 0;
+ procVal1b = 0;
+ procVal2 = Keep;
+ procVal2a = 0;
+ procVal2b = 0;
+ procLen = Keep;
+ procLenA = 0;
+ procPos = Keep;
+ procPosA = 0;
+ funcOp = Select;
+ quantVal = config.division;
+ selectedTracks = false;
+ insideLoop = false;
+ }
+ void write(int level, Xml& xml);
+ };
+
+class MidiTransformPrivate {
+ public:
+ MidiTransformation* cmt;
+ int cindex; // current index in preset list
+ };
+
+typedef std::list<MidiTransformation* > MidiTransformationList;
+typedef std::list<MidiTransformation* >::iterator iMidiTransformation;
+typedef std::list<MidiTransformation* >::const_iterator ciMidiTransformation;
+
+static MidiTransformationList mtlist;
+
+//---------------------------------------------------------
+// MidiTransformDialog
+// Widgets:
+// presetList nameEntry commentEntry
+// selEventOp selType
+// selVal1Op selVal1a selVal1b
+// selVal2Op selVal2a selVal2b
+// selLenOp selLenA selLenB
+// selRangeOp selBarA selBarB
+//
+// procEventOp procType
+// procVal1Op procVal1a procVal1b
+// procVal2Op procVal2a procVal2b
+// procLenOp procLenA
+// procPosOp procPosA
+// funcOp funcQuantVal
+// processAll selectedTracks insideLoop
+// buttonNew buttonDelete buttonApply buttonOk
+//---------------------------------------------------------
+
+MidiTransformerDialog::MidiTransformerDialog(QWidget* parent,
+ const char* name, bool modal, Qt::WFlags fl)
+ : MidiTransformDialogBase(parent, name, modal, fl)
+ {
+ data = new MidiTransformPrivate;
+ data->cmt = 0;
+ data->cindex = -1;
+ connect(buttonApply, SIGNAL(clicked()), SLOT(apply()));
+ connect(buttonNew, SIGNAL(clicked()), SLOT(presetNew()));
+ connect(buttonDelete, SIGNAL(clicked()), SLOT(presetDelete()));
+ connect(selEventOp, SIGNAL(activated(int)), SLOT(selEventOpSel(int)));
+ connect(selType, SIGNAL(activated(int)), SLOT(selTypeSel(int)));
+ connect(selVal1Op, SIGNAL(activated(int)), SLOT(selVal1OpSel(int)));
+ connect(selVal2Op, SIGNAL(activated(int)), SLOT(selVal2OpSel(int)));
+ connect(selLenOp, SIGNAL(activated(int)), SLOT(selLenOpSel(int)));
+ connect(selRangeOp, SIGNAL(activated(int)), SLOT(selRangeOpSel(int)));
+ connect(procEventOp, SIGNAL(activated(int)), SLOT(procEventOpSel(int)));
+ connect(procType, SIGNAL(activated(int)), SLOT(procEventTypeSel(int)));
+ connect(procVal1Op, SIGNAL(activated(int)), SLOT(procVal1OpSel(int)));
+ connect(procVal2Op, SIGNAL(activated(int)), SLOT(procVal2OpSel(int)));
+ connect(procLenOp, SIGNAL(activated(int)), SLOT(procLenOpSel(int)));
+ connect(procPosOp, SIGNAL(activated(int)), SLOT(procPosOpSel(int)));
+ connect(funcOp, SIGNAL(activated(int)), SLOT(funcOpSel(int)));
+ connect(funcQuantVal, SIGNAL(valueChanged(int)), SLOT(funcQuantValSel(int)));
+ connect(presetList, SIGNAL(highlighted(Q3ListBoxItem*)),
+ SLOT(presetChanged(Q3ListBoxItem*)));
+ connect(nameEntry, SIGNAL(textChanged(const QString&)),
+ SLOT(nameChanged(const QString&)));
+ connect(commentEntry, SIGNAL(textChanged()), SLOT(commentChanged()));
+
+ connect(selVal1a, SIGNAL(valueChanged(int)), SLOT(selVal1aChanged(int)));
+ connect(selVal1b, SIGNAL(valueChanged(int)), SLOT(selVal1bChanged(int)));
+ connect(selVal2a, SIGNAL(valueChanged(int)), SLOT(selVal2aChanged(int)));
+ connect(selVal2b, SIGNAL(valueChanged(int)), SLOT(selVal2bChanged(int)));
+ connect(selLenA, SIGNAL(valueChanged(int)), SLOT(selLenAChanged(int)));
+ connect(selLenB, SIGNAL(valueChanged(int)), SLOT(selLenBChanged(int)));
+ connect(selBarA, SIGNAL(valueChanged(int)), SLOT(selBarAChanged(int)));
+ connect(selBarB, SIGNAL(valueChanged(int)), SLOT(selBarBChanged(int)));
+ connect(procVal1a, SIGNAL(valueChanged(int)), SLOT(procVal1aChanged(int)));
+ connect(procVal1b, SIGNAL(valueChanged(int)), SLOT(procVal1bChanged(int)));
+ connect(procVal2a, SIGNAL(valueChanged(int)), SLOT(procVal2aChanged(int)));
+ connect(procVal2b, SIGNAL(valueChanged(int)), SLOT(procVal2bChanged(int)));
+ connect(procLenA, SIGNAL(valueChanged(int)), SLOT(procLenAChanged(int)));
+ connect(procPosA, SIGNAL(valueChanged(int)), SLOT(procPosAChanged(int)));
+
+ connect(processAll, SIGNAL(toggled(bool)), SLOT(processAllChanged(bool)));
+ connect(selectedTracks, SIGNAL(toggled(bool)), SLOT(selectedTracksChanged(bool)));
+ connect(insideLoop, SIGNAL(toggled(bool)), SLOT(insideLoopChanged(bool)));
+
+ //---------------------------------------------------
+ // populate preset list
+ //---------------------------------------------------
+
+ updatePresetList();
+ connect(song, SIGNAL(songChanged(int)), SLOT(songChanged(int)));
+ }
+
+//---------------------------------------------------------
+// ~MidiTransformDialog
+//---------------------------------------------------------
+
+MidiTransformerDialog::~MidiTransformerDialog()
+ {
+ delete data;
+ }
+
+//---------------------------------------------------------
+// songChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::songChanged(int flags)
+{
+ // Whenever a song is loaded, flags is -1. Since transforms are part of configuration,
+ // use SC_CONFIG here, to filter unwanted song change events.
+ if(flags & SC_CONFIG)
+ updatePresetList();
+}
+
+//---------------------------------------------------------
+// updatePresetList
+//---------------------------------------------------------
+
+void MidiTransformerDialog::updatePresetList()
+{
+ data->cmt = 0;
+ data->cindex = 0;
+ presetList->clear();
+ for (iMidiTransformation i = mtlist.begin(); i != mtlist.end(); ++i) {
+ presetList->insertItem((*i)->name);
+ if (data->cmt == 0)
+ data->cmt = *i;
+ }
+ if (data->cmt == 0) {
+ data->cmt = new MidiTransformation(tr("New"));
+ mtlist.push_back(data->cmt);
+ presetList->insertItem(tr("New"));
+ presetList->setCurrentItem(0);
+ }
+
+ //data->cindex = 0;
+ //presetList->setCurrentItem(0);
+
+}
+
+//---------------------------------------------------------
+// writeMidiTransforms
+//---------------------------------------------------------
+
+void writeMidiTransforms(int level, Xml& xml)
+ {
+ for (iMidiTransformation i = mtlist.begin(); i != mtlist.end(); ++i) {
+ (*i)->write(level, xml);
+ }
+ }
+
+//---------------------------------------------------------
+// write
+//---------------------------------------------------------
+
+void MidiTransformation::write(int level, Xml& xml)
+ {
+ xml.tag(level++, "midiTransform");
+ xml.strTag(level, "name", name);
+ xml.strTag(level, "comment", comment);
+ xml.intTag(level, "function", int(funcOp));
+ xml.intTag(level, "selectedTracks", selectedTracks);
+ xml.intTag(level, "insideLoop", insideLoop);
+ if (funcOp == Quantize) {
+ xml.intTag(level, "quantVal", quantVal);
+ }
+ if (funcOp == Transform || funcOp == Insert) {
+ if (procEvent != Keep) {
+ xml.intTag(level, "procEventOp", int(procEvent));
+ xml.intTag(level, "eventType", int(eventType));
+ }
+ if (procVal1 != Keep) {
+ xml.intTag(level, "procVal1Op", int(procVal1));
+ xml.intTag(level, "procVal1a", procVal1a);
+ xml.intTag(level, "procVal1b", procVal1b);
+ }
+ if (procVal2 != Keep) {
+ xml.intTag(level, "procVal2Op", int(procVal2));
+ xml.intTag(level, "procVal2a", procVal2a);
+ xml.intTag(level, "procVal2b", procVal2b);
+ }
+ if (procLen != Keep) {
+ xml.intTag(level, "procLenOp", int(procLen));
+ xml.intTag(level, "procLen", procLenA);
+ }
+ if (procPos != Keep) {
+ xml.intTag(level, "procPosOp", int(procPos));
+ xml.intTag(level, "procPos", procPosA);
+ }
+ }
+ if (selEventOp != Ignore) {
+ xml.intTag(level, "selEventOp", int(selEventOp));
+ xml.intTag(level, "selEventType", int(selType));
+ }
+ if (selVal1 != Ignore) {
+ xml.intTag(level, "selVal1Op", int(selVal1));
+ xml.intTag(level, "selVal1a", selVal1a);
+ xml.intTag(level, "selVal1b", selVal1b);
+ }
+ if (selVal2 != Ignore) {
+ xml.intTag(level, "selVal2Op", int(selVal2));
+ xml.intTag(level, "selVal2a", selVal2a);
+ xml.intTag(level, "selVal2b", selVal2b);
+ }
+ if (selLen != Ignore) {
+ xml.intTag(level, "selLenOp", int(selLen));
+ xml.intTag(level, "selLenA", selLenA);
+ xml.intTag(level, "selLenB", selLenB);
+ }
+ if (selRange != Ignore) {
+ xml.intTag(level, "selRangeOp", int(selRange));
+ xml.intTag(level, "selRangeA", selRangeA);
+ xml.intTag(level, "selRangeB", selRangeB);
+ }
+ xml.etag(level, "midiTransform");
+ }
+
+//---------------------------------------------------------
+// readMidiTransform
+//---------------------------------------------------------
+
+void readMidiTransform(Xml& xml)
+ {
+ MidiTransformation trans(QWidget::tr("new"));
+
+ for (;;) {
+ Xml::Token token = xml.parse();
+ const QString& tag = xml.s1();
+ switch (token) {
+ case Xml::Error:
+ case Xml::End:
+ return;
+ case Xml::TagStart:
+ if (tag == "name")
+ trans.name = xml.parse1();
+ else if (tag == "comment")
+ trans.comment = xml.parse1();
+ else if (tag == "function")
+ trans.funcOp = TransformFunction(xml.parseInt());
+ else if (tag == "selectedTracks")
+ trans.selectedTracks = xml.parseInt();
+ else if (tag == "insideLoop")
+ trans.insideLoop = xml.parseInt();
+ else if (tag == "quantVal")
+ trans.quantVal = xml.parseInt();
+ else if (tag == "procEventOp")
+ trans.procEvent = TransformOperator(xml.parseInt());
+ else if (tag == "eventType")
+ trans.eventType = EventType(xml.parseInt());
+ else if (tag == "procVal1Op")
+ trans.procVal1 = TransformOperator(xml.parseInt());
+ else if (tag == "procVal1a")
+ trans.procVal1a = xml.parseInt();
+ else if (tag == "procVal1b")
+ trans.procVal1b = xml.parseInt();
+ else if (tag == "procVal2Op")
+ trans.procVal2 = TransformOperator(xml.parseInt());
+ else if (tag == "procVal2a")
+ trans.procVal2a = xml.parseInt();
+ else if (tag == "procVal2b")
+ trans.procVal2b = xml.parseInt();
+ else if (tag == "procLenOp")
+ trans.procLen = TransformOperator(xml.parseInt());
+ else if (tag == "procLen")
+ trans.procLenA = xml.parseInt();
+ else if (tag == "procPosOp")
+ trans.procPos = TransformOperator(xml.parseInt());
+ else if (tag == "procPos")
+ trans.procPosA = xml.parseInt();
+ else if (tag == "selEventOp")
+ trans.selEventOp = ValOp(xml.parseInt());
+ else if (tag == "selEventType")
+ trans.selType = EventType(xml.parseInt());
+ else if (tag == "selVal1Op")
+ trans.selVal1 = ValOp(xml.parseInt());
+ else if (tag == "selVal1a")
+ trans.selVal1a = xml.parseInt();
+ else if (tag == "selVal1b")
+ trans.selVal1b = xml.parseInt();
+ else if (tag == "selVal2Op")
+ trans.selVal2 = ValOp(xml.parseInt());
+ else if (tag == "selVal2a")
+ trans.selVal2a = xml.parseInt();
+ else if (tag == "selVal2b")
+ trans.selVal2b = xml.parseInt();
+ else if (tag == "selLenOp")
+ trans.selLen = ValOp(xml.parseInt());
+ else if (tag == "selLenA")
+ trans.selLenA = xml.parseInt();
+ else if (tag == "selLenB")
+ trans.selLenB = xml.parseInt();
+ else if (tag == "selRangeOp")
+ trans.selRange = ValOp(xml.parseInt());
+ else if (tag == "selRangeA")
+ trans.selRangeA = xml.parseInt();
+ else if (tag == "selRangeB")
+ trans.selRangeB = xml.parseInt();
+ else
+ xml.unknown("midiTransform");
+ break;
+ case Xml::TagEnd:
+ if (xml.s1() == "midiTransform") {
+ // By T356. A previous bug caused some .med files to grow very large
+ // with duplicate transforms. Here we can eliminate those duplicates.
+ for(iMidiTransformation i = mtlist.begin(); i != mtlist.end(); ++i)
+ {
+ if((*i)->name == trans.name)
+ return;
+ }
+
+ MidiTransformation* t = new MidiTransformation(trans);
+ mtlist.push_back(t);
+ return;
+ }
+ default:
+ break;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// clearMidiTransforms
+//---------------------------------------------------------
+
+void clearMidiTransforms()
+{
+ for (iMidiTransformation i = mtlist.begin(); i != mtlist.end(); ++i)
+ {
+ MidiTransformation* t = *i;
+ if(t)
+ delete t;
+ }
+ mtlist.clear();
+}
+
+//---------------------------------------------------------
+// accept
+//---------------------------------------------------------
+
+void MidiTransformerDialog::accept()
+ {
+ apply();
+ reject();
+ }
+
+//---------------------------------------------------------
+// transformEvent
+// subfunction of processEvent()
+//---------------------------------------------------------
+
+void MidiTransformerDialog::transformEvent(Event& event, MidiPart* part,
+ MidiPart* newPart)
+ {
+ MidiTransformation* cmt = data->cmt;
+ Event newEvent = event.clone();
+
+ if (cmt->procEvent != Keep)
+ newEvent.setType(cmt->eventType);
+
+ //---------------------------------------------------
+ // transform value A
+ //---------------------------------------------------
+
+ int val = newEvent.dataA();
+ switch (cmt->procVal1) {
+ case Keep:
+ break;
+ case Plus:
+ val += cmt->procVal1a;
+ break;
+ case Minus:
+ val -= cmt->procVal1a;
+ break;
+ case Multiply:
+ val = int(val * (cmt->procVal1a/100.0) + .5);
+ break;
+ case Divide:
+ val = int(val / (cmt->procVal1a/100.0) + .5);
+ break;
+ case Fix:
+ val = cmt->procVal1a;
+ break;
+ case Value:
+ val = cmt->procVal2a;
+ break;
+ case Invert:
+ val = 128 - val;
+ break;
+ case ScaleMap:
+ printf("scale map not implemented\n");
+ break;
+ case Flip:
+ val = cmt->procVal1a - val;
+ break;
+ case Dynamic: // "crescendo"
+ val = (((cmt->procVal2b-cmt->procVal2a)
+ * (newEvent.tick() - song->lpos()))
+ / (song->rpos() - song->lpos())) + cmt->procVal2a;
+ break;
+ case Random:
+ {
+ int range = cmt->procVal1b - cmt->procVal1a;
+ if (range > 0)
+ val = (rand() % range) + cmt->procVal1a;
+ else if (range < 0)
+ val = (rand() % -range) + cmt->procVal1b;
+ else
+ val = cmt->procVal1a;
+ }
+ break;
+ }
+ if (val < 0)
+ val = 0;
+ if (val > 127)
+ val = 127;
+ newEvent.setA(val);
+
+ //---------------------------------------------------
+ // transform value B
+ //---------------------------------------------------
+
+ val = newEvent.dataB();
+ switch (cmt->procVal2) {
+ case Plus:
+ val += cmt->procVal2a;
+ break;
+ case Minus:
+ val -= cmt->procVal2a;
+ break;
+ case Multiply:
+ val = int(val * (cmt->procVal2a/100.0) + .5);
+ break;
+ case Divide:
+ val = int(val / (cmt->procVal2a/100.0) + .5);
+ break;
+ case Fix:
+ val = cmt->procVal2a;
+ break;
+ case Value:
+ val = cmt->procVal1a;
+ break;
+ case Invert:
+ val = 128 - val;
+ break;
+ case Dynamic:
+ val = (((cmt->procVal2b-cmt->procVal2a)
+ * (newEvent.tick() - song->lpos()))
+ / (song->rpos() - song->lpos())) + cmt->procVal2a;
+ break;
+ case Random:
+ {
+ int range = cmt->procVal2b - cmt->procVal2a;
+ if (range > 0)
+ val = (rand() % range) + cmt->procVal2a;
+ else if (range < 0)
+ val = (rand() % -range) + cmt->procVal2b;
+ else
+ val = cmt->procVal1a;
+ }
+ break;
+ case ScaleMap:
+ case Keep:
+ case Flip:
+ break;
+ }
+ if (val < 0)
+ val = 0;
+ if (val > 127)
+ val = 127;
+ newEvent.setB(val);
+
+ //---------------------------------------------------
+ // transform len
+ //---------------------------------------------------
+
+ int len = newEvent.lenTick();
+ switch (cmt->procLen) {
+ case Plus:
+ len += cmt->procLenA;
+ break;
+ case Minus:
+ len -= cmt->procLenA;
+ break;
+ case Multiply:
+ len = int(val * (cmt->procLenA/100.0) + .5);
+ break;
+ case Divide:
+ len = int(val / (cmt->procLenA/100.0) + .5);
+ break;
+ case Fix:
+ len = cmt->procLenA;
+ break;
+ case Invert:
+ case ScaleMap:
+ case Dynamic:
+ case Random:
+ case Keep:
+ case Flip:
+ case Value:
+ break;
+ }
+ if (len < 0)
+ len = 0;
+ newEvent.setLenTick(len);
+
+ //---------------------------------------------------
+ // transform pos
+ //---------------------------------------------------
+
+ int pos = newEvent.tick();
+ switch (cmt->procPos) {
+ case Plus:
+ pos += cmt->procPosA;
+ break;
+ case Minus:
+ pos -= cmt->procPosA;
+ break;
+ case Multiply:
+ pos = int(val * (cmt->procPosA/100.0) + .5);
+ break;
+ case Divide:
+ pos = int(val / (cmt->procPosA/100.0) + .5);
+ break;
+ case Fix:
+ case Invert:
+ case ScaleMap:
+ case Dynamic:
+ case Random:
+ case Keep:
+ case Flip:
+ case Value:
+ break;
+ }
+ if (pos < 0)
+ pos = 0;
+ newEvent.setTick(pos);
+
+ Event dummy;
+ switch(data->cmt->funcOp) {
+ case Transform:
+ // Indicate do clone parts.
+ removePortCtrlEvents(event, part, true);
+ song->changeEvent(event, newEvent, part);
+ // Indicate do clone parts.
+ addPortCtrlEvents(newEvent, part, true);
+ // Indicate do port controller values and clone parts.
+ //song->undoOp(UndoOp::ModifyEvent, newEvent, event, part);
+ song->undoOp(UndoOp::ModifyEvent, newEvent, event, part, true, true);
+ song->addUpdateFlags(SC_EVENT_MODIFIED);
+ break;
+ case Insert:
+ // Indicate do port controller values and clone parts.
+ //song->undoOp(UndoOp::AddEvent, dummy, newEvent, part);
+ song->undoOp(UndoOp::AddEvent, dummy, newEvent, part, true, true);
+ song->addEvent(newEvent, part);
+ // Indicate do clone parts.
+ addPortCtrlEvents(newEvent, part, true);
+ song->addUpdateFlags(SC_EVENT_INSERTED);
+ break;
+ case Extract:
+ // Indicate do port controller values and clone parts.
+ //song->undoOp(UndoOp::DeleteEvent, dummy, event, part);
+ song->undoOp(UndoOp::DeleteEvent, dummy, event, part, true, true);
+ // Indicate do clone parts.
+ removePortCtrlEvents(event, part, true);
+ song->deleteEvent(event, part);
+ song->addUpdateFlags(SC_EVENT_REMOVED);
+ case Copy:
+ newPart->addEvent(newEvent);
+ break;
+ default:
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// processEvent
+//---------------------------------------------------------
+
+void MidiTransformerDialog::processEvent(Event& event, MidiPart* part, MidiPart* newPart)
+ {
+ switch(data->cmt->funcOp) {
+ case Select:
+ break;
+ case Quantize:
+ {
+ int tick = event.tick();
+ int rt = sigmap.raster(tick, data->cmt->quantVal) - tick;
+ if (tick != rt) {
+ // Indicate do clone parts.
+ removePortCtrlEvents(event, part, true);
+ Event newEvent = event.clone();
+ newEvent.setTick(rt);
+ song->changeEvent(event, newEvent, part);
+ // Indicate do clone parts.
+ addPortCtrlEvents(newEvent, part, true);
+ // Indicate do port controller values and clone parts.
+ //song->undoOp(UndoOp::ModifyEvent, newEvent, event, part);
+ song->undoOp(UndoOp::ModifyEvent, newEvent, event, part, true, true);
+ song->addUpdateFlags(SC_EVENT_MODIFIED);
+ }
+ }
+ break;
+ case Delete:
+ {
+ Event ev;
+ // Indicate do port controller values and clone parts.
+ //song->undoOp(UndoOp::DeleteEvent, ev, event, part, true, true);
+ song->undoOp(UndoOp::DeleteEvent, ev, event, part, true, true);
+ // Indicate do clone parts.
+ removePortCtrlEvents(event, part, true);
+ song->deleteEvent(event, part);
+ song->addUpdateFlags(SC_EVENT_REMOVED);
+ }
+ break;
+ case Transform:
+ case Insert:
+ case Copy:
+ case Extract:
+ transformEvent(event, part, newPart);
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// isSelected
+// apply Select filter
+// return true if event is selected
+//---------------------------------------------------------
+
+bool MidiTransformerDialog::isSelected(Event& event, MidiPart*)
+ {
+ MidiTransformation* cmt = data->cmt;
+
+ switch (cmt->selEventOp) {
+ case Equal:
+ if (!typesMatch(event, cmt->selType)) {
+ return false;
+ }
+ break;
+ case Unequal:
+ if (typesMatch(event, cmt->selType))
+ return false;
+ break;
+ default:
+ break;
+ }
+ switch (cmt->selVal1) {
+ case Ignore:
+ break;
+ case Equal:
+ if (event.dataA() != cmt->selVal1a)
+ return false;
+ break;
+ case Unequal:
+ if (event.dataA() == cmt->selVal1a)
+ return false;
+ break;
+ case Higher:
+ if (event.dataA() <= cmt->selVal1a)
+ return false;
+ break;
+ case Lower:
+ if (event.dataA() >= cmt->selVal1a)
+ return false;
+ break;
+ case Inside:
+ if ((event.dataA() < cmt->selVal1a)
+ || (event.dataA() >= cmt->selVal1b))
+ return false;
+ break;
+ case Outside:
+ if ((event.dataA() >= cmt->selVal1a)
+ && (event.dataA() < cmt->selVal1b))
+ return false;
+ break;
+ }
+ switch (cmt->selVal2) {
+ case Ignore:
+ break;
+ case Equal:
+ if (event.dataB() != cmt->selVal2a)
+ return false;
+ break;
+ case Unequal:
+ if (event.dataB() == cmt->selVal2a)
+ return false;
+ break;
+ case Higher:
+ if (event.dataB() <= cmt->selVal2a)
+ return false;
+ break;
+ case Lower:
+ if (event.dataB() >= cmt->selVal2a)
+ return false;
+ break;
+ case Inside:
+ if ((event.dataB() < cmt->selVal2a)
+ || (event.dataB() >= cmt->selVal2b))
+ return false;
+ break;
+ case Outside:
+ if ((event.dataB() >= cmt->selVal2a)
+ && (event.dataB() < cmt->selVal2b))
+ return false;
+ break;
+ }
+ int len = event.lenTick();
+ switch (cmt->selLen) {
+ case Ignore:
+ break;
+ case Equal:
+ if (len != cmt->selLenA)
+ return false;
+ break;
+ case Unequal:
+ if (len == cmt->selLenA)
+ return false;
+ break;
+ case Higher:
+ if (len <= cmt->selLenA)
+ return false;
+ break;
+ case Lower:
+ if (len >= cmt->selLenA)
+ return false;
+ break;
+ case Inside:
+ if ((len < cmt->selLenA) || (len >= cmt->selLenB))
+ return false;
+ break;
+ case Outside:
+ if ((len >= cmt->selLenA) && (len < cmt->selLenB))
+ return false;
+ break;
+ }
+ int bar, beat;
+ unsigned tick;
+ sigmap.tickValues(event.tick(), &bar, &beat, &tick);
+ int beat1 = cmt->selRangeA / 1000;
+ unsigned tick1 = cmt->selRangeA % 1000;
+ int beat2 = cmt->selRangeB / 1000;
+ unsigned tick2 = cmt->selRangeB % 1000;
+ switch (cmt->selRange) {
+ case Ignore:
+ break;
+ case Equal:
+ if (beat != beat1 || tick != tick1)
+ return false;
+ break;
+ case Unequal:
+ if (beat == beat1 && tick == tick1)
+ return false;
+ break;
+ case Higher:
+ if (beat <= beat1)
+ return false;
+ if (beat == beat1 && tick <= tick1)
+ return false;
+ break;
+ case Lower:
+ if (beat >= beat1)
+ return false;
+ if (beat == beat1 && tick >= tick1)
+ return false;
+ break;
+ case Inside:
+ if ((beat < beat1) || (beat >= beat2))
+ return false;
+ if (beat == beat1 && tick < tick1)
+ return false;
+ if (beat == beat2 && tick >= tick2)
+ return false;
+ break;
+ case Outside:
+ if ((beat >= beat1) || (beat < beat2))
+ return false;
+ if (beat == beat1 && tick >= tick1)
+ return false;
+ if (beat == beat2 && tick < tick2)
+ return false;
+ break;
+ }
+ return true;
+ }
+
+//---------------------------------------------------------
+// apply
+//---------------------------------------------------------
+
+void MidiTransformerDialog::apply()
+ {
+ int flags = 0;
+ song->startUndo();
+ audio->msgIdle(true);
+ bool copyExtract = (data->cmt->funcOp == Copy)
+ || (data->cmt->funcOp == Extract);
+
+ std::vector< EventList* > doneList;
+ typedef std::vector< EventList* >::iterator iDoneList;
+ iDoneList idl;
+
+ MidiTrackList* tracks = song->midis();
+ MidiTrackList tl;
+ for (iMidiTrack t = tracks->begin(); t != tracks->end(); ++t) {
+ if (data->cmt->selectedTracks && !(*t)->selected())
+ continue;
+ MidiTrack* newTrack = 0;
+ PartList *pl = (*t)->parts();
+ if (copyExtract) {
+ // check wether we must generate a new track
+ for (iPart p = pl->begin(); p != pl->end(); ++p) {
+ MidiPart* part = (MidiPart *) p->second;
+ EventList* el = part->events();
+ // Check if the event list has already been done. Skip repeated clones.
+ for(idl = doneList.begin(); idl != doneList.end(); ++idl)
+ if(*idl == el)
+ break;
+ if(idl != doneList.end())
+ break;
+ doneList.push_back(el);
+
+ for (iEvent i = el->begin(); i != el->end(); ++i) {
+ Event event = i->second;
+ unsigned tick = event.tick();
+ if (data->cmt->insideLoop && (tick < song->lpos() || tick >= song->rpos()))
+ continue;
+ if (isSelected(event, part)) {
+ newTrack = new MidiTrack();
+ tl.push_back(newTrack);
+ break;
+ }
+ }
+ if (newTrack)
+ break;
+ }
+ }
+
+ for (iPart p = pl->begin(); p != pl->end(); ++p) {
+ MidiPart* part = (MidiPart *) p->second;
+ MidiPart* newPart = 0;
+ EventList* el = part->events();
+ // Check if the event list has already been done. Skip repeated clones.
+ for(idl = doneList.begin(); idl != doneList.end(); ++idl)
+ if(*idl == el)
+ break;
+ if(idl != doneList.end())
+ break;
+ doneList.push_back(el);
+
+ if (copyExtract) {
+ // check wether we must generate a new part
+ for (iEvent i = el->begin(); i != el->end(); ++i) {
+ Event event = i->second;
+ unsigned tick = event.tick();
+ if (data->cmt->insideLoop && (tick < song->lpos() || tick >= song->rpos()))
+ continue;
+ if (isSelected(event, part)) {
+ newPart = new MidiPart(newTrack);
+ newPart->setName(part->name());
+ newPart->setColorIndex(part->colorIndex());
+ newPart->setTick(part->tick());
+ newPart->setLenTick(part->lenTick());
+ song->addPart(newPart);
+ flags |= SC_PART_INSERTED;
+ break;
+ }
+ }
+ }
+ EventList pel;
+ for (iEvent i = el->begin(); i != el->end(); ++i) {
+ Event event = i->second;
+ unsigned tick = event.tick();
+ if (data->cmt->insideLoop && (tick < song->lpos() || tick >= song->rpos()))
+ continue;
+ int flag = isSelected(event, part);
+ if (data->cmt->funcOp == Select)
+ event.setSelected(flag);
+ else if (flag)
+ pel.add(event);
+ }
+ for (iEvent i = pel.begin(); i != pel.end(); ++i) {
+ Event event = i->second;
+ processEvent(event, part, newPart);
+ }
+ }
+ }
+ if (!tl.empty()) {
+ flags |= SC_TRACK_INSERTED;
+ for (iTrack t = tl.begin(); t != tl.end(); ++t) {
+ song->insertTrack0(*t, -1);
+ }
+ }
+
+ switch(data->cmt->funcOp) {
+ case Select:
+ flags |= SC_SELECTION;
+ break;
+ case Quantize:
+ flags |= SC_EVENT_MODIFIED;
+ break;
+ case Delete:
+ flags |= SC_EVENT_REMOVED;
+ break;
+ case Transform:
+ flags |= SC_EVENT_MODIFIED;
+ break;
+ case Insert:
+ flags |= SC_EVENT_INSERTED;
+ break;
+ case Copy:
+ flags |= SC_EVENT_INSERTED;
+ case Extract:
+ break;
+ }
+ audio->msgIdle(false);
+ song->endUndo(flags);
+ }
+
+//---------------------------------------------------------
+// setValOp
+//---------------------------------------------------------
+
+void MidiTransformerDialog::setValOp(QWidget* a, QWidget* b, ValOp op)
+ {
+ switch (op) {
+ case Ignore:
+ a->setEnabled(false);
+ b->setEnabled(false);
+ break;
+ case Equal:
+ case Unequal:
+ case Higher:
+ case Lower:
+ a->setEnabled(true);
+ b->setEnabled(false);
+ break;
+ case Inside:
+ case Outside:
+ a->setEnabled(true);
+ b->setEnabled(true);
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// selEventOpSel
+//---------------------------------------------------------
+
+void MidiTransformerDialog::selEventOpSel(int val)
+ {
+ selType->setEnabled(val != All);
+ data->cmt->selEventOp = ValOp(val);
+ selVal1aChanged(data->cmt->selVal1a);
+ selVal1bChanged(data->cmt->selVal1b);
+ }
+
+//---------------------------------------------------------
+// selTypeSel
+//---------------------------------------------------------
+
+void MidiTransformerDialog::selTypeSel(int val)
+ {
+ data->cmt->selType = EventType(eventTypeTable[val]);
+ selVal1aChanged(data->cmt->selVal1a);
+ selVal1bChanged(data->cmt->selVal1b);
+ }
+
+//---------------------------------------------------------
+// selVal1OpSel
+//---------------------------------------------------------
+
+void MidiTransformerDialog::selVal1OpSel(int val)
+ {
+ setValOp(selVal1a, selVal1b, ValOp(val));
+ data->cmt->selVal1 = ValOp(val);
+ }
+
+//---------------------------------------------------------
+// selVal2OpSel
+//---------------------------------------------------------
+
+void MidiTransformerDialog::selVal2OpSel(int val)
+ {
+ setValOp(selVal2a, selVal2b, ValOp(val));
+ data->cmt->selVal2 = ValOp(val);
+ }
+
+//---------------------------------------------------------
+// selLenOpSel
+//---------------------------------------------------------
+
+void MidiTransformerDialog::selLenOpSel(int val)
+ {
+ setValOp(selLenA, selLenB, ValOp(val));
+ data->cmt->selLen = ValOp(val);
+ }
+
+//---------------------------------------------------------
+// selRangeOpSel
+//---------------------------------------------------------
+
+void MidiTransformerDialog::selRangeOpSel(int val)
+ {
+ setValOp(selBarA, selBarB, ValOp(val));
+ data->cmt->selRange = ValOp(val);
+ }
+
+//---------------------------------------------------------
+// procEventOpSel
+//---------------------------------------------------------
+
+void MidiTransformerDialog::procEventOpSel(int val)
+ {
+ TransformOperator op = val == 0 ? Keep : Fix;
+ procType->setEnabled(op == Fix);
+ data->cmt->procEvent = op;
+ }
+
+//---------------------------------------------------------
+// procEventTypeSel
+//---------------------------------------------------------
+
+void MidiTransformerDialog::procEventTypeSel(int val)
+ {
+ data->cmt->eventType = EventType(eventTypeTable[val]);
+ }
+
+//---------------------------------------------------------
+// procVal1OpSel
+//---------------------------------------------------------
+
+void MidiTransformerDialog::procVal1OpSel(int val)
+ {
+ data->cmt->procVal1 = TransformOperator(val);
+ switch(TransformOperator(val)) {
+ case Keep:
+ case Invert:
+ procVal1a->setEnabled(false);
+ procVal1b->setEnabled(false);
+ break;
+ case Multiply:
+ case Divide:
+ procVal1a->setEnabled(true);
+ procVal1a->setPrecision(2);
+ procVal1b->setEnabled(false);
+ break;
+ case Plus:
+ case Minus:
+ case Fix:
+ case Value:
+ case Flip:
+ procVal1a->setPrecision(0);
+ procVal1a->setEnabled(true);
+ procVal1b->setEnabled(false);
+ break;
+ case Random:
+ case ScaleMap:
+ case Dynamic:
+ procVal1a->setPrecision(0);
+ procVal1a->setEnabled(true);
+ procVal1b->setEnabled(true);
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// procVal2OpSel
+//---------------------------------------------------------
+
+void MidiTransformerDialog::procVal2OpSel(int val)
+ {
+ TransformOperator op = TransformOperator(procVal2Map[val]);
+ data->cmt->procVal2 = op;
+
+ switch (op) {
+ case Keep:
+ case Invert:
+ procVal2a->setEnabled(false);
+ procVal2b->setEnabled(false);
+ break;
+ case Multiply:
+ case Divide:
+ procVal2a->setEnabled(true);
+ procVal2a->setPrecision(2);
+ procVal2b->setEnabled(false);
+ break;
+ case Plus:
+ case Minus:
+ case Fix:
+ case Value:
+ procVal2a->setPrecision(0);
+ procVal2a->setEnabled(true);
+ procVal2b->setEnabled(false);
+ break;
+ case Random:
+ case Dynamic:
+ procVal2a->setPrecision(0);
+ procVal2a->setEnabled(true);
+ procVal2b->setEnabled(true);
+ break;
+ default:
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// procLenOpSel
+//---------------------------------------------------------
+
+void MidiTransformerDialog::procLenOpSel(int val)
+ {
+ TransformOperator op = TransformOperator(val);
+ data->cmt->procLen = op;
+
+ switch (op) {
+ case Keep:
+ case Invert:
+ procLenA->setEnabled(false);
+ break;
+ case Plus:
+ case Minus:
+ case Fix:
+ procLenA->setPrecision(0);
+ procLenA->setEnabled(true);
+ break;
+ case Multiply:
+ case Divide:
+ procLenA->setPrecision(2);
+ procLenA->setEnabled(true);
+ break;
+ default:
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// procPosOpSel
+//---------------------------------------------------------
+
+void MidiTransformerDialog::procPosOpSel(int val)
+ {
+ TransformOperator op = TransformOperator(val);
+ data->cmt->procPos = op;
+
+ switch (op) {
+ case Keep:
+ case Invert:
+ procPosA->setEnabled(false);
+ break;
+ case Multiply:
+ case Divide:
+ procPosA->setPrecision(2);
+ procPosA->setEnabled(true);
+ break;
+ case Plus:
+ case Minus:
+ procPosA->setPrecision(0);
+ procPosA->setEnabled(true);
+ break;
+ default:
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// funcOpSel
+//---------------------------------------------------------
+
+void MidiTransformerDialog::funcOpSel(int val)
+ {
+ funcQuantVal->setEnabled(val == Quantize);
+ bool isFuncOp = val == Transform || val == Insert;
+
+ procEventOp->setEnabled(isFuncOp);
+ procType->setEnabled(isFuncOp);
+ procVal1Op->setEnabled(isFuncOp);
+ procVal1a->setEnabled(isFuncOp);
+ procVal1b->setEnabled(isFuncOp);
+ procVal2Op->setEnabled(isFuncOp);
+ procVal2a->setEnabled(isFuncOp);
+ procVal2b->setEnabled(isFuncOp);
+ procLenOp->setEnabled(isFuncOp);
+ procLenA->setEnabled(isFuncOp);
+ procPosOp->setEnabled(isFuncOp);
+ procPosA->setEnabled(isFuncOp);
+ if (isFuncOp) {
+ procEventOpSel(data->cmt->procEvent);
+ procVal1OpSel(data->cmt->procVal1);
+ procVal2OpSel(data->cmt->procVal2);
+ procLenOpSel(data->cmt->procLen);
+ procPosOpSel(data->cmt->procPos);
+ }
+ data->cmt->funcOp = TransformFunction(val);
+ }
+
+//---------------------------------------------------------
+// presetNew
+//---------------------------------------------------------
+
+void MidiTransformerDialog::presetNew()
+ {
+ QString name;
+ for (int i = 0;; ++i) {
+ name.sprintf("New-%d", i);
+ iMidiTransformation imt;
+ for (imt = mtlist.begin(); imt != mtlist.end(); ++imt) {
+ if (name == (*imt)->name)
+ break;
+ }
+ if (imt == mtlist.end())
+ break;
+ }
+ MidiTransformation* mt = new MidiTransformation(name);
+ Q3ListBoxText* lbi = new Q3ListBoxText(presetList, name);
+ mtlist.push_back(mt);
+ presetList->setCurrentItem(lbi);
+ }
+
+//---------------------------------------------------------
+// presetDelete
+//---------------------------------------------------------
+
+void MidiTransformerDialog::presetDelete()
+ {
+ if (data->cindex != -1) {
+ iMidiTransformation mt = mtlist.begin();
+ for (int i = 0; i < data->cindex; ++i, ++mt) {
+ mtlist.erase(mt);
+ presetList->removeItem(data->cindex);
+ break;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// presetChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::presetChanged(Q3ListBoxItem* item)
+ {
+ data->cindex = presetList->index(item);
+ iMidiTransformation i;
+ for (i = mtlist.begin(); i != mtlist.end(); ++i) {
+ if (item->text() == (*i)->name) {
+ data->cmt = *i;
+ break;
+ }
+ }
+ if (i == mtlist.end()) {
+ printf("MidiTransformerDialog::presetChanged: not found\n");
+ return;
+ }
+ nameEntry->setText(data->cmt->name);
+ commentEntry->setText(data->cmt->comment);
+
+ selEventOp->setCurrentItem(data->cmt->selEventOp);
+ selEventOpSel(data->cmt->selEventOp);
+
+ for (unsigned i = 0; i < sizeof(eventTypeTable)/sizeof(*eventTypeTable); ++i) {
+ if (eventTypeTable[i] == data->cmt->selType) {
+ selType->setCurrentItem(i);
+ break;
+ }
+ }
+
+ selVal1Op->setCurrentItem(data->cmt->selVal1);
+ selVal1OpSel(data->cmt->selVal1);
+
+ selVal2Op->setCurrentItem(data->cmt->selVal2);
+ selVal2OpSel(data->cmt->selVal2);
+
+ selLenOp->setCurrentItem(data->cmt->selLen);
+ selLenOpSel(data->cmt->selLen);
+
+ selRangeOp->setCurrentItem(data->cmt->selRange);
+ selRangeOpSel(data->cmt->selRange);
+
+ funcOp->setCurrentItem(data->cmt->funcOp);
+ funcOpSel(data->cmt->funcOp);
+
+ // TransformOperator procEvent: Keep, Fix
+ procEventOp->setCurrentItem(data->cmt->procEvent == Fix);
+
+ procEventOpSel(data->cmt->procEvent);
+
+ procVal1Op->setCurrentItem(data->cmt->procVal1);
+ procVal1OpSel(data->cmt->procVal1);
+
+ for (unsigned i = 0; i < sizeof(procVal2Map)/sizeof(*procVal2Map); ++i) {
+ if (procVal2Map[i] == data->cmt->procVal2) {
+ procVal2Op->setCurrentItem(i);
+ break;
+ }
+ }
+ procLenOp->setCurrentItem(data->cmt->procLen);
+ procLenOpSel(data->cmt->procLen);
+
+ procPosOp->setCurrentItem(data->cmt->procPos);
+ procPosOpSel(data->cmt->procPos);
+
+ selVal1aChanged(data->cmt->selVal1a);
+ selVal1bChanged(data->cmt->selVal1b);
+ selVal2a->setValue(data->cmt->selVal2a);
+ selVal2b->setValue(data->cmt->selVal2b);
+ selLenA->setValue(data->cmt->selLenA);
+ selLenB->setValue(data->cmt->selLenB);
+ selBarA->setValue(data->cmt->selRangeA);
+ selBarB->setValue(data->cmt->selRangeB);
+ procVal1a->setValue(data->cmt->procVal1a);
+ procVal1b->setValue(data->cmt->procVal1b);
+ procVal2a->setValue(data->cmt->procVal2a);
+ procVal2b->setValue(data->cmt->procVal2b);
+ procLenA->setValue(data->cmt->procLenA);
+ procPosA->setValue(data->cmt->procPosA);
+ funcQuantVal->setValue(data->cmt->quantVal);
+
+ selectedTracks->setChecked(data->cmt->selectedTracks);
+ selectedTracksChanged(data->cmt->selectedTracks);
+ insideLoop->setChecked(data->cmt->insideLoop);
+ insideLoopChanged(data->cmt->insideLoop);
+ }
+
+//---------------------------------------------------------
+// nameChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::nameChanged(const QString& s)
+ {
+ data->cmt->name = s;
+ Q3ListBoxItem* item = presetList->item(data->cindex);
+ if (s != item->text()) {
+ disconnect(presetList, SIGNAL(highlighted(Q3ListBoxItem*)),
+ this, SLOT(presetChanged(Q3ListBoxItem*)));
+ presetList->changeItem(s, data->cindex);
+ connect(presetList, SIGNAL(highlighted(Q3ListBoxItem*)),
+ SLOT(presetChanged(Q3ListBoxItem*)));
+ }
+ }
+
+//---------------------------------------------------------
+// commentChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::commentChanged()
+ {
+ data->cmt->comment = commentEntry->text();
+ }
+
+//-----------------------------op----------------------------
+// selVal1aChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::selVal1aChanged(int val)
+ {
+ data->cmt->selVal1a = val;
+ if ((data->cmt->selEventOp != All)
+ && (data->cmt->selType == Note)) {
+ selVal1a->setSuffix(" - " + pitch2string(val));
+ }
+ else
+ selVal1a->setSuffix(QString(""));
+ }
+
+//---------------------------------------------------------
+// selVal1bChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::selVal1bChanged(int val)
+ {
+ data->cmt->selVal1b = val;
+ if ((data->cmt->selEventOp != All)
+ && (data->cmt->selType == Note)) {
+ selVal1b->setSuffix(" - " + pitch2string(val));
+ }
+ else
+ selVal1b->setSuffix(QString(""));
+ }
+
+//---------------------------------------------------------
+// selVal2aChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::selVal2aChanged(int val)
+ {
+ data->cmt->selVal2a = val;
+ }
+
+//---------------------------------------------------------
+// selVal2bChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::selVal2bChanged(int val)
+ {
+ data->cmt->selVal2b = val;
+ }
+
+//---------------------------------------------------------
+// selLenAChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::selLenAChanged(int val)
+ {
+ data->cmt->selLenA = val;
+ }
+
+//---------------------------------------------------------
+// selLenBChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::selLenBChanged(int val)
+ {
+ data->cmt->selLenB = val;
+ }
+
+//---------------------------------------------------------
+// selBarAChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::selBarAChanged(int val)
+ {
+ data->cmt->selRangeA = val;
+ }
+
+//---------------------------------------------------------
+// selBarBChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::selBarBChanged(int val)
+ {
+ data->cmt->selRangeB = val;
+ }
+
+//---------------------------------------------------------
+// procVal1aChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::procVal1aChanged(int val)
+ {
+ data->cmt->procVal1a = val;
+ }
+
+//---------------------------------------------------------
+// procVal1bChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::procVal1bChanged(int val)
+ {
+ data->cmt->procVal1b = val;
+ }
+
+//---------------------------------------------------------
+// procVal2aChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::procVal2aChanged(int val)
+ {
+ data->cmt->procVal2a = val;
+ }
+
+//---------------------------------------------------------
+// procVal2bChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::procVal2bChanged(int val)
+ {
+ data->cmt->procVal2b = val;
+ }
+
+//---------------------------------------------------------
+// procLenAChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::procLenAChanged(int val)
+ {
+ data->cmt->procLenA = val;
+ }
+
+//---------------------------------------------------------
+// procPosAChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::procPosAChanged(int val)
+ {
+ data->cmt->procPosA = val;
+ }
+
+//---------------------------------------------------------
+// funcQuantValSel
+//---------------------------------------------------------
+
+void MidiTransformerDialog::funcQuantValSel(int val)
+ {
+ data->cmt->quantVal = val;
+ }
+
+//---------------------------------------------------------
+// processAllChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::processAllChanged(bool val)
+ {
+ if (val == true) {
+ selectedTracks->setChecked(false);
+ insideLoop->setChecked(false);
+ data->cmt->selectedTracks = false;
+ data->cmt->insideLoop = false;
+ }
+ }
+
+//---------------------------------------------------------
+// selectedTracksChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::selectedTracksChanged(bool val)
+ {
+ data->cmt->selectedTracks = val;
+ processAll->setChecked(!val && !data->cmt->insideLoop);
+ }
+
+//---------------------------------------------------------
+// insideLoopChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::insideLoopChanged(bool val)
+ {
+ data->cmt->insideLoop = val;
+ processAll->setChecked(!data->cmt->selectedTracks && !val);
+ }
+
+
+
+/*!
+ \fn MidiTransformerDialog::typesMatch(MidiEvent e, unsigned t)
+ */
+bool MidiTransformerDialog::typesMatch(Event& e, unsigned selType)
+ {
+ bool matched = false;
+ switch (selType)
+ {
+ case MIDITRANSFORM_NOTE:
+ matched = (e.type() == Note);
+ break;
+ case MIDITRANSFORM_POLY:
+ matched = (e.type() == PAfter);
+ break;
+ case MIDITRANSFORM_CTRL:
+ matched = (e.type() == Controller);
+ break;
+ case MIDITRANSFORM_ATOUCH:
+ matched = (e.type() == CAfter);
+ break;
+ case MIDITRANSFORM_PITCHBEND:
+ {
+ if (e.type() == Controller) {
+ MidiController::ControllerType c = midiControllerType(e.dataA());
+ matched = (c == MidiController::Pitch);
+ }
+ break;
+ }
+ case MIDITRANSFORM_NRPN:
+ {
+ if (e.type() == Controller) {
+ MidiController::ControllerType c = midiControllerType(e.dataA());
+ matched = (c == MidiController::NRPN);
+ }
+ }
+ case MIDITRANSFORM_RPN:
+ {
+ if (e.type() == Controller) {
+ MidiController::ControllerType c = midiControllerType(e.dataA());
+ matched = (c == MidiController::RPN);
+ }
+ }
+ default:
+ fprintf(stderr, "Error matching type in MidiTransformerDialog: unknown eventtype!\n");
+ break;
+ }
+ //printf("Event type=%d, selType =%d matched=%d\n", e.type(), selType, matched);
+ return matched;
+ }