summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--muse2/muse/helper.cpp12
-rw-r--r--muse2/muse/helper.h4
-rw-r--r--muse2/muse/midiedit/dcanvas.cpp423
-rw-r--r--muse2/muse/midiedit/dcanvas.h46
-rw-r--r--muse2/muse/midiedit/dlist.cpp223
-rw-r--r--muse2/muse/midiedit/dlist.h18
-rw-r--r--muse2/muse/midiedit/drumedit.cpp96
-rw-r--r--muse2/muse/midiedit/drumedit.h17
-rw-r--r--muse2/muse/midiedit/drummap.cpp2
-rw-r--r--muse2/muse/midiedit/drummap.h10
-rw-r--r--muse2/muse/midiedit/prcanvas.cpp4
-rw-r--r--muse2/muse/midiedit/prcanvas.h1
-rw-r--r--muse2/muse/midiedit/scoreedit.cpp25
-rw-r--r--muse2/muse/midiedit/scoreedit.h2
-rw-r--r--muse2/muse/track.cpp42
-rw-r--r--muse2/muse/track.h13
-rw-r--r--muse2/muse/undo.cpp12
-rw-r--r--muse2/muse/undo.h3
18 files changed, 791 insertions, 162 deletions
diff --git a/muse2/muse/helper.cpp b/muse2/muse/helper.cpp
index 1a223bb3..255e8505 100644
--- a/muse2/muse/helper.cpp
+++ b/muse2/muse/helper.cpp
@@ -328,4 +328,16 @@ bool any_event_selected(const set<Part*>& parts, bool in_range)
return !get_events(parts, in_range ? 3 : 1).empty();
}
+bool drummaps_almost_equal(DrumMap* one, DrumMap* two, int len)
+{
+ for (int i=0; i<len; i++)
+ {
+ DrumMap tmp = one[i];
+ tmp.mute=two[i].mute;
+ if (tmp!=two[i])
+ return false;
+ }
+ return true;
+}
+
} // namespace MusEUtil
diff --git a/muse2/muse/helper.h b/muse2/muse/helper.h
index e86a8949..b8ff391e 100644
--- a/muse2/muse/helper.h
+++ b/muse2/muse/helper.h
@@ -25,6 +25,8 @@
#include <set>
+#include "drummap.h"
+
class QActionGroup;
class QString;
class QMenu;
@@ -43,6 +45,8 @@ bool any_event_selected(const std::set<Part*>&, bool in_range=false);
QMenu* populateAddSynth(QWidget* parent);
QActionGroup* populateAddTrack(QMenu* addTrack);
+bool drummaps_almost_equal(DrumMap* one, DrumMap* two, int drummap_size=128);
+
}
#endif
diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp
index 138511d6..34173780 100644
--- a/muse2/muse/midiedit/dcanvas.cpp
+++ b/muse2/muse/midiedit/dcanvas.cpp
@@ -34,12 +34,12 @@
#include <stdio.h>
#include <values.h>
#include <errno.h>
-#include <set>
//#include <sys/stat.h>
//#include <sys/mman.h>
#include "dcanvas.h"
#include "midieditor.h"
+#include "drumedit.h"
#include "drummap.h"
#include "event.h"
#include "mpevent.h"
@@ -50,18 +50,21 @@
#include "shortcuts.h"
#include "icons.h"
#include "functions.h"
+#include "helper.h"
#define CARET 10
#define CARET2 5
+using MusEGlobal::debugMsg;
+using MusEGlobal::heavyDebugMsg;
+
//---------------------------------------------------------
// DEvent
//---------------------------------------------------------
-DEvent::DEvent(Event e, Part* p)
+DEvent::DEvent(Event e, Part* p, int instr)
: CItem(e, p)
{
- int instr = e.pitch();
int y = instr * TH + TH/2;
int tick = e.tick() + p->tick();
setPos(QPoint(tick, y));
@@ -79,7 +82,14 @@ void DrumCanvas::addItem(Part* part, Event& event)
return;
}
- DEvent* ev = new DEvent(event, part);
+ int instr=pitch_and_track_to_instrument(event.pitch(), part->track());
+ if (instr<0)
+ {
+ if (heavyDebugMsg) printf("trying to add event which is hidden or not in any part known to me\n");
+ return;
+ }
+
+ DEvent* ev = new DEvent(event, part, instr);
items.add(ev);
int diff = event.endTick()-part->lenTick();
@@ -101,6 +111,35 @@ DrumCanvas::DrumCanvas(MidiEditor* pr, QWidget* parent, int sx,
int sy, const char* name)
: EventCanvas(pr, parent, sx, sy, name)
{
+ drumEditor=dynamic_cast<DrumEdit*>(pr);
+
+ old_style_drummap_mode = drumEditor->old_style_drummap_mode();
+
+ if (old_style_drummap_mode)
+ {
+ if (debugMsg) printf("DrumCanvas in old style drummap mode\n");
+ ourDrumMap = drumMap;
+ must_delete_our_drum_map=false;
+
+ instrument_number_mapping_t temp;
+ for (ciPart it=drumEditor->parts()->begin(); it!=drumEditor->parts()->end(); it++)
+ temp.tracks.insert(it->second->track());
+
+ for (int i=0;i<DRUM_MAPSIZE;i++)
+ {
+ temp.pitch=i;
+ instrument_map.append(temp);
+ }
+ }
+ else
+ {
+ if (debugMsg) printf("DrumCanvas in new style drummap mode\n");
+ ourDrumMap=NULL;
+ rebuildOurDrumMap();
+ }
+
+
+
setVirt(false);
cursorPos= QPoint(0,0);
_stepSize=1;
@@ -114,6 +153,10 @@ DrumCanvas::DrumCanvas(MidiEditor* pr, QWidget* parent, int sx,
DrumCanvas::~DrumCanvas()
{
//items.clearDelete();
+
+ if (must_delete_our_drum_map && ourDrumMap!=NULL)
+ delete [] ourDrumMap;
+ delete steprec;
}
//---------------------------------------------------------
@@ -193,7 +236,7 @@ Undo DrumCanvas::moveCanvasItems(MusEWidget::CItemList& items, int dp, int dx, D
for(MusEWidget::iCItem ici = items.begin(); ici != items.end(); ++ici)
{
- MusEWidget::CItem* ci = ici->second;
+ MusEWidget::CItem* ci = ici->second;
int x = ci->pos().x();
int y = ci->pos().y();
@@ -215,7 +258,7 @@ Undo DrumCanvas::moveCanvasItems(MusEWidget::CItemList& items, int dp, int dx, D
doneList.push_back(ci);
}
ci->move(newpos);
-
+
if(moving.size() == 1)
itemReleased(curItem, newpos);
@@ -256,10 +299,20 @@ UndoOp DrumCanvas::moveItem(MusEWidget::CItem* item, const QPoint& pos, DragType
int ntick = editor->rasterVal(x) - part->tick();
if (ntick < 0)
ntick = 0;
- int npitch = y2pitch(pos.y());
+ int nheight = y2pitch(pos.y());
Event newEvent = event.clone();
-
- newEvent.setPitch(npitch);
+
+ Track* dest_track = part->track();
+ if (!instrument_map[nheight].tracks.contains(dest_track))
+ {
+ printf ("TODO FIXME: tried to move an event into a different track. this is not supported yet, but will be soon. ignoring this one...\n");
+ //FINDMICH
+ return UndoOp();
+ }
+
+ int ev_pitch = instrument_map[nheight].pitch;
+
+ newEvent.setPitch(ev_pitch);
newEvent.setTick(ntick);
// Added by T356, removed by flo93: with operation groups, it happens that the
@@ -280,13 +333,13 @@ UndoOp DrumCanvas::moveItem(MusEWidget::CItem* item, const QPoint& pos, DragType
MusEWidget::CItem* DrumCanvas::newItem(const QPoint& p, int state)
{
int instr = y2pitch(p.y()); //drumInmap[y2pitch(p.y())];
- int velo = drumMap[instr].lv4;
+ int velo = ourDrumMap[instr].lv4;
if (state == Qt::ShiftModifier)
- velo = drumMap[instr].lv3;
+ velo = ourDrumMap[instr].lv3;
else if (state == Qt::ControlModifier)
- velo = drumMap[instr].lv2;
+ velo = ourDrumMap[instr].lv2;
else if (state == (Qt::ControlModifier | Qt::ShiftModifier))
- velo = drumMap[instr].lv1;
+ velo = ourDrumMap[instr].lv1;
int tick = editor->rasterVal(p.x());
return newItem(tick, instr, velo);
}
@@ -297,13 +350,22 @@ MusEWidget::CItem* DrumCanvas::newItem(const QPoint& p, int state)
MusEWidget::CItem* DrumCanvas::newItem(int tick, int instrument, int velocity)
{
- tick -= curPart->tick();
- Event e(Note);
- e.setTick(tick);
- e.setPitch(instrument);
- e.setVelo(velocity);
- e.setLenTick(drumMap[instrument].len);
- return new DEvent(e, curPart);
+ if (!old_style_drummap_mode && !instrument_map[instrument].tracks.contains(curPart->track()))
+ {
+ printf("FINDMICH: tried to create a new Item which cannot be inside the current track. returning NULL\n");
+ return NULL;
+ }
+ else
+ {
+ tick -= curPart->tick();
+ Event e(Note);
+ e.setTick(tick);
+ e.setPitch(instrument_map[instrument].pitch);
+ e.setVelo(velocity);
+ e.setLenTick(ourDrumMap[instrument].len);
+
+ return new DEvent(e, curPart, instrument);
+ }
}
//---------------------------------------------------------
@@ -326,7 +388,9 @@ void DrumCanvas::newItem(MusEWidget::CItem* item, bool noSnap) {
}
void DrumCanvas::newItem(MusEWidget::CItem* item, bool noSnap, bool replace)
- {
+{
+ if (item)
+ {
DEvent* nevent = (DEvent*) item;
Event event = nevent->event();
int x = item->x();
@@ -334,7 +398,7 @@ void DrumCanvas::newItem(MusEWidget::CItem* item, bool noSnap, bool replace)
x = editor->rasterVal(x);
event.setTick(x - nevent->part()->tick());
int npitch = event.pitch();
- event.setPitch(npitch);
+ //event.setPitch(npitch); // commented out by flo: has no effect
//
// check for existing event
@@ -370,7 +434,7 @@ void DrumCanvas::newItem(MusEWidget::CItem* item, bool noSnap, bool replace)
{
operations.push_back(UndoOp(UndoOp::AddEvent,event, part, false, false));
- if (diff > 0)// part must be extended?
+ if (diff > 0) // part must be extended?
{
schedule_resize_all_same_len_clone_parts(part, event.endTick(), operations);
printf("newItem: extending\n");
@@ -380,7 +444,10 @@ void DrumCanvas::newItem(MusEWidget::CItem* item, bool noSnap, bool replace)
song->applyOperationGroup(operations);
songChanged(SC_EVENT_INSERTED); //this forces an update of the itemlist, which is neccessary
//to remove "forbidden" events from the list again
- }
+ }
+ else
+ printf("THIS SHOULD NEVER HAPPEN: DrumCanvas::newItem called with NULL item!\n");
+}
//---------------------------------------------------------
// deleteItem
@@ -435,7 +502,7 @@ void DrumCanvas::drawItem(QPainter&p, const MusEWidget::CItem*item, const QRect&
else
{
int velo = e->event().velo();
- DrumMap* dm = &drumMap[y2pitch(y)]; //Get the drum item
+ DrumMap* dm = &ourDrumMap[y2pitch(y)]; //Get the drum item
QColor color;
if (velo < dm->lv1)
color.setRgb(240, 240, 255);
@@ -526,8 +593,8 @@ void DrumCanvas::drawTopItem(QPainter& p, const QRect&)
int DrumCanvas::y2pitch(int y) const
{
int pitch = y/TH;
- if (pitch >= DRUM_MAPSIZE)
- pitch = DRUM_MAPSIZE-1;
+ if (pitch >= instrument_map.size())
+ pitch = instrument_map.size()-1;
return pitch;
}
@@ -636,7 +703,8 @@ void DrumCanvas::cmd(int cmd)
DEvent* devent = (DEvent*)(k->second);
Event event = devent->event();
Event newEvent = event.clone();
- newEvent.setLenTick(drumMap[event.pitch()].len);
+ // newEvent.setLenTick(drumMap[event.pitch()].len);
+ newEvent.setLenTick(ourDrumMap[y2pitch(devent->y())].len);
// Indicate no undo, and do not do port controller values and clone parts.
audio->msgChangeEvent(event, newEvent, devent->part(), false, false, false);
}
@@ -738,19 +806,19 @@ void DrumCanvas::dragLeaveEvent(QDragLeaveEvent*)
// keyPressed - called from DList
//---------------------------------------------------------
-void DrumCanvas::keyPressed(int index, int velocity)
+void DrumCanvas::keyPressed(int index, int velocity) //FINDMICH later
{
// called from DList - play event
- int port = drumMap[index].port;
- int channel = drumMap[index].channel;
- int pitch = drumMap[index].anote;
+ int port = ourDrumMap[index].port;
+ int channel = ourDrumMap[index].channel;
+ int pitch = ourDrumMap[index].anote;
// play note:
MidiPlayEvent e(0, port, channel, 0x90, pitch, velocity);
audio->msgPlayMidiEvent(&e);
if (_steprec && pos[0] >= start_tick /* && pos[0] < end_tick [removed by flo93: this is handled in steprec->record] */ && curPart)
- steprec->record(curPart,index,drumMap[index].len,editor->raster(),velocity,MusEGlobal::globalKeyState&Qt::ControlModifier,MusEGlobal::globalKeyState&Qt::ShiftModifier);
+ steprec->record(curPart,index,ourDrumMap[index].len,editor->raster(),velocity,MusEGlobal::globalKeyState&Qt::ControlModifier,MusEGlobal::globalKeyState&Qt::ShiftModifier);
}
@@ -758,12 +826,12 @@ void DrumCanvas::keyPressed(int index, int velocity)
// keyReleased
//---------------------------------------------------------
-void DrumCanvas::keyReleased(int index, bool)
+void DrumCanvas::keyReleased(int index, bool) //FINDMICH later
{
// called from DList - silence playing event
- int port = drumMap[index].port;
- int channel = drumMap[index].channel;
- int pitch = drumMap[index].anote;
+ int port = ourDrumMap[index].port;
+ int channel = ourDrumMap[index].channel;
+ int pitch = ourDrumMap[index].anote;
// release note:
MidiPlayEvent e(0, port, channel, 0x90, pitch, 0);
@@ -775,7 +843,12 @@ void DrumCanvas::keyReleased(int index, bool)
//---------------------------------------------------------
void DrumCanvas::mapChanged(int spitch, int dpitch)
- {
+{
+ // spitch may be the same as dpitch! and something in here must be executed
+ // even if they're same (i assume it's song->update(SC_DRUMMAP)) (flo93)
+
+ if (old_style_drummap_mode)
+ {
Undo operations;
std::vector< std::pair<Part*, Event*> > delete_events;
std::vector< std::pair<Part*, Event> > add_events;
@@ -853,7 +926,71 @@ void DrumCanvas::mapChanged(int spitch, int dpitch)
song->applyOperationGroup(operations, false); // do not indicate undo
song->update(SC_DRUMMAP); //this update is neccessary, as it's not handled by applyOperationGroup()
+ }
+ else // if (!old_style_drummap_mode)
+ {
+ if (dpitch!=spitch)
+ {
+ DrumMap dm_temp = ourDrumMap[spitch];
+ instrument_number_mapping_t im_temp = instrument_map[spitch];
+
+ global_drum_ordering_t order_temp;
+ for (global_drum_ordering_t::iterator it=global_drum_ordering.begin(); it!=global_drum_ordering.end();)
+ {
+ if (im_temp.pitch==it->second && im_temp.tracks.contains(it->first))
+ {
+ order_temp.push_back(*it);
+ it=global_drum_ordering.erase(it);
+ }
+ else
+ it++;
+ }
+
+ // the instrument represented by instrument_map[dpitch] is always the instrument
+ // which will be immediately AFTER our dragged instrument
+ for (global_drum_ordering_t::iterator it=global_drum_ordering.begin(); it!=global_drum_ordering.end(); it++)
+ if (instrument_map[dpitch].pitch==it->second && instrument_map[dpitch].tracks.contains(it->first))
+ {
+ while (!order_temp.empty())
+ it=global_drum_ordering.insert(it, order_temp.takeLast());
+
+ break;
+ }
+
+
+
+
+
+ if (dpitch > spitch)
+ {
+ for (int i=spitch; i<dpitch-1; i++)
+ {
+ ourDrumMap[i]=ourDrumMap[i+1];
+ instrument_map[i]=instrument_map[i+1];
+ }
+
+ ourDrumMap[dpitch-1] = dm_temp;
+ instrument_map[dpitch-1] = im_temp;
+ }
+ else if (spitch > dpitch)
+ {
+ for (int i=spitch; i>dpitch; i--)
+ {
+ ourDrumMap[i]=ourDrumMap[i-1];
+ instrument_map[i]=instrument_map[i-1];
+ }
+
+ ourDrumMap[dpitch] = dm_temp;
+ instrument_map[dpitch] = im_temp;
+ }
}
+
+
+ song->update(SC_DRUMMAP); // this causes a complete rebuild of ourDrumMap
+ // which also handles the changed order in all
+ // other drum editors
+ }
+}
//---------------------------------------------------------
// resizeEvent
@@ -905,6 +1042,7 @@ void DrumCanvas::modifySelected(MusEWidget::NoteInfo::ValType type, int delta)
printf("DrumCanvas::modifySelected - MusEWidget::NoteInfo::VAL_VELOFF not implemented\n");
break;
case MusEWidget::NoteInfo::VAL_PITCH:
+ if (old_style_drummap_mode)
{
int pitch = event.pitch() - delta; // Reversing order since the drumlist is displayed in increasing order
if (pitch > 127)
@@ -913,6 +1051,8 @@ void DrumCanvas::modifySelected(MusEWidget::NoteInfo::ValType type, int delta)
pitch = 0;
newEvent.setPitch(pitch);
}
+ else
+ printf("DrumCanvas::modifySelected - MusEWidget::NoteInfo::VAL_PITCH not implemented for new style drum editors\n");
break;
}
song->changeEvent(event, newEvent, part);
@@ -990,8 +1130,8 @@ void DrumCanvas::keyPress(QKeyEvent* event)
return;
}
else if (key == shortcuts[SHRT_ADDNOTE_1].key) {
- newItem(newItem(cursorPos.x(), cursorPos.y(), drumMap[cursorPos.y()].lv1),false,true);
- keyPressed(cursorPos.y(), drumMap[cursorPos.y()].lv1);
+ newItem(newItem(cursorPos.x(), cursorPos.y(), ourDrumMap[cursorPos.y()].lv1),false,true);
+ keyPressed(cursorPos.y(), ourDrumMap[cursorPos.y()].lv1);
keyReleased(cursorPos.y(), false);
cursorPos.setX(getNextStep(cursorPos.x(),1, _stepSize));
selectCursorEvent(getEventAtCursorPos());
@@ -1000,8 +1140,8 @@ void DrumCanvas::keyPress(QKeyEvent* event)
return;
}
else if (key == shortcuts[SHRT_ADDNOTE_2].key) {
- newItem(newItem(cursorPos.x(), cursorPos.y(), drumMap[cursorPos.y()].lv2),false,true);
- keyPressed(cursorPos.y(), drumMap[cursorPos.y()].lv2);
+ newItem(newItem(cursorPos.x(), cursorPos.y(), ourDrumMap[cursorPos.y()].lv2),false,true);
+ keyPressed(cursorPos.y(), ourDrumMap[cursorPos.y()].lv2);
keyReleased(cursorPos.y(), false);
cursorPos.setX(getNextStep(cursorPos.x(),1, _stepSize));
selectCursorEvent(getEventAtCursorPos());
@@ -1010,8 +1150,8 @@ void DrumCanvas::keyPress(QKeyEvent* event)
return;
}
else if (key == shortcuts[SHRT_ADDNOTE_3].key) {
- newItem(newItem(cursorPos.x(), cursorPos.y(), drumMap[cursorPos.y()].lv3),false,true);
- keyPressed(cursorPos.y(), drumMap[cursorPos.y()].lv3);
+ newItem(newItem(cursorPos.x(), cursorPos.y(), ourDrumMap[cursorPos.y()].lv3),false,true);
+ keyPressed(cursorPos.y(), ourDrumMap[cursorPos.y()].lv3);
keyReleased(cursorPos.y(), false);
cursorPos.setX(getNextStep(cursorPos.x(),1, _stepSize));
selectCursorEvent(getEventAtCursorPos());
@@ -1020,8 +1160,8 @@ void DrumCanvas::keyPress(QKeyEvent* event)
return;
}
else if (key == shortcuts[SHRT_ADDNOTE_4].key) {
- newItem(newItem(cursorPos.x(), cursorPos.y(), drumMap[cursorPos.y()].lv4),false,true);
- keyPressed(cursorPos.y(), drumMap[cursorPos.y()].lv4);
+ newItem(newItem(cursorPos.x(), cursorPos.y(), ourDrumMap[cursorPos.y()].lv4),false,true);
+ keyPressed(cursorPos.y(), ourDrumMap[cursorPos.y()].lv4);
keyReleased(cursorPos.y(), false);
cursorPos.setX(getNextStep(cursorPos.x(),1, _stepSize));
selectCursorEvent(getEventAtCursorPos());
@@ -1069,17 +1209,19 @@ Event *DrumCanvas::getEventAtCursorPos()
{
if (_tool != MusEWidget::CursorTool)
return 0;
- EventList* el = curPart->events();
- iEvent lower = el->lower_bound(cursorPos.x()-curPart->tick());
- iEvent upper = el->upper_bound(cursorPos.x()-curPart->tick());
- for (iEvent i = lower; i != upper; ++i) {
- Event &ev = i->second;
- if(!ev.isNote())
- continue;
- if (ev.pitch() == cursorPos.y()) {
- return &ev;
+ if (instrument_map[cursorPos.y()].tracks.contains(curPart->track()))
+ {
+ EventList* el = curPart->events();
+ iEvent lower = el->lower_bound(cursorPos.x()-curPart->tick());
+ iEvent upper = el->upper_bound(cursorPos.x()-curPart->tick());
+ int curPitch = instrument_map[cursorPos.y()].pitch;
+ for (iEvent i = lower; i != upper; ++i) {
+ Event &ev = i->second;
+ if (ev.isNote() && ev.pitch() == curPitch)
+ return &ev;
}
}
+ // else or if the for loop didn't find anything
return 0;
}
//---------------------------------------------------------
@@ -1103,9 +1245,13 @@ void DrumCanvas::selectCursorEvent(Event *ev)
void DrumCanvas::moveAwayUnused()
{
- using std::set;
+ if (!old_style_drummap_mode)
+ {
+ printf("THIS SHOULD NEVER HAPPEN: DrumCanvas::moveAwayUnused() cannot be used in new style mode\n");
+ return;
+ }
- set<int> used;
+ QSet<int> used;
for (MusEWidget::iCItem it=items.begin(); it!=items.end(); it++)
{
const Event& ev=it->second->event();
@@ -1115,7 +1261,7 @@ void DrumCanvas::moveAwayUnused()
}
int count=0;
- for (set<int>::iterator it=used.begin(); it!=used.end();)
+ for (QSet<int>::iterator it=used.begin(); it!=used.end();)
{
while ((*it != count) && (used.find(count)!=used.end())) count++;
@@ -1132,14 +1278,167 @@ void DrumCanvas::moveAwayUnused()
//---------------------------------------------------------
// midiNote
//---------------------------------------------------------
-void DrumCanvas::midiNote(int pitch, int velo)
+void DrumCanvas::midiNote(int pitch, int velo) //FINDMICH later.
{
- if (MusEGlobal::debugMsg) printf("DrumCanvas::midiNote: pitch=%i, velo=%i\n", pitch, velo);
+ if (debugMsg) printf("DrumCanvas::midiNote: pitch=%i, velo=%i\n", pitch, velo);
if (_midiin && _steprec && curPart
&& !audio->isPlaying() && velo && pos[0] >= start_tick
- /* && pos[0] < end_tick [removed by flo93: this is handled in steprec->record] */
+ /* && pos[0] < end_tick [removed by flo93: this is handled in steprec->record()] */
&& !(MusEGlobal::globalKeyState & Qt::AltModifier)) {
- steprec->record(curPart,drumInmap[pitch],drumMap[(int)drumInmap[pitch]].len,editor->raster(),velo,MusEGlobal::globalKeyState&Qt::ControlModifier,MusEGlobal::globalKeyState&Qt::ShiftModifier);
+ steprec->record(curPart,drumInmap[pitch],ourDrumMap[(int)drumInmap[pitch]].len,editor->raster(),velo,MusEGlobal::globalKeyState&Qt::ControlModifier,MusEGlobal::globalKeyState&Qt::ShiftModifier);
}
}
+
+
+int DrumCanvas::pitch_and_track_to_instrument(int pitch, Track* track)
+{
+ for (int i=0; i<instrument_map.size(); i++)
+ if (instrument_map[i].tracks.contains(track) && instrument_map[i].pitch==pitch)
+ return i;
+
+ printf("ERROR: DrumCanvas::pitch_and_track_to_instrument() called with invalid arguments!\n");
+ return -1;
+}
+
+void DrumCanvas::propagate_drummap_change(int instr)
+{
+ const QSet<Track*>& tracks=instrument_map[instr].tracks;
+ int index=instrument_map[instr].pitch;
+
+ for (QSet<Track*>::const_iterator it = tracks.begin(); it != tracks.end(); it++)
+ dynamic_cast<MidiTrack*>(*it)->drummap()[index] = ourDrumMap[instr];
+}
+
+
+void DrumCanvas::rebuildOurDrumMap()
+{
+ using MusEUtil::drummaps_almost_equal;
+
+ if (!old_style_drummap_mode)
+ {
+ TrackList* tl=song->tracks();
+ QList< QSet<Track*> > track_groups;
+
+ instrument_map.clear();
+
+ for (ciTrack track = tl->begin(); track!=tl->end(); track++)
+ {
+ ciPart p_it;
+ for (p_it=drumEditor->parts()->begin(); p_it!=drumEditor->parts()->end(); p_it++)
+ if (p_it->second->track() == *track)
+ break;
+
+ if (p_it!=drumEditor->parts()->end()) // if *track is represented by some part in this editor
+ {
+ bool inserted=false;
+
+ switch (drumEditor->group_mode())
+ {
+ case DrumEdit::GROUP_SAME_CHANNEL:
+ for (QList< QSet<Track*> >::iterator group=track_groups.begin(); group!=track_groups.end(); group++)
+ if ( ((MidiTrack*)*group->begin())->outChannel() == ((MidiTrack*)*track)->outChannel() &&
+ ((MidiTrack*)*group->begin())->outPort() == ((MidiTrack*)*track)->outPort() &&
+ (drummaps_almost_equal(((MidiTrack*)*group->begin())->drummap(), ((MidiTrack*)*track)->drummap())) )
+ {
+ group->insert(*track);
+ inserted=true;
+ break;
+ }
+ break;
+
+ case DrumEdit::GROUP_MAX:
+ for (QList< QSet<Track*> >::iterator group=track_groups.begin(); group!=track_groups.end(); group++)
+ if (drummaps_almost_equal(((MidiTrack*)*group->begin())->drummap(), ((MidiTrack*)*track)->drummap()))
+ {
+ group->insert(*track);
+ inserted=true;
+ break;
+ }
+ break;
+
+ case DrumEdit::DONT_GROUP:
+ inserted=false;
+ break;
+
+ default:
+ printf("THIS SHOULD NEVER HAPPEN: group_mode() is invalid!\n");
+ inserted=false;
+ }
+
+ if (!inserted)
+ {
+ QSet<Track*> temp;
+ temp.insert(*track);
+ track_groups.push_back(temp);
+ }
+ }
+ }
+
+ // from now, we assume that every track_group's entry only groups tracks with identical
+ // drum maps, but not necessarily identical hide-lists together.
+ QList< std::pair<MidiTrack*,int> > ignore_order_entries;
+ for (global_drum_ordering_t::iterator order_it=global_drum_ordering.begin(); order_it!=global_drum_ordering.end(); order_it++)
+ {
+ // if this entry should be ignored, ignore it.
+ if (ignore_order_entries.contains(*order_it))
+ continue;
+
+ // look if we have order_it->first (the MidiTrack*) in any of our track groups
+ QList< QSet<Track*> >::iterator group;
+ for (group=track_groups.begin(); group!=track_groups.end(); group++)
+ if (group->contains(order_it->first))
+ break;
+
+ if (group!=track_groups.end()) // we have
+ {
+ int pitch=order_it->second;
+
+ bool mute=true;
+ bool hidden=true;
+ for (QSet<Track*>::iterator track=group->begin(); track!=group->end() && (mute || hidden); track++)
+ {
+ if (dynamic_cast<MidiTrack*>(*track)->drummap()[pitch].mute == false)
+ mute=false;
+
+ if (dynamic_cast<MidiTrack*>(*track)->drummap_hidden()[pitch] == false)
+ hidden=false;
+ }
+
+ if (!hidden)
+ {
+ for (QSet<Track*>::iterator track=group->begin(); track!=group->end(); track++)
+ dynamic_cast<MidiTrack*>(*track)->drummap()[pitch].mute=mute;
+
+ if (dynamic_cast<MidiTrack*>(*group->begin())->drummap()[pitch].anote != pitch)
+ printf("THIS SHOULD NEVER HAPPEN: track's_drummap[pitch].anote (%i)!= pitch (%i) !!!\n",dynamic_cast<MidiTrack*>(*group->begin())->drummap()[pitch].anote,pitch);
+
+ instrument_map.append(instrument_number_mapping_t(*group, pitch));
+ }
+
+ for (QSet<Track*>::iterator track=group->begin(); track!=group->end(); track++)
+ ignore_order_entries.append(std::pair<MidiTrack*,int>(dynamic_cast<MidiTrack*>(*track), pitch));
+ }
+ // else ignore it
+ }
+
+
+ // maybe delete and then populate ourDrumMap
+
+ if (must_delete_our_drum_map && ourDrumMap!=NULL)
+ delete [] ourDrumMap;
+
+ int size = instrument_map.size();
+ ourDrumMap=new DrumMap[size];
+ must_delete_our_drum_map=true;
+
+ for (int i=0;i<size;i++)
+ ourDrumMap[i] = dynamic_cast<MidiTrack*>(*instrument_map[i].tracks.begin())->drummap()[instrument_map[i].pitch];
+
+ if (debugMsg) printf("rebuilt drummap, size is now %i\n",size);
+
+ songChanged(SC_EVENT_INSERTED); // force an update of the itemlist
+
+ emit ourDrumMapChanged();
+ }
+}
diff --git a/muse2/muse/midiedit/dcanvas.h b/muse2/muse/midiedit/dcanvas.h
index c5c51310..9a45f6ac 100644
--- a/muse2/muse/midiedit/dcanvas.h
+++ b/muse2/muse/midiedit/dcanvas.h
@@ -26,6 +26,9 @@
#include "ecanvas.h"
#include "song.h"
#include "steprec.h"
+#include <map>
+#include <QList>
+#include <QSet>
#define TH 18
@@ -36,7 +39,9 @@ class QDropEvent;
class QDragMoveEvent;
class QDragLeaveEvent;
+class DrumMap;
class MidiEditor;
+class DrumEdit;
//---------------------------------------------------------
// DEvent
@@ -45,12 +50,31 @@ class MidiEditor;
class DEvent : public MusEWidget::CItem {
public:
- DEvent(Event e, Part* p);
+ DEvent(Event e, Part* p, int instr);
};
class ScrollScale;
class PianoRoll;
+
+struct instrument_number_mapping_t
+{
+ QSet<Track*> tracks;
+ int pitch;
+
+ instrument_number_mapping_t()
+ {
+ pitch=-1;
+ tracks.clear();
+ }
+
+ instrument_number_mapping_t(const QSet<Track*>& tr, int p)
+ {
+ tracks=tr;
+ pitch=p;
+ }
+};
+
//---------------------------------------------------------
// DrumCanvas
//---------------------------------------------------------
@@ -58,6 +82,13 @@ class PianoRoll;
class DrumCanvas : public EventCanvas {
Q_OBJECT
+ bool old_style_drummap_mode;
+ DrumMap* ourDrumMap;
+ bool must_delete_our_drum_map; //FINDMICH really delete it!
+ QVector<instrument_number_mapping_t> instrument_map;
+
+ DrumEdit* drumEditor;
+
StepRec* steprec;
// Cursor tool position
@@ -88,9 +119,10 @@ class DrumCanvas : public EventCanvas {
virtual void resizeEvent(QResizeEvent*);
virtual void curPartChanged();
int getNextStep(unsigned int pos, int basicStep, int stepSize=1);
-
+
signals:
void newWidth(int);
+ void ourDrumMapChanged();
private slots:
void midiNote(int pitch, int velo);
@@ -110,7 +142,8 @@ class DrumCanvas : public EventCanvas {
CMD_SELECT_ALL, CMD_SELECT_NONE, CMD_SELECT_INVERT,
CMD_SELECT_ILOOP, CMD_SELECT_OLOOP, CMD_SELECT_PREV_PART, CMD_SELECT_NEXT_PART,
CMD_DEL, CMD_FIXED_LEN, CMD_RIGHT, CMD_LEFT, CMD_RIGHT_NOSNAP, CMD_LEFT_NOSNAP, CMD_MODIFY_VELOCITY, CMD_CRESCENDO,
- CMD_QUANTIZE, CMD_ERASE_EVENT, CMD_NOTE_SHIFT, CMD_DELETE_OVERLAPS, CMD_REORDER_LIST
+ CMD_QUANTIZE, CMD_ERASE_EVENT, CMD_NOTE_SHIFT, CMD_DELETE_OVERLAPS, CMD_REORDER_LIST,
+ CMD_GROUP_NONE, CMD_GROUP_CHAN, CMD_GROUP_MAX
};
DrumCanvas(MidiEditor*, QWidget*, int, int,
const char* name = 0);
@@ -120,7 +153,12 @@ class DrumCanvas : public EventCanvas {
virtual void keyPress(QKeyEvent* event);
Event *getEventAtCursorPos();
void selectCursorEvent(Event *ev);
-
+ int pitch_and_track_to_instrument(int pitch, Track* track);
+ DrumMap* getOurDrumMap() { return ourDrumMap; } //FINDMICH UGLY
+ int getOurDrumMapSize() { return instrument_map.size(); } //FINDMICH UGLY
+
+ void propagate_drummap_change(int instrument); //FINDMICH move to drumedit
+ void rebuildOurDrumMap();
};
#endif
diff --git a/muse2/muse/midiedit/dlist.cpp b/muse2/muse/midiedit/dlist.cpp
index 8e9633c0..350f5e5e 100644
--- a/muse2/muse/midiedit/dlist.cpp
+++ b/muse2/muse/midiedit/dlist.cpp
@@ -37,7 +37,7 @@
#include "icons.h"
#include "dlist.h"
#include "song.h"
-#include "scrollscale.h"
+#include "dcanvas.h"
//---------------------------------------------------------
// draw
@@ -56,13 +56,13 @@ void DList::draw(QPainter& p, const QRect& rect)
p.setPen(Qt::black);
- for (int i = 0; i < DRUM_MAPSIZE; ++i) {
+ for (int i = 0; i < ourDrumMapSize; ++i) {
int yy = i * TH;
if (yy+TH < y)
continue;
if (yy > y + h)
break;
- DrumMap* dm = &drumMap[i];
+ DrumMap* dm = &ourDrumMap[i];
if (dm == currentlySelected)
p.fillRect(x, yy, w, TH, Qt::yellow);
// else
@@ -178,6 +178,12 @@ void DList::draw(QPainter& p, const QRect& rect)
void DList::devicesPopupMenu(DrumMap* t, int x, int y, bool changeAll)
{
+ if (!old_style_drummap_mode)
+ {
+ printf("THIS SHOULD NEVER HAPPEN: devicesPopupMenu() called in new style mode!\n");
+ return;
+ }
+
QMenu* p = midiPortsPopup();
QAction* act = p->exec(mapToGlobal(QPoint(x, y)), 0);
bool doemit = false;
@@ -199,8 +205,8 @@ void DList::devicesPopupMenu(DrumMap* t, int x, int y, bool changeAll)
// Delete all port controller events.
song->changeAllPortDrumCtrlEvents(false);
- for (int i = 0; i < DRUM_MAPSIZE; i++)
- drumMap[i].port = n;
+ for (int i = 0; i < ourDrumMapSize; i++)
+ ourDrumMap[i].port = n;
// Add all port controller events.
song->changeAllPortDrumCtrlEvents(true);
@@ -227,13 +233,14 @@ void DList::viewMousePressEvent(QMouseEvent* ev)
int x = ev->x();
int y = ev->y();
int button = ev->button();
- unsigned pitch = y / TH;
- DrumMap* dm = &drumMap[pitch];
+ unsigned instrument = y / TH;
+ DrumMap* dm = &ourDrumMap[instrument];
+ DrumMap dm_old = *dm;
- setCurDrumInstrument(pitch);
+ setCurDrumInstrument(instrument);
startY = y;
- sPitch = pitch;
+ sInstrument = instrument;
drag = START_DRAG;
DCols col = DCols(x2col(x));
@@ -262,18 +269,18 @@ void DList::viewMousePressEvent(QMouseEvent* ev)
if (button == Qt::LeftButton)
dm->mute = !dm->mute;
break;
- case COL_PORT:
+ case COL_PORT: // this column isn't visible in new style drum mode
if ((button == Qt::RightButton) || (button == Qt::LeftButton)) {
bool changeAll = ev->modifiers() & Qt::ControlModifier;
- devicesPopupMenu(dm, mapx(x), mapy(pitch * TH), changeAll);
+ devicesPopupMenu(dm, mapx(x), mapy(instrument * TH), changeAll);
}
break;
case COL_VOL:
val = dm->vol + incVal;
if (val < 0)
val = 0;
- else if (val > 200)
- val = 200;
+ else if (val > 999) //changed from 200 to 999 by flo93
+ val = 999;
dm->vol = (unsigned char)val;
break;
case COL_QNT:
@@ -286,18 +293,22 @@ void DList::viewMousePressEvent(QMouseEvent* ev)
val = 0;
else if (val > 127)
val = 127;
- //Check if there is any other drumMap with the same inmap value (there should be one (and only one):-)
- //If so, switch the inmap between the instruments
- for (int i=0; i<DRUM_MAPSIZE; i++) {
- if (drumMap[i].enote == val && &drumMap[i] != dm) {
- drumInmap[int(dm->enote)] = i;
- drumMap[i].enote = dm->enote;
- break;
- }
- }
- //TODO: Set all the notes on the track with pitch=dm->enote to pitch=val
+
+ if (old_style_drummap_mode)
+ {
+ //Check if there is any other drumMap with the same inmap value (there should be one (and only one):-)
+ //If so, switch the inmap between the instruments
+ for (int i=0; i<ourDrumMapSize; i++) {
+ if (ourDrumMap[i].enote == val && &ourDrumMap[i] != dm) {
+ drumInmap[int(dm->enote)] = i;
+ ourDrumMap[i].enote = dm->enote;
+ break;
+ }
+ }
+ //TODO: Set all the notes on the track with instrument=dm->enote to instrument=val
+ drumInmap[val] = instrument;
+ }
dm->enote = val;
- drumInmap[val] = pitch;
break;
case COL_LEN:
val = dm->len + incVal;
@@ -306,6 +317,7 @@ void DList::viewMousePressEvent(QMouseEvent* ev)
dm->len = val;
break;
case COL_ANOTE:
+ if (old_style_drummap_mode) //only allow changing in old style mode
{
val = dm->anote + incVal;
if (val < 0)
@@ -315,16 +327,19 @@ void DList::viewMousePressEvent(QMouseEvent* ev)
if(val != dm->anote)
{
audio->msgIdle(true);
- song->remapPortDrumCtrlEvents(pitch, val, -1, -1);
+ song->remapPortDrumCtrlEvents(instrument, val, -1, -1);
audio->msgIdle(false);
dm->anote = val;
song->update(SC_DRUMMAP);
}
- int velocity = 127 * float(ev->x()) / width();
- emit keyPressed(pitch, velocity);//(dm->anote, shift);
+ }
+
+ {
+ int velocity = 127 * float(ev->x()) / width();
+ emit keyPressed(instrument, velocity);//(dm->anote, shift);
}
break;
- case COL_CHANNEL:
+ case COL_CHANNEL: // this column isn't visible in new style drum mode
val = dm->channel + incVal;
if (val < 0)
val = 0;
@@ -336,8 +351,8 @@ void DList::viewMousePressEvent(QMouseEvent* ev)
// Delete all port controller events.
song->changeAllPortDrumCtrlEvents(false, true);
- for (int i = 0; i < DRUM_MAPSIZE; i++)
- drumMap[i].channel = val;
+ for (int i = 0; i < ourDrumMapSize; i++)
+ ourDrumMap[i].channel = val;
// Add all port controller events.
song->changeAllPortDrumCtrlEvents(true, true);
audio->msgIdle(false);
@@ -348,7 +363,7 @@ void DList::viewMousePressEvent(QMouseEvent* ev)
if(val != dm->channel)
{
audio->msgIdle(true);
- song->remapPortDrumCtrlEvents(pitch, -1, val, -1);
+ song->remapPortDrumCtrlEvents(instrument, -1, val, -1);
audio->msgIdle(false);
dm->channel = val;
song->update(SC_DRUMMAP);
@@ -388,13 +403,18 @@ void DList::viewMousePressEvent(QMouseEvent* ev)
dm->lv4 = val;
break;
case COL_NAME:
- emit keyPressed(pitch, 100); //Mapping done on other side, send index
+ emit keyPressed(instrument, 100); //Mapping done on other side, send index
break;
default:
break;
}
- redraw();
+
+ if (!old_style_drummap_mode && dm_old != *dm) //something changed and we're in new style mode?
+ dcanvas->propagate_drummap_change(dm-ourDrumMap);
+
+ song->update(SC_DRUMMAP);
+ //redraw(); //this is done by the songChanged slot
}
//---------------------------------------------------------
@@ -405,18 +425,18 @@ void DList::viewMouseDoubleClickEvent(QMouseEvent* ev)
{
int x = ev->x();
int y = ev->y();
- unsigned pitch = y / TH;
+ unsigned instrument = y / TH;
int section = header->logicalIndexAt(x);
if ((section == COL_NAME || section == COL_VOL || section == COL_LEN || section == COL_LV1 ||
- section == COL_LV2 || section == COL_LV3 || section == COL_LV4 || section == COL_CHANNEL ||
- section == COL_QNT) && (ev->button() == Qt::LeftButton))
+ section == COL_LV2 || section == COL_LV3 || section == COL_LV4 || section == COL_QNT ||
+ (section == COL_CHANNEL && old_style_drummap_mode) ) && (ev->button() == Qt::LeftButton))
{
- lineEdit(pitch, section);
+ lineEdit(instrument, section);
}
- else if ((section == COL_ANOTE || section == COL_ENOTE) && (ev->button() == Qt::LeftButton))
- pitchEdit(pitch, section);
+ else if (((section == COL_ANOTE && old_style_drummap_mode) || section == COL_ENOTE) && (ev->button() == Qt::LeftButton))
+ pitchEdit(instrument, section);
else
viewMousePressEvent(ev);
}
@@ -428,7 +448,7 @@ void DList::viewMouseDoubleClickEvent(QMouseEvent* ev)
//---------------------------------------------------------
void DList::lineEdit(int line, int section)
{
- DrumMap* dm = &drumMap[line];
+ DrumMap* dm = &ourDrumMap[line];
editEntry = dm;
if (editor == 0) {
editor = new DLineEdit(this);
@@ -496,7 +516,7 @@ void DList::lineEdit(int line, int section)
//---------------------------------------------------------
void DList::pitchEdit(int line, int section)
{
- DrumMap* dm = &drumMap[line];
+ DrumMap* dm = &ourDrumMap[line];
editEntry = dm;
if (pitch_editor == 0) {
pitch_editor = new DPitchEdit(this);
@@ -550,11 +570,11 @@ int DList::x2col(int x) const
void DList::setCurDrumInstrument(int instr)
{
- if (instr < 0 || instr >= DRUM_MAPSIZE -1)
+ if (instr < 0 || instr >= ourDrumMapSize -1)
return; // illegal instrument
- DrumMap* dm = &drumMap[instr];
+ DrumMap* dm = &ourDrumMap[instr];
if (currentlySelected != dm) {
- currentlySelected = &drumMap[instr];
+ currentlySelected = dm;
emit curDrumInstrumentChanged(instr);
song->update(SC_DRUMMAP);
}
@@ -575,17 +595,22 @@ void DList::sizeChange(int, int, int)
void DList::returnPressed()
{
+ if (editEntry==NULL)
+ {
+ printf("THIS SHOULD NEVER HAPPEN: editEntry is NULL in DList::returnPressed()!\n");
+ return;
+ }
+
int val = -1;
if (selectedColumn != COL_NAME)
{
- ///val = atoi(editor->text().ascii());
val = atoi(editor->text().toAscii().constData());
switch (selectedColumn)
{
case COL_VOL:
- if (val > 200) //Check bounds for volume
- val = 200;
+ if (val > 999) //changed from 200 to 999 by flo93
+ val = 999;
if (val < 0)
val = 0;
break;
@@ -611,14 +636,14 @@ void DList::returnPressed()
default: break;
}
}
-
+
+ DrumMap editEntryOld = *editEntry;
switch(selectedColumn) {
case COL_NAME:
editEntry->name = editor->text();
break;
case COL_LEN:
- ///editEntry->len = atoi(editor->text().ascii());
editEntry->len = atoi(editor->text().toAscii().constData());
break;
@@ -654,11 +679,16 @@ void DList::returnPressed()
printf("Return pressed in unknown column\n");
break;
}
+
+ if (editEntryOld != *editEntry)
+ dcanvas->propagate_drummap_change(editEntry-ourDrumMap);
+
selectedColumn = -1;
editor->hide();
editEntry = 0;
setFocus();
- redraw();
+ song->update(SC_DRUMMAP);
+ //redraw(); //this is done by the songChanged slot
}
//---------------------------------------------------------
@@ -667,44 +697,64 @@ void DList::returnPressed()
void DList::pitchEdited()
{
+ if (editEntry==NULL)
+ {
+ printf("THIS SHOULD NEVER HAPPEN: editEntry is NULL in DList::pitchEdited()!\n");
+ return;
+ }
+
int val=pitch_editor->value();
- int pitch=(editEntry-drumMap);
+ int instrument=(editEntry-ourDrumMap);
+ DrumMap editEntryOld=*editEntry;
switch(selectedColumn) {
case COL_ANOTE:
+ if (old_style_drummap_mode) //should actually be always true, but to be sure...
+ {
if(val != editEntry->anote)
{
audio->msgIdle(true);
- song->remapPortDrumCtrlEvents(pitch, val, -1, -1);
+ song->remapPortDrumCtrlEvents(instrument, val, -1, -1);
audio->msgIdle(false);
editEntry->anote = val;
song->update(SC_DRUMMAP);
}
- break;
+ }
+ else
+ printf("ERROR: THIS SHOULD NEVER HAPPEN: pitch edited of anote in new style mode!\n");
+ break;
case COL_ENOTE:
+ if (old_style_drummap_mode)
+ {
//Check if there is any other drumMap with the same inmap value (there should be one (and only one):-)
//If so, switch the inmap between the instruments
- for (int i=0; i<DRUM_MAPSIZE; i++) {
- if (drumMap[i].enote == val && &drumMap[i] != editEntry) {
+ for (int i=0; i<ourDrumMapSize; i++) {
+ if (ourDrumMap[i].enote == val && &ourDrumMap[i] != editEntry) {
drumInmap[int(editEntry->enote)] = i;
- drumMap[i].enote = editEntry->enote;
+ ourDrumMap[i].enote = editEntry->enote;
break;
}
}
- //TODO: Set all the notes on the track with pitch=dm->enote to pitch=val
- editEntry->enote = val;
- drumInmap[val] = pitch;
- break;
+ //TODO: Set all the notes on the track with instrument=dm->enote to instrument=val
+ drumInmap[val] = instrument;
+ }
+ editEntry->enote = val;
+ break;
default:
- printf("Value changed in unknown column\n");
+ printf("ERROR: THIS SHOULD NEVER HAPPEN: Value changed in unknown column\n");
break;
}
+
+ if (editEntryOld != *editEntry)
+ dcanvas->propagate_drummap_change(editEntry-ourDrumMap);
+
selectedColumn = -1;
pitch_editor->hide();
editEntry = 0;
setFocus();
- redraw();
+ song->update(SC_DRUMMAP);
+ //redraw(); //this is done by the songChanged slot
}
//---------------------------------------------------------
@@ -739,14 +789,20 @@ void DList::songChanged(int flags)
// DList
//---------------------------------------------------------
-DList::DList(QHeaderView* h, QWidget* parent, int ymag)
+DList::DList(QHeaderView* h, QWidget* parent, int ymag, DrumCanvas* dcanvas_, bool oldstyle)
: MusEWidget::View(parent, 1, ymag)
{
setBg(Qt::white);
+
+ dcanvas=dcanvas_;
+ ourDrumMap=dcanvas->getOurDrumMap();
+ ourDrumMapSize=dcanvas->getOurDrumMapSize();
+ old_style_drummap_mode=oldstyle;
+ connect(dcanvas, SIGNAL(ourDrumMapChanged()), SLOT(ourDrumMapChanged()));
+
if (!h){
h = new QHeaderView(Qt::Horizontal, parent);}
header = h;
- scroll = 0;
//ORCAN- CHECK if really needed: header->setTracking(true);
connect(header, SIGNAL(sectionResized(int,int,int)),
SLOT(sizeChange(int,int,int)));
@@ -757,7 +813,7 @@ DList::DList(QHeaderView* h, QWidget* parent, int ymag)
pitch_editor = 0;
editEntry = 0;
// always select a drum instrument
- currentlySelected = &drumMap[0];
+ currentlySelected = &ourDrumMap[0];
selectedColumn = -1;
}
@@ -803,11 +859,21 @@ void DList::viewMouseReleaseEvent(QMouseEvent* ev)
{
if (drag == DRAG) {
int y = ev->y();
- unsigned dPitch = y / TH;
+ int dInstrument;
+ if (old_style_drummap_mode)
+ dInstrument = y / TH;
+ else
+ dInstrument = (y+TH/2) / TH;
+
+ if (dInstrument < 0) dInstrument=0;
+ if (dInstrument >= ourDrumMapSize) dInstrument=ourDrumMapSize-1;
+
+ int cur_sel = (!old_style_drummap_mode && dInstrument>sInstrument) ? dInstrument-1 : dInstrument;
+
setCursor(QCursor(Qt::ArrowCursor));
- currentlySelected = &drumMap[int(dPitch)];
- emit curDrumInstrumentChanged(dPitch);
- emit mapChanged(sPitch, dPitch); //Track pitch change done in canvas
+ currentlySelected = &ourDrumMap[cur_sel];
+ emit curDrumInstrumentChanged((unsigned)cur_sel);
+ emit mapChanged(sInstrument, (unsigned)dInstrument); //Track instrument change done in canvas
}
drag = NORMAL;
//?? redraw(); //commented out NOT by flo93; was already commented out
@@ -816,16 +882,16 @@ void DList::viewMouseReleaseEvent(QMouseEvent* ev)
int x = ev->x();
int y = ev->y();
bool shift = ev->modifiers() & Qt::ShiftModifier;
- unsigned pitch = y / TH;
+ unsigned instrument = y / TH;
DCols col = DCols(x2col(x));
switch (col) {
case COL_NAME:
- emit keyReleased(pitch, shift);
+ emit keyReleased(instrument, shift);
break;
case COL_ANOTE:
- emit keyReleased(pitch, shift);
+ emit keyReleased(instrument, shift);
break;
default:
break;
@@ -844,3 +910,16 @@ int DList::getSelectedInstrument()
}
+void DList::ourDrumMapChanged()
+{
+ int selIdx = currentlySelected - ourDrumMap;
+
+ ourDrumMap=dcanvas->getOurDrumMap();
+ ourDrumMapSize=dcanvas->getOurDrumMapSize();
+
+ editEntry=NULL;
+ if (selIdx >= ourDrumMapSize) selIdx=ourDrumMapSize-1;
+ currentlySelected = &ourDrumMap[selIdx];
+
+ redraw();
+}
diff --git a/muse2/muse/midiedit/dlist.h b/muse2/muse/midiedit/dlist.h
index 0fb1fd0b..1d87f3dc 100644
--- a/muse2/muse/midiedit/dlist.h
+++ b/muse2/muse/midiedit/dlist.h
@@ -35,11 +35,10 @@ class QHeaderView;
class QMouseEvent;
class QPainter;
-class ScrollScale;
class Device;
class QLineEdit;
class DrumMap;
-
+class DrumCanvas;
//---------------------------------------------------------
// DLineEdit
@@ -86,9 +85,13 @@ class DPitchEdit: public Awl::PitchEdit
class DList : public MusEWidget::View {
Q_OBJECT
-
+
+ DrumCanvas* dcanvas;
+ DrumMap* ourDrumMap;
+ int ourDrumMapSize;
+ bool old_style_drummap_mode;
+
QHeaderView* header;
- ScrollScale* scroll;
QLineEdit* editor;
DPitchEdit* pitch_editor;
DrumMap* editEntry;
@@ -98,7 +101,7 @@ class DList : public MusEWidget::View {
int startY;
int curY;
- int sPitch;
+ int sInstrument;
enum { NORMAL, START_DRAG, DRAG } drag;
virtual void draw(QPainter& p, const QRect&);
@@ -128,13 +131,14 @@ class DList : public MusEWidget::View {
public slots:
void tracklistChanged();
void songChanged(int);
+ void ourDrumMapChanged();
+
public:
void lineEdit(int line, int section);
void pitchEdit(int line, int section);
void setCurDrumInstrument(int n);
- DList(QHeaderView*, QWidget* parent, int ymag);
+ DList(QHeaderView*, QWidget* parent, int ymag, DrumCanvas* dcanvas, bool oldstyle);
~DList();
- void setScroll(ScrollScale* s) { scroll = s; }
int getSelectedInstrument();
enum DCols { COL_MUTE=0, COL_NAME, COL_VOL, COL_QNT, COL_ENOTE, COL_LEN,
diff --git a/muse2/muse/midiedit/drumedit.cpp b/muse2/muse/midiedit/drumedit.cpp
index 8821d0d8..92cc765a 100644
--- a/muse2/muse/midiedit/drumedit.cpp
+++ b/muse2/muse/midiedit/drumedit.cpp
@@ -177,6 +177,8 @@ DrumEdit::DrumEdit(PartList* pl, QWidget* parent, const char* name, unsigned ini
selPart = 0;
QSignalMapper *signalMapper = new QSignalMapper(this);
+ _group_mode = GROUP_SAME_CHANNEL;
+
//---------Pulldown Menu----------------------------
menuFile = menuBar()->addMenu(tr("&File"));
@@ -253,8 +255,14 @@ DrumEdit::DrumEdit(PartList* pl, QWidget* parent, const char* name, unsigned ini
menuFunctions->setTearOffEnabled(true);
- QAction* reorderListAction = menuFunctions->addAction(tr("Re-order list"));
- menuFunctions->addSeparator();
+ if (old_style_drummap_mode())
+ {
+ QAction* reorderListAction = menuFunctions->addAction(tr("Re-order list"));
+ connect(reorderListAction, SIGNAL(triggered()), signalMapper, SLOT(map()));
+ signalMapper->setMapping(reorderListAction, DrumCanvas::CMD_REORDER_LIST);
+ menuFunctions->addSeparator();
+ }
+
fixedAction = menuFunctions->addAction(tr("Set Fixed Length"));
veloAction = menuFunctions->addAction(tr("Modify Velocity"));
crescAction = menuFunctions->addAction(tr("Crescendo/Decrescendo"));
@@ -263,7 +271,6 @@ DrumEdit::DrumEdit(PartList* pl, QWidget* parent, const char* name, unsigned ini
QAction* noteShiftAction = menuFunctions->addAction(tr("Move Notes"));
QAction* delOverlapsAction = menuFunctions->addAction(tr("Delete Overlaps"));
- connect(reorderListAction, SIGNAL(triggered()), signalMapper, SLOT(map()));
connect(fixedAction, SIGNAL(triggered()), signalMapper, SLOT(map()));
connect(veloAction, SIGNAL(triggered()), signalMapper, SLOT(map()));
connect(crescAction, SIGNAL(triggered()), signalMapper, SLOT(map()));
@@ -272,7 +279,6 @@ DrumEdit::DrumEdit(PartList* pl, QWidget* parent, const char* name, unsigned ini
connect(noteShiftAction, SIGNAL(triggered()), signalMapper, SLOT(map()));
connect(delOverlapsAction, SIGNAL(triggered()), signalMapper, SLOT(map()));
- signalMapper->setMapping(reorderListAction, DrumCanvas::CMD_REORDER_LIST);
signalMapper->setMapping(fixedAction, DrumCanvas::CMD_FIXED_LEN);
signalMapper->setMapping(veloAction, DrumCanvas::CMD_MODIFY_VELOCITY);
signalMapper->setMapping(crescAction, DrumCanvas::CMD_CRESCENDO);
@@ -281,10 +287,40 @@ DrumEdit::DrumEdit(PartList* pl, QWidget* parent, const char* name, unsigned ini
signalMapper->setMapping(noteShiftAction, DrumCanvas::CMD_NOTE_SHIFT);
signalMapper->setMapping(delOverlapsAction, DrumCanvas::CMD_DELETE_OVERLAPS);
+
+
QMenu* menuScriptPlugins = menuBar()->addMenu(tr("&Plugins"));
song->populateScriptMenu(menuScriptPlugins, this);
QMenu* settingsMenu = menuBar()->addMenu(tr("Window &Config"));
+ if (!old_style_drummap_mode())
+ {
+ QMenu* menuGrouping=settingsMenu->addMenu(tr("Group"));
+ groupNoneAction = menuGrouping->addAction(tr("Don't group"));
+ groupChanAction = menuGrouping->addAction(tr("Group by channel"));
+ groupMaxAction = menuGrouping->addAction(tr("Group maximally"));
+ settingsMenu->addSeparator();
+
+ groupNoneAction->setCheckable(true);
+ groupChanAction->setCheckable(true);
+ groupMaxAction ->setCheckable(true);
+
+ connect(groupNoneAction, SIGNAL(triggered()), signalMapper, SLOT(map()));
+ connect(groupChanAction, SIGNAL(triggered()), signalMapper, SLOT(map()));
+ connect(groupMaxAction, SIGNAL(triggered()), signalMapper, SLOT(map()));
+
+ signalMapper->setMapping(groupNoneAction, DrumCanvas::CMD_GROUP_NONE);
+ signalMapper->setMapping(groupChanAction, DrumCanvas::CMD_GROUP_CHAN);
+ signalMapper->setMapping(groupMaxAction, DrumCanvas::CMD_GROUP_MAX);
+
+ updateGroupingActions();
+ }
+ else
+ {
+ groupNoneAction=NULL;
+ groupChanAction=NULL;
+ groupMaxAction =NULL;
+ }
settingsMenu->addAction(subwinAction);
settingsMenu->addAction(shareAction);
settingsMenu->addAction(fullscreenAction);
@@ -406,7 +442,7 @@ DrumEdit::DrumEdit(PartList* pl, QWidget* parent, const char* name, unsigned ini
gridS2->setSpacing(0);
time = new MusEWidget::MTScale(&_raster, split1w2, xscale);
canvas = new DrumCanvas(this, split1w2, xscale, yscale);
- vscroll = new MusEWidget::ScrollScale(-4, 1, yscale, DRUM_MAPSIZE*TH, Qt::Vertical, split1w2);
+ vscroll = new MusEWidget::ScrollScale(-4, 1, yscale, dynamic_cast<DrumCanvas*>(canvas)->getOurDrumMapSize()*TH, Qt::Vertical, split1w2);
int offset = -(MusEConfig::config.division/4);
canvas->setOrigin(offset, 0);
canvas->setCanvasTools(drumeditTools);
@@ -414,6 +450,7 @@ DrumEdit::DrumEdit(PartList* pl, QWidget* parent, const char* name, unsigned ini
connect(canvas, SIGNAL(toolChanged(int)), tools2, SLOT(set(int)));
connect(canvas, SIGNAL(horizontalZoomIn()), SLOT(horizontalZoomIn()));
connect(canvas, SIGNAL(horizontalZoomOut()), SLOT(horizontalZoomOut()));
+ connect(canvas, SIGNAL(ourDrumMapChanged()), SLOT(ourDrumMapChanged()));
time->setOrigin(offset, 0);
QList<int> mops;
@@ -454,7 +491,13 @@ DrumEdit::DrumEdit(PartList* pl, QWidget* parent, const char* name, unsigned ini
setHeaderToolTips();
setHeaderWhatsThis();
- dlist = new DList(header, split1w1, yscale);
+ if (!old_style_drummap_mode())
+ {
+ header->hideSection(COL_OUTPORT);
+ header->hideSection(COL_OUTCHANNEL);
+ }
+
+ dlist = new DList(header, split1w1, yscale, (DrumCanvas*)canvas, old_style_drummap_mode());
// p3.3.44
setCurDrumInstrument(dlist->getSelectedInstrument());
@@ -544,8 +587,12 @@ void DrumEdit::songChanged1(int bits)
toolbar->setSolo(canvas->track()->solo());
return;
}
+ if ( !old_style_drummap_mode() &&
+ ( bits & (SC_DRUMMAP | SC_TRACK_INSERTED | SC_TRACK_REMOVED | SC_TRACK_MODIFIED |
+ SC_PART_INSERTED | SC_PART_REMOVED | SC_PART_MODIFIED) ) )
+ ((DrumCanvas*)(canvas))->rebuildOurDrumMap();
+
songChanged(bits);
-
}
//---------------------------------------------------------
@@ -951,7 +998,11 @@ void DrumEdit::cmd(int cmd)
case DrumCanvas::CMD_REORDER_LIST: ((DrumCanvas*)(canvas))->moveAwayUnused(); break;
//case DrumCanvas::CMD_FIXED_LEN: // this must be handled by the drum canvas, due to its
// special nature (each drum has its own length)
-
+
+ case DrumCanvas::CMD_GROUP_NONE: _group_mode=DONT_GROUP; updateGroupingActions(); ((DrumCanvas*)(canvas))->rebuildOurDrumMap(); break;
+ case DrumCanvas::CMD_GROUP_CHAN: _group_mode=GROUP_SAME_CHANNEL; updateGroupingActions(); ((DrumCanvas*)(canvas))->rebuildOurDrumMap(); break;
+ case DrumCanvas::CMD_GROUP_MAX: _group_mode=GROUP_MAX; updateGroupingActions(); ((DrumCanvas*)(canvas))->rebuildOurDrumMap(); break;
+
default: ((DrumCanvas*)(canvas))->cmd(cmd);
}
}
@@ -1322,3 +1373,32 @@ void DrumEdit::setStep(QString v)
stepLenWidget->setFocusPolicy(Qt::NoFocus);
canvas->setFocus();
}
+
+bool DrumEdit::old_style_drummap_mode()
+{
+ for (ciPart p = parts()->begin(); p != parts()->end(); ++p)
+ if (p->second->track()->type()==Track::DRUM)
+ return true;
+
+ return false;
+}
+
+void DrumEdit::ourDrumMapChanged()
+{
+ int vmin,vmax;
+ vscroll->range(&vmin, &vmax);
+ vscroll->setRange(vmin, dynamic_cast<DrumCanvas*>(canvas)->getOurDrumMapSize()*TH);
+}
+
+void DrumEdit::updateGroupingActions()
+{
+ if (groupNoneAction==NULL || groupChanAction==NULL || groupMaxAction==NULL)
+ {
+ printf("THIS SHOULD NEVER HAPPEN: DrumEdit::updateGroupingActions() called, but one of the actions is NULL!\n");
+ return;
+ }
+
+ groupNoneAction->setChecked(_group_mode==DONT_GROUP);
+ groupChanAction->setChecked(_group_mode==GROUP_SAME_CHANNEL);
+ groupMaxAction ->setChecked(_group_mode==GROUP_MAX);
+}
diff --git a/muse2/muse/midiedit/drumedit.h b/muse2/muse/midiedit/drumedit.h
index 06f7e131..743d6151 100644
--- a/muse2/muse/midiedit/drumedit.h
+++ b/muse2/muse/midiedit/drumedit.h
@@ -67,7 +67,13 @@ class Toolbar1;
class DrumEdit : public MidiEditor {
Q_OBJECT
-
+
+ public:
+ enum group_mode_t { DONT_GROUP, GROUP_SAME_CHANNEL, GROUP_MAX };
+
+ private:
+ group_mode_t _group_mode;
+
Event selEvent;
MidiPart* selPart;
int selTick;
@@ -95,7 +101,7 @@ class DrumEdit : public MidiEditor {
QAction *fixedAction, *veloAction, *crescAction, *quantizeAction;
QAction *sallAction, *snoneAction, *invAction, *inAction , *outAction;
QAction *prevAction, *nextAction;
-
+ QAction *groupNoneAction, *groupChanAction, *groupMaxAction;
void initShortcuts();
@@ -123,6 +129,7 @@ class DrumEdit : public MidiEditor {
void configChanged();
void songChanged1(int);
void setStep(QString);
+ void updateGroupingActions();
public slots:
void setSelection(int, Event&, Part*);
@@ -130,8 +137,9 @@ class DrumEdit : public MidiEditor {
void execDeliveredScript(int);
void execUserScript(int);
CtrlEdit* addCtrl();
-
+ void ourDrumMapChanged();
virtual void updateHScrollRange();
+
signals:
void deleted(TopWin*);
@@ -142,6 +150,9 @@ class DrumEdit : public MidiEditor {
virtual void writeStatus(int, Xml&) const;
static void readConfiguration(Xml& xml);
static void writeConfiguration(int, Xml&);
+
+ bool old_style_drummap_mode();
+ group_mode_t group_mode() { return _group_mode; }
};
#endif
diff --git a/muse2/muse/midiedit/drummap.cpp b/muse2/muse/midiedit/drummap.cpp
index 032c2bd6..8f49afc0 100644
--- a/muse2/muse/midiedit/drummap.cpp
+++ b/muse2/muse/midiedit/drummap.cpp
@@ -26,6 +26,8 @@
#include "xml.h"
#include "song.h"
+global_drum_ordering_t global_drum_ordering;
+
char drumOutmap[DRUM_MAPSIZE];
char drumInmap[128];
diff --git a/muse2/muse/midiedit/drummap.h b/muse2/muse/midiedit/drummap.h
index 2c02ffcc..db512103 100644
--- a/muse2/muse/midiedit/drummap.h
+++ b/muse2/muse/midiedit/drummap.h
@@ -24,7 +24,8 @@
#ifndef __DRUMMAP_H__
#define __DRUMMAP_H__
-class QString;
+#include <QString>
+#include <QList>
class Xml;
@@ -44,8 +45,8 @@ struct DrumMap {
bool mute;
// bool selected;
- //bool const operator==(const DrumMap& map) const;
bool operator==(const DrumMap& map) const;
+ bool operator!=(const DrumMap& map) const { return !operator==(map); }
};
#define DRUM_MAPSIZE 128
@@ -53,10 +54,15 @@ struct DrumMap {
extern char drumOutmap[DRUM_MAPSIZE];
extern char drumInmap[DRUM_MAPSIZE];
extern DrumMap drumMap[DRUM_MAPSIZE];
+extern const DrumMap idrumMap[DRUM_MAPSIZE]; //FINDMICH dummy!
extern void initDrumMap();
extern void writeDrumMap(int level, Xml& xml, bool external);
extern void readDrumMap(Xml& xml, bool external);
extern void resetGMDrumMap();
+class MidiTrack;
+typedef QList< std::pair<MidiTrack*,int> > global_drum_ordering_t;
+
+extern global_drum_ordering_t global_drum_ordering;
#endif
diff --git a/muse2/muse/midiedit/prcanvas.cpp b/muse2/muse/midiedit/prcanvas.cpp
index b96cb47f..b9b4794f 100644
--- a/muse2/muse/midiedit/prcanvas.cpp
+++ b/muse2/muse/midiedit/prcanvas.cpp
@@ -110,6 +110,10 @@ PianoCanvas::PianoCanvas(MidiEditor* pr, QWidget* parent, int sx, int sy)
connect(song, SIGNAL(midiNote(int, int)), SLOT(midiNote(int,int)));
}
+PianoCanvas::~PianoCanvas()
+{
+ delete steprec;
+}
//---------------------------------------------------------
// pitch2y
//---------------------------------------------------------
diff --git a/muse2/muse/midiedit/prcanvas.h b/muse2/muse/midiedit/prcanvas.h
index a44a9a4a..b3a8a288 100644
--- a/muse2/muse/midiedit/prcanvas.h
+++ b/muse2/muse/midiedit/prcanvas.h
@@ -117,6 +117,7 @@ class PianoCanvas : public EventCanvas {
};
PianoCanvas(MidiEditor*, QWidget*, int, int);
+ virtual ~PianoCanvas();
void cmd(int cmd);
void setColorMode(int mode) {
colorMode = mode;
diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp
index b17f9b1d..64258f60 100644
--- a/muse2/muse/midiedit/scoreedit.cpp
+++ b/muse2/muse/midiedit/scoreedit.cpp
@@ -1257,6 +1257,11 @@ ScoreCanvas::ScoreCanvas(ScoreEdit* pr, QWidget* parent_widget) : View(parent_wi
unsetCursor();
}
+ScoreCanvas::~ScoreCanvas()
+{
+ delete steprec;
+}
+
void ScoreCanvas::staffmode_treble_slot()
{
set_staffmode(current_staff, MODE_TREBLE);
@@ -4581,15 +4586,35 @@ void ScoreCanvas::add_new_parts(const std::map< Part*, std::set<Part*> >& param)
* because after A (and B) got resized, the B-resize is invalid!
* o when changing toolbarstate when sharing and immediately after that
* changing "share" status, the changed state isn't stored
+ * o arranger state and mixer state aren't stored (says tim)
* ? pasting in editors sometimes fails oO? ( ERROR: reading eventlist
* from clipboard failed. ignoring this one... ) [ not reproducible ]
*
* CURRENT TODO
* ! o fix sigedit boxes (see also "important todo")
* o fix valgrind problems
+ *
* > o drum editor: channel-stuff
+ * o dialog for maintaining drum lists, hide etc
+ * o respect "_drummap_tied_to_patch": IMPLEMENT
+ * o save hide, ordering, track's drumlists
+ * o "copy drumlist" from one track to another
+ * o whenever changing the patch and maintained_automatically==true,
+ * the drumlist is replaced by the according one (for example, "jazz" drum kit's list)
+ * o whenever changing the drumlist and maintained_automatically==true,
+ * ask the user if he wants to proceed, and then set maintained_automatically to false
+ * o offer some way to set maintained_automatically to true again
+ * o move generation and deletion of ourDrumMap from DCanvas to DrumEditor and remove ugly wrapper functions
+ *
+ * o when playing back a flo-drum-track: treat as a MIDI track,
+ * EXCEPT that the drum list's mute entries are respected!
+ * o when recording or echoing a flo-drum-track: watch out for In-Notes!
+ * o update [midi]track::read/write, readproperties, writeprop... (drumlist etc), operator=
*
* IMPORTANT TODO
+ * o all places where i added doubleclick-edits: only react on left-click double clicks!
+ * o support "new style" reordering with old style drum tracks as well
+ * (not swapping but inserting!)
* ! o fix sigedit boxes (see also "current todo")
* o add "dotted quarter" quantize option (for 6/8 beat)
* o ticks-to-quarter spinboxes
diff --git a/muse2/muse/midiedit/scoreedit.h b/muse2/muse/midiedit/scoreedit.h
index 046fbf73..8f21e76b 100644
--- a/muse2/muse/midiedit/scoreedit.h
+++ b/muse2/muse/midiedit/scoreedit.h
@@ -811,7 +811,7 @@ class ScoreCanvas : public MusEWidget::View
public:
ScoreCanvas(ScoreEdit*, QWidget*);
- ~ScoreCanvas(){};
+ ~ScoreCanvas();
void add_staves(PartList* pl, bool all_in_one);
void push_back_staff(staff_t& staff) { staves.push_back(staff); } //FINDMICH dirty. very dirty.
diff --git a/muse2/muse/track.cpp b/muse2/muse/track.cpp
index 18578d88..90e9beec 100644
--- a/muse2/muse/track.cpp
+++ b/muse2/muse/track.cpp
@@ -32,6 +32,7 @@
#include "audio.h"
#include "globaldefs.h"
#include "route.h"
+#include "drummap.h"
bool MidiTrack::_isVisible=true;
//bool Track::_isVisible=true;
@@ -392,6 +393,23 @@ MidiTrack::MidiTrack()
_events = new EventList;
_mpevents = new MPEventList;
clefType=trebleClef;
+
+ _drummap=new DrumMap[128];
+ _drummap_hidden=new bool[128];
+
+ for (int i=0;i<128;i++)
+ {
+ int idx=idrumMap[i].anote;
+ if (idx < 0 || idx >= 128)
+ printf ("ERROR: THIS SHOULD NEVER HAPPEN: idrumMap[%i].anote is not within 0..127!\n", idx);
+ else
+ _drummap[idx]=idrumMap[i];
+
+ global_drum_ordering.push_back(std::pair<MidiTrack*,int>(this,idx));
+ }
+ for (int i=0;i<128;i++)
+ _drummap_hidden[i]=false;
+
}
//MidiTrack::MidiTrack(const MidiTrack& mt)
@@ -412,12 +430,36 @@ MidiTrack::MidiTrack(const MidiTrack& mt, bool cloneParts)
compression = mt.compression;
_recEcho = mt.recEcho();
clefType=trebleClef;
+
+ _drummap=new DrumMap[128];
+ _drummap_hidden=new bool[128];
+ memcpy(_drummap, mt._drummap, 128*sizeof(*_drummap));
+ memcpy(_drummap_hidden, mt._drummap_hidden, 128*sizeof(*_drummap_hidden));
+
+ for (global_drum_ordering_t::iterator it=global_drum_ordering.begin(); it!=global_drum_ordering.end(); it++)
+ if (it->first == &mt)
+ {
+ it=global_drum_ordering.insert(it, *it); // duplicates the entry at it, set it to the first entry of both
+ it++; // make it point to the second entry
+ it->first=this;
+ }
}
MidiTrack::~MidiTrack()
{
delete _events;
delete _mpevents;
+ delete [] _drummap;
+ delete [] _drummap_hidden;
+
+ // remove ourselves from the global_drum_ordering list
+ // this is not really necessary, but cleaner
+ for (global_drum_ordering_t::iterator it=global_drum_ordering.begin(); it!=global_drum_ordering.end();)
+ if (it->first == this)
+ it=global_drum_ordering.erase(it);
+ else
+ it++;
+
}
//---------------------------------------------------------
diff --git a/muse2/muse/track.h b/muse2/muse/track.h
index f0f8ebde..752a79be 100644
--- a/muse2/muse/track.h
+++ b/muse2/muse/track.h
@@ -43,6 +43,7 @@ class SndFile;
class MPEventList;
class SynthI;
class PluginI;
+class DrumMap;
//---------------------------------------------------------
// Track
@@ -202,7 +203,7 @@ class Track {
virtual bool canRecord() const { return false; }
virtual AutomationType automationType() const = 0;
virtual void setAutomationType(AutomationType t) = 0;
- static void setVisible(bool ) { }
+ static void setVisible(bool) { }
};
@@ -225,6 +226,12 @@ class MidiTrack : public Track {
MPEventList* _mpevents; // tmp Events druring recording
static bool _isVisible;
clefTypes clefType;
+
+ DrumMap* _drummap;
+ bool _drummap_tied_to_patch; //if true, changing patch also changes drummap
+ bool* _drummap_hidden;
+
+ void init();
public:
MidiTrack();
@@ -232,7 +239,6 @@ class MidiTrack : public Track {
MidiTrack(const MidiTrack&, bool cloneParts);
virtual ~MidiTrack();
- void init();
virtual AutomationType automationType() const;
virtual void setAutomationType(AutomationType);
@@ -293,6 +299,9 @@ class MidiTrack : public Track {
void setClef(clefTypes i) { clefType = i; }
clefTypes getClef() { return clefType; }
+
+ DrumMap* drummap() { return _drummap; }
+ bool* drummap_hidden() { return _drummap_hidden; }
};
//---------------------------------------------------------
diff --git a/muse2/muse/undo.cpp b/muse2/muse/undo.cpp
index c0191362..63911fcf 100644
--- a/muse2/muse/undo.cpp
+++ b/muse2/muse/undo.cpp
@@ -775,6 +775,7 @@ void Song::doRedo2()
UndoOp::UndoOp()
{
+ type=UndoOp::DoNothing;
}
UndoOp::UndoOp(UndoType type_)
@@ -1073,3 +1074,14 @@ void Song::doRedo3()
dirty = true;
}
+
+bool Undo::empty() const
+{
+ if (std::list<UndoOp>::empty()) return true;
+
+ for (const_iterator it=begin(); it!=end(); it++)
+ if (it->type!=UndoOp::DoNothing)
+ return false;
+
+ return true;
+}
diff --git a/muse2/muse/undo.h b/muse2/muse/undo.h
index 5dca82b6..f2a523cc 100644
--- a/muse2/muse/undo.h
+++ b/muse2/muse/undo.h
@@ -119,7 +119,8 @@ struct UndoOp {
};
class Undo : public std::list<UndoOp> {
- void undoOp(UndoOp::UndoType, int data);
+ public:
+ bool empty() const;
};
typedef Undo::iterator iUndoOp;