summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim E. Real <termtech@rogers.com>2012-10-27 09:58:29 +0000
committerTim E. Real <termtech@rogers.com>2012-10-27 09:58:29 +0000
commitb1776f093d4b87ad2635990f429f4503157f6288 (patch)
treea18bcc5e23674d74037c87e0541f9feefdc7b9ca
parentb297348e8e2cd76be6f1d546fb458865cc4d263b (diff)
Improved: Velocity graphs. Icon for showing per-note or all velocities. Also found in Settings.
Improved: Piano KB has current selected note (yellow). For velocity/polyaftertouch/other per-note ctrls. Bad timing warning now has "don't show again". Added 'speaker' icon to drum edit. And drum list and piano keyboard now obey the 'speaker' icon.
-rw-r--r--muse2/ChangeLog6
-rw-r--r--muse2/muse/arranger/tlist.cpp355
-rw-r--r--muse2/muse/conf.cpp6
-rw-r--r--muse2/muse/ctrl/ctrlcanvas.cpp42
-rw-r--r--muse2/muse/ctrl/ctrlpanel.cpp79
-rw-r--r--muse2/muse/ctrl/ctrlpanel.h9
-rw-r--r--muse2/muse/driver/alsamidi.cpp5
-rw-r--r--muse2/muse/driver/jackmidi.cpp8
-rw-r--r--muse2/muse/gconfig.cpp4
-rw-r--r--muse2/muse/gconfig.h2
-rw-r--r--muse2/muse/helper.cpp14
-rw-r--r--muse2/muse/icons.cpp8
-rw-r--r--muse2/muse/icons.h2
-rw-r--r--muse2/muse/midictrl.cpp31
-rw-r--r--muse2/muse/midictrl.h12
-rw-r--r--muse2/muse/mididev.cpp3
-rw-r--r--muse2/muse/midiedit/dcanvas.cpp15
-rw-r--r--muse2/muse/midiedit/dlist.cpp9
-rw-r--r--muse2/muse/midiedit/dlist.h2
-rw-r--r--muse2/muse/midiedit/drumedit.cpp37
-rw-r--r--muse2/muse/midiedit/drumedit.h3
-rw-r--r--muse2/muse/midiedit/piano.cpp265
-rw-r--r--muse2/muse/midiedit/piano.h17
-rw-r--r--muse2/muse/midiedit/pianoroll.cpp59
-rw-r--r--muse2/muse/midiedit/pianoroll.h2
-rw-r--r--muse2/muse/midiedit/prcanvas.cpp14
-rw-r--r--muse2/muse/midiport.cpp2
-rw-r--r--muse2/muse/midiseq.cpp23
-rw-r--r--muse2/muse/widgets/CMakeLists.txt3
-rw-r--r--muse2/muse/widgets/genset.cpp4
-rw-r--r--muse2/muse/widgets/gensetbase.ui91
-rw-r--r--muse2/muse/widgets/midi_warn_init_pending_impl.h2
-rw-r--r--muse2/muse/widgets/musewidgetsplug.cpp4
-rw-r--r--muse2/muse/widgets/warn_bad_timing.cpp33
-rw-r--r--muse2/muse/widgets/warn_bad_timing.h41
-rw-r--r--muse2/muse/widgets/warn_bad_timing.ui111
-rw-r--r--muse2/share/instruments/gm.idf2
-rw-r--r--muse2/share/templates/MusE.cfg7
-rw-r--r--muse2/xpm/velo_all.xpm23
-rw-r--r--muse2/xpm/velo_per_note.xpm25
40 files changed, 974 insertions, 406 deletions
diff --git a/muse2/ChangeLog b/muse2/ChangeLog
index dca54595..f8c4da81 100644
--- a/muse2/ChangeLog
+++ b/muse2/ChangeLog
@@ -1,3 +1,9 @@
+27.10.2012:
+ * Improved: Velocity graphs. Icon for showing per-note or all velocities. Also found in Settings. (Tim)
+ * Improved: Piano KB has current selected note (yellow). For velocity/polyaftertouch/other per-note ctrls. (Tim)
+ - Bad timing warning now has "don't show again". (Tim)
+ - Added 'speaker' icon to drum edit. And drum list and piano keyboard now obey the 'speaker' icon. (Tim)
+ - TODO: Still W.I.P on the aftertouch stuff...
22.10.2012:
- Oops, fixed regression: Re-add default managed controllers to midi ports at Song::clear. (Tim)
- W.I.P. Preparations for Aftertouch and Poly Aftertouch (channel and key pressure) graph editing. (Tim)
diff --git a/muse2/muse/arranger/tlist.cpp b/muse2/muse/arranger/tlist.cpp
index b3be35ea..3bc13934 100644
--- a/muse2/muse/arranger/tlist.cpp
+++ b/muse2/muse/arranger/tlist.cpp
@@ -2497,181 +2497,186 @@ void TList::mouseReleaseEvent(QMouseEvent* ev)
void TList::wheelEvent(QWheelEvent* ev)
{
- int x = ev->x();
- int y = ev->y();
- MusECore::Track* t = y2Track(y + ypos);
- if (t == 0) {
- emit redirectWheelEvent(ev);
- return;
- }
- TrackColumn col = TrackColumn(header->logicalIndexAt(x));
- int delta = ev->delta() / WHEEL_DELTA;
- ev->accept();
-
- switch (col) {
- case COL_RECORD:
- case COL_NONE:
- case COL_CLASS:
- case COL_NAME:
- case COL_AUTOMATION:
- break;
- case COL_MUTE:
- // p3.3.29
- if (((QInputEvent*)ev)->modifiers() & Qt::ShiftModifier)
- t->setOff(!t->off());
- else
- {
- if (t->off())
- t->setOff(false);
- else
- t->setMute(!t->mute());
- }
- MusEGlobal::song->update(SC_MUTE);
- break;
-
- case COL_SOLO:
- MusEGlobal::audio->msgSetSolo(t, !t->solo());
- MusEGlobal::song->update(SC_SOLO);
- break;
-
- case COL_TIMELOCK:
- t->setLocked(!t->locked());
- break;
-
- case COL_OPORT:
- if (t->isMidiTrack()) {
- MusECore::MidiTrack* mt = (MusECore::MidiTrack*)t;
- int port = mt->outPort() + delta;
-
- if (port >= MIDI_PORTS)
- port = MIDI_PORTS-1;
- else if (port < 0)
- port = 0;
- if (port != ((MusECore::MidiTrack*)t)->outPort()) {
- MusEGlobal::audio->msgIdle(true);
- mt->setOutPortAndUpdate(port);
- MusEGlobal::audio->msgIdle(false);
-
- MusEGlobal::audio->msgUpdateSoloStates(); // p4.0.14
- MusEGlobal::song->update(SC_MIDI_TRACK_PROP); // p4.0.17
- }
- }
- break;
-
- case COL_OCHANNEL:
- if (t->isMidiTrack()) {
- MusECore::MidiTrack* mt = (MusECore::MidiTrack*)t;
- if (mt && mt->type() == MusECore::Track::DRUM)
- break;
-
- int channel = mt->outChannel() + delta;
-
- if (channel >= MIDI_CHANNELS)
- channel = MIDI_CHANNELS-1;
- else if (channel < 0)
- channel = 0;
- if (channel != ((MusECore::MidiTrack*)t)->outChannel()) {
- MusEGlobal::audio->msgIdle(true);
- mt->setOutChanAndUpdate(channel);
- MusEGlobal::audio->msgIdle(false);
-
- // may result in adding/removing mixer strip:
- //MusEGlobal::song->update(-1);
- MusEGlobal::audio->msgUpdateSoloStates(); // p4.0.14
- MusEGlobal::song->update(SC_MIDI_TRACK_PROP);
- }
- }
- else {
- int n = t->channels() + delta;
- if (n > MAX_CHANNELS)
- n = MAX_CHANNELS;
- else if (n < 1)
- n = 1;
- if (n != t->channels()) {
- MusEGlobal::audio->msgSetChannels((MusECore::AudioTrack*)t, n);
- MusEGlobal::song->update(SC_CHANNELS);
- }
- }
- break;
- default:
- if (col>=COL_CUSTOM_MIDICTRL_OFFSET)
- {
- mode = START_DRAG;
-
- if (t->isMidiTrack())
- {
- MusECore::MidiTrack* mt = dynamic_cast<MusECore::MidiTrack*>(t);
- if (mt == 0)
- break;
-
- int ctrl_num = Arranger::custom_columns[col-COL_CUSTOM_MIDICTRL_OFFSET].ctrl;
-
- MusECore::MidiPort* mp = &MusEGlobal::midiPorts[mt->outPort()];
- MusECore::MidiController* mctl = mp->midiController(ctrl_num);
-
- int minval=mctl->minVal()+mctl->bias();
- int maxval=mctl->maxVal()+mctl->bias();
-
- int val = mt->getControllerChangeAtTick(0,ctrl_num);
- int oldval=val;
-
- if (ctrl_num!=MusECore::CTRL_PROGRAM)
- {
- val += delta;
- if(val > maxval)
- val = maxval;
- if(val < minval-1) // "-1" because of "off"
- val = minval-1;
- }
- else
- {
- MusECore::MidiInstrument* instr = mp->instrument();
- if (delta>0) val=instr->getNextPatch(mt->outChannel(), val, false);
- else if (delta<0) val=instr->getPrevPatch(mt->outChannel(), val, false);
- }
-
- if (val != oldval)
- {
- if (val!=minval-1)
- {
- int at_tick;
- if (Arranger::custom_columns[col-COL_CUSTOM_MIDICTRL_OFFSET].affected_pos ==
- Arranger::custom_col_t::AFFECT_BEGIN)
- at_tick=0;
- else
- at_tick=MusEGlobal::song->cpos();
-
- record_controller_change_and_maybe_send(at_tick, ctrl_num, val, mt);
- }
- else
- {
- MusECore::Undo operations;
- for (MusECore::iPart p = mt->parts()->begin(); p!=mt->parts()->end(); p++)
- {
- if (p->second->tick()==0)
- {
- for (MusECore::iEvent ev=p->second->events()->begin(); ev!=p->second->events()->end(); ev++)
- {
- if (ev->second.tick()!=0) break;
- else if (ev->second.type()==MusECore::Controller && ev->second.dataA()==ctrl_num)
- {
- using MusECore::UndoOp;
- operations.push_back(UndoOp(UndoOp::DeleteEvent, ev->second, p->second, false, false));
- break;
- }
- }
- }
- }
- MusEGlobal::song->applyOperationGroup(operations);
- }
- }
- }
- }
- else
- mode = START_DRAG;
-
- break;
- }
+ emit redirectWheelEvent(ev);
+
+// REMOVE Tim. Hate to just kill all this, so remove later if all tests OK.
+// int x = ev->x();
+// int y = ev->y();
+// MusECore::Track* t = y2Track(y + ypos);
+// if (t == 0) {
+// emit redirectWheelEvent(ev);
+// return;
+// }
+//
+// TrackColumn col = TrackColumn(header->logicalIndexAt(x));
+// int delta = ev->delta() / WHEEL_DELTA;
+// ev->accept();
+//
+// switch (col) {
+// case COL_RECORD:
+// case COL_NONE:
+// case COL_CLASS:
+// case COL_NAME:
+// case COL_AUTOMATION:
+// break;
+// case COL_MUTE:
+// // p3.3.29
+// if (((QInputEvent*)ev)->modifiers() & Qt::ShiftModifier)
+// t->setOff(!t->off());
+// else
+// {
+// if (t->off())
+// t->setOff(false);
+// else
+// t->setMute(!t->mute());
+// }
+// MusEGlobal::song->update(SC_MUTE);
+// break;
+//
+// case COL_SOLO:
+// MusEGlobal::audio->msgSetSolo(t, !t->solo());
+// MusEGlobal::song->update(SC_SOLO);
+// break;
+//
+// case COL_TIMELOCK:
+// t->setLocked(!t->locked());
+// break;
+//
+// case COL_OPORT:
+// if (t->isMidiTrack()) {
+// MusECore::MidiTrack* mt = (MusECore::MidiTrack*)t;
+// int port = mt->outPort() + delta;
+//
+// if (port >= MIDI_PORTS)
+// port = MIDI_PORTS-1;
+// else if (port < 0)
+// port = 0;
+// if (port != ((MusECore::MidiTrack*)t)->outPort()) {
+// MusEGlobal::audio->msgIdle(true);
+// mt->setOutPortAndUpdate(port);
+// MusEGlobal::audio->msgIdle(false);
+//
+// MusEGlobal::audio->msgUpdateSoloStates(); // p4.0.14
+// MusEGlobal::song->update(SC_MIDI_TRACK_PROP); // p4.0.17
+// }
+// }
+// break;
+//
+// case COL_OCHANNEL:
+// if (t->isMidiTrack()) {
+// MusECore::MidiTrack* mt = (MusECore::MidiTrack*)t;
+// if (mt && mt->type() == MusECore::Track::DRUM)
+// break;
+//
+// int channel = mt->outChannel() + delta;
+//
+// if (channel >= MIDI_CHANNELS)
+// channel = MIDI_CHANNELS-1;
+// else if (channel < 0)
+// channel = 0;
+// if (channel != ((MusECore::MidiTrack*)t)->outChannel()) {
+// MusEGlobal::audio->msgIdle(true);
+// mt->setOutChanAndUpdate(channel);
+// MusEGlobal::audio->msgIdle(false);
+//
+// // may result in adding/removing mixer strip:
+// //MusEGlobal::song->update(-1);
+// MusEGlobal::audio->msgUpdateSoloStates(); // p4.0.14
+// MusEGlobal::song->update(SC_MIDI_TRACK_PROP);
+// }
+// }
+// else {
+// int n = t->channels() + delta;
+// if (n > MAX_CHANNELS)
+// n = MAX_CHANNELS;
+// else if (n < 1)
+// n = 1;
+// if (n != t->channels()) {
+// MusEGlobal::audio->msgSetChannels((MusECore::AudioTrack*)t, n);
+// MusEGlobal::song->update(SC_CHANNELS);
+// }
+// }
+// break;
+// default:
+// if (col>=COL_CUSTOM_MIDICTRL_OFFSET)
+// {
+// mode = START_DRAG;
+//
+// if (t->isMidiTrack())
+// {
+// MusECore::MidiTrack* mt = dynamic_cast<MusECore::MidiTrack*>(t);
+// if (mt == 0)
+// break;
+//
+// int ctrl_num = Arranger::custom_columns[col-COL_CUSTOM_MIDICTRL_OFFSET].ctrl;
+//
+// MusECore::MidiPort* mp = &MusEGlobal::midiPorts[mt->outPort()];
+// MusECore::MidiController* mctl = mp->midiController(ctrl_num);
+//
+// int minval=mctl->minVal()+mctl->bias();
+// int maxval=mctl->maxVal()+mctl->bias();
+//
+// int val = mt->getControllerChangeAtTick(0,ctrl_num);
+// int oldval=val;
+//
+// if (ctrl_num!=MusECore::CTRL_PROGRAM)
+// {
+// val += delta;
+// if(val > maxval)
+// val = maxval;
+// if(val < minval-1) // "-1" because of "off"
+// val = minval-1;
+// }
+// else
+// {
+// MusECore::MidiInstrument* instr = mp->instrument();
+// if (delta>0) val=instr->getNextPatch(mt->outChannel(), val, false);
+// else if (delta<0) val=instr->getPrevPatch(mt->outChannel(), val, false);
+// }
+//
+// if (val != oldval)
+// {
+// if (val!=minval-1)
+// {
+// int at_tick;
+// if (Arranger::custom_columns[col-COL_CUSTOM_MIDICTRL_OFFSET].affected_pos ==
+// Arranger::custom_col_t::AFFECT_BEGIN)
+// at_tick=0;
+// else
+// at_tick=MusEGlobal::song->cpos();
+//
+// record_controller_change_and_maybe_send(at_tick, ctrl_num, val, mt);
+// }
+// else
+// {
+// MusECore::Undo operations;
+// for (MusECore::iPart p = mt->parts()->begin(); p!=mt->parts()->end(); p++)
+// {
+// if (p->second->tick()==0)
+// {
+// for (MusECore::iEvent ev=p->second->events()->begin(); ev!=p->second->events()->end(); ev++)
+// {
+// if (ev->second.tick()!=0) break;
+// else if (ev->second.type()==MusECore::Controller && ev->second.dataA()==ctrl_num)
+// {
+// using MusECore::UndoOp;
+// operations.push_back(UndoOp(UndoOp::DeleteEvent, ev->second, p->second, false, false));
+// break;
+// }
+// }
+// }
+// }
+// MusEGlobal::song->applyOperationGroup(operations);
+// }
+// }
+// }
+// }
+// else
+// mode = START_DRAG;
+//
+// break;
+// }
+
}
diff --git a/muse2/muse/conf.cpp b/muse2/muse/conf.cpp
index 4c14cff0..54a02265 100644
--- a/muse2/muse/conf.cpp
+++ b/muse2/muse/conf.cpp
@@ -894,6 +894,8 @@ void readConfiguration(Xml& xml, bool doReadMidiPortConfig, bool doReadGlobalCon
MusEGlobal::config.warnInitPending = xml.parseInt();
else if (tag == "midiSendCtlDefaults")
MusEGlobal::config.midiSendCtlDefaults = xml.parseInt();
+ else if (tag == "warnIfBadTiming")
+ MusEGlobal::config.warnIfBadTiming = xml.parseInt();
else if (tag == "minMeter")
MusEGlobal::config.minMeter = xml.parseInt();
else if (tag == "minSlider")
@@ -946,6 +948,8 @@ void readConfiguration(Xml& xml, bool doReadMidiPortConfig, bool doReadGlobalCon
MusEGlobal::config.unhideTracks = xml.parseInt();
else if (tag == "smartFocus")
MusEGlobal::config.smartFocus = xml.parseInt();
+ else if (tag == "velocityPerNote")
+ MusEGlobal::config.velocityPerNote = xml.parseInt();
else if (tag == "plugin_groups")
MusEGlobal::readPluginGroupConfiguration(xml);
@@ -1215,6 +1219,7 @@ void MusE::writeGlobalConfiguration(int level, MusECore::Xml& xml) const
xml.intTag(level, "midiSendInit", MusEGlobal::config.midiSendInit);
xml.intTag(level, "warnInitPending", MusEGlobal::config.warnInitPending);
xml.intTag(level, "midiSendCtlDefaults", MusEGlobal::config.midiSendCtlDefaults);
+ xml.intTag(level, "warnIfBadTiming", MusEGlobal::config.warnIfBadTiming);
xml.intTag(level, "minMeter", MusEGlobal::config.minMeter);
xml.doubleTag(level, "minSlider", MusEGlobal::config.minSlider);
xml.intTag(level, "freewheelMode", MusEGlobal::config.freewheelMode);
@@ -1266,6 +1271,7 @@ void MusE::writeGlobalConfiguration(int level, MusECore::Xml& xml) const
xml.intTag(level, "leftMouseButtonCanDecrease", MusEGlobal::config.leftMouseButtonCanDecrease);
xml.intTag(level, "rangeMarkerWithoutMMB", MusEGlobal::config.rangeMarkerWithoutMMB);
xml.intTag(level, "smartFocus", MusEGlobal::config.smartFocus);
+ xml.intTag(level, "velocityPerNote", MusEGlobal::config.velocityPerNote);
xml.intTag(level, "unhideTracks", MusEGlobal::config.unhideTracks);
xml.intTag(level, "addHiddenTracks", MusEGlobal::config.addHiddenTracks);
diff --git a/muse2/muse/ctrl/ctrlcanvas.cpp b/muse2/muse/ctrl/ctrlcanvas.cpp
index 1774174f..6e92f3c6 100644
--- a/muse2/muse/ctrl/ctrlcanvas.cpp
+++ b/muse2/muse/ctrl/ctrlcanvas.cpp
@@ -511,16 +511,14 @@ void CtrlCanvas::partControllers(const MusECore::MidiPart* part, int num, int* d
int di;
int n;
- if(!mt->isDrumTrack() && curDrumPitch != -1)
- printf("keyfilter != -1 in non drum track?\n");
-
if((mt->type() == MusECore::Track::DRUM) && (curDrumPitch >= 0) && ((num & 0xff) == 0xff))
{
di = (num & ~0xff) | curDrumPitch;
n = (num & ~0xff) | MusEGlobal::drumMap[curDrumPitch].anote; // construct real controller number
mp = &MusEGlobal::midiPorts[MusEGlobal::drumMap[curDrumPitch].port];
}
- else if ((mt->type() == MusECore::Track::NEW_DRUM) && (curDrumPitch >= 0) && ((num & 0xff) == 0xff)) //FINDMICHJETZT does this work?
+ else if ((mt->type() == MusECore::Track::NEW_DRUM || mt->type() == MusECore::Track::MIDI) &&
+ (curDrumPitch >= 0) && ((num & 0xff) == 0xff)) //FINDMICHJETZT does this work?
{
di = (num & ~0xff) | curDrumPitch;
n = (num & ~0xff) | curDrumPitch;
@@ -599,12 +597,8 @@ void CtrlCanvas::updateItems()
if(_cnum == MusECore::CTRL_VELOCITY && e.type() == MusECore::Note)
{
newev = 0;
- if (curDrumPitch == -1) // and NOT >=0
- {
- // This is interesting - it would allow ALL drum note velocities to be shown.
- // But currently the drum list ALWAYS has a selected item so this is not supposed to happen.
+ if (curDrumPitch == -1 || !MusEGlobal::config.velocityPerNote) // and NOT >=0
items.add(newev = new CEvent(e, part, e.velo()));
- }
else if (e.dataA() == curDrumPitch) //same note. if curDrumPitch==-2, this never is true
items.add(newev = new CEvent(e, part, e.velo()));
if(newev && e.selected())
@@ -615,32 +609,16 @@ void CtrlCanvas::updateItems()
int ctl = e.dataA();
if(part->track() && part->track()->type() == MusECore::Track::DRUM && (_cnum & 0xff) == 0xff)
{
- //MusECore::MidiPort* port = &MusEGlobal::midiPorts[part->track()->outPort()];
if(curDrumPitch < 0)
- //if(curDrumPitch >= 0)
continue;
- //{
- //MusECore::MidiPort* port = &MusEGlobal::midiPorts[MusEGlobal::drumMap[curDrumPitch].port];
- //MusECore::MidiPort* port = &MusEGlobal::midiPorts[MusEGlobal::drumMap[ctl & 0x7f].port];
- int port = MusEGlobal::drumMap[ctl & 0x7f].port;
- int chan = MusEGlobal::drumMap[ctl & 0x7f].channel;
- //MusECore::MidiPort* cur_port = &MusEGlobal::midiPorts[MusEGlobal::drumMap[curDrumPitch].port];
- int cur_port = MusEGlobal::drumMap[curDrumPitch].port;
- int cur_chan = MusEGlobal::drumMap[curDrumPitch].channel;
- if((port != cur_port) || (chan != cur_chan))
- continue;
- // Is it a drum controller event, according to the track port's instrument?
- //MusECore::MidiController *mc = port->drumController(ctl);
- //if(!mc)
- // continue;
- //if(mc)
- //{
- //if(MusEGlobal::drumMap[ctl & 0x7f].channel != e.
- // continue;
- ctl = (ctl & ~0xff) | MusEGlobal::drumMap[ctl & 0x7f].anote;
- //}
- //}
+ int port = MusEGlobal::drumMap[ctl & 0x7f].port;
+ int chan = MusEGlobal::drumMap[ctl & 0x7f].channel;
+ int cur_port = MusEGlobal::drumMap[curDrumPitch].port;
+ int cur_chan = MusEGlobal::drumMap[curDrumPitch].channel;
+ if((port != cur_port) || (chan != cur_chan))
+ continue;
+ ctl = (ctl & ~0xff) | MusEGlobal::drumMap[ctl & 0x7f].anote;
}
if(ctl == _dnum)
{
diff --git a/muse2/muse/ctrl/ctrlpanel.cpp b/muse2/muse/ctrl/ctrlpanel.cpp
index c6adc778..8e380356 100644
--- a/muse2/muse/ctrl/ctrlpanel.cpp
+++ b/muse2/muse/ctrl/ctrlpanel.cpp
@@ -57,6 +57,7 @@
#include "menutitleitem.h"
#include "popupmenu.h"
#include "helper.h"
+#include "pixmap_button.h"
namespace MusEGui {
@@ -87,7 +88,7 @@ CtrlPanel::CtrlPanel(QWidget* parent, MidiEditor* e, CtrlCanvas* c, const char*
kbox->setContentsMargins(0, 0, 0, 0);
dbox->setContentsMargins(0, 0, 0, 0);
- selCtrl = new QPushButton(tr("S"));
+ selCtrl = new QPushButton(tr("S"), this);
selCtrl->setFocusPolicy(Qt::NoFocus);
selCtrl->setFont(MusEGlobal::config.fonts[3]);
selCtrl->setFixedHeight(20);
@@ -96,7 +97,7 @@ CtrlPanel::CtrlPanel(QWidget* parent, MidiEditor* e, CtrlCanvas* c, const char*
selCtrl->setToolTip(tr("select controller"));
// destroy button
- QPushButton* destroy = new QPushButton(tr("X"));
+ QPushButton* destroy = new QPushButton(tr("X"), this);
destroy->setFocusPolicy(Qt::NoFocus);
destroy->setFont(MusEGlobal::config.fonts[3]);
destroy->setFixedHeight(20);
@@ -112,7 +113,7 @@ CtrlPanel::CtrlPanel(QWidget* parent, MidiEditor* e, CtrlCanvas* c, const char*
_val = MusECore::CTRL_VAL_UNKNOWN;
_dnum = -1;
- _knob = new MusEGui::Knob;
+ _knob = new Knob(this);
_knob->setFixedWidth(25);
_knob->setFixedHeight(25);
_knob->setToolTip(tr("manual adjust"));
@@ -122,7 +123,7 @@ CtrlPanel::CtrlPanel(QWidget* parent, MidiEditor* e, CtrlCanvas* c, const char*
_knob->hide();
_knob->setAltFaceColor(Qt::red);
- _dl = new MusEGui::DoubleLabel(-1.0, 0.0, +127.0);
+ _dl = new DoubleLabel(-1.0, 0.0, +127.0, this);
_dl->setPrecision(0);
_dl->setToolTip(tr("ctrl-double-click on/off"));
_dl->setSpecialText(tr("off"));
@@ -139,16 +140,28 @@ CtrlPanel::CtrlPanel(QWidget* parent, MidiEditor* e, CtrlCanvas* c, const char*
connect(_dl, SIGNAL(valueChanged(double,int)), SLOT(ctrlChanged(double)));
connect(_dl, SIGNAL(ctrlDoubleClicked(int)), SLOT(labelDoubleClicked()));
+ _veloPerNoteButton = new PixmapButton(veloPerNote_OnIcon, veloPerNote_OffIcon, 2, this); // Margin = 2
+ _veloPerNoteButton->setFocusPolicy(Qt::NoFocus);
+ _veloPerNoteButton->setCheckable(true);
+ _veloPerNoteButton->setToolTip(tr("all/per-note velocity mode"));
+ _veloPerNoteButton->setEnabled(false);
+ _veloPerNoteButton->hide();
+ connect(_veloPerNoteButton, SIGNAL(clicked()), SLOT(velPerNoteClicked()));
+
bbox->addStretch();
bbox->addWidget(selCtrl);
bbox->addWidget(destroy);
bbox->addStretch();
kbox->addStretch();
kbox->addWidget(_knob);
+ kbox->addWidget(_veloPerNoteButton);
kbox->addStretch();
dbox->addStretch();
dbox->addWidget(_dl);
dbox->addStretch();
+
+ connect(MusEGlobal::song, SIGNAL(songChanged(MusECore::SongChangedFlags_t)), SLOT(songChanged(MusECore::SongChangedFlags_t)));
+ connect(MusEGlobal::muse, SIGNAL(configChanged()), SLOT(configChanged()));
connect(MusEGlobal::heartBeatTimer, SIGNAL(timeout()), SLOT(heartBeat()));
inHeartBeat = false;
setLayout(vbox);
@@ -227,6 +240,35 @@ void CtrlPanel::heartBeat()
}
//---------------------------------------------------------
+// configChanged
+//---------------------------------------------------------
+
+void CtrlPanel::configChanged()
+{
+ songChanged(SC_CONFIG);
+}
+
+//---------------------------------------------------------
+// songChanged
+//---------------------------------------------------------
+
+void CtrlPanel::songChanged(MusECore::SongChangedFlags_t type)
+{
+ if(editor->deleting()) // Ignore while while deleting to prevent crash.
+ return;
+
+ // Is it simply a midi controller value adjustment? Forget it.
+ if(type == SC_MIDI_CONTROLLER)
+ return;
+
+ if(type & SC_CONFIG)
+ {
+ if(_veloPerNoteButton->isChecked() != MusEGlobal::config.velocityPerNote)
+ _veloPerNoteButton->setChecked(MusEGlobal::config.velocityPerNote);
+ }
+}
+
+//---------------------------------------------------------
// labelDoubleClicked
//---------------------------------------------------------
@@ -424,7 +466,7 @@ void CtrlPanel::setHWController(MusECore::MidiTrack* t, MusECore::MidiController
mp = &MusEGlobal::midiPorts[MusEGlobal::drumMap[cdp].port];
ch = MusEGlobal::drumMap[cdp].channel;
}
- else if(_track->type() == MusECore::Track::NEW_DRUM && ((_dnum & 0xff) == 0xff) && cdp != -1)
+ else if((_track->type() == MusECore::Track::NEW_DRUM || _track->type() == MusECore::Track::MIDI) && ((_dnum & 0xff) == 0xff) && cdp != -1)
{
_dnum = (_dnum & ~0xff) | cdp; //FINDMICHJETZT does that work?
mp = &MusEGlobal::midiPorts[_track->outPort()];
@@ -442,11 +484,15 @@ void CtrlPanel::setHWController(MusECore::MidiTrack* t, MusECore::MidiController
_dl->setEnabled(false);
_knob->hide();
_dl->hide();
+ _veloPerNoteButton->setEnabled(true);
+ _veloPerNoteButton->show();
}
else
{
_knob->setEnabled(true);
_dl->setEnabled(true);
+ _veloPerNoteButton->setEnabled(false);
+ _veloPerNoteButton->hide();
double dlv;
int mn; int mx; int v;
if(_dnum == MusECore::CTRL_PROGRAM)
@@ -573,7 +619,7 @@ void CtrlPanel::ctrlPopupTriggered(QAction* act)
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;
+ bool isNewDrum = (track->type() == MusECore::Track::NEW_DRUM) || (track->type() == MusECore::Track::MIDI);
MusECore::MidiInstrument* instr = port->instrument();
MusECore::MidiControllerList* mcl = instr->controller();
@@ -586,20 +632,12 @@ void CtrlPanel::ctrlPopupTriggered(QAction* act)
const int edit_ins = max + 3;
const int velo = max + 0x101;
- const int polyafter = max + 0x102;
- const int after = max + 0x103;
int rv = act->data().toInt();
if (rv == velo) { // special case velocity
emit controllerChanged(MusECore::CTRL_VELOCITY);
}
- else if (rv == polyafter) { // special case
- emit controllerChanged(MusECore::CTRL_POLYAFTER);
- }
- else if (rv == after) { // special case
- emit controllerChanged(MusECore::CTRL_AFTERTOUCH);
- }
else if (rv == add_ins_def) { // add new instrument controller
PopupMenu * ctrlSubPop = new PopupMenu(this, true); // true = enable stay open
@@ -736,5 +774,18 @@ void CtrlPanel::ctrlRightClicked(const QPoint& p, int /*id*/)
MusEGlobal::song->execMidiAutomationCtlPopup(0, part, p, ctlnum);
}
+//---------------------------------------------------------
+// velPerNoteClicked
+//---------------------------------------------------------
+
+void CtrlPanel::velPerNoteClicked()
+{
+ if(MusEGlobal::config.velocityPerNote != _veloPerNoteButton->isChecked())
+ {
+ MusEGlobal::config.velocityPerNote = _veloPerNoteButton->isChecked();
+ MusEGlobal::muse->changeConfig(false); // Save settings? No, wait till close.
+ }
+}
+
} // namespace MusEGui
diff --git a/muse2/muse/ctrl/ctrlpanel.h b/muse2/muse/ctrl/ctrlpanel.h
index 58b8d8c7..261f982f 100644
--- a/muse2/muse/ctrl/ctrlpanel.h
+++ b/muse2/muse/ctrl/ctrlpanel.h
@@ -25,6 +25,8 @@
#include <QWidget>
+#include "type_defs.h"
+
class QPushButton;
class QAction;
@@ -39,6 +41,7 @@ class DoubleLabel;
class Knob;
class MidiEditor;
class CtrlCanvas;
+class PixmapButton;
//---------------------------------------------------------
// CtrlPanel
@@ -58,8 +61,7 @@ class CtrlPanel: public QWidget {
MusEGui::Knob* _knob;
MusEGui::DoubleLabel* _dl;
int _val;
-
-
+ PixmapButton* _veloPerNoteButton;
signals:
void destroyPanel();
@@ -70,6 +72,9 @@ class CtrlPanel: public QWidget {
void labelDoubleClicked();
void ctrlRightClicked(const QPoint& p, int id);
void ctrlPopupTriggered(QAction* act);
+ void velPerNoteClicked();
+ void songChanged(MusECore::SongChangedFlags_t type);
+ void configChanged();
protected slots:
virtual void heartBeat();
diff --git a/muse2/muse/driver/alsamidi.cpp b/muse2/muse/driver/alsamidi.cpp
index 80595fb0..f140224c 100644
--- a/muse2/muse/driver/alsamidi.cpp
+++ b/muse2/muse/driver/alsamidi.cpp
@@ -327,6 +327,11 @@ bool MidiAlsaDevice::putMidiEvent(const MidiPlayEvent& e)
snd_seq_ev_set_pitchbend(&event, chn, b);
break;
}
+ else if((a | 0xff) == CTRL_POLYAFTER)
+ {
+ snd_seq_ev_set_keypress(&event, chn, a & 0x7f, b & 0x7f);
+ break;
+ }
else if(a == CTRL_AFTERTOUCH)
{
snd_seq_ev_set_chanpress(&event, chn, b);
diff --git a/muse2/muse/driver/jackmidi.cpp b/muse2/muse/driver/jackmidi.cpp
index a088290a..7306b93c 100644
--- a/muse2/muse/driver/jackmidi.cpp
+++ b/muse2/muse/driver/jackmidi.cpp
@@ -846,7 +846,13 @@ bool MidiJackDevice::processEvent(const MidiPlayEvent& event)
}
}
- if(a == CTRL_AFTERTOUCH)
+ if((a | 0xff) == CTRL_POLYAFTER)
+ {
+ //printf("MidiJackDevice::processEvent CTRL_AFTERTOUCH v:%d time:%d type:%d ch:%d A:%d B:%d\n", v, event.time(), event.type(), event.channel(), event.dataA(), event.dataB());
+ if(!queueEvent(MidiPlayEvent(t, port, chn, ME_POLYAFTER, a & 0x7f, b & 0x7f)))
+ return false;
+ }
+ else if(a == CTRL_AFTERTOUCH)
{
//printf("MidiJackDevice::processEvent CTRL_AFTERTOUCH v:%d time:%d type:%d ch:%d A:%d B:%d\n", v, event.time(), event.type(), event.channel(), event.dataA(), event.dataB());
if(!queueEvent(MidiPlayEvent(t, port, chn, ME_AFTERTOUCH, b & 0x7f, 0)))
diff --git a/muse2/muse/gconfig.cpp b/muse2/muse/gconfig.cpp
index c88c3fc5..0da8ccf7 100644
--- a/muse2/muse/gconfig.cpp
+++ b/muse2/muse/gconfig.cpp
@@ -26,7 +26,7 @@
namespace MusEGlobal {
GlobalConfigValues config = {
- 190, // globalAlphaBlend
+ 170, // globalAlphaBlend
{
QColor(0xff, 0xff, 0xff), // palette
QColor(0xff, 0xff, 0xff),
@@ -130,6 +130,8 @@ GlobalConfigValues config = {
true, // midiSendInit Send instrument initialization sequences
true, // warnInitPending Warn instrument initialization sequences pending
false, // midiSendCtlDefaults Send instrument controller defaults at position 0 if none in song
+ true, // warnIfBadTiming Warn if timer res not good
+ false, // velocityPerNote Whether to show per-note or all velocities
-60, // int minMeter;
-60.0, // double minSlider;
false, // use Jack freewheel
diff --git a/muse2/muse/gconfig.h b/muse2/muse/gconfig.h
index 6fa85846..af45ed92 100644
--- a/muse2/muse/gconfig.h
+++ b/muse2/muse/gconfig.h
@@ -139,6 +139,8 @@ struct GlobalConfigValues {
bool midiSendInit; // Send instrument initialization sequences
bool warnInitPending; // Warn instrument initialization sequences pending
bool midiSendCtlDefaults; // Send instrument controller defaults at position 0 if none in song
+ bool warnIfBadTiming; // Warn if timer res not good
+ bool velocityPerNote; // Whether to show per-note or all velocities
int minMeter;
double minSlider;
bool freewheelMode;
diff --git a/muse2/muse/helper.cpp b/muse2/muse/helper.cpp
index 986d38aa..e2186af9 100644
--- a/muse2/muse/helper.cpp
+++ b/muse2/muse/helper.cpp
@@ -888,7 +888,7 @@ 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;
+ bool isNewDrum = (track->type() == MusECore::Track::NEW_DRUM) || (track->type() == MusECore::Track::MIDI);
MusECore::MidiInstrument* instr = port->instrument();
MusECore::MidiControllerList* mcl = instr->controller();
@@ -1030,18 +1030,6 @@ int populateMidiCtrlMenu(PopupMenu* menu, MusECore::PartList* part_list, MusECor
est_width = fmw;
menu->addAction(stext)->setData(velo);
-// stext = QWidget::tr("PolyAftertouch");
-// fmw = menu->fontMetrics().width(stext);
-// if(fmw > est_width)
-// est_width = fmw;
-// menu->addAction(stext)->setData(polyafter);
-//
-// stext = QWidget::tr("Aftertouch");
-// fmw = menu->fontMetrics().width(stext);
-// if(fmw > est_width)
-// est_width = fmw;
-// menu->addAction(stext)->setData(after);
-
// Add global default controllers (all controllers not found in instrument).
for (isList i = sList.begin(); i != sList.end(); ++i)
{
diff --git a/muse2/muse/icons.cpp b/muse2/muse/icons.cpp
index dab1067b..a3dfbf50 100644
--- a/muse2/muse/icons.cpp
+++ b/muse2/muse/icons.cpp
@@ -212,6 +212,8 @@
#include "xpm/initS.xpm"
#include "xpm/delta_on.xpm"
#include "xpm/delta_off.xpm"
+#include "xpm/velo_all.xpm"
+#include "xpm/velo_per_note.xpm"
#include "xpm/addtrack_addmiditrack.xpm"
#include "xpm/addtrack_audiogroup.xpm"
@@ -294,6 +296,8 @@ QPixmap* mixerAudioSIcon;
QPixmap* initSIcon;
QPixmap* deltaOnIcon;
QPixmap* deltaOffIcon;
+QPixmap* veloPerNote_OnIcon;
+QPixmap* veloPerNote_OffIcon;
QPixmap* exitIcon;
QPixmap* exit1Icon;
@@ -678,6 +682,8 @@ void initIcons()
initSIcon = new MPIXMAP(initS_xpm, NULL);
deltaOnIcon = new MPIXMAP(delta_on_xpm, NULL);
deltaOffIcon = new MPIXMAP(delta_off_xpm, NULL);
+ veloPerNote_OnIcon = new MPIXMAP(velo_per_note_xpm, NULL);
+ veloPerNote_OffIcon = new MPIXMAP(velo_all_xpm, NULL);
addtrack_addmiditrackIcon = new MPIXMAP(addtrack_addmiditrack_xpm, NULL);
addtrack_audiogroupIcon = new MPIXMAP(addtrack_audiogroup_xpm, NULL);
@@ -917,6 +923,8 @@ void deleteIcons()
delete initSIcon;
delete deltaOnIcon;
delete deltaOffIcon;
+ delete veloPerNote_OnIcon;
+ delete veloPerNote_OffIcon;
delete addtrack_addmiditrackIcon;
delete addtrack_audiogroupIcon;
diff --git a/muse2/muse/icons.h b/muse2/muse/icons.h
index a6c95577..36a780ae 100644
--- a/muse2/muse/icons.h
+++ b/muse2/muse/icons.h
@@ -195,6 +195,8 @@ extern QPixmap* mixerAudioSIcon;
extern QPixmap* initSIcon;
extern QPixmap* deltaOnIcon;
extern QPixmap* deltaOffIcon;
+extern QPixmap* veloPerNote_OnIcon;
+extern QPixmap* veloPerNote_OffIcon;
extern QPixmap* addtrack_addmiditrackIcon;
extern QPixmap* addtrack_audiogroupIcon;
diff --git a/muse2/muse/midictrl.cpp b/muse2/muse/midictrl.cpp
index 2cf4f790..b87ea8d1 100644
--- a/muse2/muse/midictrl.cpp
+++ b/muse2/muse/midictrl.cpp
@@ -87,9 +87,6 @@ static MidiController programCtrl("Program", CTRL_PROGRAM, 0, 0xf
static MidiController mastervolCtrl("MasterVolume", CTRL_MASTER_VOLUME, 0, 0x3fff, 0x3000);
static MidiController volumeCtrl("MainVolume", CTRL_VOLUME, 0, 127, 100);
static MidiController panCtrl("Pan", CTRL_PANPOT, -64, 63, 0);
-static MidiController polyAfterCtrl("PolyAftertouch", CTRL_POLYAFTER, 0, 127, 0);
-static MidiController afterCtrl("Aftertouch", CTRL_AFTERTOUCH, 0, 127, 0);
-
//---------------------------------------------------------
// ctrlType2Int
@@ -149,8 +146,6 @@ const QString& int2ctrlType(int n)
void initMidiController()
{
defaultMidiController.add(&veloCtrl);
- defaultMidiController.add(&polyAfterCtrl);
- defaultMidiController.add(&afterCtrl);
defaultMidiController.add(&pitchCtrl);
defaultMidiController.add(&programCtrl);
defaultMidiController.add(&mastervolCtrl);
@@ -432,7 +427,7 @@ void MidiController::updateBias()
void MidiController::write(int level, Xml& xml) const
{
ControllerType t = midiControllerType(_num);
- if(t == Velo || t == PolyAftertouch || t == Aftertouch)
+ if(t == Velo)
return;
QString type(int2ctrlType(t));
@@ -475,10 +470,16 @@ void MidiController::write(int level, Xml& xml) const
mn = -8192;
mx = 8191;
break;
- case Program:
- case Velo: // Cannot happen
case PolyAftertouch:
+ mn = 0;
+ mx = 127;
+ break;
case Aftertouch:
+ mn = 0;
+ mx = 127;
+ break;
+ case Program:
+ case Velo: // Cannot happen
break;
}
@@ -599,9 +600,21 @@ void MidiController::read(Xml& xml)
_maxVal = 0xffffff;
_num = CTRL_PROGRAM;
break;
- case Velo: // cannot happen
case PolyAftertouch:
+ if (_maxVal == NOT_SET)
+ _maxVal = 127;
+ if (_minVal == NOT_SET)
+ _minVal = 0;
+ _num = CTRL_POLYAFTER;
+ break;
case Aftertouch:
+ if (_maxVal == NOT_SET)
+ _maxVal = 127;
+ if (_minVal == NOT_SET)
+ _minVal = 0;
+ _num = CTRL_AFTERTOUCH;
+ break;
+ case Velo: // cannot happen
break;
}
if (_minVal == NOT_SET)
diff --git a/muse2/muse/midictrl.h b/muse2/muse/midictrl.h
index 5e197dc0..5ff3f129 100644
--- a/muse2/muse/midictrl.h
+++ b/muse2/muse/midictrl.h
@@ -81,11 +81,13 @@ const int CTRL_LOCAL_OFF = 0x7a; // 122
const int CTRL_INTERNAL_OFFSET = 0x40000;
const int CTRL_PITCH = CTRL_INTERNAL_OFFSET;
-const int CTRL_PROGRAM = CTRL_INTERNAL_OFFSET + 1;
-const int CTRL_VELOCITY = CTRL_INTERNAL_OFFSET + 2;
-const int CTRL_MASTER_VOLUME = CTRL_INTERNAL_OFFSET + 3;
-const int CTRL_POLYAFTER = CTRL_INTERNAL_OFFSET + 4;
-const int CTRL_AFTERTOUCH = CTRL_INTERNAL_OFFSET + 5;
+const int CTRL_PROGRAM = CTRL_INTERNAL_OFFSET + 0x01;
+const int CTRL_VELOCITY = CTRL_INTERNAL_OFFSET + 0x02;
+const int CTRL_MASTER_VOLUME = CTRL_INTERNAL_OFFSET + 0x03;
+const int CTRL_AFTERTOUCH = CTRL_INTERNAL_OFFSET + 0x04;
+// NOTE: The range from CTRL_INTERNAL_OFFSET + 0x100 to CTRL_INTERNAL_OFFSET + 0x1ff is reserved
+// for this control. (The low byte is reserved because this is a per-note control.)
+const int CTRL_POLYAFTER = CTRL_INTERNAL_OFFSET + 0x1FF; // 100 to 1FF !
const int CTRL_VAL_UNKNOWN = 0x10000000; // used as unknown hwVal
diff --git a/muse2/muse/mididev.cpp b/muse2/muse/mididev.cpp
index 96fee89a..3703def2 100644
--- a/muse2/muse/mididev.cpp
+++ b/muse2/muse/mididev.cpp
@@ -456,6 +456,9 @@ bool MidiDevice::putEvent(const MidiPlayEvent& ev)
if (a == CTRL_PITCH) {
return putMidiEvent(MidiPlayEvent(t, port, chn, ME_PITCHBEND, b, 0));
}
+ if ((a | 0xff) == CTRL_POLYAFTER) {
+ return putMidiEvent(MidiPlayEvent(t, port, chn, ME_POLYAFTER, a & 0x7f, b & 0x7f));
+ }
if (a == CTRL_AFTERTOUCH) {
return putMidiEvent(MidiPlayEvent(t, port, chn, ME_AFTERTOUCH, b, 0));
}
diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp
index 42eda0fd..9189b0d8 100644
--- a/muse2/muse/midiedit/dcanvas.cpp
+++ b/muse2/muse/midiedit/dcanvas.cpp
@@ -871,9 +871,11 @@ void DrumCanvas::keyPressed(int index, int velocity)
int pitch = old_style_drummap_mode ? ourDrumMap[index].anote : instrument_map[index].pitch;
// play note:
- MusECore::MidiPlayEvent e(0, port, channel, 0x90, pitch, velocity);
- MusEGlobal::audio->msgPlayMidiEvent(&e);
-
+ if(_playEvents)
+ {
+ MusECore::MidiPlayEvent e(0, port, channel, 0x90, pitch, velocity);
+ MusEGlobal::audio->msgPlayMidiEvent(&e);
+ }
if (_steprec) /* && pos[0] >= start_tick && pos[0] < end_tick [removed by flo93: this is handled in steprec->record] */
{
@@ -909,8 +911,11 @@ void DrumCanvas::keyReleased(int index, bool)
int pitch = old_style_drummap_mode ? ourDrumMap[index].anote : instrument_map[index].pitch;
// release note:
- MusECore::MidiPlayEvent e(0, port, channel, 0x90, pitch, 0);
- MusEGlobal::audio->msgPlayMidiEvent(&e);
+ if(_playEvents)
+ {
+ MusECore::MidiPlayEvent e(0, port, channel, 0x90, pitch, 0);
+ MusEGlobal::audio->msgPlayMidiEvent(&e);
+ }
}
//---------------------------------------------------------
diff --git a/muse2/muse/midiedit/dlist.cpp b/muse2/muse/midiedit/dlist.cpp
index a77fb810..3222e278 100644
--- a/muse2/muse/midiedit/dlist.cpp
+++ b/muse2/muse/midiedit/dlist.cpp
@@ -1123,6 +1123,15 @@ void DList::viewMouseReleaseEvent(QMouseEvent* ev)
}
//---------------------------------------------------------
+// wheelEvent
+//---------------------------------------------------------
+
+void DList::wheelEvent(QWheelEvent* ev)
+ {
+ emit redirectWheelEvent(ev);
+ }
+
+//---------------------------------------------------------
// getSelectedInstrument
//---------------------------------------------------------
diff --git a/muse2/muse/midiedit/dlist.h b/muse2/muse/midiedit/dlist.h
index b4c757e8..28b4af27 100644
--- a/muse2/muse/midiedit/dlist.h
+++ b/muse2/muse/midiedit/dlist.h
@@ -137,6 +137,7 @@ class DList : public View {
virtual void viewMouseReleaseEvent(QMouseEvent* event);
virtual void viewMouseDoubleClickEvent(QMouseEvent*);
virtual void viewMouseMoveEvent(QMouseEvent*);
+ virtual void wheelEvent(QWheelEvent* e);
int x2col(int x) const;
void devicesPopupMenu(MusECore::DrumMap* t, int x, int y, bool changeAll);
@@ -155,6 +156,7 @@ class DList : public View {
void keyPressed(int, int);
void keyReleased(int, bool);
void curDrumInstrumentChanged(int);
+ void redirectWheelEvent(QWheelEvent*);
public slots:
void tracklistChanged();
diff --git a/muse2/muse/midiedit/drumedit.cpp b/muse2/muse/midiedit/drumedit.cpp
index 238b37fd..03f246cf 100644
--- a/muse2/muse/midiedit/drumedit.cpp
+++ b/muse2/muse/midiedit/drumedit.cpp
@@ -166,6 +166,7 @@ DrumEdit::DrumEdit(MusECore::PartList* pl, QWidget* parent, const char* name, un
lastSelections = 0;
split1w1 = 0;
//selPart = 0;
+ _playEvents = false;
QSignalMapper *signalMapper = new QSignalMapper(this);
_group_mode = GROUP_SAME_CHANNEL;
@@ -419,7 +420,13 @@ DrumEdit::DrumEdit(MusECore::PartList* pl, QWidget* parent, const char* name, un
midiin->setFocusPolicy(Qt::NoFocus);
tools->addWidget(midiin);
-
+ speaker = new QToolButton();
+ speaker->setToolTip(tr("Play Events"));
+ speaker->setIcon(*speakerIcon);
+ speaker->setCheckable(true);
+ speaker->setFocusPolicy(Qt::NoFocus);
+ tools->addWidget(speaker);
+
tools2 = new MusEGui::EditToolBar(this, drumeditTools);
addToolBar(tools2);
@@ -554,6 +561,7 @@ DrumEdit::DrumEdit(MusECore::PartList* pl, QWidget* parent, const char* name, un
connect(dlist, SIGNAL(keyPressed(int, int)), canvas, SLOT(keyPressed(int, int)));
connect(dlist, SIGNAL(keyReleased(int, bool)), canvas, SLOT(keyReleased(int, bool)));
connect(dlist, SIGNAL(mapChanged(int, int)), canvas, SLOT(mapChanged(int, int)));
+ connect(dlist, SIGNAL(redirectWheelEvent(QWheelEvent*)), canvas, SLOT(redirectedWheelEvent(QWheelEvent*)));
gridS1->setRowStretch(1, 100);
gridS1->setColumnStretch(0, 100);
@@ -568,11 +576,12 @@ DrumEdit::DrumEdit(MusECore::PartList* pl, QWidget* parent, const char* name, un
connect(MusEGlobal::song, SIGNAL(songChanged(MusECore::SongChangedFlags_t)), dlist, SLOT(songChanged(MusECore::SongChangedFlags_t)));
connect(vscroll, SIGNAL(scrollChanged(int)), canvas, SLOT(setYPos(int)));
connect(vscroll, SIGNAL(scaleChanged(int)), canvas, SLOT(setYMag(int)));
- connect(vscroll, SIGNAL(scaleChanged(int)), dlist, SLOT(setYMag(int)));
+ connect(vscroll, SIGNAL(scaleChanged(int)), dlist, SLOT(setYMag(int)));
connect(hscroll, SIGNAL(scrollChanged(int)), canvas, SLOT(setXPos(int)));
connect(hscroll, SIGNAL(scaleChanged(int)), canvas, SLOT(setXMag(int)));
connect(srec, SIGNAL(toggled(bool)), canvas, SLOT(setSteprec(bool)));
connect(midiin, SIGNAL(toggled(bool)), canvas, SLOT(setMidiin(bool)));
+ connect(speaker, SIGNAL(toggled(bool)), SLOT(setSpeaker(bool)));
connect(vscroll, SIGNAL(scrollChanged(int)), dlist, SLOT(setYPos(int)));
connect(hscroll, SIGNAL(scrollChanged(int)), time, SLOT(setXPos(int)));
@@ -930,6 +939,7 @@ void DrumEdit::writeStatus(int level, MusECore::Xml& xml) const
header->writeStatus(level, xml);
xml.intTag(level, "steprec", canvas->steprec());
xml.intTag(level, "midiin", canvas->midiin());
+ xml.intTag(level, "playEvents", _playEvents);
xml.intTag(level, "xpos", hscroll->pos());
xml.intTag(level, "xmag", hscroll->mag());
xml.intTag(level, "ypos", vscroll->pos());
@@ -974,6 +984,11 @@ void DrumEdit::readStatus(MusECore::Xml& xml)
MidiEditor::readStatus(xml);
else if (tag == header->objectName())
header->readStatus(xml);
+ else if (tag == "playEvents") {
+ _playEvents = xml.parseInt();
+ canvas->playEvents(_playEvents);
+ speaker->setChecked(_playEvents);
+ }
else if (tag == "xmag")
hscroll->setMag(xml.parseInt());
else if (tag == "xpos")
@@ -1253,20 +1268,12 @@ void DrumEdit::ctrlPopupTriggered(QAction* act)
const int edit_ins = max + 3;
const int velo = max + 0x101;
- const int polyafter = max + 0x102;
- const int after = max + 0x103;
int rv = act->data().toInt();
if (rv == velo) { // special case velocity
newCtlNum = MusECore::CTRL_VELOCITY;
}
- else if (rv == polyafter) { // special case
- newCtlNum = MusECore::CTRL_POLYAFTER;
- }
- else if (rv == after) { // special case
- newCtlNum = MusECore::CTRL_AFTERTOUCH;
- }
else if (rv == add_ins_def) { // add new instrument controller
PopupMenu * ctrlSubPop = new PopupMenu(this, true); // true = enable stay open
@@ -1708,6 +1715,16 @@ void DrumEdit::keyPressEvent(QKeyEvent* event)
//---------------------------------------------------------
+// setSpeaker
+//---------------------------------------------------------
+
+void DrumEdit::setSpeaker(bool val)
+ {
+ _playEvents = val;
+ canvas->playEvents(_playEvents);
+ }
+
+//---------------------------------------------------------
// initShortcuts
//---------------------------------------------------------
diff --git a/muse2/muse/midiedit/drumedit.h b/muse2/muse/midiedit/drumedit.h
index 63246e2e..4b9d391a 100644
--- a/muse2/muse/midiedit/drumedit.h
+++ b/muse2/muse/midiedit/drumedit.h
@@ -103,7 +103,9 @@ class DrumEdit : public MidiEditor {
MusEGui::NoteInfo* info;
QToolButton* srec;
QToolButton* midiin;
+ QToolButton* speaker;
MusEGui::EditToolBar* tools2;
+ bool _playEvents;
MusEGui::Toolbar1* toolbar;
MusEGui::Splitter* split1;
@@ -152,6 +154,7 @@ class DrumEdit : public MidiEditor {
void configChanged();
void songChanged1(MusECore::SongChangedFlags_t);
void setStep(QString);
+ void setSpeaker(bool);
void addCtrlClicked();
void ctrlPopupTriggered(QAction* act);
diff --git a/muse2/muse/midiedit/piano.cpp b/muse2/muse/midiedit/piano.cpp
index 1000ffe9..afbf8328 100644
--- a/muse2/muse/midiedit/piano.cpp
+++ b/muse2/muse/midiedit/piano.cpp
@@ -26,7 +26,11 @@
#include <stdio.h>
#include "piano.h"
+#include "globals.h"
+#include "song.h"
+namespace MusEGui {
+
static const char *oct_xpm[] = {
// w h colors
"40 91 2 1",
@@ -120,134 +124,125 @@ static const char *oct_xpm[] = {
".........................#...#.........#",
".........................#.............#",
".........................#.............#",
- ".........................#...#.........#", // 10
+ ".........................#...#.........#", // 9
"..........................###..........#",
".......................................#",
".......................................#",
- ".......................................#",
};
static const char *mk1_xpmC1[] = {
- "40 10 2 1",
- ". c #c0c0c0",
+ "40 9 2 1",
+ ". c none",
"# c #000000",
".......................................#",
"..........................###.....#....#",
".........................#...#...##....#",
".........................#........#....#",
".........................#........#....#",
- ".........................#...#....#....#", // 10
+ ".........................#...#....#....#", // 9
"..........................###....###...#",
".......................................#",
".......................................#",
- ".......................................#",
};
static const char *mk1_xpmC2[] = {
- "40 10 2 1",
- ". c #c0c0c0",
+ "40 9 2 1",
+ ". c none",
"# c #000000",
".......................................#",
"..........................###....##....#",
".........................#...#..#..#...#",
".........................#........#....#",
".........................#.......#.....#",
- ".........................#...#..#......#", // 10
+ ".........................#...#..#......#", // 9
"..........................###...####...#",
".......................................#",
".......................................#",
- ".......................................#",
};
static const char *mk1_xpmC3[] = {
- "40 10 2 1",
- ". c #c0c0c0",
+ "40 9 2 1",
+ ". c none",
"# c #000000",
".......................................#",
"..........................###....##....#",
".........................#...#..#..#...#",
".........................#........#....#",
".........................#.........#...#",
- ".........................#...#..#..#...#", // 10
+ ".........................#...#..#..#...#", // 9
"..........................###....##....#",
".......................................#",
".......................................#",
- ".......................................#",
};
static const char *mk1_xpmC4[] = {
- "40 10 2 1",
- ". c #c0c0c0",
+ "40 9 2 1",
+ ". c none",
"# c #000000",
".......................................#",
"..........................###...#..#...#",
".........................#...#..#..#...#",
".........................#......####...#",
".........................#.........#...#",
- ".........................#...#.....#...#", // 10
+ ".........................#...#.....#...#", // 9
"..........................###......#...#",
".......................................#",
".......................................#",
- ".......................................#",
};
static const char *mk1_xpmC5[] = {
- "40 10 2 1",
- ". c #c0c0c0",
+ "40 9 2 1",
+ ". c none",
"# c #000000",
".......................................#",
"..........................###...####...#",
".........................#...#..#......#",
".........................#......###....#",
".........................#.........#...#",
- ".........................#...#.....#...#", // 10
+ ".........................#...#.....#...#", // 9
"..........................###...###....#",
".......................................#",
".......................................#",
- ".......................................#",
};
static const char *mk1_xpmC6[] = {
- "40 10 2 1",
- ". c #c0c0c0",
+ "40 9 2 1",
+ ". c none",
"# c #000000",
".......................................#",
"..........................###....###...#",
".........................#...#..#......#",
".........................#......###....#",
".........................#......#..#...#",
- ".........................#...#..#..#...#", // 10
+ ".........................#...#..#..#...#", // 9
"..........................###...###....#",
".......................................#",
".......................................#",
- ".......................................#",
};
static const char *mk1_xpmC7[] = {
- "40 10 2 1",
- ". c #c0c0c0",
+ "40 9 2 1",
+ ". c none",
"# c #000000",
".......................................#",
"..........................###...####...#",
".........................#...#.....#...#",
".........................#........#....#",
".........................#.......#.....#",
- ".........................#...#..#......#", // 10
+ ".........................#...#..#......#", // 9
"..........................###...#......#",
".......................................#",
".......................................#",
- ".......................................#",
};
static const char *mk1_xpmC8[] = {
- "40 10 2 1",
- ". c #c0c0c0",
+ "40 9 2 1",
+ ". c none",
"# c #000000",
".......................................#",
"..........................###....##....#",
- ".........................#...#..#..#....#",
+ ".........................#...#..#..#...#",
".........................#.......##....#",
".........................#......#..#...#",
- ".........................#...#..#..#...#", // 10
+ ".........................#...#..#..#...#", // 9
"..........................###....##....#",
".......................................#",
".......................................#",
- ".......................................#",
};
static const char *mk1_xpm[] = {
@@ -266,7 +261,7 @@ static const char *mk1_xpm[] = {
"#######################................#",
"########################...............#",
"########################...............#",
- "####################################### ",
+ "########################################",
};
static const char *mk2_xpm[] = {
@@ -285,7 +280,7 @@ static const char *mk2_xpm[] = {
"#######################................#",
"########################...............#",
"########################...............#", // 7
- "####################################### ",
+ "########################################",
};
static const char *mk3_xpm[] = {
@@ -325,6 +320,83 @@ static const char *mk4_xpm[] = {
"........................................",
"........................................",
};
+
+static const char *mk5_xpm[] = {
+ "40 13 2 1",
+ ". c #ffff00",
+ "# c none",
+ ".......................................#",
+ ".......................................#",
+ ".......................................#",
+ ".......................................#",
+ ".......................................#",
+ ".......................................#",
+ ".......................................#",
+ ".......................................#",
+ ".......................................#",
+ "#######################................#",
+ "########################...............#",
+ "########################...............#",
+ "########################################",
+ };
+
+static const char *mk6_xpm[] = {
+ "40 13 2 1",
+ ". c #ffff00",
+ "# c none",
+ "########################...............#",
+ "########################...............#",
+ "#######################................#", //------------------------
+ ".......................................#",
+ ".......................................#",
+ ".......................................#", // 6
+ ".......................................#",
+ ".......................................#",
+ ".......................................#", //--------------------------
+ "#######################................#",
+ "########################...............#",
+ "########################...............#", // 7
+ "########################################",
+ };
+
+static const char *mk7_xpm[] = {
+ "40 13 2 1",
+ ". c #ffff00",
+ "# c none",
+ "########################...............#",
+ "########################...............#",
+ "#######################................#",
+ ".......................................#",
+ ".......................................#",
+ ".......................................#",
+ ".......................................#",
+ ".......................................#",
+ ".......................................#",
+ ".......................................#",
+ ".......................................#",
+ ".......................................#",
+ "########################################",
+ };
+
+static const char *mk8_xpm[] = {
+ "40 13 2 1",
+ "# c #ffff00",
+ ". c none",
+ "........................................",
+ "........................................",
+ "........................................",
+ "#######################.................",
+ "########################................",
+ "########################................",
+ "########################................",
+ "########################................",
+ "########################................",
+ "#######################.................",
+ "........................................",
+ "........................................",
+ "........................................",
+ };
+
/*
0 1 2 3 4 5 6 7 8 9 10
c-2 c-1 C0 C1 C2 C3 C4 C5 C6 C7 C8 - G8
@@ -367,10 +439,11 @@ static const char *mk4_xpm[] = {
//---------------------------------------------------------
Piano::Piano(QWidget* parent, int ymag)
- : MusEGui::View(parent, 1, ymag)
+ : View(parent, 1, ymag)
{
setMouseTracking(true);
curPitch = -1;
+ _curSelectedPitch = 60; // Start with 'C3"
octave = new QPixmap(oct_xpm);
c_keys[0] = new QPixmap(mk1_xpmC8);
c_keys[1] = new QPixmap(mk1_xpmC7);
@@ -385,6 +458,12 @@ Piano::Piano(QWidget* parent, int ymag)
mk2 = new QPixmap(mk2_xpm);
mk3 = new QPixmap(mk3_xpm);
mk4 = new QPixmap(mk4_xpm);
+
+ mk5 = new QPixmap(mk5_xpm);
+ mk6 = new QPixmap(mk6_xpm);
+ mk7 = new QPixmap(mk7_xpm);
+ mk8 = new QPixmap(mk8_xpm);
+
keyDown = -1;
button = Qt::NoButton;
}
@@ -398,39 +477,67 @@ void Piano::draw(QPainter& p, const QRect& r)
QPoint offset(0, KH*2);
p.drawTiledPixmap(r, *octave, r.topLeft()+offset);
+ if (_curSelectedPitch != -1 && _curSelectedPitch != curPitch)
+ {
+ int y = pitch2y(_curSelectedPitch);
+ QPixmap* pm;
+ switch(_curSelectedPitch % 12) {
+ case 0:
+ case 5:
+ pm = mk7;
+ break;
+ case 2:
+ case 7:
+ case 9:
+ pm = mk6;
+ break;
+ case 4:
+ case 11:
+ pm = mk5;
+ break;
+ default:
+ pm = mk8;
+ break;
+ }
+ p.drawPixmap(0, y, *pm);
+ }
+
+ if (curPitch != -1)
+ {
+ int y = pitch2y(curPitch);
+ QPixmap* pm;
+ switch(curPitch % 12) {
+ case 0:
+ case 5:
+ pm = mk3;
+ break;
+ case 2:
+ case 7:
+ case 9:
+ pm = mk2;
+ break;
+ case 4:
+ case 11:
+ pm = mk1;
+ break;
+ default:
+ pm = mk4;
+ break;
+ }
+ p.drawPixmap(0, y, *pm);
+ }
+
// draw C notes
for (int drawKey = 0; drawKey < 8;drawKey++) {
int octaveSize=91;
- int drawY = octaveSize * drawKey + 81 - KH*2;
+ int drawY = octaveSize * drawKey + 82 - KH*2;
if (drawY > r.y() && drawY < r.y() + r.height()) {
p.drawPixmap(0,drawY,*c_keys[drawKey]);
}
}
-
- if (curPitch == -1)
- return;
- int y = pitch2y(curPitch);
- QPixmap* pm;
- switch(curPitch % 12) {
- case 0:
- case 5:
- pm = mk3;
- break;
- case 2:
- case 7:
- case 9:
- pm = mk2;
- break;
- case 4:
- case 11:
- pm = mk1;
- break;
- default:
- pm = mk4;
- break;
- }
- p.drawPixmap(0, y, *pm);
+
+
}
//---------------------------------------------------------
@@ -547,6 +654,13 @@ void Piano::viewMousePressEvent(QMouseEvent* event)
int velocity = event->x()*127/40;
emit keyPressed(keyDown, velocity>127 ? 127 : velocity, shift); //emit keyPressed(keyDown, shift);
}
+
+ if (keyDown != -1 && keyDown != _curSelectedPitch) {
+ _curSelectedPitch = keyDown;
+ emit curSelectedPitchChanged(_curSelectedPitch);
+ redraw();
+ MusEGlobal::song->update(SC_DRUMMAP);
+ }
}
//---------------------------------------------------------
@@ -563,3 +677,28 @@ void Piano::viewMouseReleaseEvent(QMouseEvent* event)
}
}
+//---------------------------------------------------------
+// setCurSelectedPitch
+//---------------------------------------------------------
+
+void Piano::setCurSelectedPitch(int pitch)
+ {
+ if (pitch < 0 || pitch >= 128)
+ return;
+ if (pitch != _curSelectedPitch) {
+ _curSelectedPitch = pitch;
+ emit curSelectedPitchChanged(_curSelectedPitch);
+ redraw();
+ }
+ }
+
+//---------------------------------------------------------
+// wheelEvent
+//---------------------------------------------------------
+
+void Piano::wheelEvent(QWheelEvent* ev)
+ {
+ emit redirectWheelEvent(ev);
+ }
+
+} // namespace MusEGui
diff --git a/muse2/muse/midiedit/piano.h b/muse2/muse/midiedit/piano.h
index ea032189..f42037ec 100644
--- a/muse2/muse/midiedit/piano.h
+++ b/muse2/muse/midiedit/piano.h
@@ -27,26 +27,34 @@
class QEvent;
class QMouseEvent;
+class QWheelEvent;
class QPainter;
class QPixmap;
#define KH 13
+namespace MusEGui {
+
//---------------------------------------------------------
// Piano
//---------------------------------------------------------
-class Piano : public MusEGui::View
+class Piano : public View
{
Q_OBJECT
int curPitch;
+ int _curSelectedPitch;
QPixmap* octave;
QPixmap* c_keys[10];
QPixmap* mk1;
QPixmap* mk2;
QPixmap* mk3;
QPixmap* mk4;
+ QPixmap* mk5;
+ QPixmap* mk6;
+ QPixmap* mk7;
+ QPixmap* mk8;
int keyDown;
bool shift;
int button;
@@ -59,6 +67,7 @@ class Piano : public MusEGui::View
virtual void viewMousePressEvent(QMouseEvent* event);
virtual void viewMouseReleaseEvent(QMouseEvent*);
+ virtual void wheelEvent(QWheelEvent* e);
protected:
virtual void draw(QPainter&, const QRect&);
@@ -67,13 +76,19 @@ class Piano : public MusEGui::View
void pitchChanged(int);
void keyPressed(int, int, bool);
void keyReleased(int, bool);
+ void curSelectedPitchChanged(int);
+ void redirectWheelEvent(QWheelEvent*);
public slots:
void setPitch(int);
public:
Piano(QWidget*, int);
+ int curSelectedPitch() const { return _curSelectedPitch; }
+ void setCurSelectedPitch(int pitch);
};
+} // namespace MusEGui
+
#endif
diff --git a/muse2/muse/midiedit/pianoroll.cpp b/muse2/muse/midiedit/pianoroll.cpp
index 1701f537..97c5ecc3 100644
--- a/muse2/muse/midiedit/pianoroll.cpp
+++ b/muse2/muse/midiedit/pianoroll.cpp
@@ -359,9 +359,10 @@ PianoRoll::PianoRoll(MusECore::PartList* pl, QWidget* parent, const char* name,
gridS1->setSpacing(0);
time = new MusEGui::MTScale(&_raster, split1, xscale);
- Piano* piano = new Piano(split1, yscale);
+ piano = new Piano(split1, yscale);
canvas = new PianoCanvas(this, split1, xscale, yscale);
vscroll = new MusEGui::ScrollScale(-3, 7, yscale, KH * 75, Qt::Vertical, split1);
+ setCurDrumInstrument(piano->curSelectedPitch());
int offset = -(MusEGlobal::config.division/4);
canvas->setOrigin(offset, 0);
@@ -428,6 +429,7 @@ PianoRoll::PianoRoll(MusECore::PartList* pl, QWidget* parent, const char* name,
connect(piano, SIGNAL(keyPressed(int, int, bool)), canvas, SLOT(pianoPressed(int, int, bool)));
connect(piano, SIGNAL(keyReleased(int, bool)), canvas, SLOT(pianoReleased(int, bool)));
+ connect(piano, SIGNAL(redirectWheelEvent(QWheelEvent*)), canvas, SLOT(redirectedWheelEvent(QWheelEvent*)));
connect(srec, SIGNAL(toggled(bool)), SLOT(setSteprec(bool)));
connect(midiin, SIGNAL(toggled(bool)), canvas, SLOT(setMidiin(bool)));
connect(speaker, SIGNAL(toggled(bool)), SLOT(setSpeaker(bool)));
@@ -811,9 +813,7 @@ void PianoRoll::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;
+ int curPitch = curDrumInstrument();
MusECore::MidiInstrument* instr = port->instrument();
MusECore::MidiControllerList* mcl = instr->controller();
@@ -826,20 +826,12 @@ void PianoRoll::ctrlPopupTriggered(QAction* act)
const int edit_ins = max + 3;
const int velo = max + 0x101;
- const int polyafter = max + 0x102;
- const int after = max + 0x103;
int rv = act->data().toInt();
if (rv == velo) { // special case velocity
newCtlNum = MusECore::CTRL_VELOCITY;
}
- else if (rv == polyafter) { // special case
- newCtlNum = MusECore::CTRL_POLYAFTER;
- }
- else if (rv == after) { // special case
- newCtlNum = MusECore::CTRL_AFTERTOUCH;
- }
else if (rv == add_ins_def) { // add new instrument controller
PopupMenu * ctrlSubPop = new PopupMenu(this, true); // true = enable stay open
@@ -855,10 +847,11 @@ void PianoRoll::ctrlPopupTriggered(QAction* act)
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?
+ //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;
}
@@ -885,10 +878,11 @@ void PianoRoll::ctrlPopupTriggered(QAction* act)
{
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 & 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;
@@ -923,10 +917,10 @@ void PianoRoll::ctrlPopupTriggered(QAction* act)
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 (((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())
{
@@ -972,7 +966,7 @@ void PianoRoll::addCtrlClicked()
PopupMenu* pup = new PopupMenu(true); // true = enable stay open. Don't bother with parent.
connect(pup, SIGNAL(triggered(QAction*)), SLOT(ctrlPopupTriggered(QAction*)));
- int est_width = populateMidiCtrlMenu(pup, parts(), curCanvasPart(), -1); // _curDrumInstrument);
+ int est_width = populateMidiCtrlMenu(pup, parts(), curCanvasPart(), curDrumInstrument());
QPoint ep = ctrl->mapToGlobal(QPoint(0,0));
//int newx = ep.x() - ctrlMainPop->width(); // Too much! Width says 640. Maybe because it hasn't been shown yet .
@@ -1010,7 +1004,11 @@ void PianoRoll::setupNewCtrl(CtrlEdit* ctrlEdit)
connect(ctrlEdit, SIGNAL(timeChanged(unsigned)), SLOT(setTime(unsigned)));
connect(ctrlEdit, SIGNAL(destroyedCtrl(CtrlEdit*)), SLOT(removeCtrl(CtrlEdit*)));
connect(ctrlEdit, SIGNAL(yposChanged(int)), toolbar, SLOT(setInt(int)));
+ connect(piano, SIGNAL(curSelectedPitchChanged(int)), SLOT(setCurDrumInstrument(int)));
+ //connect(piano, SIGNAL(curSelectedPitchChanged(int)), canvas, SLOT(setCurDrumInstrument(int)));
+ setCurDrumInstrument(piano->curSelectedPitch());
+
ctrlEdit->setTool(tools2->curTool());
ctrlEdit->setXPos(hscroll->pos());
ctrlEdit->setXMag(hscroll->getScaleValue());
@@ -1275,6 +1273,17 @@ void PianoRoll::keyPressEvent(QKeyEvent* event)
tools2->set(MusEGui::DrawTool);
return;
}
+ else if (key == shortcuts[SHRT_INSTRUMENT_STEP_UP].key) {
+ piano->setCurSelectedPitch(piano->curSelectedPitch()+1);
+ MusEGlobal::song->update(SC_DRUMMAP);
+ return;
+ }
+ else if (key == shortcuts[SHRT_INSTRUMENT_STEP_DOWN].key) {
+ piano->setCurSelectedPitch(piano->curSelectedPitch()-1);
+ MusEGlobal::song->update(SC_DRUMMAP);
+ return;
+ }
+
else if (key == shortcuts[SHRT_POS_INC].key) {
pc->pianoCmd(CMD_RIGHT);
return;
diff --git a/muse2/muse/midiedit/pianoroll.h b/muse2/muse/midiedit/pianoroll.h
index 75e3c9af..87ea1d3d 100644
--- a/muse2/muse/midiedit/pianoroll.h
+++ b/muse2/muse/midiedit/pianoroll.h
@@ -66,6 +66,7 @@ class ScrollScale;
class Splitter;
class TimeLabel;
class Toolbar1;
+class Piano;
//---------------------------------------------------------
// PianoRoll
@@ -126,6 +127,7 @@ class PianoRoll : public MidiEditor {
QToolButton* srec;
QToolButton* midiin;
+ Piano* piano;
MusEGui::Toolbar1* toolbar;
MusEGui::Splitter* splitter;
MusEGui::Splitter* hsplitter;
diff --git a/muse2/muse/midiedit/prcanvas.cpp b/muse2/muse/midiedit/prcanvas.cpp
index 99c2ea8c..7670abb2 100644
--- a/muse2/muse/midiedit/prcanvas.cpp
+++ b/muse2/muse/midiedit/prcanvas.cpp
@@ -718,8 +718,11 @@ void PianoCanvas::pianoPressed(int pitch, int velocity, bool shift)
pitch += track()->transposition;
// play note:
- MusECore::MidiPlayEvent e(0, port, channel, 0x90, pitch, velocity);
- MusEGlobal::audio->msgPlayMidiEvent(&e);
+ if(_playEvents)
+ {
+ MusECore::MidiPlayEvent e(0, port, channel, 0x90, pitch, velocity);
+ MusEGlobal::audio->msgPlayMidiEvent(&e);
+ }
if (_steprec && curPart) // && pos[0] >= start_tick && pos[0] < end_tick [removed by flo93: this is handled in steprec->record]
steprec->record(curPart,pitch,editor->raster(),editor->raster(),velocity,MusEGlobal::globalKeyState&Qt::ControlModifier,shift, -1 /* anything which is != rcSteprecNote */);
@@ -736,8 +739,11 @@ void PianoCanvas::pianoReleased(int pitch, bool)
pitch += track()->transposition;
// release key:
- MusECore::MidiPlayEvent e(0, port, channel, 0x90, pitch, 0);
- MusEGlobal::audio->msgPlayMidiEvent(&e);
+ if(_playEvents)
+ {
+ MusECore::MidiPlayEvent e(0, port, channel, 0x90, pitch, 0);
+ MusEGlobal::audio->msgPlayMidiEvent(&e);
+ }
}
//---------------------------------------------------------
diff --git a/muse2/muse/midiport.cpp b/muse2/muse/midiport.cpp
index 2f3898ff..4365d698 100644
--- a/muse2/muse/midiport.cpp
+++ b/muse2/muse/midiport.cpp
@@ -742,8 +742,6 @@ void MidiPort::addDefaultControllers()
addManagedController(i, CTRL_PROGRAM);
addManagedController(i, CTRL_VOLUME);
addManagedController(i, CTRL_PANPOT);
- addManagedController(i, CTRL_POLYAFTER);
- addManagedController(i, CTRL_AFTERTOUCH);
_automationType[i] = AUTO_READ;
}
}
diff --git a/muse2/muse/midiseq.cpp b/muse2/muse/midiseq.cpp
index 32e9de4c..8e636658 100644
--- a/muse2/muse/midiseq.cpp
+++ b/muse2/muse/midiseq.cpp
@@ -46,6 +46,7 @@
#include "synth.h"
#include "song.h"
#include "gconfig.h"
+#include "warn_bad_timing.h"
namespace MusEGlobal {
MusECore::MidiSeq* midiSeq;
@@ -507,13 +508,23 @@ void MidiSeq::checkAndReportTimingResolution()
{
int freq = timer->getTimerFreq();
if (freq < 500) {
- QMessageBox::warning( MusEGlobal::muse,
- qApp->translate("@default", QT_TRANSLATE_NOOP("@default", "Bad timing")),
- qApp->translate("@default", QT_TRANSLATE_NOOP("@default",
- "Timing source frequency is %1hz, which is below the recommended minimum: 500hz!\n" \
- "This could lead to audible timing problems for MIDI.\n" \
- "Please see the FAQ on http://muse-sequencer.org for remedies.\n" \
+ if(MusEGlobal::config.warnIfBadTiming)
+ {
+ MusEGui::WarnBadTimingDialog dlg;
+ dlg.setLabelText(qApp->translate("@default", QT_TRANSLATE_NOOP("@default",
+ "Timing source frequency is %1hz, which is below the recommended minimum: 500hz!\n"
+ "This could lead to audible timing problems for MIDI.\n"
+ "Please see the FAQ on http://muse-sequencer.org for remedies.\n"
"Also please check console output for any further error messages.\n ")).arg(freq) );
+
+ dlg.exec();
+ bool warn = !dlg.dontAsk();
+ if(warn != MusEGlobal::config.warnIfBadTiming)
+ {
+ MusEGlobal::config.warnIfBadTiming = warn;
+ //MusEGlobal::muse->changeConfig(true); // Save settings? No, wait till close.
+ }
+ }
}
}
diff --git a/muse2/muse/widgets/CMakeLists.txt b/muse2/muse/widgets/CMakeLists.txt
index 3aad8b92..3808a99f 100644
--- a/muse2/muse/widgets/CMakeLists.txt
+++ b/muse2/muse/widgets/CMakeLists.txt
@@ -105,6 +105,7 @@ QT4_WRAP_CPP (widget_mocs
view.h
vscale.h
visibletracks.h
+ warn_bad_timing.h
)
##
@@ -142,6 +143,7 @@ file (GLOB widgets_ui_files
tracks_duplicate_base.ui
transformbase.ui
unusedwavefiles.ui
+ warn_bad_timing.ui
)
QT4_WRAP_UI (widget_ui_headers ${widgets_ui_files})
@@ -229,6 +231,7 @@ file (GLOB widgets_source_files
view.cpp
vscale.cpp
visibletracks.cpp
+ warn_bad_timing.cpp
)
##
diff --git a/muse2/muse/widgets/genset.cpp b/muse2/muse/widgets/genset.cpp
index 5c4b2dfb..7063b960 100644
--- a/muse2/muse/widgets/genset.cpp
+++ b/muse2/muse/widgets/genset.cpp
@@ -153,6 +153,7 @@ void GlobalSettingsConfig::updateSettings()
}
}
+ warnIfBadTimingCheckBox->setChecked(MusEGlobal::config.warnIfBadTiming);
midiSendInit->setChecked(MusEGlobal::config.midiSendInit);
midiWarnInitPending->setChecked(MusEGlobal::config.warnInitPending);
midiSendCtlDefaults->setChecked(MusEGlobal::config.midiSendCtlDefaults);
@@ -220,6 +221,7 @@ void GlobalSettingsConfig::updateSettings()
lmbDecreasesCheckBox->setChecked(MusEGlobal::config.leftMouseButtonCanDecrease);
rangeMarkerWithoutMMBCheckBox->setChecked(MusEGlobal::config.rangeMarkerWithoutMMB);
smartFocusCheckBox->setChecked(MusEGlobal::config.smartFocus);
+ velocityPerNoteCheckBox->setChecked(MusEGlobal::config.velocityPerNote);
addHiddenCheckBox->setChecked(MusEGlobal::config.addHiddenTracks);
unhideTracksCheckBox->setChecked(MusEGlobal::config.unhideTracks);
@@ -272,6 +274,7 @@ void GlobalSettingsConfig::apply()
MusEGlobal::config.useOutputLimiter = outputLimiterCheckBox->isChecked();
MusEGlobal::config.vstInPlace = vstInPlaceCheckBox->isChecked();
MusEGlobal::config.rtcTicks = rtcResolutions[rtcticks];
+ MusEGlobal::config.warnIfBadTiming = warnIfBadTimingCheckBox->isChecked();
MusEGlobal::config.midiSendInit = midiSendInit->isChecked();
MusEGlobal::config.warnInitPending = midiWarnInitPending->isChecked();
MusEGlobal::config.midiSendCtlDefaults = midiSendCtlDefaults->isChecked();
@@ -335,6 +338,7 @@ void GlobalSettingsConfig::apply()
MusEGlobal::config.leftMouseButtonCanDecrease = lmbDecreasesCheckBox->isChecked();
MusEGlobal::config.rangeMarkerWithoutMMB = rangeMarkerWithoutMMBCheckBox->isChecked();
MusEGlobal::config.smartFocus = smartFocusCheckBox->isChecked();
+ MusEGlobal::config.velocityPerNote = velocityPerNoteCheckBox->isChecked();
MusEGlobal::config.addHiddenTracks = addHiddenCheckBox->isChecked();
MusEGlobal::config.unhideTracks = unhideTracksCheckBox->isChecked();
diff --git a/muse2/muse/widgets/gensetbase.ui b/muse2/muse/widgets/gensetbase.ui
index 30d823ec..35c2d2b2 100644
--- a/muse2/muse/widgets/gensetbase.ui
+++ b/muse2/muse/widgets/gensetbase.ui
@@ -1116,7 +1116,7 @@ Adjusts responsiveness of audio controls and
<string>Ticks</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
- <item row="0" column="0" rowspan="2">
+ <item row="1" column="0" rowspan="2">
<widget class="QLabel" name="TextLabel3">
<property name="text">
<string>RTC Resolution
@@ -1127,7 +1127,7 @@ Adjusts responsiveness of audio controls and
</property>
</widget>
</item>
- <item row="0" column="1">
+ <item row="1" column="1">
<widget class="QComboBox" name="rtcResolutionSelect">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
@@ -1167,7 +1167,7 @@ Adjusts responsiveness of audio controls and
</item>
</widget>
</item>
- <item row="1" column="1" rowspan="2">
+ <item row="2" column="1" rowspan="2">
<widget class="QComboBox" name="midiDivisionSelect">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
@@ -1225,7 +1225,7 @@ Adjusts responsiveness of audio controls and
</item>
</widget>
</item>
- <item row="2" column="0">
+ <item row="3" column="0">
<widget class="QLabel" name="midiResLabel">
<property name="text">
<string>Midi Resolution
@@ -1236,7 +1236,7 @@ Adjusts responsiveness of audio controls and
</property>
</widget>
</item>
- <item row="3" column="0">
+ <item row="4" column="0">
<widget class="QLabel" name="TextLabel4">
<property name="text">
<string>Displayed Resolution
@@ -1247,7 +1247,7 @@ Adjusts responsiveness of audio controls and
</property>
</widget>
</item>
- <item row="3" column="1">
+ <item row="4" column="1">
<widget class="QComboBox" name="guiDivisionSelect">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
@@ -1305,6 +1305,13 @@ Adjusts responsiveness of audio controls and
</item>
</widget>
</item>
+ <item row="0" column="0">
+ <widget class="QCheckBox" name="warnIfBadTimingCheckBox">
+ <property name="text">
+ <string>Warn if timer frequency is inadequate</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</item>
@@ -1326,7 +1333,7 @@ Adjusts responsiveness of audio controls and
<property name="title">
<string>Behavior</string>
</property>
- <layout class="QGridLayout">
+ <layout class="QGridLayout" name="gridLayout7">
<item row="0" column="0">
<widget class="QLabel" name="TextLabel1">
<property name="text">
@@ -1337,7 +1344,7 @@ Adjusts responsiveness of audio controls and
</property>
</widget>
</item>
- <item row="0" column="1">
+ <item row="0" column="2">
<widget class="QSpinBox" name="guiRefreshSelect">
<property name="suffix">
<string>/sec</string>
@@ -1363,7 +1370,7 @@ Adjusts responsiveness of audio controls and
</property>
</widget>
</item>
- <item row="1" column="1">
+ <item row="1" column="2">
<widget class="QCheckBox" name="oldStyleStopCheckBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
@@ -1376,7 +1383,7 @@ Adjusts responsiveness of audio controls and
</property>
</widget>
</item>
- <item row="2" column="0">
+ <item row="2" column="0" colspan="2">
<widget class="QLabel" name="textLabel1_4_2">
<property name="text">
<string>Move single armed track with selection</string>
@@ -1386,7 +1393,7 @@ Adjusts responsiveness of audio controls and
</property>
</widget>
</item>
- <item row="2" column="1">
+ <item row="2" column="2">
<widget class="QCheckBox" name="moveArmedCheckBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
@@ -1409,7 +1416,7 @@ Adjusts responsiveness of audio controls and
</property>
</widget>
</item>
- <item row="3" column="1">
+ <item row="3" column="2">
<widget class="QCheckBox" name="projectSaveCheckBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
@@ -1422,7 +1429,7 @@ Adjusts responsiveness of audio controls and
</property>
</widget>
</item>
- <item row="4" column="0">
+ <item row="4" column="0" colspan="2">
<widget class="QLabel" name="TextLabel1_3">
<property name="toolTip">
<string/>
@@ -1432,7 +1439,7 @@ Adjusts responsiveness of audio controls and
</property>
</widget>
</item>
- <item row="4" column="1">
+ <item row="4" column="2">
<widget class="QCheckBox" name="popsDefStayOpenCheckBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
@@ -1449,7 +1456,7 @@ Otherwise, hold Ctrl to keep them open.</string>
</property>
</widget>
</item>
- <item row="5" column="0">
+ <item row="5" column="0" colspan="2">
<widget class="QLabel" name="label_2">
<property name="toolTip">
<string>In some areas, the middle mouse button decreases
@@ -1462,7 +1469,7 @@ left button behave like the middle button in such areas.</string>
</property>
</widget>
</item>
- <item row="5" column="1">
+ <item row="5" column="2">
<widget class="QCheckBox" name="lmbDecreasesCheckBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
@@ -1475,7 +1482,14 @@ left button behave like the middle button in such areas.</string>
</property>
</widget>
</item>
- <item row="6" column="1">
+ <item row="6" column="0" colspan="2">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Shift + Right click sets left range marker</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="2">
<widget class="QCheckBox" name="rangeMarkerWithoutMMBCheckBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
@@ -1488,42 +1502,35 @@ left button behave like the middle button in such areas.</string>
</property>
</widget>
</item>
- <item row="6" column="0">
- <widget class="QLabel" name="label_3">
+ <item row="7" column="0" colspan="2">
+ <widget class="QLabel" name="label_4">
<property name="text">
- <string>Shift + Right click sets left range marker</string>
+ <string>Allow adding hidden tracks in track list menu</string>
</property>
</widget>
</item>
- <item row="7" column="1">
+ <item row="7" column="2">
<widget class="QCheckBox" name="addHiddenCheckBox">
<property name="text">
<string/>
</property>
</widget>
</item>
- <item row="7" column="0">
- <widget class="QLabel" name="label_4">
- <property name="text">
- <string>Allow adding hidden tracks in track list menu</string>
- </property>
- </widget>
- </item>
- <item row="8" column="0">
+ <item row="8" column="0" colspan="2">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Unhide tracks when adding hidden tracks</string>
</property>
</widget>
</item>
- <item row="8" column="1">
+ <item row="8" column="2">
<widget class="QCheckBox" name="unhideTracksCheckBox">
<property name="text">
<string/>
</property>
</widget>
</item>
- <item row="9" column="0">
+ <item row="9" column="0" colspan="2">
<widget class="QLabel" name="label5">
<property name="text">
<string>Smart focus</string>
@@ -1533,7 +1540,7 @@ left button behave like the middle button in such areas.</string>
</property>
</widget>
</item>
- <item row="9" column="1">
+ <item row="9" column="2">
<widget class="QCheckBox" name="smartFocusCheckBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
@@ -1553,7 +1560,21 @@ left button behave like the middle button in such areas.</string>
</property>
</widget>
</item>
- <item row="10" column="0">
+ <item row="10" column="0" colspan="2">
+ <widget class="QLabel" name="label_6">
+ <property name="text">
+ <string>Show midi velocity graphs per-note</string>
+ </property>
+ </widget>
+ </item>
+ <item row="10" column="2">
+ <widget class="QCheckBox" name="velocityPerNoteCheckBox">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="11" column="1">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
@@ -1677,8 +1698,8 @@ left button behave like the middle button in such areas.</string>
<rect>
<x>0</x>
<y>0</y>
- <width>96</width>
- <height>26</height>
+ <width>474</width>
+ <height>410</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
diff --git a/muse2/muse/widgets/midi_warn_init_pending_impl.h b/muse2/muse/widgets/midi_warn_init_pending_impl.h
index d24ee129..3a4b8c50 100644
--- a/muse2/muse/widgets/midi_warn_init_pending_impl.h
+++ b/muse2/muse/widgets/midi_warn_init_pending_impl.h
@@ -37,4 +37,4 @@ public:
} // namespace MusEGui
-#endif \ No newline at end of file
+#endif
diff --git a/muse2/muse/widgets/musewidgetsplug.cpp b/muse2/muse/widgets/musewidgetsplug.cpp
index 70cdcd0f..967ab9ac 100644
--- a/muse2/muse/widgets/musewidgetsplug.cpp
+++ b/muse2/muse/widgets/musewidgetsplug.cpp
@@ -54,7 +54,7 @@ static const char* valu[] = {
};
MusEGlobal::GlobalConfigValues config = {
- 190, // globalAlphaBlend
+ 170, // globalAlphaBlend
{
QColor(0xff, 0xff, 0xff), // palette
QColor(0xff, 0xff, 0xff),
@@ -158,6 +158,8 @@ MusEGlobal::GlobalConfigValues config = {
true, // midiSendInit Send instrument initialization sequences
true, // warnInitPending Warn instrument initialization sequences pending
false, // midiSendCtlDefaults Send instrument controller defaults at position 0 if none in song
+ true, // warnIfBadTiming Warn if timer res not good
+ false, // velocityPerNote Whether to show per-note or all velocities
-60, // int minMeter;
-60.0, // double minSlider;
false, // use Jack freewheel
diff --git a/muse2/muse/widgets/warn_bad_timing.cpp b/muse2/muse/widgets/warn_bad_timing.cpp
new file mode 100644
index 00000000..38721d36
--- /dev/null
+++ b/muse2/muse/widgets/warn_bad_timing.cpp
@@ -0,0 +1,33 @@
+//=========================================================
+// MusE
+// Linux Music Editor
+// warn_bad_timing.cpp
+// (C) Copyright 2012 Tim E. Real (terminator356 on users dot sourceforge dot net)
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; version 2 of
+// the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=========================================================
+
+#include "warn_bad_timing.h"
+
+namespace MusEGui {
+
+WarnBadTimingDialog::WarnBadTimingDialog()
+{
+ setupUi(this);
+}
+
+} // namespace MusEGui
+
diff --git a/muse2/muse/widgets/warn_bad_timing.h b/muse2/muse/widgets/warn_bad_timing.h
new file mode 100644
index 00000000..4e6ce77e
--- /dev/null
+++ b/muse2/muse/widgets/warn_bad_timing.h
@@ -0,0 +1,41 @@
+//=========================================================
+// MusE
+// Linux Music Editor
+// warn_bad_timing.h
+// (C) Copyright 2012 Tim E. Real (terminator356 on users dot sourceforge dot net)
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; version 2 of
+// the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=========================================================
+#ifndef __WARN_BAD_TIMING_H__
+#define __WARN_BAD_TIMING_H__
+
+#include "ui_warn_bad_timing.h"
+
+namespace MusEGui {
+
+class WarnBadTimingDialog : public QDialog, public Ui::warnBadTimingBase
+{
+ Q_OBJECT
+
+public:
+ WarnBadTimingDialog();
+ bool dontAsk() const { return dontAskAgain->isChecked(); }
+ void setLabelText(const QString& s) { label->setText(s); }
+};
+
+} // namespace MusEGui
+
+#endif
diff --git a/muse2/muse/widgets/warn_bad_timing.ui b/muse2/muse/widgets/warn_bad_timing.ui
new file mode 100644
index 00000000..7c92850f
--- /dev/null
+++ b/muse2/muse/widgets/warn_bad_timing.ui
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>warnBadTimingBase</class>
+ <widget class="QDialog" name="warnBadTimingBase">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>371</width>
+ <height>207</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>Bad timing</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Message here</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::AutoText</enum>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="dontAskAgain">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Don't ask me again</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Ok</set>
+ </property>
+ <property name="centerButtons">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>warnBadTimingBase</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>warnBadTimingBase</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/muse2/share/instruments/gm.idf b/muse2/share/instruments/gm.idf
index 6c346eb2..cdfff7e5 100644
--- a/muse2/share/instruments/gm.idf
+++ b/muse2/share/instruments/gm.idf
@@ -201,5 +201,7 @@
<Controller name="FineTuning" type="RPN" h="0" l="1" min="-64" max="63" init="0" />
<Controller name="Pitch" type="Pitch" />
<Controller name="Program" type="Program" />
+ <Controller name="PolyAftertouch" type="PolyAftertouch" />
+ <Controller name="Aftertouch" type="Aftertouch" />
</MidiInstrument>
</muse>
diff --git a/muse2/share/templates/MusE.cfg b/muse2/share/templates/MusE.cfg
index 4d5840d6..7df28f44 100644
--- a/muse2/share/templates/MusE.cfg
+++ b/muse2/share/templates/MusE.cfg
@@ -3,6 +3,10 @@
<configuration>
<division>384</division>
<rtcTicks>1024</rtcTicks>
+ <midiSendInit>1</midiSendInit>
+ <warnInitPending>1</warnInitPending>
+ <midiSendCtlDefaults>0</midiSendCtlDefaults>
+ <warnIfBadTiming>1</warnIfBadTiming>
<minMeter>-60</minMeter>
<minSlider>-60</minSlider>
<freewheelMode>0</freewheelMode>
@@ -61,6 +65,7 @@
<outputTracksVisible>0</outputTracksVisible>
<synthTracksVisible>0</synthTracksVisible>
<smartFocus>1</smartFocus>
+ <velocityPerNote>0</velocityPerNote>
<unhideTracks>1</unhideTracks>
<addHiddenTracks>1</addHiddenTracks>
<waveTracksVisible>1</waveTracksVisible>
@@ -77,7 +82,7 @@
<font4>arial,8,-1,5,50,0,0,0,0,0</font4>
<font5>arial,8,-1,5,75,0,0,0,0,0</font5>
<font6>arial,8,-1,5,75,1,0,0,0,0</font6>
- <globalAlphaBlend>190</globalAlphaBlend>
+ <globalAlphaBlend>170</globalAlphaBlend>
<palette0 r="255" g="255" b="255"></palette0>
<palette1 r="255" g="255" b="255"></palette1>
<palette2 r="255" g="255" b="255"></palette2>
diff --git a/muse2/xpm/velo_all.xpm b/muse2/xpm/velo_all.xpm
new file mode 100644
index 00000000..4c8a509f
--- /dev/null
+++ b/muse2/xpm/velo_all.xpm
@@ -0,0 +1,23 @@
+/* XPM */
+static const char * velo_all_xpm[] = {
+"15 15 5 1",
+" c None",
+". c #58A8FF",
+"+ c #000000",
+"@ c #FFFFFF",
+"# c #ED7700",
+"...............",
+".++++@.........",
+".+++++.+.+.+##.",
+".++++@......##.",
+".@@@@@......##.",
+".@@@@@......##.",
+".++++@......##.",
+".++++++.+##.##.",
+".++++@...##.##.",
+".@@@@@...##.##.",
+".@@@@@...##.##.",
+".++++@...##.##.",
+".+++++##.##.##.",
+".++++@##.##.##.",
+"..............."};
diff --git a/muse2/xpm/velo_per_note.xpm b/muse2/xpm/velo_per_note.xpm
new file mode 100644
index 00000000..1962f0e7
--- /dev/null
+++ b/muse2/xpm/velo_per_note.xpm
@@ -0,0 +1,25 @@
+/* XPM */
+static const char * velo_per_note_xpm[] = {
+"15 15 7 1",
+" c None",
+". c #58A8FF",
+"+ c #000000",
+"@ c #FFFFFF",
+"# c #D6D600",
+"$ c #FFFF00",
+"% c #ED7700",
+"...............",
+".++++@.........",
+".+++++.........",
+".++++@.........",
+".@@@@@.........",
+".@@@@@.........",
+".####@.........",
+".#$$$#+.+%%....",
+".####@...%%....",
+".@@@@@...%%....",
+".@@@@@...%%....",
+".++++@...%%....",
+".+++++...%%....",
+".++++@...%%....",
+"..............."};