summaryrefslogtreecommitdiff
path: root/muse2
diff options
context:
space:
mode:
authorTim E. Real <termtech@rogers.com>2012-11-03 12:05:56 +0000
committerTim E. Real <termtech@rogers.com>2012-11-03 12:05:56 +0000
commit31f618e5461553bd7836677f944acfa233e5ae3c (patch)
tree9ce5c671ed1a089bb2cd19692db5a9c45951b237 /muse2
parentb45ce65ca39817a0678f2172410b71433f79f736 (diff)
Improved: Instrument Editor, fFixed MANY bugs. Should be SOLID now.
Improved: Midi controller graph 'Ctrl' popup menus. Improved: Aftertouch and PolyAftertouch (channel/key pressure) are true MusE controllers now. TODO: Still W.I.P. See ChangeLog
Diffstat (limited to 'muse2')
-rw-r--r--muse2/ChangeLog9
-rw-r--r--muse2/muse/app.cpp11
-rw-r--r--muse2/muse/app.h3
-rw-r--r--muse2/muse/ctrl/ctrlpanel.cpp149
-rw-r--r--muse2/muse/helper.cpp150
-rw-r--r--muse2/muse/icons.cpp4
-rw-r--r--muse2/muse/icons.h1
-rw-r--r--muse2/muse/importmidi.cpp2
-rw-r--r--muse2/muse/instruments/editinstrument.cpp939
-rw-r--r--muse2/muse/instruments/editinstrument.h15
-rw-r--r--muse2/muse/instruments/editinstrumentbase.ui1946
-rw-r--r--muse2/muse/liste/editctrlbase.ui124
-rw-r--r--muse2/muse/liste/editevent.cpp148
-rw-r--r--muse2/muse/midictrl.cpp55
-rw-r--r--muse2/muse/midictrl.h18
-rw-r--r--muse2/muse/mididev.cpp5
-rw-r--r--muse2/muse/midiedit/drumedit.cpp133
-rw-r--r--muse2/muse/midiedit/pianoroll.cpp133
-rw-r--r--muse2/muse/midiport.cpp4
-rw-r--r--muse2/muse/vst.cpp4
-rw-r--r--muse2/muse/vst.h4
-rw-r--r--muse2/muse/widgets/midi_audio_control.cpp8
-rw-r--r--muse2/muse/widgets/warn_bad_timing.ui2
-rw-r--r--muse2/share/instruments/Emu-4mbgsgmmt-sf.idf10
-rw-r--r--muse2/share/instruments/Roland-E28.idf10
-rw-r--r--muse2/share/instruments/Yamaha-CS1x.idf22
-rw-r--r--muse2/share/instruments/gs.idf12
-rw-r--r--muse2/share/instruments/xg.idf24
-rw-r--r--muse2/xpm/reddot.xpm36
29 files changed, 2214 insertions, 1767 deletions
diff --git a/muse2/ChangeLog b/muse2/ChangeLog
index 6bdb943a..ca69853c 100644
--- a/muse2/ChangeLog
+++ b/muse2/ChangeLog
@@ -1,3 +1,12 @@
+03.11.2012:
+ * Improved: Instrument Editor (controller tab): Redesigned. Fixed MANY bugs. Should be SOLID now. (Tim)
+ Two new columns: "Show in midi tracks" and "Show in drum tracks".
+ * Improved: Midi controller graph 'Ctrl' popup menus now unified (cascading). (Tim)
+ 'Edit Instrument' menu item now takes you right to the instrument and controllers tab.
+ * Improved: Aftertouch and PolyAftertouch (channel/key pressure) are true MusE controllers now.
+ Now FULLY supported in controller graphs AND in the improved Instrument Editor / Definition Files.
+ TODO: Still W.I.P. on Event List Editor, and recording these controllers, and other aftertouch places.
+ - Midi controller stuff: Fixed some bugs, added some methods and improvements.
28.10.2012:
* Improved: Eliminated copious unrequired "controller" sections from songs and templates. (Tim)
These controllers such as volume, pan are already always added, so it's useless to store them when "Off".
diff --git a/muse2/muse/app.cpp b/muse2/muse/app.cpp
index 296b4eff..0286fc2c 100644
--- a/muse2/muse/app.cpp
+++ b/muse2/muse/app.cpp
@@ -2725,21 +2725,26 @@ again:
// startEditInstrument
//---------------------------------------------------------
-void MusE::startEditInstrument()
+void MusE::startEditInstrument(const QString& find_instrument, EditInstrument::TabType show_tab)
{
if(editInstrument == 0)
{
editInstrument = new MusEGui::EditInstrument(this);
editInstrument->show();
+ editInstrument->findInstrument(find_instrument);
+ editInstrument->showTab(show_tab);
}
else
{
if(! editInstrument->isHidden())
editInstrument->hide();
- else
+ else
+ {
editInstrument->show();
+ editInstrument->findInstrument(find_instrument);
+ editInstrument->showTab(show_tab);
+ }
}
-
}
//---------------------------------------------------------
diff --git a/muse2/muse/app.h b/muse2/muse/app.h
index 4831e61d..bdeaadf4 100644
--- a/muse2/muse/app.h
+++ b/muse2/muse/app.h
@@ -26,6 +26,7 @@
#include "config.h"
#include "cobject.h"
+#include <editinstrument.h>
#include <QFileInfo>
#include <list>
@@ -336,7 +337,7 @@ class MusE : public QMainWindow
void showArranger(bool);
void importMidi(const QString &file);
void showDidYouKnowDialog();
- void startEditInstrument();
+ void startEditInstrument(const QString& find_instrument = QString(), EditInstrument::TabType show_tab = EditInstrument::Patches);
void configMidiPorts();
void startEditor(MusECore::PartList*, int);
diff --git a/muse2/muse/ctrl/ctrlpanel.cpp b/muse2/muse/ctrl/ctrlpanel.cpp
index 8e380356..b4d089ff 100644
--- a/muse2/muse/ctrl/ctrlpanel.cpp
+++ b/muse2/muse/ctrl/ctrlpanel.cpp
@@ -39,6 +39,7 @@
#include "globals.h"
#include "midictrl.h"
#include "instruments/minstrument.h"
+#include "editinstrument.h"
#include "midiport.h"
#include "mididev.h"
#include "xml.h"
@@ -184,7 +185,7 @@ void CtrlPanel::heartBeat()
int outport;
int chan;
int cdp = ctrlcanvas->getCurDrumPitch();
- if(_track->type() == MusECore::Track::DRUM && ((_ctrl->num() & 0xff) == 0xff) && cdp != -1)
+ if(_track->type() == MusECore::Track::DRUM && _ctrl->isPerNoteController() && cdp != -1)
{
outport = MusEGlobal::drumMap[cdp].port;
chan = MusEGlobal::drumMap[cdp].channel;
@@ -280,7 +281,7 @@ void CtrlPanel::labelDoubleClicked()
int outport;
int chan;
int cdp = ctrlcanvas->getCurDrumPitch();
- if(_track->type() == MusECore::Track::DRUM && ((_ctrl->num() & 0xff) == 0xff) && cdp != -1)
+ if(_track->type() == MusECore::Track::DRUM && _ctrl->isPerNoteController() && cdp != -1)
{
outport = MusEGlobal::drumMap[cdp].port;
chan = MusEGlobal::drumMap[cdp].channel;
@@ -385,7 +386,7 @@ void CtrlPanel::ctrlChanged(double val)
int outport;
int chan;
int cdp = ctrlcanvas->getCurDrumPitch();
- if(_track->type() == MusECore::Track::DRUM && ((_ctrl->num() & 0xff) == 0xff) && cdp != -1)
+ if(_track->type() == MusECore::Track::DRUM && _ctrl->isPerNoteController() && cdp != -1)
{
outport = MusEGlobal::drumMap[cdp].port;
chan = MusEGlobal::drumMap[cdp].channel;
@@ -460,13 +461,13 @@ void CtrlPanel::setHWController(MusECore::MidiTrack* t, MusECore::MidiController
int ch;
int cdp = ctrlcanvas->getCurDrumPitch();
_dnum = _ctrl->num();
- if(_track->type() == MusECore::Track::DRUM && ((_dnum & 0xff) == 0xff) && cdp != -1)
+ if(_track->type() == MusECore::Track::DRUM && _ctrl->isPerNoteController() && cdp != -1)
{
_dnum = (_dnum & ~0xff) | MusEGlobal::drumMap[cdp].anote;
mp = &MusEGlobal::midiPorts[MusEGlobal::drumMap[cdp].port];
ch = MusEGlobal::drumMap[cdp].channel;
}
- else if((_track->type() == MusECore::Track::NEW_DRUM || _track->type() == MusECore::Track::MIDI) && ((_dnum & 0xff) == 0xff) && cdp != -1)
+ else if((_track->type() == MusECore::Track::NEW_DRUM || _track->type() == MusECore::Track::MIDI) && _ctrl->isPerNoteController() && cdp != -1)
{
_dnum = (_dnum & ~0xff) | cdp; //FINDMICHJETZT does that work?
mp = &MusEGlobal::midiPorts[_track->outPort()];
@@ -617,142 +618,32 @@ void CtrlPanel::ctrlPopupTriggered(QAction* act)
MusECore::MidiTrack* track = (MusECore::MidiTrack*)(part->track());
int channel = track->outChannel();
MusECore::MidiPort* port = &MusEGlobal::midiPorts[track->outPort()];
- int curDrumPitch = ctrlcanvas->getCurDrumPitch();
- bool isDrum = track->type() == MusECore::Track::DRUM;
- bool isNewDrum = (track->type() == MusECore::Track::NEW_DRUM) || (track->type() == MusECore::Track::MIDI);
- MusECore::MidiInstrument* instr = port->instrument();
- MusECore::MidiControllerList* mcl = instr->controller();
-
MusECore::MidiCtrlValListList* cll = port->controller();
const int min = channel << 24;
const int max = min + 0x1000000;
-
- const int add_ins_def = max + 1;
- const int add_other = max + 2;
const int edit_ins = max + 3;
-
const int velo = max + 0x101;
-
int rv = act->data().toInt();
if (rv == velo) { // special case velocity
emit controllerChanged(MusECore::CTRL_VELOCITY);
}
- else if (rv == add_ins_def) { // add new instrument controller
-
- PopupMenu * ctrlSubPop = new PopupMenu(this, true); // true = enable stay open
- ctrlSubPop->addAction(new MenuTitleItem(tr("Instrument-defined"), ctrlSubPop));
-
- //
- // populate popup with all controllers available for
- // current instrument
- //
-
- for (MusECore::iMidiController ci = mcl->begin(); ci != mcl->end(); ++ci)
- {
- int num = ci->second->num();
- if((num & 0xff) == 0xff)
- {
- if (isDrum && curDrumPitch!=-1)
- num = (num & ~0xff) + MusEGlobal::drumMap[curDrumPitch].anote;
- else if (isNewDrum && curDrumPitch!=-1)
- num = (num & ~0xff) + curDrumPitch; //FINDMICH does this work?
- else // dont show drum specific controller if not a drum track
- continue;
- }
-
- if(cll->find(channel, num) == cll->end())
- ctrlSubPop->addAction(MusECore::midiCtrlNumString(num, true) + ci->second->name())->setData(num);
- }
-
- // Don't allow editing instrument if it's a synth
- if(!port->device() || port->device()->deviceType() != MusECore::MidiDevice::SYNTH_MIDI)
- ctrlSubPop->addAction(QIcon(*midi_edit_instrumentIcon), tr("Edit instrument ..."))->setData(edit_ins);
-
- QAction *act2 = ctrlSubPop->exec(selCtrl->mapToGlobal(QPoint(0,0)));
- if (act2)
- {
- int rv2 = act2->data().toInt();
-
- if (rv2 == edit_ins) // edit instrument
- MusEGlobal::muse->startEditInstrument();
- else // select new instrument control
- {
- MusECore::MidiController* c;
- for (MusECore::iMidiController ci = mcl->begin(); ci != mcl->end(); ++ci)
- {
- c = ci->second;
- int num = c->num();
- if (isDrum && ((num & 0xff) == 0xff) && curDrumPitch!=-1)
- num = (num & ~0xff) + MusEGlobal::drumMap[curDrumPitch].anote;
- else if (isNewDrum && ((num & 0xff) == 0xff) && curDrumPitch!=-1)
- num = (num & ~0xff) + curDrumPitch; //FINDMICHJETZT does this work?
-
- if(num != rv2)
- continue;
-
- if(cll->find(channel, num) == cll->end())
- {
- MusECore::MidiCtrlValList* vl = new MusECore::MidiCtrlValList(num);
-
- cll->add(channel, vl);
- emit controllerChanged(c->num());
- }
- else
- emit controllerChanged(c->num());
- break;
- }
- }
- }
- delete ctrlSubPop;
- }
-
- //else if (rv == edit_ins) // edit instrument
- // MusEGlobal::muse->startEditInstrument();
-
- else if (rv == add_other) { // add new other controller
- PopupMenu* ctrlSubPop = new PopupMenu(this, true); // true = enable stay open
- ctrlSubPop->addAction(new MenuTitleItem(tr("Common Controls"), ctrlSubPop));
-
- for(int num = 0; num < 127; ++num)
- if(cll->find(channel, num) == cll->end())
- ctrlSubPop->addAction(MusECore::midiCtrlName(num, true))->setData(num);
- QAction *act2 = ctrlSubPop->exec(selCtrl->mapToGlobal(QPoint(0,0)));
- if (act2) {
- int rv2 = act2->data().toInt();
- int num = rv2;
- if (isDrum && ((num & 0xff) == 0xff) && curDrumPitch!=-1)
- num = (num & ~0xff) + MusEGlobal::drumMap[curDrumPitch].anote;
- if (isNewDrum && ((num & 0xff) == 0xff) && curDrumPitch!=-1)
- num = (num & ~0xff) + curDrumPitch; //FINDMICHJETZT does this work?
-
- if(cll->find(channel, num) == cll->end())
- {
- MusECore::MidiCtrlValList* vl = new MusECore::MidiCtrlValList(num);
-
- cll->add(channel, vl);
- emit controllerChanged(rv2);
- }
- else
- emit controllerChanged(rv2);
- }
- delete ctrlSubPop;
+ else if (rv == edit_ins) { // edit instrument
+ MusECore::MidiInstrument* instr = port->instrument();
+ MusEGlobal::muse->startEditInstrument(instr ? instr->iname() : QString(), EditInstrument::Controllers);
}
else { // Select a control
- MusECore::iMidiCtrlValList i = cll->begin();
- for (; i != cll->end(); ++i) {
- MusECore::MidiCtrlValList* cl = i->second;
- MusECore::MidiController* c = port->midiController(cl->num());
- if (c->num() == rv) {
- emit controllerChanged(c->num());
- break;
- }
- }
- if (i == cll->end()) {
- printf("CtrlPanel: controller number %d not found!", rv);
- }
+ MusECore::iMidiCtrlValList i = cll->find(channel, rv);
+ if(i == cll->end())
+ {
+ MusECore::MidiCtrlValList* vl = new MusECore::MidiCtrlValList(rv);
+ cll->add(channel, vl);
}
-
+ int num = rv;
+ if(port->drumController(rv))
+ num |= 0xff;
+ emit controllerChanged(num);
+ }
}
//---------------------------------------------------------
@@ -766,7 +657,7 @@ void CtrlPanel::ctrlRightClicked(const QPoint& p, int /*id*/)
int cdp = ctrlcanvas->getCurDrumPitch();
int ctlnum = _ctrl->num();
- if(_track->type() == MusECore::Track::DRUM && ((ctlnum & 0xff) == 0xff) && cdp != -1)
+ if(_track->type() == MusECore::Track::DRUM && _ctrl->isPerNoteController() && cdp != -1)
//ctlnum = (ctlnum & ~0xff) | MusEGlobal::drumMap[cdp].enote; DELETETHIS or which of them is correct?
ctlnum = (ctlnum & ~0xff) | cdp;
diff --git a/muse2/muse/helper.cpp b/muse2/muse/helper.cpp
index e2186af9..1c4db8c7 100644
--- a/muse2/muse/helper.cpp
+++ b/muse2/muse/helper.cpp
@@ -888,43 +888,38 @@ int populateMidiCtrlMenu(PopupMenu* menu, MusECore::PartList* part_list, MusECor
int channel = track->outChannel();
MusECore::MidiPort* port = &MusEGlobal::midiPorts[track->outPort()];
bool isDrum = track->type() == MusECore::Track::DRUM;
- bool isNewDrum = (track->type() == MusECore::Track::NEW_DRUM) || (track->type() == MusECore::Track::MIDI);
+ bool isNewDrum = track->type() == MusECore::Track::NEW_DRUM;
+ bool isMidi = track->type() == MusECore::Track::MIDI;
MusECore::MidiInstrument* instr = port->instrument();
MusECore::MidiControllerList* mcl = instr->controller();
-
MusECore::MidiCtrlValListList* cll = port->controller();
const int min = channel << 24;
const int max = min + 0x1000000;
-
- const int add_ins_def = max + 1;
- const int add_other = max + 2;
-
+ const int edit_ins = max + 3;
const int velo = max + 0x101;
-// const int polyafter = max + 0x102;
-// const int after = max + 0x103;
-
int est_width = 0;
std::list<CI> sList;
typedef std::list<CI>::iterator isList;
+ std::set<int> already_added_nums;
for (MusECore::iMidiCtrlValList it = cll->lower_bound(min); it != cll->lower_bound(max); ++it) {
MusECore::MidiCtrlValList* cl = it->second;
MusECore::MidiController* c = port->midiController(cl->num());
- bool isDrumCtrl = ((c->num() & 0xff) == 0xff);
-
- // dont show drum specific controller if not a drum track
+ bool isDrumCtrl = (c->isPerNoteController());
+ int show = c->showInTracks();
+ int cnum = c->num();
+ int num = cl->num();
if (isDrumCtrl) {
+ // Only show controller for current pitch:
if (isDrum)
{
- // only show controller for curDrumPitch:
- if ((curDrumPitch == -1) || ((cl->num() & 0xff) != MusEGlobal::drumMap[curDrumPitch].anote))
+ if ((curDrumPitch == -1) || ((num & 0xff) != MusEGlobal::drumMap[curDrumPitch].anote))
continue;
}
- else if (isNewDrum)
+ else if (isNewDrum || isMidi)
{
- // only show controller for curDrumPitch: FINDMICH does this work?
- if ((curDrumPitch == -1) || ((cl->num() & 0xff) != curDrumPitch))
+ if ((curDrumPitch == -1) || ((num & 0xff) != curDrumPitch)) // FINDMICH does this work?
continue;
}
else
@@ -932,14 +927,11 @@ int populateMidiCtrlMenu(PopupMenu* menu, MusECore::PartList* part_list, MusECor
}
isList i = sList.begin();
for (; i != sList.end(); ++i) {
- //if (i->s == c->name())
- if (i->num == c->num())
+ if (i->num == num)
break;
}
- //printf("\n** c->num():%d cl->num:%d\n", c->num(), cl->num());
if (i == sList.end()) {
- bool off = cl->hwVal() == MusECore::CTRL_VAL_UNKNOWN; // Does it have a value or is it 'off'
bool used = false;
for (MusECore::iPart ip = part_list->begin(); ip != part_list->end(); ++ip) {
MusECore::EventList* el = ip->second->events();
@@ -947,21 +939,17 @@ int populateMidiCtrlMenu(PopupMenu* menu, MusECore::PartList* part_list, MusECor
MusECore::Event e = ie->second;
if(e.type() != MusECore::Controller)
continue;
- //e.dump();
int ctl_num = e.dataA();
- if(!isNewDrum)
+ // Is it a drum controller event, according to the track port's instrument?
+ MusECore::MidiController *mc = port->drumController(ctl_num);
+ if(mc)
{
- // Is it a drum controller event, according to the track port's instrument?
- MusECore::MidiController *mc = port->drumController(ctl_num);
- if(mc)
- {
- if((ctl_num & 0xff) != curDrumPitch)
- continue;
- // Change the controller event's index into the drum map to an instrument note.
+ if((ctl_num & 0xff) != curDrumPitch)
+ continue;
+ if(isDrum)
ctl_num = (ctl_num & ~0xff) | MusEGlobal::drumMap[ctl_num & 0x7f].anote;
- }
}
- if(ctl_num == cl->num())
+ if(ctl_num == num)
{
used = true;
break;
@@ -971,15 +959,21 @@ int populateMidiCtrlMenu(PopupMenu* menu, MusECore::PartList* part_list, MusECor
if (used)
break;
}
- bool isinstr = ( mcl->find(c->num()) != mcl->end() );
- int cnum = c->num();
+ bool off = cl->hwVal() == MusECore::CTRL_VAL_UNKNOWN; // Does it have a value or is it 'off'?
+ // Filter if not used and off. But if there's something there, we must show it.
+ if(!used && off &&
+ (((isDrumCtrl || isNewDrum) && !(show & MusECore::MidiController::ShowInDrum)) ||
+ (isMidi && !(show & MusECore::MidiController::ShowInMidi))))
+ continue;
+ bool isinstr = mcl->find(cnum) != mcl->end();
// Need to distinguish between global default controllers and
// instrument defined controllers. Instrument takes priority over global
// ie they 'overtake' definition of a global controller such that the
// global def is no longer available.
- sList.push_back(CI(cnum,
+ sList.push_back(CI(num,
isinstr ? MusECore::midiCtrlNumString(cnum, true) + c->name() : MusECore::midiCtrlName(cnum, true),
used, off, isinstr));
+ already_added_nums.insert(num);
}
}
@@ -987,19 +981,69 @@ int populateMidiCtrlMenu(PopupMenu* menu, MusECore::PartList* part_list, MusECor
int fmw = menu->fontMetrics().width(stext);
if(fmw > est_width)
est_width = fmw;
-
menu->addAction(new MenuTitleItem(stext, menu));
- // Add instrument-defined controllers.
- for (isList i = sList.begin(); i != sList.end(); ++i)
+ // Don't allow editing instrument if it's a synth
+ if(!port->device() || port->device()->deviceType() != MusECore::MidiDevice::SYNTH_MIDI)
+ {
+ stext = QWidget::tr("Edit instrument ...");
+ fmw = menu->fontMetrics().width(stext);
+ if(fmw > est_width)
+ est_width = fmw;
+ menu->addAction(QIcon(*midi_edit_instrumentIcon), QWidget::tr("Edit instrument ..."))->setData(edit_ins);
+ menu->addSeparator();
+ }
+
+ //
+ // populate popup with all controllers available for
+ // current instrument
+ //
+
+ stext = QWidget::tr("Add");
+ fmw = menu->fontMetrics().width(stext);
+ if(fmw > est_width)
+ est_width = fmw;
+ PopupMenu * ctrlSubPop = new PopupMenu(stext, menu, true); // true = enable stay open
+ for (MusECore::iMidiController ci = mcl->begin(); ci != mcl->end(); ++ci)
+ {
+ int show = ci->second->showInTracks();
+ if(((isDrum || isNewDrum) && !(show & MusECore::MidiController::ShowInDrum)) ||
+ (isMidi && !(show & MusECore::MidiController::ShowInMidi)))
+ continue;
+ int cnum = ci->second->num();
+ int num = cnum;
+ if(ci->second->isPerNoteController())
+ {
+ if (isDrum && curDrumPitch!=-1)
+ num = (cnum & ~0xff) | MusEGlobal::drumMap[curDrumPitch].anote;
+ else if ((isNewDrum || isMidi) && curDrumPitch!=-1)
+ num = (cnum & ~0xff) | curDrumPitch; //FINDMICH does this work?
+ else
+ continue;
+ }
+
+ // If it's not already in the parent menu...
+ if(cll->find(channel, num) == cll->end())
+ {
+ ctrlSubPop->addAction(MusECore::midiCtrlNumString(cnum, true) + ci->second->name())->setData(num);
+ already_added_nums.insert(num); //cnum);
+ }
+ }
+
+ menu->addMenu(ctrlSubPop);
+
+ menu->addSeparator();
+
+ // Add instrument-defined controllers:
+ for (isList i = sList.begin(); i != sList.end(); ++i)
{
if(!i->instrument)
continue;
-
+
fmw = menu->fontMetrics().width(i->s);
if(fmw > est_width)
est_width = fmw;
-
+
if (i->used && !i->off)
menu->addAction(QIcon(*orangedotIcon), i->s)->setData(i->num);
else if (i->used)
@@ -1010,20 +1054,28 @@ int populateMidiCtrlMenu(PopupMenu* menu, MusECore::PartList* part_list, MusECor
menu->addAction(i->s)->setData(i->num);
}
- stext = QWidget::tr("Add ...");
+ stext = QWidget::tr("Others");
fmw = menu->fontMetrics().width(stext);
if(fmw > est_width)
est_width = fmw;
- menu->addAction(QIcon(*configureIcon), stext)->setData(add_ins_def);
+ menu->addAction(new MenuTitleItem(stext, menu));
- menu->addSeparator();
-
- stext = QWidget::tr("Others");
+ // Add a.k.a. Common Controls not found in instrument:
+ stext = QWidget::tr("Common Controls");
fmw = menu->fontMetrics().width(stext);
if(fmw > est_width)
est_width = fmw;
- menu->addAction(new MenuTitleItem(stext, menu));
+ PopupMenu* ccSubPop = new PopupMenu(stext, menu, true); // true = enable stay open
+ for(int num = 0; num < 127; ++num)
+ // If it's not already in the parent menu...
+ if(already_added_nums.find(num) == already_added_nums.end())
+ ccSubPop->addAction(MusECore::midiCtrlName(num, true))->setData(num);
+
+ menu->addMenu(ccSubPop);
+
+ menu->addSeparator();
+ // Add the special case velocity:
stext = QWidget::tr("Velocity");
fmw = menu->fontMetrics().width(stext);
if(fmw > est_width)
@@ -1050,12 +1102,6 @@ int populateMidiCtrlMenu(PopupMenu* menu, MusECore::PartList* part_list, MusECor
menu->addAction(i->s)->setData(i->num);
}
- stext = QWidget::tr("Add ...");
- fmw = menu->fontMetrics().width(stext);
- if(fmw > est_width)
- est_width = fmw;
- menu->addAction(QIcon(*configureIcon), stext)->setData(add_other);
-
est_width += 60; // Add about 60 for the coloured lights on the left.
return est_width;
diff --git a/muse2/muse/icons.cpp b/muse2/muse/icons.cpp
index a3dfbf50..45aff5ee 100644
--- a/muse2/muse/icons.cpp
+++ b/muse2/muse/icons.cpp
@@ -186,6 +186,7 @@
#include "xpm/redled.xpm"
#include "xpm/darkredled.xpm"
#include "xpm/greendot.xpm"
+#include "xpm/reddot.xpm"
//#include "xpm/darkgreendot.xpm"
#include "xpm/bluedot.xpm"
#include "xpm/graydot.xpm"
@@ -428,6 +429,7 @@ QPixmap* toggle_small_Icon;
QPixmap* redLedIcon;
QPixmap* darkRedLedIcon;
QPixmap* greendotIcon;
+QPixmap* reddotIcon;
//QPixmap* darkgreendotIcon;
QPixmap* graydotIcon;
QPixmap* bluedotIcon;
@@ -653,6 +655,7 @@ void initIcons()
redLedIcon = new MPIXMAP(redled_xpm, NULL);
darkRedLedIcon = new MPIXMAP(darkredled_xpm, NULL);
greendotIcon = new MPIXMAP(greendot_xpm, NULL);
+ reddotIcon = new MPIXMAP(reddot_xpm, NULL);
//darkgreendotIcon = new MPIXMAP(darkgreendot_xpm, NULL);
bluedotIcon = new MPIXMAP(bluedot_xpm, NULL);
graydotIcon = new MPIXMAP(graydot_xpm, NULL);
@@ -894,6 +897,7 @@ void deleteIcons()
delete redLedIcon;
delete darkRedLedIcon;
delete greendotIcon;
+ delete reddotIcon;
//delete darkgreendotIcon;
delete bluedotIcon;
delete graydotIcon;
diff --git a/muse2/muse/icons.h b/muse2/muse/icons.h
index 36a780ae..04a8df26 100644
--- a/muse2/muse/icons.h
+++ b/muse2/muse/icons.h
@@ -167,6 +167,7 @@ extern QPixmap* toggle_small_Icon;
extern QPixmap* redLedIcon;
extern QPixmap* darkRedLedIcon;
extern QPixmap* greendotIcon;
+extern QPixmap* reddotIcon;
//extern QPixmap* darkgreendotIcon;
extern QPixmap* graydotIcon;
extern QPixmap* bluedotIcon;
diff --git a/muse2/muse/importmidi.cpp b/muse2/muse/importmidi.cpp
index 73f2e071..e22d865e 100644
--- a/muse2/muse/importmidi.cpp
+++ b/muse2/muse/importmidi.cpp
@@ -526,7 +526,7 @@ void MusE::importController(int channel, MusECore::MidiPort* mport, int n)
break;
}
// wildcard?
- if (((cn & 0xff) == 0xff) && ((cn & ~0xff) == (n & ~0xff))) {
+ if (mc->isPerNoteController() && ((cn & ~0xff) == (n & ~0xff))) {
ctrl = i->second;
break;
}
diff --git a/muse2/muse/instruments/editinstrument.cpp b/muse2/muse/instruments/editinstrument.cpp
index 57c466b8..3dc4488d 100644
--- a/muse2/muse/instruments/editinstrument.cpp
+++ b/muse2/muse/instruments/editinstrument.cpp
@@ -35,6 +35,7 @@
#include <QStringListModel>
#include <QScrollBar>
#include <QVariant>
+#include <QList>
#include <list>
#include "editinstrument.h"
@@ -45,7 +46,7 @@
#include "midictrl.h"
#include "gconfig.h"
#include "icons.h"
-
+#include "popupmenu.h"
#include "dlist.h"
#include "drummap.h"
#include "header.h"
@@ -59,7 +60,7 @@ namespace MusEGui {
enum {
COL_CNAME = 0, COL_TYPE,
- COL_HNUM, COL_LNUM, COL_MIN, COL_MAX, COL_DEF
+ COL_HNUM, COL_LNUM, COL_MIN, COL_MAX, COL_DEF, COL_SHOW_MIDI, COL_SHOW_DRUM
};
//---------------------------------------------------------
@@ -88,12 +89,6 @@ EditInstrument::EditInstrument(QWidget* parent, Qt::WFlags fl)
checkBoxXG->setVisible(false);
// populate instrument list
- // Populate common controller list.
- for(int i = 0; i < 128; ++i)
- {
- QListWidgetItem *lci = new QListWidgetItem(MusECore::midiCtrlName(i));
- listController->addItem(lci);
- }
oldMidiInstrument = 0;
oldPatchItem = 0;
for (MusECore::iMidiInstrument i = MusECore::midiInstruments.begin(); i != MusECore::midiInstruments.end(); ++i) {
@@ -132,6 +127,7 @@ EditInstrument::EditInstrument(QWidget* parent, Qt::WFlags fl)
dlist_header->hideSection(COL_MUTE);
dlist_header->hide();
+ ctrlValidLabel->setPixmap(*greendotIcon);
connect(patchFromBox, SIGNAL(valueChanged(int)), this, SLOT(patchCollectionSpinboxChanged(int)));
connect(patchToBox, SIGNAL(valueChanged(int)), this, SLOT(patchCollectionSpinboxChanged(int)));
@@ -193,17 +189,18 @@ EditInstrument::EditInstrument(QWidget* parent, Qt::WFlags fl)
connect(deleteController, SIGNAL(clicked()), SLOT(deleteControllerClicked()));
connect(newController, SIGNAL(clicked()), SLOT(newControllerClicked()));
connect(addController, SIGNAL(clicked()), SLOT(addControllerClicked()));
- connect(listController, SIGNAL(itemDoubleClicked(QListWidgetItem*)), SLOT(addControllerClicked()));
- connect(ctrlType,SIGNAL(activated(int)), SLOT(ctrlTypeChanged(int)));
+ connect(ctrlType,SIGNAL(activated(int)), SLOT(ctrlTypeChanged()));
connect(ctrlName, SIGNAL(returnPressed()), SLOT(ctrlNameReturn()));
connect(ctrlName, SIGNAL(lostFocus()), SLOT(ctrlNameReturn()));
- connect(spinBoxHCtrlNo, SIGNAL(valueChanged(int)), SLOT(ctrlHNumChanged(int)));
- connect(spinBoxLCtrlNo, SIGNAL(valueChanged(int)), SLOT(ctrlLNumChanged(int)));
+ connect(spinBoxHCtrlNo, SIGNAL(valueChanged(int)), SLOT(ctrlNumChanged()));
+ connect(spinBoxLCtrlNo, SIGNAL(valueChanged(int)), SLOT(ctrlNumChanged()));
connect(spinBoxMin, SIGNAL(valueChanged(int)), SLOT(ctrlMinChanged(int)));
connect(spinBoxMax, SIGNAL(valueChanged(int)), SLOT(ctrlMaxChanged(int)));
connect(spinBoxDefault, SIGNAL(valueChanged(int)), SLOT(ctrlDefaultChanged(int)));
connect(nullParamSpinBoxH, SIGNAL(valueChanged(int)), SLOT(ctrlNullParamHChanged(int)));
connect(nullParamSpinBoxL, SIGNAL(valueChanged(int)), SLOT(ctrlNullParamLChanged(int)));
+ connect(ctrlShowInMidi,SIGNAL(stateChanged(int)), SLOT(ctrlShowInMidiChanged(int)));
+ connect(ctrlShowInDrum,SIGNAL(stateChanged(int)), SLOT(ctrlShowInDrumChanged(int)));
connect(tabWidget3, SIGNAL(currentChanged(QWidget*)), SLOT(tabChanged(QWidget*)));
connect(sysexList, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),
@@ -212,7 +209,23 @@ EditInstrument::EditInstrument(QWidget* parent, Qt::WFlags fl)
connect(newSysex, SIGNAL(clicked()), SLOT(newSysexClicked()));
}
+void EditInstrument::findInstrument(const QString& find_instrument)
+{
+ if(find_instrument.isEmpty())
+ return;
+ QList<QListWidgetItem*> found = instrumentList->findItems(find_instrument, Qt::MatchExactly);
+ if(!found.isEmpty())
+ instrumentList->setCurrentItem(found.at(0));
+}
+
+void EditInstrument::showTab(TabType n)
+{
+ if(n >= tabWidget3->count())
+ return;
+ tabWidget3->setCurrentIndex(n);
+}
+
void EditInstrument::patchCollectionSpinboxChanged(int)
{
if (patchFromBox->value() > patchToBox->value())
@@ -1608,6 +1621,8 @@ QTreeWidgetItem* EditInstrument::addControllerToView(MusECore::MidiController* m
def.setNum(defval);
break;
case MusECore::MidiController::Pitch:
+ case MusECore::MidiController::PolyAftertouch:
+ case MusECore::MidiController::Aftertouch:
hnum = "---";
lnum = "---";
min.setNum(mctrl->minVal());
@@ -1634,7 +1649,17 @@ QTreeWidgetItem* EditInstrument::addControllerToView(MusECore::MidiController* m
break;
}
- QTreeWidgetItem* ci = new QTreeWidgetItem(viewController, QStringList() << mctrl->name() << int2ctrlType(t) << hnum << lnum << min << max << def);
+ QString show_midi, show_drum;
+ if(mctrl->showInTracks() & MusECore::MidiController::ShowInMidi)
+ show_midi = "X";
+ if(mctrl->showInTracks() & MusECore::MidiController::ShowInDrum)
+ show_drum = "X";
+ QTreeWidgetItem* ci = new QTreeWidgetItem(viewController,
+ QStringList() << mctrl->name() << int2ctrlType(t) << hnum << lnum << min << max << def << show_midi << show_drum);
+ ci->setTextAlignment(0, Qt::AlignLeft | Qt::AlignVCenter);
+ ci->setTextAlignment(1, Qt::AlignLeft | Qt::AlignVCenter);
+ for(int i = 2; i < 9; ++i)
+ ci->setTextAlignment(i, Qt::AlignRight | Qt::AlignVCenter);
QVariant v = qVariantFromValue((void*)(mctrl));
ci->setData(0, Qt::UserRole, v);
@@ -1665,7 +1690,7 @@ void EditInstrument::controllerChanged()
int ctrlH = (c->num() >> 8) & 0x7f;
int ctrlL = c->num() & 0x7f;
- if((c->num() & 0xff) == 0xff)
+ if(c->isPerNoteController())
ctrlL = -1;
MusECore::MidiController::ControllerType type = MusECore::midiControllerType(c->num());
@@ -1673,6 +1698,9 @@ void EditInstrument::controllerChanged()
ctrlType->blockSignals(true);
ctrlType->setCurrentIndex(type);
ctrlType->blockSignals(false);
+
+ ctrlShowInMidi->setChecked(c->showInTracks() & MusECore::MidiController::ShowInMidi);
+ ctrlShowInDrum->setChecked(c->showInTracks() & MusECore::MidiController::ShowInDrum);
spinBoxHCtrlNo->blockSignals(true);
spinBoxLCtrlNo->blockSignals(true);
@@ -1736,6 +1764,20 @@ void EditInstrument::controllerChanged()
spinBoxMax->setValue(c->maxVal());
enableDefaultControls(true, false);
break;
+ case MusECore::MidiController::PolyAftertouch:
+ case MusECore::MidiController::Aftertouch:
+ spinBoxHCtrlNo->setEnabled(false);
+ spinBoxLCtrlNo->setEnabled(false);
+ spinBoxHCtrlNo->setValue(0);
+ spinBoxLCtrlNo->setValue(0);
+ spinBoxMin->setEnabled(true);
+ spinBoxMax->setEnabled(true);
+ spinBoxMin->setRange(0, 127);
+ spinBoxMax->setRange(0, 127);
+ spinBoxMin->setValue(c->minVal());
+ spinBoxMax->setValue(c->maxVal());
+ enableDefaultControls(true, false);
+ break;
case MusECore::MidiController::Program:
spinBoxHCtrlNo->setEnabled(false);
spinBoxLCtrlNo->setEnabled(false);
@@ -1778,6 +1820,9 @@ void EditInstrument::controllerChanged()
spinBoxMin->blockSignals(false);
spinBoxMax->blockSignals(false);
spinBoxDefault->blockSignals(false);
+
+ ctrlValidLabel->setPixmap(*greendotIcon);
+ enableNonCtrlControls(true);
}
//---------------------------------------------------------
@@ -1794,9 +1839,6 @@ void EditInstrument::ctrlNameReturn()
QString cName = ctrlName->text();
- if(c->name() == cName)
- return;
-
MusECore::MidiControllerList* cl = workingInstrument.controller();
for(MusECore::ciMidiController ic = cl->begin(); ic != cl->end(); ++ic)
{
@@ -1818,6 +1860,9 @@ void EditInstrument::ctrlNameReturn()
}
}
+ if(c->name() == cName)
+ return;
+
c->setName(ctrlName->text());
item->setText(COL_CNAME, ctrlName->text());
workingInstrument.setDirty(true);
@@ -1827,172 +1872,286 @@ void EditInstrument::ctrlNameReturn()
// ctrlTypeChanged
//---------------------------------------------------------
-void EditInstrument::ctrlTypeChanged(int idx)
+void EditInstrument::ctrlTypeChanged()
{
QTreeWidgetItem* item = viewController->currentItem();
if (item == 0)
return;
- MusECore::MidiController::ControllerType t = (MusECore::MidiController::ControllerType)idx;
+ MusECore::MidiController::ControllerType t = MusECore::ctrlType2Int(ctrlType->currentText());
MusECore::MidiController* c = (MusECore::MidiController*)item->data(0, Qt::UserRole).value<void*>();
+ //if(t == MusECore::midiControllerType(c->num()))
+ // return;
+
+ // REMOVE Tim.
+ //if(c->showInTracks() & MusECore::MidiController::ShowInMidi)
+ // item->setText(COL_SHOW_MIDI, "Y");
+ //if(c->showInTracks() & MusECore::MidiController::ShowInDrum)
+ // item->setText(COL_SHOW_DRUM, "Y");
+
+ int hnum = 0, lnum = 0;
+
+// spinBoxMin->blockSignals(true);
+// spinBoxMax->blockSignals(true);
+// spinBoxDefault->blockSignals(true);
+//
+ switch (t) {
+ case MusECore::MidiController::Controller7:
+ spinBoxHCtrlNo->setEnabled(false);
+ spinBoxLCtrlNo->setEnabled(true);
+// spinBoxMin->setEnabled(true);
+// spinBoxMax->setEnabled(true);
+// enableDefaultControls(true, false);
+// spinBoxMin->setRange(-128, 127);
+// spinBoxMax->setRange(-128, 127);
+// spinBoxMin->setValue(0);
+// spinBoxMax->setValue(127);
+// spinBoxDefault->setRange(spinBoxMin->value() - 1, spinBoxMax->value());
+// spinBoxDefault->setValue(spinBoxDefault->minimum());
+ lnum = spinBoxLCtrlNo->value();
+ break;
+ case MusECore::MidiController::RPN:
+ case MusECore::MidiController::NRPN:
+ spinBoxHCtrlNo->setEnabled(true);
+ spinBoxLCtrlNo->setEnabled(true);
+// spinBoxMin->setEnabled(true);
+// spinBoxMax->setEnabled(true);
+// enableDefaultControls(true, false);
+// spinBoxMin->setRange(-128, 127);
+// spinBoxMax->setRange(-128, 127);
+// spinBoxMin->setValue(0);
+// spinBoxMax->setValue(127);
+// spinBoxDefault->setRange(spinBoxMin->value() - 1, spinBoxMax->value());
+// spinBoxDefault->setValue(spinBoxDefault->minimum());
+ hnum = spinBoxHCtrlNo->value();
+ lnum = spinBoxLCtrlNo->value();
+ break;
+ case MusECore::MidiController::Controller14:
+ case MusECore::MidiController::RPN14:
+ case MusECore::MidiController::NRPN14:
+ spinBoxHCtrlNo->setEnabled(true);
+ spinBoxLCtrlNo->setEnabled(true);
+// spinBoxMin->setEnabled(true);
+// spinBoxMax->setEnabled(true);
+// enableDefaultControls(true, false);
+// spinBoxMin->setRange(-16384, 16383);
+// spinBoxMax->setRange(-16384, 16383);
+// spinBoxMin->setValue(0);
+// spinBoxMax->setValue(16383);
+// spinBoxDefault->setRange(spinBoxMin->value() - 1, spinBoxMax->value());
+// spinBoxDefault->setValue(spinBoxDefault->minimum());
+ hnum = spinBoxHCtrlNo->value();
+ lnum = spinBoxLCtrlNo->value();
+ break;
+ case MusECore::MidiController::Pitch:
+ spinBoxHCtrlNo->setEnabled(false);
+ spinBoxLCtrlNo->setEnabled(false);
+// spinBoxMin->setEnabled(true);
+// spinBoxMax->setEnabled(true);
+// enableDefaultControls(true, false);
+// spinBoxMin->setRange(-8192, 8191);
+// spinBoxMax->setRange(-8192, 8191);
+// spinBoxMin->setValue(-8192);
+// spinBoxMax->setValue(8191);
+// spinBoxDefault->setRange(spinBoxMin->value() - 1, spinBoxMax->value());
+// spinBoxDefault->setValue(spinBoxDefault->minimum());
+ break;
+ case MusECore::MidiController::PolyAftertouch:
+ case MusECore::MidiController::Aftertouch:
+ spinBoxHCtrlNo->setEnabled(false);
+ spinBoxLCtrlNo->setEnabled(false);
+// spinBoxMin->setEnabled(true);
+// spinBoxMax->setEnabled(true);
+// enableDefaultControls(true, false);
+// spinBoxMin->setRange(0, 127);
+// spinBoxMax->setRange(0, 127);
+// spinBoxMin->setValue(0);
+// spinBoxMax->setValue(127);
+// spinBoxDefault->setRange(spinBoxMin->value() - 1, spinBoxMax->value());
+// spinBoxDefault->setValue(spinBoxDefault->minimum());
+ break;
+ case MusECore::MidiController::Program:
+ spinBoxHCtrlNo->setEnabled(false);
+ spinBoxLCtrlNo->setEnabled(false);
+// spinBoxMin->setEnabled(false);
+// spinBoxMax->setEnabled(false);
+// enableDefaultControls(false, true);
+// spinBoxMin->setRange(0, 0);
+// spinBoxMax->setRange(0, 0);
+// spinBoxMin->setValue(0);
+// spinBoxMax->setValue(0);
+// spinBoxDefault->setRange(0, 0);
+// spinBoxDefault->setValue(0);
+ break;
+ // Shouldn't happen...
+ default:
+ spinBoxHCtrlNo->setEnabled(false);
+ spinBoxLCtrlNo->setEnabled(false);
+ spinBoxMin->setEnabled(false);
+ spinBoxMax->setEnabled(false);
+ enableDefaultControls(false, false);
+ spinBoxMin->blockSignals(false);
+ spinBoxMax->blockSignals(false);
+ return;
+ break;
+ }
+
+// spinBoxMin->blockSignals(false);
+// spinBoxMax->blockSignals(false);
+// spinBoxDefault->blockSignals(false);
+//
+ int new_num = MusECore::MidiController::genNum(t, hnum, lnum);
+ MusECore::MidiControllerList* cl = workingInstrument.controller();
+ // Check if either a per-note controller, or else a regular controller already exists.
+ if(!cl->ctrlAvailable(new_num, c))
+ {
+ ctrlValidLabel->setPixmap(*reddotIcon);
+ enableNonCtrlControls(false);
+ return;
+ }
+
+ ctrlValidLabel->setPixmap(*greendotIcon);
+
if(t == MusECore::midiControllerType(c->num()))
+ {
+ enableNonCtrlControls(true);
return;
+ }
- item->setText(COL_TYPE, ctrlType->currentText());
+ cl->erase(c->num());
+ c->setNum(new_num);
+ cl->add(c);
- int hnum = 0, lnum = 0;
+ enableNonCtrlControls(true);
+ item->setText(COL_TYPE, ctrlType->currentText());
+
spinBoxMin->blockSignals(true);
spinBoxMax->blockSignals(true);
spinBoxDefault->blockSignals(true);
-
+
switch (t) {
case MusECore::MidiController::Controller7:
- spinBoxHCtrlNo->setEnabled(false);
- spinBoxLCtrlNo->setEnabled(true);
- spinBoxMin->setEnabled(true);
- spinBoxMax->setEnabled(true);
- enableDefaultControls(true, false);
+ //spinBoxMin->setEnabled(true);
+ //spinBoxMax->setEnabled(true);
+ //enableDefaultControls(true, false);
spinBoxMin->setRange(-128, 127);
spinBoxMax->setRange(-128, 127);
-
spinBoxMin->setValue(0);
spinBoxMax->setValue(127);
spinBoxDefault->setRange(spinBoxMin->value() - 1, spinBoxMax->value());
-
spinBoxDefault->setValue(spinBoxDefault->minimum());
- lnum = spinBoxLCtrlNo->value();
-
if(lnum == -1)
item->setText(COL_LNUM, QString("*"));
- else
+ else
item->setText(COL_LNUM, QString().setNum(lnum));
item->setText(COL_HNUM, QString("---"));
item->setText(COL_MIN, QString().setNum(spinBoxMin->value()));
item->setText(COL_MAX, QString().setNum(spinBoxMax->value()));
item->setText(COL_DEF, QString("---"));
break;
-
case MusECore::MidiController::RPN:
case MusECore::MidiController::NRPN:
- spinBoxHCtrlNo->setEnabled(true);
- spinBoxLCtrlNo->setEnabled(true);
- spinBoxMin->setEnabled(true);
- spinBoxMax->setEnabled(true);
- enableDefaultControls(true, false);
+ //spinBoxMin->setEnabled(true);
+ //spinBoxMax->setEnabled(true);
+ //enableDefaultControls(true, false);
spinBoxMin->setRange(-128, 127);
spinBoxMax->setRange(-128, 127);
-
spinBoxMin->setValue(0);
spinBoxMax->setValue(127);
spinBoxDefault->setRange(spinBoxMin->value() - 1, spinBoxMax->value());
spinBoxDefault->setValue(spinBoxDefault->minimum());
-
- hnum = spinBoxHCtrlNo->value();
- lnum = spinBoxLCtrlNo->value();
-
if(lnum == -1)
item->setText(COL_LNUM, QString("*"));
- else
+ else
item->setText(COL_LNUM, QString().setNum(lnum));
item->setText(COL_HNUM, QString().setNum(hnum));
item->setText(COL_MIN, QString().setNum(spinBoxMin->value()));
item->setText(COL_MAX, QString().setNum(spinBoxMax->value()));
item->setText(COL_DEF, QString("---"));
break;
-
case MusECore::MidiController::Controller14:
case MusECore::MidiController::RPN14:
case MusECore::MidiController::NRPN14:
- spinBoxHCtrlNo->setEnabled(true);
- spinBoxLCtrlNo->setEnabled(true);
- spinBoxMin->setEnabled(true);
- spinBoxMax->setEnabled(true);
- enableDefaultControls(true, false);
+ //spinBoxMin->setEnabled(true);
+ //spinBoxMax->setEnabled(true);
+ //enableDefaultControls(true, false);
spinBoxMin->setRange(-16384, 16383);
spinBoxMax->setRange(-16384, 16383);
-
spinBoxMin->setValue(0);
spinBoxMax->setValue(16383);
spinBoxDefault->setRange(spinBoxMin->value() - 1, spinBoxMax->value());
spinBoxDefault->setValue(spinBoxDefault->minimum());
-
- hnum = spinBoxHCtrlNo->value();
- lnum = spinBoxLCtrlNo->value();
if(lnum == -1)
item->setText(COL_LNUM, QString("*"));
- else
+ else
item->setText(COL_LNUM, QString().setNum(lnum));
item->setText(COL_HNUM, QString().setNum(hnum));
item->setText(COL_MIN, QString().setNum(spinBoxMin->value()));
item->setText(COL_MAX, QString().setNum(spinBoxMax->value()));
item->setText(COL_DEF, QString("---"));
break;
-
case MusECore::MidiController::Pitch:
- spinBoxHCtrlNo->setEnabled(false);
- spinBoxLCtrlNo->setEnabled(false);
- spinBoxMin->setEnabled(true);
- spinBoxMax->setEnabled(true);
- enableDefaultControls(true, false);
+ //spinBoxMin->setEnabled(true);
+ //spinBoxMax->setEnabled(true);
+ //enableDefaultControls(true, false);
spinBoxMin->setRange(-8192, 8191);
spinBoxMax->setRange(-8192, 8191);
-
spinBoxMin->setValue(-8192);
spinBoxMax->setValue(8191);
spinBoxDefault->setRange(spinBoxMin->value() - 1, spinBoxMax->value());
spinBoxDefault->setValue(spinBoxDefault->minimum());
-
- item->setText(COL_LNUM, QString("---"));
- item->setText(COL_HNUM, QString("---"));
- item->setText(COL_MIN, QString().setNum(spinBoxMin->value()));
- item->setText(COL_MAX, QString().setNum(spinBoxMax->value()));
- item->setText(COL_DEF, QString("---"));
+ item->setText(COL_LNUM, QString("---"));
+ item->setText(COL_HNUM, QString("---"));
+ item->setText(COL_MIN, QString().setNum(spinBoxMin->value()));
+ item->setText(COL_MAX, QString().setNum(spinBoxMax->value()));
+ item->setText(COL_DEF, QString("---"));
+ break;
+ case MusECore::MidiController::PolyAftertouch:
+ case MusECore::MidiController::Aftertouch:
+ //spinBoxMin->setEnabled(true);
+ //spinBoxMax->setEnabled(true);
+ //enableDefaultControls(true, false);
+ spinBoxMin->setRange(0, 127);
+ spinBoxMax->setRange(0, 127);
+ spinBoxMin->setValue(0);
+ spinBoxMax->setValue(127);
+ spinBoxDefault->setRange(spinBoxMin->value() - 1, spinBoxMax->value());
+ spinBoxDefault->setValue(spinBoxDefault->minimum());
+ item->setText(COL_LNUM, QString("---"));
+ item->setText(COL_HNUM, QString("---"));
+ item->setText(COL_MIN, QString().setNum(spinBoxMin->value()));
+ item->setText(COL_MAX, QString().setNum(spinBoxMax->value()));
+ item->setText(COL_DEF, QString("---"));
break;
-
case MusECore::MidiController::Program:
- spinBoxHCtrlNo->setEnabled(false);
- spinBoxLCtrlNo->setEnabled(false);
- spinBoxMin->setEnabled(false);
- spinBoxMax->setEnabled(false);
- enableDefaultControls(false, true);
+ //spinBoxMin->setEnabled(false);
+ //spinBoxMax->setEnabled(false);
+ //enableDefaultControls(false, true);
spinBoxMin->setRange(0, 0);
spinBoxMax->setRange(0, 0);
-
spinBoxMin->setValue(0);
spinBoxMax->setValue(0);
spinBoxDefault->setRange(0, 0);
spinBoxDefault->setValue(0);
-
- item->setText(COL_LNUM, QString("---"));
- item->setText(COL_HNUM, QString("---"));
- item->setText(COL_MIN, QString("---"));
- item->setText(COL_MAX, QString("---"));
- item->setText(COL_DEF, QString("---"));
+ item->setText(COL_LNUM, QString("---"));
+ item->setText(COL_HNUM, QString("---"));
+ item->setText(COL_MIN, QString("---"));
+ item->setText(COL_MAX, QString("---"));
+ item->setText(COL_DEF, QString("---"));
break;
-
// Shouldn't happen...
default:
- spinBoxHCtrlNo->setEnabled(false);
- spinBoxLCtrlNo->setEnabled(false);
- spinBoxMin->setEnabled(false);
- spinBoxMax->setEnabled(false);
- enableDefaultControls(false, false);
-
- spinBoxMin->blockSignals(false);
- spinBoxMax->blockSignals(false);
return;
-
break;
- }
-
+ }
+
spinBoxMin->blockSignals(false);
spinBoxMax->blockSignals(false);
spinBoxDefault->blockSignals(false);
-
- c->setNum(MusECore::MidiController::genNum(t, hnum, lnum));
-
+
+
setDefaultPatchControls(0xffffff);
if(t == MusECore::MidiController::Program)
{
@@ -2014,21 +2173,99 @@ void EditInstrument::ctrlTypeChanged(int idx)
}
//---------------------------------------------------------
+// ctrlShowInMidiChanged
+//---------------------------------------------------------
+
+void EditInstrument::ctrlShowInMidiChanged(int state)
+ {
+ QTreeWidgetItem* item = viewController->currentItem();
+ if (item == 0)
+ return;
+ MusECore::MidiController* c = (MusECore::MidiController*)item->data(0, Qt::UserRole).value<void*>();
+ int show = c->showInTracks();
+ if((show & MusECore::MidiController::ShowInMidi) == (state == Qt::Checked))
+ return;
+ if(state == Qt::Checked)
+ {
+ c->setShowInTracks(show | MusECore::MidiController::ShowInMidi);
+ item->setText(COL_SHOW_MIDI, "X");
+ }
+ else
+ {
+ c->setShowInTracks(show & ~MusECore::MidiController::ShowInMidi);
+ item->setText(COL_SHOW_MIDI, "");
+ }
+ workingInstrument.setDirty(true);
+ }
+
+//---------------------------------------------------------
+// ctrlShowInMidiChanged
+//---------------------------------------------------------
+
+void EditInstrument::ctrlShowInDrumChanged(int state)
+ {
+ QTreeWidgetItem* item = viewController->currentItem();
+ if (item == 0)
+ return;
+ MusECore::MidiController* c = (MusECore::MidiController*)item->data(0, Qt::UserRole).value<void*>();
+ int show = c->showInTracks();
+ if((show & MusECore::MidiController::ShowInDrum) == (state == Qt::Checked))
+ return;
+ if(state == Qt::Checked)
+ {
+ c->setShowInTracks(show | MusECore::MidiController::ShowInDrum);
+ item->setText(COL_SHOW_DRUM, "X");
+ }
+ else
+ {
+ c->setShowInTracks(show & ~MusECore::MidiController::ShowInDrum);
+ item->setText(COL_SHOW_DRUM, "");
+ }
+ workingInstrument.setDirty(true);
+ }
+
+// REMOVE Tim.
+/*
+//---------------------------------------------------------
// ctrlHNumChanged
//---------------------------------------------------------
void EditInstrument::ctrlHNumChanged(int val)
{
QTreeWidgetItem* item = viewController->currentItem();
-
if (item == 0)
return;
+ MusECore::MidiController* c = (MusECore::MidiController*)item->data(0, Qt::UserRole).value<void*>();
+ int n = spinBoxLCtrlNo->isEnabled() ? spinBoxLCtrlNo->value() & 0xff : c->num() & 0xff;
+ MusECore::MidiControllerList* cl = workingInstrument.controller();
+ MusECore::MidiController::ControllerType t = MusECore::ctrlType2Int(ctrlType->currentText());
+ int tn = MusECore::midiCtrlTerms2Number(t);
+ if((tn & 0xffff0000) == MusECore::CTRL_INTERNAL_OFFSET) // Error, should not happen.
+ return;
+ int new_num = tn | ((val & 0xff) << 8) | n;
+ // Check if either a per-note controller, or else a regular controller already exists.
+ if(!cl->ctrlAvailable(new_num, c))
+ {
+ ctrlValidLabel->setPixmap(*reddotIcon);
+ enableNonCtrlControls(false);
+ return;
+ }
+ ctrlValidLabel->setPixmap(*greendotIcon);
+ enableNonCtrlControls(true);
+ cl->erase(c->num());
+ c->setNum(new_num);
+ cl->add(c);
QString s;
+ if(c->isPerNoteController())
+ item->setText(COL_LNUM, QString("*"));
+ else
+ {
+ s.setNum(n);
+ item->setText(COL_LNUM, s);
+ }
s.setNum(val);
- MusECore::MidiController* c = (MusECore::MidiController*)item->data(0, Qt::UserRole).value<void*>();
- int n = c->num() & 0x7fff00ff;
- c->setNum(n | ((val & 0xff) << 8));
item->setText(COL_HNUM, s);
+ item->setText(COL_TYPE, ctrlType->currentText());
workingInstrument.setDirty(true);
}
@@ -2039,20 +2276,136 @@ void EditInstrument::ctrlHNumChanged(int val)
void EditInstrument::ctrlLNumChanged(int val)
{
QTreeWidgetItem* item = viewController->currentItem();
-
if (item == 0)
return;
MusECore::MidiController* c = (MusECore::MidiController*)item->data(0, Qt::UserRole).value<void*>();
- int n = c->num() & ~0xff;
- c->setNum(n | (val & 0xff));
- if(val == -1)
+ int n = spinBoxHCtrlNo->isEnabled() ? (spinBoxHCtrlNo->value() & 0x7f) << 8 : c->num() & 0x7f00;
+ MusECore::MidiControllerList* cl = workingInstrument.controller();
+ MusECore::MidiController::ControllerType t = MusECore::ctrlType2Int(ctrlType->currentText());
+ int tn = MusECore::midiCtrlTerms2Number(t);
+ if((tn & 0xffff0000) == MusECore::CTRL_INTERNAL_OFFSET) // Error, should not happen.
+ return;
+ int new_num = tn | n | (val & 0xff);
+ // Check if either a per-note controller, or else a regular controller already exists.
+ if(!cl->ctrlAvailable(new_num, c))
+ {
+ ctrlValidLabel->setPixmap(*reddotIcon);
+ enableNonCtrlControls(false);
+ return;
+ }
+ ctrlValidLabel->setPixmap(*greendotIcon);
+ enableNonCtrlControls(true);
+ cl->erase(c->num());
+ c->setNum(new_num);
+ cl->add(c);
+ QString s;
+ if(c->isPerNoteController())
item->setText(COL_LNUM, QString("*"));
else
{
- QString s;
s.setNum(val);
item->setText(COL_LNUM, s);
- }
+ }
+ if(t == MusECore::MidiController::Controller7)
+ item->setText(COL_HNUM, "---");
+ else
+ {
+ s.setNum(n >> 8);
+ item->setText(COL_HNUM, s);
+ }
+ item->setText(COL_TYPE, ctrlType->currentText());
+ workingInstrument.setDirty(true);
+ }
+*/
+
+//---------------------------------------------------------
+// ctrlNumChanged
+//---------------------------------------------------------
+
+void EditInstrument::ctrlNumChanged()
+ {
+ QTreeWidgetItem* item = viewController->currentItem();
+ if (item == 0)
+ return;
+ MusECore::MidiController::ControllerType t = MusECore::ctrlType2Int(ctrlType->currentText());
+ int hnum = 0, lnum = 0;
+ switch (t) {
+ case MusECore::MidiController::Controller7:
+ lnum = spinBoxLCtrlNo->value();
+ break;
+ case MusECore::MidiController::Controller14:
+ case MusECore::MidiController::RPN:
+ case MusECore::MidiController::NRPN:
+ case MusECore::MidiController::RPN14:
+ case MusECore::MidiController::NRPN14:
+ hnum = spinBoxHCtrlNo->value();
+ lnum = spinBoxLCtrlNo->value();
+ break;
+ // Should not happen...
+ case MusECore::MidiController::Pitch:
+ case MusECore::MidiController::PolyAftertouch:
+ case MusECore::MidiController::Aftertouch:
+ case MusECore::MidiController::Program:
+ case MusECore::MidiController::Velo:
+ return;
+ default:
+ printf("EditInstrument::ctrlNumChanged Error: Unknown control type\n");
+ return;
+ break;
+ }
+
+ int new_num = MusECore::MidiController::genNum(t, hnum, lnum);
+ if(new_num == -1)
+ {
+ printf("EditInstrument::ctrlNumChanged Error: genNum returned -1\n");
+ return;
+ }
+
+
+ //int n = spinBoxLCtrlNo->isEnabled() ? spinBoxLCtrlNo->value() & 0xff : c->num() & 0xff;
+ MusECore::MidiControllerList* cl = workingInstrument.controller();
+ MusECore::MidiController* c = (MusECore::MidiController*)item->data(0, Qt::UserRole).value<void*>();
+
+ //int tn = MusECore::midiCtrlTerms2Number(t);
+ //if((tn & 0xffff0000) == MusECore::CTRL_INTERNAL_OFFSET) // Error, should not happen.
+ // return;
+ //int new_num = tn | ((val & 0xff) << 8) | n;
+ // Check if either a per-note controller, or else a regular controller already exists.
+ if(!cl->ctrlAvailable(new_num, c))
+ {
+ ctrlValidLabel->setPixmap(*reddotIcon);
+ enableNonCtrlControls(false);
+ return;
+ }
+ ctrlValidLabel->setPixmap(*greendotIcon);
+ enableNonCtrlControls(true);
+ if(cl->erase(c->num()) == 0)
+ printf("EditInstrument::ctrlNumChanged Warning: Erase failed! Proceeding anyway.\n");
+ c->setNum(new_num);
+ cl->add(c);
+ QString s;
+ if(c->isPerNoteController())
+ item->setText(COL_LNUM, QString("*"));
+ else {
+ s.setNum(lnum);
+ item->setText(COL_LNUM, s);
+ }
+ switch (t) {
+ case MusECore::MidiController::Controller7:
+ item->setText(COL_HNUM, "---");
+ break;
+ case MusECore::MidiController::Controller14:
+ case MusECore::MidiController::RPN:
+ case MusECore::MidiController::NRPN:
+ case MusECore::MidiController::RPN14:
+ case MusECore::MidiController::NRPN14:
+ s.setNum(hnum);
+ item->setText(COL_HNUM, s);
+ break;
+ default:
+ return;
+ }
+ item->setText(COL_TYPE, ctrlType->currentText());
workingInstrument.setDirty(true);
}
@@ -2080,6 +2433,8 @@ void EditInstrument::ctrlMinChanged(int val)
case MusECore::MidiController::Controller7:
case MusECore::MidiController::RPN:
case MusECore::MidiController::NRPN:
+ case MusECore::MidiController::PolyAftertouch:
+ case MusECore::MidiController::Aftertouch:
rng = 127;
break;
case MusECore::MidiController::Controller14:
@@ -2164,6 +2519,8 @@ void EditInstrument::ctrlMaxChanged(int val)
case MusECore::MidiController::Controller7:
case MusECore::MidiController::RPN:
case MusECore::MidiController::NRPN:
+ case MusECore::MidiController::PolyAftertouch:
+ case MusECore::MidiController::Aftertouch:
rng = 127;
break;
case MusECore::MidiController::Controller14:
@@ -2788,56 +3145,112 @@ void EditInstrument::newControllerClicked()
ctrl->setInitVal(MusECore::CTRL_VAL_UNKNOWN);
QTreeWidgetItem* ci = viewController->currentItem();
-
+
+ int l = 0;
+ int h = 0;
+ int hmax = 0x100;
// To allow for quick multiple successive controller creation.
// If there's a current controller item selected, copy initial values from it.
- bool found = false;
if(ci)
{
MusECore::MidiController* selctl = (MusECore::MidiController*)ci->data(0, Qt::UserRole).value<void*>();
-
- // Auto increment controller number.
- int l = selctl->num() & 0x7f;
- int h = selctl->num() & 0xffffff00;
-
// Ignore internal controllers and wild cards.
- if(((h & 0xff0000) != 0x40000) && ((selctl->num() & 0xff) != 0xff))
+ if(((selctl->num() & 0xff0000) != MusECore::CTRL_INTERNAL_OFFSET) && !selctl->isPerNoteController())
{
- // Assign.
- *ctrl = *selctl;
-
- for (int i = 1; i < 128; ++i)
+ switch(MusECore::midiControllerType(selctl->num()))
{
- int j = ((i + l) & 0x7f) | h;
+ case MusECore::MidiController::Controller7:
+ // Auto increment controller number.
+ l = selctl->num() & 0x7f;
+ *ctrl = *selctl; // Assign.
+ break;
+ case MusECore::MidiController::Controller14:
+ case MusECore::MidiController::RPN:
+ case MusECore::MidiController::NRPN:
+ case MusECore::MidiController::RPN14:
+ case MusECore::MidiController::NRPN14:
+ // Auto increment controller number.
+ l = selctl->num() & 0x7f;
+ h = selctl->num() & 0xffffff00;
+ *ctrl = *selctl; // Assign.
+ break;
+ // Don't duplicate these types.
+ case MusECore::MidiController::Pitch:
+ case MusECore::MidiController::Program:
+ case MusECore::MidiController::PolyAftertouch:
+ case MusECore::MidiController::Aftertouch:
+ case MusECore::MidiController::Velo:
+ break;
+ default:
+ printf("error: newControllerClicked: Unknown control type!\n");
+ delete ctrl;
+ return;
+ }
+ }
+ }
+
+ bool found = false;
+ for(int k = (h & 0xffff0000); k < MusECore::CTRL_NONE_OFFSET; k += 0x10000)
+ {
+ // Don't copy internal controllers.
+ if(k == MusECore::CTRL_INTERNAL_OFFSET)
+ {
+ found = true;
+ continue;
+ }
+ if(k == 0)
+ // We're currently within the Controller7 group, limit the hi-number loop to one go (j = 0).
+ hmax = 0x100;
+ else
+ // All other relevant controllers use hi and lo numbers.
+ hmax = 0x10000;
+ for(int j = 0; j < hmax; j += 0x100)
+ {
+ for(int i = 0; i < 128; ++i)
+ {
+ int num = ((i + l) & 0x7f) | ((h + j) & 0x7f00) | k;
found = false;
- for (MusECore::iMidiController ic = cl->begin(); ic != cl->end(); ++ic)
+ // First check if there's already a per-note controller for this control number.
+ if(cl->find(num | 0xff) != cl->end())
{
- MusECore::MidiController* c = ic->second;
- if(c->num() == j)
- {
- found = true;
- break;
- }
+ found = true;
+ break; // Next outer loop (hi-number) iteration...
}
- if(!found)
+ // Now check if the actual control number is NOT already taken.
+ if(cl->find(num) == cl->end())
{
- ctrl->setNum(j);
+ ctrl->setNum(num);
break;
- }
- }
+ }
+ // Actual number was also taken. Keep iterating lo-number...
+ found = true;
+ }
+ if(!found)
+ break;
}
- }
+ if(!found)
+ break;
+ }
+
+ if(found)
+ {
+ QMessageBox::critical(this, tr("New controller: Error"), tr("Error! All control numbers are taken up!\nClean up the instrument!"));
+ delete ctrl;
+ return;
+ }
ctrl->setName(cName);
workingInstrument.controller()->add(ctrl);
QTreeWidgetItem* item = addControllerToView(ctrl);
-
- viewController->blockSignals(true);
- item->setSelected(true);
- viewController->blockSignals(false);
-
- controllerChanged();
+
+ if(viewController->currentItem() != item)
+ {
+ viewController->blockSignals(true);
+ viewController->setCurrentItem(item);
+ viewController->blockSignals(false);
+ controllerChanged();
+ }
workingInstrument.setDirty(true);
}
@@ -2848,75 +3261,132 @@ void EditInstrument::newControllerClicked()
void EditInstrument::addControllerClicked()
{
- QListWidgetItem* idx = listController->currentItem();
- if(idx == 0)
- return;
-
- int lnum = -1;
- QString name = listController->currentItem()->text();
- for(int i = 0; i < 128; i++)
- {
- if(MusECore::midiCtrlName(i) == name)
- {
- lnum = i;
- break;
- }
- }
- if(lnum == -1)
+ // Add Common Controls not already found in instrument:
+ PopupMenu* pup = new PopupMenu(true); // true = enable stay open. Don't bother with parent.
+ MusECore::MidiControllerList* cl = workingInstrument.controller();
+ for(int num = 0; num < 127; ++num)
{
- printf("Add controller: Controller not found: %s\n", name.toLatin1().constData());
- return;
+ // If it's not already in the parent menu...
+ if(cl->find(num) == cl->end())
+ pup->addAction(MusECore::midiCtrlName(num, true))->setData(num);
}
- int num = MusECore::MidiController::genNum(MusECore::MidiController::Controller7, 0, lnum);
-
+ connect(pup, SIGNAL(triggered(QAction*)), SLOT(ctrlPopupTriggered(QAction*)));
+ pup->exec(mapToGlobal(QPoint(0,0)));
+ delete pup;
+
+
+
+
+
+
+// REMOVE Tim.
+// QListWidgetItem* idx = listController->currentItem();
+// if(idx == 0)
+// return;
+
+// int lnum = -1;
+// QString name = listController->currentItem()->text();
+// for(int i = 0; i < 128; i++)
+// {
+// if(MusECore::midiCtrlName(i) == name)
+// {
+// lnum = i;
+// break;
+// }
+// }
+
+// if(lnum == -1)
+// {
+// printf("Add controller: Controller not found: %s\n", name.toLatin1().constData());
+// return;
+// }
+//
+// int num = MusECore::MidiController::genNum(MusECore::MidiController::Controller7, 0, lnum);
+//
+// MusECore::MidiControllerList* cl = workingInstrument.controller();
+// for(MusECore::iMidiController ic = cl->begin(); ic != cl->end(); ++ic)
+// {
+// MusECore::MidiController* c = ic->second;
+// if(c->name() == name)
+// {
+// QMessageBox::critical(this,
+// tr("MusE: Cannot add common controller"),
+// tr("A controller named '%1' already exists.").arg(name),
+// QMessageBox::Ok,
+// Qt::NoButton,
+// Qt::NoButton);
+//
+// return;
+// }
+//
+// if(c->num() == num)
+// {
+// QMessageBox::critical(this,
+// tr("MusE: Cannot add common controller"),
+// tr("A controller number %1 already exists.").arg(num),
+// QMessageBox::Ok,
+// Qt::NoButton,
+// Qt::NoButton);
+//
+// return;
+// }
+// }
+//
+// MusECore::MidiController* ctrl = new MusECore::MidiController();
+// ctrl->setNum(num);
+// ctrl->setMinVal(0);
+// ctrl->setMaxVal(127);
+// ctrl->setInitVal(MusECore::CTRL_VAL_UNKNOWN);
+// ctrl->setName(name);
+//
+// workingInstrument.controller()->add(ctrl);
+//
+// QTreeWidgetItem* item = addControllerToView(ctrl);
+//
+// viewController->blockSignals(true);
+// item->setSelected(true);
+// viewController->blockSignals(false);
+//
+// controllerChanged();
+//
+// workingInstrument.setDirty(true);
+}
+
+//---------------------------------------------------------
+// ctrlPopupTriggered
+//---------------------------------------------------------
+
+void EditInstrument::ctrlPopupTriggered(QAction* act)
+{
+ if(!act || (act->data().toInt() == -1))
+ return;
+ int rv = act->data().toInt();
MusECore::MidiControllerList* cl = workingInstrument.controller();
- for(MusECore::iMidiController ic = cl->begin(); ic != cl->end(); ++ic)
+ if(cl->find(rv) == cl->end())
{
- MusECore::MidiController* c = ic->second;
- if(c->name() == name)
- {
- QMessageBox::critical(this,
- tr("MusE: Cannot add common controller"),
- tr("A controller named '%1' already exists.").arg(name),
- QMessageBox::Ok,
- Qt::NoButton,
- Qt::NoButton);
-
- return;
- }
+ int num = rv; // = MusECore::MidiController::genNum(MusECore::MidiController::Controller7, 0, rv);
+ MusECore::MidiController* ctrl = new MusECore::MidiController();
+ ctrl->setNum(num);
+ ctrl->setMinVal(0);
+ ctrl->setMaxVal(127);
+ ctrl->setInitVal(MusECore::CTRL_VAL_UNKNOWN);
+ ctrl->setName(MusECore::midiCtrlName(num, false));
- if(c->num() == num)
+ workingInstrument.controller()->add(ctrl);
+
+ QTreeWidgetItem* item = addControllerToView(ctrl);
+
+ if(viewController->currentItem() != item)
{
- QMessageBox::critical(this,
- tr("MusE: Cannot add common controller"),
- tr("A controller number %1 already exists.").arg(num),
- QMessageBox::Ok,
- Qt::NoButton,
- Qt::NoButton);
-
- return;
+ viewController->blockSignals(true);
+ viewController->setCurrentItem(item);
+ viewController->blockSignals(false);
+ controllerChanged();
}
+
+ workingInstrument.setDirty(true);
}
-
- MusECore::MidiController* ctrl = new MusECore::MidiController();
- ctrl->setNum(num);
- ctrl->setMinVal(0);
- ctrl->setMaxVal(127);
- ctrl->setInitVal(MusECore::CTRL_VAL_UNKNOWN);
- ctrl->setName(name);
-
- workingInstrument.controller()->add(ctrl);
-
- QTreeWidgetItem* item = addControllerToView(ctrl);
-
- viewController->blockSignals(true);
- item->setSelected(true);
- viewController->blockSignals(false);
-
- controllerChanged();
-
- workingInstrument.setDirty(true);
}
//---------------------------------------------------------
@@ -3105,6 +3575,81 @@ void EditInstrument::enableDefaultControls(bool enVal, bool enPatch)
}
//---------------------------------------------------------
+// enableNonCtrlControls
+//---------------------------------------------------------
+
+void EditInstrument::enableNonCtrlControls(bool v)
+{
+ QTreeWidgetItem* sel = viewController->selectedItems().size() ? viewController->selectedItems()[0] : 0;
+
+ if(!sel || !sel->data(0, Qt::UserRole).value<void*>())
+ return;
+ MusECore::MidiController* c = (MusECore::MidiController*)sel->data(0, Qt::UserRole).value<void*>();
+ MusECore::MidiController::ControllerType type = MusECore::midiControllerType(c->num());
+
+ if(v)
+ {
+ switch (type) {
+ case MusECore::MidiController::Controller7:
+ spinBoxMin->setEnabled(true);
+ spinBoxMax->setEnabled(true);
+ enableDefaultControls(true, false);
+ break;
+ case MusECore::MidiController::RPN:
+ case MusECore::MidiController::NRPN:
+ spinBoxMin->setEnabled(true);
+ spinBoxMax->setEnabled(true);
+ enableDefaultControls(true, false);
+ break;
+ case MusECore::MidiController::Controller14:
+ case MusECore::MidiController::RPN14:
+ case MusECore::MidiController::NRPN14:
+ spinBoxMin->setEnabled(true);
+ spinBoxMax->setEnabled(true);
+ enableDefaultControls(true, false);
+ break;
+ case MusECore::MidiController::Pitch:
+ spinBoxMin->setEnabled(true);
+ spinBoxMax->setEnabled(true);
+ enableDefaultControls(true, false);
+ break;
+ case MusECore::MidiController::PolyAftertouch:
+ case MusECore::MidiController::Aftertouch:
+ spinBoxMin->setEnabled(true);
+ spinBoxMax->setEnabled(true);
+ enableDefaultControls(true, false);
+ break;
+ case MusECore::MidiController::Program:
+ spinBoxMin->setEnabled(false);
+ spinBoxMax->setEnabled(false);
+ enableDefaultControls(false, true);
+ break;
+ default:
+ spinBoxMin->setEnabled(false);
+ spinBoxMax->setEnabled(false);
+ enableDefaultControls(false, false);
+ break;
+ }
+ }
+ else
+ {
+ spinBoxDefault->setEnabled(false);
+ patchButton->setEnabled(false);
+ defPatchH->setEnabled(false);
+ defPatchL->setEnabled(false);
+ defPatchProg->setEnabled(false);
+
+ spinBoxMin->setEnabled(false);
+ spinBoxMax->setEnabled(false);
+ }
+
+ ctrlShowInMidi->setEnabled(v);
+ ctrlShowInDrum->setEnabled(v);
+
+ ctrlName->setEnabled(v);
+}
+
+//---------------------------------------------------------
// setDefaultPatchName
//---------------------------------------------------------
diff --git a/muse2/muse/instruments/editinstrument.h b/muse2/muse/instruments/editinstrument.h
index 90745301..ac4da064 100644
--- a/muse2/muse/instruments/editinstrument.h
+++ b/muse2/muse/instruments/editinstrument.h
@@ -33,6 +33,8 @@ class QMenu;
class QCloseEvent;
class QGridLayout;
class QStringListModel;
+class QString;
+class QAction;
namespace MusEGui {
@@ -70,6 +72,7 @@ class EditInstrument : public QMainWindow, public Ui::EditInstrumentBase {
QTreeWidgetItem* addControllerToView(MusECore::MidiController* mctrl);
QString getPatchItemText(int);
void enableDefaultControls(bool, bool);
+ void enableNonCtrlControls(bool);
void setDefaultPatchName(int);
int getDefaultPatchNumber();
void setDefaultPatchNumbers(int);
@@ -98,13 +101,15 @@ class EditInstrument : public QMainWindow, public Ui::EditInstrumentBase {
void deleteControllerClicked();
void newControllerClicked();
void addControllerClicked();
- void ctrlTypeChanged(int);
+ void ctrlPopupTriggered(QAction*);
+ void ctrlTypeChanged();
void ctrlNameReturn();
- void ctrlHNumChanged(int);
- void ctrlLNumChanged(int);
+ void ctrlNumChanged();
void ctrlMinChanged(int);
void ctrlMaxChanged(int);
void ctrlDefaultChanged(int);
+ void ctrlShowInMidiChanged(int);
+ void ctrlShowInDrumChanged(int);
void sysexChanged(QListWidgetItem*, QListWidgetItem*);
void deleteSysexClicked();
void newSysexClicked();
@@ -124,7 +129,11 @@ class EditInstrument : public QMainWindow, public Ui::EditInstrumentBase {
void fetchPatchCollection();
public:
+ enum TabType { Patches=0, DrumMaps=1, Controllers=2, Sysex=3 };
+
EditInstrument(QWidget* parent = 0, Qt::WFlags fl = Qt::Window);
+ void findInstrument(const QString& find_instrument);
+ void showTab(TabType);
};
} // namespace MusEGui
diff --git a/muse2/muse/instruments/editinstrumentbase.ui b/muse2/muse/instruments/editinstrumentbase.ui
index e1f935d5..8e3e7db0 100644
--- a/muse2/muse/instruments/editinstrumentbase.ui
+++ b/muse2/muse/instruments/editinstrumentbase.ui
@@ -6,14 +6,14 @@
<rect>
<x>0</x>
<y>0</y>
- <width>802</width>
- <height>505</height>
+ <width>772</width>
+ <height>421</height>
</rect>
</property>
<property name="minimumSize">
<size>
- <width>802</width>
- <height>464</height>
+ <width>0</width>
+ <height>0</height>
</size>
</property>
<property name="windowTitle">
@@ -25,8 +25,8 @@
<widget class="QSplitter" name="splitter4">
<property name="minimumSize">
<size>
- <width>780</width>
- <height>365</height>
+ <width>0</width>
+ <height>0</height>
</size>
</property>
<property name="orientation">
@@ -346,6 +346,19 @@
</property>
</widget>
</item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
</layout>
</item>
</layout>
@@ -444,945 +457,9 @@
</item>
</layout>
</widget>
- <widget class="QWidget" name="controllerTab">
- <attribute name="title">
- <string>Contro&amp;ller</string>
- </attribute>
- <layout class="QVBoxLayout">
- <item>
- <widget class="QSplitter" name="splitter6">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <widget class="QWidget" name="layout13">
- <layout class="QVBoxLayout">
- <item>
- <widget class="QLabel" name="textLabel1">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Common:</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QListWidget" name="listController">
- <property name="toolTip">
- <string/>
- </property>
- <property name="whatsThis">
- <string>This is a list of commonly used midi controllers.
-Note that in MusE pitch and program changes are
-handled like normal controllers.</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="layout17">
- <layout class="QVBoxLayout">
- <item>
- <widget class="QTreeWidget" name="viewController">
- <property name="toolTip">
- <string>List of defined controllers</string>
- </property>
- <property name="whatsThis">
- <string>List of defined controllers.</string>
- </property>
- <property name="frameShape">
- <enum>QFrame::StyledPanel</enum>
- </property>
- <property name="frameShadow">
- <enum>QFrame::Sunken</enum>
- </property>
- <property name="allColumnsShowFocus">
- <bool>true</bool>
- </property>
- <column>
- <property name="text">
- <string>Name </string>
- </property>
- </column>
- <column>
- <property name="text">
- <string>Type </string>
- </property>
- </column>
- <column>
- <property name="text">
- <string>H-Ctrl</string>
- </property>
- </column>
- <column>
- <property name="text">
- <string>L-Ctrl</string>
- </property>
- </column>
- <column>
- <property name="text">
- <string>Min </string>
- </property>
- </column>
- <column>
- <property name="text">
- <string>Max </string>
- </property>
- </column>
- <column>
- <property name="text">
- <string>Def </string>
- </property>
- </column>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="GroupBox1">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="title">
- <string>Properties</string>
- </property>
- <layout class="QVBoxLayout">
- <item>
- <layout class="QHBoxLayout">
- <item>
- <widget class="QLabel" name="TextLabel1_3">
- <property name="text">
- <string>Name:</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLineEdit" name="ctrlName">
- <property name="toolTip">
- <string/>
- </property>
- <property name="whatsThis">
- <string>Midi controller name</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout">
- <item>
- <widget class="QLabel" name="TextLabel2_4">
- <property name="text">
- <string>Type:</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QComboBox" name="ctrlType">
- <property name="toolTip">
- <string>Midi controller type</string>
- </property>
- <property name="whatsThis">
- <string>Midi controller type</string>
- </property>
- <item>
- <property name="text">
- <string>Control7</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Control14</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>RPN</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>NRPN</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>RPN14</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>NRPN14</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Pitch</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Program</string>
- </property>
- </item>
- </widget>
- </item>
- <item>
- <spacer name="spacer15">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Expanding</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QLabel" name="TextLabel3_2">
- <property name="text">
- <string>H-Ctrl</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- <property name="indent">
- <number>10</number>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSpinBox" name="spinBoxHCtrlNo">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="toolTip">
- <string>Midi controller number high byte</string>
- </property>
- <property name="whatsThis">
- <string>Midi controller number high byte</string>
- </property>
- <property name="minimum">
- <number>0</number>
- </property>
- <property name="maximum">
- <number>127</number>
- </property>
- <property name="value">
- <number>0</number>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="spacer16">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Expanding</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QLabel" name="TextLabel2_3_2">
- <property name="text">
- <string>L-Ctrl</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- <property name="indent">
- <number>10</number>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSpinBox" name="spinBoxLCtrlNo">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="toolTip">
- <string>Midi controller number low byte (* means drum controller)</string>
- </property>
- <property name="whatsThis">
- <string>Midi controller number low byte.
-If low byte is * then the controller is a
- 'drum controller'. For drum tracks and
- GS/XG type songs and instruments.
-Allows controllers for each instrument in
- Muse's drum map. The low byte will be
- replaced by the 'ANote' in the drum map.
-Examples: The GS and XG instruments'
- Drum controllers.</string>
- </property>
- <property name="specialValueText">
- <string comment="wild card">*</string>
- </property>
- <property name="minimum">
- <number>-1</number>
- </property>
- <property name="maximum">
- <number>127</number>
- </property>
- <property name="value">
- <number>0</number>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout">
- <item>
- <widget class="QLabel" name="textLabel4_2">
- <property name="text">
- <string>Range:</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="spacer17">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Expanding</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QLabel" name="TextLabel1_2_2">
- <property name="text">
- <string>Min</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- <property name="indent">
- <number>10</number>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSpinBox" name="spinBoxMin">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="toolTip">
- <string>Minimum value. If negative, auto-translate.</string>
- </property>
- <property name="whatsThis">
- <string>Minimum value. If the minimum value
- is negative, the range will automatically
- be translated to a positive range.
-
-Useful for controllers which should be
- displayed with zero bias. For example,
-'Pan': Minimum: -64 Maximum: 63
-True range: Min: 0 Max: 127 (bias = 64)
-'CoarseTuning': Min: -24 Max: 23
-True range: Min: 40 Max: 87 (bias = 64)
-
-Bias is determined from controller type:
-7-bit Controller7 / RPN: Bias = 64
-14-bit Controller14 / RPN14: Bias = 8192
-
-Type 'Pitch' is the exception. It is biased
- at zero, even with a negative minimum:
-'Pitch': Min: -8192 Max: 8191
-True range: Min: -8192 Max: 8191 (bias 0)</string>
- </property>
- <property name="minimum">
- <number>-16384</number>
- </property>
- <property name="maximum">
- <number>16383</number>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="spacer18">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Expanding</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QLabel" name="TextLabel2_2_2">
- <property name="text">
- <string>Max</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- <property name="indent">
- <number>10</number>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSpinBox" name="spinBoxMax">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="toolTip">
- <string>Maximum value</string>
- </property>
- <property name="whatsThis">
- <string>Maximum value</string>
- </property>
- <property name="minimum">
- <number>-16384</number>
- </property>
- <property name="maximum">
- <number>16383</number>
- </property>
- <property name="value">
- <number>127</number>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QGridLayout">
- <item row="1" column="0" colspan="2">
- <spacer name="spacer13_2">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Expanding</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="0" column="0">
- <widget class="QLabel" name="textLabel1_3">
- <property name="text">
- <string>Default:</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignVCenter</set>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="0" column="6">
- <widget class="QLabel" name="textLabel2_4">
- <property name="text">
- <string>L-Bank</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="0" column="5">
- <widget class="QSpinBox" name="defPatchH">
- <property name="specialValueText">
- <string>off</string>
- </property>
- <property name="minimum">
- <number>0</number>
- </property>
- <property name="maximum">
- <number>128</number>
- </property>
- <property name="value">
- <number>0</number>
- </property>
- </widget>
- </item>
- <item row="0" column="7">
- <widget class="QSpinBox" name="defPatchL">
- <property name="specialValueText">
- <string>off</string>
- </property>
- <property name="minimum">
- <number>0</number>
- </property>
- <property name="maximum">
- <number>128</number>
- </property>
- <property name="value">
- <number>0</number>
- </property>
- </widget>
- </item>
- <item row="1" column="6">
- <widget class="QLabel" name="textLabel3">
- <property name="text">
- <string>Progr.</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="1" column="7">
- <widget class="QSpinBox" name="defPatchProg">
- <property name="specialValueText">
- <string>off</string>
- </property>
- <property name="minimum">
- <number>0</number>
- </property>
- <property name="maximum">
- <number>128</number>
- </property>
- <property name="value">
- <number>0</number>
- </property>
- </widget>
- </item>
- <item row="1" column="2" colspan="4">
- <widget class="QPushButton" name="patchButton">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="minimumSize">
- <size>
- <width>210</width>
- <height>0</height>
- </size>
- </property>
- <property name="text">
- <string>???</string>
- </property>
- <property name="shortcut">
- <string/>
- </property>
- </widget>
- </item>
- <item row="0" column="4">
- <widget class="QLabel" name="textLabel1_5">
- <property name="text">
- <string>H-Bank</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="0" column="3">
- <spacer name="spacer12_2">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Expanding</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="0" column="1" colspan="2">
- <widget class="QSpinBox" name="spinBoxDefault">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>0</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>85</width>
- <height>32767</height>
- </size>
- </property>
- <property name="toolTip">
- <string>Default value. Off: No default.</string>
- </property>
- <property name="whatsThis">
- <string>Default (initial) value. Off means no default.
-
-If a default value is chosen, the value will be sent
- to the controller when the controller is added to
- the song (in piano roll or event editor). When
- the song is re-loaded, the value is sent again.
-Otherwise the controller remains at its last value.
-Controllers are also automatically added to a
- song upon reception of a midi controller event.
-
-Caution! Watch out for controllers such as
- 'Sustain' and 'ResetAllController' with default
- values. You should probably turn 'off' their
- default (in piano roll or drum edit, and
- instrument editor).</string>
- </property>
- <property name="specialValueText">
- <string comment="dont care">off</string>
- </property>
- <property name="minimum">
- <number>-1</number>
- </property>
- <property name="maximum">
- <number>16383</number>
- </property>
- <property name="value">
- <number>-1</number>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <layout class="QHBoxLayout">
- <item>
- <widget class="QToolButton" name="addController">
- <property name="toolTip">
- <string>Add common controller</string>
- </property>
- <property name="text">
- <string>&amp;Add</string>
- </property>
- <property name="shortcut">
- <string>Alt+A</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QToolButton" name="deleteController">
- <property name="toolTip">
- <string>Delete controller</string>
- </property>
- <property name="text">
- <string>&amp;Delete</string>
- </property>
- <property name="shortcut">
- <string>Alt+D</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QToolButton" name="newController">
- <property name="toolTip">
- <string>Create a new controller</string>
- </property>
- <property name="text">
- <string>New &amp;Controller</string>
- </property>
- <property name="shortcut">
- <string>Alt+C</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="spacer13">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Expanding</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>200</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QLabel" name="nullValLabelH">
- <property name="text">
- <string>Null Param Hi:</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSpinBox" name="nullParamSpinBoxH">
- <property name="toolTip">
- <string>Null parameter number High byte</string>
- </property>
- <property name="whatsThis">
- <string>If set, these 'null' parameter numbers will
- be sent after each RPN/NRPN event.
-This prevents subsequent 'data' events
- from corrupting the RPN/NRPN controller.
-Typically, set to 127/127, or an unused
- RPN/NRPN controller number.</string>
- </property>
- <property name="specialValueText">
- <string>off</string>
- </property>
- <property name="minimum">
- <number>-1</number>
- </property>
- <property name="maximum">
- <number>127</number>
- </property>
- <property name="value">
- <number>127</number>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="spacer13_3">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Expanding</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>200</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QLabel" name="nullValLabelL">
- <property name="text">
- <string> Lo:</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSpinBox" name="nullParamSpinBoxL">
- <property name="toolTip">
- <string>Null parameter number Low byte</string>
- </property>
- <property name="whatsThis">
- <string>If set, these 'null' parameter numbers will
- be sent after each RPN/NRPN event.
-This prevents subsequent 'data' events
- from corrupting the RPN/NRPN controller.
-Typically, set to 127/127, or an unused
- RPN/NRPN controller number.</string>
- </property>
- <property name="specialValueText">
- <string>off</string>
- </property>
- <property name="minimum">
- <number>-1</number>
- </property>
- <property name="maximum">
- <number>127</number>
- </property>
- <property name="value">
- <number>127</number>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="sysExTab">
- <attribute name="title">
- <string>S&amp;ysEx</string>
- </attribute>
- <layout class="QVBoxLayout">
- <item>
- <widget class="QSplitter" name="splitter2">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <widget class="QWidget" name="layout12">
- <layout class="QVBoxLayout">
- <item>
- <widget class="QLabel" name="textLabel2_3">
- <property name="text">
- <string>SysEx List:</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QListWidget" name="sysexList">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="layout11">
- <layout class="QVBoxLayout">
- <item>
- <widget class="QLabel" name="textLabel1_4">
- <property name="text">
- <string>Name:</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLineEdit" name="sysexName"/>
- </item>
- <item>
- <widget class="QLabel" name="label_2">
- <property name="text">
- <string>Comment:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QTextEdit" name="sysexComment"/>
- </item>
- <item>
- <widget class="QLabel" name="textLabel1_2">
- <property name="text">
- <string>Hex Entry:</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QTextEdit" name="sysexData"/>
- </item>
- <item>
- <layout class="QHBoxLayout">
- <item>
- <widget class="QToolButton" name="deleteSysex">
- <property name="text">
- <string>&amp;Delete</string>
- </property>
- <property name="shortcut">
- <string>Alt+D</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QToolButton" name="newSysex">
- <property name="text">
- <string>New SysE&amp;x</string>
- </property>
- <property name="shortcut">
- <string>Alt+X</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="spacer12">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Expanding</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>60</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- </widget>
- </item>
- </layout>
- </widget>
<widget class="QWidget" name="drumTab">
<attribute name="title">
- <string>Drummaps</string>
+ <string>Drum&amp;maps</string>
</attribute>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
@@ -1796,6 +873,982 @@ Typically, set to 127/127, or an unused
</item>
</layout>
</widget>
+ <widget class="QWidget" name="controllerTab">
+ <attribute name="title">
+ <string>Contro&amp;llers</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_7">
+ <item>
+ <widget class="QLabel" name="nullValLabelH">
+ <property name="text">
+ <string>Null Parameters: Hi:</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="nullParamSpinBoxH">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Null parameter number High byte</string>
+ </property>
+ <property name="whatsThis">
+ <string>If set, these 'null' parameter numbers will
+ be sent after each RPN/NRPN event.
+This prevents subsequent 'data' events
+ from corrupting the RPN/NRPN controller.
+Typically, set to 127/127, or an unused
+ RPN/NRPN controller number.</string>
+ </property>
+ <property name="specialValueText">
+ <string>off</string>
+ </property>
+ <property name="minimum">
+ <number>-1</number>
+ </property>
+ <property name="maximum">
+ <number>127</number>
+ </property>
+ <property name="value">
+ <number>127</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="nullValLabelL">
+ <property name="text">
+ <string> Lo:</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="nullParamSpinBoxL">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Null parameter number Low byte</string>
+ </property>
+ <property name="whatsThis">
+ <string>If set, these 'null' parameter numbers will
+ be sent after each RPN/NRPN event.
+This prevents subsequent 'data' events
+ from corrupting the RPN/NRPN controller.
+Typically, set to 127/127, or an unused
+ RPN/NRPN controller number.</string>
+ </property>
+ <property name="specialValueText">
+ <string>off</string>
+ </property>
+ <property name="minimum">
+ <number>-1</number>
+ </property>
+ <property name="maximum">
+ <number>127</number>
+ </property>
+ <property name="value">
+ <number>127</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QTreeWidget" name="viewController">
+ <property name="toolTip">
+ <string>List of defined controllers</string>
+ </property>
+ <property name="whatsThis">
+ <string>List of defined controllers.</string>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Sunken</enum>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>true</bool>
+ </property>
+ <attribute name="headerDefaultSectionSize">
+ <number>60</number>
+ </attribute>
+ <attribute name="headerMinimumSectionSize">
+ <number>30</number>
+ </attribute>
+ <attribute name="headerStretchLastSection">
+ <bool>false</bool>
+ </attribute>
+ <column>
+ <property name="text">
+ <string>Name </string>
+ </property>
+ <property name="textAlignment">
+ <set>AlignLeft|AlignVCenter</set>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Type </string>
+ </property>
+ <property name="textAlignment">
+ <set>AlignLeft|AlignVCenter</set>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>H-Ctrl</string>
+ </property>
+ <property name="textAlignment">
+ <set>AlignRight|AlignVCenter</set>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>L-Ctrl</string>
+ </property>
+ <property name="textAlignment">
+ <set>AlignRight|AlignVCenter</set>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Min </string>
+ </property>
+ <property name="textAlignment">
+ <set>AlignRight|AlignVCenter</set>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Max </string>
+ </property>
+ <property name="textAlignment">
+ <set>AlignRight|AlignVCenter</set>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Def </string>
+ </property>
+ <property name="textAlignment">
+ <set>AlignRight|AlignVCenter</set>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Midi</string>
+ </property>
+ <property name="textAlignment">
+ <set>AlignRight|AlignVCenter</set>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Drum</string>
+ </property>
+ <property name="textAlignment">
+ <set>AlignRight|AlignVCenter</set>
+ </property>
+ </column>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="GroupBox1">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Properties</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <property name="spacing">
+ <number>2</number>
+ </property>
+ <property name="margin">
+ <number>2</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout">
+ <item>
+ <widget class="QLabel" name="TextLabel1_3">
+ <property name="text">
+ <string>Name:</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="ctrlName">
+ <property name="toolTip">
+ <string/>
+ </property>
+ <property name="whatsThis">
+ <string>Midi controller name</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="newController">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Create a new controller</string>
+ </property>
+ <property name="text">
+ <string>New &amp;Controller</string>
+ </property>
+ <property name="shortcut">
+ <string>Alt+C</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="addController">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Add common controller</string>
+ </property>
+ <property name="text">
+ <string>&amp;Add Common...</string>
+ </property>
+ <property name="shortcut">
+ <string>Alt+A</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="deleteController">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Delete controller</string>
+ </property>
+ <property name="text">
+ <string>&amp;Delete</string>
+ </property>
+ <property name="shortcut">
+ <string>Alt+D</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_6">
+ <item>
+ <widget class="QLabel" name="TextLabel2_4">
+ <property name="text">
+ <string>Type:</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="ctrlType">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Midi controller type</string>
+ </property>
+ <property name="whatsThis">
+ <string>Midi controller type</string>
+ </property>
+ <item>
+ <property name="text">
+ <string>Control7</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Control14</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>RPN</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>NRPN</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>RPN14</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>NRPN14</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Pitch</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Program</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>PolyAftertouch</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Aftertouch</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="TextLabel3_2">
+ <property name="text">
+ <string>H-Ctrl</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ <property name="indent">
+ <number>10</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="spinBoxHCtrlNo">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Midi controller number high byte</string>
+ </property>
+ <property name="whatsThis">
+ <string>Midi controller number high byte</string>
+ </property>
+ <property name="minimum">
+ <number>0</number>
+ </property>
+ <property name="maximum">
+ <number>127</number>
+ </property>
+ <property name="value">
+ <number>0</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="TextLabel2_3_2">
+ <property name="text">
+ <string>L-Ctrl</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ <property name="indent">
+ <number>10</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="spinBoxLCtrlNo">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Midi controller number low byte (* means drum controller)</string>
+ </property>
+ <property name="whatsThis">
+ <string>Midi controller number low byte.
+If low byte is * then the controller is a
+ 'drum controller'. For drum tracks and
+ GS/XG type songs and instruments.
+Allows controllers for each instrument in
+ Muse's drum map. The low byte will be
+ replaced by the 'ANote' in the drum map.
+Examples: The GS and XG instruments'
+ Drum controllers.</string>
+ </property>
+ <property name="specialValueText">
+ <string comment="wild card">*</string>
+ </property>
+ <property name="minimum">
+ <number>-1</number>
+ </property>
+ <property name="maximum">
+ <number>127</number>
+ </property>
+ <property name="value">
+ <number>0</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="ctrlValidLabel">
+ <property name="text">
+ <string>W</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="spacer16">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>0</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout">
+ <item>
+ <widget class="QLabel" name="textLabel4_2">
+ <property name="text">
+ <string>Range:</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="TextLabel1_2_2">
+ <property name="text">
+ <string>Min</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ <property name="indent">
+ <number>10</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="spinBoxMin">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Minimum value. If negative, auto-translate.</string>
+ </property>
+ <property name="whatsThis">
+ <string>Minimum value. If the minimum value
+ is negative, the range will automatically
+ be translated to a positive range.
+
+Useful for controllers which should be
+ displayed with zero bias. For example,
+'Pan': Minimum: -64 Maximum: 63
+True range: Min: 0 Max: 127 (bias = 64)
+'CoarseTuning': Min: -24 Max: 23
+True range: Min: 40 Max: 87 (bias = 64)
+
+Bias is determined from controller type:
+7-bit Controller7 / RPN: Bias = 64
+14-bit Controller14 / RPN14: Bias = 8192
+
+Type 'Pitch' is the exception. It is biased
+ at zero, even with a negative minimum:
+'Pitch': Min: -8192 Max: 8191
+True range: Min: -8192 Max: 8191 (bias 0)</string>
+ </property>
+ <property name="minimum">
+ <number>-16384</number>
+ </property>
+ <property name="maximum">
+ <number>16383</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="TextLabel2_2_2">
+ <property name="text">
+ <string>Max</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ <property name="indent">
+ <number>10</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="spinBoxMax">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Maximum value</string>
+ </property>
+ <property name="whatsThis">
+ <string>Maximum value</string>
+ </property>
+ <property name="minimum">
+ <number>-16384</number>
+ </property>
+ <property name="maximum">
+ <number>16383</number>
+ </property>
+ <property name="value">
+ <number>127</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>22</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Show in tracks:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="ctrlShowInMidi">
+ <property name="text">
+ <string>Midi</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="ctrlShowInDrum">
+ <property name="text">
+ <string>Drum</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="spacer18">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>0</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_5">
+ <item>
+ <widget class="QLabel" name="textLabel1_3">
+ <property name="text">
+ <string>Default:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignVCenter</set>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="spinBoxDefault">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>Default value. Off: No default.</string>
+ </property>
+ <property name="whatsThis">
+ <string>Default (initial) value. Off means no default.
+
+If a default value is chosen, the value will be sent
+ to the controller when the controller is added to
+ the song (in piano roll or event editor). When
+ the song is re-loaded, the value is sent again.
+Otherwise the controller remains at its last value.
+Controllers are also automatically added to a
+ song upon reception of a midi controller event.
+
+Caution! Watch out for controllers such as
+ 'Sustain' and 'ResetAllController' with default
+ values. You should probably turn 'off' their
+ default (in piano roll or drum edit, and
+ instrument editor).</string>
+ </property>
+ <property name="specialValueText">
+ <string comment="dont care">off</string>
+ </property>
+ <property name="minimum">
+ <number>-1</number>
+ </property>
+ <property name="maximum">
+ <number>16383</number>
+ </property>
+ <property name="value">
+ <number>-1</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="textLabel1_5">
+ <property name="text">
+ <string>H-Bank</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="defPatchH">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="specialValueText">
+ <string>off</string>
+ </property>
+ <property name="minimum">
+ <number>0</number>
+ </property>
+ <property name="maximum">
+ <number>128</number>
+ </property>
+ <property name="value">
+ <number>0</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="textLabel2_4">
+ <property name="text">
+ <string>L-Bank</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="defPatchL">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="specialValueText">
+ <string>off</string>
+ </property>
+ <property name="minimum">
+ <number>0</number>
+ </property>
+ <property name="maximum">
+ <number>128</number>
+ </property>
+ <property name="value">
+ <number>0</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="textLabel3">
+ <property name="text">
+ <string>Progr.</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="defPatchProg">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="specialValueText">
+ <string>off</string>
+ </property>
+ <property name="minimum">
+ <number>0</number>
+ </property>
+ <property name="maximum">
+ <number>128</number>
+ </property>
+ <property name="value">
+ <number>0</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="patchButton">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>???</string>
+ </property>
+ <property name="shortcut">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="sysExTab">
+ <attribute name="title">
+ <string>S&amp;ysEx</string>
+ </attribute>
+ <layout class="QVBoxLayout">
+ <item>
+ <widget class="QSplitter" name="splitter2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <widget class="QWidget" name="layout12">
+ <layout class="QVBoxLayout">
+ <item>
+ <widget class="QLabel" name="textLabel2_3">
+ <property name="text">
+ <string>SysEx List:</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QListWidget" name="sysexList">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="layout11">
+ <layout class="QVBoxLayout">
+ <item>
+ <widget class="QLabel" name="textLabel1_4">
+ <property name="text">
+ <string>Name:</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="sysexName"/>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Comment:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTextEdit" name="sysexComment"/>
+ </item>
+ <item>
+ <widget class="QLabel" name="textLabel1_2">
+ <property name="text">
+ <string>Hex Entry:</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTextEdit" name="sysexData"/>
+ </item>
+ <item>
+ <layout class="QHBoxLayout">
+ <item>
+ <widget class="QToolButton" name="deleteSysex">
+ <property name="text">
+ <string>&amp;Delete</string>
+ </property>
+ <property name="shortcut">
+ <string>Alt+D</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="newSysex">
+ <property name="text">
+ <string>New SysE&amp;x</string>
+ </property>
+ <property name="shortcut">
+ <string>Alt+X</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="spacer12">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>60</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
</widget>
</widget>
</item>
@@ -1821,8 +1874,8 @@ Typically, set to 127/127, or an unused
<rect>
<x>0</x>
<y>0</y>
- <width>802</width>
- <height>21</height>
+ <width>772</width>
+ <height>23</height>
</rect>
</property>
<property name="defaultUp">
@@ -1960,14 +2013,11 @@ Typically, set to 127/127, or an unused
<tabstop>checkBoxGM</tabstop>
<tabstop>checkBoxGS</tabstop>
<tabstop>checkBoxXG</tabstop>
- <tabstop>listController</tabstop>
- <tabstop>viewController</tabstop>
<tabstop>ctrlName</tabstop>
<tabstop>ctrlType</tabstop>
<tabstop>spinBoxHCtrlNo</tabstop>
<tabstop>spinBoxLCtrlNo</tabstop>
<tabstop>spinBoxMin</tabstop>
- <tabstop>spinBoxMax</tabstop>
<tabstop>spinBoxDefault</tabstop>
<tabstop>sysexList</tabstop>
<tabstop>sysexName</tabstop>
diff --git a/muse2/muse/liste/editctrlbase.ui b/muse2/muse/liste/editctrlbase.ui
index 7b4d68ec..036b4525 100644
--- a/muse2/muse/liste/editctrlbase.ui
+++ b/muse2/muse/liste/editctrlbase.ui
@@ -500,23 +500,34 @@
</disabled>
</palette>
</property>
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
<widget class="QWidget" name="WStackPage">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>140</width>
- <height>349</height>
- </rect>
- </property>
- <layout class="QGridLayout">
- <item row="3" column="0" colspan="2">
- <widget class="QSlider" name="valSlider">
- <property name="maximum">
- <number>127</number>
- </property>
+ <layout class="QGridLayout" name="gridLayout1">
+ <item row="0" column="1">
+ <spacer name="spacer2">
<property name="orientation">
- <enum>Qt::Horizontal</enum>
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="textLabel2">
+ <property name="text">
+ <string>Controller</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
</property>
</widget>
</item>
@@ -534,59 +545,52 @@
</widget>
</item>
<item row="2" column="0">
- <widget class="QLabel" name="textLabel4">
+ <widget class="QLabel" name="textLabel2_3">
<property name="text">
- <string>Value</string>
+ <string>Note</string>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget>
</item>
- <item row="1" column="0">
- <widget class="QLabel" name="textLabel2">
+ <item row="2" column="1">
+ <widget class="QSpinBox" name="noteSpinBox">
+ <property name="maximum">
+ <number>127</number>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="textLabel4">
<property name="text">
- <string>Controller</string>
+ <string>Value</string>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget>
</item>
- <item row="2" column="1">
+ <item row="3" column="1">
<widget class="QSpinBox" name="valSpinBox">
<property name="maximum">
<number>127</number>
</property>
</widget>
</item>
- <item row="0" column="1">
- <spacer name="spacer2">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Expanding</enum>
+ <item row="4" column="0" colspan="2">
+ <widget class="QSlider" name="valSlider">
+ <property name="maximum">
+ <number>127</number>
</property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
</property>
- </spacer>
+ </widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="WStackPage2">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>100</width>
- <height>30</height>
- </rect>
- </property>
<layout class="QGridLayout">
<item row="2" column="0">
<widget class="QLabel" name="textLabel2_2">
@@ -759,8 +763,7 @@
</widget>
</item>
<item row="1" column="0" colspan="2">
- <widget class="QListWidget" name="ctrlList">
- </widget>
+ <widget class="QListWidget" name="ctrlList"/>
</item>
<item row="2" column="1">
<spacer name="spacer3">
@@ -802,44 +805,11 @@
<class>Awl::PosEdit</class>
<extends>QWidget</extends>
<header>awl/posedit.h</header>
- <container>0</container>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
- <sender>buttonOk</sender>
- <signal>clicked()</signal>
- <receiver>MyDialog</receiver>
- <slot>accept()</slot>
- <hints>
- <hint type="sourcelabel">
- <x>20</x>
- <y>20</y>
- </hint>
- <hint type="destinationlabel">
- <x>20</x>
- <y>20</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>buttonCancel</sender>
- <signal>clicked()</signal>
- <receiver>MyDialog</receiver>
- <slot>reject()</slot>
- <hints>
- <hint type="sourcelabel">
- <x>20</x>
- <y>20</y>
- </hint>
- <hint type="destinationlabel">
- <x>20</x>
- <y>20</y>
- </hint>
- </hints>
- </connection>
- <connection>
<sender>valSlider</sender>
<signal>valueChanged(int)</signal>
<receiver>valSpinBox</receiver>
diff --git a/muse2/muse/liste/editevent.cpp b/muse2/muse/liste/editevent.cpp
index 415c6385..fac6866d 100644
--- a/muse2/muse/liste/editevent.cpp
+++ b/muse2/muse/liste/editevent.cpp
@@ -27,6 +27,7 @@
#include <QGridLayout>
#include <QLabel>
#include <QListWidget>
+#include <QListWidgetItem>
#include <QMessageBox>
#include <QPushButton>
#include <QRadioButton>
@@ -602,22 +603,32 @@ EditCtrlDialog::EditCtrlDialog(int tick, const MusECore::Event& event,
{
setupUi(this);
widgetStack->setAutoFillBackground(true);
+
+ MusECore::MidiTrack* track = part->track();
+ int portn = track->outPort();
+ MusECore::MidiPort* port = &MusEGlobal::midiPorts[portn];
+ bool isDrum = track->type() == MusECore::Track::DRUM;
+ bool isNewDrum = track->type() == MusECore::Track::NEW_DRUM;
+ bool isMidi = track->type() == MusECore::Track::MIDI;
+ MusECore::MidiCtrlValListList* cll = port->controller();
+
val = 0;
num = 0;
+ int note = -1;
if (!event.empty()) {
num = event.dataA();
val = event.dataB();
+ if(port->drumController(num))
+ {
+ if(isDrum)
+ num = (num & ~0xff) | MusEGlobal::drumMap[num & 0xff].anote;
+ note = num & 0xff;
}
+ }
///pop = new QMenu(this);
//pop->setCheckable(false); //not necessary in Qt4
- MusECore::MidiTrack* track = part->track();
- int portn = track->outPort();
- MusECore::MidiPort* port = &MusEGlobal::midiPorts[portn];
- bool isDrum = track->isDrumTrack();
- MusECore::MidiCtrlValListList* cll = port->controller();
-
ctrlList->clear();
ctrlList->setSelectionMode(QAbstractItemView::SingleSelection);
@@ -630,14 +641,34 @@ EditCtrlDialog::EditCtrlDialog(int tick, const MusECore::Event& event,
for (MusECore::iMidiCtrlValList it = cll->begin(); it != cll->end(); ++it) {
MusECore::MidiCtrlValList* cl = it->second;
- int num = cl->num();
+ int clnum = cl->num();
// dont show drum specific controller if not a drum track
- if ((num & 0xff) == 0xff) {
- if (!isDrum)
- continue;
- }
- MusECore::MidiController* c = port->midiController(num);
+ //if ((num & 0xff) == 0xff) { // REMOVE Tim. Or keep.
+ // if (!isDrum)
+ // continue;
+ // }
+// int rnum = num;
+// if(port->drumController(num))
+// {
+// rnum |= 0xff;
+// if()
+// continue;
+// }
+
+
+// FIXME: TODO: Finish this stuff off. Use items' data member for control number.
+
+ MusECore::MidiController* c = port->midiController(clnum);
+ //int cnum = c->num();
+ //if(c->isPerNoteController())
+ //{
+ if(((isDrum || isNewDrum) && !(c->showInTracks() & MusECore::MidiController::ShowInDrum)) ||
+ (isMidi && !(c->showInTracks() & MusECore::MidiController::ShowInMidi)))
+ continue;
+ //}
+
+
{
isList i = sList.begin();
for (; i != sList.end(); ++i) {
@@ -674,10 +705,27 @@ EditCtrlDialog::EditCtrlDialog(int tick, const MusECore::Event& event,
{
widgetStack->setCurrentIndex(0);
valSlider->setValue(val - mc->bias());
+
+ if(mc->isPerNoteController())
+ {
+ noteSpinBox->setVisible(true);
+ noteSpinBox->setEnabled(true);
+ if(note != -1)
+ noteSpinBox->setValue(note);
+ }
+ else
+ {
+ noteSpinBox->setEnabled(false);
+ noteSpinBox->setVisible(false);
+ }
}
}
else
+ {
+ noteSpinBox->setEnabled(false);
+ noteSpinBox->setVisible(false);
ctrlListClicked(ctrlList->selectedItems()[0]);
+ }
connect(ctrlList, SIGNAL(itemClicked(QListWidgetItem*)), SLOT(ctrlListClicked(QListWidgetItem*)));
connect(buttonNewController, SIGNAL(clicked()), SLOT(newController()));
connect(hbank, SIGNAL(valueChanged(int)), SLOT(programChanged()));
@@ -703,36 +751,77 @@ void EditCtrlDialog::newController()
MusECore::MidiTrack* track = part->track();
int portn = track->outPort();
MusECore::MidiPort* port = &MusEGlobal::midiPorts[portn];
+ bool isDrum = track->type() == MusECore::Track::DRUM;
+ bool isNewDrum = track->type() == MusECore::Track::NEW_DRUM;
+ bool isMidi = track->type() == MusECore::Track::MIDI;
MusECore::MidiInstrument* instr = port->instrument();
MusECore::MidiControllerList* mcl = instr->controller();
MusECore::MidiCtrlValListList* cll = port->controller();
int channel = track->outChannel();
- int nn = 0;
+ //int nn = 0;
for (MusECore::iMidiController ci = mcl->begin(); ci != mcl->end(); ++ci)
{
- if(cll->find(channel, ci->second->num()) == cll->end())
- {
- QAction* act = pup->addAction(ci->second->name());
- act->setData(nn);
- ++nn;
- }
+
+ MusECore::MidiController* c = ci->second;
+ int num = c->num();
+ int show = c->showInTracks();
+
+ if(((isDrum || isNewDrum) && !(show & MusECore::MidiController::ShowInDrum)) ||
+ (isMidi && !(show & MusECore::MidiController::ShowInMidi)))
+ continue;
+ if(c->isPerNoteController())
+ {
+ if (isDrum)
+ num = (num & ~0xff) | MusEGlobal::drumMap[noteSpinBox->value()].anote;
+ else if ((isNewDrum || isMidi))
+ num = (num & ~0xff) | noteSpinBox->value();
+ else // dont show drum specific controller if not a drum track
+ continue;
+ }
+
+ // If it's not already in the parent menu...
+ if(cll->find(channel, num) == cll->end())
+ {
+ //ctrlSubPop->addAction(MusECore::midiCtrlNumString(num, true) + ci->second->name())->setData(num);
+ QAction* act = pup->addAction(MusECore::midiCtrlNumString(num, true) + c->name());
+ act->setData(num);
+ }
+
+// REMOVE Tim.
+// if(cll->find(channel, ci->second->num()) == cll->end())
+// {
+// QAction* act = pup->addAction(ci->second->name());
+// act->setData(nn);
+// ++nn;
+// }
}
- QAction* rv = pup->exec(buttonNewController->mapToGlobal(QPoint(0,0)));
- if (rv) {
- QString s = rv->text();
+
+// QAction* rv = pup->exec(buttonNewController->mapToGlobal(QPoint(0,0)));
+ QAction* act = pup->exec(buttonNewController->mapToGlobal(QPoint(0,0)));
+ if (act && act->data().toInt() != -1) {
+ //QString s = rv->text(); // REMOVE Tim.
+ int rv = act->data().toInt();
+ int num = rv;
+ if(port->drumController(rv))
+ num |= 0xff;
for (MusECore::iMidiController ci = mcl->begin(); ci != mcl->end(); ++ci) {
MusECore::MidiController* mc = ci->second;
- if (mc->name() == s) {
- if(cll->find(channel, mc->num()) == cll->end())
+ //if (mc->name() == s) { // REMOVE Tim.
+ if (mc->num() == num) {
+ //if(cll->find(channel, mc->num()) == cll->end()) // REMOVE Tim.
+ if(cll->find(channel, rv) == cll->end())
{
- MusECore::MidiCtrlValList* vl = new MusECore::MidiCtrlValList(mc->num());
+ //MusECore::MidiCtrlValList* vl = new MusECore::MidiCtrlValList(mc->num()); // REMOVE Tim.
+ MusECore::MidiCtrlValList* vl = new MusECore::MidiCtrlValList(rv);
cll->add(channel, vl);
}
int idx = 0;
for (; idx < ctrlList->count() ;++idx) { // p4.0.25 Fix segfault
- QString str = ctrlList->item(idx)->text();
- if (s == str)
+ //QString str = ctrlList->item(idx)->text(); // REMOVE Tim.
+ int item_data = ctrlList->item(idx)->data(Qt::UserRole).toInt();
+ //if (s == str)
+ if (item_data == num)
{
ctrlList->item(idx)->setSelected(true);
ctrlListClicked(ctrlList->item(idx));
@@ -740,7 +829,10 @@ void EditCtrlDialog::newController()
}
}
if (idx >= ctrlList->count()) { // p4.0.25 Fix segfault
- ctrlList->addItem(s);
+ //ctrlList->addItem(s); // REMOVE Tim.
+ QListWidgetItem* new_item = new QListWidgetItem(act->text(), ctrlList);
+ new_item->setData(Qt::UserRole, num);
+ //ctrlList->addItem(new_item);
ctrlList->item(idx)->setSelected(true);
ctrlListClicked(ctrlList->item(idx));
break;
diff --git a/muse2/muse/midictrl.cpp b/muse2/muse/midictrl.cpp
index 56b1b2a8..14dd666e 100644
--- a/muse2/muse/midictrl.cpp
+++ b/muse2/muse/midictrl.cpp
@@ -250,11 +250,12 @@ MidiController::MidiController()
_minVal = 0;
_maxVal = 127;
_initVal = 0;
+ _showInTracks = ShowInDrum | ShowInMidi;
updateBias();
}
-MidiController::MidiController(const QString& s, int n, int min, int max, int init)
- : _name(s), _num(n), _minVal(min), _maxVal(max), _initVal(init)
+MidiController::MidiController(const QString& s, int n, int min, int max, int init, int show_in_track)
+ : _name(s), _num(n), _minVal(min), _maxVal(max), _initVal(init), _showInTracks(show_in_track)
{
updateBias();
}
@@ -276,6 +277,7 @@ void MidiController::copy(const MidiController &mc)
_maxVal = mc._maxVal;
_initVal = mc._initVal;
_bias = mc._bias;
+ _showInTracks = mc._showInTracks;
}
//---------------------------------------------------------
@@ -308,7 +310,7 @@ MidiController::ControllerType midiControllerType(int num)
return MidiController::Program;
if (num == CTRL_VELOCITY)
return MidiController::Velo;
- if (num == CTRL_POLYAFTER)
+ if ((num | 0xff) == CTRL_POLYAFTER)
return MidiController::PolyAftertouch;
if (num == CTRL_AFTERTOUCH)
return MidiController::Aftertouch;
@@ -323,10 +325,10 @@ MidiController::ControllerType midiControllerType(int num)
// midiCtrlTerms2Number
//---------------------------------------------------------
-int midiCtrlTerms2Number(int type_num, int ctrl)
+int midiCtrlTerms2Number(MidiController::ControllerType type, int ctrl)
{
ctrl &= 0xffff;
- switch(type_num)
+ switch(type)
{
case MidiController::Controller7:
return ctrl & 0xff;
@@ -442,7 +444,7 @@ void MidiController::write(int level, Xml& xml) const
int l = _num & 0x7f;
QString sl;
- if ((_num & 0xff) == 0xff)
+ if (isPerNoteController())
sl = "pitch";
else
sl.setNum(l);
@@ -504,6 +506,10 @@ void MidiController::write(int level, Xml& xml) const
if(_initVal != CTRL_VAL_UNKNOWN)
xml.nput(" init=\"%d\"", _initVal);
}
+
+ if(_showInTracks != (ShowInDrum | ShowInMidi))
+ xml.nput(" showType=\"%d\"", _showInTracks);
+
xml.put(" />");
}
@@ -542,9 +548,7 @@ void MidiController::read(Xml& xml)
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.
+ // Support instrument files with '*' or 'pitch' as wildcard.
if ((xml.s2() == "*") || (xml.s2() == "pitch"))
l = 0xff;
else
@@ -556,6 +560,8 @@ void MidiController::read(Xml& xml)
_maxVal = xml.s2().toInt(&ok, base);
else if (tag == "init")
_initVal = xml.s2().toInt(&ok, base);
+ else if (tag == "showType")
+ _showInTracks = xml.s2().toInt(&ok, base);
}
break;
case Xml::TagStart:
@@ -625,7 +631,6 @@ void MidiController::read(Xml& xml)
}
if (_minVal == NOT_SET)
_minVal = 0;
-
updateBias();
return;
}
@@ -641,10 +646,10 @@ void MidiController::read(Xml& xml)
int MidiController::genNum(MidiController::ControllerType t, int h, int l)
{
- int val = (h << 8) + l;
+ int val = (h << 8) | (l & 0xff);
switch(t) {
case Controller7:
- return l;
+ return l & 0xff;
case Controller14:
return val + CTRL_14_OFFSET;
case RPN:
@@ -881,4 +886,30 @@ MidiControllerList::MidiControllerList(const MidiControllerList& mcl) : std::map
}
}
+//---------------------------------------------------------
+// ctrlAvailable (static)
+// Check if either a per-note controller, or else a regular controller already exists.
+//---------------------------------------------------------
+
+bool MidiControllerList::ctrlAvailable(int find_num, MidiController* ignore_this)
+{
+ MusECore::ciMidiController imc;
+ for(imc = begin(); imc != end(); ++ imc)
+ {
+ // Ignore this controller.
+ if(ignore_this && imc->second == ignore_this)
+ continue;
+ int n = imc->second->num();
+ if(((find_num & 0xff) == 0xff) && ((n | 0xff) == find_num))
+ break;
+ if(imc->second->isPerNoteController() && ((find_num | 0xff) == n))
+ break;
+ if(find_num == n)
+ break;
+ }
+ return imc == end();
+}
+
+
+
} // namespace MusECore
diff --git a/muse2/muse/midictrl.h b/muse2/muse/midictrl.h
index d4cd1079..1431d5e5 100644
--- a/muse2/muse/midictrl.h
+++ b/muse2/muse/midictrl.h
@@ -117,10 +117,13 @@ class MidiController {
NRPN14, // non registered parameter 0x60000 -
Pitch, // num value = CTRL_PITCH
Program, // num value = CTRL_PROGRAM
- Velo, // not assigned
- PolyAftertouch, // num value = CTRL_POLYAFTER
- Aftertouch // num value = CTRL_AFTERTOUCH
+ PolyAftertouch, // num value = CTRL_POLYAFTER
+ Aftertouch, // num value = CTRL_AFTERTOUCH
+ Velo // not assigned
};
+
+ enum ShowInTrackType { ShowInDrum=1, ShowInMidi=2 };
+
private:
QString _name;
int _num; // Controller Number
@@ -128,11 +131,12 @@ class MidiController {
int _maxVal;
int _initVal;
int _bias;
+ int _showInTracks;
void updateBias();
public:
MidiController();
- MidiController(const QString& n, int num, int min, int max, int init);
+ MidiController(const QString& n, int num, int min, int max, int init, int show_in_track = (ShowInDrum | ShowInMidi));
MidiController(const MidiController& mc);
void copy(const MidiController &mc);
MidiController& operator= (const MidiController &mc);
@@ -150,6 +154,9 @@ class MidiController {
void setMinVal(int val) { _minVal = val; updateBias(); }
void setMaxVal(int val) { _maxVal = val; updateBias(); }
int bias() const { return _bias; }
+ int showInTracks() const { return _showInTracks; }
+ void setShowInTracks(int i) { _showInTracks = i; }
+ bool isPerNoteController() const { return (_num & 0xff) == 0xff; }
static int genNum(ControllerType, int, int);
};
@@ -239,6 +246,7 @@ class MidiControllerList : public std::map<int, MidiController*, std::less<int>
MidiControllerList(const MidiControllerList& mcl);
void add(MidiController* mc) { insert(std::pair<int, MidiController*>(mc->num(), mc)); }
+ bool ctrlAvailable(int find_num, MidiController* ignore_this = 0);
};
typedef MidiControllerList::iterator iMidiController;
@@ -248,7 +256,7 @@ typedef MidiControllerList MidiControllerList;
extern MidiControllerList defaultMidiController;
extern void initMidiController();
extern MidiController::ControllerType midiControllerType(int num);
-extern int midiCtrlTerms2Number(int type_num, int ctrl);
+extern int midiCtrlTerms2Number(MidiController::ControllerType type, int ctrl = 0);
extern const QString& int2ctrlType(int n);
diff --git a/muse2/muse/mididev.cpp b/muse2/muse/mididev.cpp
index 3703def2..2459f72a 100644
--- a/muse2/muse/mididev.cpp
+++ b/muse2/muse/mididev.cpp
@@ -775,7 +775,10 @@ void MidiDevice::handleSeek()
{
//_playEvents.add(MidiPlayEvent(0, _port, chan, ME_CONTROLLER, ctlnum, imcv->second.val));
// Use sendEvent to get the optimizations and limiting. But force if there's a value at this exact position.
- mp->sendEvent(MidiPlayEvent(0, _port, chan, ME_CONTROLLER, ctlnum, imcv->second.val), imcv->first == pos);
+ // NOTE: Why again was this forced? There was a reason. Think it was RJ in response to bug rep, then I modded.
+ // A reason not to force: If a straight line is drawn on graph, multiple identical events are stored
+ // (which must be allowed). So seeking through them here sends them all redundantly, not good. // REMOVE Tim.
+ mp->sendEvent(MidiPlayEvent(0, _port, chan, ME_CONTROLLER, ctlnum, imcv->second.val), false); //, imcv->first == pos);
//mp->sendEvent(MidiPlayEvent(0, _port, chan, ME_CONTROLLER, ctlnum, imcv->second.val), pos == 0 || imcv->first == pos);
//done = true;
}
diff --git a/muse2/muse/midiedit/drumedit.cpp b/muse2/muse/midiedit/drumedit.cpp
index 03f246cf..5126180f 100644
--- a/muse2/muse/midiedit/drumedit.cpp
+++ b/muse2/muse/midiedit/drumedit.cpp
@@ -64,6 +64,7 @@
#include "popupmenu.h"
#include "menutitleitem.h"
#include "widgets/function_dialogs/quantize.h"
+#include "editinstrument.h"
namespace MusEGui {
@@ -1253,141 +1254,27 @@ void DrumEdit::ctrlPopupTriggered(QAction* act)
MusECore::MidiTrack* track = (MusECore::MidiTrack*)(part->track());
int channel = track->outChannel();
MusECore::MidiPort* port = &MusEGlobal::midiPorts[track->outPort()];
- int curDrumPitch = curDrumInstrument();
- bool isDrum = track->type() == MusECore::Track::DRUM;
- bool isNewDrum = track->type() == MusECore::Track::NEW_DRUM;
- MusECore::MidiInstrument* instr = port->instrument();
- MusECore::MidiControllerList* mcl = instr->controller();
-
MusECore::MidiCtrlValListList* cll = port->controller();
const int min = channel << 24;
const int max = min + 0x1000000;
-
- const int add_ins_def = max + 1;
- const int add_other = max + 2;
const int edit_ins = max + 3;
-
const int velo = max + 0x101;
-
int rv = act->data().toInt();
if (rv == velo) { // special case velocity
newCtlNum = MusECore::CTRL_VELOCITY;
}
- else if (rv == add_ins_def) { // add new instrument controller
-
- PopupMenu * ctrlSubPop = new PopupMenu(this, true); // true = enable stay open
- ctrlSubPop->addAction(new MenuTitleItem(tr("Instrument-defined"), ctrlSubPop));
-
- //
- // populate popup with all controllers available for
- // current instrument
- //
-
- for (MusECore::iMidiController ci = mcl->begin(); ci != mcl->end(); ++ci)
- {
- int num = ci->second->num();
- if((num & 0xff) == 0xff)
- {
- if (isDrum && curDrumPitch!=-1)
- num = (num & ~0xff) + MusEGlobal::drumMap[curDrumPitch].anote;
- else if (isNewDrum && curDrumPitch!=-1)
- num = (num & ~0xff) + curDrumPitch; //FINDMICH does this work?
- else // dont show drum specific controller if not a drum track
- continue;
- }
-
- if(cll->find(channel, num) == cll->end())
- ctrlSubPop->addAction(MusECore::midiCtrlNumString(num, true) + ci->second->name())->setData(num);
- }
-
- // Don't allow editing instrument if it's a synth
- if(!port->device() || port->device()->deviceType() != MusECore::MidiDevice::SYNTH_MIDI)
- ctrlSubPop->addAction(QIcon(*midi_edit_instrumentIcon), tr("Edit instrument ..."))->setData(edit_ins);
-
- QAction *act2 = ctrlSubPop->exec(ctrl->mapToGlobal(QPoint(0,0)));
- if (act2)
- {
- int rv2 = act2->data().toInt();
-
- if (rv2 == edit_ins) // edit instrument
- MusEGlobal::muse->startEditInstrument();
- else // select new instrument control
- {
- MusECore::MidiController* c;
- for (MusECore::iMidiController ci = mcl->begin(); ci != mcl->end(); ++ci)
- {
- c = ci->second;
- int num = c->num();
- if (isDrum && ((num & 0xff) == 0xff) && curDrumPitch!=-1)
- num = (num & ~0xff) + MusEGlobal::drumMap[curDrumPitch].anote;
- else if (isNewDrum && ((num & 0xff) == 0xff) && curDrumPitch!=-1)
- num = (num & ~0xff) + curDrumPitch; //FINDMICHJETZT does this work?
-
- if(num != rv2)
- continue;
-
- if(cll->find(channel, num) == cll->end())
- {
- MusECore::MidiCtrlValList* vl = new MusECore::MidiCtrlValList(num);
-
- cll->add(channel, vl);
- newCtlNum = c->num();
- }
- else
- newCtlNum = c->num();
- break;
- }
- }
- }
- delete ctrlSubPop;
- }
-
- //else if (rv == edit_ins) // edit instrument
- // MusEGlobal::muse->startEditInstrument();
-
- else if (rv == add_other) { // add new other controller
- PopupMenu* ctrlSubPop = new PopupMenu(this, true); // true = enable stay open
- ctrlSubPop->addAction(new MenuTitleItem(tr("Common Controls"), ctrlSubPop));
-
- for(int num = 0; num < 127; ++num)
- if(cll->find(channel, num) == cll->end())
- ctrlSubPop->addAction(MusECore::midiCtrlName(num, true))->setData(num);
- QAction *act2 = ctrlSubPop->exec(ctrl->mapToGlobal(QPoint(0,0)));
- if (act2) {
- int rv2 = act2->data().toInt();
- int num = rv2;
- if (isDrum && ((num & 0xff) == 0xff) && curDrumPitch!=-1)
- num = (num & ~0xff) + MusEGlobal::drumMap[curDrumPitch].anote;
- if (isNewDrum && ((num & 0xff) == 0xff) && curDrumPitch!=-1)
- num = (num & ~0xff) + curDrumPitch; //FINDMICHJETZT does this work?
-
- if(cll->find(channel, num) == cll->end())
- {
- MusECore::MidiCtrlValList* vl = new MusECore::MidiCtrlValList(num);
-
- cll->add(channel, vl);
- newCtlNum = rv2;
- }
- else
- newCtlNum = rv2;
- }
- delete ctrlSubPop;
+ else if (rv == edit_ins) { // edit instrument
+ MusECore::MidiInstrument* instr = port->instrument();
+ MusEGlobal::muse->startEditInstrument(instr ? instr->iname() : QString(), EditInstrument::Controllers);
}
else { // Select a control
- MusECore::iMidiCtrlValList i = cll->begin();
- for (; i != cll->end(); ++i) {
- MusECore::MidiCtrlValList* cl = i->second;
- MusECore::MidiController* c = port->midiController(cl->num());
- if (c->num() == rv) {
- newCtlNum = c->num();
- break;
- }
- }
- if (i == cll->end()) {
- printf("DrumEdit: controller number %d not found!", rv);
- }
- }
+ if(cll->find(channel, rv) == cll->end())
+ cll->add(channel, new MusECore::MidiCtrlValList(rv));
+ newCtlNum = rv;
+ if(port->drumController(rv))
+ newCtlNum |= 0xff;
+ }
if(newCtlNum != -1)
{
diff --git a/muse2/muse/midiedit/pianoroll.cpp b/muse2/muse/midiedit/pianoroll.cpp
index 97c5ecc3..e4064bd9 100644
--- a/muse2/muse/midiedit/pianoroll.cpp
+++ b/muse2/muse/midiedit/pianoroll.cpp
@@ -64,6 +64,7 @@
#include "helper.h"
#include "popupmenu.h"
#include "menutitleitem.h"
+#include "editinstrument.h"
#include "cmd.h"
@@ -813,141 +814,27 @@ void PianoRoll::ctrlPopupTriggered(QAction* act)
MusECore::MidiTrack* track = (MusECore::MidiTrack*)(part->track());
int channel = track->outChannel();
MusECore::MidiPort* port = &MusEGlobal::midiPorts[track->outPort()];
- int curPitch = curDrumInstrument();
- MusECore::MidiInstrument* instr = port->instrument();
- MusECore::MidiControllerList* mcl = instr->controller();
-
MusECore::MidiCtrlValListList* cll = port->controller();
const int min = channel << 24;
const int max = min + 0x1000000;
-
- const int add_ins_def = max + 1;
- const int add_other = max + 2;
const int edit_ins = max + 3;
-
const int velo = max + 0x101;
-
int rv = act->data().toInt();
if (rv == velo) { // special case velocity
newCtlNum = MusECore::CTRL_VELOCITY;
}
- else if (rv == add_ins_def) { // add new instrument controller
-
- PopupMenu * ctrlSubPop = new PopupMenu(this, true); // true = enable stay open
- ctrlSubPop->addAction(new MenuTitleItem(tr("Instrument-defined"), ctrlSubPop));
-
- //
- // populate popup with all controllers available for
- // current instrument
- //
-
- for (MusECore::iMidiController ci = mcl->begin(); ci != mcl->end(); ++ci)
- {
- int num = ci->second->num();
- if((num & 0xff) == 0xff)
- {
- //if (curPitch!=-1)
- // num = (num & ~0xff) + MusEGlobal::drumMap[curPitch].anote;
- //else
- if(curPitch!=-1)
- num = (num & ~0xff) + curPitch; //FINDMICH does this work?
- else // dont show drum specific controller if not a drum track
- continue;
- }
-
- if(cll->find(channel, num) == cll->end())
- ctrlSubPop->addAction(MusECore::midiCtrlNumString(num, true) + ci->second->name())->setData(num);
- }
-
- // Don't allow editing instrument if it's a synth
- if(!port->device() || port->device()->deviceType() != MusECore::MidiDevice::SYNTH_MIDI)
- ctrlSubPop->addAction(QIcon(*midi_edit_instrumentIcon), tr("Edit instrument ..."))->setData(edit_ins);
-
- QAction *act2 = ctrlSubPop->exec(ctrl->mapToGlobal(QPoint(0,0)));
- if (act2)
- {
- int rv2 = act2->data().toInt();
-
- if (rv2 == edit_ins) // edit instrument
- MusEGlobal::muse->startEditInstrument();
- else // select new instrument control
- {
- MusECore::MidiController* c;
- for (MusECore::iMidiController ci = mcl->begin(); ci != mcl->end(); ++ci)
- {
- c = ci->second;
- int num = c->num();
- //if (((num & 0xff) == 0xff) && curPitch!=-1)
- // num = (num & ~0xff) + MusEGlobal::drumMap[curPitch].anote;
- //else
- if (((num & 0xff) == 0xff) && curPitch!=-1)
- num = (num & ~0xff) + curPitch; //FINDMICHJETZT does this work?
-
- if(num != rv2)
- continue;
-
- if(cll->find(channel, num) == cll->end())
- {
- MusECore::MidiCtrlValList* vl = new MusECore::MidiCtrlValList(num);
-
- cll->add(channel, vl);
- newCtlNum = c->num();
- }
- else
- newCtlNum = c->num();
- break;
- }
- }
- }
- delete ctrlSubPop;
- }
-
- //else if (rv == edit_ins) // edit instrument
- // MusEGlobal::muse->startEditInstrument();
-
- else if (rv == add_other) { // add new other controller
- PopupMenu* ctrlSubPop = new PopupMenu(this, true); // true = enable stay open
- ctrlSubPop->addAction(new MenuTitleItem(tr("Common Controls"), ctrlSubPop));
-
- for(int num = 0; num < 127; ++num)
- if(cll->find(channel, num) == cll->end())
- ctrlSubPop->addAction(MusECore::midiCtrlName(num, true))->setData(num);
- QAction *act2 = ctrlSubPop->exec(ctrl->mapToGlobal(QPoint(0,0)));
- if (act2) {
- int rv2 = act2->data().toInt();
- int num = rv2;
- //if (((num & 0xff) == 0xff) && curPitch!=-1)
- // num = (num & ~0xff) + MusEGlobal::drumMap[curPitch].anote;
- if (((num & 0xff) == 0xff) && curPitch!=-1)
- num = (num & ~0xff) + curPitch; //FINDMICHJETZT does this work?
-
- if(cll->find(channel, num) == cll->end())
- {
- MusECore::MidiCtrlValList* vl = new MusECore::MidiCtrlValList(num);
-
- cll->add(channel, vl);
- newCtlNum = rv2;
- }
- else
- newCtlNum = rv2;
- }
- delete ctrlSubPop;
+ else if (rv == edit_ins) { // edit instrument
+ MusECore::MidiInstrument* instr = port->instrument();
+ MusEGlobal::muse->startEditInstrument(instr ? instr->iname() : QString(), EditInstrument::Controllers);
}
else { // Select a control
- MusECore::iMidiCtrlValList i = cll->begin();
- for (; i != cll->end(); ++i) {
- MusECore::MidiCtrlValList* cl = i->second;
- MusECore::MidiController* c = port->midiController(cl->num());
- if (c->num() == rv) {
- newCtlNum = c->num();
- break;
- }
- }
- if (i == cll->end()) {
- printf("PianoRoll: controller number %d not found!", rv);
- }
- }
+ if(cll->find(channel, rv) == cll->end())
+ cll->add(channel, new MusECore::MidiCtrlValList(rv));
+ newCtlNum = rv;
+ if(port->drumController(rv))
+ newCtlNum |= 0xff;
+ }
if(newCtlNum != -1)
{
diff --git a/muse2/muse/midiport.cpp b/muse2/muse/midiport.cpp
index f7a3d5e3..36b38ae0 100644
--- a/muse2/muse/midiport.cpp
+++ b/muse2/muse/midiport.cpp
@@ -1020,7 +1020,7 @@ MidiController* MidiPort::midiController(int num) const
if (cn == num)
return i->second;
// wildcard?
- if (((cn & 0xff) == 0xff) && ((cn & ~0xff) == (num & ~0xff)))
+ if (i->second->isPerNoteController() && ((cn & ~0xff) == (num & ~0xff)))
return i->second;
}
}
@@ -1030,7 +1030,7 @@ MidiController* MidiPort::midiController(int num) const
if (cn == num)
return i->second;
// wildcard?
- if (((cn & 0xff) == 0xff) && ((cn & ~0xff) == (num & ~0xff)))
+ if (i->second->isPerNoteController() && ((cn & ~0xff) == (num & ~0xff)))
return i->second;
}
diff --git a/muse2/muse/vst.cpp b/muse2/muse/vst.cpp
index 1f03e0ac..60b1983d 100644
--- a/muse2/muse/vst.cpp
+++ b/muse2/muse/vst.cpp
@@ -342,12 +342,12 @@ void jfst_reserve_mem (int bufsize)
void initVST()
{
jfst_reserve_mem(1000000);
-
+
if (fst_init(fstSignalHandler)) {
printf("initVST failed\n");
return;
}
-
+
char* vstPath = getenv("VST_PATH");
if (vstPath == 0)
vstPath = "/usr/lib/vst:/usr/local/lib/vst";
diff --git a/muse2/muse/vst.h b/muse2/muse/vst.h
index 52c45f16..7e693863 100644
--- a/muse2/muse/vst.h
+++ b/muse2/muse/vst.h
@@ -47,7 +47,7 @@ class VstSynth : public Synth {
VstSynth(const QFileInfo& fi) : Synth(fi, fi->baseName()) {
fstHandle = 0;
}
-
+
virtual ~VstSynth() {}
virtual Type synthType() const { return VST_SYNTH; }
virtual void incInstances(int val);
@@ -70,7 +70,7 @@ class VstSynthIF : public SynthIF
_fst = 0;
_guiVisible = false;
}
-
+
virtual bool initGui() { return true; };
virtual void guiHeartBeat() { }
virtual bool guiVisible() const { return false; }
diff --git a/muse2/muse/widgets/midi_audio_control.cpp b/muse2/muse/widgets/midi_audio_control.cpp
index 78c8de3c..17d724ac 100644
--- a/muse2/muse/widgets/midi_audio_control.cpp
+++ b/muse2/muse/widgets/midi_audio_control.cpp
@@ -88,7 +88,7 @@ void MidiAudioControl::heartbeat()
if(MusEGlobal::midiLearnCtrl != -1)
{
- int type = MusECore::midiControllerType(MusEGlobal::midiLearnCtrl);
+ MusECore::MidiController::ControllerType type = MusECore::midiControllerType(MusEGlobal::midiLearnCtrl);
if(type < controlTypeComboBox->count() && type != controlTypeComboBox->currentIndex())
{
controlTypeComboBox->blockSignals(true);
@@ -223,7 +223,7 @@ void MidiAudioControl::ctrlTypeChanged(int idx)
updateCtrlBoxes();
_ctrl = (ctrlHiSpinBox->value() << 8) + ctrlLoSpinBox->value();
- _ctrl = MusECore::midiCtrlTerms2Number(idx, _ctrl);
+ _ctrl = MusECore::midiCtrlTerms2Number(MusECore::MidiController::ControllerType(idx), _ctrl);
resetLearn();
}
@@ -233,7 +233,7 @@ void MidiAudioControl::ctrlHChanged()
if(controlTypeComboBox->currentIndex() == -1)
return;
_ctrl = (ctrlHiSpinBox->value() << 8) + ctrlLoSpinBox->value();
- _ctrl = MusECore::midiCtrlTerms2Number(controlTypeComboBox->currentIndex(), _ctrl);
+ _ctrl = MusECore::midiCtrlTerms2Number(MusECore::MidiController::ControllerType(controlTypeComboBox->currentIndex()), _ctrl);
resetLearn();
}
@@ -243,7 +243,7 @@ void MidiAudioControl::ctrlLChanged()
if(controlTypeComboBox->currentIndex() == -1)
return;
_ctrl = (ctrlHiSpinBox->value() << 8) + ctrlLoSpinBox->value();
- _ctrl = MusECore::midiCtrlTerms2Number(controlTypeComboBox->currentIndex(), _ctrl);
+ _ctrl = MusECore::midiCtrlTerms2Number(MusECore::MidiController::ControllerType(controlTypeComboBox->currentIndex()), _ctrl);
resetLearn();
}
diff --git a/muse2/muse/widgets/warn_bad_timing.ui b/muse2/muse/widgets/warn_bad_timing.ui
index 7c92850f..6f183f37 100644
--- a/muse2/muse/widgets/warn_bad_timing.ui
+++ b/muse2/muse/widgets/warn_bad_timing.ui
@@ -48,7 +48,7 @@
</sizepolicy>
</property>
<property name="text">
- <string>Don't ask me again</string>
+ <string>Don't warn me again</string>
</property>
</widget>
</item>
diff --git a/muse2/share/instruments/Emu-4mbgsgmmt-sf.idf b/muse2/share/instruments/Emu-4mbgsgmmt-sf.idf
index b8b312c9..39aa1be5 100644
--- a/muse2/share/instruments/Emu-4mbgsgmmt-sf.idf
+++ b/muse2/share/instruments/Emu-4mbgsgmmt-sf.idf
@@ -429,11 +429,11 @@
<Controller name="AttackRate" type="NRPN" h="1" l="99" />
<Controller name="DecayRate" type="NRPN" h="1" l="100" />
<Controller name="ReleaseRate" type="NRPN" h="1" l="102" />
- <Controller name="DrumPitchCoarseTune" type="NRPN" h="24" l="pitch" min="-64" max="63" />
- <Controller name="DrumLevel" type="NRPN" h="26" l="pitch" />
- <Controller name="DrumPanpot" type="NRPN" h="28" l="pitch" min="-64" max="63" init="0" />
- <Controller name="DrumReverbSend" type="NRPN" h="29" l="pitch" />
- <Controller name="DrumChorusSend" type="NRPN" h="30" l="pitch" />
+ <Controller name="DrumPitchCoarseTune" type="NRPN" h="24" l="pitch" min="-64" max="63" showType="1" />
+ <Controller name="DrumLevel" type="NRPN" h="26" l="pitch" showType="1" />
+ <Controller name="DrumPanpot" type="NRPN" h="28" l="pitch" min="-64" max="63" init="0" showType="1" />
+ <Controller name="DrumReverbSend" type="NRPN" h="29" l="pitch" showType="1" />
+ <Controller name="DrumChorusSend" type="NRPN" h="30" l="pitch" showType="1" />
<Controller name="Pitch" type="Pitch" />
<Controller name="Program" type="Program" />
</MidiInstrument>
diff --git a/muse2/share/instruments/Roland-E28.idf b/muse2/share/instruments/Roland-E28.idf
index dd96fdd7..5d6d62d8 100644
--- a/muse2/share/instruments/Roland-E28.idf
+++ b/muse2/share/instruments/Roland-E28.idf
@@ -298,11 +298,11 @@
<Controller name="AttackRate" type="NRPN" h="1" l="99" />
<Controller name="DecayRate" type="NRPN" h="1" l="100" />
<Controller name="ReleaseRate" type="NRPN" h="1" l="102" />
- <Controller name="DrumPitchCoarseTune" type="NRPN" h="24" l="pitch" min="-64" max="63" />
- <Controller name="DrumLevel" type="NRPN" h="26" l="pitch" />
- <Controller name="DrumPanpot" type="NRPN" h="28" l="pitch" min="-64" max="63" />
- <Controller name="DrumReverbSend" type="NRPN" h="29" l="pitch" />
- <Controller name="DrumChorusSend" type="NRPN" h="30" l="pitch" />
+ <Controller name="DrumPitchCoarseTune" type="NRPN" h="24" l="pitch" min="-64" max="63" showType="1" />
+ <Controller name="DrumLevel" type="NRPN" h="26" l="pitch" showType="1" />
+ <Controller name="DrumPanpot" type="NRPN" h="28" l="pitch" min="-64" max="63" showType="1" />
+ <Controller name="DrumReverbSend" type="NRPN" h="29" l="pitch" showType="1" />
+ <Controller name="DrumChorusSend" type="NRPN" h="30" l="pitch" showType="1" />
<Controller name="Pitch" type="Pitch" />
<Controller name="Program" type="Program" />
</MidiInstrument>
diff --git a/muse2/share/instruments/Yamaha-CS1x.idf b/muse2/share/instruments/Yamaha-CS1x.idf
index 41e8e16a..1c05f5be 100644
--- a/muse2/share/instruments/Yamaha-CS1x.idf
+++ b/muse2/share/instruments/Yamaha-CS1x.idf
@@ -1565,17 +1565,17 @@
<Controller name="NRPN EG Attack Time" type="NRPN" h="0x01" l="0x63" min="-0x40" max="0x3f" init="0x00" />
<Controller name="NRPN EG Decay Time" type="NRPN" h="0x01" l="0x64" min="-0x40" max="0x3f" init="0x00" />
<Controller name="NRPN EG Release Time" type="NRPN" h="0x01" l="0x66" min="-0x40" max="0x3f" init="0x00" />
- <Controller name="NRPN Drum Cutoff Freq." type="NRPN" h="0x14" l="pitch" min="-0x40" max="0x3f" init="0x00" />
- <Controller name="NRPN Drum Filter Res." type="NRPN" h="0x15" l="pitch" min="-0x40" max="0x3f" init="0x00" />
- <Controller name="NRPN Drum AEG Atk Time" type="NRPN" h="0x16" l="pitch" min="-0x40" max="0x3f" init="0x00" />
- <Controller name="NRPN Drum AEG Dcy Time" type="NRPN" h="0x17" l="pitch" min="-0x40" max="0x3f" init="0x00" />
- <Controller name="NRPN Drum Pitch Coarse" type="NRPN" h="0x18" l="pitch" min="-0x40" max="0x3f" init="0x00" />
- <Controller name="NRPN Drum Pitch Fine" type="NRPN" h="0x19" l="pitch" min="-0x40" max="0x3f" init="0x00" />
- <Controller name="NRPN Drum Level" type="NRPN" h="0x1a" l="pitch" min="0x00" max="0x7f" init="0x64" />
- <Controller name="NRPN Drum Panpot" type="NRPN" h="0x1c" l="pitch" min="-0x40" max="0x3f" init="0x00" />
- <Controller name="NRPN Drum Reverb Send" type="NRPN" h="0x1d" l="pitch" min="0x00" max="0x7f" init="0x28" />
- <Controller name="NRPN Drum Chorus Send" type="NRPN" h="0x1e" l="pitch" min="0x00" max="0x7f" init="0x00" />
- <Controller name="NRPN Drum Var Send" type="NRPN" h="0x1f" l="pitch" min="0x00" max="0x7f" init="0x00" />
+ <Controller name="NRPN Drum Cutoff Freq." type="NRPN" h="0x14" l="pitch" min="-0x40" max="0x3f" init="0x00" showType="1" />
+ <Controller name="NRPN Drum Filter Res." type="NRPN" h="0x15" l="pitch" min="-0x40" max="0x3f" init="0x00" showType="1" />
+ <Controller name="NRPN Drum AEG Atk Time" type="NRPN" h="0x16" l="pitch" min="-0x40" max="0x3f" init="0x00" showType="1" />
+ <Controller name="NRPN Drum AEG Dcy Time" type="NRPN" h="0x17" l="pitch" min="-0x40" max="0x3f" init="0x00" showType="1" />
+ <Controller name="NRPN Drum Pitch Coarse" type="NRPN" h="0x18" l="pitch" min="-0x40" max="0x3f" init="0x00" showType="1" />
+ <Controller name="NRPN Drum Pitch Fine" type="NRPN" h="0x19" l="pitch" min="-0x40" max="0x3f" init="0x00" showType="1" />
+ <Controller name="NRPN Drum Level" type="NRPN" h="0x1a" l="pitch" min="0x00" max="0x7f" init="0x64" showType="1" />
+ <Controller name="NRPN Drum Panpot" type="NRPN" h="0x1c" l="pitch" min="-0x40" max="0x3f" init="0x00" showType="1" />
+ <Controller name="NRPN Drum Reverb Send" type="NRPN" h="0x1d" l="pitch" min="0x00" max="0x7f" init="0x28" showType="1" />
+ <Controller name="NRPN Drum Chorus Send" type="NRPN" h="0x1e" l="pitch" min="0x00" max="0x7f" init="0x00" showType="1" />
+ <Controller name="NRPN Drum Var Send" type="NRPN" h="0x1f" l="pitch" min="0x00" max="0x7f" init="0x00" showType="1" />
<Controller name="RPN Pitch Bend Sens." type="RPN" h="0x00" l="0x00" min="0x00" max="0x18" init="0x02" />
<Controller name="RPN Master Coarse Tune" type="RPN" h="0x00" l="0x02" min="0x28" max="0x58" init="0x40" />
<Controller name="RPN Master Fine Tune" type="RPN14" h="0x00" l="0x01" min="0x0000" max="0x7f7f" init="0x4000" />
diff --git a/muse2/share/instruments/gs.idf b/muse2/share/instruments/gs.idf
index 873cbd18..0e0bca78 100644
--- a/muse2/share/instruments/gs.idf
+++ b/muse2/share/instruments/gs.idf
@@ -223,13 +223,15 @@
<Controller name="AttackRate" type="NRPN" h="1" l="99" />
<Controller name="DecayRate" type="NRPN" h="1" l="100" />
<Controller name="ReleaseRate" type="NRPN" h="1" l="102" />
- <Controller name="DrumPitchCoarseTune" type="NRPN" h="24" l="pitch" min="-64" max="63" />
- <Controller name="DrumLevel" type="NRPN" h="26" l="pitch" />
- <Controller name="DrumPanpot" type="NRPN" h="28" l="pitch" min="-64" max="63" init="0" />
- <Controller name="DrumReverbSend" type="NRPN" h="29" l="pitch" />
- <Controller name="DrumChorusSend" type="NRPN" h="30" l="pitch" />
+ <Controller name="DrumPitchCoarseTune" type="NRPN" h="24" l="pitch" min="-64" max="63" showType="1" />
+ <Controller name="DrumLevel" type="NRPN" h="26" l="pitch" showType="1" />
+ <Controller name="DrumPanpot" type="NRPN" h="28" l="pitch" min="-64" max="63" init="0" showType="1" />
+ <Controller name="DrumReverbSend" type="NRPN" h="29" l="pitch" showType="1" />
+ <Controller name="DrumChorusSend" type="NRPN" h="30" l="pitch" showType="1" />
<Controller name="Pitch" type="Pitch" />
<Controller name="Program" type="Program" />
+ <Controller name="PolyAftertouch" type="PolyAftertouch" />
+ <Controller name="Aftertouch" type="Aftertouch" />
<Drummaps>
<entry>
<patch_collection hbank="127" prog="0-7" />
diff --git a/muse2/share/instruments/xg.idf b/muse2/share/instruments/xg.idf
index 6d597d38..4d169a94 100644
--- a/muse2/share/instruments/xg.idf
+++ b/muse2/share/instruments/xg.idf
@@ -605,19 +605,21 @@
<Controller name="EG AttackTime" type="NRPN" h="1" l="99" />
<Controller name="EG DecayTime" type="NRPN" h="1" l="100" />
<Controller name="EG Release" type="NRPN" h="1" l="102" />
- <Controller name="Drum FilterCutoffFreq" type="NRPN" h="20" l="pitch" />
- <Controller name="Drum FilterResonance" type="NRPN" h="21" l="pitch" />
- <Controller name="Drum EG AttackRate" type="NRPN" h="22" l="pitch" />
- <Controller name="Drum EG DecayRage" type="NRPN" h="23" l="pitch" />
- <Controller name="Drum Pitch Coarse" type="NRPN" h="24" l="pitch" min="-64" max="63" />
- <Controller name="Drum Pitch Fine" type="NRPN" h="25" l="pitch" min="-64" max="63" />
- <Controller name="Drum Level" type="NRPN" h="26" l="pitch" />
- <Controller name="Drum Pan" type="NRPN" h="28" l="pitch" min="-64" max="63" />
- <Controller name="Drum ReverbSendLevel" type="NRPN" h="29" l="pitch" />
- <Controller name="Drum ChorusSendLevel" type="NRPN" h="30" l="pitch" />
- <Controller name="Drum VariationSendLev" type="NRPN" h="31" l="pitch" />
+ <Controller name="Drum FilterCutoffFreq" type="NRPN" h="20" l="pitch" showType="1" />
+ <Controller name="Drum FilterResonance" type="NRPN" h="21" l="pitch" showType="1" />
+ <Controller name="Drum EG AttackRate" type="NRPN" h="22" l="pitch" showType="1" />
+ <Controller name="Drum EG DecayRage" type="NRPN" h="23" l="pitch" showType="1" />
+ <Controller name="Drum Pitch Coarse" type="NRPN" h="24" l="pitch" min="-64" max="63" showType="1" />
+ <Controller name="Drum Pitch Fine" type="NRPN" h="25" l="pitch" min="-64" max="63" showType="1" />
+ <Controller name="Drum Level" type="NRPN" h="26" l="pitch" showType="1" />
+ <Controller name="Drum Pan" type="NRPN" h="28" l="pitch" min="-64" max="63" showType="1" />
+ <Controller name="Drum ReverbSendLevel" type="NRPN" h="29" l="pitch" showType="1" />
+ <Controller name="Drum ChorusSendLevel" type="NRPN" h="30" l="pitch" showType="1" />
+ <Controller name="Drum VariationSendLev" type="NRPN" h="31" l="pitch" showType="1" />
<Controller name="Pitch" type="Pitch" />
<Controller name="Program" type="Program" />
+ <Controller name="PolyAftertouch" type="PolyAftertouch" />
+ <Controller name="Aftertouch" type="Aftertouch" />
<Drummaps>
<entry>
diff --git a/muse2/xpm/reddot.xpm b/muse2/xpm/reddot.xpm
index c094934a..eae182d0 100644
--- a/muse2/xpm/reddot.xpm
+++ b/muse2/xpm/reddot.xpm
@@ -1,17 +1,21 @@
/* XPM */
-static const char *reddot_xpm[]={
-"12 12 2 1",
-". c None",
-"# c #ff5600",
-"...#####....",
-"..#######...",
-".#########..",
-"###########.",
-"###########.",
-"###########.",
-"###########.",
-"###########.",
-".#########..",
-"..#######...",
-"...#####....",
-"............"};
+static const char * reddot_xpm[] = {
+"12 16 2 1",
+" c None",
+". c #FF0000",
+" ",
+" ",
+" ",
+" .. ",
+" .... ",
+" ...... ",
+" ........ ",
+" ........ ",
+" ........ ",
+" ...... ",
+" .... ",
+" .. ",
+" ",
+" ",
+" ",
+" "};