diff options
author | Tim E. Real <termtech@rogers.com> | 2012-11-12 04:49:31 +0000 |
---|---|---|
committer | Tim E. Real <termtech@rogers.com> | 2012-11-12 04:49:31 +0000 |
commit | be1005a6031861b91e1a2df33f62e1c5a0a2aeb6 (patch) | |
tree | 89152909549c7dd624f4748f394c3adbcbf65b86 /muse2/muse | |
parent | 31f618e5461553bd7836677f944acfa233e5ae3c (diff) |
Finished Aftertouch controllers
Feature: Piano KB / drum list show coloured dots when per-pitch controllers exist / have data.
Diffstat (limited to 'muse2/muse')
42 files changed, 837 insertions, 1112 deletions
diff --git a/muse2/muse/arranger/pcanvas.cpp b/muse2/muse/arranger/pcanvas.cpp index 3c3e6116..ccd727aa 100644 --- a/muse2/muse/arranger/pcanvas.cpp +++ b/muse2/muse/arranger/pcanvas.cpp @@ -2333,12 +2333,17 @@ void PartCanvas::drawMidiPart(QPainter& p, const QRect&, MusECore::EventList* ev for (MusECore::iEvent i = events->lower_bound(from); i != ito; ++i) { MusECore::EventType type = i->second.type(); + int a = i->second.dataA() | 0xff; if ( ((MusEGlobal::config.canvasShowPartEvent & 1) && (type == MusECore::Note)) - || ((MusEGlobal::config.canvasShowPartEvent & 2) && (type == MusECore::PAfter)) - || ((MusEGlobal::config.canvasShowPartEvent & 4) && (type == MusECore::Controller)) - || ((MusEGlobal::config.canvasShowPartEvent &16) && (type == MusECore::CAfter)) - || ((MusEGlobal::config.canvasShowPartEvent &64) && (type == MusECore::Sysex || type == MusECore::Meta)) + || ((MusEGlobal::config.canvasShowPartEvent & (2 | 4)) == (2 | 4) && + type == MusECore::Controller && a == MusECore::CTRL_POLYAFTER) + || ((MusEGlobal::config.canvasShowPartEvent & 4) && (type == MusECore::Controller) && + (a != MusECore::CTRL_POLYAFTER || (MusEGlobal::config.canvasShowPartEvent & 2)) && + (a != MusECore::CTRL_AFTERTOUCH || (MusEGlobal::config.canvasShowPartEvent & 16))) + || ((MusEGlobal::config.canvasShowPartEvent & (16 | 4)) == (16 | 4) && + type == MusECore::Controller && a == MusECore::CTRL_AFTERTOUCH) + || ((MusEGlobal::config.canvasShowPartEvent & 64) && (type == MusECore::Sysex || type == MusECore::Meta)) ) { int t = i->first + pTick; int th = mt->height(); diff --git a/muse2/muse/ctrl/ctrlcanvas.cpp b/muse2/muse/ctrl/ctrlcanvas.cpp index 6e92f3c6..0028d426 100644 --- a/muse2/muse/ctrl/ctrlcanvas.cpp +++ b/muse2/muse/ctrl/ctrlcanvas.cpp @@ -476,6 +476,7 @@ void CtrlCanvas::songChanged(MusECore::SongChangedFlags_t type) //--------------------------------------------------------- // partControllers +// num is the controller number, in 'MidiController terms' (lo-byte = 0xff for per-note controllers). //--------------------------------------------------------- void CtrlCanvas::partControllers(const MusECore::MidiPart* part, int num, int* dnum, int* didx, MusECore::MidiController** mc, MusECore::MidiCtrlValList** mcvl) @@ -510,20 +511,27 @@ void CtrlCanvas::partControllers(const MusECore::MidiPart* part, int num, int* d MusECore::MidiPort* mp; int di; int 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 || mt->type() == MusECore::Track::MIDI) && - (curDrumPitch >= 0) && ((num & 0xff) == 0xff)) //FINDMICHJETZT does this work? + + if((curDrumPitch >= 0) && ((num & 0xff) == 0xff)) { di = (num & ~0xff) | curDrumPitch; - n = (num & ~0xff) | curDrumPitch; - mp = &MusEGlobal::midiPorts[mt->outPort()]; + if((mt->type() == MusECore::Track::DRUM)) + { + n = (num & ~0xff) | MusEGlobal::drumMap[curDrumPitch].anote; + mp = &MusEGlobal::midiPorts[MusEGlobal::drumMap[curDrumPitch].port]; + } + if(mt->type() == MusECore::Track::NEW_DRUM) + { + n = di; // Simple one-to-one correspondence. + mp = &MusEGlobal::midiPorts[mt->outPort()]; + } + else if(mt->type() == MusECore::Track::MIDI) + { + n = di; // Simple one-to-one correspondence. There is no 'mapping' for piano roll midi - yet. + mp = &MusEGlobal::midiPorts[mt->outPort()]; + } } + else { di = num; @@ -611,7 +619,6 @@ void CtrlCanvas::updateItems() { if(curDrumPitch < 0) continue; - int port = MusEGlobal::drumMap[ctl & 0x7f].port; int chan = MusEGlobal::drumMap[ctl & 0x7f].channel; int cur_port = MusEGlobal::drumMap[curDrumPitch].port; @@ -2026,7 +2033,7 @@ void CtrlCanvas::setCurDrumPitch(int instrument) // Crash protection by Tim. // FIXME: Still, drum list is blank, editor can't edit. Other values of instrument or curDrumPitch just crash too. // Seems only with drum tracks that were created by importing a midi file (then changed to use fluidsynth device?). - if(instrument == -1) curDrumPitch = -1; + if(instrument == -1) curDrumPitch = -1; else if (drumedit->get_instrument_map()[instrument].tracks.contains(curTrack)) curDrumPitch = drumedit->get_instrument_map()[instrument].pitch; diff --git a/muse2/muse/ctrl/ctrlpanel.cpp b/muse2/muse/ctrl/ctrlpanel.cpp index b4d089ff..84d155ea 100644 --- a/muse2/muse/ctrl/ctrlpanel.cpp +++ b/muse2/muse/ctrl/ctrlpanel.cpp @@ -3,6 +3,7 @@ // Linux Music Editor // $Id: ctrlpanel.cpp,v 1.10.2.9 2009/06/14 05:24:45 terminator356 Exp $ // (C) Copyright 1999-2004 Werner Schweer (ws@seh.de) +// (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 diff --git a/muse2/muse/ctrl/ctrlpanel.h b/muse2/muse/ctrl/ctrlpanel.h index 261f982f..a8c24c65 100644 --- a/muse2/muse/ctrl/ctrlpanel.h +++ b/muse2/muse/ctrl/ctrlpanel.h @@ -3,6 +3,7 @@ // Linux Music Editor // $Id: ctrlpanel.h,v 1.2.2.5 2009/06/10 00:34:59 terminator356 Exp $ // (C) Copyright 1999-2001 Werner Schweer (ws@seh.de) +// (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 diff --git a/muse2/muse/driver/jackmidi.cpp b/muse2/muse/driver/jackmidi.cpp index 7306b93c..dbb052e6 100644 --- a/muse2/muse/driver/jackmidi.cpp +++ b/muse2/muse/driver/jackmidi.cpp @@ -848,7 +848,7 @@ bool MidiJackDevice::processEvent(const MidiPlayEvent& event) 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()); + //printf("MidiJackDevice::processEvent CTRL_POLYAFTER 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; } diff --git a/muse2/muse/event.h b/muse2/muse/event.h index e31fb116..8da37d4f 100644 --- a/muse2/muse/event.h +++ b/muse2/muse/event.h @@ -39,8 +39,9 @@ class Xml; class EventBase; class WavePart; -enum EventType { Note, Controller, Sysex, PAfter, CAfter, Meta, Wave }; - +// NOTICE: The values 3 and 4 (PAfter and CAfter) are reserved for the support of those two obsolete +// channel and key pressure events in old files. They are converted to controllers upon load. +enum EventType { Note=0, Controller=1, Sysex=2, /*PAfter=3,*/ /*CAfter=4,*/ Meta=5, Wave=6 }; //--------------------------------------------------------- // Event diff --git a/muse2/muse/eventlist.cpp b/muse2/muse/eventlist.cpp index 25acd5a8..50ba2652 100644 --- a/muse2/muse/eventlist.cpp +++ b/muse2/muse/eventlist.cpp @@ -64,7 +64,7 @@ void EventList::read(Xml& xml, const char* name, bool midi) iEvent EventList::add(Event& event) { - // Added by T356. An event list containing wave events should be sorted by + // Changed by Tim. An event list containing wave events should be sorted by // frames. WaveTrack::fetchData() relies on the sorting order, and // there was a bug that waveparts were sometimes muted because of // incorrect sorting order (by ticks). @@ -74,12 +74,6 @@ iEvent EventList::add(Event& event) // Note that in a med file, the tempo list is loaded AFTER all the tracks. // There was a bug that all the wave events' tick values were not correct, // since they were computed BEFORE the tempo map was loaded. -// REMOVE Tim. Original -// if(event.type() == Wave) -// return std::multimap<unsigned, Event, std::less<unsigned> >::insert(std::pair<const unsigned, Event> (event.frame(), event)); -// else -// -// return std::multimap<unsigned, Event, std::less<unsigned> >::insert(std::pair<const unsigned, Event> (event.tick(), event)); if(event.type() == Wave) return insert(std::pair<const unsigned, Event> (event.frame(), event)); @@ -108,13 +102,6 @@ void EventList::move(Event& event, unsigned tick) iEvent i = find(event); erase(i); -// REMOVE Tim. Original. -// if(event.type() == Wave) -// std::multimap<unsigned, Event, std::less<unsigned> >::insert(std::pair<const unsigned, Event> (MusEGlobal::tempomap.tick2frame(tick), event)); -// else -// -// std::multimap<unsigned, Event, std::less<unsigned> >::insert(std::pair<const unsigned, Event> (tick, event)); - if(event.type() == Wave) { insert(std::pair<const unsigned, Event> (MusEGlobal::tempomap.tick2frame(tick), event)); diff --git a/muse2/muse/exportmidi.cpp b/muse2/muse/exportmidi.cpp index 8e10884c..e5cd74e1 100644 --- a/muse2/muse/exportmidi.cpp +++ b/muse2/muse/exportmidi.cpp @@ -84,7 +84,7 @@ static void addController(MPEventList* l, int tick, int port, int channel, int a int lb = (b >> 8) & 0xff; int pr = b & 0x7f; int tickoffset = 0; - // REMOVE Tim. Song type removal. + // REMOVE Tim. Song type removal. Hm, TEST is this OK here? //switch(MusEGlobal::song->mtype()) { // case MT_GM: // no HBANK/LBANK // break; @@ -204,15 +204,6 @@ static void addEventList(MusECore::EventList* evlist, MusECore::MPEventList* mpe //mpevlist->add(ev); } break; - - case MusECore::PAfter: - mpevlist->add(MusECore::MidiPlayEvent(tick, port, channel, MusECore::ME_AFTERTOUCH, ev.dataA(), ev.dataB())); - break; - - case MusECore::CAfter: - mpevlist->add(MusECore::MidiPlayEvent(tick, port, channel, MusECore::ME_POLYAFTER, ev.dataA(), ev.dataB())); - break; - case MusECore::Meta: { MusECore::MidiPlayEvent mpev(tick, port, MusECore::ME_META, ev.eventData()); diff --git a/muse2/muse/icons.cpp b/muse2/muse/icons.cpp index 45aff5ee..9a36b11b 100644 --- a/muse2/muse/icons.cpp +++ b/muse2/muse/icons.cpp @@ -186,11 +186,15 @@ #include "xpm/redled.xpm" #include "xpm/darkredled.xpm" #include "xpm/greendot.xpm" +#include "xpm/greendot12x12.xpm" #include "xpm/reddot.xpm" //#include "xpm/darkgreendot.xpm" #include "xpm/bluedot.xpm" +#include "xpm/bluedot12x12.xpm" #include "xpm/graydot.xpm" +#include "xpm/graydot12x12.xpm" #include "xpm/orangedot.xpm" +#include "xpm/orangedot12x12.xpm" #include "xpm/off.xpm" #include "xpm/blacksquare.xpm" #include "xpm/blacksqcheck.xpm" @@ -429,11 +433,15 @@ QPixmap* toggle_small_Icon; QPixmap* redLedIcon; QPixmap* darkRedLedIcon; QPixmap* greendotIcon; +QPixmap* greendot12x12Icon; QPixmap* reddotIcon; //QPixmap* darkgreendotIcon; QPixmap* graydotIcon; +QPixmap* graydot12x12Icon; QPixmap* bluedotIcon; +QPixmap* bluedot12x12Icon; QPixmap* orangedotIcon; +QPixmap* orangedot12x12Icon; QPixmap* offIcon; QPixmap* blacksquareIcon; QPixmap* blacksqcheckIcon; @@ -655,11 +663,15 @@ void initIcons() redLedIcon = new MPIXMAP(redled_xpm, NULL); darkRedLedIcon = new MPIXMAP(darkredled_xpm, NULL); greendotIcon = new MPIXMAP(greendot_xpm, NULL); + greendot12x12Icon = new MPIXMAP(greendot12x12_xpm, NULL); reddotIcon = new MPIXMAP(reddot_xpm, NULL); //darkgreendotIcon = new MPIXMAP(darkgreendot_xpm, NULL); bluedotIcon = new MPIXMAP(bluedot_xpm, NULL); + bluedot12x12Icon = new MPIXMAP(bluedot12x12_xpm, NULL); graydotIcon = new MPIXMAP(graydot_xpm, NULL); + graydot12x12Icon = new MPIXMAP(graydot12x12_xpm, NULL); orangedotIcon = new MPIXMAP(orangedot_xpm, NULL); + orangedot12x12Icon = new MPIXMAP(orangedot12x12_xpm, NULL); offIcon = new MPIXMAP(off_xpm, NULL); blacksquareIcon = new MPIXMAP(blacksquare_xpm, NULL); blacksqcheckIcon = new MPIXMAP(blacksqcheck_xpm, NULL); diff --git a/muse2/muse/icons.h b/muse2/muse/icons.h index 04a8df26..673392da 100644 --- a/muse2/muse/icons.h +++ b/muse2/muse/icons.h @@ -167,11 +167,15 @@ extern QPixmap* toggle_small_Icon; extern QPixmap* redLedIcon; extern QPixmap* darkRedLedIcon; extern QPixmap* greendotIcon; +extern QPixmap* greendot12x12Icon; extern QPixmap* reddotIcon; //extern QPixmap* darkgreendotIcon; extern QPixmap* graydotIcon; +extern QPixmap* graydot12x12Icon; extern QPixmap* bluedotIcon; +extern QPixmap* bluedot12x12Icon; extern QPixmap* orangedotIcon; +extern QPixmap* orangedot12x12Icon; extern QPixmap* offIcon; extern QPixmap* blacksquareIcon; extern QPixmap* blacksqcheckIcon; diff --git a/muse2/muse/instruments/editinstrument.cpp b/muse2/muse/instruments/editinstrument.cpp index 3dc4488d..c0d82595 100644 --- a/muse2/muse/instruments/editinstrument.cpp +++ b/muse2/muse/instruments/editinstrument.cpp @@ -4,6 +4,7 @@ // $Id: editinstrument.cpp,v 1.2.2.6 2009/05/31 05:12:12 terminator356 Exp $ // // (C) Copyright 2003 Werner Schweer (ws@seh.de) +// (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 @@ -71,6 +72,19 @@ EditInstrument::EditInstrument(QWidget* parent, Qt::WFlags fl) : QMainWindow(parent, fl) { setupUi(this); + + ctrlType->addItem(tr("Control7"), MusECore::MidiController::Controller7); + ctrlType->addItem(tr("Control14"), MusECore::MidiController::Controller14); + ctrlType->addItem(tr("RPN"), MusECore::MidiController::RPN); + ctrlType->addItem(tr("NPRN"), MusECore::MidiController::NRPN); + ctrlType->addItem(tr("RPN14"), MusECore::MidiController::RPN14); + ctrlType->addItem(tr("NRPN14"), MusECore::MidiController::NRPN14); + ctrlType->addItem(tr("Pitch"), MusECore::MidiController::Pitch); + ctrlType->addItem(tr("Program"), MusECore::MidiController::Program); + ctrlType->addItem(tr("PolyAftertouch"), MusECore::MidiController::PolyAftertouch); + ctrlType->addItem(tr("Aftertouch"), MusECore::MidiController::Aftertouch); + ctrlType->setCurrentIndex(0); + fileNewAction->setIcon(QIcon(*filenewIcon)); fileOpenAction->setIcon(QIcon(*openIcon)); fileSaveAction->setIcon(QIcon(*saveIcon)); @@ -189,7 +203,7 @@ 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(ctrlType,SIGNAL(activated(int)), SLOT(ctrlTypeChanged())); + connect(ctrlType,SIGNAL(activated(int)), SLOT(ctrlTypeChanged(int))); connect(ctrlName, SIGNAL(returnPressed()), SLOT(ctrlNameReturn())); connect(ctrlName, SIGNAL(lostFocus()), SLOT(ctrlNameReturn())); connect(spinBoxHCtrlNo, SIGNAL(valueChanged(int)), SLOT(ctrlNumChanged())); @@ -1694,10 +1708,13 @@ void EditInstrument::controllerChanged() ctrlL = -1; MusECore::MidiController::ControllerType type = MusECore::midiControllerType(c->num()); - - ctrlType->blockSignals(true); - ctrlType->setCurrentIndex(type); - ctrlType->blockSignals(false); + int idx = ctrlType->findData(type); + if(idx != -1) + { + ctrlType->blockSignals(true); + ctrlType->setCurrentIndex(idx); + ctrlType->blockSignals(false); + } ctrlShowInMidi->setChecked(c->showInTracks() & MusECore::MidiController::ShowInMidi); ctrlShowInDrum->setChecked(c->showInTracks() & MusECore::MidiController::ShowInDrum); @@ -1872,58 +1889,27 @@ void EditInstrument::ctrlNameReturn() // ctrlTypeChanged //--------------------------------------------------------- -void EditInstrument::ctrlTypeChanged() +void EditInstrument::ctrlTypeChanged(int idx) { QTreeWidgetItem* item = viewController->currentItem(); if (item == 0) return; - MusECore::MidiController::ControllerType t = MusECore::ctrlType2Int(ctrlType->currentText()); + MusECore::MidiController::ControllerType t = (MusECore::MidiController::ControllerType)ctrlType->itemData(idx).toInt(); 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; @@ -1932,57 +1918,21 @@ void EditInstrument::ctrlTypeChanged() 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: @@ -1997,10 +1947,6 @@ void EditInstrument::ctrlTypeChanged() 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. @@ -2033,9 +1979,6 @@ void EditInstrument::ctrlTypeChanged() switch (t) { case MusECore::MidiController::Controller7: - //spinBoxMin->setEnabled(true); - //spinBoxMax->setEnabled(true); - //enableDefaultControls(true, false); spinBoxMin->setRange(-128, 127); spinBoxMax->setRange(-128, 127); spinBoxMin->setValue(0); @@ -2053,9 +1996,6 @@ void EditInstrument::ctrlTypeChanged() break; case MusECore::MidiController::RPN: case MusECore::MidiController::NRPN: - //spinBoxMin->setEnabled(true); - //spinBoxMax->setEnabled(true); - //enableDefaultControls(true, false); spinBoxMin->setRange(-128, 127); spinBoxMax->setRange(-128, 127); spinBoxMin->setValue(0); @@ -2074,9 +2014,6 @@ void EditInstrument::ctrlTypeChanged() case MusECore::MidiController::Controller14: case MusECore::MidiController::RPN14: case MusECore::MidiController::NRPN14: - //spinBoxMin->setEnabled(true); - //spinBoxMax->setEnabled(true); - //enableDefaultControls(true, false); spinBoxMin->setRange(-16384, 16383); spinBoxMax->setRange(-16384, 16383); spinBoxMin->setValue(0); @@ -2093,9 +2030,6 @@ void EditInstrument::ctrlTypeChanged() item->setText(COL_DEF, QString("---")); break; case MusECore::MidiController::Pitch: - //spinBoxMin->setEnabled(true); - //spinBoxMax->setEnabled(true); - //enableDefaultControls(true, false); spinBoxMin->setRange(-8192, 8191); spinBoxMax->setRange(-8192, 8191); spinBoxMin->setValue(-8192); @@ -2110,9 +2044,6 @@ void EditInstrument::ctrlTypeChanged() 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); @@ -2126,9 +2057,6 @@ void EditInstrument::ctrlTypeChanged() item->setText(COL_DEF, QString("---")); break; case MusECore::MidiController::Program: - //spinBoxMin->setEnabled(false); - //spinBoxMax->setEnabled(false); - //enableDefaultControls(false, true); spinBoxMin->setRange(0, 0); spinBoxMax->setRange(0, 0); spinBoxMin->setValue(0); @@ -2224,100 +2152,6 @@ void EditInstrument::ctrlShowInDrumChanged(int state) 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); - item->setText(COL_HNUM, s); - item->setText(COL_TYPE, ctrlType->currentText()); - workingInstrument.setDirty(true); - } - -//--------------------------------------------------------- -// ctrlLNumChanged -//--------------------------------------------------------- - -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 = 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 - { - 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 //--------------------------------------------------------- @@ -2325,9 +2159,9 @@ void EditInstrument::ctrlLNumChanged(int val) void EditInstrument::ctrlNumChanged() { QTreeWidgetItem* item = viewController->currentItem(); - if (item == 0) + if (item == 0 || ctrlType->currentIndex() == -1) return; - MusECore::MidiController::ControllerType t = MusECore::ctrlType2Int(ctrlType->currentText()); + MusECore::MidiController::ControllerType t = (MusECore::MidiController::ControllerType)ctrlType->itemData(ctrlType->currentIndex()).toInt(); int hnum = 0, lnum = 0; switch (t) { case MusECore::MidiController::Controller7: @@ -2361,15 +2195,9 @@ void EditInstrument::ctrlNumChanged() 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)) { @@ -3270,87 +3098,9 @@ void EditInstrument::addControllerClicked() if(cl->find(num) == cl->end()) pup->addAction(MusECore::midiCtrlName(num, true))->setData(num); } - 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); } //--------------------------------------------------------- diff --git a/muse2/muse/instruments/editinstrument.h b/muse2/muse/instruments/editinstrument.h index ac4da064..ff156988 100644 --- a/muse2/muse/instruments/editinstrument.h +++ b/muse2/muse/instruments/editinstrument.h @@ -4,6 +4,7 @@ // $Id: editinstrument.h,v 1.1.1.1.2.4 2009/05/31 05:12:12 terminator356 Exp $ // // (C) Copyright 2003 Werner Schweer (ws@seh.de) +// (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 @@ -102,7 +103,7 @@ class EditInstrument : public QMainWindow, public Ui::EditInstrumentBase { void newControllerClicked(); void addControllerClicked(); void ctrlPopupTriggered(QAction*); - void ctrlTypeChanged(); + void ctrlTypeChanged(int); void ctrlNameReturn(); void ctrlNumChanged(); void ctrlMinChanged(int); diff --git a/muse2/muse/instruments/editinstrumentbase.ui b/muse2/muse/instruments/editinstrumentbase.ui index 8e3e7db0..5140b27d 100644 --- a/muse2/muse/instruments/editinstrumentbase.ui +++ b/muse2/muse/instruments/editinstrumentbase.ui @@ -1206,56 +1206,6 @@ Typically, set to 127/127, or an unused <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> diff --git a/muse2/muse/liste/editctrlbase.ui b/muse2/muse/liste/editctrlbase.ui index 036b4525..c63e1c22 100644 --- a/muse2/muse/liste/editctrlbase.ui +++ b/muse2/muse/liste/editctrlbase.ui @@ -545,7 +545,7 @@ </widget> </item> <item row="2" column="0"> - <widget class="QLabel" name="textLabel2_3"> + <widget class="QLabel" name="noteLabel"> <property name="text"> <string>Note</string> </property> diff --git a/muse2/muse/liste/editevent.cpp b/muse2/muse/liste/editevent.cpp index fac6866d..e75a7359 100644 --- a/muse2/muse/liste/editevent.cpp +++ b/muse2/muse/liste/editevent.cpp @@ -148,28 +148,6 @@ MusECore::Event EditMetaDialog::getEvent(int tick, const MusECore::Event& event, return nevent; } -MusECore::Event EditCAfterDialog::getEvent(int tick, const MusECore::Event& event, QWidget* parent) - { - EditEventDialog* dlg = new EditCAfterDialog(tick, event, parent); - MusECore::Event nevent; - if (dlg->exec() == QDialog::Accepted) { - nevent = dlg->event(); - } - delete dlg; - return nevent; - } - -MusECore::Event EditPAfterDialog::getEvent(int tick, const MusECore::Event& event, QWidget* parent) - { - EditEventDialog* dlg = new EditPAfterDialog(tick, event, parent); - MusECore::Event nevent; - if (dlg->exec() == QDialog::Accepted) { - nevent = dlg->event(); - } - delete dlg; - return nevent; - } - //--------------------------------------------------------- // EditEventDialog //--------------------------------------------------------- @@ -434,128 +412,6 @@ void EditMetaDialog::accept() } //--------------------------------------------------------- -// EditCAfterDialog -//--------------------------------------------------------- - -EditCAfterDialog::EditCAfterDialog(int tick, const MusECore::Event& event, - QWidget* parent) - : EditEventDialog(parent) - { - setWindowTitle(tr("MusE: Enter Channel Aftertouch")); - - QLabel* l1 = new QLabel(tr("Time Position")); - epos = new Awl::PosEdit; - - QLabel* l2 = new QLabel(tr("Pressure")); - il2 = new MusEGui::IntLabel(-1, 0, 127, this, -1); - il2->setFrame(true); - il2->setDark(); - - QSlider* slider = new QSlider(Qt::Horizontal); - slider->setMinimum(0); - slider->setMaximum(127); - slider->setPageStep(1); - slider->setValue(0); - - connect(slider, SIGNAL(valueChanged(int)), il2, SLOT(setValue(int))); - connect(il2, SIGNAL(valueChanged(int)), slider, SLOT(setValue(int))); - - if (!event.empty()) { - epos->setValue(tick); - il2->setValue(event.dataA()); - slider->setValue(event.dataA()); - } - else { - epos->setValue(tick); - il2->setValue(64); - slider->setValue(64); - } - - layout1->addWidget(l1, 0, 0); - layout1->addWidget(epos, 0, 1, Qt::AlignLeft); - layout1->addWidget(l2, 1, 0); - layout1->addWidget(il2, 1, 1, Qt::AlignLeft); - //layout1->addMultiCellWidget(slider, 2, 2, 0, 1); - layout1->addWidget(slider, 2, 0, 1, 2); - } - -//--------------------------------------------------------- -// EditCAfterDialog::event -//--------------------------------------------------------- - -MusECore::Event EditCAfterDialog::event() - { - MusECore::Event event(MusECore::CAfter); - event.setTick(epos->pos().tick()); - event.setA(il2->value()); - return event; - } - -//--------------------------------------------------------- -// EditPAfterDialog -//--------------------------------------------------------- - -EditPAfterDialog::EditPAfterDialog(int tick, const MusECore::Event& event, - QWidget* parent) - : EditEventDialog(parent) - { - setWindowTitle(tr("MusE: Enter Poly Aftertouch")); - - QLabel* l1 = new QLabel(tr("Time Position")); - epos = new Awl::PosEdit; - - QLabel* l2 = new QLabel(tr("Pitch")); - pl = new MusEGui::PitchEdit; - QLabel* l3 = new QLabel(tr("Pressure")); - il2 = new MusEGui::IntLabel(-1, 0, 127, this, -1); - il2->setFrame(true); - il2->setDark(); - - QSlider* slider = new QSlider(Qt::Horizontal); - slider->setMinimum(0); - slider->setMaximum(127); - slider->setPageStep(1); - slider->setValue(0); - - connect(slider, SIGNAL(valueChanged(int)), il2, SLOT(setValue(int))); - connect(il2, SIGNAL(valueChanged(int)), slider, SLOT(setValue(int))); - - if (!event.empty()) { - epos->setValue(tick); - pl->setValue(event.pitch()); - il2->setValue(event.dataB()); - slider->setValue(event.dataB()); - } - else { - epos->setValue(tick); - pl->setValue(64); - il2->setValue(64); - slider->setValue(64); - } - - layout1->addWidget(l1, 0, 0); - layout1->addWidget(epos, 0, 1, Qt::AlignLeft); - layout1->addWidget(l2, 1, 0); - layout1->addWidget(pl, 1, 1, Qt::AlignLeft); - layout1->addWidget(l3, 2, 0); - layout1->addWidget(il2, 2, 1, Qt::AlignLeft); - //layout1->addMultiCellWidget(slider, 3, 3, 0, 1); - layout1->addWidget(slider, 3, 0, 1, 2); - } - -//--------------------------------------------------------- -// EditPAfterDialog::event -//--------------------------------------------------------- - -MusECore::Event EditPAfterDialog::event() - { - MusECore::Event event(MusECore::PAfter); - event.setTick(epos->pos().tick()); - event.setA(pl->value()); - event.setB(il2->value()); - return event; - } -//--------------------------------------------------------- // getEvent //--------------------------------------------------------- @@ -579,11 +435,64 @@ MusECore::Event EditCtrlDialog::event() { MusECore::Event event(MusECore::Controller); event.setTick(timePos->pos().tick()); - event.setA(num); - if (num == MusECore::CTRL_PROGRAM) - event.setB(val); + + int cnum = 0; + QListWidgetItem* item = ctrlList->currentItem(); + if(item != 0) + cnum = item->data(Qt::UserRole).toInt(); + + MusECore::MidiTrack* track = part->track(); + bool isDrum = track->type() == MusECore::Track::DRUM; + MusECore::MidiPort* port = &MusEGlobal::midiPorts[track->outPort()]; + int channel = track->outChannel(); + + int evnum = cnum; + int num = cnum; + if((cnum & 0xff) == 0xff) + { + evnum = (cnum & ~0xff) | (noteSpinBox->value() & 0x7f); + num = evnum; + if(isDrum) + { + MusECore::DrumMap* dm = &MusEGlobal::drumMap[noteSpinBox->value() & 0x7f]; + num = (cnum & ~0xff) | dm->anote; + port = &MusEGlobal::midiPorts[dm->port]; + channel = dm->channel; + } + } + + MusECore::MidiController* c = port->midiController(cnum); + MusECore::MidiCtrlValListList* cll = port->controller(); + + if(cll->find(channel, num) == cll->end()) + { + MusECore::MidiCtrlValList* vl = new MusECore::MidiCtrlValList(num); + cll->add(channel, vl); + } + + event.setA(evnum); + if(cnum == MusECore::CTRL_PROGRAM) + { + int hb = hbank->value(); + int lb = lbank->value(); + int prog = program->value(); + if (hb > 0 && hb < 129) + hb -= 1; + else + hb = 0xff; + if (lb > 0 && lb < 129) + lb -= 1; + else + lb = 0xff; + if (prog > 0 && prog < 129) + prog -= 1; + else + prog = 0xff; + int val = (hb << 16) + (lb << 8) + prog; + event.setB(val); + } else - event.setB(valSlider->value() + MusEGlobal::midiPorts[part->track()->outPort()].midiController(num)->bias()); + event.setB(valSlider->value() + c->bias()); return event; } @@ -597,6 +506,15 @@ MusECore::Event EditCtrlDialog::event() // QPushButton* buttonNewController; //--------------------------------------------------------- +struct CI { + int num; + QString s; + bool used; + bool off; + bool instrument; + CI(int n, const QString& ss, bool u, bool o, bool i) : num(n), s(ss), used(u), off(o), instrument(i) {} + }; + EditCtrlDialog::EditCtrlDialog(int tick, const MusECore::Event& event, const MusECore::MidiPart* p, QWidget* parent) : QDialog(parent), part(p) @@ -605,90 +523,100 @@ EditCtrlDialog::EditCtrlDialog(int tick, const MusECore::Event& event, widgetStack->setAutoFillBackground(true); MusECore::MidiTrack* track = part->track(); - int portn = track->outPort(); - MusECore::MidiPort* port = &MusEGlobal::midiPorts[portn]; + MusECore::MidiPort* port = &MusEGlobal::midiPorts[track->outPort()]; 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; + int channel = track->outChannel(); + MusECore::MidiInstrument* instr = port->instrument(); + MusECore::MidiControllerList* mcl = instr->controller(); + int val = 0; + int ev_num = 0; + int num = 0; + int ev_cnum = 0; + int ev_note = -1; if (!event.empty()) { - num = event.dataA(); + ev_num = event.dataA(); + num = ev_num; + ev_cnum = ev_num; val = event.dataB(); - if(port->drumController(num)) + if(port->drumController(ev_num)) { + ev_cnum |= 0xff; if(isDrum) - num = (num & ~0xff) | MusEGlobal::drumMap[num & 0xff].anote; - note = num & 0xff; + num = (ev_num & ~0xff) | MusEGlobal::drumMap[ev_num & 0xff].anote; + ev_note = ev_num & 0xff; } } - ///pop = new QMenu(this); - //pop->setCheckable(false); //not necessary in Qt4 - + MusECore::MidiController* mc = port->midiController(ev_num); + ctrlList->clear(); ctrlList->setSelectionMode(QAbstractItemView::SingleSelection); - // - // populate list of available controller - // + //--------------------------------------------------- + // build list of midi controllers for current + // MusECore::MidiPort/channel + //--------------------------------------------------- - std::list<QString> sList; - typedef std::list<QString>::iterator isList; + std::list<CI> sList; + typedef std::list<CI>::iterator isList; + std::set<int> already_added_nums; for (MusECore::iMidiCtrlValList it = cll->begin(); it != cll->end(); ++it) { MusECore::MidiCtrlValList* cl = it->second; - int clnum = cl->num(); - - // dont show drum specific controller if not a drum track - //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; - //} - - - { + int ch = it->first >> 24; + if(ch != channel) + continue; + MusECore::MidiController* c = port->midiController(cl->num()); + bool isDrumCtrl = (c->isPerNoteController()); + int show = c->showInTracks(); + int cnum = c->num(); + int clnum = cl->num(); isList i = sList.begin(); for (; i != sList.end(); ++i) { - if (*i == c->name()) + if (i->num == cnum) break; } - if (i == sList.end()) - sList.push_back(c->name()); - } - } - MusECore::MidiController* mc = port->midiController(num); - int idx = 0; - int selectionIndex = 0; - for (isList i = sList.begin(); i != sList.end(); ++i, ++idx) { - ctrlList->addItem(*i); - if (mc->name() == *i) - selectionIndex = idx; + + if (i == sList.end()) { + bool used = (clnum == 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 && + 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(num, + sList.push_back(CI(cnum, + isinstr ? MusECore::midiCtrlNumString(cnum, true) + c->name() : MusECore::midiCtrlName(cnum, true), + used, off, isinstr)); + already_added_nums.insert(num); + } } - ctrlList->item(selectionIndex)->setSelected(true); + // Add instrument-defined controllers: + QListWidgetItem* sel_item = 0; + for (isList i = sList.begin(); i != sList.end(); ++i) + { + // Filter if not used and off. But if there's something there, we must show it. + if(!i->instrument && !i->used && i->off) + continue; + QListWidgetItem* item = new QListWidgetItem(i->s, ctrlList); + item->setData(Qt::UserRole, i->num); + if(i->num == ev_cnum) + sel_item = item; + } + if(sel_item) + ctrlList->setCurrentItem(sel_item); + valSlider->setRange(mc->minVal(), mc->maxVal()); valSpinBox->setRange(mc->minVal(), mc->maxVal()); @@ -696,10 +624,10 @@ EditCtrlDialog::EditCtrlDialog(int tick, const MusECore::Event& event, if(!event.empty()) { - if(num == MusECore::CTRL_PROGRAM) + if(ev_num == MusECore::CTRL_PROGRAM) { widgetStack->setCurrentIndex(1); - updatePatch(); + updatePatch(val); } else { @@ -710,13 +638,17 @@ EditCtrlDialog::EditCtrlDialog(int tick, const MusECore::Event& event, { noteSpinBox->setVisible(true); noteSpinBox->setEnabled(true); - if(note != -1) - noteSpinBox->setValue(note); + noteLabel->setVisible(true); + noteLabel->setEnabled(true); + if(ev_note != -1) + noteSpinBox->setValue(ev_note); } else { noteSpinBox->setEnabled(false); noteSpinBox->setVisible(false); + noteLabel->setEnabled(false); + noteLabel->setVisible(false); } } } @@ -724,7 +656,10 @@ EditCtrlDialog::EditCtrlDialog(int tick, const MusECore::Event& event, { noteSpinBox->setEnabled(false); noteSpinBox->setVisible(false); - ctrlListClicked(ctrlList->selectedItems()[0]); + noteLabel->setEnabled(false); + noteLabel->setVisible(false); + if(sel_item) + ctrlListClicked(sel_item); } connect(ctrlList, SIGNAL(itemClicked(QListWidgetItem*)), SLOT(ctrlListClicked(QListWidgetItem*))); connect(buttonNewController, SIGNAL(clicked()), SLOT(newController())); @@ -759,86 +694,61 @@ void EditCtrlDialog::newController() MusECore::MidiCtrlValListList* cll = port->controller(); int channel = track->outChannel(); - //int nn = 0; for (MusECore::iMidiController ci = mcl->begin(); ci != mcl->end(); ++ci) { - MusECore::MidiController* c = ci->second; - int num = c->num(); + int cnum = 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); + int idx = 0; + for(; idx < ctrlList->count(); ++idx) { + if(ctrlList->item(idx)->data(Qt::UserRole).toInt() == cnum) + break; + } + if(idx >= ctrlList->count()) { + QAction* act = pup->addAction(MusECore::midiCtrlNumString(cnum, true) + c->name()); + act->setData(cnum); } - -// 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))); 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; + int cnum = rv; for (MusECore::iMidiController ci = mcl->begin(); ci != mcl->end(); ++ci) { MusECore::MidiController* mc = ci->second; - //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()) + if (mc->num() == cnum) { + // Create a new controller list if it does not exist. + // FIXME: Sorry no per-pitch controller lists created here + // (meaning you should only create one 'new' one at a time) + // because the user has not had a chance to choose a pitch yet. + // They are handled in accept(), where there are more checks and creations. + if(!mc->isPerNoteController() && cll->find(channel, rv) == cll->end()) { - //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(); // REMOVE Tim. - int item_data = ctrlList->item(idx)->data(Qt::UserRole).toInt(); - //if (s == str) - if (item_data == num) + for (; idx < ctrlList->count() ;++idx) { + QListWidgetItem* item = ctrlList->item(idx); + int item_data = item->data(Qt::UserRole).toInt(); + if(item_data == cnum) { - ctrlList->item(idx)->setSelected(true); - ctrlListClicked(ctrlList->item(idx)); + ctrlList->setCurrentItem(item); + ctrlListClicked(item); break; } } - if (idx >= ctrlList->count()) { // p4.0.25 Fix segfault - //ctrlList->addItem(s); // REMOVE Tim. + if (idx >= ctrlList->count()) { 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)); + new_item->setData(Qt::UserRole, cnum); + ctrlList->setCurrentItem(new_item); + ctrlListClicked(new_item); break; } - - break; } } @@ -851,65 +761,67 @@ void EditCtrlDialog::newController() void EditCtrlDialog::ctrlListClicked(QListWidgetItem* item) { - if (item == 0) - return; - QString s(item->text()); + if(item == 0) + return; + int cnum = item->data(Qt::UserRole).toInt(); + MusECore::MidiTrack* track = part->track(); + int portn = track->outPort(); + MusECore::MidiPort* port = &MusEGlobal::midiPorts[portn]; + MusECore::MidiController* c = port->midiController(cnum); + int val; + if (cnum == MusECore::CTRL_PROGRAM) { + widgetStack->setCurrentIndex(1); + + val = c->initVal(); + if(val == MusECore::CTRL_VAL_UNKNOWN) + val = 0; + updatePatch(val); + } + else { + widgetStack->setCurrentIndex(0); + if(c->isPerNoteController()) + { + noteSpinBox->setEnabled(true); + noteSpinBox->setVisible(true); + noteLabel->setEnabled(true); + noteLabel->setVisible(true); + } + else + { + noteSpinBox->setEnabled(false); + noteSpinBox->setVisible(false); + noteLabel->setEnabled(false); + noteLabel->setVisible(false); + } + valSlider->setRange(c->minVal(), c->maxVal()); + valSpinBox->setRange(c->minVal(), c->maxVal()); + controllerName->setText(c->name()); + val = c->initVal(); - MusECore::MidiTrack* track = part->track(); - int portn = track->outPort(); - MusECore::MidiPort* port = &MusEGlobal::midiPorts[portn]; - MusECore::MidiCtrlValListList* cll = port->controller(); - - MusECore::iMidiCtrlValList i; - for (i = cll->begin(); i != cll->end(); ++i) { - MusECore::MidiCtrlValList* cl = i->second; - num = cl->num(); - MusECore::MidiController* c = port->midiController(num); - if (s == c->name()) { - if (num == MusECore::CTRL_PROGRAM) { - widgetStack->setCurrentIndex(1); - - val = c->initVal(); - if(val == MusECore::CTRL_VAL_UNKNOWN) - val = 0; - updatePatch(); - } - else { - widgetStack->setCurrentIndex(0); - valSlider->setRange(c->minVal(), c->maxVal()); - valSpinBox->setRange(c->minVal(), c->maxVal()); - controllerName->setText(s); - val = c->initVal(); - - if(val == MusECore::CTRL_VAL_UNKNOWN || val == 0) - { - switch(num) - { - case MusECore::CTRL_PANPOT: - val = 64 - c->bias(); - break; - case MusECore::CTRL_VOLUME: - val = 100; - break; - default: - val = 0; - break; - } - } - valSlider->setValue(val); - } - break; - } + if(val == MusECore::CTRL_VAL_UNKNOWN || val == 0) + { + switch(cnum) + { + case MusECore::CTRL_PANPOT: + val = 64 - c->bias(); + break; + case MusECore::CTRL_VOLUME: + val = 100; + break; + default: + val = 0; + break; + } + } + valSlider->setValue(val); } - if (i == cll->end()) - printf("controller %s not found!\n", s.toLatin1().constData()); } //--------------------------------------------------------- // updatePatch //--------------------------------------------------------- -void EditCtrlDialog::updatePatch() +void EditCtrlDialog::updatePatch(int val) { MusECore::MidiTrack* track = part->track(); int port = track->outPort(); @@ -962,8 +874,7 @@ void EditCtrlDialog::instrPopup() QAction* rv = pup->exec(patchName->mapToGlobal(QPoint(10,5))); if (rv) { - val = rv->data().toInt(); - updatePatch(); + updatePatch(rv->data().toInt()); } delete pup; @@ -992,8 +903,8 @@ void EditCtrlDialog::programChanged() else prog = 0xff; - val = (hb << 16) + (lb << 8) + prog; - updatePatch(); + int val = (hb << 16) + (lb << 8) + prog; + updatePatch(val); } } // namespace MusEGui diff --git a/muse2/muse/liste/editevent.h b/muse2/muse/liste/editevent.h index cd02c82e..0674fe30 100644 --- a/muse2/muse/liste/editevent.h +++ b/muse2/muse/liste/editevent.h @@ -112,12 +112,8 @@ class EditSysexDialog : public QDialog, public Ui::EditSysexDialogBase { class EditCtrlDialog : public QDialog, public Ui::EditCtrlBase { Q_OBJECT - int num; // controller number - int val; // controller value (for prog. changes) - const MusECore::MidiPart* part; - - void updatePatch(); + void updatePatch(int val); private slots: void ctrlListClicked(QListWidgetItem*); @@ -128,7 +124,6 @@ class EditCtrlDialog : public QDialog, public Ui::EditCtrlBase { protected: QGridLayout* layout; - public: EditCtrlDialog(int tick, const MusECore::Event&, const MusECore::MidiPart*, QWidget* parent=0); @@ -169,49 +164,6 @@ class EditMetaDialog : public EditEventDialog { virtual MusECore::Event event(); }; -//--------------------------------------------------------- -// EditCAfterDialog -//--------------------------------------------------------- - -class EditCAfterDialog : public EditEventDialog { - Q_OBJECT - - Awl::PosEdit* epos; - MusEGui::IntLabel* il2; - - protected: - QGridLayout* layout; - - public: - EditCAfterDialog(int tick, const MusECore::Event&, - QWidget* parent=0); - static MusECore::Event getEvent(int tick, const MusECore::Event&, - QWidget* parent = 0); - virtual MusECore::Event event(); - }; - -//--------------------------------------------------------- -// EditPAfterDialog -//--------------------------------------------------------- - -class EditPAfterDialog : public EditEventDialog { - Q_OBJECT - - Awl::PosEdit* epos; - MusEGui::PitchEdit* pl; - MusEGui::IntLabel* il2; - - protected: - QGridLayout* layout; - - public: - EditPAfterDialog(int tick, const MusECore::Event&, - QWidget* parent=0); - static MusECore::Event getEvent(int tick, const MusECore::Event&, - QWidget* parent = 0); - virtual MusECore::Event event(); - }; - } // namespace MusEGui #endif diff --git a/muse2/muse/liste/listedit.cpp b/muse2/muse/liste/listedit.cpp index d6bf894a..52958e3c 100644 --- a/muse2/muse/liste/listedit.cpp +++ b/muse2/muse/liste/listedit.cpp @@ -213,35 +213,10 @@ void ListEdit::songChanged(MusECore::SongChangedFlags_t type) } liste->setSortingEnabled(false); if (type == SC_SELECTION) { - - - // DELETETHIS or clean up or whatever? // BUGFIX: I found the keyboard modifier states affect how QTreeWidget::setCurrentItem() operates. // So for example (not) holding shift while lassoo-ing notes in piano roll affected // whether multiple items were selected in this event list editor! // Also blockSignals() definitely required - was messing up selections. p4.0.18 Tim. - /* - bool update = false; - QTreeWidgetItem* ci = 0; - for (int row = 0; row < liste->topLevelItemCount(); ++row) { - QTreeWidgetItem* i = liste->topLevelItem(row); - if (i->isSelected() ^ ((EventListItem*)i)->event.selected()) - { - i->setSelected(((EventListItem*)i)->event.selected()); - if (i->isSelected()) - ci = i; - update = true; - } - } - if (update) - { - if (ci) - { - liste->setCurrentItem(ci); - } - //liste->update(); - } - */ bool ci_done = false; liste->blockSignals(true); // Go backwards to avoid QTreeWidget::setCurrentItem() dependency on KB modifiers! @@ -339,6 +314,8 @@ QString EventListItem::text(int col) const case MusECore::MidiController::NRPN: cs = "NRPN"; break; case MusECore::MidiController::Pitch: cs = "Pitch"; break; case MusECore::MidiController::Program: cs = "Program"; break; + case MusECore::MidiController::PolyAftertouch: cs = "PolyAftertouch"; break; + case MusECore::MidiController::Aftertouch: cs = "Aftertouch"; break; case MusECore::MidiController::RPN14: cs = "RPN14"; break; case MusECore::MidiController::NRPN14: cs = "NRPN14"; break; default: cs = "Ctrl?"; break; @@ -369,12 +346,6 @@ QString EventListItem::text(int col) const } s = QString("SysEx"); break; - case MusECore::PAfter: - s = QString("PoAT"); - break; - case MusECore::CAfter: - s = QString("ChAT"); - break; case MusECore::Meta: commentLabel = midiMetaComment(event); s = QString("Meta"); @@ -389,7 +360,7 @@ QString EventListItem::text(int col) const s.setNum(part->track()->outChannel() + 1); break; case 4: - if (event.isNote() || event.type() == MusECore::PAfter) + if (event.isNote()) s = MusECore::pitch2string(event.dataA()); else if (event.type() == MusECore::Controller) s.setNum(event.dataA() & 0xffff); // mask off type bits @@ -479,15 +450,11 @@ ListEdit::ListEdit(MusECore::PartList* pl) insertSysEx = new QAction(QIcon(*sysexIcon), tr("insert SysEx"), insertItems); insertCtrl = new QAction(QIcon(*ctrlIcon), tr("insert Ctrl"), insertItems); insertMeta = new QAction(QIcon(*metaIcon), tr("insert Meta"), insertItems); - insertCAfter = new QAction(QIcon(*cafterIcon), tr("insert Channel Aftertouch"), insertItems); - insertPAfter = new QAction(QIcon(*pafterIcon), tr("insert Poly Aftertouch"), insertItems); connect(insertNote, SIGNAL(activated()), SLOT(editInsertNote())); connect(insertSysEx, SIGNAL(activated()), SLOT(editInsertSysEx())); connect(insertCtrl, SIGNAL(activated()), SLOT(editInsertCtrl())); connect(insertMeta, SIGNAL(activated()), SLOT(editInsertMeta())); - connect(insertCAfter, SIGNAL(activated()), SLOT(editInsertCAfter())); - connect(insertPAfter, SIGNAL(activated()), SLOT(editInsertPAfter())); //---------Pulldown Menu---------------------------- @@ -717,53 +684,6 @@ void ListEdit::editInsertMeta() } //--------------------------------------------------------- -// editInsertCAfter -//--------------------------------------------------------- - -void ListEdit::editInsertCAfter() - { - if(!curPart) - return; - - MusECore::Event event = EditCAfterDialog::getEvent(curPart->tick(), MusECore::Event(), this); - if (!event.empty()) { - //No events before beginning of part + take Part offset into consideration - unsigned tick = event.tick(); - if (tick < curPart->tick()) - tick = 0; - else - tick-= curPart->tick(); - event.setTick(tick); - // Indicate do undo, and do not handle port controller values. - MusEGlobal::audio->msgAddEvent(event, curPart, true, false, false); - } - } - -//--------------------------------------------------------- -// editInsertPAfter -//--------------------------------------------------------- - -void ListEdit::editInsertPAfter() - { - if(!curPart) - return; - - MusECore::Event ev; - MusECore::Event event = EditPAfterDialog::getEvent(curPart->tick(), ev, this); - if (!event.empty()) { - //No events before beginning of part + take Part offset into consideration - unsigned tick = event.tick(); - if (tick < curPart->tick()) - tick = 0; - else - tick-= curPart->tick(); - event.setTick(tick); - // Indicate do undo, and do not handle port controller values. - MusEGlobal::audio->msgAddEvent(event, curPart, true, false, false); - } - } - -//--------------------------------------------------------- // editEvent //--------------------------------------------------------- @@ -781,12 +701,6 @@ void ListEdit::editEvent(MusECore::Event& event, MusECore::MidiPart* part) case MusECore::Sysex: nevent = EditSysexDialog::getEvent(tick, event, this); break; - case MusECore::PAfter: - nevent = EditPAfterDialog::getEvent(tick, event, this); - break; - case MusECore::CAfter: - nevent = EditCAfterDialog::getEvent(tick, event, this); - break; case MusECore::Meta: nevent = EditMetaDialog::getEvent(tick, event, this); break; @@ -1025,8 +939,6 @@ void ListEdit::initShortcuts() insertSysEx->setShortcut(shortcuts[SHRT_LE_INS_SYSEX].key); insertCtrl->setShortcut(shortcuts[SHRT_LE_INS_CTRL].key); insertMeta->setShortcut(shortcuts[SHRT_LE_INS_META].key); - insertCAfter->setShortcut(shortcuts[SHRT_LE_INS_CHAN_AFTERTOUCH].key); - insertPAfter->setShortcut(shortcuts[SHRT_LE_INS_POLY_AFTERTOUCH].key); } //--------------------------------------------------------- diff --git a/muse2/muse/liste/listedit.h b/muse2/muse/liste/listedit.h index 472ba7b8..5ab4faf7 100644 --- a/muse2/muse/liste/listedit.h +++ b/muse2/muse/liste/listedit.h @@ -68,15 +68,13 @@ class ListEdit : public MidiEditor { virtual void closeEvent(QCloseEvent*); virtual void keyPressEvent(QKeyEvent*); void initShortcuts(); - QAction *insertNote, *insertSysEx, *insertCtrl, *insertMeta, *insertCAfter, *insertPAfter; + QAction *insertNote, *insertSysEx, *insertCtrl, *insertMeta; private slots: void editInsertNote(); void editInsertSysEx(); void editInsertCtrl(); void editInsertMeta(); - void editInsertCAfter(); - void editInsertPAfter(); void editEvent(MusECore::Event&, MusECore::MidiPart*); void selectionChanged(); void doubleClicked(QTreeWidgetItem*); diff --git a/muse2/muse/midi.cpp b/muse2/muse/midi.cpp index 33b98c00..e5b1c62a 100644 --- a/muse2/muse/midi.cpp +++ b/muse2/muse/midi.cpp @@ -280,10 +280,11 @@ void buildMidiEventList(EventList* del, const MPEventList* el, MidiTrack* track, e.setLenTick(0); break; case ME_POLYAFTER: - e.setType(PAfter); - e.setA(ev.dataA()); + e.setType(Controller); + e.setA((CTRL_POLYAFTER & ~0xff) | (ev.dataA() & 0x7f)); e.setB(ev.dataB()); break; + case ME_CONTROLLER: { int val = ev.dataB(); @@ -393,8 +394,9 @@ void buildMidiEventList(EventList* del, const MPEventList* el, MidiTrack* track, break; case ME_AFTERTOUCH: - e.setType(CAfter); - e.setA(ev.dataA()); + e.setType(Controller); + e.setA(CTRL_AFTERTOUCH); + e.setB(ev.dataA()); break; case ME_PITCHBEND: diff --git a/muse2/muse/midictrl.cpp b/muse2/muse/midictrl.cpp index 14dd666e..b45118c2 100644 --- a/muse2/muse/midictrl.cpp +++ b/muse2/muse/midictrl.cpp @@ -4,6 +4,7 @@ // $Id: midictrl.cpp,v 1.17.2.10 2009/06/10 00:34:59 terminator356 Exp $ // // (C) Copyright 2001-2004 Werner Schweer (ws@seh.de) +// (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 diff --git a/muse2/muse/midictrl.h b/muse2/muse/midictrl.h index 1431d5e5..56e1f9fe 100644 --- a/muse2/muse/midictrl.h +++ b/muse2/muse/midictrl.h @@ -4,6 +4,7 @@ // $Id: midictrl.h,v 1.16.2.8 2009/11/25 09:09:43 terminator356 Exp $ // // (C) Copyright 1999-2003 Werner Schweer (ws@seh.de) +// (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 diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp index 9189b0d8..8b324bde 100644 --- a/muse2/muse/midiedit/dcanvas.cpp +++ b/muse2/muse/midiedit/dcanvas.cpp @@ -116,7 +116,7 @@ DrumCanvas::DrumCanvas(MidiEditor* pr, QWidget* parent, int sx, int sy, const char* name) : EventCanvas(pr, parent, sx, sy, name) { - drumEditor=dynamic_cast<DrumEdit*>(pr); + drumEditor=static_cast<DrumEdit*>(pr); _setCurPartIfOnlyOneEventIsSelected=false; diff --git a/muse2/muse/midiedit/dcanvas.h b/muse2/muse/midiedit/dcanvas.h index 1cd8074a..d35a8891 100644 --- a/muse2/muse/midiedit/dcanvas.h +++ b/muse2/muse/midiedit/dcanvas.h @@ -170,6 +170,7 @@ class DrumCanvas : public EventCanvas { QVector<instrument_number_mapping_t>& get_instrument_map() { return instrument_map; } void propagate_drummap_change(int instrument, bool update_druminmap); void rebuildOurDrumMap(); + DrumEdit* drumEdit() { return drumEditor; } }; } // namespace MusEGui diff --git a/muse2/muse/midiedit/dlist.cpp b/muse2/muse/midiedit/dlist.cpp index 3222e278..de89834f 100644 --- a/muse2/muse/midiedit/dlist.cpp +++ b/muse2/muse/midiedit/dlist.cpp @@ -166,8 +166,190 @@ void DList::draw(QPainter& p, const QRect& rect) } break; case COL_NAME: - s = dm->name; - align = Qt::AlignVCenter | Qt::AlignLeft; + { + if(dcanvas && dcanvas->part()) + { + MusECore::Part* cur_part = dcanvas->part(); + if(cur_part->track() && cur_part->track()->isMidiTrack()) + { + MusECore::MidiTrack* cur_track = static_cast<MusECore::MidiTrack*>(cur_part->track()); + int cur_channel = cur_track->outChannel(); + MusECore::MidiPort* cur_port = &MusEGlobal::midiPorts[cur_track->outPort()]; + + if(old_style_drummap_mode) + { + int channel = dm->channel; + MusECore::MidiPort* mp = &MusEGlobal::midiPorts[dm->port]; + int instr_pitch = dm->anote; + MusECore::MidiCtrlValListList* cll = mp->controller(); + const int min = channel << 24; + const int max = min + 0x1000000; + bool found = false; + bool used = false; + bool off = true; + for(MusECore::iMidiCtrlValList imcvl = cll->lower_bound(min); imcvl != cll->lower_bound(max); ++imcvl) + { + MusECore::MidiCtrlValList* cl = imcvl->second; + MusECore::MidiController* c = mp->midiController(cl->num()); + if(!c->isPerNoteController()) + continue; + int cnum = c->num(); + int num = cl->num(); + int pitch = num & 0x7f; + if(pitch != instr_pitch) + continue; + + found = true; + MusECore::EventList* el = cur_part->events(); + for(MusECore::iEvent ie = el->begin(); ie != el->end(); ++ie) + { + MusECore::Event e = ie->second; + if(e.type() != MusECore::Controller) + continue; + int ctl_num = e.dataA(); + if((ctl_num | 0xff) == cnum && (ctl_num & 0x7f) == instrument) + { + used = true; + break; + } + } + off = cl->hwVal() == MusECore::CTRL_VAL_UNKNOWN; // Does it have a value or is it 'off'? + if(used && !off) + break; // We have all the info we need, done. + } + + if(found) + { + int rx = r.x() + 1; + int ry = r.y() + r.height()/2 - 3; + int rw = 6; + int rh = 6; + if(used) + { + if(off) + p.drawPixmap(rx, ry, rw, rh, *greendot12x12Icon); + else + p.drawPixmap(rx, ry, rw, rh, *orangedot12x12Icon); + } + else + { + if(off) + p.drawPixmap(rx, ry, rw, rh, *graydot12x12Icon); + else + p.drawPixmap(rx, ry, rw, rh, *bluedot12x12Icon); + } + } + } + else + { + + QSet<MusECore::Track*>* group = &dcanvas->get_instrument_map()[instrument].tracks; + bool found = false; + bool used = false; + bool off = true; + + // REMOVE Tim. Or FIXME. An attempt to light the dots while respecting grouping. + //if(!group->empty()) + { +// int group_size = group->size(); +// if(group_size == 1) +// { +// MusECore::Track* t = *group->begin(); +// MusECore::PartList* part_list = dcanvas->drumEdit()->parts(); +// for(MusECore::ciPart ip = part_list->cbegin(); ip != part_list->cend(); ++ip) { +// if(ip->second->track() == t) { +// } +// } +// } + + int instr_pitch = dcanvas->get_instrument_map()[instrument].pitch; + + //if(//dcanvas->drumEdit()->group_mode() == DrumEdit::DONT_GROUP || + //dcanvas->drumEdit()->group_mode() == DrumEdit::GROUP_MAX || + //dcanvas->drumEdit()->group_mode() == DrumEdit::GROUP_SAME_CHANNEL || + //group_size >= 2 && group->find(cur_track) != group->end()) + //for(QSet<MusECore::Track*>::iterator it = group->begin(); it != group->end(); ++it) + if(group->find(cur_track) != group->end()) + { + //if(!(*it)->isMidiTrack()) + // continue; + //MusECore::MidiTrack* track = static_cast<MusECore::MidiTrack*>(*it); + //MusECore::MidiPort* mp = &MusEGlobal::midiPorts[track->outPort()]; + //MusECore::MidiCtrlValListList* cll = mp->controller(); + MusECore::MidiCtrlValListList* cll = cur_port->controller(); + //int channel = track->outChannel(); + //const int min = channel << 24; + const int min = cur_channel << 24; + const int max = min + 0x1000000; + + for(MusECore::iMidiCtrlValList imcvl = cll->lower_bound(min); imcvl != cll->lower_bound(max); ++imcvl) + { + MusECore::MidiCtrlValList* cl = imcvl->second; + MusECore::MidiController* c = cur_port->midiController(cl->num()); + if(!c->isPerNoteController()) + continue; + int cnum = c->num(); + int num = cl->num(); + int pitch = num & 0x7f; + if(pitch != instr_pitch) + continue; + + found = true; + MusECore::EventList* el = cur_part->events(); + //MusECore::PartList* part_list = dcanvas->drumEdit()->parts(); + //for(MusECore::ciPart ip = part_list->cbegin(); ip != part_list->cend(); ++ip) + { + //MusECore::Part* part = ip->second; + ///if(part->track() != + //MusECore::EventList* el = part->events(); + for(MusECore::iEvent ie = el->begin(); ie != el->end(); ++ie) + { + MusECore::Event e = ie->second; + if(e.type() != MusECore::Controller) + continue; + int ctl_num = e.dataA(); + if((ctl_num | 0xff) == cnum && (ctl_num & 0x7f) == pitch) + { + used = true; + break; + } + } + } + off = cl->hwVal() == MusECore::CTRL_VAL_UNKNOWN; // Does it have a value or is it 'off'? + if(used && !off) + break; // We have all the info we need, done. + } + } + + if(found) + { + int rx = r.x() + 1; + int ry = r.y() + r.height()/2 - 3; + int rw = 6; + int rh = 6; + if(used) + { + if(off) + p.drawPixmap(rx, ry, rw, rh, *greendot12x12Icon); + else + p.drawPixmap(rx, ry, rw, rh, *orangedot12x12Icon); + } + else + { + if(off) + p.drawPixmap(rx, ry, rw, rh, *graydot12x12Icon); + else + p.drawPixmap(rx, ry, rw, rh, *bluedot12x12Icon); + } + } + } + } + } + } + QString str = dm->name; + align = Qt::AlignVCenter | Qt::AlignLeft; + p.drawText(r.x() + 8, r.y(), r.width() - 8, r.height(), align, str); + } break; case COL_OUTCHANNEL: s.setNum(dm->channel+1); diff --git a/muse2/muse/midiedit/dlist.h b/muse2/muse/midiedit/dlist.h index 28b4af27..df23a200 100644 --- a/muse2/muse/midiedit/dlist.h +++ b/muse2/muse/midiedit/dlist.h @@ -113,7 +113,7 @@ class DPitchEdit: public Awl::PitchEdit class DList : public View { Q_OBJECT - + MusEGui::DrumCanvas* dcanvas; MusECore::DrumMap* ourDrumMap; int ourDrumMapSize; diff --git a/muse2/muse/midiedit/drumedit.cpp b/muse2/muse/midiedit/drumedit.cpp index 5126180f..2ff9448d 100644 --- a/muse2/muse/midiedit/drumedit.cpp +++ b/muse2/muse/midiedit/drumedit.cpp @@ -3,6 +3,7 @@ // Linux Music Editor // $Id: drumedit.cpp,v 1.22.2.21 2009/11/16 11:29:33 lunar_shuttle Exp $ // (C) Copyright 1999 Werner Schweer (ws@seh.de) +// (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 @@ -1292,8 +1293,14 @@ void DrumEdit::addCtrlClicked() { PopupMenu* pup = new PopupMenu(true); // true = enable stay open. Don't bother with parent. connect(pup, SIGNAL(triggered(QAction*)), SLOT(ctrlPopupTriggered(QAction*))); + + int cur_instr = curDrumInstrument(); + // HACK! New drum ctrl canvas current drum index is not the same as the editor current drum index. + // Should try to fix this situation - two different values exist. Tim. + if(!old_style_drummap_mode()) + cur_instr = (cur_instr & ~0xff) | get_instrument_map()[cur_instr].pitch; - int est_width = populateMidiCtrlMenu(pup, parts(), curCanvasPart(), curDrumInstrument()); + int est_width = populateMidiCtrlMenu(pup, parts(), curCanvasPart(), cur_instr); QPoint ep = ctrl->mapToGlobal(QPoint(0,0)); //int newx = ep.x() - pup->width(); // Too much! Width says 640. Maybe because it hasn't been shown yet . diff --git a/muse2/muse/midiedit/drumedit.h b/muse2/muse/midiedit/drumedit.h index 4b9d391a..2daafd30 100644 --- a/muse2/muse/midiedit/drumedit.h +++ b/muse2/muse/midiedit/drumedit.h @@ -3,6 +3,7 @@ // Linux Music Editor // $Id: drumedit.h,v 1.9.2.7 2009/11/16 11:29:33 lunar_shuttle Exp $ // (C) Copyright 1999 Werner Schweer (ws@seh.de) +// (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 diff --git a/muse2/muse/midiedit/piano.cpp b/muse2/muse/midiedit/piano.cpp index afbf8328..40d93910 100644 --- a/muse2/muse/midiedit/piano.cpp +++ b/muse2/muse/midiedit/piano.cpp @@ -3,6 +3,7 @@ // Linux Music Editor // $Id: piano.cpp,v 1.3 2004/05/31 11:48:55 lunar_shuttle Exp $ // (C) Copyright 1999 Werner Schweer (ws@seh.de) +// (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 @@ -25,9 +26,15 @@ #include <stdio.h> +#include <map> + #include "piano.h" #include "globals.h" #include "song.h" +#include "track.h" +#include "midieditor.h" +#include "midictrl.h" +#include "icons.h" namespace MusEGui { @@ -438,10 +445,11 @@ static const char *mk8_xpm[] = { // Piano //--------------------------------------------------------- -Piano::Piano(QWidget* parent, int ymag) +Piano::Piano(QWidget* parent, int ymag, MidiEditor* editor) : View(parent, 1, ymag) { setMouseTracking(true); + _midiEditor = editor; curPitch = -1; _curSelectedPitch = 60; // Start with 'C3" octave = new QPixmap(oct_xpm); @@ -537,6 +545,63 @@ void Piano::draw(QPainter& p, const QRect& r) } } + + if(!_midiEditor) + return; + MusECore::PartList* part_list = _midiEditor->parts(); + MusECore::Part* cur_part = _midiEditor->curCanvasPart(); + if(!part_list || !cur_part) + return; + + MusECore::MidiTrack* track = (MusECore::MidiTrack*)(cur_part->track()); + int channel = track->outChannel(); + MusECore::MidiPort* port = &MusEGlobal::midiPorts[track->outPort()]; + MusECore::MidiCtrlValListList* cll = port->controller(); + const int min = channel << 24; + const int max = min + 0x1000000; + + for(MusECore::ciMidiCtrlValList it = cll->lower_bound(min); it != cll->lower_bound(max); ++it) + { + MusECore::MidiCtrlValList* cl = it->second; + MusECore::MidiController* c = port->midiController(cl->num()); + if(!c->isPerNoteController()) + continue; + int cnum = c->num(); + int num = cl->num(); + int pitch = num & 0x7f; + bool used = false; + MusECore::EventList* el = cur_part->events(); + for (MusECore::ciEvent ie = el->begin(); ie != el->end(); ++ie) + { + MusECore::Event e = ie->second; + if(e.type() != MusECore::Controller) + continue; + int ctl_num = e.dataA(); + if((ctl_num | 0xff) == cnum && (ctl_num & 0x7f) == pitch) + { + used = true; + break; + } + } + + bool off = cl->hwVal() == MusECore::CTRL_VAL_UNKNOWN; // Does it have a value or is it 'off'? + + int y = pitch2y(pitch) + 3; + if(used) + { + if(off) + p.drawPixmap(0, y, 6, 6, *greendot12x12Icon); + else + p.drawPixmap(0, y, 6, 6, *orangedot12x12Icon); + } + else + { + if(off) + p.drawPixmap(0, y, 6, 6, *graydot12x12Icon); + else + p.drawPixmap(0, y, 6, 6, *bluedot12x12Icon); + } + } } diff --git a/muse2/muse/midiedit/piano.h b/muse2/muse/midiedit/piano.h index f42037ec..c2044dd4 100644 --- a/muse2/muse/midiedit/piano.h +++ b/muse2/muse/midiedit/piano.h @@ -3,6 +3,7 @@ // Linux Music Editor // $Id: piano.h,v 1.2 2004/05/31 11:48:55 lunar_shuttle Exp $ // (C) Copyright 1999 Werner Schweer (ws@seh.de) +// (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 @@ -34,7 +35,9 @@ class QPixmap; #define KH 13 namespace MusEGui { - + +class MidiEditor; + //--------------------------------------------------------- // Piano //--------------------------------------------------------- @@ -42,7 +45,8 @@ namespace MusEGui { class Piano : public View { Q_OBJECT - + + MidiEditor* _midiEditor; int curPitch; int _curSelectedPitch; QPixmap* octave; @@ -83,7 +87,7 @@ class Piano : public View void setPitch(int); public: - Piano(QWidget*, int); + Piano(QWidget* parent, int ymag, MidiEditor* editor = 0); int curSelectedPitch() const { return _curSelectedPitch; } void setCurSelectedPitch(int pitch); }; diff --git a/muse2/muse/midiedit/pianoroll.cpp b/muse2/muse/midiedit/pianoroll.cpp index e4064bd9..0698f5ad 100644 --- a/muse2/muse/midiedit/pianoroll.cpp +++ b/muse2/muse/midiedit/pianoroll.cpp @@ -3,6 +3,7 @@ // Linux Music Editor // $Id: pianoroll.cpp,v 1.25.2.15 2009/11/16 11:29:33 lunar_shuttle Exp $ // (C) Copyright 1999 Werner Schweer (ws@seh.de) +// (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 @@ -360,7 +361,7 @@ PianoRoll::PianoRoll(MusECore::PartList* pl, QWidget* parent, const char* name, gridS1->setSpacing(0); time = new MusEGui::MTScale(&_raster, split1, xscale); - piano = new Piano(split1, yscale); + piano = new Piano(split1, yscale, this); canvas = new PianoCanvas(this, split1, xscale, yscale); vscroll = new MusEGui::ScrollScale(-3, 7, yscale, KH * 75, Qt::Vertical, split1); setCurDrumInstrument(piano->curSelectedPitch()); diff --git a/muse2/muse/midiedit/pianoroll.h b/muse2/muse/midiedit/pianoroll.h index 87ea1d3d..65af30a8 100644 --- a/muse2/muse/midiedit/pianoroll.h +++ b/muse2/muse/midiedit/pianoroll.h @@ -3,6 +3,7 @@ // Linux Music Editor // $Id: pianoroll.h,v 1.5.2.4 2009/11/16 11:29:33 lunar_shuttle Exp $ // (C) Copyright 1999 Werner Schweer (ws@seh.de) +// (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 diff --git a/muse2/muse/midievent.cpp b/muse2/muse/midievent.cpp index 7599e3d9..9fd47eaf 100644 --- a/muse2/muse/midievent.cpp +++ b/muse2/muse/midievent.cpp @@ -75,8 +75,6 @@ void MidiEventBase::dump(int n) const case Note: p = "Note "; break; case Controller: p = "Ctrl "; break; case Sysex: p = "Sysex "; break; - case PAfter: p = "PAfter "; break; - case CAfter: p = "CAfter "; break; case Meta: p = "Meta "; break; default: p = "?? "; break; } @@ -129,7 +127,7 @@ void MidiEventBase::write(int level, Xml& xml, const Pos& offset, bool /*forcePa void MidiEventBase::read(Xml& xml) { - setType(Note); + int ev_type = Note; a = 0; b = 0; c = 0; @@ -163,7 +161,8 @@ void MidiEventBase::read(Xml& xml) if (tag == "tick") setTick(xml.s2().toInt()); else if (tag == "type") - setType(EventType(xml.s2().toInt())); + //setType(EventType(xml.s2().toInt())); + ev_type = xml.s2().toInt(); else if (tag == "len") setLenTick(xml.s2().toInt()); else if (tag == "a") @@ -176,12 +175,27 @@ void MidiEventBase::read(Xml& xml) dataLen = xml.s2().toInt(); break; case Xml::TagEnd: - if (tag == "event") - { + if (tag == "event") { + // Convert obsolete PAfter and CAfter events to newer controllers + if(ev_type == 3) // PAfter + { + ev_type = Controller; + a = (a & 0x7f) | (CTRL_POLYAFTER & ~0xff); // Controller number + pitch. B is the value. + } + else + if(ev_type == 4) // CAfter + { + ev_type = Controller; + b = a; // Value + a = CTRL_AFTERTOUCH; // Controller number + } + + setType(EventType(ev_type)); + // HACK: Repair controllers saved with lo byte 0xff. // No such control. It was supposed to be 0x00. // It's an error caused by a previous bug, fixed now. - if((type() == Controller) && ((a & 0xff) == 0xff)) + if((ev_type == Controller) && ((a & 0xff) == 0xff)) a &= ~0xff; return; } diff --git a/muse2/muse/midifile.cpp b/muse2/muse/midifile.cpp index 6f92d0f5..39b2e51d 100644 --- a/muse2/muse/midifile.cpp +++ b/muse2/muse/midifile.cpp @@ -699,8 +699,7 @@ bool MidiFile::write() writeShort(MusEGlobal::config.smfFormat); if (MusEGlobal::config.smfFormat == 0) { // DELETETHIS 30 - /* - //writeShort(1); // Removed. Bug tracker 3293339 + /* // REMOVE Tim. MidiFileTrack dst; for (iMidiFileTrack i = _tracks->begin(); i != _tracks->end(); ++i) { MPEventList* sl = &((*i)->events); @@ -713,8 +712,8 @@ bool MidiFile::write() // Nope. Didn't help. Now that it's a single MidiFileTrack, try skipping this section altogether... // Yes that appears to have fixed it. Weird. What's the difference - the local 'dst' variable ? // Or are there still lurking problems, or something more fundamentally wrong with Event or MPEvent? - printf("MidiFile::write adding event to dst:\n"); // REMOVE Tim. - ie->dump(); // REMOVE Tim. + printf("MidiFile::write adding event to dst:\n"); + ie->dump(); dst.events.add(*ie); } } diff --git a/muse2/muse/midiport.cpp b/muse2/muse/midiport.cpp index 36b38ae0..61e7ab50 100644 --- a/muse2/muse/midiport.cpp +++ b/muse2/muse/midiport.cpp @@ -4,6 +4,7 @@ // $Id: midiport.cpp,v 1.21.2.15 2009/12/07 20:11:51 terminator356 Exp $ // // (C) Copyright 2000-2004 Werner Schweer (ws@seh.de) +// (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 @@ -831,24 +832,26 @@ bool MidiPort::sendHwCtrlState(const MidiPlayEvent& ev, bool forceSend) return false; } } -// else -// if (ev.type() == ME_POLYAFTER) // REMOVE Tim. Or keep? -// { -// int db = limitValToInstrCtlRange(CTRL_POLYAFTER, ev.dataB()); -// if(!setHwCtrlState(ev.channel(), CTRL_POLYAFTER, db)) { -// if (!forceSend) -// return false; -// } -// } -// else -// if (ev.type() == ME_AFTERTOUCH) -// { -// int da = limitValToInstrCtlRange(CTRL_AFTERTOUCH, ev.dataA()); -// if(!setHwCtrlState(ev.channel(), CTRL_AFTERTOUCH, da)) { -// if (!forceSend) -// return false; -// } -// } + else + if (ev.type() == ME_POLYAFTER) // REMOVE Tim. Or keep? ... + { + int pitch = ev.dataA() & 0x7f; + int ctl = (CTRL_POLYAFTER & ~0xff) | pitch; + int db = limitValToInstrCtlRange(ctl, ev.dataB()); + if(!setHwCtrlState(ev.channel(), ctl, db)) { + if (!forceSend) + return false; + } + } + else + if (ev.type() == ME_AFTERTOUCH) // ... Same + { + int da = limitValToInstrCtlRange(CTRL_AFTERTOUCH, ev.dataA()); + if(!setHwCtrlState(ev.channel(), CTRL_AFTERTOUCH, da)) { + if (!forceSend) + return false; + } + } else if (ev.type() == ME_PITCHBEND) { diff --git a/muse2/muse/midiport.h b/muse2/muse/midiport.h index 3a1feba6..71e36154 100644 --- a/muse2/muse/midiport.h +++ b/muse2/muse/midiport.h @@ -4,6 +4,7 @@ // $Id: midiport.h,v 1.9.2.6 2009/11/17 22:08:22 terminator356 Exp $ // // (C) Copyright 1999-2004 Werner Schweer (ws@seh.de) +// (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 diff --git a/muse2/muse/miditransform.cpp b/muse2/muse/miditransform.cpp index bd8dea27..247fdaf8 100644 --- a/muse2/muse/miditransform.cpp +++ b/muse2/muse/miditransform.cpp @@ -1716,14 +1716,24 @@ bool MidiTransformerDialog::typesMatch(MusECore::Event& e, unsigned selType) matched = (e.type() == MusECore::Note); break; case MIDITRANSFORM_POLY: - matched = (e.type() == MusECore::PAfter); + { + if (e.type() == MusECore::Controller) { + MusECore::MidiController::ControllerType c = MusECore::midiControllerType(e.dataA()); + matched = (c == MusECore::MidiController::PolyAftertouch); + } break; + } case MIDITRANSFORM_CTRL: matched = (e.type() == MusECore::Controller); break; case MIDITRANSFORM_ATOUCH: - matched = (e.type() == MusECore::CAfter); + { + if (e.type() == MusECore::Controller) { + MusECore::MidiController::ControllerType c = MusECore::midiControllerType(e.dataA()); + matched = (c == MusECore::MidiController::Aftertouch); + } break; + } case MIDITRANSFORM_PITCHBEND: { if (e.type() == MusECore::Controller) { diff --git a/muse2/muse/mpevent.cpp b/muse2/muse/mpevent.cpp index c1b0e5dc..54546e89 100644 --- a/muse2/muse/mpevent.cpp +++ b/muse2/muse/mpevent.cpp @@ -62,16 +62,6 @@ MEvent::MEvent(unsigned tick, int port, int channel, const Event& e) setA(e.dataA()); // controller number setB(e.dataB()); // controller value break; - case PAfter: - setType(ME_POLYAFTER); - setA(e.dataA()); - setB(e.dataB()); - break; - case CAfter: - setType(ME_AFTERTOUCH); - setA(e.dataA()); - setB(0); - break; case Sysex: setType(ME_SYSEX); setData(e.eventData()); diff --git a/muse2/muse/part.cpp b/muse2/muse/part.cpp index d270f6c0..65ca93b4 100644 --- a/muse2/muse/part.cpp +++ b/muse2/muse/part.cpp @@ -865,18 +865,6 @@ void Song::cmdResizePart(Track* track, Part* oPart, unsigned int len, bool doClo unsigned event_endframe = event_startframe + e.lenFrame(); if (event_endframe < new_partlength) continue; -// REMOVE Tim. -// if (event_startframe > new_partlength) { // If event start was after the new length, remove it from part -// // Do not do port controller values and clone parts. -// operations.push_back(UndoOp(UndoOp::DeleteEvent, e, nPart, false, false)); -// continue; -// } -// if (event_endframe > new_partlength) { // If this event starts before new length and ends after, shrink it -// Event newEvent = e.clone(); -// newEvent.setLenFrame(new_partlength - event_startframe); -// // Do not do port controller values and clone parts. -// operations.push_back(UndoOp(UndoOp::ModifyEvent, newEvent, e, nPart, false,false)); -// } } nPart->setLenFrame(new_partlength); // Do not do port controller values and clone parts. @@ -895,20 +883,10 @@ void Song::cmdResizePart(Track* track, Part* oPart, unsigned int len, bool doClo iEvent i = el->end(); i--; Event last = i->second; -// REMOVE Tim. unsigned last_start = last.frame(); MusECore::SndFileR file = last.sndFile(); if (file.isNull()) return; - -// unsigned clipframes = (file.samples() - last.spos());// / file.channels(); Event newEvent = last.clone(); - -// REMOVE Tim. -// unsigned new_eventlength = new_partlength - last_start; -// if (new_eventlength > clipframes) // Shrink event length if new partlength exceeds last clip -// new_eventlength = clipframes; -// -// newEvent.setLenFrame(new_eventlength); // Do not do port controller values and clone parts. operations.push_back(UndoOp(UndoOp::ModifyEvent, newEvent, last, nPart, false, false)); } diff --git a/muse2/muse/widgets/arrangercolumns.cpp b/muse2/muse/widgets/arrangercolumns.cpp index 08a9580e..9e8137e6 100644 --- a/muse2/muse/widgets/arrangercolumns.cpp +++ b/muse2/muse/widgets/arrangercolumns.cpp @@ -32,6 +32,18 @@ ArrangerColumns::ArrangerColumns(QWidget* parent) : QDialog(parent) ignoreSomethingChanged=true; setupUi(this); + + ctrlType->addItem(tr("Control7"), MusECore::MidiController::Controller7); + ctrlType->addItem(tr("Control14"), MusECore::MidiController::Controller14); + ctrlType->addItem(tr("RPN"), MusECore::MidiController::RPN); + ctrlType->addItem(tr("NPRN"), MusECore::MidiController::NRPN); + ctrlType->addItem(tr("RPN14"), MusECore::MidiController::RPN14); + ctrlType->addItem(tr("NRPN14"), MusECore::MidiController::NRPN14); + ctrlType->addItem(tr("Pitch"), MusECore::MidiController::Pitch); + ctrlType->addItem(tr("Program"), MusECore::MidiController::Program); + //ctrlType->addItem(tr("PolyAftertouch"), MusECore::MidiController::PolyAftertouch); // Not supported yet. Need a way to select pitch. + ctrlType->addItem(tr("Aftertouch"), MusECore::MidiController::Aftertouch); + ctrlType->setCurrentIndex(0); initList(); @@ -58,7 +70,9 @@ ArrangerColumns::ArrangerColumns(QWidget* parent) : QDialog(parent) void ArrangerColumns::ctrlTypeChanged(int idx) { - MusECore::MidiController::ControllerType t = (MusECore::MidiController::ControllerType)idx; + if(idx == -1) + return; + MusECore::MidiController::ControllerType t = (MusECore::MidiController::ControllerType)ctrlType->itemData(idx).toInt(); switch (t) { @@ -90,17 +104,17 @@ void ArrangerColumns::somethingChanged() if (ignoreSomethingChanged) return; int row=listWidget->currentRow(); - if (row!=-1) + if (row!=-1 && ctrlType->currentIndex() != -1) { + MusECore::MidiController::ControllerType t = (MusECore::MidiController::ControllerType)ctrlType->itemData(ctrlType->currentIndex()).toInt(); int hnum = spinBoxHCtrlNo->value(); int lnum = spinBoxLCtrlNo->value(); - MusECore::MidiController::ControllerType t = (MusECore::MidiController::ControllerType)ctrlType->currentIndex(); int ctrl_number = MusECore::MidiController::genNum(t, hnum, lnum); Arranger::new_custom_columns[row].name=nameEdit->text(); Arranger::new_custom_columns[row].ctrl=ctrl_number; Arranger::new_custom_columns[row].affected_pos=(affectBeginButton->isChecked() ? Arranger::custom_col_t::AFFECT_BEGIN : Arranger::custom_col_t::AFFECT_CPOS); - + listWidget->currentItem()->setText(getListEntryString(row)); } } @@ -134,7 +148,9 @@ void ArrangerColumns::itemSelected(int i) nameEdit->setText(Arranger::new_custom_columns[i].name); int num=Arranger::new_custom_columns[i].ctrl; - ctrlType->setCurrentIndex(MusECore::midiControllerType(num)); + int idx = ctrlType->findData(MusECore::midiControllerType(num)); + if(idx != -1) + ctrlType->setCurrentIndex(idx); if (spinBoxHCtrlNo->isEnabled()) spinBoxHCtrlNo->setValue((num & 0xFF00)>>8); else diff --git a/muse2/muse/widgets/arrangercolumnsbase.ui b/muse2/muse/widgets/arrangercolumnsbase.ui index eda9e923..8568f9f5 100644 --- a/muse2/muse/widgets/arrangercolumnsbase.ui +++ b/muse2/muse/widgets/arrangercolumnsbase.ui @@ -69,46 +69,6 @@ <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> </layout> diff --git a/muse2/muse/widgets/midi_audio_control.cpp b/muse2/muse/widgets/midi_audio_control.cpp index 17d724ac..7e2d5091 100644 --- a/muse2/muse/widgets/midi_audio_control.cpp +++ b/muse2/muse/widgets/midi_audio_control.cpp @@ -45,6 +45,18 @@ MidiAudioControl::MidiAudioControl(int port, int chan, int ctrl, QWidget* parent { setupUi(this); + controlTypeComboBox->addItem(tr("Control7"), MusECore::MidiController::Controller7); + controlTypeComboBox->addItem(tr("Control14"), MusECore::MidiController::Controller14); + controlTypeComboBox->addItem(tr("RPN"), MusECore::MidiController::RPN); + controlTypeComboBox->addItem(tr("NPRN"), MusECore::MidiController::NRPN); + controlTypeComboBox->addItem(tr("RPN14"), MusECore::MidiController::RPN14); + controlTypeComboBox->addItem(tr("NRPN14"), MusECore::MidiController::NRPN14); + controlTypeComboBox->addItem(tr("Pitch"), MusECore::MidiController::Pitch); + controlTypeComboBox->addItem(tr("Program"), MusECore::MidiController::Program); + //controlTypeComboBox->addItem(tr("PolyAftertouch"), MusECore::MidiController::PolyAftertouch); // Not supported yet. Need a way to select pitch. + controlTypeComboBox->addItem(tr("Aftertouch"), MusECore::MidiController::Aftertouch); + controlTypeComboBox->setCurrentIndex(0); + _port = port; _chan = chan; _ctrl = ctrl; @@ -89,59 +101,71 @@ void MidiAudioControl::heartbeat() if(MusEGlobal::midiLearnCtrl != -1) { MusECore::MidiController::ControllerType type = MusECore::midiControllerType(MusEGlobal::midiLearnCtrl); - if(type < controlTypeComboBox->count() && type != controlTypeComboBox->currentIndex()) + int idx = controlTypeComboBox->findData(type); + if(idx != -1 && idx != controlTypeComboBox->currentIndex()) { controlTypeComboBox->blockSignals(true); - controlTypeComboBox->setCurrentIndex(type); + controlTypeComboBox->setCurrentIndex(idx); controlTypeComboBox->blockSignals(false); } int hv = (MusEGlobal::midiLearnCtrl >> 8) & 0xff; int lv = MusEGlobal::midiLearnCtrl & 0xff; - if(type == MusECore::MidiController::Program || type == MusECore::MidiController::Pitch) - { - ctrlHiSpinBox->setEnabled(false); - ctrlLoSpinBox->setEnabled(false); - ctrlHiSpinBox->blockSignals(true); - ctrlLoSpinBox->blockSignals(true); - ctrlHiSpinBox->setValue(0); - ctrlLoSpinBox->setValue(0); - ctrlHiSpinBox->blockSignals(false); - ctrlLoSpinBox->blockSignals(false); - } - else if(type == MusECore::MidiController::Controller7) - { - ctrlHiSpinBox->setEnabled(false); - ctrlLoSpinBox->setEnabled(true); - ctrlHiSpinBox->blockSignals(true); - ctrlHiSpinBox->setValue(0); - ctrlHiSpinBox->blockSignals(false); - - if(lv != ctrlLoSpinBox->value()) - { - ctrlLoSpinBox->blockSignals(true); - ctrlLoSpinBox->setValue(lv); - ctrlLoSpinBox->blockSignals(false); - } - } - else + switch(type) { - ctrlHiSpinBox->setEnabled(true); - ctrlLoSpinBox->setEnabled(true); - if(hv != ctrlHiSpinBox->value()) - { + case MusECore::MidiController::Program: + case MusECore::MidiController::Pitch: + case MusECore::MidiController::PolyAftertouch: // Unsupported yet. Need a way to select pitch. + case MusECore::MidiController::Aftertouch: + ctrlHiSpinBox->setEnabled(false); + ctrlLoSpinBox->setEnabled(false); ctrlHiSpinBox->blockSignals(true); - ctrlHiSpinBox->setValue(hv); - ctrlHiSpinBox->blockSignals(false); - } - if(lv != ctrlLoSpinBox->value()) - { ctrlLoSpinBox->blockSignals(true); - ctrlLoSpinBox->setValue(lv); + ctrlHiSpinBox->setValue(0); + ctrlLoSpinBox->setValue(0); + ctrlHiSpinBox->blockSignals(false); ctrlLoSpinBox->blockSignals(false); - } - } + break; + case MusECore::MidiController::Controller7: + ctrlHiSpinBox->setEnabled(false); + ctrlLoSpinBox->setEnabled(true); + + ctrlHiSpinBox->blockSignals(true); + ctrlHiSpinBox->setValue(0); + ctrlHiSpinBox->blockSignals(false); + + if(lv != ctrlLoSpinBox->value()) + { + ctrlLoSpinBox->blockSignals(true); + ctrlLoSpinBox->setValue(lv); + ctrlLoSpinBox->blockSignals(false); + } + break; + case MusECore::MidiController::Controller14: + case MusECore::MidiController::RPN: + case MusECore::MidiController::RPN14: + case MusECore::MidiController::NRPN: + case MusECore::MidiController::NRPN14: + ctrlHiSpinBox->setEnabled(true); + ctrlLoSpinBox->setEnabled(true); + if(hv != ctrlHiSpinBox->value()) + { + ctrlHiSpinBox->blockSignals(true); + ctrlHiSpinBox->setValue(hv); + ctrlHiSpinBox->blockSignals(false); + } + if(lv != ctrlLoSpinBox->value()) + { + ctrlLoSpinBox->blockSignals(true); + ctrlLoSpinBox->setValue(lv); + ctrlLoSpinBox->blockSignals(false); + } + break; + default: + printf("FIXME: MidiAudioControl::heartbeat: Unknown control type: %d\n", type); + break; + } _ctrl = MusECore::midiCtrlTerms2Number(type, (ctrlHiSpinBox->value() << 8) + ctrlLoSpinBox->value()); } @@ -184,46 +208,55 @@ void MidiAudioControl::chanChanged() void MidiAudioControl::updateCtrlBoxes() { - int idx = controlTypeComboBox->currentIndex(); - if(idx == -1) + if(controlTypeComboBox->currentIndex() == -1) return; - - if(idx == MusECore::MidiController::Program || idx == MusECore::MidiController::Pitch) - { - ctrlHiSpinBox->setEnabled(false); - ctrlLoSpinBox->setEnabled(false); - ctrlHiSpinBox->blockSignals(true); - ctrlLoSpinBox->blockSignals(true); - ctrlHiSpinBox->setValue(0); - ctrlLoSpinBox->setValue(0); - ctrlHiSpinBox->blockSignals(false); - ctrlLoSpinBox->blockSignals(false); - } - else if(idx == MusECore::MidiController::Controller7) - { - ctrlHiSpinBox->setEnabled(false); - ctrlLoSpinBox->setEnabled(true); + MusECore::MidiController::ControllerType t = (MusECore::MidiController::ControllerType)controlTypeComboBox->itemData(controlTypeComboBox->currentIndex()).toInt(); - ctrlHiSpinBox->blockSignals(true); - ctrlHiSpinBox->setValue(0); - ctrlHiSpinBox->blockSignals(false); - } - else + switch(t) { - ctrlHiSpinBox->setEnabled(true); - ctrlLoSpinBox->setEnabled(true); - } + case MusECore::MidiController::Program: + case MusECore::MidiController::Pitch: + case MusECore::MidiController::PolyAftertouch: // Unsupported yet. Need a way to select pitch. + case MusECore::MidiController::Aftertouch: + ctrlHiSpinBox->setEnabled(false); + ctrlLoSpinBox->setEnabled(false); + ctrlHiSpinBox->blockSignals(true); + ctrlLoSpinBox->blockSignals(true); + ctrlHiSpinBox->setValue(0); + ctrlLoSpinBox->setValue(0); + ctrlHiSpinBox->blockSignals(false); + ctrlLoSpinBox->blockSignals(false); + break; + case MusECore::MidiController::Controller7: + ctrlHiSpinBox->setEnabled(false); + ctrlLoSpinBox->setEnabled(true); + ctrlHiSpinBox->blockSignals(true); + ctrlHiSpinBox->setValue(0); + ctrlHiSpinBox->blockSignals(false); + break; + case MusECore::MidiController::Controller14: + case MusECore::MidiController::RPN: + case MusECore::MidiController::RPN14: + case MusECore::MidiController::NRPN: + case MusECore::MidiController::NRPN14: + ctrlHiSpinBox->setEnabled(true); + ctrlLoSpinBox->setEnabled(true); + break; + default: + printf("FIXME: MidiAudioControl::updateCtrlBoxes: Unknown control type: %d\n", t); + break; + } } void MidiAudioControl::ctrlTypeChanged(int idx) { if(idx == -1) return; - + updateCtrlBoxes(); _ctrl = (ctrlHiSpinBox->value() << 8) + ctrlLoSpinBox->value(); - _ctrl = MusECore::midiCtrlTerms2Number(MusECore::MidiController::ControllerType(idx), _ctrl); + _ctrl = MusECore::midiCtrlTerms2Number((MusECore::MidiController::ControllerType)controlTypeComboBox->itemData(idx).toInt(), _ctrl); resetLearn(); } @@ -233,7 +266,7 @@ void MidiAudioControl::ctrlHChanged() if(controlTypeComboBox->currentIndex() == -1) return; _ctrl = (ctrlHiSpinBox->value() << 8) + ctrlLoSpinBox->value(); - _ctrl = MusECore::midiCtrlTerms2Number(MusECore::MidiController::ControllerType(controlTypeComboBox->currentIndex()), _ctrl); + _ctrl = MusECore::midiCtrlTerms2Number((MusECore::MidiController::ControllerType)controlTypeComboBox->itemData(controlTypeComboBox->currentIndex()).toInt(), _ctrl); resetLearn(); } @@ -243,7 +276,7 @@ void MidiAudioControl::ctrlLChanged() if(controlTypeComboBox->currentIndex() == -1) return; _ctrl = (ctrlHiSpinBox->value() << 8) + ctrlLoSpinBox->value(); - _ctrl = MusECore::midiCtrlTerms2Number(MusECore::MidiController::ControllerType(controlTypeComboBox->currentIndex()), _ctrl); + _ctrl = MusECore::midiCtrlTerms2Number((MusECore::MidiController::ControllerType)controlTypeComboBox->itemData(controlTypeComboBox->currentIndex()).toInt(), _ctrl); resetLearn(); } @@ -282,59 +315,71 @@ void MidiAudioControl::update() channelSpinBox->blockSignals(false); int type = MusECore::midiControllerType(_ctrl); - if(type < controlTypeComboBox->count()) + int idx = controlTypeComboBox->findData(type); + if(idx != -1 && idx != controlTypeComboBox->currentIndex()) { controlTypeComboBox->blockSignals(true); - controlTypeComboBox->setCurrentIndex(type); + controlTypeComboBox->setCurrentIndex(idx); controlTypeComboBox->blockSignals(false); } int hv = (_ctrl >> 8) & 0xff; int lv = _ctrl & 0xff; - if(type == MusECore::MidiController::Program || type == MusECore::MidiController::Pitch) - { - ctrlHiSpinBox->setEnabled(false); - ctrlLoSpinBox->setEnabled(false); - ctrlHiSpinBox->blockSignals(true); - ctrlLoSpinBox->blockSignals(true); - ctrlHiSpinBox->setValue(0); - ctrlLoSpinBox->setValue(0); - ctrlHiSpinBox->blockSignals(false); - ctrlLoSpinBox->blockSignals(false); - } - else if(type == MusECore::MidiController::Controller7) - { - ctrlHiSpinBox->setEnabled(false); - ctrlLoSpinBox->setEnabled(true); - ctrlHiSpinBox->blockSignals(true); - ctrlHiSpinBox->setValue(0); - ctrlHiSpinBox->blockSignals(false); - - if(lv != ctrlLoSpinBox->value()) - { - ctrlLoSpinBox->blockSignals(true); - ctrlLoSpinBox->setValue(lv); - ctrlLoSpinBox->blockSignals(false); - } - } - else + switch(type) { - ctrlHiSpinBox->setEnabled(true); - ctrlLoSpinBox->setEnabled(true); - if(hv != ctrlHiSpinBox->value()) - { + case MusECore::MidiController::Program: + case MusECore::MidiController::Pitch: + case MusECore::MidiController::PolyAftertouch: // Unsupported yet. Need a way to select pitch. + case MusECore::MidiController::Aftertouch: + ctrlHiSpinBox->setEnabled(false); + ctrlLoSpinBox->setEnabled(false); ctrlHiSpinBox->blockSignals(true); - ctrlHiSpinBox->setValue(hv); - ctrlHiSpinBox->blockSignals(false); - } - if(lv != ctrlLoSpinBox->value()) - { ctrlLoSpinBox->blockSignals(true); - ctrlLoSpinBox->setValue(lv); + ctrlHiSpinBox->setValue(0); + ctrlLoSpinBox->setValue(0); + ctrlHiSpinBox->blockSignals(false); ctrlLoSpinBox->blockSignals(false); - } + break; + case MusECore::MidiController::Controller7: + ctrlHiSpinBox->setEnabled(false); + ctrlLoSpinBox->setEnabled(true); + + ctrlHiSpinBox->blockSignals(true); + ctrlHiSpinBox->setValue(0); + ctrlHiSpinBox->blockSignals(false); + + if(lv != ctrlLoSpinBox->value()) + { + ctrlLoSpinBox->blockSignals(true); + ctrlLoSpinBox->setValue(lv); + ctrlLoSpinBox->blockSignals(false); + } + break; + case MusECore::MidiController::Controller14: + case MusECore::MidiController::RPN: + case MusECore::MidiController::RPN14: + case MusECore::MidiController::NRPN: + case MusECore::MidiController::NRPN14: + ctrlHiSpinBox->setEnabled(true); + ctrlLoSpinBox->setEnabled(true); + if(hv != ctrlHiSpinBox->value()) + { + ctrlHiSpinBox->blockSignals(true); + ctrlHiSpinBox->setValue(hv); + ctrlHiSpinBox->blockSignals(false); + } + if(lv != ctrlLoSpinBox->value()) + { + ctrlLoSpinBox->blockSignals(true); + ctrlLoSpinBox->setValue(lv); + ctrlLoSpinBox->blockSignals(false); + } + break; + default: + printf("FIXME: MidiAudioControl::updateCtrlBoxes: Unknown control type: %d\n", type); + break; } } -} +} // namespace MusEGui diff --git a/muse2/muse/widgets/midi_audio_control_base.ui b/muse2/muse/widgets/midi_audio_control_base.ui index 2e341121..11ecc590 100644 --- a/muse2/muse/widgets/midi_audio_control_base.ui +++ b/muse2/muse/widgets/midi_audio_control_base.ui @@ -6,8 +6,8 @@ <rect> <x>0</x> <y>0</y> - <width>341</width> - <height>148</height> + <width>367</width> + <height>156</height> </rect> </property> <property name="windowTitle"> @@ -80,46 +80,6 @@ <verstretch>0</verstretch> </sizepolicy> </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> @@ -225,7 +185,7 @@ </sizepolicy> </property> <property name="text"> - <string>Learn</string> + <string>&Learn</string> </property> <property name="checkable"> <bool>true</bool> |