From 56417f8e86e19d459a86f31a41a494f4a9e813a1 Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Wed, 28 Sep 2011 15:34:53 +0000 Subject: first changes for "new-style-drumtracks" almost certainly buggy, incomplete etc. --- muse2/muse/midiedit/dcanvas.cpp | 316 ++++++++++++++++++++++++++++++-------- muse2/muse/midiedit/dcanvas.h | 40 ++++- muse2/muse/midiedit/drumedit.cpp | 11 +- muse2/muse/midiedit/drumedit.h | 2 + muse2/muse/midiedit/drummap.h | 1 + muse2/muse/midiedit/scoreedit.cpp | 21 +++ 6 files changed, 324 insertions(+), 67 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp index 3f80133a..172dd069 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" @@ -54,14 +54,15 @@ #define CARET 10 #define CARET2 5 +using MusEGlobal::debugMsg; + //--------------------------------------------------------- // 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 +80,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 (debugMsg) 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 +109,92 @@ DrumCanvas::DrumCanvas(MidiEditor* pr, QWidget* parent, int sx, int sy, const char* name) : EventCanvas(pr, parent, sx, sy, name) { + old_style_drummap_mode = dynamic_cast<DrumEdit*>(pr)->old_style_drummap_mode(); //FINDMICH TODO + + 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=pr->parts()->begin(); it!=pr->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"); + // FINDMICHJETZT + TrackList* tl=song->tracks(); + + QList< QSet<Track*> > track_groups; + + for (ciTrack track = tl->begin(); track!=tl->end(); track++) + { + ciPart p_it; + for (p_it=pr->parts()->begin(); p_it!=pr->parts()->end(); p_it++) + if (p_it->second->track() == *track) + break; + + if (p_it!=pr->parts()->end()) // if *track is represented by some part in this editor + { + 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. + + for (QList< QSet<Track*> >::iterator group=track_groups.begin(); group!=track_groups.end(); group++) + { + /* FINDMICH activate me when Track::drummap() works! + for (int i=0;i<128;i++) // make "mute" consistent across groups + { + bool mute=true; + for (QSet<Track*>::iterator track=group->begin(); track!=group->end(); track++) + { + if (track->drummap()[i].mute == false) + { + mute=false; + break; + } + } + + for (QSet<Track*>::iterator track=group->begin(); track!=group->end(); track++) + track->drummap()[i].mute=mute; + } */ + + bool hidden[128]; + for (int i=0;i<128;i++) hidden[i]=false; //FINDMICH later: respect the track's hidden-lists! + + for (int i=0;i<128;i++) + if (!hidden[i]) + instrument_map.append(instrument_number_mapping_t(*group, i)); + } + + + + // populate 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] = instrument_map[i].tracks.begin()->drummap()[instrument_map[i].pitch]; FINDMICH activate me when Track::drummap works + ourDrumMap[i] = idrumMap[instrument_map[i].pitch]; //FINDMICH dummy! + } + + + setVirt(false); cursorPos= QPoint(0,0); _stepSize=1; @@ -188,7 +282,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(); @@ -206,11 +300,11 @@ Undo DrumCanvas::moveCanvasItems(MusEWidget::CItemList& items, int dp, int dx, D // Do not process if the event has already been processed (meaning it's an event in a clone part)... if (idl == doneList.end()) { - operations.push_back(moveItem(ci, newpos, dtype)); + operations.push_back(moveItem(ci, newpos, dtype)); //FINDMICH update moveItem() doneList.push_back(ci); } ci->move(newpos); - + if(moving.size() == 1) itemReleased(curItem, newpos); @@ -238,7 +332,7 @@ Undo DrumCanvas::moveCanvasItems(MusEWidget::CItemList& items, int dp, int dx, D // moveItem //--------------------------------------------------------- -UndoOp DrumCanvas::moveItem(MusEWidget::CItem* item, const QPoint& pos, DragType dtype) +UndoOp DrumCanvas::moveItem(MusEWidget::CItem* item, const QPoint& pos, DragType dtype) //FINDMICHJETZT { DEvent* nevent = (DEvent*) item; @@ -251,10 +345,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 @@ -275,13 +379,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); } @@ -292,13 +396,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); + } } //--------------------------------------------------------- @@ -321,15 +434,17 @@ 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(); if (!noSnap) x = editor->rasterVal(x); event.setTick(x - nevent->part()->tick()); - int npitch = event.pitch(); - event.setPitch(npitch); + int npitch = event.pitch(); //FINDMICH + //event.setPitch(npitch); // commented out by flo: has no effect // // check for existing event @@ -365,7 +480,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"); @@ -375,7 +490,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 @@ -430,7 +548,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); @@ -521,8 +639,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; } @@ -631,7 +749,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(ourDrumMap[event.pitch()].len); + newEvent.setLenTick(ourDrumMap[y2pitch(devent->y())].len); //FINDMICH // Indicate no undo, and do not do port controller values and clone parts. audio->msgChangeEvent(event, newEvent, devent->part(), false, false, false); } @@ -733,19 +852,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); } @@ -753,12 +872,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); @@ -767,10 +886,13 @@ void DrumCanvas::keyReleased(int index, bool) //--------------------------------------------------------- // mapChanged +// this function is only for old-style-drummaps //--------------------------------------------------------- void DrumCanvas::mapChanged(int spitch, int dpitch) { + if (!old_style_drummap_mode) return; + Undo operations; std::vector< std::pair<Part*, Event*> > delete_events; std::vector< std::pair<Part*, Event> > add_events; @@ -900,6 +1022,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) @@ -908,6 +1031,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); @@ -985,8 +1110,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()); @@ -995,8 +1120,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()); @@ -1005,8 +1130,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()); @@ -1015,8 +1140,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()); @@ -1064,17 +1189,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; } //--------------------------------------------------------- @@ -1098,9 +1225,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"); //FINDMICH really disable that + return; + } - set<int> used; + QSet<int> used; for (MusEWidget::iCItem it=items.begin(); it!=items.end(); it++) { const Event& ev=it->second->event(); @@ -1110,7 +1241,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++; @@ -1127,14 +1258,71 @@ 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); } } + + +/* FINDMICH OBSOLETE +int DrumCanvas::tracks_first_instrument(Track* t) +{ + if (instrument_number_map.find(t) == instrument_number_map.end()) + { + printf("THIS SHOULD NEVER HAPPEN: DrumCanvas::tracks_first_instrument() called with unknown track!\n"); + return 0; + } + else + return instrument_number_map[t]; +} + +int DrumCanvas::parts_first_instrument(Part* p) +{ + return tracks_first_instrument(p->track()); +} + +QSet<Track*> DrumCanvas::tracks_of_instrument(int instr) +{ + QSet<Track*> result; + int first_instr = -1; + + for (std::map<Track*, int>::iterator it=instrument_number_map.begin(); it!=instrument_number_map.end(); it++) + { + if ((it->second <= instr) && (it->second > first_instr)) + { + first_instr = it->second; + result.clear(); + result.insert(it->first); + } + else if (it->second == first_instr) + { + result.insert(it->first); + } + } + + return result; +} + +bool DrumCanvas::is_track_of_instrument(Track* t, int instr) +{ + QSet<Track*> temp = tracks_of_instrument(instr); + return (temp.find(t) != temp.end()); +} +*/ + +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; +} diff --git a/muse2/muse/midiedit/dcanvas.h b/muse2/muse/midiedit/dcanvas.h index c25f71ca..7c574821 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,6 +39,7 @@ class QDropEvent; class QDragMoveEvent; class QDragLeaveEvent; +class DrumMap; class MidiEditor; //--------------------------------------------------------- @@ -45,12 +49,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 +81,11 @@ 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; + StepRec* steprec; // Cursor tool position @@ -88,6 +116,13 @@ class DrumCanvas : public EventCanvas { virtual void resizeEvent(QResizeEvent*); virtual void curPartChanged(); int getNextStep(unsigned int pos, int basicStep, int stepSize=1); + + /* FINDMICH OBSOLETE + int parts_first_instrument(Part* p); + int tracks_first_instrument(Track* t); + bool is_track_of_instrument(Track* t, int instr); + QSet<Track*> tracks_of_instrument(int instr); + */ signals: void newWidth(int); @@ -119,7 +154,8 @@ class DrumCanvas : public EventCanvas { virtual void keyPress(QKeyEvent* event); Event *getEventAtCursorPos(); void selectCursorEvent(Event *ev); - + int drum_map_size() { return instrument_map.size(); } + int pitch_and_track_to_instrument(int pitch, Track* track); }; #endif diff --git a/muse2/muse/midiedit/drumedit.cpp b/muse2/muse/midiedit/drumedit.cpp index 8821d0d8..4e99c0c1 100644 --- a/muse2/muse/midiedit/drumedit.cpp +++ b/muse2/muse/midiedit/drumedit.cpp @@ -406,7 +406,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)->drum_map_size()*TH, Qt::Vertical, split1w2); int offset = -(MusEConfig::config.division/4); canvas->setOrigin(offset, 0); canvas->setCanvasTools(drumeditTools); @@ -1322,3 +1322,12 @@ 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; +} diff --git a/muse2/muse/midiedit/drumedit.h b/muse2/muse/midiedit/drumedit.h index 06f7e131..87226365 100644 --- a/muse2/muse/midiedit/drumedit.h +++ b/muse2/muse/midiedit/drumedit.h @@ -142,6 +142,8 @@ 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(); }; #endif diff --git a/muse2/muse/midiedit/drummap.h b/muse2/muse/midiedit/drummap.h index 2c02ffcc..e4764b21 100644 --- a/muse2/muse/midiedit/drummap.h +++ b/muse2/muse/midiedit/drummap.h @@ -53,6 +53,7 @@ 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); diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index b17f9b1d..fe3e5696 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -4587,7 +4587,28 @@ void ScoreCanvas::add_new_parts(const std::map< Part*, std::set<Part*> >& param) * CURRENT TODO * ! o fix sigedit boxes (see also "important todo") * o fix valgrind problems + * * > o drum editor: channel-stuff + * o stuff is inserted into the right part, but displayed in the wrong part + * + * o each track has its own drumlist and a bool maintained_automatically + * 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 each track has a bool hidden[128], which is used for hiding entries. + * when mixing, the values of all tracks are ANDed + * + * o drum editor can: "display each track separately", "mix all with same port, patch and drumlist" + * x a map maps all y-coord.s to { set<Track*>, pitch } + * o either open flo-tracks OR old-style-tracks + * o replace all DRUM_MAPSIZE by instrument_map.size() + * o signal for instrument_map.size or drum_map_size() changed! + * o ... + * + * o when playing back a flo-drum-track: treat as a MIDI track, + * EXCEPT that the drum list's mute entries are respected! * * IMPORTANT TODO * ! o fix sigedit boxes (see also "current todo") -- cgit v1.2.3 From 53a46fee00aa9256144c8cb71bc8e71444f339a8 Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Wed, 28 Sep 2011 15:56:24 +0000 Subject: Undo::empty() also returns empty if the list only contains DoNothings removed unused, unimplemented function --- muse2/muse/undo.cpp | 12 ++++++++++++ muse2/muse/undo.h | 3 ++- 2 files changed, 14 insertions(+), 1 deletion(-) (limited to 'muse2') 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; -- cgit v1.2.3 From bd41d7c53d2b7590263a7d126b02736268932c8f Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Thu, 29 Sep 2011 16:11:59 +0000 Subject: removed "reorder list" function when in new-style-mode really tiny cleanups --- muse2/muse/midiedit/dcanvas.cpp | 13 +++++++------ muse2/muse/midiedit/drumedit.cpp | 12 ++++++++---- muse2/muse/midiedit/scoreedit.cpp | 3 +-- 3 files changed, 16 insertions(+), 12 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp index 172dd069..8aecc525 100644 --- a/muse2/muse/midiedit/dcanvas.cpp +++ b/muse2/muse/midiedit/dcanvas.cpp @@ -55,6 +55,7 @@ #define CARET2 5 using MusEGlobal::debugMsg; +using MusEGlobal::heavyDebugMsg; //--------------------------------------------------------- // DEvent @@ -83,7 +84,7 @@ void DrumCanvas::addItem(Part* part, Event& event) int instr=pitch_and_track_to_instrument(event.pitch(), part->track()); if (instr<0) { - if (debugMsg) printf("trying to add event which is hidden or not in any part known to me\n"); + if (heavyDebugMsg) printf("trying to add event which is hidden or not in any part known to me\n"); return; } @@ -109,7 +110,7 @@ DrumCanvas::DrumCanvas(MidiEditor* pr, QWidget* parent, int sx, int sy, const char* name) : EventCanvas(pr, parent, sx, sy, name) { - old_style_drummap_mode = dynamic_cast<DrumEdit*>(pr)->old_style_drummap_mode(); //FINDMICH TODO + old_style_drummap_mode = dynamic_cast<DrumEdit*>(pr)->old_style_drummap_mode(); if (old_style_drummap_mode) { @@ -300,7 +301,7 @@ Undo DrumCanvas::moveCanvasItems(MusEWidget::CItemList& items, int dp, int dx, D // Do not process if the event has already been processed (meaning it's an event in a clone part)... if (idl == doneList.end()) { - operations.push_back(moveItem(ci, newpos, dtype)); //FINDMICH update moveItem() + operations.push_back(moveItem(ci, newpos, dtype)); doneList.push_back(ci); } ci->move(newpos); @@ -332,7 +333,7 @@ Undo DrumCanvas::moveCanvasItems(MusEWidget::CItemList& items, int dp, int dx, D // moveItem //--------------------------------------------------------- -UndoOp DrumCanvas::moveItem(MusEWidget::CItem* item, const QPoint& pos, DragType dtype) //FINDMICHJETZT +UndoOp DrumCanvas::moveItem(MusEWidget::CItem* item, const QPoint& pos, DragType dtype) { DEvent* nevent = (DEvent*) item; @@ -749,7 +750,7 @@ void DrumCanvas::cmd(int cmd) DEvent* devent = (DEvent*)(k->second); Event event = devent->event(); Event newEvent = event.clone(); - // newEvent.setLenTick(ourDrumMap[event.pitch()].len); + // newEvent.setLenTick(drumMap[event.pitch()].len); newEvent.setLenTick(ourDrumMap[y2pitch(devent->y())].len); //FINDMICH // Indicate no undo, and do not do port controller values and clone parts. audio->msgChangeEvent(event, newEvent, devent->part(), false, false, false); @@ -1227,7 +1228,7 @@ void DrumCanvas::moveAwayUnused() { if (!old_style_drummap_mode) { - printf("THIS SHOULD NEVER HAPPEN: DrumCanvas::moveAwayUnused() cannot be used in new style mode\n"); //FINDMICH really disable that + printf("THIS SHOULD NEVER HAPPEN: DrumCanvas::moveAwayUnused() cannot be used in new style mode\n"); return; } diff --git a/muse2/muse/midiedit/drumedit.cpp b/muse2/muse/midiedit/drumedit.cpp index 4e99c0c1..230eef04 100644 --- a/muse2/muse/midiedit/drumedit.cpp +++ b/muse2/muse/midiedit/drumedit.cpp @@ -253,8 +253,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 +269,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 +277,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); diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index fe3e5696..c9f5454d 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -4581,6 +4581,7 @@ 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 ] * @@ -4589,8 +4590,6 @@ void ScoreCanvas::add_new_parts(const std::map< Part*, std::set<Part*> >& param) * o fix valgrind problems * * > o drum editor: channel-stuff - * o stuff is inserted into the right part, but displayed in the wrong part - * * o each track has its own drumlist and a bool maintained_automatically * o whenever changing the patch and maintained_automatically==true, * the drumlist is replaced by the according one (for example, "jazz" drum kit's list) -- cgit v1.2.3 From 790900244f2eca7370ebdc7d40426ff5f7178416 Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Thu, 29 Sep 2011 17:38:25 +0000 Subject: drum list supports new style mode added ability to reorder in new style mode (properly) still work-in-progress --- muse2/muse/midiedit/dcanvas.cpp | 25 +++++-- muse2/muse/midiedit/dcanvas.h | 2 + muse2/muse/midiedit/dlist.cpp | 150 +++++++++++++++++++++----------------- muse2/muse/midiedit/dlist.h | 12 ++- muse2/muse/midiedit/drumedit.cpp | 8 +- muse2/muse/midiedit/scoreedit.cpp | 1 + 6 files changed, 122 insertions(+), 76 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp index 8aecc525..0b39c409 100644 --- a/muse2/muse/midiedit/dcanvas.cpp +++ b/muse2/muse/midiedit/dcanvas.cpp @@ -191,7 +191,7 @@ DrumCanvas::DrumCanvas(MidiEditor* pr, QWidget* parent, int sx, for (int i=0;i<size;i++) //ourDrumMap[i] = instrument_map[i].tracks.begin()->drummap()[instrument_map[i].pitch]; FINDMICH activate me when Track::drummap works - ourDrumMap[i] = idrumMap[instrument_map[i].pitch]; //FINDMICH dummy! + ourDrumMap[i] = idrumMap[instrument_map[i%128].pitch]; //FINDMICH dummy! } @@ -887,13 +887,12 @@ void DrumCanvas::keyReleased(int index, bool) //FINDMICH later //--------------------------------------------------------- // mapChanged -// this function is only for old-style-drummaps //--------------------------------------------------------- void DrumCanvas::mapChanged(int spitch, int dpitch) - { - if (!old_style_drummap_mode) return; - +{ + if (old_style_drummap_mode) + { Undo operations; std::vector< std::pair<Part*, Event*> > delete_events; std::vector< std::pair<Part*, Event> > add_events; @@ -971,7 +970,20 @@ 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) + { + DrumMap dm = ourDrumMap[spitch]; + ourDrumMap[spitch] = ourDrumMap[dpitch]; + ourDrumMap[dpitch] = dm; + + instrument_number_mapping_t im = instrument_map[spitch]; + instrument_map[spitch] = instrument_map[dpitch]; + instrument_map[dpitch] = im; + + song->update(SC_DRUMMAP); //FINDMICHJETZT handle that properly! + } +} //--------------------------------------------------------- // resizeEvent @@ -1327,3 +1339,4 @@ int DrumCanvas::pitch_and_track_to_instrument(int pitch, Track* track) printf("ERROR: DrumCanvas::pitch_and_track_to_instrument() called with invalid arguments!\n"); return -1; } + diff --git a/muse2/muse/midiedit/dcanvas.h b/muse2/muse/midiedit/dcanvas.h index 7c574821..c02c5442 100644 --- a/muse2/muse/midiedit/dcanvas.h +++ b/muse2/muse/midiedit/dcanvas.h @@ -156,6 +156,8 @@ class DrumCanvas : public EventCanvas { void selectCursorEvent(Event *ev); int drum_map_size() { return instrument_map.size(); } int pitch_and_track_to_instrument(int pitch, Track* track); + DrumMap* getOurDrumMap() { return ourDrumMap; } //FINDMICH UGLY + int getOurDrumMapSize() { return instrument_map.size(); } //FINDMICH UGLY }; #endif diff --git a/muse2/muse/midiedit/dlist.cpp b/muse2/muse/midiedit/dlist.cpp index 8e9633c0..6cd469ae 100644 --- a/muse2/muse/midiedit/dlist.cpp +++ b/muse2/muse/midiedit/dlist.cpp @@ -38,6 +38,7 @@ #include "dlist.h" #include "song.h" #include "scrollscale.h" +#include "dcanvas.h" //--------------------------------------------------------- // draw @@ -56,13 +57,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 @@ -199,8 +200,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,16 +228,16 @@ 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]; - setCurDrumInstrument(pitch); + setCurDrumInstrument(instrument); startY = y; - sPitch = pitch; + sInstrument = instrument; drag = START_DRAG; - DCols col = DCols(x2col(x)); + DCols col = DCols(x2col(x)); //FINDMICH update int val; int incVal = 0; @@ -262,17 +263,17 @@ 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) + else if (val > 200) //FINDMICH: why 200? why not 999 or infinity? (flo93) val = 200; dm->vol = (unsigned char)val; break; @@ -286,18 +287,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) //FINDMICH auch beim doppelklick! + { + //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 +311,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 FINDMICH auch beim doppelklick { val = dm->anote + incVal; if (val < 0) @@ -315,16 +321,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 +345,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 +357,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,7 +397,7 @@ 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: @@ -405,18 +414,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 +437,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 +505,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,13 +559,13 @@ 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); + song->update(SC_DRUMMAP); //FINDMICH necessary?? } } @@ -578,7 +587,6 @@ void DList::returnPressed() int val = -1; if (selectedColumn != COL_NAME) { - ///val = atoi(editor->text().ascii()); val = atoi(editor->text().toAscii().constData()); switch (selectedColumn) @@ -618,7 +626,6 @@ void DList::returnPressed() break; case COL_LEN: - ///editEntry->len = atoi(editor->text().ascii()); editEntry->len = atoi(editor->text().toAscii().constData()); break; @@ -668,36 +675,44 @@ void DList::returnPressed() void DList::pitchEdited() { int val=pitch_editor->value(); - int pitch=(editEntry-drumMap); + int instrument=(editEntry-ourDrumMap); 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; } selectedColumn = -1; @@ -739,10 +754,15 @@ 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); + + ourDrumMap=dcanvas->getOurDrumMap(); + ourDrumMapSize=dcanvas->getOurDrumMapSize(); + old_style_drummap_mode=oldstyle; + if (!h){ h = new QHeaderView(Qt::Horizontal, parent);} header = h; @@ -757,7 +777,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 +823,11 @@ void DList::viewMouseReleaseEvent(QMouseEvent* ev) { if (drag == DRAG) { int y = ev->y(); - unsigned dPitch = y / TH; + unsigned dInstrument = y / TH; setCursor(QCursor(Qt::ArrowCursor)); - currentlySelected = &drumMap[int(dPitch)]; - emit curDrumInstrumentChanged(dPitch); - emit mapChanged(sPitch, dPitch); //Track pitch change done in canvas + currentlySelected = &ourDrumMap[int(dInstrument)]; + emit curDrumInstrumentChanged(dInstrument); + emit mapChanged(sInstrument, dInstrument); //Track instrument change done in canvas } drag = NORMAL; //?? redraw(); //commented out NOT by flo93; was already commented out @@ -816,16 +836,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; diff --git a/muse2/muse/midiedit/dlist.h b/muse2/muse/midiedit/dlist.h index 0fb1fd0b..8e141c3b 100644 --- a/muse2/muse/midiedit/dlist.h +++ b/muse2/muse/midiedit/dlist.h @@ -39,7 +39,7 @@ class ScrollScale; class Device; class QLineEdit; class DrumMap; - +class DrumCanvas; //--------------------------------------------------------- // DLineEdit @@ -86,7 +86,11 @@ class DPitchEdit: public Awl::PitchEdit class DList : public MusEWidget::View { Q_OBJECT - + + DrumMap* ourDrumMap; //FINDMICHJETZT init! + int ourDrumMapSize; + bool old_style_drummap_mode; + QHeaderView* header; ScrollScale* scroll; QLineEdit* editor; @@ -98,7 +102,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&); @@ -132,7 +136,7 @@ class DList : public MusEWidget::View { 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(); diff --git a/muse2/muse/midiedit/drumedit.cpp b/muse2/muse/midiedit/drumedit.cpp index 230eef04..f21b0e8c 100644 --- a/muse2/muse/midiedit/drumedit.cpp +++ b/muse2/muse/midiedit/drumedit.cpp @@ -458,7 +458,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()); diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index c9f5454d..844c1311 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -4604,6 +4604,7 @@ void ScoreCanvas::add_new_parts(const std::map< Part*, std::set<Part*> >& param) * o either open flo-tracks OR old-style-tracks * o replace all DRUM_MAPSIZE by instrument_map.size() * o signal for instrument_map.size or drum_map_size() changed! + * o move generation and deletion of ourDrumMap from DCanvas to DrumEditor and remove ugly wrapper functions * o ... * * o when playing back a flo-drum-track: treat as a MIDI track, -- cgit v1.2.3 From 0d93b9b7a99847b19b7f0863a694e5441727419e Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Fri, 30 Sep 2011 16:34:40 +0000 Subject: added dedicated drummap to tracks (only relevant for new-style-drumtracks) propagating ourDrumMap changes to track's drummaps changed volume percent limit from 200 to 999 cleaned up a bit --- muse2/muse/midiedit/dcanvas.cpp | 94 ++++++++++++--------------------------- muse2/muse/midiedit/dcanvas.h | 8 +++- muse2/muse/midiedit/dlist.cpp | 45 ++++++++++++++++--- muse2/muse/midiedit/dlist.h | 3 +- muse2/muse/midiedit/drumedit.cpp | 2 +- muse2/muse/midiedit/drummap.h | 2 +- muse2/muse/midiedit/scoreedit.cpp | 12 ++++- muse2/muse/track.cpp | 17 +++++++ muse2/muse/track.h | 11 ++++- 9 files changed, 113 insertions(+), 81 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp index 0b39c409..26e7aed4 100644 --- a/muse2/muse/midiedit/dcanvas.cpp +++ b/muse2/muse/midiedit/dcanvas.cpp @@ -125,6 +125,7 @@ DrumCanvas::DrumCanvas(MidiEditor* pr, QWidget* parent, int sx, for (int i=0;i<DRUM_MAPSIZE;i++) { temp.pitch=i; + temp.track_dlist_index=i; // actually unneeded, but who knows... instrument_map.append(temp); } } @@ -156,29 +157,27 @@ DrumCanvas::DrumCanvas(MidiEditor* pr, QWidget* parent, int sx, for (QList< QSet<Track*> >::iterator group=track_groups.begin(); group!=track_groups.end(); group++) { - /* FINDMICH activate me when Track::drummap() works! - for (int i=0;i<128;i++) // make "mute" consistent across groups - { + for (int i=0;i<128;i++) // find out if instrument is hidden and make "mute" + { // consistent across groups for non-hidden instruments bool mute=true; - for (QSet<Track*>::iterator track=group->begin(); track!=group->end(); track++) + bool hidden=true; + for (QSet<Track*>::iterator track=group->begin(); track!=group->end() && (mute || hidden); track++) { - if (track->drummap()[i].mute == false) - { + if (dynamic_cast<MidiTrack*>(*track)->drummap()[i].mute == false) mute=false; - break; - } + + if (dynamic_cast<MidiTrack*>(*track)->drummap_hidden()[i] == false) + hidden=false; } - for (QSet<Track*>::iterator track=group->begin(); track!=group->end(); track++) - track->drummap()[i].mute=mute; - } */ - - bool hidden[128]; - for (int i=0;i<128;i++) hidden[i]=false; //FINDMICH later: respect the track's hidden-lists! - - for (int i=0;i<128;i++) - if (!hidden[i]) - instrument_map.append(instrument_number_mapping_t(*group, i)); + if (!hidden) + { + for (QSet<Track*>::iterator track=group->begin(); track!=group->end(); track++) + dynamic_cast<MidiTrack*>(*track)->drummap()[i].mute=mute; + + instrument_map.append(instrument_number_mapping_t(*group, dynamic_cast<MidiTrack*>(*group->begin())->drummap()[i].anote, i)); + } + } } @@ -190,8 +189,8 @@ DrumCanvas::DrumCanvas(MidiEditor* pr, QWidget* parent, int sx, must_delete_our_drum_map=true; for (int i=0;i<size;i++) - //ourDrumMap[i] = instrument_map[i].tracks.begin()->drummap()[instrument_map[i].pitch]; FINDMICH activate me when Track::drummap works - ourDrumMap[i] = idrumMap[instrument_map[i%128].pitch]; //FINDMICH dummy! + ourDrumMap[i] = dynamic_cast<MidiTrack*>(*instrument_map[i].tracks.begin())->drummap()[instrument_map[i].track_dlist_index]; + //ourDrumMap[i] = idrumMap[instrument_map[i%128].pitch]; //FINDMICH dummy! } @@ -1284,52 +1283,6 @@ void DrumCanvas::midiNote(int pitch, int velo) //FINDMICH later. } -/* FINDMICH OBSOLETE -int DrumCanvas::tracks_first_instrument(Track* t) -{ - if (instrument_number_map.find(t) == instrument_number_map.end()) - { - printf("THIS SHOULD NEVER HAPPEN: DrumCanvas::tracks_first_instrument() called with unknown track!\n"); - return 0; - } - else - return instrument_number_map[t]; -} - -int DrumCanvas::parts_first_instrument(Part* p) -{ - return tracks_first_instrument(p->track()); -} - -QSet<Track*> DrumCanvas::tracks_of_instrument(int instr) -{ - QSet<Track*> result; - int first_instr = -1; - - for (std::map<Track*, int>::iterator it=instrument_number_map.begin(); it!=instrument_number_map.end(); it++) - { - if ((it->second <= instr) && (it->second > first_instr)) - { - first_instr = it->second; - result.clear(); - result.insert(it->first); - } - else if (it->second == first_instr) - { - result.insert(it->first); - } - } - - return result; -} - -bool DrumCanvas::is_track_of_instrument(Track* t, int instr) -{ - QSet<Track*> temp = tracks_of_instrument(instr); - return (temp.find(t) != temp.end()); -} -*/ - int DrumCanvas::pitch_and_track_to_instrument(int pitch, Track* track) { for (int i=0; i<instrument_map.size(); i++) @@ -1340,3 +1293,12 @@ int DrumCanvas::pitch_and_track_to_instrument(int pitch, Track* track) return -1; } +void DrumCanvas::propagate_drummap_change(int instr) +//FINDMICHJETZT does that work properly? +{ + const QSet<Track*>& tracks=instrument_map[instr].tracks; + int index=instrument_map[instr].track_dlist_index; + + for (QSet<Track*>::const_iterator it = tracks.begin(); it != tracks.end(); it++) + dynamic_cast<MidiTrack*>(*it)->drummap()[index] = ourDrumMap[instr]; +} diff --git a/muse2/muse/midiedit/dcanvas.h b/muse2/muse/midiedit/dcanvas.h index c02c5442..736b63b3 100644 --- a/muse2/muse/midiedit/dcanvas.h +++ b/muse2/muse/midiedit/dcanvas.h @@ -60,17 +60,20 @@ struct instrument_number_mapping_t { QSet<Track*> tracks; int pitch; + int track_dlist_index; instrument_number_mapping_t() { pitch=-1; + track_dlist_index=-1; tracks.clear(); } - instrument_number_mapping_t(const QSet<Track*>& tr, int p) + instrument_number_mapping_t(const QSet<Track*>& tr, int p, int i) { tracks=tr; pitch=p; + track_dlist_index=i; } }; @@ -154,10 +157,11 @@ class DrumCanvas : public EventCanvas { virtual void keyPress(QKeyEvent* event); Event *getEventAtCursorPos(); void selectCursorEvent(Event *ev); - int drum_map_size() { return instrument_map.size(); } 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 }; #endif diff --git a/muse2/muse/midiedit/dlist.cpp b/muse2/muse/midiedit/dlist.cpp index 6cd469ae..9f1d9b28 100644 --- a/muse2/muse/midiedit/dlist.cpp +++ b/muse2/muse/midiedit/dlist.cpp @@ -179,6 +179,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; @@ -230,6 +236,7 @@ void DList::viewMousePressEvent(QMouseEvent* ev) int button = ev->button(); unsigned instrument = y / TH; DrumMap* dm = &ourDrumMap[instrument]; + DrumMap dm_old = *dm; setCurDrumInstrument(instrument); @@ -273,8 +280,8 @@ void DList::viewMousePressEvent(QMouseEvent* ev) val = dm->vol + incVal; if (val < 0) val = 0; - else if (val > 200) //FINDMICH: why 200? why not 999 or infinity? (flo93) - val = 200; + else if (val > 999) //changed from 200 to 999 by flo93 + val = 999; dm->vol = (unsigned char)val; break; case COL_QNT: @@ -403,6 +410,13 @@ void DList::viewMousePressEvent(QMouseEvent* ev) default: break; } + + if (!old_style_drummap_mode && dm_old != *dm) //something changed and we're in new style mode? + { + //FINDMICHJETZT propagate that! + dcanvas->propagate_drummap_change(dm-ourDrumMap); + } + redraw(); } @@ -592,8 +606,8 @@ void DList::returnPressed() 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; @@ -619,7 +633,8 @@ void DList::returnPressed() default: break; } } - + + DrumMap editEntryOld = *editEntry; switch(selectedColumn) { case COL_NAME: editEntry->name = editor->text(); @@ -661,6 +676,13 @@ void DList::returnPressed() printf("Return pressed in unknown column\n"); break; } + + if (editEntryOld != *editEntry) + { + //FINDMICHJETZT propagate! + dcanvas->propagate_drummap_change(editEntry-ourDrumMap); + } + selectedColumn = -1; editor->hide(); editEntry = 0; @@ -677,6 +699,7 @@ void DList::pitchEdited() int val=pitch_editor->value(); 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... @@ -709,12 +732,19 @@ void DList::pitchEdited() //TODO: Set all the notes on the track with instrument=dm->enote to instrument=val drumInmap[val] = instrument; } - editEntry->enote = val; + editEntry->enote = val; break; default: printf("ERROR: THIS SHOULD NEVER HAPPEN: Value changed in unknown column\n"); break; } + + if (editEntryOld != *editEntry) + { + //FINDMICHJETZT propagate + dcanvas->propagate_drummap_change(editEntry-ourDrumMap); + } + selectedColumn = -1; pitch_editor->hide(); editEntry = 0; @@ -754,11 +784,12 @@ void DList::songChanged(int flags) // DList //--------------------------------------------------------- -DList::DList(QHeaderView* h, QWidget* parent, int ymag, DrumCanvas* dcanvas, bool oldstyle) +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; diff --git a/muse2/muse/midiedit/dlist.h b/muse2/muse/midiedit/dlist.h index 8e141c3b..52bf8de4 100644 --- a/muse2/muse/midiedit/dlist.h +++ b/muse2/muse/midiedit/dlist.h @@ -87,7 +87,8 @@ class DPitchEdit: public Awl::PitchEdit class DList : public MusEWidget::View { Q_OBJECT - DrumMap* ourDrumMap; //FINDMICHJETZT init! + DrumCanvas* dcanvas; + DrumMap* ourDrumMap; int ourDrumMapSize; bool old_style_drummap_mode; diff --git a/muse2/muse/midiedit/drumedit.cpp b/muse2/muse/midiedit/drumedit.cpp index f21b0e8c..9c433386 100644 --- a/muse2/muse/midiedit/drumedit.cpp +++ b/muse2/muse/midiedit/drumedit.cpp @@ -410,7 +410,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, dynamic_cast<DrumCanvas*>(canvas)->drum_map_size()*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); diff --git a/muse2/muse/midiedit/drummap.h b/muse2/muse/midiedit/drummap.h index e4764b21..7bf2b834 100644 --- a/muse2/muse/midiedit/drummap.h +++ b/muse2/muse/midiedit/drummap.h @@ -44,8 +44,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 diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index 844c1311..b3c87206 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -4590,6 +4590,11 @@ void ScoreCanvas::add_new_parts(const std::map< Part*, std::set<Part*> >& param) * o fix valgrind problems * * > o drum editor: channel-stuff + * o hide instruments: should work + * o remember ordering of instruments: IMPLEMENT + * o tracks have own drumlists: should work. + * o respect "_drummap_tied_to_patch": IMPLEMENT + * * o each track has its own drumlist and a bool maintained_automatically * o whenever changing the patch and maintained_automatically==true, * the drumlist is replaced by the according one (for example, "jazz" drum kit's list) @@ -4601,14 +4606,17 @@ void ScoreCanvas::add_new_parts(const std::map< Part*, std::set<Part*> >& param) * * o drum editor can: "display each track separately", "mix all with same port, patch and drumlist" * x a map maps all y-coord.s to { set<Track*>, pitch } - * o either open flo-tracks OR old-style-tracks - * o replace all DRUM_MAPSIZE by instrument_map.size() + * x either open flo-tracks OR old-style-tracks + * x replace all DRUM_MAPSIZE by instrument_map.size() * o signal for instrument_map.size or drum_map_size() changed! * o move generation and deletion of ourDrumMap from DCanvas to DrumEditor and remove ugly wrapper functions * o ... * * 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= + * o BUG: drummap[i].pitch MUST BE i! or instr_map.pitch must be set accordingly! * * IMPORTANT TODO * ! o fix sigedit boxes (see also "current todo") diff --git a/muse2/muse/track.cpp b/muse2/muse/track.cpp index 57c4a658..29917dc1 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; @@ -387,6 +388,15 @@ 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++) + { + _drummap[i]=idrumMap[i]; + _drummap_hidden[i]=false; + } } //MidiTrack::MidiTrack(const MidiTrack& mt) @@ -407,12 +417,19 @@ 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)); } MidiTrack::~MidiTrack() { delete _events; delete _mpevents; + delete [] _drummap; + delete [] _drummap_hidden; } //--------------------------------------------------------- diff --git a/muse2/muse/track.h b/muse2/muse/track.h index 9c6aea24..a2c6a190 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 @@ -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; } }; //--------------------------------------------------------- -- cgit v1.2.3 From fbb72c809a2e75e0d4b038056df80d60c09d62c5 Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Sun, 2 Oct 2011 14:53:39 +0000 Subject: drum list entry ordering is now remembered bugfix in reordering drummap --- muse2/muse/midiedit/dcanvas.cpp | 101 ++++++++++++++++++++++++++++++-------- muse2/muse/midiedit/dcanvas.h | 5 +- muse2/muse/midiedit/dlist.cpp | 18 +++++-- muse2/muse/midiedit/drummap.cpp | 2 + muse2/muse/midiedit/drummap.h | 4 ++ muse2/muse/midiedit/scoreedit.cpp | 17 ++++--- muse2/muse/track.cpp | 29 ++++++++++- 7 files changed, 139 insertions(+), 37 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp index 26e7aed4..81f8da00 100644 --- a/muse2/muse/midiedit/dcanvas.cpp +++ b/muse2/muse/midiedit/dcanvas.cpp @@ -125,7 +125,6 @@ DrumCanvas::DrumCanvas(MidiEditor* pr, QWidget* parent, int sx, for (int i=0;i<DRUM_MAPSIZE;i++) { temp.pitch=i; - temp.track_dlist_index=i; // actually unneeded, but who knows... instrument_map.append(temp); } } @@ -154,32 +153,42 @@ DrumCanvas::DrumCanvas(MidiEditor* pr, QWidget* parent, int sx, // from now, we assume that every track_group's entry only groups tracks with identical // drum maps, but not necessarily identical hide-lists together. - - for (QList< QSet<Track*> >::iterator group=track_groups.begin(); group!=track_groups.end(); group++) + for (global_drum_ordering_t::iterator order_it=global_drum_ordering.begin(); order_it!=global_drum_ordering.end(); order_it++) { - for (int i=0;i<128;i++) // find out if instrument is hidden and make "mute" - { // consistent across groups for non-hidden instruments + // 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()[i].mute == false) + if (dynamic_cast<MidiTrack*>(*track)->drummap()[pitch].mute == false) mute=false; - if (dynamic_cast<MidiTrack*>(*track)->drummap_hidden()[i] == 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()[i].mute=mute; + dynamic_cast<MidiTrack*>(*track)->drummap()[pitch].mute=mute; - instrument_map.append(instrument_number_mapping_t(*group, dynamic_cast<MidiTrack*>(*group->begin())->drummap()[i].anote, i)); + 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)); } } + // else ignore it } - // populate ourDrumMap @@ -189,8 +198,7 @@ DrumCanvas::DrumCanvas(MidiEditor* pr, QWidget* parent, int sx, 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].track_dlist_index]; - //ourDrumMap[i] = idrumMap[instrument_map[i%128].pitch]; //FINDMICH dummy! + ourDrumMap[i] = dynamic_cast<MidiTrack*>(*instrument_map[i].tracks.begin())->drummap()[instrument_map[i].pitch]; } @@ -890,6 +898,9 @@ void DrumCanvas::keyReleased(int index, bool) //FINDMICH later 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; @@ -972,15 +983,64 @@ void DrumCanvas::mapChanged(int spitch, int dpitch) } else // if (!old_style_drummap_mode) { - DrumMap dm = ourDrumMap[spitch]; - ourDrumMap[spitch] = ourDrumMap[dpitch]; - ourDrumMap[dpitch] = dm; + 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; + } - instrument_number_mapping_t im = instrument_map[spitch]; - instrument_map[spitch] = instrument_map[dpitch]; - instrument_map[dpitch] = im; - song->update(SC_DRUMMAP); //FINDMICHJETZT handle that properly! + + + + 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); //FINDMICHJETZT handle that properly! if not done already (?) i think it is } } @@ -1294,10 +1354,9 @@ int DrumCanvas::pitch_and_track_to_instrument(int pitch, Track* track) } void DrumCanvas::propagate_drummap_change(int instr) -//FINDMICHJETZT does that work properly? { const QSet<Track*>& tracks=instrument_map[instr].tracks; - int index=instrument_map[instr].track_dlist_index; + 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]; diff --git a/muse2/muse/midiedit/dcanvas.h b/muse2/muse/midiedit/dcanvas.h index 736b63b3..75bcccf6 100644 --- a/muse2/muse/midiedit/dcanvas.h +++ b/muse2/muse/midiedit/dcanvas.h @@ -60,20 +60,17 @@ struct instrument_number_mapping_t { QSet<Track*> tracks; int pitch; - int track_dlist_index; instrument_number_mapping_t() { pitch=-1; - track_dlist_index=-1; tracks.clear(); } - instrument_number_mapping_t(const QSet<Track*>& tr, int p, int i) + instrument_number_mapping_t(const QSet<Track*>& tr, int p) { tracks=tr; pitch=p; - track_dlist_index=i; } }; diff --git a/muse2/muse/midiedit/dlist.cpp b/muse2/muse/midiedit/dlist.cpp index 9f1d9b28..be7255b9 100644 --- a/muse2/muse/midiedit/dlist.cpp +++ b/muse2/muse/midiedit/dlist.cpp @@ -854,11 +854,21 @@ void DList::viewMouseReleaseEvent(QMouseEvent* ev) { if (drag == DRAG) { int y = ev->y(); - unsigned dInstrument = 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 = &ourDrumMap[int(dInstrument)]; - emit curDrumInstrumentChanged(dInstrument); - emit mapChanged(sInstrument, dInstrument); //Track instrument 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 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 7bf2b834..9fe14cc9 100644 --- a/muse2/muse/midiedit/drummap.h +++ b/muse2/muse/midiedit/drummap.h @@ -59,5 +59,9 @@ 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/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index b3c87206..ad43527a 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -4590,19 +4590,23 @@ void ScoreCanvas::add_new_parts(const std::map< Part*, std::set<Part*> >& param) * o fix valgrind problems * * > o drum editor: channel-stuff - * o hide instruments: should work - * o remember ordering of instruments: IMPLEMENT - * o tracks have own drumlists: should work. + * o dialog for maintaining drum lists, hide etc + * o grouping * o respect "_drummap_tied_to_patch": IMPLEMENT + * o save hide, ordering, track's drumlists + * x hide instruments + * x remember ordering of instruments + * x tracks have own drumlists * - * o each track has its own drumlist and a bool maintained_automatically + * x each track has its own drumlist and a bool maintained_automatically * 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 each track has a bool hidden[128], which is used for hiding entries. + * x each track has a bool hidden[128], which is used for hiding entries. * when mixing, the values of all tracks are ANDed + * o offer a way to hide/show instruments * * o drum editor can: "display each track separately", "mix all with same port, patch and drumlist" * x a map maps all y-coord.s to { set<Track*>, pitch } @@ -4616,9 +4620,10 @@ void ScoreCanvas::add_new_parts(const std::map< Part*, std::set<Part*> >& param) * 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= - * o BUG: drummap[i].pitch MUST BE i! or instr_map.pitch must be set accordingly! * * IMPORTANT TODO + * 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/track.cpp b/muse2/muse/track.cpp index 29917dc1..64ad928c 100644 --- a/muse2/muse/track.cpp +++ b/muse2/muse/track.cpp @@ -394,9 +394,17 @@ MidiTrack::MidiTrack() for (int i=0;i<128;i++) { - _drummap[i]=idrumMap[i]; - _drummap_hidden[i]=false; + 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) @@ -422,6 +430,14 @@ MidiTrack::MidiTrack(const MidiTrack& mt, bool cloneParts) _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() @@ -430,6 +446,15 @@ MidiTrack::~MidiTrack() 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++; + } //--------------------------------------------------------- -- cgit v1.2.3 From b99988059eb65520df143380aa707c52256cf77c Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Mon, 3 Oct 2011 12:35:57 +0000 Subject: added support for grouping tracks in drum editor --- muse2/muse/helper.cpp | 12 ++++++++ muse2/muse/helper.h | 4 +++ muse2/muse/midiedit/dcanvas.cpp | 64 ++++++++++++++++++++++++++++++++++----- muse2/muse/midiedit/dcanvas.h | 7 ----- muse2/muse/midiedit/dlist.cpp | 15 ++------- muse2/muse/midiedit/drumedit.cpp | 2 ++ muse2/muse/midiedit/drumedit.h | 9 +++++- muse2/muse/midiedit/drummap.h | 3 +- muse2/muse/midiedit/scoreedit.cpp | 3 ++ muse2/muse/track.h | 2 +- 10 files changed, 92 insertions(+), 29 deletions(-) (limited to 'muse2') 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 81f8da00..550de13b 100644 --- a/muse2/muse/midiedit/dcanvas.cpp +++ b/muse2/muse/midiedit/dcanvas.cpp @@ -50,6 +50,7 @@ #include "shortcuts.h" #include "icons.h" #include "functions.h" +#include "helper.h" #define CARET 10 #define CARET2 5 @@ -110,6 +111,8 @@ DrumCanvas::DrumCanvas(MidiEditor* pr, QWidget* parent, int sx, int sy, const char* name) : EventCanvas(pr, parent, sx, sy, name) { + using MusEUtil::drummaps_almost_equal; + old_style_drummap_mode = dynamic_cast<DrumEdit*>(pr)->old_style_drummap_mode(); if (old_style_drummap_mode) @@ -131,7 +134,6 @@ DrumCanvas::DrumCanvas(MidiEditor* pr, QWidget* parent, int sx, else { if (debugMsg) printf("DrumCanvas in new style drummap mode\n"); - // FINDMICHJETZT TrackList* tl=song->tracks(); QList< QSet<Track*> > track_groups; @@ -145,16 +147,61 @@ DrumCanvas::DrumCanvas(MidiEditor* pr, QWidget* parent, int sx, if (p_it!=pr->parts()->end()) // if *track is represented by some part in this editor { - QSet<Track*> temp; - temp.insert(*track); - track_groups.push_back(temp); + bool inserted=false; + + switch (dynamic_cast<DrumEdit*>(pr)->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); + } } } + printf("FINDMICH DEBUG: we have %i groups\n",track_groups.size()); + // 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++) @@ -186,6 +233,9 @@ DrumCanvas::DrumCanvas(MidiEditor* pr, QWidget* parent, int sx, 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 } @@ -451,7 +501,7 @@ void DrumCanvas::newItem(MusEWidget::CItem* item, bool noSnap, bool replace) if (!noSnap) x = editor->rasterVal(x); event.setTick(x - nevent->part()->tick()); - int npitch = event.pitch(); //FINDMICH + int npitch = event.pitch(); //event.setPitch(npitch); // commented out by flo: has no effect // @@ -758,7 +808,7 @@ void DrumCanvas::cmd(int cmd) Event event = devent->event(); Event newEvent = event.clone(); // newEvent.setLenTick(drumMap[event.pitch()].len); - newEvent.setLenTick(ourDrumMap[y2pitch(devent->y())].len); //FINDMICH + 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); } @@ -1040,7 +1090,7 @@ void DrumCanvas::mapChanged(int spitch, int dpitch) } - song->update(SC_DRUMMAP); //FINDMICHJETZT handle that properly! if not done already (?) i think it is + song->update(SC_DRUMMAP); } } diff --git a/muse2/muse/midiedit/dcanvas.h b/muse2/muse/midiedit/dcanvas.h index 75bcccf6..f0c601f5 100644 --- a/muse2/muse/midiedit/dcanvas.h +++ b/muse2/muse/midiedit/dcanvas.h @@ -117,13 +117,6 @@ class DrumCanvas : public EventCanvas { virtual void curPartChanged(); int getNextStep(unsigned int pos, int basicStep, int stepSize=1); - /* FINDMICH OBSOLETE - int parts_first_instrument(Part* p); - int tracks_first_instrument(Track* t); - bool is_track_of_instrument(Track* t, int instr); - QSet<Track*> tracks_of_instrument(int instr); - */ - signals: void newWidth(int); diff --git a/muse2/muse/midiedit/dlist.cpp b/muse2/muse/midiedit/dlist.cpp index be7255b9..7de39b81 100644 --- a/muse2/muse/midiedit/dlist.cpp +++ b/muse2/muse/midiedit/dlist.cpp @@ -295,7 +295,7 @@ void DList::viewMousePressEvent(QMouseEvent* ev) else if (val > 127) val = 127; - if (old_style_drummap_mode) //FINDMICH auch beim doppelklick! + 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 @@ -318,7 +318,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 FINDMICH auch beim doppelklick + if (old_style_drummap_mode) //only allow changing in old style mode { val = dm->anote + incVal; if (val < 0) @@ -412,10 +412,7 @@ void DList::viewMousePressEvent(QMouseEvent* ev) } if (!old_style_drummap_mode && dm_old != *dm) //something changed and we're in new style mode? - { - //FINDMICHJETZT propagate that! dcanvas->propagate_drummap_change(dm-ourDrumMap); - } redraw(); } @@ -579,7 +576,7 @@ void DList::setCurDrumInstrument(int instr) if (currentlySelected != dm) { currentlySelected = dm; emit curDrumInstrumentChanged(instr); - song->update(SC_DRUMMAP); //FINDMICH necessary?? + song->update(SC_DRUMMAP); } } @@ -678,10 +675,7 @@ void DList::returnPressed() } if (editEntryOld != *editEntry) - { - //FINDMICHJETZT propagate! dcanvas->propagate_drummap_change(editEntry-ourDrumMap); - } selectedColumn = -1; editor->hide(); @@ -740,10 +734,7 @@ void DList::pitchEdited() } if (editEntryOld != *editEntry) - { - //FINDMICHJETZT propagate dcanvas->propagate_drummap_change(editEntry-ourDrumMap); - } selectedColumn = -1; pitch_editor->hide(); diff --git a/muse2/muse/midiedit/drumedit.cpp b/muse2/muse/midiedit/drumedit.cpp index 9c433386..a74f3dd1 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")); diff --git a/muse2/muse/midiedit/drumedit.h b/muse2/muse/midiedit/drumedit.h index 87226365..d854d054 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; @@ -144,6 +150,7 @@ class DrumEdit : public MidiEditor { 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.h b/muse2/muse/midiedit/drummap.h index 9fe14cc9..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; diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index ad43527a..cf7d031f 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -4598,6 +4598,8 @@ void ScoreCanvas::add_new_parts(const std::map< Part*, std::set<Part*> >& param) * x remember ordering of instruments * x tracks have own drumlists * + * o "copy drumlist" from one track to another + * * x each track has its own drumlist and a bool maintained_automatically * o whenever changing the patch and maintained_automatically==true, * the drumlist is replaced by the according one (for example, "jazz" drum kit's list) @@ -4622,6 +4624,7 @@ void ScoreCanvas::add_new_parts(const std::map< Part*, std::set<Part*> >& param) * 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") diff --git a/muse2/muse/track.h b/muse2/muse/track.h index a2c6a190..1df73620 100644 --- a/muse2/muse/track.h +++ b/muse2/muse/track.h @@ -203,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) { } }; -- cgit v1.2.3 From 09e02c07130a56a992e919cf19d32f50d067d149 Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Mon, 3 Oct 2011 13:15:24 +0000 Subject: added infrastructure for being able to handle major drummap changes should have changed nothing in functionality --- muse2/muse/midiedit/dcanvas.cpp | 252 +++++++++++++++++++++------------------ muse2/muse/midiedit/dcanvas.h | 5 + muse2/muse/midiedit/dlist.cpp | 28 ++++- muse2/muse/midiedit/dlist.h | 5 +- muse2/muse/midiedit/drumedit.cpp | 8 ++ muse2/muse/midiedit/drumedit.h | 3 +- 6 files changed, 177 insertions(+), 124 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp index 550de13b..07e5a430 100644 --- a/muse2/muse/midiedit/dcanvas.cpp +++ b/muse2/muse/midiedit/dcanvas.cpp @@ -111,9 +111,9 @@ DrumCanvas::DrumCanvas(MidiEditor* pr, QWidget* parent, int sx, int sy, const char* name) : EventCanvas(pr, parent, sx, sy, name) { - using MusEUtil::drummaps_almost_equal; + drumEditor=dynamic_cast<DrumEdit*>(pr); - old_style_drummap_mode = dynamic_cast<DrumEdit*>(pr)->old_style_drummap_mode(); + old_style_drummap_mode = drumEditor->old_style_drummap_mode(); if (old_style_drummap_mode) { @@ -122,7 +122,7 @@ DrumCanvas::DrumCanvas(MidiEditor* pr, QWidget* parent, int sx, must_delete_our_drum_map=false; instrument_number_mapping_t temp; - for (ciPart it=pr->parts()->begin(); it!=pr->parts()->end(); it++) + 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++) @@ -134,121 +134,8 @@ DrumCanvas::DrumCanvas(MidiEditor* pr, QWidget* parent, int sx, else { if (debugMsg) printf("DrumCanvas in new style drummap mode\n"); - TrackList* tl=song->tracks(); - - QList< QSet<Track*> > track_groups; - - for (ciTrack track = tl->begin(); track!=tl->end(); track++) - { - ciPart p_it; - for (p_it=pr->parts()->begin(); p_it!=pr->parts()->end(); p_it++) - if (p_it->second->track() == *track) - break; - - if (p_it!=pr->parts()->end()) // if *track is represented by some part in this editor - { - bool inserted=false; - - switch (dynamic_cast<DrumEdit*>(pr)->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); - } - } - } - - printf("FINDMICH DEBUG: we have %i groups\n",track_groups.size()); - - // 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 - } - - - // populate 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]; + ourDrumMap=NULL; + rebuildOurDrumMap(); } @@ -1411,3 +1298,132 @@ void DrumCanvas::propagate_drummap_change(int instr) 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]; + + emit ourDrumMapChanged(); + } +} diff --git a/muse2/muse/midiedit/dcanvas.h b/muse2/muse/midiedit/dcanvas.h index f0c601f5..0f519b70 100644 --- a/muse2/muse/midiedit/dcanvas.h +++ b/muse2/muse/midiedit/dcanvas.h @@ -41,6 +41,7 @@ class QDragLeaveEvent; class DrumMap; class MidiEditor; +class DrumEdit; //--------------------------------------------------------- // DEvent @@ -86,6 +87,8 @@ class DrumCanvas : public EventCanvas { bool must_delete_our_drum_map; //FINDMICH really delete it! QVector<instrument_number_mapping_t> instrument_map; + DrumEdit* drumEditor; + StepRec* steprec; // Cursor tool position @@ -119,6 +122,7 @@ class DrumCanvas : public EventCanvas { signals: void newWidth(int); + void ourDrumMapChanged(); private slots: void midiNote(int pitch, int velo); @@ -152,6 +156,7 @@ class DrumCanvas : public EventCanvas { 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 7de39b81..c35f2a21 100644 --- a/muse2/muse/midiedit/dlist.cpp +++ b/muse2/muse/midiedit/dlist.cpp @@ -37,7 +37,6 @@ #include "icons.h" #include "dlist.h" #include "song.h" -#include "scrollscale.h" #include "dcanvas.h" //--------------------------------------------------------- @@ -595,6 +594,12 @@ 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) { @@ -690,6 +695,12 @@ 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 instrument=(editEntry-ourDrumMap); @@ -784,11 +795,11 @@ DList::DList(QHeaderView* h, QWidget* parent, int ymag, DrumCanvas* dcanvas_, bo 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))); @@ -896,3 +907,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 52bf8de4..1d87f3dc 100644 --- a/muse2/muse/midiedit/dlist.h +++ b/muse2/muse/midiedit/dlist.h @@ -35,7 +35,6 @@ class QHeaderView; class QMouseEvent; class QPainter; -class ScrollScale; class Device; class QLineEdit; class DrumMap; @@ -93,7 +92,6 @@ class DList : public MusEWidget::View { bool old_style_drummap_mode; QHeaderView* header; - ScrollScale* scroll; QLineEdit* editor; DPitchEdit* pitch_editor; DrumMap* editEntry; @@ -133,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, 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 a74f3dd1..4cb6a7b1 100644 --- a/muse2/muse/midiedit/drumedit.cpp +++ b/muse2/muse/midiedit/drumedit.cpp @@ -420,6 +420,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; @@ -1343,3 +1344,10 @@ bool DrumEdit::old_style_drummap_mode() return false; } + +void DrumEdit::ourDrumMapChanged() +{ + int vmin,vmax; + vscroll->range(&vmin, &vmax); + vscroll->setRange(vmin, dynamic_cast<DrumCanvas*>(canvas)->getOurDrumMapSize()*TH); +} diff --git a/muse2/muse/midiedit/drumedit.h b/muse2/muse/midiedit/drumedit.h index d854d054..7d85cb2f 100644 --- a/muse2/muse/midiedit/drumedit.h +++ b/muse2/muse/midiedit/drumedit.h @@ -136,8 +136,9 @@ class DrumEdit : public MidiEditor { void execDeliveredScript(int); void execUserScript(int); CtrlEdit* addCtrl(); - + void ourDrumMapChanged(); virtual void updateHScrollRange(); + signals: void deleted(TopWin*); -- cgit v1.2.3 From d2427fa3b72eeb897ab214b38572009e6e4f4987 Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Mon, 3 Oct 2011 13:40:36 +0000 Subject: added support for changing grouping mode --- muse2/muse/midiedit/dcanvas.cpp | 4 ++++ muse2/muse/midiedit/dcanvas.h | 3 ++- muse2/muse/midiedit/drumedit.cpp | 49 +++++++++++++++++++++++++++++++++++++++- muse2/muse/midiedit/drumedit.h | 3 ++- 4 files changed, 56 insertions(+), 3 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp index 07e5a430..8e2f284d 100644 --- a/muse2/muse/midiedit/dcanvas.cpp +++ b/muse2/muse/midiedit/dcanvas.cpp @@ -1424,6 +1424,10 @@ void DrumCanvas::rebuildOurDrumMap() 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 0f519b70..e06857a9 100644 --- a/muse2/muse/midiedit/dcanvas.h +++ b/muse2/muse/midiedit/dcanvas.h @@ -142,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); diff --git a/muse2/muse/midiedit/drumedit.cpp b/muse2/muse/midiedit/drumedit.cpp index 4cb6a7b1..ce261425 100644 --- a/muse2/muse/midiedit/drumedit.cpp +++ b/muse2/muse/midiedit/drumedit.cpp @@ -287,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); @@ -964,7 +994,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); } } @@ -1351,3 +1385,16 @@ void DrumEdit::ourDrumMapChanged() 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 7d85cb2f..743d6151 100644 --- a/muse2/muse/midiedit/drumedit.h +++ b/muse2/muse/midiedit/drumedit.h @@ -101,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(); @@ -129,6 +129,7 @@ class DrumEdit : public MidiEditor { void configChanged(); void songChanged1(int); void setStep(QString); + void updateGroupingActions(); public slots: void setSelection(int, Event&, Part*); -- cgit v1.2.3 From 890ee8999eaca679fa1874adf3f572f365138e29 Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Mon, 3 Oct 2011 14:02:55 +0000 Subject: drum map changes are now handled properly --- muse2/muse/midiedit/dcanvas.cpp | 4 +++- muse2/muse/midiedit/dlist.cpp | 9 ++++++--- muse2/muse/midiedit/drumedit.cpp | 6 +++++- 3 files changed, 14 insertions(+), 5 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp index 8e2f284d..35236e87 100644 --- a/muse2/muse/midiedit/dcanvas.cpp +++ b/muse2/muse/midiedit/dcanvas.cpp @@ -977,7 +977,9 @@ void DrumCanvas::mapChanged(int spitch, int dpitch) } - song->update(SC_DRUMMAP); + song->update(SC_DRUMMAP); // this causes a complete rebuild of ourDrumMap + // which also handles the changed order in all + // other drum editors } } diff --git a/muse2/muse/midiedit/dlist.cpp b/muse2/muse/midiedit/dlist.cpp index c35f2a21..85382c4a 100644 --- a/muse2/muse/midiedit/dlist.cpp +++ b/muse2/muse/midiedit/dlist.cpp @@ -413,7 +413,8 @@ void DList::viewMousePressEvent(QMouseEvent* ev) if (!old_style_drummap_mode && dm_old != *dm) //something changed and we're in new style mode? dcanvas->propagate_drummap_change(dm-ourDrumMap); - redraw(); + song->update(SC_DRUMMAP); + //redraw(); //this is done by the songChanged slot } //--------------------------------------------------------- @@ -686,7 +687,8 @@ void DList::returnPressed() editor->hide(); editEntry = 0; setFocus(); - redraw(); + song->update(SC_DRUMMAP); + //redraw(); //this is done by the songChanged slot } //--------------------------------------------------------- @@ -751,7 +753,8 @@ void DList::pitchEdited() pitch_editor->hide(); editEntry = 0; setFocus(); - redraw(); + song->update(SC_DRUMMAP); + //redraw(); //this is done by the songChanged slot } //--------------------------------------------------------- diff --git a/muse2/muse/midiedit/drumedit.cpp b/muse2/muse/midiedit/drumedit.cpp index ce261425..92cc765a 100644 --- a/muse2/muse/midiedit/drumedit.cpp +++ b/muse2/muse/midiedit/drumedit.cpp @@ -587,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); - } //--------------------------------------------------------- -- cgit v1.2.3 From f60ddccd6d328a5cebc4d524246e33b399a8dfdd Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Thu, 6 Oct 2011 11:37:57 +0000 Subject: you can now hide and show drumlist instruments squashed some minor bugs --- muse2/muse/icons.cpp | 11 ++ muse2/muse/icons.h | 3 + muse2/muse/midiedit/dcanvas.cpp | 32 +++++- muse2/muse/midiedit/dcanvas.h | 15 ++- muse2/muse/midiedit/dlist.cpp | 231 +++++++++++++++++++++++++++----------- muse2/muse/midiedit/dlist.h | 5 +- muse2/muse/midiedit/drumedit.cpp | 66 +++++++---- muse2/muse/midiedit/drumedit.h | 24 +++- muse2/muse/midiedit/scoreedit.cpp | 7 +- muse2/muse/song.cpp | 8 +- muse2/muse/song.h | 4 +- muse2/xpm/eye.xpm | 22 ++++ muse2/xpm/eye_crossed.xpm | 23 ++++ muse2/xpm/eye_gray.xpm | 22 ++++ 14 files changed, 368 insertions(+), 105 deletions(-) create mode 100644 muse2/xpm/eye.xpm create mode 100644 muse2/xpm/eye_crossed.xpm create mode 100644 muse2/xpm/eye_gray.xpm (limited to 'muse2') diff --git a/muse2/muse/icons.cpp b/muse2/muse/icons.cpp index 89a3a48e..34493d13 100644 --- a/muse2/muse/icons.cpp +++ b/muse2/muse/icons.cpp @@ -1,4 +1,5 @@ //========================================================= +//========================================================= // MusE // Linux Music Editor // $Id: icons.cpp,v 1.13.2.8 2009/11/14 03:37:48 terminator356 Exp $ @@ -120,6 +121,10 @@ #include "xpm/rec_echo_on.xpm" #include "xpm/rec_echo_off.xpm" +#include "xpm/eye.xpm" +#include "xpm/eye_gray.xpm" +#include "xpm/eye_crossed.xpm" + #include "xpm/up.xpm" #include "xpm/down.xpm" #include "xpm/bold.xpm" @@ -331,6 +336,9 @@ QPixmap* homeIcon; QPixmap* backIcon; QPixmap* forwardIcon; QPixmap* muteIcon; +QPixmap* eyeIcon; +QPixmap* eyeCrossedIcon; +QPixmap* eyeGrayIcon; QPixmap* upIcon; QPixmap* downIcon; QPixmap* boldIcon; @@ -534,6 +542,9 @@ void initIcons() backIcon = new MPIXMAP(back_xpm, "go-previous"); forwardIcon = new MPIXMAP(forward_xpm, "go-next"); muteIcon = new MPIXMAP(editmuteS_xpm, "audio-volume-muted"); + eyeIcon = new MPIXMAP(eye_xpm, NULL); + eyeCrossedIcon = new MPIXMAP(eye_crossed_xpm, NULL); + eyeGrayIcon = new MPIXMAP(eye_gray_xpm, NULL); upIcon = new MPIXMAP(up_xpm, "go-up"); downIcon = new MPIXMAP(down_xpm, "go-down"); boldIcon = new MPIXMAP(bold_xpm, "format-text-bold"); diff --git a/muse2/muse/icons.h b/muse2/muse/icons.h index 957f4a74..30852f81 100644 --- a/muse2/muse/icons.h +++ b/muse2/muse/icons.h @@ -85,6 +85,9 @@ extern QPixmap* homeIcon; extern QPixmap* backIcon; extern QPixmap* forwardIcon; extern QPixmap* muteIcon; +extern QPixmap* eyeIcon; +extern QPixmap* eyeCrossedIcon; +extern QPixmap* eyeGrayIcon; extern QPixmap* upIcon; extern QPixmap* downIcon; extern QPixmap* boldIcon; diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp index 34173780..c6b39e76 100644 --- a/muse2/muse/midiedit/dcanvas.cpp +++ b/muse2/muse/midiedit/dcanvas.cpp @@ -1317,8 +1317,11 @@ void DrumCanvas::rebuildOurDrumMap() if (!old_style_drummap_mode) { + bool need_update = false; + TrackList* tl=song->tracks(); QList< QSet<Track*> > track_groups; + QVector<instrument_number_mapping_t> old_instrument_map = instrument_map; instrument_map.clear(); @@ -1396,6 +1399,9 @@ void DrumCanvas::rebuildOurDrumMap() bool mute=true; bool hidden=true; + + if (drumEditor->ignore_hide()) hidden=false; + for (QSet<Track*>::iterator track=group->begin(); track!=group->end() && (mute || hidden); track++) { if (dynamic_cast<MidiTrack*>(*track)->drummap()[pitch].mute == false) @@ -1408,7 +1414,14 @@ void DrumCanvas::rebuildOurDrumMap() if (!hidden) { for (QSet<Track*>::iterator track=group->begin(); track!=group->end(); track++) - dynamic_cast<MidiTrack*>(*track)->drummap()[pitch].mute=mute; + { + DrumMap* dm = &dynamic_cast<MidiTrack*>(*track)->drummap()[pitch]; + if (dm->mute != mute) + { + dm->mute=mute; + need_update = true; + } + } 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); @@ -1435,10 +1448,19 @@ void DrumCanvas::rebuildOurDrumMap() 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); + if (instrument_map!=old_instrument_map) + { + if (debugMsg) printf("rebuilt drummap and instrument map, size is now %i\n",size); - songChanged(SC_EVENT_INSERTED); // force an update of the itemlist - - emit ourDrumMapChanged(); + songChanged(SC_EVENT_INSERTED); // force an update of the itemlist + emit ourDrumMapChanged(true); + } + else + emit ourDrumMapChanged(false); + + if (need_update) + song->update(SC_DRUMMAP, true); // i know, this causes a recursion, which possibly + // isn't the most elegant solution here. but it will + // never be an infinite recursion } } diff --git a/muse2/muse/midiedit/dcanvas.h b/muse2/muse/midiedit/dcanvas.h index 9a45f6ac..8ecbdac9 100644 --- a/muse2/muse/midiedit/dcanvas.h +++ b/muse2/muse/midiedit/dcanvas.h @@ -73,6 +73,17 @@ struct instrument_number_mapping_t tracks=tr; pitch=p; } + + bool operator==(const instrument_number_mapping_t& that) //TODO maybe compare the Track* serial numbers, not the pointers themselves? + { + return (this->tracks == that.tracks && this->pitch==that.pitch); + } + + bool operator!=(const instrument_number_mapping_t& that) + { + return !operator==(that); + } + }; //--------------------------------------------------------- @@ -122,7 +133,7 @@ class DrumCanvas : public EventCanvas { signals: void newWidth(int); - void ourDrumMapChanged(); + void ourDrumMapChanged(bool /*instrumentMap changed as well?*/); private slots: void midiNote(int pitch, int velo); @@ -156,7 +167,7 @@ class DrumCanvas : public EventCanvas { int pitch_and_track_to_instrument(int pitch, Track* track); DrumMap* getOurDrumMap() { return ourDrumMap; } //FINDMICH UGLY int getOurDrumMapSize() { return instrument_map.size(); } //FINDMICH UGLY - + QVector<instrument_number_mapping_t>& get_instrument_map() { return instrument_map; } //FINDMICH UGLY void propagate_drummap_change(int instrument); //FINDMICH move to drumedit void rebuildOurDrumMap(); }; diff --git a/muse2/muse/midiedit/dlist.cpp b/muse2/muse/midiedit/dlist.cpp index 350f5e5e..c5379a15 100644 --- a/muse2/muse/midiedit/dlist.cpp +++ b/muse2/muse/midiedit/dlist.cpp @@ -33,6 +33,7 @@ #include "pitchedit.h" #include "midiport.h" #include "drummap.h" +#include "drumedit.h" #include "helper.h" #include "icons.h" #include "dlist.h" @@ -56,13 +57,13 @@ void DList::draw(QPainter& p, const QRect& rect) p.setPen(Qt::black); - for (int i = 0; i < ourDrumMapSize; ++i) { - int yy = i * TH; + for (int instrument = 0; instrument < ourDrumMapSize; ++instrument) { + int yy = instrument * TH; if (yy+TH < y) continue; if (yy > y + h) break; - DrumMap* dm = &ourDrumMap[i]; + DrumMap* dm = &ourDrumMap[instrument]; if (dm == currentlySelected) p.fillRect(x, yy, w, TH, Qt::yellow); // else @@ -71,6 +72,10 @@ void DList::draw(QPainter& p, const QRect& rect) p.save(); p.setWorldMatrixEnabled(false); for (int k = 0; k < h->count(); ++k) { + if (h->isSectionHidden(k)) + continue; + + int x = h->sectionPosition(k); int w = h->sectionSize(k); //QRect r = p.combinedTransform().mapRect(QRect(x+2, yy, w-4, TH)); // Gives inconsistent positions. Source shows wrong operation for our needs. @@ -81,33 +86,72 @@ void DList::draw(QPainter& p, const QRect& rect) //p.save(); //p.setWorldMatrixEnabled(false); switch (k) { - case COL_VOL: + case COL_VOLUME: s.setNum(dm->vol); break; - case COL_QNT: + case COL_QUANT: s.setNum(dm->quant); break; - case COL_LEN: + case COL_NOTELENGTH: s.setNum(dm->len); break; - case COL_ANOTE: + case COL_NOTE: s = MusEUtil::pitch2string(dm->anote); break; - case COL_ENOTE: + case COL_INPUTTRIGGER: s = MusEUtil::pitch2string(dm->enote); break; - case COL_LV1: + case COL_LEVEL1: s.setNum(dm->lv1); break; - case COL_LV2: + case COL_LEVEL2: s.setNum(dm->lv2); break; - case COL_LV3: + case COL_LEVEL3: s.setNum(dm->lv3); break; - case COL_LV4: + case COL_LEVEL4: s.setNum(dm->lv4); break; + case COL_HIDE: + { + bool hidden=false; + bool shown=false; + QSet<Track*>* group = &dcanvas->get_instrument_map()[instrument].tracks; + int pitch = dcanvas->get_instrument_map()[instrument].pitch; + + for (QSet<Track*>::iterator track=group->begin(); track!=group->end() && !(hidden&&shown); track++) + if (dynamic_cast<MidiTrack*>(*track)->drummap_hidden()[pitch]) + hidden=true; + else + shown=true; + + if (!hidden && !shown) + printf("THIS SHOULD NEVER HAPPEN: in DList::draw(): instrument %i's track group is empty. strange...\n", instrument); + + const QPixmap* pm = NULL; + + if (shown && !hidden) + pm = eyeIcon; + else if (!shown && hidden) + pm = eyeCrossedIcon; + else if (shown && hidden) + pm = eyeGrayIcon; + else //if (!shown && !hidden) + pm = NULL; + + if (pm) + { + // p.setPen(Qt::red); + p.drawPixmap( + r.x() + r.width()/2 - pm->width()/2, + r.y() + r.height()/2 - pm->height()/2, + *pm); + // p.setPen(Qt::black); + } + + break; + } case COL_MUTE: if (dm->mute) { p.setPen(Qt::red); @@ -123,10 +167,10 @@ void DList::draw(QPainter& p, const QRect& rect) s = dm->name; align = Qt::AlignVCenter | Qt::AlignLeft; break; - case COL_CHANNEL: + case COL_OUTCHANNEL: s.setNum(dm->channel+1); break; - case COL_PORT: + case COL_OUTPORT: s.sprintf("%d:%s", dm->port+1, midiPorts[dm->port].portname().toLatin1().constData()); align = Qt::AlignVCenter | Qt::AlignLeft; break; @@ -243,7 +287,7 @@ void DList::viewMousePressEvent(QMouseEvent* ev) sInstrument = instrument; drag = START_DRAG; - DCols col = DCols(x2col(x)); + DrumColumn col = DrumColumn(x2col(x)); int val; int incVal = 0; @@ -257,7 +301,7 @@ void DList::viewMousePressEvent(QMouseEvent* ev) // In that case, treat it as if a return was pressed if (button == Qt::LeftButton) { - if (((editEntry && editEntry != dm) || col != selectedColumn) && editEntry != 0) { + if (editEntry && (editEntry != dm || col != selectedColumn)) { returnPressed(); } } @@ -265,17 +309,35 @@ void DList::viewMousePressEvent(QMouseEvent* ev) switch (col) { case COL_NONE: break; + case COL_HIDE: + if (button == Qt::LeftButton) + { + bool hidden=true; + QSet<Track*>* group = &dcanvas->get_instrument_map()[instrument].tracks; + int pitch = dcanvas->get_instrument_map()[instrument].pitch; + + for (QSet<Track*>::iterator track=group->begin(); track!=group->end(); track++) + if (dynamic_cast<MidiTrack*>(*track)->drummap_hidden()[pitch] == false) + { + hidden=false; + break; + } + + for (QSet<Track*>::iterator track=group->begin(); track!=group->end(); track++) + dynamic_cast<MidiTrack*>(*track)->drummap_hidden()[pitch] = !hidden; + } + break; case COL_MUTE: if (button == Qt::LeftButton) dm->mute = !dm->mute; break; - case COL_PORT: // this column isn't visible in new style drum mode + case COL_OUTPORT: // 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(instrument * TH), changeAll); } break; - case COL_VOL: + case COL_VOLUME: val = dm->vol + incVal; if (val < 0) val = 0; @@ -283,11 +345,11 @@ void DList::viewMousePressEvent(QMouseEvent* ev) val = 999; dm->vol = (unsigned char)val; break; - case COL_QNT: + case COL_QUANT: dm->quant += incVal; // ?? range break; - case COL_ENOTE: + case COL_INPUTTRIGGER: val = dm->enote + incVal; if (val < 0) val = 0; @@ -310,13 +372,13 @@ void DList::viewMousePressEvent(QMouseEvent* ev) } dm->enote = val; break; - case COL_LEN: + case COL_NOTELENGTH: val = dm->len + incVal; if (val < 0) val = 0; dm->len = val; break; - case COL_ANOTE: + case COL_NOTE: if (old_style_drummap_mode) //only allow changing in old style mode { val = dm->anote + incVal; @@ -339,7 +401,7 @@ void DList::viewMousePressEvent(QMouseEvent* ev) emit keyPressed(instrument, velocity);//(dm->anote, shift); } break; - case COL_CHANNEL: // this column isn't visible in new style drum mode + case COL_OUTCHANNEL: // this column isn't visible in new style drum mode val = dm->channel + incVal; if (val < 0) val = 0; @@ -370,7 +432,7 @@ void DList::viewMousePressEvent(QMouseEvent* ev) } } break; - case COL_LV1: + case COL_LEVEL1: val = dm->lv1 + incVal; if (val < 0) val = 0; @@ -378,7 +440,7 @@ void DList::viewMousePressEvent(QMouseEvent* ev) val = 127; dm->lv1 = val; break; - case COL_LV2: + case COL_LEVEL2: val = dm->lv2 + incVal; if (val < 0) val = 0; @@ -386,7 +448,7 @@ void DList::viewMousePressEvent(QMouseEvent* ev) val = 127; dm->lv2 = val; break; - case COL_LV3: + case COL_LEVEL3: val = dm->lv3 + incVal; if (val < 0) val = 0; @@ -394,7 +456,7 @@ void DList::viewMousePressEvent(QMouseEvent* ev) val = 127; dm->lv3 = val; break; - case COL_LV4: + case COL_LEVEL4: val = dm->lv4 + incVal; if (val < 0) val = 0; @@ -403,7 +465,48 @@ void DList::viewMousePressEvent(QMouseEvent* ev) dm->lv4 = val; break; case COL_NAME: - emit keyPressed(instrument, 100); //Mapping done on other side, send index + if (button == Qt::LeftButton) + emit keyPressed(instrument, 100); //Mapping done on other side, send index + else if (button == Qt::MidButton) // hide that instrument + { + QSet<Track*>* group = &dcanvas->get_instrument_map()[instrument].tracks; + int pitch = dcanvas->get_instrument_map()[instrument].pitch; + for (QSet<Track*>::iterator track=group->begin(); track!=group->end(); track++) + dynamic_cast<MidiTrack*>(*track)->drummap_hidden()[pitch] = true; + } + else if (button == Qt::RightButton) + { + bool hidden=false; + bool shown=false; + QSet<Track*>* group = &dcanvas->get_instrument_map()[instrument].tracks; + int pitch = dcanvas->get_instrument_map()[instrument].pitch; + + for (QSet<Track*>::iterator track=group->begin(); track!=group->end() && !(hidden&&shown); track++) + if (dynamic_cast<MidiTrack*>(*track)->drummap_hidden()[pitch]) + hidden=true; + else + shown=true; + + QMenu* popup = new QMenu(NULL /* intendedly not "this" */); + QAction* hideAction = popup->addAction(tr("hide this instrument")); + QAction* showAction = popup->addAction(tr("show this instrument")); + showAction->setToolTip(tr("this turns a grayed out eye into a blue eye")); + + if (!hidden) + showAction->setEnabled(false); + if (!shown) + hideAction->setEnabled(false); + + QAction* result = popup->exec(ev->globalPos()); + if (result==hideAction) + for (QSet<Track*>::iterator track=group->begin(); track!=group->end(); track++) + dynamic_cast<MidiTrack*>(*track)->drummap_hidden()[pitch] = true; + else if (result==showAction) + for (QSet<Track*>::iterator track=group->begin(); track!=group->end(); track++) + dynamic_cast<MidiTrack*>(*track)->drummap_hidden()[pitch] = false; + + delete popup; + } break; default: @@ -429,13 +532,13 @@ void DList::viewMouseDoubleClickEvent(QMouseEvent* ev) 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_QNT || - (section == COL_CHANNEL && old_style_drummap_mode) ) && (ev->button() == Qt::LeftButton)) + if ((section == COL_NAME || section == COL_VOLUME || section == COL_NOTELENGTH || section == COL_LEVEL1 || + section == COL_LEVEL2 || section == COL_LEVEL3 || section == COL_LEVEL4 || section == COL_QUANT || + (section == COL_OUTCHANNEL && old_style_drummap_mode) ) && (ev->button() == Qt::LeftButton)) { lineEdit(instrument, section); } - else if (((section == COL_ANOTE && old_style_drummap_mode) || section == COL_ENOTE) && (ev->button() == Qt::LeftButton)) + else if (((section == COL_NOTE && old_style_drummap_mode) || section == COL_INPUTTRIGGER) && (ev->button() == Qt::LeftButton)) pitchEdit(instrument, section); else viewMousePressEvent(ev); @@ -466,37 +569,37 @@ void DList::lineEdit(int line, int section) editor->setText(dm->name); break; - case COL_VOL: { + case COL_VOLUME: { editor->setText(QString::number(dm->vol)); break; } - case COL_LEN: { + case COL_NOTELENGTH: { editor->setText(QString::number(dm->len)); break; } - case COL_LV1: + case COL_LEVEL1: editor->setText(QString::number(dm->lv1)); break; - case COL_LV2: + case COL_LEVEL2: editor->setText(QString::number(dm->lv2)); break; - case COL_LV3: + case COL_LEVEL3: editor->setText(QString::number(dm->lv3)); break; - case COL_LV4: + case COL_LEVEL4: editor->setText(QString::number(dm->lv4)); break; - case COL_QNT: + case COL_QUANT: editor->setText(QString::number(dm->quant)); break; - case COL_CHANNEL: + case COL_OUTCHANNEL: editor->setText(QString::number(dm->channel+1)); break; } @@ -530,11 +633,11 @@ void DList::pitchEdit(int line, int section) int colh = rmapy(TH); selectedColumn = section; //Store selected column to have an idea of which one was selected when return is pressed switch (section) { - case COL_ENOTE: + case COL_INPUTTRIGGER: pitch_editor->setValue(dm->enote); break; - case COL_ANOTE: + case COL_NOTE: pitch_editor->setValue(dm->anote); break; } @@ -608,24 +711,24 @@ void DList::returnPressed() switch (selectedColumn) { - case COL_VOL: + case COL_VOLUME: if (val > 999) //changed from 200 to 999 by flo93 val = 999; if (val < 0) val = 0; break; - case COL_LV1: - case COL_LV2: - case COL_LV3: - case COL_LV4: + case COL_LEVEL1: + case COL_LEVEL2: + case COL_LEVEL3: + case COL_LEVEL4: if (val > 127) //Check bounds for lv1-lv4 values val = 127; if (val < 0) val = 0; break; - case COL_CHANNEL: + case COL_OUTCHANNEL: val--; if (val >= 16) val = 15; @@ -643,35 +746,35 @@ void DList::returnPressed() editEntry->name = editor->text(); break; - case COL_LEN: + case COL_NOTELENGTH: editEntry->len = atoi(editor->text().toAscii().constData()); break; - case COL_VOL: + case COL_VOLUME: editEntry->vol = val; break; - case COL_LV1: + case COL_LEVEL1: editEntry->lv1 = val; break; - case COL_LV2: + case COL_LEVEL2: editEntry->lv2 = val; break; - case COL_LV3: + case COL_LEVEL3: editEntry->lv3 = val; break; - case COL_LV4: + case COL_LEVEL4: editEntry->lv4 = val; break; - case COL_QNT: + case COL_QUANT: editEntry->quant = val; break; - case COL_CHANNEL: + case COL_OUTCHANNEL: editEntry->channel = val; break; @@ -708,7 +811,7 @@ void DList::pitchEdited() DrumMap editEntryOld=*editEntry; switch(selectedColumn) { - case COL_ANOTE: + case COL_NOTE: if (old_style_drummap_mode) //should actually be always true, but to be sure... { if(val != editEntry->anote) @@ -724,7 +827,7 @@ void DList::pitchEdited() printf("ERROR: THIS SHOULD NEVER HAPPEN: pitch edited of anote in new style mode!\n"); break; - case COL_ENOTE: + case COL_INPUTTRIGGER: if (old_style_drummap_mode) { //Check if there is any other drumMap with the same inmap value (there should be one (and only one):-) @@ -798,7 +901,7 @@ DList::DList(QHeaderView* h, QWidget* parent, int ymag, DrumCanvas* dcanvas_, bo ourDrumMap=dcanvas->getOurDrumMap(); ourDrumMapSize=dcanvas->getOurDrumMapSize(); old_style_drummap_mode=oldstyle; - connect(dcanvas, SIGNAL(ourDrumMapChanged()), SLOT(ourDrumMapChanged())); + connect(dcanvas, SIGNAL(ourDrumMapChanged(bool)), SLOT(ourDrumMapChanged(bool))); if (!h){ h = new QHeaderView(Qt::Horizontal, parent);} @@ -884,13 +987,13 @@ void DList::viewMouseReleaseEvent(QMouseEvent* ev) bool shift = ev->modifiers() & Qt::ShiftModifier; unsigned instrument = y / TH; - DCols col = DCols(x2col(x)); + DrumColumn col = DrumColumn(x2col(x)); switch (col) { case COL_NAME: emit keyReleased(instrument, shift); break; - case COL_ANOTE: + case COL_NOTE: emit keyReleased(instrument, shift); break; default: @@ -910,14 +1013,16 @@ int DList::getSelectedInstrument() } -void DList::ourDrumMapChanged() +void DList::ourDrumMapChanged(bool instrMapChanged) { int selIdx = currentlySelected - ourDrumMap; ourDrumMap=dcanvas->getOurDrumMap(); ourDrumMapSize=dcanvas->getOurDrumMapSize(); - editEntry=NULL; + if (instrMapChanged) + editEntry=NULL; + if (selIdx >= ourDrumMapSize) selIdx=ourDrumMapSize-1; currentlySelected = &ourDrumMap[selIdx]; diff --git a/muse2/muse/midiedit/dlist.h b/muse2/muse/midiedit/dlist.h index 1d87f3dc..cc3f3edc 100644 --- a/muse2/muse/midiedit/dlist.h +++ b/muse2/muse/midiedit/dlist.h @@ -131,7 +131,7 @@ class DList : public MusEWidget::View { public slots: void tracklistChanged(); void songChanged(int); - void ourDrumMapChanged(); + void ourDrumMapChanged(bool); public: void lineEdit(int line, int section); @@ -141,9 +141,6 @@ class DList : public MusEWidget::View { ~DList(); int getSelectedInstrument(); -enum DCols { COL_MUTE=0, COL_NAME, COL_VOL, COL_QNT, COL_ENOTE, COL_LEN, - COL_ANOTE, COL_CHANNEL, COL_PORT, - COL_LV1, COL_LV2, COL_LV3, COL_LV4, COL_NONE=-1}; }; #endif // __DLIST_H_ diff --git a/muse2/muse/midiedit/drumedit.cpp b/muse2/muse/midiedit/drumedit.cpp index 92cc765a..c98d0632 100644 --- a/muse2/muse/midiedit/drumedit.cpp +++ b/muse2/muse/midiedit/drumedit.cpp @@ -80,27 +80,12 @@ static const char* map_file_save_pattern[] = { int DrumEdit::_rasterInit = 96; int DrumEdit::_dlistWidthInit = 50; int DrumEdit::_dcanvasWidthInit = 300; +bool DrumEdit::_ignore_hide_init = false; static const int xscale = -10; static const int yscale = 1; static const int drumeditTools = MusEWidget::PointerTool | MusEWidget::PencilTool | MusEWidget::RubberTool | MusEWidget::CursorTool | MusEWidget::DrawTool; -enum DrumColumn { - COL_MUTE = 0, - COL_NAME, - COL_VOLUME, - COL_QUANT, - COL_INPUTTRIGGER, - COL_NOTELENGTH, - COL_NOTE, - COL_OUTCHANNEL, - COL_OUTPORT, - COL_LEVEL1, - COL_LEVEL2, - COL_LEVEL3, - COL_LEVEL4, - COL_NONE = -1 -}; //--------------------------------------------------------- // setHeaderWhatsThis @@ -108,6 +93,7 @@ enum DrumColumn { void DrumEdit::setHeaderWhatsThis() { + header->setWhatsThis(COL_HIDE, tr("hide instrument")); header->setWhatsThis(COL_MUTE, tr("mute instrument")); header->setWhatsThis(COL_NAME, tr("sound name")); header->setWhatsThis(COL_VOLUME, tr("volume percent")); @@ -129,6 +115,7 @@ void DrumEdit::setHeaderWhatsThis() void DrumEdit::setHeaderToolTips() { + header->setToolTip(COL_HIDE, tr("hide instrument")); header->setToolTip(COL_MUTE, tr("mute instrument")); header->setToolTip(COL_NAME, tr("sound name")); header->setToolTip(COL_VOLUME, tr("volume percent")); @@ -178,6 +165,7 @@ DrumEdit::DrumEdit(PartList* pl, QWidget* parent, const char* name, unsigned ini QSignalMapper *signalMapper = new QSignalMapper(this); _group_mode = GROUP_SAME_CHANNEL; + _ignore_hide = _ignore_hide_init; //---------Pulldown Menu---------------------------- menuFile = menuBar()->addMenu(tr("&File")); @@ -299,15 +287,19 @@ DrumEdit::DrumEdit(PartList* pl, QWidget* parent, const char* name, unsigned ini groupNoneAction = menuGrouping->addAction(tr("Don't group")); groupChanAction = menuGrouping->addAction(tr("Group by channel")); groupMaxAction = menuGrouping->addAction(tr("Group maximally")); + QAction* ignoreHideAction = settingsMenu->addAction(tr("Also show hidden events")); settingsMenu->addSeparator(); groupNoneAction->setCheckable(true); groupChanAction->setCheckable(true); groupMaxAction ->setCheckable(true); + ignoreHideAction->setCheckable(true); + ignoreHideAction->setChecked(_ignore_hide); connect(groupNoneAction, SIGNAL(triggered()), signalMapper, SLOT(map())); connect(groupChanAction, SIGNAL(triggered()), signalMapper, SLOT(map())); connect(groupMaxAction, SIGNAL(triggered()), signalMapper, SLOT(map())); + connect(ignoreHideAction, SIGNAL(toggled(bool)), SLOT(set_ignore_hide(bool))); signalMapper->setMapping(groupNoneAction, DrumCanvas::CMD_GROUP_NONE); signalMapper->setMapping(groupChanAction, DrumCanvas::CMD_GROUP_CHAN); @@ -450,7 +442,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())); + connect(canvas, SIGNAL(ourDrumMapChanged(bool)), SLOT(ourDrumMapChanged(bool))); time->setOrigin(offset, 0); QList<int> mops; @@ -474,6 +466,7 @@ DrumEdit::DrumEdit(PartList* pl, QWidget* parent, const char* name, unsigned ini // header = new MusEWidget::Header(split1w1, "header"); header->setFixedHeight(31); + header->setColumnLabel(tr("H"), COL_HIDE, 20); header->setColumnLabel(tr("M"), COL_MUTE, 20); header->setColumnLabel(tr("Sound"), COL_NAME, 120); header->setColumnLabel(tr("Vol"), COL_VOLUME); @@ -496,6 +489,11 @@ DrumEdit::DrumEdit(PartList* pl, QWidget* parent, const char* name, unsigned ini header->hideSection(COL_OUTPORT); header->hideSection(COL_OUTCHANNEL); } + + if (!old_style_drummap_mode() && _ignore_hide) + header->showSection(COL_HIDE); + else + header->hideSection(COL_HIDE); dlist = new DList(header, split1w1, yscale, (DrumCanvas*)canvas, old_style_drummap_mode()); // p3.3.44 @@ -749,6 +747,7 @@ void DrumEdit::writeStatus(int level, Xml& xml) const xml.intTag(level, "xmag", hscroll->mag()); xml.intTag(level, "ypos", vscroll->pos()); xml.intTag(level, "ymag", vscroll->mag()); + xml.intTag(level, "ignore_hide", _ignore_hide); xml.tag(level, "/drumedit"); } @@ -796,6 +795,8 @@ void DrumEdit::readStatus(Xml& xml) vscroll->setMag(xml.parseInt()); else if (tag == "ypos") vscroll->setPos(xml.parseInt()); + else if (tag == "ignore_hide") + _ignore_hide=xml.parseInt(); else xml.unknown("DrumEdit"); break; @@ -832,6 +833,8 @@ void DrumEdit::readConfiguration(Xml& xml) _dcanvasWidthInit = xml.parseInt(); else if (tag == "dlistwidth") _dlistWidthInit = xml.parseInt(); + else if (tag == "ignore_hide_init") + _ignore_hide_init = xml.parseInt(); else if (tag == "topwin") TopWin::readConfiguration(DRUM, xml); else @@ -857,6 +860,7 @@ void DrumEdit::writeConfiguration(int level, Xml& xml) xml.intTag(level, "raster", _rasterInit); xml.intTag(level, "dlistwidth", _dlistWidthInit); xml.intTag(level, "dcanvaswidth", _dcanvasWidthInit); + xml.intTag(level, "ignore_hide_init", _ignore_hide_init); TopWin::writeConfiguration(DRUM, level,xml); xml.tag(level, "/drumedit"); } @@ -1177,7 +1181,7 @@ void DrumEdit::keyPressEvent(QKeyEvent* event) return; } else if (key == Qt::Key_F2) { - dlist->lineEdit(dlist->getSelectedInstrument(),(int)DList::COL_NAME); + dlist->lineEdit(dlist->getSelectedInstrument(),(int)COL_NAME); return; } else if (key == shortcuts[SHRT_INSTRUMENT_STEP_UP].key) { @@ -1383,11 +1387,14 @@ bool DrumEdit::old_style_drummap_mode() return false; } -void DrumEdit::ourDrumMapChanged() +void DrumEdit::ourDrumMapChanged(bool instrMapChanged) { - int vmin,vmax; - vscroll->range(&vmin, &vmax); - vscroll->setRange(vmin, dynamic_cast<DrumCanvas*>(canvas)->getOurDrumMapSize()*TH); + if (instrMapChanged) + { + int vmin,vmax; + vscroll->range(&vmin, &vmax); + vscroll->setRange(vmin, dynamic_cast<DrumCanvas*>(canvas)->getOurDrumMapSize()*TH); + } } void DrumEdit::updateGroupingActions() @@ -1402,3 +1409,18 @@ void DrumEdit::updateGroupingActions() groupChanAction->setChecked(_group_mode==GROUP_SAME_CHANNEL); groupMaxAction ->setChecked(_group_mode==GROUP_MAX); } + +void DrumEdit::set_ignore_hide(bool val) +{ + _ignore_hide=val; + _ignore_hide_init=val; + // this may only called be from the action's toggled signal. + // if called otherwise, the action's checked state isn't updated! + + if (!old_style_drummap_mode() && _ignore_hide) + header->showSection(COL_HIDE); + else + header->hideSection(COL_HIDE); + + ((DrumCanvas*)(canvas))->rebuildOurDrumMap(); +} diff --git a/muse2/muse/midiedit/drumedit.h b/muse2/muse/midiedit/drumedit.h index 743d6151..4b0a39b8 100644 --- a/muse2/muse/midiedit/drumedit.h +++ b/muse2/muse/midiedit/drumedit.h @@ -61,6 +61,24 @@ class Splitter; class Toolbar1; } +enum DrumColumn { + COL_HIDE = 0, + COL_MUTE, + COL_NAME, + COL_VOLUME, + COL_QUANT, + COL_INPUTTRIGGER, + COL_NOTELENGTH, + COL_NOTE, + COL_OUTCHANNEL, + COL_OUTPORT, + COL_LEVEL1, + COL_LEVEL2, + COL_LEVEL3, + COL_LEVEL4, + COL_NONE = -1 +}; + //--------------------------------------------------------- // DrumEdit //--------------------------------------------------------- @@ -73,6 +91,7 @@ class DrumEdit : public MidiEditor { private: group_mode_t _group_mode; + bool _ignore_hide; Event selEvent; MidiPart* selPart; @@ -95,6 +114,7 @@ class DrumEdit : public MidiEditor { static int _rasterInit; static int _dlistWidthInit, _dcanvasWidthInit; + static bool _ignore_hide_init; QAction *loadAction, *saveAction, *resetAction; QAction *cutAction, *copyAction, *copyRangeAction, *pasteAction, *pasteDialogAction, *deleteAction; @@ -130,6 +150,7 @@ class DrumEdit : public MidiEditor { void songChanged1(int); void setStep(QString); void updateGroupingActions(); + void set_ignore_hide(bool); public slots: void setSelection(int, Event&, Part*); @@ -137,7 +158,7 @@ class DrumEdit : public MidiEditor { void execDeliveredScript(int); void execUserScript(int); CtrlEdit* addCtrl(); - void ourDrumMapChanged(); + void ourDrumMapChanged(bool); virtual void updateHScrollRange(); signals: @@ -153,6 +174,7 @@ class DrumEdit : public MidiEditor { bool old_style_drummap_mode(); group_mode_t group_mode() { return _group_mode; } + bool ignore_hide() { return _ignore_hide; } }; #endif diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index 64258f60..e82ab7ad 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -4591,11 +4591,11 @@ void ScoreCanvas::add_new_parts(const std::map< Part*, std::set<Part*> >& param) * 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 clearly state in the changelog: when having multiple drumeditors open, + * the mute-column may not work, because another editor is overriding this. * o respect "_drummap_tied_to_patch": IMPLEMENT * o save hide, ordering, track's drumlists * o "copy drumlist" from one track to another @@ -4615,7 +4615,6 @@ void ScoreCanvas::add_new_parts(const std::map< Part*, std::set<Part*> >& param) * 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 * o newly created windows have to be focussed! diff --git a/muse2/muse/song.cpp b/muse2/muse/song.cpp index a994b0e6..db2bcad5 100644 --- a/muse2/muse/song.cpp +++ b/muse2/muse/song.cpp @@ -1468,11 +1468,13 @@ void Song::rewindStart() // update //--------------------------------------------------------- -void Song::update(int flags) +void Song::update(int flags, bool allowRecursion) { static int level = 0; // DEBUG - if (level) { - printf("Song::update %08x, level %d\n", flags, level); + if (level && !allowRecursion) { + printf("THIS SHOULD NEVER HAPPEN: unallowed recursion in Song::update(%08x), level %d!\n" + " the songChanged() signal is NOT emitted. this will\n" + " probably cause windows being not up-to-date.\n", flags, level); return; } ++level; diff --git a/muse2/muse/song.h b/muse2/muse/song.h index 79e5521f..ad77d723 100644 --- a/muse2/muse/song.h +++ b/muse2/muse/song.h @@ -379,7 +379,9 @@ class Song : public QObject { public slots: void seekTo(int tick); - void update(int flags = -1); + void update(int flags = -1, bool allowRecursion=false); // use allowRecursion with care! this + // could lock up muse if you aren't sure + // that your recursion will be finite! void beat(); void undo(); diff --git a/muse2/xpm/eye.xpm b/muse2/xpm/eye.xpm new file mode 100644 index 00000000..74e5bcc1 --- /dev/null +++ b/muse2/xpm/eye.xpm @@ -0,0 +1,22 @@ +/* XPM */ +static const char * eye_xpm[] = { +"16 16 3 1", +" c None", +". c #000000", +"+ c #0000FD", +" ", +" ", +" ", +" .... ", +" ........ ", +" ... ... ", +" ... ++++ ... ", +"... ++++++ ...", +".. ++++++ ..", +"... ++++++ ...", +" ... ++++ ... ", +" ... ... ", +" ........ ", +" .... ", +" ", +" "}; diff --git a/muse2/xpm/eye_crossed.xpm b/muse2/xpm/eye_crossed.xpm new file mode 100644 index 00000000..65dca19c --- /dev/null +++ b/muse2/xpm/eye_crossed.xpm @@ -0,0 +1,23 @@ +/* XPM */ +static const char * eye_crossed_xpm[] = { +"16 16 4 1", +" c None", +". c #E10E08", +"+ c #000000", +"@ c #0000FD", +" ", +" .. ", +" ....", +" ++++ .... ", +" ++++++.... ", +" +++ ....+ ", +" +++ @@....+++ ", +"+++ @@.... +++", +"++ @....@ ++", +"+++ ....@@ +++", +" +++....@@ +++ ", +" +.... +++ ", +" ....++++++ ", +" .... ++++ ", +" .. ", +" "}; diff --git a/muse2/xpm/eye_gray.xpm b/muse2/xpm/eye_gray.xpm new file mode 100644 index 00000000..8d5a7d9d --- /dev/null +++ b/muse2/xpm/eye_gray.xpm @@ -0,0 +1,22 @@ +/* XPM */ +static const char * eye_gray_xpm[] = { +"16 16 3 1", +" c None", +". c #292929", +"+ c #535353", +" ", +" ", +" ", +" .... ", +" ........ ", +" ... ... ", +" ... ++++ ... ", +"... ++++++ ...", +".. ++++++ ..", +"... ++++++ ...", +" ... ++++ ... ", +" ... ... ", +" ........ ", +" .... ", +" ", +" "}; -- cgit v1.2.3 From 3e6f82d7b9b29e8df7d63658540b762203b820f6 Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Fri, 7 Oct 2011 14:53:22 +0000 Subject: added new style drum tracks atm, they aren't different from midi tracks except that they launch a drum editor by default added markers to help me finding the places to change TODO: instrument muting, in-note-mapping etc... --- muse2/muse/app.cpp | 1 + muse2/muse/appearance.cpp | 5 ++--- muse2/muse/arranger/arrangerview.cpp | 12 +++++++----- muse2/muse/arranger/arrangerview.h | 2 +- muse2/muse/arranger/pcanvas.cpp | 6 +++++- muse2/muse/arranger/tlist.cpp | 25 +++++++++++++++++++------ muse2/muse/conf.cpp | 10 +++++++++- muse2/muse/ctrl/ctrlcanvas.cpp | 6 +++--- muse2/muse/ctrl/ctrlpanel.cpp | 6 +++--- muse2/muse/gconfig.cpp | 6 ++++-- muse2/muse/gconfig.h | 3 +++ muse2/muse/helper.cpp | 18 ++++++++++++++++++ muse2/muse/importmidi.cpp | 4 ++-- muse2/muse/liste/editevent.cpp | 6 +++--- muse2/muse/midi.cpp | 18 +++++++++--------- muse2/muse/midiedit/scoreedit.cpp | 8 ++++++++ muse2/muse/mixer/amixer.cpp | 17 +++++++++++++++-- muse2/muse/mixer/amixer.h | 2 ++ muse2/muse/mixer/strip.cpp | 4 ++++ muse2/muse/part.cpp | 11 +++++++---- muse2/muse/remote/pyapi.cpp | 6 ++++-- muse2/muse/shortcuts.cpp | 1 + muse2/muse/shortcuts.h | 1 + muse2/muse/song.cpp | 23 ++++++++++++++++------- muse2/muse/songfile.cpp | 8 +++++++- muse2/muse/track.cpp | 25 ++++++++++++++++--------- muse2/muse/track.h | 4 ++-- muse2/muse/widgets/mtrackinfo.cpp | 23 ++++++++++++++--------- muse2/muse/widgets/musewidgetsplug.cpp | 6 ++++-- 29 files changed, 190 insertions(+), 77 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/app.cpp b/muse2/muse/app.cpp index fd024d57..c56376fe 100644 --- a/muse2/muse/app.cpp +++ b/muse2/muse/app.cpp @@ -1792,6 +1792,7 @@ void MusE::startEditor(Track* t) switch (t->type()) { case Track::MIDI: startPianoroll(); break; case Track::DRUM: startDrumEditor(); break; + case Track::NEW_DRUM: startDrumEditor(); break; case Track::WAVE: startWaveEditor(); break; default: break; diff --git a/muse2/muse/appearance.cpp b/muse2/muse/appearance.cpp index b3e89aa1..a702965c 100644 --- a/muse2/muse/appearance.cpp +++ b/muse2/muse/appearance.cpp @@ -1,5 +1,4 @@ //========================================================= -//========================================================= // MusE // Linux Music Editor // $Id: appearance.cpp,v 1.11.2.5 2009/11/14 03:37:48 terminator356 Exp $ @@ -841,7 +840,7 @@ void Appearance::colorItemSelectionChanged() case 0x300: color = &config->waveEditBackgroundColor; break; case 0x411: color = &config->trackBg; break; case 0x412: color = &config->midiTrackBg; break; - case 0x413: color = &config->drumTrackBg; break; + case 0x413: color = &config->drumTrackBg; break; //FINDMICHJETZT add newDrum... case 0x414: color = &config->waveTrackBg; break; case 0x415: color = &config->outputTrackBg; break; case 0x416: color = &config->inputTrackBg; break; @@ -855,7 +854,7 @@ void Appearance::colorItemSelectionChanged() case 0x500: color = &config->mixerBg; break; case 0x501: color = &config->midiTrackLabelBg; break; - case 0x502: color = &config->drumTrackLabelBg; break; + case 0x502: color = &config->drumTrackLabelBg; break; //FINDMICHJETZT add newDrum... case 0x503: color = &config->waveTrackLabelBg; break; case 0x504: color = &config->outputTrackLabelBg; break; case 0x505: color = &config->inputTrackLabelBg; break; diff --git a/muse2/muse/arranger/arrangerview.cpp b/muse2/muse/arranger/arrangerview.cpp index 96ce4c09..d828feeb 100644 --- a/muse2/muse/arranger/arrangerview.cpp +++ b/muse2/muse/arranger/arrangerview.cpp @@ -634,11 +634,12 @@ void ArrangerView::populateAddTrack() trackMidiAction = grp->actions()[0]; trackDrumAction = grp->actions()[1]; - trackWaveAction = grp->actions()[2]; - trackAOutputAction = grp->actions()[3]; - trackAGroupAction = grp->actions()[4]; - trackAInputAction = grp->actions()[5]; - trackAAuxAction = grp->actions()[6]; + trackNewStyleDrumAction = grp->actions()[2]; + trackWaveAction = grp->actions()[3]; + trackAOutputAction = grp->actions()[4]; + trackAGroupAction = grp->actions()[5]; + trackAInputAction = grp->actions()[6]; + trackAAuxAction = grp->actions()[7]; } void ArrangerView::addNewTrack(QAction* action) @@ -662,6 +663,7 @@ void ArrangerView::updateShortcuts() trackMidiAction->setShortcut(shortcuts[SHRT_ADD_MIDI_TRACK].key); trackDrumAction->setShortcut(shortcuts[SHRT_ADD_DRUM_TRACK].key); + trackNewStyleDrumAction->setShortcut(shortcuts[SHRT_ADD_NEW_STYLE_DRUM_TRACK].key); trackWaveAction->setShortcut(shortcuts[SHRT_ADD_WAVE_TRACK].key); trackAOutputAction->setShortcut(shortcuts[SHRT_ADD_AUDIO_OUTPUT].key); trackAGroupAction->setShortcut(shortcuts[SHRT_ADD_AUDIO_GROUP].key); diff --git a/muse2/muse/arranger/arrangerview.h b/muse2/muse/arranger/arrangerview.h index 20655840..7c273ad8 100644 --- a/muse2/muse/arranger/arrangerview.h +++ b/muse2/muse/arranger/arrangerview.h @@ -88,7 +88,7 @@ class ArrangerView : public TopWin QMenu* master; QAction *strGlobalCutAction, *strGlobalInsertAction, *strGlobalSplitAction; - QAction *trackMidiAction, *trackDrumAction, *trackWaveAction, *trackAOutputAction, *trackAGroupAction; + QAction *trackMidiAction, *trackDrumAction, *trackNewStyleDrumAction, *trackWaveAction, *trackAOutputAction, *trackAGroupAction; QAction *trackAInputAction, *trackAAuxAction; QAction *editCutAction, *editCopyAction, *editCopyRangeAction; QAction *editPasteAction, *editPasteCloneAction, *editPasteDialogAction, *editPasteCloneDialogAction; diff --git a/muse2/muse/arranger/pcanvas.cpp b/muse2/muse/arranger/pcanvas.cpp index 5b5f3a6f..eaeec291 100644 --- a/muse2/muse/arranger/pcanvas.cpp +++ b/muse2/muse/arranger/pcanvas.cpp @@ -238,6 +238,7 @@ void PartCanvas::viewMouseDoubleClickEvent(QMouseEvent* event) switch(track->type()) { case Track::MIDI: case Track::DRUM: + case Track::NEW_DRUM: { MidiPart* part = new MidiPart((MidiTrack*)track); part->setTick(pos[1]); @@ -521,6 +522,7 @@ MusEWidget::CItem* PartCanvas::newItem(const QPoint& pos, int) switch(track->type()) { case Track::MIDI: case Track::DRUM: + case Track::NEW_DRUM: pa = new MidiPart((MidiTrack*)track); pa->setTick(x); pa->setLenTick(0); @@ -659,6 +661,7 @@ QMenu* PartCanvas::genItemPopup(MusEWidget::CItem* item) act_mexport->setData(16); } break; + case Track::NEW_DRUM: case Track::DRUM: { partPopup->addAction(MusEGlobal::muse->arranger()->parentWin->startDrumEditAction); partPopup->addAction(MusEGlobal::muse->arranger()->parentWin->startListEditAction); @@ -1259,6 +1262,7 @@ void PartCanvas::keyPress(QKeyEvent* event) // else track is midi switch (track->type()) { + case Track::NEW_DRUM: case Track::DRUM: type = 3; break; @@ -2302,7 +2306,7 @@ void PartCanvas::drawMidiPart(QPainter& p, const QRect&, EventList* events, Midi using std::pair; iEvent ito(events->lower_bound(to)); - bool isdrum = (mt->type() == Track::DRUM); + bool isdrum = (mt->type() == Track::DRUM || mt->type() == Track::NEW_DRUM); // draw controllers ------------------------------------------ p.setPen(QColor(192,192,color_brightness/2)); diff --git a/muse2/muse/arranger/tlist.cpp b/muse2/muse/arranger/tlist.cpp index 68f6dceb..c4a2094a 100644 --- a/muse2/muse/arranger/tlist.cpp +++ b/muse2/muse/arranger/tlist.cpp @@ -226,6 +226,9 @@ void TList::paint(const QRect& r) case Track::DRUM: bg = MusEConfig::config.drumTrackBg; break; + case Track::NEW_DRUM: + bg = MusEConfig::config.newDrumTrackBg; + break; case Track::WAVE: bg = MusEConfig::config.waveTrackBg; break; @@ -281,6 +284,7 @@ void TList::paint(const QRect& r) case Track::MIDI: pm = addtrack_addmiditrackIcon; break; + case Track::NEW_DRUM: case Track::DRUM: pm = addtrack_drumtrackIcon; break; @@ -585,6 +589,7 @@ void TList::portsPopupMenu(Track* t, int x, int y) switch(t->type()) { case Track::MIDI: case Track::DRUM: + case Track::NEW_DRUM: case Track::AUDIO_SOFTSYNTH: { MidiTrack* track = (MidiTrack*)t; @@ -739,7 +744,7 @@ void TList::oportPropertyPopupMenu(Track* t, int x, int y) } - if (t->type() != Track::MIDI && t->type() != Track::DRUM) + if (t->type() != Track::MIDI && t->type() != Track::DRUM && t->type() != Track::NEW_DRUM) return; int oPort = ((MidiTrack*)t)->outPort(); MidiPort* port = &midiPorts[oPort]; @@ -923,7 +928,8 @@ TrackList TList::getRecEnabledTracks() void TList::changeAutomation(QAction* act) { //printf("changeAutomation %d\n", act->data().toInt()); - if (editAutomation->type() == Track::MIDI) { + if (editAutomation->type() == Track::MIDI) { //FINDMICHJETZT is this correct? or should we also + //consider DRUM and NEW_DRUM? svn blame could help printf("this is wrong, we can't edit automation for midi tracks from arranger yet!\n"); return; } @@ -949,7 +955,7 @@ void TList::changeAutomation(QAction* act) //--------------------------------------------------------- void TList::changeAutomationColor(QAction* act) { - if (editAutomation->type() == Track::MIDI) { + if (editAutomation->type() == Track::MIDI) { //FINDMICHJETZT is this correct? see above printf("this is wrong, we can't edit automation for midi tracks from arranger yet!\n"); return; } @@ -1707,13 +1713,14 @@ void TList::classesPopupMenu(Track* t, int x, int y) p.clear(); p.addAction(QIcon(*addtrack_addmiditrackIcon), tr("Midi"))->setData(Track::MIDI); p.addAction(QIcon(*addtrack_drumtrackIcon), tr("Drum"))->setData(Track::DRUM); + p.addAction(QIcon(*addtrack_drumtrackIcon), tr("New style drum"))->setData(Track::NEW_DRUM); QAction* act = p.exec(mapToGlobal(QPoint(x, y)), 0); if (!act) return; int n = act->data().toInt(); - if (Track::TrackType(n) == Track::MIDI && t->type() == Track::DRUM) { + if ((Track::TrackType(n) == Track::MIDI || Track::TrackType(n) == Track::NEW_DRUM) && t->type() == Track::DRUM) { //FINDMICHJETZT passt das? // // Drum -> Midi // @@ -1747,11 +1754,11 @@ void TList::classesPopupMenu(Track* t, int x, int y) } } - t->setType(Track::MIDI); + t->setType(Track::TrackType(n)); audio->msgIdle(false); song->update(SC_EVENT_MODIFIED); } - else if (Track::TrackType(n) == Track::DRUM && t->type() == Track::MIDI) { + else if (Track::TrackType(n) == Track::DRUM && (t->type() == Track::MIDI || t->type() == Track::NEW_DRUM)) { //FINDMICHJETZT passt das? // // Midi -> Drum // @@ -1809,6 +1816,12 @@ void TList::classesPopupMenu(Track* t, int x, int y) audio->msgIdle(false); song->update(SC_EVENT_MODIFIED); } + else // MIDI -> NEW_DRUM or vice versa. added by flo. FINDMICHJETZT does this work properly? + { + Track* t2 = t->clone(false); + t->setType(Track::TrackType(n)); + audio->msgChangeTrack(t2, t, true); + } } } // namespace MusEArranger diff --git a/muse2/muse/conf.cpp b/muse2/muse/conf.cpp index 35b96591..e1d141e7 100644 --- a/muse2/muse/conf.cpp +++ b/muse2/muse/conf.cpp @@ -786,6 +786,8 @@ void readConfiguration(Xml& xml, bool readOnlySequencer, bool doReadGlobalConfig MusEConfig::config.midiTrackLabelBg = readColor(xml); else if (tag == "drumTrackLabelBg") MusEConfig::config.drumTrackLabelBg = readColor(xml); + else if (tag == "newDrumTrackLabelBg") + MusEConfig::config.newDrumTrackLabelBg = readColor(xml); else if (tag == "waveTrackLabelBg") MusEConfig::config.waveTrackLabelBg = readColor(xml); else if (tag == "outputTrackLabelBg") @@ -805,6 +807,8 @@ void readConfiguration(Xml& xml, bool readOnlySequencer, bool doReadGlobalConfig MusEConfig::config.ctrlGraphFg = readColor(xml); else if (tag == "drumTrackBg") MusEConfig::config.drumTrackBg = readColor(xml); + else if (tag == "newDrumTrackBg") + MusEConfig::config.newDrumTrackBg = readColor(xml); else if (tag == "waveTrackBg") MusEConfig::config.waveTrackBg = readColor(xml); else if (tag == "outputTrackBg") @@ -1317,6 +1321,7 @@ void MusE::writeGlobalConfiguration(int level, Xml& xml) const xml.colorTag(level, "mixerBg", MusEConfig::config.mixerBg); xml.colorTag(level, "midiTrackLabelBg", MusEConfig::config.midiTrackLabelBg); xml.colorTag(level, "drumTrackLabelBg", MusEConfig::config.drumTrackLabelBg); + xml.colorTag(level, "newDrumTrackLabelBg", MusEConfig::config.newDrumTrackLabelBg); xml.colorTag(level, "waveTrackLabelBg", MusEConfig::config.waveTrackLabelBg); xml.colorTag(level, "outputTrackLabelBg", MusEConfig::config.outputTrackLabelBg); xml.colorTag(level, "inputTrackLabelBg", MusEConfig::config.inputTrackLabelBg); @@ -1326,7 +1331,7 @@ void MusE::writeGlobalConfiguration(int level, Xml& xml) const xml.colorTag(level, "midiTrackBg", MusEConfig::config.midiTrackBg); xml.colorTag(level, "ctrlGraphFg", MusEConfig::config.ctrlGraphFg); - xml.colorTag(level, "drumTrackBg", MusEConfig::config.drumTrackBg); + xml.colorTag(level, "newDrumTrackBg", MusEConfig::config.newDrumTrackBg); xml.colorTag(level, "waveTrackBg", MusEConfig::config.waveTrackBg); xml.colorTag(level, "outputTrackBg", MusEConfig::config.outputTrackBg); xml.colorTag(level, "inputTrackBg", MusEConfig::config.inputTrackBg); @@ -1655,6 +1660,7 @@ void MixerConfig::write(int level, Xml& xml) xml.intTag(level, "showMidiTracks", showMidiTracks); xml.intTag(level, "showDrumTracks", showDrumTracks); + xml.intTag(level, "showNewDrumTracks", showNewDrumTracks); xml.intTag(level, "showInputTracks", showInputTracks); xml.intTag(level, "showOutputTracks", showOutputTracks); xml.intTag(level, "showWaveTracks", showWaveTracks); @@ -1692,6 +1698,8 @@ void MixerConfig::read(Xml& xml) showMidiTracks = xml.parseInt(); else if (tag == "showDrumTracks") showDrumTracks = xml.parseInt(); + else if (tag == "showNewDrumTracks") + showNewDrumTracks = xml.parseInt(); else if (tag == "showInputTracks") showInputTracks = xml.parseInt(); else if (tag == "showOutputTracks") diff --git a/muse2/muse/ctrl/ctrlcanvas.cpp b/muse2/muse/ctrl/ctrlcanvas.cpp index 7c77a836..fb4816f9 100644 --- a/muse2/muse/ctrl/ctrlcanvas.cpp +++ b/muse2/muse/ctrl/ctrlcanvas.cpp @@ -535,10 +535,10 @@ void CtrlCanvas::partControllers(const MidiPart* part, int num, int* dnum, int* int di; int n; - if((mt->type() != Track::DRUM) && curDrumInstrument != -1) + if((mt->type() != Track::DRUM) && curDrumInstrument != -1) //FINDMICHJETZT was ist das? printf("keyfilter != -1 in non drum track?\n"); - if((mt->type() == Track::DRUM) && (curDrumInstrument != -1) && ((num & 0xff) == 0xff)) + if((mt->type() == Track::DRUM) && (curDrumInstrument != -1) && ((num & 0xff) == 0xff)) //FINDMICHJETZT was ist das? { di = (num & ~0xff) | curDrumInstrument; n = (num & ~0xff) | drumMap[curDrumInstrument].anote; // construct real controller number @@ -1688,7 +1688,7 @@ void CtrlCanvas::pdrawItems(QPainter& p, const QRect& rect, const MidiPart* part MidiTrack* mt = part->track(); MidiPort* mp; - if((mt->type() == Track::DRUM) && (curDrumInstrument != -1) && ((_cnum & 0xff) == 0xff)) + if((mt->type() == Track::DRUM) && (curDrumInstrument != -1) && ((_cnum & 0xff) == 0xff)) //FINDMICHJETZT was ist das? mp = &midiPorts[drumMap[curDrumInstrument].port]; else mp = &midiPorts[mt->outPort()]; diff --git a/muse2/muse/ctrl/ctrlpanel.cpp b/muse2/muse/ctrl/ctrlpanel.cpp index cb18afad..ef2196fa 100644 --- a/muse2/muse/ctrl/ctrlpanel.cpp +++ b/muse2/muse/ctrl/ctrlpanel.cpp @@ -169,7 +169,7 @@ void CtrlPanel::heartBeat() int outport; int chan; int cdi = editor->curDrumInstrument(); - if(_track->type() == Track::DRUM && ((_ctrl->num() & 0xff) == 0xff) && cdi != -1) + if(_track->type() == Track::DRUM && ((_ctrl->num() & 0xff) == 0xff) && cdi != -1) //FINDMICHJETZT was ist das? und ähnliche dinger { outport = drumMap[cdi].port; chan = drumMap[cdi].channel; @@ -560,7 +560,7 @@ void CtrlPanel::ctrlPopup() int channel = track->outChannel(); MidiPort* port = &midiPorts[track->outPort()]; int curDrumInstrument = editor->curDrumInstrument(); - bool isDrum = track->type() == Track::DRUM; + bool isDrum = track->type() == Track::DRUM; //FINDMICHJETZT ist das wichtig? QMenu* pop = new QMenu; //pop->clear(); @@ -718,7 +718,7 @@ void CtrlPanel::ctrlPopup() int channel = track->outChannel(); MidiPort* port = &midiPorts[track->outPort()]; int curDrumInstrument = editor->curDrumInstrument(); - bool isDrum = track->type() == Track::DRUM; + bool isDrum = track->type() == Track::DRUM; //FINDMICHJETZT ist das wichtig? MidiInstrument* instr = port->instrument(); MidiControllerList* mcl = instr->controller(); diff --git a/muse2/muse/gconfig.cpp b/muse2/muse/gconfig.cpp index 0a521c3a..f8334b1e 100644 --- a/muse2/muse/gconfig.cpp +++ b/muse2/muse/gconfig.cpp @@ -103,6 +103,7 @@ GlobalConfigValues config = { QColor(74, 150, 194), // midiTrackLabelBg; // Med blue QColor(74, 150, 194), // drumTrackLabelBg; // Med blue + QColor(74, 150, 194), // newDrumTrackLabelBg; // Med blue QColor(213, 128, 202), // waveTrackLabelBg; // magenta QColor(84, 185, 58), // outputTrackLabelBg; // green QColor(199, 75, 64), // inputTrackLabelBg; // red @@ -112,6 +113,7 @@ GlobalConfigValues config = { QColor(215, 220, 230), // midiTrackBg; QColor(215, 220, 230), // drumTrackBg; + QColor(215, 220, 230), // newDrumTrackBg; QColor(220, 209, 217), // waveTrackBg; QColor(197, 220, 206), // outputTrackBg; QColor(220, 214, 206), // inputTrackBg; @@ -149,13 +151,13 @@ GlobalConfigValues config = { QString("Mixer A"), QRect(0, 0, 300, 500), // Mixer1 true, true, true, true, - true, true, true, true + true, true, true, true, true }, { QString("Mixer B"), QRect(200, 200, 300, 500), // Mixer2 true, true, true, true, - true, true, true, true + true, true, true, true, true }, true, // TransportVisible; false, // BigTimeVisible; diff --git a/muse2/muse/gconfig.h b/muse2/muse/gconfig.h index dd5f10fd..0d173b26 100644 --- a/muse2/muse/gconfig.h +++ b/muse2/muse/gconfig.h @@ -45,6 +45,7 @@ struct MixerConfig { QRect geometry; bool showMidiTracks; bool showDrumTracks; + bool showNewDrumTracks; bool showInputTracks; bool showOutputTracks; bool showWaveTracks; @@ -81,6 +82,7 @@ struct GlobalConfigValues { QColor midiTrackLabelBg; QColor drumTrackLabelBg; + QColor newDrumTrackLabelBg; QColor waveTrackLabelBg; QColor outputTrackLabelBg; QColor inputTrackLabelBg; @@ -90,6 +92,7 @@ struct GlobalConfigValues { QColor midiTrackBg; QColor drumTrackBg; + QColor newDrumTrackBg; QColor waveTrackBg; QColor outputTrackBg; QColor inputTrackBg; diff --git a/muse2/muse/helper.cpp b/muse2/muse/helper.cpp index 255e8505..2c128ef3 100644 --- a/muse2/muse/helper.cpp +++ b/muse2/muse/helper.cpp @@ -285,26 +285,44 @@ QActionGroup* populateAddTrack(QMenu* addTrack) QT_TRANSLATE_NOOP("@default", "Add Midi Track")); midi->setData(Track::MIDI); grp->addAction(midi); + + QAction* drum = addTrack->addAction(QIcon(*addtrack_drumtrackIcon), QT_TRANSLATE_NOOP("@default", "Add Drum Track")); drum->setData(Track::DRUM); grp->addAction(drum); + + + QAction* newdrum = addTrack->addAction(QIcon(*addtrack_drumtrackIcon), + QT_TRANSLATE_NOOP("@default", "Add New Style Drum Track")); + newdrum->setData(Track::NEW_DRUM); + grp->addAction(newdrum); + + QAction* wave = addTrack->addAction(QIcon(*addtrack_wavetrackIcon), QT_TRANSLATE_NOOP("@default", "Add Wave Track")); wave->setData(Track::WAVE); grp->addAction(wave); + + QAction* aoutput = addTrack->addAction(QIcon(*addtrack_audiooutputIcon), QT_TRANSLATE_NOOP("@default", "Add Audio Output")); aoutput->setData(Track::AUDIO_OUTPUT); grp->addAction(aoutput); + + QAction* agroup = addTrack->addAction(QIcon(*addtrack_audiogroupIcon), QT_TRANSLATE_NOOP("@default", "Add Audio Group")); agroup->setData(Track::AUDIO_GROUP); grp->addAction(agroup); + + QAction* ainput = addTrack->addAction(QIcon(*addtrack_audioinputIcon), QT_TRANSLATE_NOOP("@default", "Add Audio Input")); ainput->setData(Track::AUDIO_INPUT); grp->addAction(ainput); + + QAction* aaux = addTrack->addAction(QIcon(*addtrack_auxsendIcon), QT_TRANSLATE_NOOP("@default", "Add Aux Send")); aaux->setData(Track::AUDIO_AUX); diff --git a/muse2/muse/importmidi.cpp b/muse2/muse/importmidi.cpp index 558ffb69..0e09ecfa 100644 --- a/muse2/muse/importmidi.cpp +++ b/muse2/muse/importmidi.cpp @@ -181,7 +181,7 @@ bool MusE::importMidi(const QString name, bool merge) MidiTrack* track = new MidiTrack(); if ((*t)->isDrumTrack) - track->setType(Track::DRUM); + track->setType(Track::DRUM); //FINDMICHJETZT track->setOutChannel(channel); track->setOutPort(port); @@ -200,7 +200,7 @@ bool MusE::importMidi(const QString name, bool merge) // Hmm. buildMidiEventList already takes care of this. // But it seems to work. How? Must test. if (channel == 9 && song->mtype() != MT_UNKNOWN) { - track->setType(Track::DRUM); + track->setType(Track::DRUM); //FINDMICHJETZT // // remap drum pitch with drumInmap // diff --git a/muse2/muse/liste/editevent.cpp b/muse2/muse/liste/editevent.cpp index e211e7f7..702e61e5 100644 --- a/muse2/muse/liste/editevent.cpp +++ b/muse2/muse/liste/editevent.cpp @@ -617,7 +617,7 @@ EditCtrlDialog::EditCtrlDialog(int tick, const Event& event, MidiTrack* track = part->track(); int portn = track->outPort(); MidiPort* port = &midiPorts[portn]; - bool isDrum = track->type() == Track::DRUM; + bool isDrum = track->type() == Track::DRUM; //FINDMICHJETZT was soll das? MidiCtrlValListList* cll = port->controller(); ctrlList->clear(); @@ -833,7 +833,7 @@ void EditCtrlDialog::updatePatch() int port = track->outPort(); int channel = track->outChannel(); MidiInstrument* instr = midiPorts[port].instrument(); - patchName->setText(instr->getPatchName(channel, val, song->mtype(), track->type() == Track::DRUM)); + patchName->setText(instr->getPatchName(channel, val, song->mtype(), track->type() == Track::DRUM)); //FINDMICHJETZT was soll das? int hb = ((val >> 16) & 0xff) + 1; if (hb == 0x100) @@ -872,7 +872,7 @@ void EditCtrlDialog::instrPopup() ///instr->populatePatchPopup(pop, channel, song->mtype(), track->type() == Track::DRUM); //QMenu* pup = new QMenu(this); MusEWidget::PopupMenu* pup = new MusEWidget::PopupMenu(this); - instr->populatePatchPopup(pup, channel, song->mtype(), track->type() == Track::DRUM); + instr->populatePatchPopup(pup, channel, song->mtype(), track->type() == Track::DRUM); //FINDMICHJETZT was soll das? ///if(pop->actions().count() == 0) /// return; diff --git a/muse2/muse/midi.cpp b/muse2/muse/midi.cpp index 39642348..5d7fe560 100644 --- a/muse2/muse/midi.cpp +++ b/muse2/muse/midi.cpp @@ -254,7 +254,7 @@ void buildMidiEventList(EventList* del, const MPEventList* el, MidiTrack* track, case ME_NOTEON: e.setType(Note); - if (track->type() == Track::DRUM) { + if (track->type() == Track::DRUM) { //FINDMICHJETZT int instr = drumInmap[ev.dataA()]; e.setPitch(instr); } @@ -268,7 +268,7 @@ void buildMidiEventList(EventList* del, const MPEventList* el, MidiTrack* track, break; case ME_NOTEOFF: e.setType(Note); - if (track->type() == Track::DRUM) { + if (track->type() == Track::DRUM) { //FINDMICHJETZT int instr = drumInmap[ev.dataA()]; e.setPitch(instr); } @@ -370,7 +370,7 @@ void buildMidiEventList(EventList* del, const MPEventList* el, MidiTrack* track, int ctl = ev.dataA(); e.setA(ctl); - if(track->type() == Track::DRUM) + if(track->type() == Track::DRUM) //FINDMICHJETZT drum controller? { // Is it a drum controller event, according to the track port's instrument? MidiController *mc = midiPorts[track->outPort()].drumController(ctl); @@ -723,7 +723,7 @@ void Audio::collectEvents(MidiTrack* track, unsigned int cts, unsigned int nts) // if (ev.type() == Meta) continue; - if (track->type() == Track::DRUM) { + if (track->type() == Track::DRUM) { //FINDMICHJETZT ignore muted int instr = ev.pitch(); // ignore muted drums if (ev.isNote() && drumMap[instr].mute) @@ -747,7 +747,7 @@ void Audio::collectEvents(MidiTrack* track, unsigned int cts, unsigned int nts) channel = drumMap[instr].channel; velo = int(double(velo) * (double(drumMap[instr].vol) / 100.0)) ; } - else { + else { //FINDMICHJETZT don't transpose for new style drum tracks // // transpose non drum notes // @@ -800,7 +800,7 @@ void Audio::collectEvents(MidiTrack* track, unsigned int cts, unsigned int nts) case Controller: { - if (track->type() == Track::DRUM) + if (track->type() == Track::DRUM) //FINDMICHJETZT was ist das? drumcontroller -_- { int ctl = ev.dataA(); // Is it a drum controller event, according to the track port's instrument? @@ -972,7 +972,7 @@ void Audio::processMidi() // //Apply drum inkey: - if (track->type() == Track::DRUM) + if (track->type() == Track::DRUM) //FINDMICHJETZT schwierig... { int pitch = event.dataA(); //Map note that is played according to drumInmap @@ -1009,7 +1009,7 @@ void Audio::processMidi() else if(event.type() == ME_CONTROLLER) { - if(track->type() == Track::DRUM) + if(track->type() == Track::DRUM) //FINDMICHJETZT was ist das? { ctl = event.dataA(); // Regardless of what port the event came from, is it a drum controller event @@ -1072,7 +1072,7 @@ void Audio::processMidi() // to the track port so buildMidiEventList will accept it. Even though // the port may have no device "<none>". // - if (track->type() == Track::DRUM) + if (track->type() == Track::DRUM) //FINDMICHJETZT was ist das? { // Is it a drum controller event? if(mc) diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index e82ab7ad..a06d2a8c 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -4591,6 +4591,14 @@ void ScoreCanvas::add_new_parts(const std::map< Part*, std::set<Part*> >& param) * from clipboard failed. ignoring this one... ) [ not reproducible ] * * CURRENT TODO + * o in appearance.cpp: add the new stuff for drumTrackLabelBg and drumTrackBg + * o find and fix FINDMICHJETZT + * o fix all segfaults and non-working stuff! + * - creating, changing types to and from, erasing NEW_DRUM tracks + * - move parts around + * - playing them. mute? + * - recording/echoing/steprec them + * - load, save them * o fix valgrind problems * * > o drum editor: channel-stuff diff --git a/muse2/muse/mixer/amixer.cpp b/muse2/muse/mixer/amixer.cpp index 18fe926f..082b9461 100644 --- a/muse2/muse/mixer/amixer.cpp +++ b/muse2/muse/mixer/amixer.cpp @@ -183,6 +183,7 @@ AudioMixerApp::AudioMixerApp(QWidget* parent, MusEConfig::MixerConfig* c) showMidiTracksId = new QAction(tr("Show Midi Tracks"), actionItems); showDrumTracksId = new QAction(tr("Show Drum Tracks"), actionItems); + showNewDrumTracksId = new QAction(tr("Show New Style Drum Tracks"), actionItems); showWaveTracksId = new QAction(tr("Show Wave Tracks"), actionItems); QAction *separator = new QAction(this); @@ -197,6 +198,7 @@ AudioMixerApp::AudioMixerApp(QWidget* parent, MusEConfig::MixerConfig* c) showMidiTracksId->setCheckable(true); showDrumTracksId->setCheckable(true); + showNewDrumTracksId->setCheckable(true); showWaveTracksId->setCheckable(true); showInputTracksId->setCheckable(true); showOutputTracksId->setCheckable(true); @@ -208,6 +210,7 @@ AudioMixerApp::AudioMixerApp(QWidget* parent, MusEConfig::MixerConfig* c) //connect(actionItems, SIGNAL(selected(QAction*)), this, SLOT(showTracksChanged(QAction*))); connect(showMidiTracksId, SIGNAL(triggered(bool)), SLOT(showMidiTracksChanged(bool))); connect(showDrumTracksId, SIGNAL(triggered(bool)), SLOT(showDrumTracksChanged(bool))); + connect(showNewDrumTracksId, SIGNAL(triggered(bool)), SLOT(showNewDrumTracksChanged(bool))); connect(showWaveTracksId, SIGNAL(triggered(bool)), SLOT(showWaveTracksChanged(bool))); connect(showInputTracksId, SIGNAL(triggered(bool)), SLOT(showInputTracksChanged(bool))); connect(showOutputTracksId, SIGNAL(triggered(bool)), SLOT(showOutputTracksChanged(bool))); @@ -349,6 +352,7 @@ void AudioMixerApp::updateMixer(UpdateAction action) showMidiTracksId->setChecked(cfg->showMidiTracks); showDrumTracksId->setChecked(cfg->showDrumTracks); + showNewDrumTracksId->setChecked(cfg->showNewDrumTracks); showInputTracksId->setChecked(cfg->showInputTracks); showOutputTracksId->setChecked(cfg->showOutputTracks); showWaveTracksId->setChecked(cfg->showWaveTracks); @@ -428,7 +432,7 @@ void AudioMixerApp::updateMixer(UpdateAction action) for (iMidiTrack i = mtl->begin(); i != mtl->end(); ++i) { MidiTrack* mt = *i; - if((mt->type() == Track::MIDI && cfg->showMidiTracks) || (mt->type() == Track::DRUM && cfg->showDrumTracks)) + if((mt->type() == Track::MIDI && cfg->showMidiTracks) || (mt->type() == Track::DRUM && cfg->showDrumTracks) || (mt->type() == Track::NEW_DRUM && cfg->showNewDrumTracks)) addStrip(*i, idx++); } @@ -485,7 +489,7 @@ void AudioMixerApp::updateMixer(UpdateAction action) for (iMidiTrack i = mtl->begin(); i != mtl->end(); ++i) { MidiTrack* mt = *i; - if((mt->type() == Track::MIDI && cfg->showMidiTracks) || (mt->type() == Track::DRUM && cfg->showDrumTracks)) + if((mt->type() == Track::MIDI && cfg->showMidiTracks) || (mt->type() == Track::DRUM && cfg->showDrumTracks) || (mt->type() == Track::NEW_DRUM && cfg->showNewDrumTracks)) addStrip(*i, idx++); } @@ -627,6 +631,8 @@ void AudioMixerApp::showTracksChanged(QAction* id) cfg->showMidiTracks = val; else if (id == showDrumTracksId) cfg->showDrumTracks = val; + else if (id == showNewDrumTracksId) + cfg->showNewDrumTracks = val; else if (id == showInputTracksId) cfg->showInputTracks = val; else if (id == showOutputTracksId) @@ -655,6 +661,12 @@ void AudioMixerApp::showDrumTracksChanged(bool v) updateMixer(UPDATE_ALL); } +void AudioMixerApp::showNewDrumTracksChanged(bool v) +{ + cfg->showNewDrumTracks = v; + updateMixer(UPDATE_ALL); +} + void AudioMixerApp::showWaveTracksChanged(bool v) { cfg->showWaveTracks = v; @@ -710,6 +722,7 @@ void AudioMixerApp::write(int level, Xml& xml) xml.intTag(level, "showMidiTracks", cfg->showMidiTracks); xml.intTag(level, "showDrumTracks", cfg->showDrumTracks); + xml.intTag(level, "showNewDrumTracks", cfg->showNewDrumTracks); xml.intTag(level, "showInputTracks", cfg->showInputTracks); xml.intTag(level, "showOutputTracks", cfg->showOutputTracks); xml.intTag(level, "showWaveTracks", cfg->showWaveTracks); diff --git a/muse2/muse/mixer/amixer.h b/muse2/muse/mixer/amixer.h index 5be12659..60a77f12 100644 --- a/muse2/muse/mixer/amixer.h +++ b/muse2/muse/mixer/amixer.h @@ -101,6 +101,7 @@ class AudioMixerApp : public QMainWindow { QAction* showMidiTracksId; QAction* showDrumTracksId; + QAction* showNewDrumTracksId; QAction* showInputTracksId; QAction* showOutputTracksId; QAction* showWaveTracksId; @@ -134,6 +135,7 @@ class AudioMixerApp : public QMainWindow { //void showTracksChanged(QAction*); void showMidiTracksChanged(bool); void showDrumTracksChanged(bool); + void showNewDrumTracksChanged(bool); void showWaveTracksChanged(bool); void showInputTracksChanged(bool); void showOutputTracksChanged(bool); diff --git a/muse2/muse/mixer/strip.cpp b/muse2/muse/mixer/strip.cpp index 59149222..67594e3a 100644 --- a/muse2/muse/mixer/strip.cpp +++ b/muse2/muse/mixer/strip.cpp @@ -150,6 +150,10 @@ void Strip::setLabelText() //c = QColor(0, 160, 255); // Med blue c = MusEConfig::config.drumTrackLabelBg; break; + case Track::NEW_DRUM: + //c = QColor(0, 160, 255); // Med blue + c = MusEConfig::config.newDrumTrackLabelBg; + break; default: return; } diff --git a/muse2/muse/part.cpp b/muse2/muse/part.cpp index 6d273c82..2d9111f7 100644 --- a/muse2/muse/part.cpp +++ b/muse2/muse/part.cpp @@ -401,7 +401,7 @@ void addPortCtrlEvents(Event& event, Part* part, bool doClones) MidiPort* mp = &midiPorts[port]; // Is it a drum controller event, according to the track port's instrument? - if(mt->type() == Track::DRUM) + if(mt->type() == Track::DRUM) //FINDMICHJETZT was ist das? { MidiController* mc = mp->drumController(cntrl); if(mc) @@ -469,7 +469,7 @@ void addPortCtrlEvents(Part* part, bool doClones) MidiPort* mp = &midiPorts[port]; // Is it a drum controller event, according to the track port's instrument? - if(mt->type() == Track::DRUM) + if(mt->type() == Track::DRUM) //FINDMICHJETZT was ist das? { MidiController* mc = mp->drumController(cntrl); if(mc) @@ -528,7 +528,7 @@ void removePortCtrlEvents(Event& event, Part* part, bool doClones) MidiPort* mp = &midiPorts[port]; // Is it a drum controller event, according to the track port's instrument? - if(mt->type() == Track::DRUM) + if(mt->type() == Track::DRUM) //FINDMICHJETZT was ist das? { MidiController* mc = mp->drumController(cntrl); if(mc) @@ -597,7 +597,7 @@ void removePortCtrlEvents(Part* part, bool doClones) MidiPort* mp = &midiPorts[port]; // Is it a drum controller event, according to the track port's instrument? - if(mt->type() == Track::DRUM) + if(mt->type() == Track::DRUM) //FINDMICHJETZT was ist das? { MidiController* mc = mp->drumController(cntrl); if(mc) @@ -913,6 +913,7 @@ void Song::cmdResizePart(Track* track, Part* oPart, unsigned int len, bool doClo break; case Track::MIDI: case Track::DRUM: + case Track::NEW_DRUM: { Undo operations; @@ -959,6 +960,7 @@ void Track::splitPart(Part* part, int tickpos, Part*& p1, Part*& p2) break; case MIDI: case DRUM: + case NEW_DRUM: l1 = tickpos - part->tick(); l2 = part->lenTick() - l1; break; @@ -982,6 +984,7 @@ void Track::splitPart(Part* part, int tickpos, Part*& p1, Part*& p2) break; case MIDI: case DRUM: + case NEW_DRUM: p1->setLenTick(l1); p2->setTick(tickpos); p2->setLenTick(l2); diff --git a/muse2/muse/remote/pyapi.cpp b/muse2/muse/remote/pyapi.cpp index 27a44e49..ff88ca23 100644 --- a/muse2/muse/remote/pyapi.cpp +++ b/muse2/muse/remote/pyapi.cpp @@ -695,7 +695,8 @@ PyObject* getAudioTrackVolume(PyObject*, PyObject* args) if (t == NULL) return NULL; - if (t->type() == Track::DRUM || t->type() == Track::MIDI) + //if (t->type() == Track::DRUM || t->type() == Track::MIDI || t->type() == Track::NEW_DRUM) + if (t->isMidiTrack()) // changed by flo. should do the same thing and is better maintainable return NULL; AudioTrack* track = (AudioTrack*) t; @@ -1089,7 +1090,8 @@ bool Song::event(QEvent* _e) if (t == NULL) return false; - if (t->type() == Track::DRUM || t->type() == Track::MIDI) + if (t->isMidiTrack()) // changed by flo. is better maintainable + //if (t->type() == Track::DRUM || t->type() == Track::NEW_DRUM || t->type() == Track::MIDI) return false; AudioTrack* track = (AudioTrack*) t; diff --git a/muse2/muse/shortcuts.cpp b/muse2/muse/shortcuts.cpp index 2270befa..a8cd8062 100644 --- a/muse2/muse/shortcuts.cpp +++ b/muse2/muse/shortcuts.cpp @@ -98,6 +98,7 @@ void initShortCuts() defShrt(SHRT_OPEN_MIDI_TRANSFORM, Qt::CTRL + Qt::Key_T, "Open midi transformer", ARRANG_SHRT, "open_midi_transform"); defShrt(SHRT_ADD_MIDI_TRACK, Qt::CTRL + Qt::Key_J, "Add midi track", ARRANG_SHRT, "add_midi_track"); defShrt(SHRT_ADD_DRUM_TRACK, 0, "Add drum track", ARRANG_SHRT, "add_drum_track"); + defShrt(SHRT_ADD_NEW_STYLE_DRUM_TRACK, 0, "Add new style drum track", ARRANG_SHRT, "add_new_style_drum_track"); defShrt(SHRT_ADD_WAVE_TRACK, 0, "Add wave track", ARRANG_SHRT, "add_wave_track"); defShrt(SHRT_ADD_AUDIO_OUTPUT, 0, "Add audio output", ARRANG_SHRT, "add_audio_output"); defShrt(SHRT_ADD_AUDIO_GROUP, 0, "Add audio group", ARRANG_SHRT, "add_audio_group"); diff --git a/muse2/muse/shortcuts.h b/muse2/muse/shortcuts.h index 451c4ec3..37e8b507 100644 --- a/muse2/muse/shortcuts.h +++ b/muse2/muse/shortcuts.h @@ -172,6 +172,7 @@ enum { SHRT_ADD_MIDI_TRACK, //Default: Ctrl+J SHRT_ADD_DRUM_TRACK, //Default: undefined + SHRT_ADD_NEW_STYLE_DRUM_TRACK, //Default: undefined SHRT_ADD_WAVE_TRACK, //Default: undefined SHRT_ADD_AUDIO_OUTPUT, //Default: undefined SHRT_ADD_AUDIO_GROUP, //Default: undefined diff --git a/muse2/muse/song.cpp b/muse2/muse/song.cpp index db2bcad5..dca43681 100644 --- a/muse2/muse/song.cpp +++ b/muse2/muse/song.cpp @@ -238,6 +238,11 @@ Track* Song::addTrack(Track::TrackType type, Track* insertAt) track = new MidiTrack(); track->setType(Track::MIDI); break; + case Track::NEW_DRUM: + track = new MidiTrack(); + track->setType(Track::NEW_DRUM); + ((MidiTrack*)track)->setOutChannel(9); + break; case Track::DRUM: track = new MidiTrack(); track->setType(Track::DRUM); @@ -315,7 +320,7 @@ Track* Song::addTrack(Track::TrackType type, Track* insertAt) { defOutFound = true; mt->setOutPort(i); - if(type != Track::DRUM) // p4.0.17 Leave drum tracks at channel 10. + if(type != Track::DRUM && type != Track::NEW_DRUM) // p4.0.17 Leave drum tracks at channel 10. mt->setOutChannel(ch); updateFlags |= SC_ROUTE; break; @@ -336,6 +341,7 @@ Track* Song::addTrack(Track::TrackType type, Track* insertAt) switch(type) { //case Track::MIDI: //case Track::DRUM: + //case Track::NEW_DRUM: //case Track::AUDIO_OUTPUT: // break; @@ -435,7 +441,7 @@ bool Song::addEvent(Event& event, Part* part) MidiPort* mp = &midiPorts[track->outPort()]; // Is it a drum controller event, according to the track port's instrument? - if(track->type() == Track::DRUM) + if(track->type() == Track::DRUM) //FINDMICHJETZT was ist das? { MidiController* mc = mp->drumController(cntrl); if(mc) @@ -508,7 +514,7 @@ void Song::changeEvent(Event& oldEvent, Event& newEvent, Part* part) int cntrl = oldEvent.dataA(); MidiPort* mp = &midiPorts[track->outPort()]; // Is it a drum controller event, according to the track port's instrument? - if(track->type() == Track::DRUM) + if(track->type() == Track::DRUM) //FINDMICHJETZT was ist das? { MidiController* mc = mp->drumController(cntrl); if(mc) @@ -535,7 +541,7 @@ void Song::changeEvent(Event& oldEvent, Event& newEvent, Part* part) int val = newEvent.dataB(); MidiPort* mp = &midiPorts[track->outPort()]; // Is it a drum controller event, according to the track port's instrument? - if(track->type() == Track::DRUM) + if(track->type() == Track::DRUM) //FINDMICHJETZT was ist das? { MidiController* mc = mp->drumController(cntrl); if(mc) @@ -569,7 +575,7 @@ void Song::deleteEvent(Event& event, Part* part) MidiPort* mp = &midiPorts[track->outPort()]; // Is it a drum controller event, according to the track port's instrument? - if(track->type() == Track::DRUM) + if(track->type() == Track::DRUM) //FINDMICHJETZT was ist das? { MidiController* mc = mp->drumController(cntrl); if(mc) @@ -610,7 +616,7 @@ void Song::remapPortDrumCtrlEvents(int mapidx, int newnote, int newchan, int new for(ciMidiTrack it = _midis.begin(); it != _midis.end(); ++it) { MidiTrack* mt = *it; - if(mt->type() != Track::DRUM) + if(mt->type() != Track::DRUM) //FINDMICHJETZT was ist das? drumcontroller? continue; MidiPort* trackmp = &midiPorts[mt->outPort()]; @@ -624,6 +630,7 @@ void Song::remapPortDrumCtrlEvents(int mapidx, int newnote, int newchan, int new { const Event& ev = ie->second; // Added by T356. Do not handle events which are past the end of the part. + //FINDMICHJETZT why not? if(ev.tick() >= len) break; @@ -680,7 +687,7 @@ void Song::changeAllPortDrumCtrlEvents(bool add, bool drumonly) for(ciMidiTrack it = _midis.begin(); it != _midis.end(); ++it) { MidiTrack* mt = *it; - if(mt->type() != Track::DRUM) + if(mt->type() != Track::DRUM) //FINDMICHJETZT was ist das? drumcontroller continue; trackmp = &midiPorts[mt->outPort()]; @@ -3351,6 +3358,7 @@ void Song::insertTrack2(Track* track, int idx) switch(track->type()) { case Track::MIDI: case Track::DRUM: + case Track::NEW_DRUM: _midis.push_back((MidiTrack*)track); // Added by T356. //((MidiTrack*)track)->addPortCtrlEvents(); @@ -3601,6 +3609,7 @@ void Song::removeTrack2(Track* track) switch(track->type()) { case Track::MIDI: case Track::DRUM: + case Track::NEW_DRUM: // Added by T356. //((MidiTrack*)track)->removePortCtrlEvents(); removePortCtrlEvents(((MidiTrack*)track)); diff --git a/muse2/muse/songfile.cpp b/muse2/muse/songfile.cpp index 344ecc89..c430ed1e 100644 --- a/muse2/muse/songfile.cpp +++ b/muse2/muse/songfile.cpp @@ -719,7 +719,7 @@ void Part::read(Xml& xml, int, bool toTrack) // int newPartOffset newPartOffset=this->tick(); int ctl = e.dataA(); - if(mt->type() == Track::DRUM) + if(mt->type() == Track::DRUM) //FINDMICHJETZT commented out: was ist das? { // Is it a drum controller event, according to the track port's instrument? MidiController* mc = mp->drumController(ctl); @@ -1403,6 +1403,12 @@ void Song::read(Xml& xml, bool isTemplate) track->read(xml); insertTrack0(track, -1); } + else if (tag == "newdrumtrack") { + MidiTrack* track = new MidiTrack(); + track->setType(Track::NEW_DRUM); + track->read(xml); + insertTrack0(track, -1); + } else if (tag == "wavetrack") { WaveTrack* track = new WaveTrack(); track->read(xml); diff --git a/muse2/muse/track.cpp b/muse2/muse/track.cpp index 90e9beec..58c53f63 100644 --- a/muse2/muse/track.cpp +++ b/muse2/muse/track.cpp @@ -43,8 +43,8 @@ bool Track::_tmpSoloChainDoIns = false; bool Track::_tmpSoloChainNoDec = false; const char* Track::_cname[] = { - "Midi", "Drum", "Wave", "AudioOut", "AudioIn", "AudioGroup", - "AudioAux", "AudioSynth" + "Midi", "Drum", "NewStyleDrum", "Wave", + "AudioOut", "AudioIn", "AudioGroup", "AudioAux", "AudioSynth" }; //--------------------------------------------------------- @@ -75,7 +75,7 @@ void addPortCtrlEvents(MidiTrack* t) MidiPort* mp = &midiPorts[t->outPort()]; // Is it a drum controller event, according to the track port's instrument? - if(t->type() == Track::DRUM) + if(t->type() == Track::DRUM) //FINDMICHJETZT was soll das? drumcontroller -_- { MidiController* mc = mp->drumController(cntrl); if(mc) @@ -123,7 +123,7 @@ void removePortCtrlEvents(MidiTrack* t) MidiPort* mp = &midiPorts[t->outPort()]; // Is it a drum controller event, according to the track port's instrument? - if(t->type() == Track::DRUM) + if(t->type() == Track::DRUM) //FINDMICHJETZT was soll das? drumcontroller... { MidiController* mc = mp->drumController(cntrl); if(mc) @@ -239,7 +239,8 @@ Track::Track(const Track& t, bool cloneParts) // A couple of schemes were conceived to deal with cloneList being invalid, but the best way is // to not alter the part list here. It's a big headache because: Either the parts in the cloneList // need to be reliably looked up replaced with the new ones, or the clipboard and cloneList must be cleared. - // Fortunately the ONLY part of muse using this function is track rename (in TrackList and TrackInfo). + // Fortunately the ONLY parts of muse using this function are track rename (in TrackList and TrackInfo) and + // changing track type from MIDI to NEW_DRUM or vice versa (NOT something -> DRUM or vice versa). // So we can get away with leaving this out: //for (iPart ip = _parts.begin(); ip != _parts.end(); ++ip) // ip->second->setTrack(this); @@ -311,6 +312,7 @@ void Track::setDefaultName() switch(_type) { case MIDI: case DRUM: + case NEW_DRUM: case WAVE: base = QString("Track"); break; @@ -469,7 +471,7 @@ MidiTrack::~MidiTrack() void MidiTrack::init() { _outPort = 0; - _outChannel = 0; + _outChannel = (type()==NEW_DRUM) ? 9 : 0; // Changed by Tim. p3.3.8 //_inPortMask = 0xffff; ///_inPortMask = 0xffffffff; @@ -643,7 +645,7 @@ void MidiTrack::addPortCtrlEvents() MidiPort* mp = &midiPorts[_outPort]; // Is it a drum controller event, according to the track port's instrument? - if(type() == DRUM) + if(type() == DRUM) //FINDMICHJETZT commented out. was soll das? { MidiController* mc = mp->drumController(cntrl); if(mc) @@ -684,7 +686,7 @@ void MidiTrack::removePortCtrlEvents() MidiPort* mp = &midiPorts[_outPort]; // Is it a drum controller event, according to the track port's instrument? - if(type() == DRUM) + if(type() == DRUM) //FINDMICHJETZT commented out: was soll das? { MidiController* mc = mp->drumController(cntrl); if(mc) @@ -941,8 +943,13 @@ void MidiTrack::write(int level, Xml& xml) const if (type() == DRUM) tag = "drumtrack"; - else + else if (type() == MIDI) tag = "miditrack"; + else if (type() == NEW_DRUM) + tag = "newdrumtrack"; + else + printf("THIS SHOULD NEVER HAPPEN: non-midi-type in MidiTrack::write()\n"); + xml.tag(level++, tag); Track::writeProperties(level, xml); diff --git a/muse2/muse/track.h b/muse2/muse/track.h index 752a79be..7ed30914 100644 --- a/muse2/muse/track.h +++ b/muse2/muse/track.h @@ -52,7 +52,7 @@ class DrumMap; class Track { public: enum TrackType { - MIDI=0, DRUM, WAVE, AUDIO_OUTPUT, AUDIO_INPUT, AUDIO_GROUP, + MIDI=0, DRUM, NEW_DRUM, WAVE, AUDIO_OUTPUT, AUDIO_INPUT, AUDIO_GROUP, AUDIO_AUX, AUDIO_SOFTSYNTH }; private: @@ -199,7 +199,7 @@ class Track { void setDefaultName(); int channels() const { return _channels; } virtual void setChannels(int n); - bool isMidiTrack() const { return type() == MIDI || type() == DRUM; } + bool isMidiTrack() const { return type() == MIDI || type() == DRUM || type() == NEW_DRUM; } virtual bool canRecord() const { return false; } virtual AutomationType automationType() const = 0; virtual void setAutomationType(AutomationType t) = 0; diff --git a/muse2/muse/widgets/mtrackinfo.cpp b/muse2/muse/widgets/mtrackinfo.cpp index 56429879..57674395 100644 --- a/muse2/muse/widgets/mtrackinfo.cpp +++ b/muse2/muse/widgets/mtrackinfo.cpp @@ -216,6 +216,7 @@ void MidiTrackInfo::heartBeat() { case Track::MIDI: case Track::DRUM: + case Track::NEW_DRUM: { MidiTrack* track = (MidiTrack*)selected; @@ -344,7 +345,7 @@ void MidiTrackInfo::heartBeat() else { MidiInstrument* instr = mp->instrument(); - QString name = instr->getPatchName(outChannel, nprogram, song->mtype(), track->type() == Track::DRUM); + QString name = instr->getPatchName(outChannel, nprogram, song->mtype(), track->type() == Track::DRUM); //FINDMICHJETZT was soll das? if(name.isEmpty()) { const QString n("???"); @@ -390,7 +391,7 @@ void MidiTrackInfo::heartBeat() //else //{ MidiInstrument* instr = mp->instrument(); - QString name = instr->getPatchName(outChannel, program, song->mtype(), track->type() == Track::DRUM); + QString name = instr->getPatchName(outChannel, program, song->mtype(), track->type() == Track::DRUM); //FINDMICHJETZT was soll das? if(iPatch->text() != name) iPatch->setText(name); @@ -567,8 +568,12 @@ void MidiTrackInfo::setLabelText() //pal.setColor(trackNameLabel->backgroundRole(), QColor(0, 160, 255)); // Med blue if(track->type() == Track::DRUM) c = MusEConfig::config.drumTrackLabelBg; - else + else if (track->type() == Track::MIDI) c = MusEConfig::config.midiTrackLabelBg; + else if (track->type() == Track::NEW_DRUM) + c = MusEConfig::config.newDrumTrackLabelBg; + else + printf("THIS SHOULD NEVER HAPPEN: track is not a MIDI track in MidiTrackInfo::setLabelText()!\n"); QLinearGradient gradient(trackNameLabel->geometry().topLeft(), trackNameLabel->geometry().bottomLeft()); //gradient.setColorAt(0, c.darker()); @@ -757,7 +762,7 @@ void MidiTrackInfo::iProgHBankChanged() audio->msgPlayMidiEvent(&ev); MidiInstrument* instr = mp->instrument(); - iPatch->setText(instr->getPatchName(channel, program, song->mtype(), track->type() == Track::DRUM)); + iPatch->setText(instr->getPatchName(channel, program, song->mtype(), track->type() == Track::DRUM)); //FINDMICHJETZT was soll das? // updateTrackInfo(); } @@ -835,7 +840,7 @@ void MidiTrackInfo::iProgLBankChanged() audio->msgPlayMidiEvent(&ev); MidiInstrument* instr = mp->instrument(); - iPatch->setText(instr->getPatchName(channel, program, song->mtype(), track->type() == Track::DRUM)); + iPatch->setText(instr->getPatchName(channel, program, song->mtype(), track->type() == Track::DRUM)); //FINDMICHJETZT was soll das? // updateTrackInfo(); } @@ -913,7 +918,7 @@ void MidiTrackInfo::iProgramChanged() audio->msgPlayMidiEvent(&ev); MidiInstrument* instr = mp->instrument(); - iPatch->setText(instr->getPatchName(channel, program, song->mtype(), track->type() == Track::DRUM)); + iPatch->setText(instr->getPatchName(channel, program, song->mtype(), track->type() == Track::DRUM)); //FINDMICHJETZT was soll das? } // updateTrackInfo(); @@ -1082,7 +1087,7 @@ void MidiTrackInfo::instrPopup() PopupMenu* pup = new PopupMenu(true); //instr->populatePatchPopup(pop, channel, song->mtype(), track->type() == Track::DRUM); - instr->populatePatchPopup(pup, channel, song->mtype(), track->type() == Track::DRUM); + instr->populatePatchPopup(pup, channel, song->mtype(), track->type() == Track::DRUM); //FINDMICHJETZT was soll das? //if(pop->actions().count() == 0) // return; @@ -1406,7 +1411,7 @@ void MidiTrackInfo::updateTrackInfo(int flags) else { MidiInstrument* instr = mp->instrument(); - iPatch->setText(instr->getPatchName(outChannel, nprogram, song->mtype(), track->type() == Track::DRUM)); + iPatch->setText(instr->getPatchName(outChannel, nprogram, song->mtype(), track->type() == Track::DRUM)); //FINDMICHJETZT was soll das? } } else @@ -1422,7 +1427,7 @@ void MidiTrackInfo::updateTrackInfo(int flags) //else //{ MidiInstrument* instr = mp->instrument(); - iPatch->setText(instr->getPatchName(outChannel, program, song->mtype(), track->type() == Track::DRUM)); + iPatch->setText(instr->getPatchName(outChannel, program, song->mtype(), track->type() == Track::DRUM)); //FINDMICHJETZT was soll das? int hb = ((program >> 16) & 0xff) + 1; if (hb == 0x100) diff --git a/muse2/muse/widgets/musewidgetsplug.cpp b/muse2/muse/widgets/musewidgetsplug.cpp index 3ebd1aa5..01cc68b3 100644 --- a/muse2/muse/widgets/musewidgetsplug.cpp +++ b/muse2/muse/widgets/musewidgetsplug.cpp @@ -131,6 +131,7 @@ GlobalConfigValues config = { QColor(0, 160, 255), // midiTrackLabelBg; // Med blue QColor(0, 160, 255), // drumTrackLabelBg; // Med blue + QColor(0, 160, 255), // newDrumTrackLabelBg; // Med blue Qt::magenta, // waveTrackLabelBg; Qt::green, // outputTrackLabelBg; Qt::red, // inputTrackLabelBg; @@ -140,6 +141,7 @@ GlobalConfigValues config = { QColor(220, 220, 220), // midiTrackBg; QColor(220, 220, 220), // drumTrackBg; + QColor(220, 220, 220), // newDrumTrackBg; QColor(220, 220, 220), // waveTrackBg; QColor(189, 220, 193), // outputTrackBg; QColor(189, 220, 193), // inputTrackBg; @@ -178,13 +180,13 @@ GlobalConfigValues config = { QString("Mixer A"), QRect(0, 0, 300, 500), // Mixer1 true, true, true, true, - true, true, true, true + true, true, true, true, true }, { QString("Mixer B"), QRect(200, 200, 300, 500), // Mixer2 true, true, true, true, - true, true, true, true + true, true, true, true, true }, true, // TransportVisible; false, // BigTimeVisible; -- cgit v1.2.3 From 375d6a53630f364c6560eb40255a8cc4c0496b8c Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Fri, 7 Oct 2011 14:55:42 +0000 Subject: fixed small bug in tlist.cpp --- muse2/muse/arranger/tlist.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/arranger/tlist.cpp b/muse2/muse/arranger/tlist.cpp index c4a2094a..73c8eec7 100644 --- a/muse2/muse/arranger/tlist.cpp +++ b/muse2/muse/arranger/tlist.cpp @@ -928,8 +928,7 @@ TrackList TList::getRecEnabledTracks() void TList::changeAutomation(QAction* act) { //printf("changeAutomation %d\n", act->data().toInt()); - if (editAutomation->type() == Track::MIDI) { //FINDMICHJETZT is this correct? or should we also - //consider DRUM and NEW_DRUM? svn blame could help + if ( (editAutomation->type() == Track::MIDI) || (editAutomation->type() == Track::DRUM) || (editAutomation->type() == Track::NEW_DRUM) ) { printf("this is wrong, we can't edit automation for midi tracks from arranger yet!\n"); return; } -- cgit v1.2.3 From 9e6dc222b92bbfba58756d3be47890dd885b8f71 Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Sat, 8 Oct 2011 14:10:24 +0000 Subject: muted instruments in new style drum tracks are now respected --- muse2/muse/midi.cpp | 8 +++++++- muse2/muse/track.h | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/midi.cpp b/muse2/muse/midi.cpp index e927674f..65bccc70 100644 --- a/muse2/muse/midi.cpp +++ b/muse2/muse/midi.cpp @@ -730,12 +730,18 @@ void Audio::collectEvents(MusECore::MidiTrack* track, unsigned int cts, unsigned // if (ev.type() == Meta) continue; - if (track->type() == Track::DRUM) { //FINDMICHJETZT ignore muted + if (track->type() == Track::DRUM) { int instr = ev.pitch(); // ignore muted drums if (ev.isNote() && MusEGlobal::drumMap[instr].mute) continue; } + else if (track->type() == Track::NEW_DRUM) { + int instr = ev.pitch(); + // ignore muted drums + if (ev.isNote() && track->drummap()[instr].mute) + continue; + } unsigned tick = ev.tick() + offset; unsigned frame = MusEGlobal::tempomap.tick2frame(tick) + frameOffset; switch (ev.type()) { diff --git a/muse2/muse/track.h b/muse2/muse/track.h index 9d3db8af..0911b4f1 100644 --- a/muse2/muse/track.h +++ b/muse2/muse/track.h @@ -229,7 +229,7 @@ class MidiTrack : public Track { static bool _isVisible; clefTypes clefType; - DrumMap* _drummap; + DrumMap* _drummap; // _drummap[foo].anote is always equal to foo bool _drummap_tied_to_patch; //if true, changing patch also changes drummap bool* _drummap_hidden; -- cgit v1.2.3 From 159a2b58fd28c7a00b9b723dcea77e6c2ec2e874 Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Sun, 9 Oct 2011 13:20:51 +0000 Subject: updated MidiTrack::read and ::write --- muse2/muse/midiedit/drummap.cpp | 9 ++ muse2/muse/midiedit/drummap.h | 1 + muse2/muse/midiedit/scoreedit.cpp | 6 +- muse2/muse/track.cpp | 245 ++++++++++++++++++++++++++++++++++---- muse2/muse/track.h | 9 +- 5 files changed, 246 insertions(+), 24 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/midiedit/drummap.cpp b/muse2/muse/midiedit/drummap.cpp index 43e66345..47232011 100644 --- a/muse2/muse/midiedit/drummap.cpp +++ b/muse2/muse/midiedit/drummap.cpp @@ -43,6 +43,15 @@ namespace MusECore { const DrumMap blankdm = { QString(""), 100, 16, 32, 9, 0, 70, 90, 127, 110, 127, 127, false }; +// this map must have 128 entries, as it's used for initalising new-style-drummaps as well. +// new-style-drummaps only have 128 entries. also, the every "out-note" ("anote") must be +// represented exactly once in that map, and there may be no duplicate or unused "out-notes". +// reason: the track's drummap are inited as follows: iterate through the full idrumMap[], +// tracks_drummap[ idrumMap[i].anote ] = idrumMap[i] +// if you ever want to change this, you will need to go through track.cpp/.h and +// {dlist,dcanvas,drumedit,drummap}{.cpp,.h} (and possibly some more) and find every usage +// of idrumMap by new style drummaps, and fix the problem. a possible fix would be duplicating +// idrumMap, change idrumMap, and use the duplicate for the new style stuff instead. const DrumMap idrumMap[DRUM_MAPSIZE] = { { QString("Acoustic Bass Drum"), 100, 16, 32, 9, 0, 70, 90, 127, 110, 35, 35, false }, { QString("Bass Drum 1"), 100, 16, 32, 9, 0, 70, 90, 127, 110, 36, 36, false }, diff --git a/muse2/muse/midiedit/drummap.h b/muse2/muse/midiedit/drummap.h index f3186afa..3b6ffaf3 100644 --- a/muse2/muse/midiedit/drummap.h +++ b/muse2/muse/midiedit/drummap.h @@ -51,6 +51,7 @@ struct DrumMap { bool operator!=(const DrumMap& map) const { return !operator==(map); } }; +// please let this at "128". idrumMap must have length 128 (see drummap.cpp for details) #define DRUM_MAPSIZE 128 extern const DrumMap idrumMap[DRUM_MAPSIZE]; //FINDMICH dummy! diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index 5770ee6c..8f647966 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -4608,7 +4608,7 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo * o clearly state in the changelog: when having multiple drumeditors open, * the mute-column may not work, because another editor is overriding this. * o respect "_drummap_tied_to_patch": IMPLEMENT - * o save hide, ordering, track's drumlists + * o allow loading and saving track-drumlists to external files * 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) @@ -4616,11 +4616,13 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo * 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 + * x save hide, ordering, track's drumlists * * x 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= + * * update [midi]track::read/write, readproperties, writeprop... (drumlist etc), operator= + * _should_ be okay, but i'm not sure * * IMPORTANT TODO * o all places where i added doubleclick-edits: only react on left-click double clicks! diff --git a/muse2/muse/track.cpp b/muse2/muse/track.cpp index 32344b6e..e24ddad9 100644 --- a/muse2/muse/track.cpp +++ b/muse2/muse/track.cpp @@ -405,19 +405,7 @@ MidiTrack::MidiTrack() _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]; - - MusEGlobal::global_drum_ordering.push_back(std::pair<MidiTrack*,int>(this,idx)); - } - for (int i=0;i<128;i++) - _drummap_hidden[i]=false; - + init_drummap(true /* write drummap ordering information as well */); } //MidiTrack::MidiTrack(const MidiTrack& mt) @@ -460,16 +448,18 @@ MidiTrack::~MidiTrack() delete [] _drummap; delete [] _drummap_hidden; - // remove ourselves from the global_drum_ordering list - // this is not really necessary, but cleaner - for (MusEGlobal::global_drum_ordering_t::iterator it=MusEGlobal::global_drum_ordering.begin(); it!=MusEGlobal::global_drum_ordering.end();) - if (it->first == this) - it=MusEGlobal::global_drum_ordering.erase(it); - else - it++; - + remove_ourselves_from_drum_ordering(); } +void MidiTrack::remove_ourselves_from_drum_ordering() +{ + for (MusEGlobal::global_drum_ordering_t::iterator it=MusEGlobal::global_drum_ordering.begin(); it!=MusEGlobal::global_drum_ordering.end();) + if (it->first == this) + it=MusEGlobal::global_drum_ordering.erase(it); + else + it++; +} + //--------------------------------------------------------- // init //--------------------------------------------------------- @@ -491,6 +481,26 @@ void MidiTrack::init() _recEcho = true; } +void MidiTrack::init_drummap(bool write_ordering) +{ + 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]; + + if (write_ordering) + MusEGlobal::global_drum_ordering.push_back(std::pair<MidiTrack*,int>(this,idx)); + } + + for (int i=0;i<128;i++) + _drummap_hidden[i]=false; +} + + + //--------------------------------------------------------- // height //--------------------------------------------------------- @@ -793,9 +803,77 @@ void MidiTrack::write(int level, Xml& xml) const const PartList* pl = cparts(); for (ciPart p = pl->begin(); p != pl->end(); ++p) p->second->write(level, xml); + + writeOurDrumSettings(level, xml); + xml.etag(level, tag); } +void MidiTrack::writeOurDrumSettings(int level, Xml& xml) const +{ + xml.tag(level++, "our_drum_settings"); + + xml.intTag(level, "tied", _drummap_tied_to_patch); + + writeOurDrumMap(level, xml); + + xml.etag(level, "our_drum_settings"); +} + +void MidiTrack::writeOurDrumMap(int level, Xml& xml) const +{ + xml.tag(level++, "our_drummap"); + + for (int i=0;i<128;i++) + { + int j; + for (j=0;j<128;j++) + if (idrumMap[j].anote == i) break; + + if (j==128) + printf("THIS SHOULD NEVER HAPPEN: couldn't find initial drum map entry in MidiTrack::writeOurDrumMap()\n"); + else + { + DrumMap* dm = &_drummap[i]; + const DrumMap* idm = &idrumMap[j]; + + if ( (dm->name != idm->name) || (dm->vol != idm->vol) || + (dm->quant != idm->quant) || (dm->len != idm->len) || + (dm->lv1 != idm->lv1) || (dm->lv2 != idm->lv2) || + (dm->lv3 != idm->lv3) || (dm->lv4 != idm->lv4) || + (dm->enote != idm->enote) || (dm->mute != idm->mute) || + _drummap_hidden[i] ) + { + xml.tag(level++, "entry pitch=\"%d\"", i); + + // when any of these "if"s changes, also update the large "if" + // above (this scope's parent) + if (dm->name != idm->name) xml.strTag(level, "name", dm->name); + if (dm->vol != idm->vol) xml.intTag(level, "vol", dm->vol); + if (dm->quant != idm->quant) xml.intTag(level, "quant", dm->quant); + if (dm->len != idm->len) xml.intTag(level, "len", dm->len); + if (dm->lv1 != idm->lv1) xml.intTag(level, "lv1", dm->lv1); + if (dm->lv2 != idm->lv2) xml.intTag(level, "lv2", dm->lv2); + if (dm->lv3 != idm->lv3) xml.intTag(level, "lv3", dm->lv3); + if (dm->lv4 != idm->lv4) xml.intTag(level, "lv4", dm->lv4); + if (dm->enote != idm->enote) xml.intTag(level, "enote", dm->enote); + if (dm->mute != idm->mute) xml.intTag(level, "mute", dm->mute); + if (_drummap_hidden[i]) xml.intTag(level, "hide", _drummap_hidden[i]); + + // anote is ignored anyway, as dm->anote == i, and this is + // already stored in the begin tag (pitch=...) + + // channel and port are ignored as well, as they're not used + // in new-style-drum-mode + + xml.tag(level--, "/entry"); + } + } + } + + xml.etag(level, "our_drummap"); +} + //--------------------------------------------------------- // MidiTrack::read //--------------------------------------------------------- @@ -852,6 +930,8 @@ void MidiTrack::read(Xml& xml) setAutomationType(AutomationType(xml.parseInt())); else if (tag == "clef") clefType = (clefTypes)xml.parseInt(); + else if (tag == "our_drum_settings") + readOurDrumSettings(xml); else if (Track::readProperties(xml, tag)) { // version 1.0 compatibility: if (tag == "track" && xml.majorVersion() == 1 && xml.minorVersion() == 0) @@ -873,6 +953,129 @@ void MidiTrack::read(Xml& xml) } } +void MidiTrack::readOurDrumSettings(Xml& xml) +{ + for (;;) + { + Xml::Token token = xml.parse(); + if (token == Xml::Error || token == Xml::End) + break; + const QString& tag = xml.s1(); + switch (token) + { + case Xml::TagStart: + if (tag == "tied") + _drummap_tied_to_patch = xml.parseInt(); + else if (tag == "our_drummap") + readOurDrumMap(xml); + else + xml.unknown("MidiTrack::readOurDrumSettings"); + break; + + case Xml::TagEnd: + if (tag == "our_drum_settings") + return; + + default: + break; + } + } +} + +void MidiTrack::readOurDrumMap(Xml& xml) +{ + init_drummap(false); + + for (;;) + { + Xml::Token token = xml.parse(); + if (token == Xml::Error || token == Xml::End) + break; + const QString& tag = xml.s1(); + switch (token) + { + case Xml::TagStart: + if (tag == "entry") // then read that entry with a nested loop + { + DrumMap* dm=NULL; + bool* hidden=NULL; + for (;;) // nested loop + { + Xml::Token token = xml.parse(); + const QString& tag = xml.s1(); + switch (token) + { + case Xml::Error: + case Xml::End: + goto end_of_nested_for; + + case Xml::Attribut: + if (tag == "pitch") + { + int pitch = xml.s2().toInt() & 0x7f; + if (pitch < 0 || pitch > 127) + printf("ERROR: THIS SHOULD NEVER HAPPEN: invalid pitch in MidiTrack::readOurDrumMap()!\n"); + else + { + dm = &_drummap[pitch]; + hidden = &_drummap_hidden[pitch]; + } + } + break; + + case Xml::TagStart: + if (dm==NULL) + printf("ERROR: THIS SHOULD NEVER HAPPEN: no valid 'pitch' attribute in <entry> tag, but sub-tags follow in MidiTrack::readOurDrumMap()!\n"); + else if (tag == "name") + dm->name = xml.parse(QString("name")); + else if (tag == "vol") + dm->vol = (unsigned char)xml.parseInt(); + else if (tag == "quant") + dm->quant = xml.parseInt(); + else if (tag == "len") + dm->len = xml.parseInt(); + else if (tag == "lv1") + dm->lv1 = xml.parseInt(); + else if (tag == "lv2") + dm->lv2 = xml.parseInt(); + else if (tag == "lv3") + dm->lv3 = xml.parseInt(); + else if (tag == "lv4") + dm->lv4 = xml.parseInt(); + else if (tag == "enote") + dm->enote = xml.parseInt(); + else if (tag == "mute") + dm->mute = xml.parseInt(); + else if (tag == "hide") + *hidden = xml.parseInt(); + else + xml.unknown("MidiTrack::readOurDrumMap"); + break; + + case Xml::TagEnd: + if (tag == "entry") + goto end_of_nested_for; + + default: + break; + } + } // end of nested loop + end_of_nested_for: ; + } // end of 'if (tag == "entry")' + else + xml.unknown("MidiTrack::readOurDrumMap"); + break; + + case Xml::TagEnd: + if (tag == "our_drummap") + return; + + default: + break; + } + } +} + //--------------------------------------------------------- // addPart diff --git a/muse2/muse/track.h b/muse2/muse/track.h index 0911b4f1..a958ca74 100644 --- a/muse2/muse/track.h +++ b/muse2/muse/track.h @@ -230,10 +230,17 @@ class MidiTrack : public Track { clefTypes clefType; DrumMap* _drummap; // _drummap[foo].anote is always equal to foo + bool* _drummap_hidden; // _drummap und _drummap_hidden will be an array[128] bool _drummap_tied_to_patch; //if true, changing patch also changes drummap - bool* _drummap_hidden; void init(); + void init_drummap(bool write_ordering=false); + void remove_ourselves_from_drum_ordering(); + + void writeOurDrumSettings(int level, Xml& xml) const; + void writeOurDrumMap(int level, Xml& xml) const; + void readOurDrumSettings(Xml& xml); + void readOurDrumMap(Xml& xml); public: MidiTrack(); -- cgit v1.2.3 From 9a4a4ee6fd5c2a73216240da912f7273aacaa11e Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Sun, 9 Oct 2011 16:02:35 +0000 Subject: recording and importing midi now works for new style drum tracks plus fixes for old-style drum tracks --- muse2/muse/importmidi.cpp | 14 +++++++++----- muse2/muse/midi.cpp | 17 ++++++++--------- muse2/muse/midiedit/dcanvas.cpp | 6 +++++- muse2/muse/midiedit/dcanvas.h | 2 +- muse2/muse/midiedit/dlist.cpp | 6 +++--- muse2/muse/track.cpp | 14 ++++++++++++-- muse2/muse/track.h | 5 ++++- 7 files changed, 42 insertions(+), 22 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/importmidi.cpp b/muse2/muse/importmidi.cpp index 593ddb79..90e8cecb 100644 --- a/muse2/muse/importmidi.cpp +++ b/muse2/muse/importmidi.cpp @@ -181,7 +181,8 @@ bool MusE::importMidi(const QString name, bool merge) MusECore::MidiTrack* track = new MusECore::MidiTrack(); if ((*t)->isDrumTrack) - track->setType(MusECore::Track::DRUM); //FINDMICHJETZT + track->setType(MusECore::Track::NEW_DRUM); //FINDMICHJETZT config option + //track->setType(MusECore::Track::DRUM); track->setOutChannel(channel); track->setOutPort(port); @@ -200,15 +201,17 @@ bool MusE::importMidi(const QString name, bool merge) // Hmm. buildMidiEventList already takes care of this. // But it seems to work. How? Must test. if (channel == 9 && MusEGlobal::song->mtype() != MT_UNKNOWN) { - track->setType(MusECore::Track::DRUM); //FINDMICHJETZT + track->setType(MusECore::Track::NEW_DRUM); //FINDMICHJETZT config option + /* + track->setType(MusECore::Track::DRUM); // - // remap drum pitch with drumInmap + // remap drum pitch with drumOutmap // MusECore::EventList* tevents = track->events(); for (MusECore::iEvent i = tevents->begin(); i != tevents->end(); ++i) { MusECore::Event ev = i->second; if (ev.isNote()) { - int pitch = MusEGlobal::drumInmap[ev.pitch()]; + int pitch = MusEGlobal::drumOutmap[ev.pitch()]; ev.setPitch(pitch); } else @@ -217,9 +220,10 @@ bool MusE::importMidi(const QString name, bool merge) int ctl = ev.dataA(); MusECore::MidiController *mc = mport->drumController(ctl); if(mc) - ev.setA((ctl & ~0xff) | MusEGlobal::drumInmap[ctl & 0x7f]); + ev.setA((ctl & ~0xff) | MusEGlobal::drumOutmap[ctl & 0x7f]); } } + */ } processTrack(track); diff --git a/muse2/muse/midi.cpp b/muse2/muse/midi.cpp index 65bccc70..0138f1d8 100644 --- a/muse2/muse/midi.cpp +++ b/muse2/muse/midi.cpp @@ -262,9 +262,7 @@ void buildMidiEventList(EventList* del, const MPEventList* el, MidiTrack* track, e.setPitch(instr); } else - { e.setPitch(ev.dataA()); - } e.setVelo(ev.dataB()); e.setLenTick(0); @@ -277,6 +275,7 @@ void buildMidiEventList(EventList* del, const MPEventList* el, MidiTrack* track, } else e.setPitch(ev.dataA()); + e.setVelo(0); e.setVeloOff(ev.dataB()); e.setLenTick(0); @@ -751,19 +750,15 @@ void Audio::collectEvents(MusECore::MidiTrack* track, unsigned int cts, unsigned int pitch = ev.pitch(); int velo = ev.velo(); if (track->type() == Track::DRUM) { - // // Map drum-notes to the drum-map values - // int instr = ev.pitch(); pitch = MusEGlobal::drumMap[instr].anote; port = MusEGlobal::drumMap[instr].port; //This changes to non-default port channel = MusEGlobal::drumMap[instr].channel; velo = int(double(velo) * (double(MusEGlobal::drumMap[instr].vol) / 100.0)) ; } - else { //FINDMICHJETZT don't transpose for new style drum tracks - // + else if (track->type() != Track::NEW_DRUM) { // transpose non drum notes - // pitch += (track->transposition + MusEGlobal::song->globalPitchShift()); } @@ -985,7 +980,7 @@ void Audio::processMidi() // //Apply drum inkey: - if (track->type() == Track::DRUM) //FINDMICHJETZT schwierig... + if (track->type() == Track::DRUM) //FINDMICHJETZT does this work? { int pitch = event.dataA(); //Map note that is played according to MusEGlobal::drumInmap @@ -996,7 +991,11 @@ void Audio::processMidi() event.setA(MusEGlobal::drumMap[(unsigned int)MusEGlobal::drumInmap[pitch]].anote); event.setChannel(channel); } - else + else if (track->type() == Track::NEW_DRUM) + { + event.setA(track->map_drum_in(event.dataA())); + } + else { //Track transpose if non-drum prePitch = event.dataA(); int pitch = prePitch + track->transposition; diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp index 22db70d0..7daaff29 100644 --- a/muse2/muse/midiedit/dcanvas.cpp +++ b/muse2/muse/midiedit/dcanvas.cpp @@ -1306,13 +1306,17 @@ int DrumCanvas::pitch_and_track_to_instrument(int pitch, MusECore::Track* track) return -1; } -void DrumCanvas::propagate_drummap_change(int instr) +void DrumCanvas::propagate_drummap_change(int instr, bool update_druminmap) { const QSet<MusECore::Track*>& tracks=instrument_map[instr].tracks; int index=instrument_map[instr].pitch; for (QSet<MusECore::Track*>::const_iterator it = tracks.begin(); it != tracks.end(); it++) + { dynamic_cast<MusECore::MidiTrack*>(*it)->drummap()[index] = ourDrumMap[instr]; + if (update_druminmap) + dynamic_cast<MusECore::MidiTrack*>(*it)->update_drum_in_map(); + } } diff --git a/muse2/muse/midiedit/dcanvas.h b/muse2/muse/midiedit/dcanvas.h index 581de9d7..2911862e 100644 --- a/muse2/muse/midiedit/dcanvas.h +++ b/muse2/muse/midiedit/dcanvas.h @@ -166,7 +166,7 @@ class DrumCanvas : public EventCanvas { MusECore::DrumMap* getOurDrumMap() { return ourDrumMap; } //FINDMICH UGLY int getOurDrumMapSize() { return instrument_map.size(); } //FINDMICH UGLY QVector<instrument_number_mapping_t>& get_instrument_map() { return instrument_map; } //FINDMICH UGLY - void propagate_drummap_change(int instrument); //FINDMICH move to drumedit + void propagate_drummap_change(int instrument, bool update_druminmap); //FINDMICH move to drumedit void rebuildOurDrumMap(); }; diff --git a/muse2/muse/midiedit/dlist.cpp b/muse2/muse/midiedit/dlist.cpp index 4ad971e7..3399b78e 100644 --- a/muse2/muse/midiedit/dlist.cpp +++ b/muse2/muse/midiedit/dlist.cpp @@ -517,7 +517,7 @@ void DList::viewMousePressEvent(QMouseEvent* ev) } if (!old_style_drummap_mode && dm_old != *dm) //something changed and we're in new style mode? - dcanvas->propagate_drummap_change(dm-ourDrumMap); + dcanvas->propagate_drummap_change(dm-ourDrumMap, (dm_old.enote != dm->enote)); MusEGlobal::song->update(SC_DRUMMAP); //redraw(); //this is done by the songChanged slot @@ -787,7 +787,7 @@ void DList::returnPressed() } if (editEntryOld != *editEntry) - dcanvas->propagate_drummap_change(editEntry-ourDrumMap); + dcanvas->propagate_drummap_change(editEntry-ourDrumMap, false); selectedColumn = -1; editor->hide(); @@ -854,7 +854,7 @@ void DList::pitchEdited() } if (editEntryOld != *editEntry) - dcanvas->propagate_drummap_change(editEntry-ourDrumMap); + dcanvas->propagate_drummap_change(editEntry-ourDrumMap, (editEntryOld.enote!=editEntry->enote)); selectedColumn = -1; pitch_editor->hide(); diff --git a/muse2/muse/track.cpp b/muse2/muse/track.cpp index e24ddad9..8f213616 100644 --- a/muse2/muse/track.cpp +++ b/muse2/muse/track.cpp @@ -431,6 +431,7 @@ MidiTrack::MidiTrack(const MidiTrack& mt, bool cloneParts) _drummap_hidden=new bool[128]; memcpy(_drummap, mt._drummap, 128*sizeof(*_drummap)); memcpy(_drummap_hidden, mt._drummap_hidden, 128*sizeof(*_drummap_hidden)); + update_drum_in_map(); for (MusEGlobal::global_drum_ordering_t::iterator it=MusEGlobal::global_drum_ordering.begin(); it!=MusEGlobal::global_drum_ordering.end(); it++) if (it->first == &mt) @@ -495,11 +496,17 @@ void MidiTrack::init_drummap(bool write_ordering) MusEGlobal::global_drum_ordering.push_back(std::pair<MidiTrack*,int>(this,idx)); } + update_drum_in_map(); + for (int i=0;i<128;i++) _drummap_hidden[i]=false; } - +void MidiTrack::update_drum_in_map() +{ + for (int i=0;i<127;i++) + drum_in_map[_drummap[i].enote]=i; +} //--------------------------------------------------------- // height @@ -966,7 +973,7 @@ void MidiTrack::readOurDrumSettings(Xml& xml) case Xml::TagStart: if (tag == "tied") _drummap_tied_to_patch = xml.parseInt(); - else if (tag == "our_drummap") + else if (tag == "our_drummap") readOurDrumMap(xml); else xml.unknown("MidiTrack::readOurDrumSettings"); @@ -1068,7 +1075,10 @@ void MidiTrack::readOurDrumMap(Xml& xml) case Xml::TagEnd: if (tag == "our_drummap") + { + update_drum_in_map(); return; + } default: break; diff --git a/muse2/muse/track.h b/muse2/muse/track.h index a958ca74..73f18cc2 100644 --- a/muse2/muse/track.h +++ b/muse2/muse/track.h @@ -232,7 +232,8 @@ class MidiTrack : public Track { DrumMap* _drummap; // _drummap[foo].anote is always equal to foo bool* _drummap_hidden; // _drummap und _drummap_hidden will be an array[128] bool _drummap_tied_to_patch; //if true, changing patch also changes drummap - + int drum_in_map[128]; + void init(); void init_drummap(bool write_ordering=false); void remove_ourselves_from_drum_ordering(); @@ -311,6 +312,8 @@ class MidiTrack : public Track { DrumMap* drummap() { return _drummap; } bool* drummap_hidden() { return _drummap_hidden; } + int map_drum_in(int enote) { return drum_in_map[enote]; } + void update_drum_in_map(); }; } // namespace MusECore -- cgit v1.2.3 From 0e67ba1af056a0df0b6b01c70bb6cb12063479a8 Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Sun, 9 Oct 2011 17:10:21 +0000 Subject: settings for importing midi --- muse2/muse/conf.cpp | 3 + muse2/muse/gconfig.cpp | 1 + muse2/muse/gconfig.h | 1 + muse2/muse/importmidi.cpp | 21 +- muse2/muse/midiedit/scoreedit.cpp | 3 + muse2/muse/widgets/configmidifilebase.ui | 491 +++++++++++++++++-------------- muse2/muse/widgets/musewidgetsplug.cpp | 1 + 7 files changed, 285 insertions(+), 236 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/conf.cpp b/muse2/muse/conf.cpp index 027ad431..22259041 100644 --- a/muse2/muse/conf.cpp +++ b/muse2/muse/conf.cpp @@ -1610,6 +1610,8 @@ void MidiFileConfig::updateValues() optNoteOffs->setChecked(MusEGlobal::config.expOptimNoteOffs); twoByteTimeSigs->setChecked(MusEGlobal::config.exp2ByteTimeSigs); splitPartsCheckBox->setChecked(MusEGlobal::config.importMidiSplitParts); + newDrumsCheckbox->setChecked(MusEGlobal::config.importMidiNewStyleDrum); + oldDrumsCheckbox->setChecked(!MusEGlobal::config.importMidiNewStyleDrum); } //--------------------------------------------------------- @@ -1629,6 +1631,7 @@ void MidiFileConfig::okClicked() MusEGlobal::config.expOptimNoteOffs = optNoteOffs->isChecked(); MusEGlobal::config.exp2ByteTimeSigs = twoByteTimeSigs->isChecked(); MusEGlobal::config.importMidiSplitParts = splitPartsCheckBox->isChecked(); + MusEGlobal::config.importMidiNewStyleDrum = newDrumsCheckbox->isChecked(); MusEGlobal::muse->changeConfig(true); // write config file close(); diff --git a/muse2/muse/gconfig.cpp b/muse2/muse/gconfig.cpp index 65397fe4..8aff870d 100644 --- a/muse2/muse/gconfig.cpp +++ b/muse2/muse/gconfig.cpp @@ -140,6 +140,7 @@ MusEGui::GlobalConfigValues config = { false, // midi export file 2 byte timesigs instead of 4 true, // optimize midi export file note offs true, // Split imported tracks into multiple parts. + true, // importMidiNewStyleDrum 1, // startMode QString(""), // start song path 384, // gui division diff --git a/muse2/muse/gconfig.h b/muse2/muse/gconfig.h index a6b55557..cf205eba 100644 --- a/muse2/muse/gconfig.h +++ b/muse2/muse/gconfig.h @@ -121,6 +121,7 @@ struct GlobalConfigValues { bool exp2ByteTimeSigs; // Export 2 byte time sigs instead of 4 bytes bool expOptimNoteOffs; // Save space by replacing note offs with note on velocity 0 bool importMidiSplitParts; // Split imported tracks into multiple parts. + bool importMidiNewStyleDrum; // Use new style drum tracks int startMode; // 0 - start with last song // 1 - start with default template diff --git a/muse2/muse/importmidi.cpp b/muse2/muse/importmidi.cpp index 90e8cecb..86738fe4 100644 --- a/muse2/muse/importmidi.cpp +++ b/muse2/muse/importmidi.cpp @@ -181,8 +181,12 @@ bool MusE::importMidi(const QString name, bool merge) MusECore::MidiTrack* track = new MusECore::MidiTrack(); if ((*t)->isDrumTrack) - track->setType(MusECore::Track::NEW_DRUM); //FINDMICHJETZT config option - //track->setType(MusECore::Track::DRUM); + { + if (MusEGlobal::config.importMidiNewStyleDrum) + track->setType(MusECore::Track::NEW_DRUM); + else + track->setType(MusECore::Track::DRUM); + } track->setOutChannel(channel); track->setOutPort(port); @@ -201,12 +205,13 @@ bool MusE::importMidi(const QString name, bool merge) // Hmm. buildMidiEventList already takes care of this. // But it seems to work. How? Must test. if (channel == 9 && MusEGlobal::song->mtype() != MT_UNKNOWN) { - track->setType(MusECore::Track::NEW_DRUM); //FINDMICHJETZT config option - /* + if (MusEGlobal::config.importMidiNewStyleDrum) + track->setType(MusECore::Track::NEW_DRUM); + else + { track->setType(MusECore::Track::DRUM); - // + // remap drum pitch with drumOutmap - // MusECore::EventList* tevents = track->events(); for (MusECore::iEvent i = tevents->begin(); i != tevents->end(); ++i) { MusECore::Event ev = i->second; @@ -222,9 +227,9 @@ bool MusE::importMidi(const QString name, bool merge) if(mc) ev.setA((ctl & ~0xff) | MusEGlobal::drumOutmap[ctl & 0x7f]); } - } - */ } + } + } processTrack(track); diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index 8f647966..cf436465 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -4603,6 +4603,9 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo * - recording/echoing/steprec them * - load, save them * o fix valgrind problems + * x midi-import settings + * o support or handle duplicate enotes somehow! + * o steprec, test midi thru * * > o drum editor: channel-stuff * o clearly state in the changelog: when having multiple drumeditors open, diff --git a/muse2/muse/widgets/configmidifilebase.ui b/muse2/muse/widgets/configmidifilebase.ui index 920596ec..c050450c 100644 --- a/muse2/muse/widgets/configmidifilebase.ui +++ b/muse2/muse/widgets/configmidifilebase.ui @@ -1,238 +1,273 @@ <?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0" stdsetdef="1"> - <author></author> - <comment></comment> - <exportmacro></exportmacro> - <class>ConfigMidiFileBase</class> - <widget class="QDialog" name="ConfigMidiFileBase"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>548</width> - <height>353</height> - </rect> - </property> - <property name="windowTitle"> - <string>MusE: Config Midi File Import/Export</string> - </property> - <property name="sizeGripEnabled"> - <bool>true</bool> - </property> - <layout class="QVBoxLayout"> +<ui version="4.0"> + <class>ConfigMidiFileBase</class> + <widget class="QDialog" name="ConfigMidiFileBase"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>548</width> + <height>346</height> + </rect> + </property> + <property name="windowTitle"> + <string>MusE: Config Midi File Import/Export</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <layout class="QVBoxLayout"> + <item> + <widget class="QGroupBox" name="midiImportGroupBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Minimum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Import:</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> <item> - <widget class="QGroupBox" name="midiImportGroupBox"> - <property name="sizePolicy"> - <sizepolicy> - <hsizetype>5</hsizetype> - <vsizetype>1</vsizetype> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="title"> - <string>Import:</string> - </property> - <layout class="QGridLayout"> - <item row="0" column="0"> - <widget class="QCheckBox" name="splitPartsCheckBox"> - <property name="text"> - <string>Split tracks into &parts</string> - </property> - <property name="shortcut"> - <string>Alt+P</string> - </property> - <property name="toolTip" stdset="0"> - <string>Split tracks into parts, or one single part</string> - </property> - </widget> - </item> - </layout> - </widget> + <widget class="QCheckBox" name="splitPartsCheckBox"> + <property name="toolTip"> + <string>Split tracks into parts, or one single part</string> + </property> + <property name="text"> + <string>Split tracks into &parts</string> + </property> + <property name="shortcut"> + <string>Alt+P</string> + </property> + </widget> </item> <item> - <widget class="QGroupBox" name="midiExportGroupBox"> - <property name="sizePolicy"> - <sizepolicy> - <hsizetype>5</hsizetype> - <vsizetype>7</vsizetype> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QRadioButton" name="newDrumsCheckbox"> + <property name="text"> + <string>Use new-style drum tracks</string> </property> - <property name="title"> - <string>Export:</string> + <property name="checked"> + <bool>true</bool> </property> - <layout class="QGridLayout"> - <item row="2" column="1"> - <widget class="QLineEdit" name="copyrightEdit"/> - </item> - <item row="1" column="1"> - <widget class="QComboBox" name="divisionCombo"> - <item> - <property name="text"> - <string>96</string> - </property> - </item> - <item> - <property name="text"> - <string>192</string> - </property> - </item> - <item> - <property name="text"> - <string>384</string> - </property> - </item> - </widget> - </item> - <item row="3" column="0" rowspan="1" colspan="2"> - <widget class="QCheckBox" name="extendedFormat"> - <property name="enabled"> - <bool>true</bool> - </property> - <property name="text"> - <string>Enable extended smf format (currently not implemented)</string> - </property> - </widget> - </item> - <item row="4" column="0" rowspan="1" colspan="2"> - <widget class="QCheckBox" name="twoByteTimeSigs"> - <property name="text"> - <string>Use &2-byte time signatures instead of standard 4</string> - </property> - <property name="shortcut"> - <string>Alt+2</string> - </property> - </widget> - </item> - <item row="2" column="0"> - <widget class="QLabel" name="textLabel2"> - <property name="text"> - <string>Copyright:</string> - </property> - <property name="wordWrap"> - <bool>false</bool> - </property> - </widget> - </item> - <item row="0" column="0"> - <widget class="QLabel" name="textLabel3"> - <property name="text"> - <string>Format:</string> - </property> - <property name="wordWrap"> - <bool>false</bool> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="textLabel1"> - <property name="text"> - <string>Division:</string> - </property> - <property name="wordWrap"> - <bool>false</bool> - </property> - </widget> - </item> - <item row="5" column="0" rowspan="1" colspan="2"> - <widget class="QCheckBox" name="optNoteOffs"> - <property name="text"> - <string>Save space by replacing note-offs with &zero velocity note-ons</string> - </property> - <property name="shortcut"> - <string>Alt+Z</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QComboBox" name="formatCombo"> - <item> - <property name="text"> - <string>0 (single track)</string> - </property> - </item> - <item> - <property name="text"> - <string>1 (multiple tracks)</string> - </property> - </item> - </widget> - </item> - </layout> - </widget> - </item> - <item> - <layout class="QHBoxLayout"> - <property name="margin"> - <number>0</number> + </widget> + </item> + <item> + <widget class="QRadioButton" name="oldDrumsCheckbox"> + <property name="text"> + <string>Use old-style drum tracks</string> </property> - <property name="spacing"> - <number>6</number> - </property> - <item> - <spacer name="Horizontal Spacing2"> - <property name="sizeHint"> - <size> - <width>20</width> - <height>20</height> - </size> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Expanding</enum> - </property> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - </spacer> - </item> - <item> - <widget class="QPushButton" name="buttonOk"> - <property name="text"> - <string>&OK</string> - </property> - <property name="shortcut"> - <string/> - </property> - <property name="autoDefault"> - <bool>true</bool> - </property> - <property name="default"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="buttonCancel"> - <property name="text"> - <string>&Cancel</string> - </property> - <property name="shortcut"> - <string/> - </property> - <property name="autoDefault"> - <bool>true</bool> - </property> - </widget> - </item> - </layout> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="midiExportGroupBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Export:</string> + </property> + <layout class="QGridLayout"> + <item row="2" column="1"> + <widget class="QLineEdit" name="copyrightEdit"/> + </item> + <item row="1" column="1"> + <widget class="QComboBox" name="divisionCombo"> + <item> + <property name="text"> + <string>96</string> + </property> + </item> + <item> + <property name="text"> + <string>192</string> + </property> + </item> + <item> + <property name="text"> + <string>384</string> + </property> + </item> + </widget> + </item> + <item row="3" column="0" colspan="2"> + <widget class="QCheckBox" name="extendedFormat"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="text"> + <string>Enable extended smf format (currently not implemented)</string> + </property> + </widget> + </item> + <item row="4" column="0" colspan="2"> + <widget class="QCheckBox" name="twoByteTimeSigs"> + <property name="text"> + <string>Use &2-byte time signatures instead of standard 4</string> + </property> + <property name="shortcut"> + <string>Alt+2</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="textLabel2"> + <property name="text"> + <string>Copyright:</string> + </property> + <property name="wordWrap"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="textLabel3"> + <property name="text"> + <string>Format:</string> + </property> + <property name="wordWrap"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="textLabel1"> + <property name="text"> + <string>Division:</string> + </property> + <property name="wordWrap"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="5" column="0" colspan="2"> + <widget class="QCheckBox" name="optNoteOffs"> + <property name="text"> + <string>Save space by replacing note-offs with &zero velocity note-ons</string> + </property> + <property name="shortcut"> + <string>Alt+Z</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QComboBox" name="formatCombo"> + <item> + <property name="text"> + <string>0 (single track)</string> + </property> + </item> + <item> + <property name="text"> + <string>1 (multiple tracks)</string> + </property> + </item> + </widget> </item> + </layout> + </widget> + </item> + <item> + <layout class="QHBoxLayout"> + <property name="spacing"> + <number>6</number> + </property> + <property name="margin"> + <number>0</number> + </property> + <item> + <spacer name="Horizontal Spacing2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Expanding</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="buttonOk"> + <property name="text"> + <string>&OK</string> + </property> + <property name="shortcut"> + <string/> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="buttonCancel"> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="shortcut"> + <string/> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + </item> </layout> - </widget> - <layoutdefault spacing="6" margin="11"/> - <connections> - <connection> - <sender>buttonOk</sender> - <signal>clicked()</signal> - <receiver>ConfigMidiFileBase</receiver> - <slot>accept()</slot> - </connection> - <connection> - <sender>buttonCancel</sender> - <signal>clicked()</signal> - <receiver>ConfigMidiFileBase</receiver> - <slot>reject()</slot> - </connection> - </connections> + </item> + </layout> + </widget> + <layoutdefault spacing="6" margin="11"/> + <resources/> + <connections> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>ConfigMidiFileBase</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>20</x> + <y>20</y> + </hint> + <hint type="destinationlabel"> + <x>20</x> + <y>20</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonCancel</sender> + <signal>clicked()</signal> + <receiver>ConfigMidiFileBase</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>20</x> + <y>20</y> + </hint> + <hint type="destinationlabel"> + <x>20</x> + <y>20</y> + </hint> + </hints> + </connection> + </connections> </ui> diff --git a/muse2/muse/widgets/musewidgetsplug.cpp b/muse2/muse/widgets/musewidgetsplug.cpp index 26a3054d..c1674e75 100644 --- a/muse2/muse/widgets/musewidgetsplug.cpp +++ b/muse2/muse/widgets/musewidgetsplug.cpp @@ -167,6 +167,7 @@ GlobalConfigValues config = { false, // midi export file 2 byte timesigs instead of 4 true, // optimize midi export file note offs true, // Split imported tracks into multiple parts. + true, // importMidiNewStyleDrum 1, // startMode QString(""), // start song path 384, // gui division -- cgit v1.2.3 From 182474fce42414f8f8c5545c4ce822aa5ce73c2c Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Mon, 10 Oct 2011 12:00:09 +0000 Subject: steprec and dlist-enote-changing fixes steprec now works for new style drum tracks --- muse2/muse/midiedit/dcanvas.cpp | 42 +++++++++++++++++++++++++++------------ muse2/muse/midiedit/dlist.cpp | 34 ++++++++++++++++++++++++++++++- muse2/muse/midiedit/scoreedit.cpp | 11 +++++----- muse2/muse/steprec.cpp | 9 ++++++--- muse2/muse/steprec.h | 2 +- 5 files changed, 75 insertions(+), 23 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp index 7daaff29..3431eabf 100644 --- a/muse2/muse/midiedit/dcanvas.cpp +++ b/muse2/muse/midiedit/dcanvas.cpp @@ -158,7 +158,8 @@ DrumCanvas::~DrumCanvas() if (must_delete_our_drum_map && ourDrumMap!=NULL) delete [] ourDrumMap; - delete steprec; + + delete steprec; } //--------------------------------------------------------- @@ -808,19 +809,22 @@ void DrumCanvas::dragLeaveEvent(QDragLeaveEvent*) // keyPressed - called from DList //--------------------------------------------------------- -void DrumCanvas::keyPressed(int index, int velocity) //FINDMICH later +void DrumCanvas::keyPressed(int index, int velocity) { + using MusECore::MidiTrack; + // called from DList - play event - int port = ourDrumMap[index].port; - int channel = ourDrumMap[index].channel; - int pitch = ourDrumMap[index].anote; + int port = old_style_drummap_mode ? ourDrumMap[index].port : dynamic_cast<MidiTrack*>(*instrument_map[index].tracks.begin())->outPort(); + int channel = old_style_drummap_mode ? ourDrumMap[index].channel : dynamic_cast<MidiTrack*>(*instrument_map[index].tracks.begin())->outChannel(); + int pitch = old_style_drummap_mode ? ourDrumMap[index].anote : instrument_map[index].pitch; // play note: MusECore::MidiPlayEvent e(0, port, channel, 0x90, pitch, velocity); MusEGlobal::audio->msgPlayMidiEvent(&e); - if (_steprec && pos[0] >= start_tick /* && pos[0] < end_tick [removed by flo93: this is handled in steprec->record] */ && curPart) - steprec->record(curPart,index,ourDrumMap[index].len,editor->raster(),velocity,MusEGlobal::globalKeyState&Qt::ControlModifier,MusEGlobal::globalKeyState&Qt::ShiftModifier); + if (_steprec && pos[0] >= start_tick /* && pos[0] < end_tick [removed by flo93: this is handled in steprec->record] */ && + curPart && instrument_map[index].tracks.contains(curPart->track()) ) + steprec->record(curPart,instrument_map[index].pitch,ourDrumMap[index].len,editor->raster(),velocity,MusEGlobal::globalKeyState&Qt::ControlModifier,MusEGlobal::globalKeyState&Qt::ShiftModifier, -1 /* invalid pitch as "really played" -> the "insert rest" feature is never triggered */); } @@ -828,12 +832,14 @@ void DrumCanvas::keyPressed(int index, int velocity) //FINDMICH later // keyReleased //--------------------------------------------------------- -void DrumCanvas::keyReleased(int index, bool) //FINDMICH later +void DrumCanvas::keyReleased(int index, bool) { + using MusECore::MidiTrack; + // called from DList - silence playing event - int port = ourDrumMap[index].port; - int channel = ourDrumMap[index].channel; - int pitch = ourDrumMap[index].anote; + int port = old_style_drummap_mode ? ourDrumMap[index].port : dynamic_cast<MidiTrack*>(*instrument_map[index].tracks.begin())->outPort(); + int channel = old_style_drummap_mode ? ourDrumMap[index].channel : dynamic_cast<MidiTrack*>(*instrument_map[index].tracks.begin())->outChannel(); + int pitch = old_style_drummap_mode ? ourDrumMap[index].anote : instrument_map[index].pitch; // release note: MusECore::MidiPlayEvent e(0, port, channel, 0x90, pitch, 0); @@ -1283,7 +1289,7 @@ void DrumCanvas::moveAwayUnused() //--------------------------------------------------------- // midiNote //--------------------------------------------------------- -void DrumCanvas::midiNote(int pitch, int velo) //FINDMICH later. +void DrumCanvas::midiNote(int pitch, int velo) { if (debugMsg) printf("DrumCanvas::midiNote: pitch=%i, velo=%i\n", pitch, velo); @@ -1291,7 +1297,17 @@ void DrumCanvas::midiNote(int pitch, int velo) //FINDMICH later. && !MusEGlobal::audio->isPlaying() && velo && pos[0] >= start_tick /* && pos[0] < end_tick [removed by flo93: this is handled in steprec->record()] */ && !(MusEGlobal::globalKeyState & Qt::AltModifier)) { - steprec->record(curPart,MusEGlobal::drumInmap[pitch],ourDrumMap[(int)MusEGlobal::drumInmap[pitch]].len,editor->raster(),velo,MusEGlobal::globalKeyState&Qt::ControlModifier,MusEGlobal::globalKeyState&Qt::ShiftModifier); + + int ourDrumMapSize=getOurDrumMapSize(); + int i; + for (i=0;i<ourDrumMapSize;i++) + { + if ( instrument_map[i].tracks.contains(curPart->track()) && ourDrumMap[i].enote==pitch) + break; + } + + if (i!=ourDrumMapSize) + steprec->record(curPart,instrument_map[i].pitch,ourDrumMap[i].len,editor->raster(),velo,MusEGlobal::globalKeyState&Qt::ControlModifier,MusEGlobal::globalKeyState&Qt::ShiftModifier, pitch); } } diff --git a/muse2/muse/midiedit/dlist.cpp b/muse2/muse/midiedit/dlist.cpp index 3399b78e..1d8436b6 100644 --- a/muse2/muse/midiedit/dlist.cpp +++ b/muse2/muse/midiedit/dlist.cpp @@ -372,8 +372,25 @@ void DList::viewMousePressEvent(QMouseEvent* ev) //TODO: Set all the notes on the track with instrument=dm->enote to instrument=val MusEGlobal::drumInmap[val] = instrument; } + else + { + //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 (QSet<MusECore::Track*>::iterator it = dcanvas->get_instrument_map()[instrument].tracks.begin(); it!=dcanvas->get_instrument_map()[instrument].tracks.end(); it++) + { + MusECore::MidiTrack* mt = dynamic_cast<MusECore::MidiTrack*>(*it); + mt->drummap()[mt->map_drum_in(val)].enote=dm->enote; + } + // propagating this is unneccessary as it's already done. + // updating the drumInmap is unneccessary, as the propagate call below + // does this for us. + // updating ourDrumMap is unneccessary because the song->update(SC_DRUMMAP) + // does this for us. + } + dm->enote = val; break; + case COL_NOTELENGTH: val = dm->len + incVal; if (val < 0) @@ -844,7 +861,22 @@ void DList::pitchEdited() } //TODO: Set all the notes on the track with instrument=dm->enote to instrument=val MusEGlobal::drumInmap[val] = instrument; - } + } + else + { + //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 (QSet<MusECore::Track*>::iterator it = dcanvas->get_instrument_map()[instrument].tracks.begin(); it!=dcanvas->get_instrument_map()[instrument].tracks.end(); it++) + { + MusECore::MidiTrack* mt = dynamic_cast<MusECore::MidiTrack*>(*it); + mt->drummap()[mt->map_drum_in(val)].enote=editEntry->enote; + } + // propagating this is unneccessary as it's already done. + // updating the drumInmap is unneccessary, as the propagate call below + // does this for us. + // updating ourDrumMap is unneccessary because the song->update(SC_DRUMMAP) + // does this for us. + } editEntry->enote = val; break; diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index cf436465..5fa117f5 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -4592,8 +4592,11 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo * 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 don't record muted/hidden instr.s + * o offer menu entry for hiding all unused / empty drum instruments + * * o in appearance.cpp: add the new stuff for drumTrackLabelBg and drumTrackBg * o find and fix FINDMICHJETZT * o fix all segfaults and non-working stuff! @@ -4603,9 +4606,6 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo * - recording/echoing/steprec them * - load, save them * o fix valgrind problems - * x midi-import settings - * o support or handle duplicate enotes somehow! - * o steprec, test midi thru * * > o drum editor: channel-stuff * o clearly state in the changelog: when having multiple drumeditors open, @@ -4623,11 +4623,12 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo * * x 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! + * x when recording or echoing a flo-drum-track: watch out for In-Notes! * * update [midi]track::read/write, readproperties, writeprop... (drumlist etc), operator= * _should_ be okay, but i'm not sure * * IMPORTANT TODO + * o allow steprec-insert-rest-note to be set to "off" / "unused" * 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!) diff --git a/muse2/muse/steprec.cpp b/muse2/muse/steprec.cpp index ea3feae7..c07a5bb8 100644 --- a/muse2/muse/steprec.cpp +++ b/muse2/muse/steprec.cpp @@ -55,13 +55,16 @@ void StepRec::timeout() } } -void StepRec::record(Part* part, int pitch, int len, int step, int velo, bool ctrl, bool shift) +void StepRec::record(Part* part, int pitch, int len, int step, int velo, bool ctrl, bool shift, int incoming_pitch) { unsigned tick = MusEGlobal::song->cpos(); unsigned lasttick=0; Undo operations; - if (pitch!=MusEGlobal::rcSteprecNote) + // if incoming_pitch wasn't specified, set it to pitch + if (incoming_pitch == 1337) incoming_pitch=pitch; + + if (incoming_pitch!=MusEGlobal::rcSteprecNote) { chord_timer->stop(); @@ -132,7 +135,7 @@ void StepRec::record(Part* part, int pitch, int len, int step, int velo, bool ct goto steprec_record_foot; // this is actually unneccessary, but for clarity } - else // equals if (pitch==MusEGlobal::rcSteprecNote) + else // equals if (incoming_pitch==MusEGlobal::rcSteprecNote) { bool held_notes=false; if (note_held_down!=NULL) diff --git a/muse2/muse/steprec.h b/muse2/muse/steprec.h index ba42c49c..a82cab20 100644 --- a/muse2/muse/steprec.h +++ b/muse2/muse/steprec.h @@ -37,7 +37,7 @@ class StepRec : public QObject public: StepRec(bool* note_held_down_array); - void record(Part* part, int pitch, int len, int step, int velo=80, bool ctrl=false, bool shift=false); + void record(Part* part, int recorded_pitch, int len, int step, int velo=80, bool ctrl=false, bool shift=false, int incoming_pitch=1337); private slots: void timeout(); -- cgit v1.2.3 From e4bedb86763c85a637921d566cd445cfa2c07444 Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Mon, 10 Oct 2011 12:22:40 +0000 Subject: added "show all" and "hide unused" menu entries --- muse2/muse/midiedit/dcanvas.cpp | 2 +- muse2/muse/midiedit/drumedit.cpp | 61 ++++++++++++++++++++++++++++++++++++++- muse2/muse/midiedit/drumedit.h | 2 ++ muse2/muse/midiedit/scoreedit.cpp | 1 + 4 files changed, 64 insertions(+), 2 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp index 3431eabf..03432bbd 100644 --- a/muse2/muse/midiedit/dcanvas.cpp +++ b/muse2/muse/midiedit/dcanvas.cpp @@ -1318,7 +1318,7 @@ int DrumCanvas::pitch_and_track_to_instrument(int pitch, MusECore::Track* track) 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"); + if (heavyDebugMsg) printf("DrumCanvas::pitch_and_track_to_instrument() called with invalid arguments.\n"); return -1; } diff --git a/muse2/muse/midiedit/drumedit.cpp b/muse2/muse/midiedit/drumedit.cpp index 3a75e32d..e46e2504 100644 --- a/muse2/muse/midiedit/drumedit.cpp +++ b/muse2/muse/midiedit/drumedit.cpp @@ -289,7 +289,11 @@ DrumEdit::DrumEdit(MusECore::PartList* pl, QWidget* parent, const char* name, un groupNoneAction = menuGrouping->addAction(tr("Don't group")); groupChanAction = menuGrouping->addAction(tr("Group by channel")); groupMaxAction = menuGrouping->addAction(tr("Group maximally")); - QAction* ignoreHideAction = settingsMenu->addAction(tr("Also show hidden events")); + QMenu* menuShowHide=settingsMenu->addMenu(tr("Show/Hide")); + QAction* ignoreHideAction = menuShowHide->addAction(tr("Also show hidden instruments")); + menuShowHide->addSeparator(); + QAction* showAllAction = menuShowHide->addAction(tr("Show all instruments")); + QAction* hideUnusedAction = menuShowHide->addAction(tr("Only show used instruments")); settingsMenu->addSeparator(); groupNoneAction->setCheckable(true); @@ -302,6 +306,8 @@ DrumEdit::DrumEdit(MusECore::PartList* pl, QWidget* parent, const char* name, un connect(groupChanAction, SIGNAL(triggered()), signalMapper, SLOT(map())); connect(groupMaxAction, SIGNAL(triggered()), signalMapper, SLOT(map())); connect(ignoreHideAction, SIGNAL(toggled(bool)), SLOT(set_ignore_hide(bool))); + connect(showAllAction, SIGNAL(triggered()), this, SLOT(showAllInstruments())); + connect(hideUnusedAction, SIGNAL(triggered()), this, SLOT(hideUnusedInstruments())); signalMapper->setMapping(groupNoneAction, DrumCanvas::CMD_GROUP_NONE); signalMapper->setMapping(groupChanAction, DrumCanvas::CMD_GROUP_CHAN); @@ -1427,4 +1433,57 @@ void DrumEdit::set_ignore_hide(bool val) ((DrumCanvas*)(canvas))->rebuildOurDrumMap(); } +void DrumEdit::showAllInstruments() +{ + using MusECore::MidiTrack; + + QSet<MidiTrack*> tracks; + for (MusECore::ciPart p = parts()->begin(); p != parts()->end(); ++p) + tracks.insert((MidiTrack*)p->second->track()); + + for (QSet<MidiTrack*>::iterator it=tracks.begin(); it!=tracks.end(); it++) + { + MidiTrack* track=*it; + + for (int i=0;i<128;i++) + track->drummap_hidden()[i]=false; + } + + ((DrumCanvas*)(canvas))->rebuildOurDrumMap(); +} + +void DrumEdit::hideUnusedInstruments() +{ + using MusECore::MidiTrack; + using MusECore::ciEvent; + using MusECore::EventList; + using MusECore::ciPart; + + QSet<MidiTrack*> tracks; + for (MusECore::ciPart p = parts()->begin(); p != parts()->end(); ++p) + tracks.insert((MidiTrack*)p->second->track()); + + for (QSet<MidiTrack*>::iterator it=tracks.begin(); it!=tracks.end(); it++) + { + MidiTrack* track=*it; + + bool hide[128]; + for (int i=0;i<128;i++) hide[i]=true; + + for (MusECore::ciPart p = parts()->begin(); p != parts()->end(); ++p) + if (p->second->track() == track) + { + const EventList* el = p->second->cevents(); + for (ciEvent ev=el->begin(); ev!=el->end(); ev++) + hide[ev->second.pitch()]=false; + } + + for (int i=0;i<128;i++) + track->drummap_hidden()[i]=hide[i]; + } + + ((DrumCanvas*)(canvas))->rebuildOurDrumMap(); +} + + } // namespace MusEGui diff --git a/muse2/muse/midiedit/drumedit.h b/muse2/muse/midiedit/drumedit.h index 5603e449..b08812f3 100644 --- a/muse2/muse/midiedit/drumedit.h +++ b/muse2/muse/midiedit/drumedit.h @@ -154,6 +154,8 @@ class DrumEdit : public MidiEditor { void setStep(QString); void updateGroupingActions(); void set_ignore_hide(bool); + void showAllInstruments(); + void hideUnusedInstruments(); public slots: void setSelection(int, MusECore::Event&, MusECore::Part*); diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index 5fa117f5..2b391461 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -4596,6 +4596,7 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo * CURRENT TODO * o don't record muted/hidden instr.s * o offer menu entry for hiding all unused / empty drum instruments + * o my record flag handling * * o in appearance.cpp: add the new stuff for drumTrackLabelBg and drumTrackBg * o find and fix FINDMICHJETZT -- cgit v1.2.3 From 068ed02a48ffb6b06d87d858ee04022da5062914 Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Mon, 10 Oct 2011 13:21:55 +0000 Subject: not recording muted/hidden instruments works --- muse2/muse/conf.cpp | 3 ++ muse2/muse/gconfig.cpp | 3 +- muse2/muse/gconfig.h | 10 ++++++ muse2/muse/midi.cpp | 16 ++++++--- muse2/muse/midiedit/scoreedit.cpp | 4 +-- muse2/muse/widgets/genset.cpp | 13 ++++++++ muse2/muse/widgets/genset.h | 1 + muse2/muse/widgets/gensetbase.ui | 59 +++++++++++++++++++++++++++------- muse2/muse/widgets/musewidgetsplug.cpp | 3 +- 9 files changed, 93 insertions(+), 19 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/conf.cpp b/muse2/muse/conf.cpp index 22259041..8fd2de1d 100644 --- a/muse2/muse/conf.cpp +++ b/muse2/muse/conf.cpp @@ -942,6 +942,8 @@ void readConfiguration(Xml& xml, bool readOnlySequencer, bool doReadGlobalConfig MusEGlobal::config.startMode = xml.parseInt(); else if (tag == "startSong") MusEGlobal::config.startSong = xml.parse1(); + else if (tag == "newDrumRecordCondition") + MusEGlobal::config.newDrumRecordCondition = MusECore::newDrumRecordCondition_t(xml.parseInt()); else if (tag == "projectBaseFolder") MusEGlobal::config.projectBaseFolder = xml.parse1(); else if (tag == "projectStoreInFolder") @@ -1268,6 +1270,7 @@ void MusE::writeGlobalConfiguration(int level, MusECore::Xml& xml) const xml.intTag(level, "importMidiSplitParts", MusEGlobal::config.importMidiSplitParts); xml.intTag(level, "startMode", MusEGlobal::config.startMode); xml.strTag(level, "startSong", MusEGlobal::config.startSong); + xml.intTag(level, "newDrumRecordCondition", MusEGlobal::config.newDrumRecordCondition); xml.strTag(level, "projectBaseFolder", MusEGlobal::config.projectBaseFolder); xml.intTag(level, "projectStoreInFolder", MusEGlobal::config.projectStoreInFolder); xml.intTag(level, "useProjectSaveDialog", MusEGlobal::config.useProjectSaveDialog); diff --git a/muse2/muse/gconfig.cpp b/muse2/muse/gconfig.cpp index 8aff870d..df8742e8 100644 --- a/muse2/muse/gconfig.cpp +++ b/muse2/muse/gconfig.cpp @@ -190,7 +190,8 @@ MusEGui::GlobalConfigValues config = { 64, // minControlProcessPeriod false, // popupsDefaultStayOpen false, // leftMouseButtonCanDecrease - false // rangeMarkerWithoutMMB + false, // rangeMarkerWithoutMMB + MusECore::DONT_REC_MUTED_OR_HIDDEN }; } // namespace MusEGlobal diff --git a/muse2/muse/gconfig.h b/muse2/muse/gconfig.h index cf205eba..85eecf60 100644 --- a/muse2/muse/gconfig.h +++ b/muse2/muse/gconfig.h @@ -34,6 +34,15 @@ namespace MusECore { class Xml; + +enum newDrumRecordCondition_t +{ + REC_ALL = 0, + DONT_REC_HIDDEN = 1, + DONT_REC_MUTED = 2, + DONT_REC_MUTED_OR_HIDDEN = 3 +}; + } namespace MusEGui { @@ -168,6 +177,7 @@ struct GlobalConfigValues { bool popupsDefaultStayOpen; bool leftMouseButtonCanDecrease; bool rangeMarkerWithoutMMB; + MusECore::newDrumRecordCondition_t newDrumRecordCondition; }; } // namespace MusEGui diff --git a/muse2/muse/midi.cpp b/muse2/muse/midi.cpp index 0138f1d8..52d6e4f8 100644 --- a/muse2/muse/midi.cpp +++ b/muse2/muse/midi.cpp @@ -257,7 +257,7 @@ void buildMidiEventList(EventList* del, const MPEventList* el, MidiTrack* track, case ME_NOTEON: e.setType(Note); - if (track->type() == Track::DRUM) { //FINDMICHJETZT + if (track->type() == Track::DRUM) { int instr = MusEGlobal::drumInmap[ev.dataA()]; e.setPitch(instr); } @@ -269,7 +269,7 @@ void buildMidiEventList(EventList* del, const MPEventList* el, MidiTrack* track, break; case ME_NOTEOFF: e.setType(Note); - if (track->type() == Track::DRUM) { //FINDMICHJETZT + if (track->type() == Track::DRUM) { int instr = MusEGlobal::drumInmap[ev.dataA()]; e.setPitch(instr); } @@ -980,7 +980,7 @@ void Audio::processMidi() // //Apply drum inkey: - if (track->type() == Track::DRUM) //FINDMICHJETZT does this work? + if (track->type() == Track::DRUM) { int pitch = event.dataA(); //Map note that is played according to MusEGlobal::drumInmap @@ -991,9 +991,17 @@ void Audio::processMidi() event.setA(MusEGlobal::drumMap[(unsigned int)MusEGlobal::drumInmap[pitch]].anote); event.setChannel(channel); } - else if (track->type() == Track::NEW_DRUM) + else if (track->type() == Track::NEW_DRUM) //FINDMICH DOES THAT WORK? { event.setA(track->map_drum_in(event.dataA())); + + if (MusEGlobal::config.newDrumRecordCondition & MusECore::DONT_REC_HIDDEN && + track->drummap_hidden()[event.dataA()] ) + continue; // skip that event, proceed with the next + + if (MusEGlobal::config.newDrumRecordCondition & MusECore::DONT_REC_MUTED && + track->drummap()[event.dataA()].mute ) + continue; // skip that event, proceed with the next } else { //Track transpose if non-drum diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index 2b391461..93a24129 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -4594,9 +4594,9 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo * from clipboard failed. ignoring this one... ) [ not reproducible ] * * CURRENT TODO - * o don't record muted/hidden instr.s - * o offer menu entry for hiding all unused / empty drum instruments + * x offer menu entry for hiding all unused / empty drum instruments * o my record flag handling + * x don't record muted/hidden instr.s * * o in appearance.cpp: add the new stuff for drumTrackLabelBg and drumTrackBg * o find and fix FINDMICHJETZT diff --git a/muse2/muse/widgets/genset.cpp b/muse2/muse/widgets/genset.cpp index d7642b3b..dd91e9ec 100644 --- a/muse2/muse/widgets/genset.cpp +++ b/muse2/muse/widgets/genset.cpp @@ -61,6 +61,13 @@ GlobalSettingsConfig::GlobalSettingsConfig(QWidget* parent) startSongGroup->addButton(startLastButton, 0); startSongGroup->addButton(startEmptyButton, 1); startSongGroup->addButton(startSongButton, 2); + + recDrumGroup = new QButtonGroup(this); + recDrumGroup->addButton(recordAllButton, MusECore::REC_ALL); + recDrumGroup->addButton(dontRecHiddenButton, MusECore::DONT_REC_HIDDEN); + recDrumGroup->addButton(dontRecMutedButton, MusECore::DONT_REC_MUTED); + recDrumGroup->addButton(dontRecBothButton, MusECore::DONT_REC_MUTED_OR_HIDDEN); + for (unsigned i = 0; i < sizeof(rtcResolutions)/sizeof(*rtcResolutions); ++i) { if (rtcResolutions[i] == MusEGlobal::config.rtcTicks) { rtcResolutionSelect->setCurrentIndex(i); @@ -123,6 +130,8 @@ Shorter periods are desirable.</string> startSongEntry->setText(MusEGlobal::config.startSong); startSongGroup->button(MusEGlobal::config.startMode)->setChecked(true); + recDrumGroup->button(MusEGlobal::config.newDrumRecordCondition)->setChecked(true); + showTransport->setChecked(MusEGlobal::config.transportVisible); showBigtime->setChecked(MusEGlobal::config.bigTimeVisible); //showMixer->setChecked(MusEGlobal::config.mixerVisible); @@ -261,6 +270,8 @@ void GlobalSettingsConfig::updateSettings() startSongEntry->setText(MusEGlobal::config.startSong); startSongGroup->button(MusEGlobal::config.startMode)->setChecked(true); + recDrumGroup->button(MusEGlobal::config.newDrumRecordCondition)->setChecked(true); + showTransport->setChecked(MusEGlobal::config.transportVisible); showBigtime->setChecked(MusEGlobal::config.bigTimeVisible); //showMixer->setChecked(MusEGlobal::config.mixerVisible); @@ -353,6 +364,8 @@ void GlobalSettingsConfig::apply() MusEGlobal::config.userInstrumentsDir = userInstrumentsPath->text(); MusEGlobal::config.startSong = startSongEntry->text(); MusEGlobal::config.startMode = startSongGroup->checkedId(); + MusEGlobal::config.newDrumRecordCondition = MusECore::newDrumRecordCondition_t(recDrumGroup->checkedId()); + int das = dummyAudioSize->currentIndex(); MusEGlobal::config.dummyAudioBufSize = dummyAudioBufSizes[das]; MusEGlobal::config.dummyAudioSampleRate = dummyAudioRate->value(); diff --git a/muse2/muse/widgets/genset.h b/muse2/muse/widgets/genset.h index 0e1697ee..92da61e3 100644 --- a/muse2/muse/widgets/genset.h +++ b/muse2/muse/widgets/genset.h @@ -62,6 +62,7 @@ class GlobalSettingsConfig : public QDialog, public Ui::GlobalSettingsDialogBase protected: void showEvent(QShowEvent*); QButtonGroup *startSongGroup; + QButtonGroup *recDrumGroup; std::list<MdiSettings*> mdisettings; public: diff --git a/muse2/muse/widgets/gensetbase.ui b/muse2/muse/widgets/gensetbase.ui index ba26cf38..39dcd4c3 100644 --- a/muse2/muse/widgets/gensetbase.ui +++ b/muse2/muse/widgets/gensetbase.ui @@ -23,7 +23,7 @@ </sizepolicy> </property> <property name="currentIndex"> - <number>0</number> + <number>2</number> </property> <widget class="QWidget" name="TabPage"> <attribute name="title"> @@ -1203,22 +1203,59 @@ Adjusts responsiveness of audio controls and </property> </widget> </item> - <item row="4" column="1"> - <spacer name="verticalSpacer_3"> - <property name="orientation"> - <enum>Qt::Vertical</enum> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBox_3"> + <property name="title"> + <string>Record new style drum tracks</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_5"> + <item> + <widget class="QRadioButton" name="recordAllButton"> + <property name="text"> + <string>Record all instruments</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="dontRecHiddenButton"> + <property name="text"> + <string>Don't record hidden instruments</string> </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> + </widget> + </item> + <item> + <widget class="QRadioButton" name="dontRecMutedButton"> + <property name="text"> + <string>Don't record muted instruments</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="dontRecBothButton"> + <property name="text"> + <string>Don't record hidden or muted instruments</string> </property> - </spacer> + </widget> </item> </layout> </widget> </item> + <item> + <spacer name="verticalSpacer_2"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> </layout> </widget> <widget class="QWidget" name="tab3"> diff --git a/muse2/muse/widgets/musewidgetsplug.cpp b/muse2/muse/widgets/musewidgetsplug.cpp index c1674e75..64189147 100644 --- a/muse2/muse/widgets/musewidgetsplug.cpp +++ b/muse2/muse/widgets/musewidgetsplug.cpp @@ -217,7 +217,8 @@ GlobalConfigValues config = { 64, // minControlProcessPeriod false, // popupsDefaultStayOpen false, // leftMouseButtonCanDecrease - false // rangeMarkerWithoutMMBCheckBox + false, // rangeMarkerWithoutMMBCheckBox + MusECore::DONT_REC_MUTED_OR_HIDDEN }; //--------------------------------------------------------- -- cgit v1.2.3 From 0b3e41f1bc7140de590d57f40df52412855c9099 Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Mon, 10 Oct 2011 13:29:37 +0000 Subject: small drum-map-hide-menu-entry additions --- muse2/muse/midiedit/drumedit.cpp | 56 +++++++++++++++++++++++++++++++++++++++ muse2/muse/midiedit/drumedit.h | 2 ++ muse2/muse/midiedit/scoreedit.cpp | 9 ------- 3 files changed, 58 insertions(+), 9 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/midiedit/drumedit.cpp b/muse2/muse/midiedit/drumedit.cpp index e46e2504..5c8f2c23 100644 --- a/muse2/muse/midiedit/drumedit.cpp +++ b/muse2/muse/midiedit/drumedit.cpp @@ -293,7 +293,9 @@ DrumEdit::DrumEdit(MusECore::PartList* pl, QWidget* parent, const char* name, un QAction* ignoreHideAction = menuShowHide->addAction(tr("Also show hidden instruments")); menuShowHide->addSeparator(); QAction* showAllAction = menuShowHide->addAction(tr("Show all instruments")); + QAction* hideAllAction = menuShowHide->addAction(tr("Hide all instruments")); QAction* hideUnusedAction = menuShowHide->addAction(tr("Only show used instruments")); + QAction* hideEmptyAction = menuShowHide->addAction(tr("Only show instruments with non-empty name or used instruments")); settingsMenu->addSeparator(); groupNoneAction->setCheckable(true); @@ -307,7 +309,9 @@ DrumEdit::DrumEdit(MusECore::PartList* pl, QWidget* parent, const char* name, un connect(groupMaxAction, SIGNAL(triggered()), signalMapper, SLOT(map())); connect(ignoreHideAction, SIGNAL(toggled(bool)), SLOT(set_ignore_hide(bool))); connect(showAllAction, SIGNAL(triggered()), this, SLOT(showAllInstruments())); + connect(hideAllAction, SIGNAL(triggered()), this, SLOT(hideAllInstruments())); connect(hideUnusedAction, SIGNAL(triggered()), this, SLOT(hideUnusedInstruments())); + connect(hideEmptyAction, SIGNAL(triggered()), this, SLOT(hideEmptyInstruments())); signalMapper->setMapping(groupNoneAction, DrumCanvas::CMD_GROUP_NONE); signalMapper->setMapping(groupChanAction, DrumCanvas::CMD_GROUP_CHAN); @@ -1452,6 +1456,25 @@ void DrumEdit::showAllInstruments() ((DrumCanvas*)(canvas))->rebuildOurDrumMap(); } +void DrumEdit::hideAllInstruments() +{ + using MusECore::MidiTrack; + + QSet<MidiTrack*> tracks; + for (MusECore::ciPart p = parts()->begin(); p != parts()->end(); ++p) + tracks.insert((MidiTrack*)p->second->track()); + + for (QSet<MidiTrack*>::iterator it=tracks.begin(); it!=tracks.end(); it++) + { + MidiTrack* track=*it; + + for (int i=0;i<128;i++) + track->drummap_hidden()[i]=true; + } + + ((DrumCanvas*)(canvas))->rebuildOurDrumMap(); +} + void DrumEdit::hideUnusedInstruments() { using MusECore::MidiTrack; @@ -1485,5 +1508,38 @@ void DrumEdit::hideUnusedInstruments() ((DrumCanvas*)(canvas))->rebuildOurDrumMap(); } +void DrumEdit::hideEmptyInstruments() +{ + using MusECore::MidiTrack; + using MusECore::ciEvent; + using MusECore::EventList; + using MusECore::ciPart; + + QSet<MidiTrack*> tracks; + for (MusECore::ciPart p = parts()->begin(); p != parts()->end(); ++p) + tracks.insert((MidiTrack*)p->second->track()); + + for (QSet<MidiTrack*>::iterator it=tracks.begin(); it!=tracks.end(); it++) + { + MidiTrack* track=*it; + + bool hide[128]; + for (int i=0;i<128;i++) hide[i]=track->drummap()[i].name.isEmpty(); + + for (MusECore::ciPart p = parts()->begin(); p != parts()->end(); ++p) + if (p->second->track() == track) + { + const EventList* el = p->second->cevents(); + for (ciEvent ev=el->begin(); ev!=el->end(); ev++) + hide[ev->second.pitch()]=false; + } + + for (int i=0;i<128;i++) + track->drummap_hidden()[i]=hide[i]; + } + + ((DrumCanvas*)(canvas))->rebuildOurDrumMap(); +} + } // namespace MusEGui diff --git a/muse2/muse/midiedit/drumedit.h b/muse2/muse/midiedit/drumedit.h index b08812f3..2c1f3060 100644 --- a/muse2/muse/midiedit/drumedit.h +++ b/muse2/muse/midiedit/drumedit.h @@ -155,7 +155,9 @@ class DrumEdit : public MidiEditor { void updateGroupingActions(); void set_ignore_hide(bool); void showAllInstruments(); + void hideAllInstruments(); void hideUnusedInstruments(); + void hideEmptyInstruments(); public slots: void setSelection(int, MusECore::Event&, MusECore::Part*); diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index 93a24129..9965fd99 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -4594,9 +4594,7 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo * from clipboard failed. ignoring this one... ) [ not reproducible ] * * CURRENT TODO - * x offer menu entry for hiding all unused / empty drum instruments * o my record flag handling - * x don't record muted/hidden instr.s * * o in appearance.cpp: add the new stuff for drumTrackLabelBg and drumTrackBg * o find and fix FINDMICHJETZT @@ -4620,13 +4618,6 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo * 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 - * x save hide, ordering, track's drumlists - * - * x when playing back a flo-drum-track: treat as a MIDI track, - * EXCEPT that the drum list's mute entries are respected! - * x when recording or echoing a flo-drum-track: watch out for In-Notes! - * * update [midi]track::read/write, readproperties, writeprop... (drumlist etc), operator= - * _should_ be okay, but i'm not sure * * IMPORTANT TODO * o allow steprec-insert-rest-note to be set to "off" / "unused" -- cgit v1.2.3 From b3280635650c81a718c1b93a2a3436d7bb35bab8 Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Mon, 10 Oct 2011 16:15:56 +0000 Subject: track's drumlists can be loaded, saved and copied around --- muse2/muse/arranger/tlist.cpp | 169 ++++++++++++++++++++++++++++++++++++-- muse2/muse/arranger/tlist.h | 3 + muse2/muse/midiedit/scoreedit.cpp | 2 - muse2/muse/track.cpp | 35 ++++---- muse2/muse/track.h | 13 ++- 5 files changed, 193 insertions(+), 29 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/arranger/tlist.cpp b/muse2/muse/arranger/tlist.cpp index be33808e..decd1a2e 100644 --- a/muse2/muse/arranger/tlist.cpp +++ b/muse2/muse/arranger/tlist.cpp @@ -62,6 +62,7 @@ #include "synth.h" #include "config.h" #include "popupmenu.h" +#include "filedialog.h" #ifdef DSSI_SUPPORT #include "dssihost.h" @@ -1261,9 +1262,21 @@ void TList::mousePressEvent(QMouseEvent* ev) QMenu* p = new QMenu; //p->clear(); // Leave room for normal track IDs - base these at AUDIO_SOFTSYNTH. - p->addAction(QIcon(*automation_clear_dataIcon), tr("Delete Track"))->setData(MusECore::Track::AUDIO_SOFTSYNTH + 1); - p->addAction(QIcon(*track_commentIcon), tr("Track Comment"))->setData(MusECore::Track::AUDIO_SOFTSYNTH + 2); + p->addAction(QIcon(*automation_clear_dataIcon), tr("Delete Track"))->setData(1001); + p->addAction(QIcon(*track_commentIcon), tr("Track Comment"))->setData(1002); p->addSeparator(); + + if (t->type()==MusECore::Track::NEW_DRUM) + { + p->addAction(tr("Save track's drumlist"))->setData(1010); + p->addAction(tr("Save track's drumlist differences to initial state"))->setData(1011); + p->addAction(tr("Load track's drumlist"))->setData(1012); + p->addAction(tr("Reset track's drumlist"))->setData(1013); + p->addAction(tr("Copy track's drumlist to all selected tracks"))->setData(1014); + p->addAction(tr("Copy track's drumlist's differences to all selected tracks"))->setData(1015); + p->addSeparator(); + } + QMenu* pnew = new QMenu(p); pnew->setTitle(tr("Insert Track")); pnew->setIcon(QIcon(*edit_track_addIcon)); @@ -1272,23 +1285,52 @@ void TList::mousePressEvent(QMouseEvent* ev) QAction* act = p->exec(ev->globalPos(), 0); if (act) { int n = act->data().toInt(); - if(n >= MusECore::Track::AUDIO_SOFTSYNTH && n < MENU_ADD_SYNTH_ID_BASE) + if(n >= 1000) { - n -= MusECore::Track::AUDIO_SOFTSYNTH; switch (n) { - case 1: // delete track + case 1001: // delete track MusEGlobal::song->removeTrack0(t); MusEGlobal::audio->msgUpdateSoloStates(); break; - case 2: // show track comment + case 1002: // show track comment { TrackComment* tc = new TrackComment(t, 0); tc->show(); //QToolTip::add( this, "FOOOOOOOOOOOOO" ); } break; - + + case 1010: + saveTrackDrummap((MusECore::MidiTrack*)t, true); + break; + + case 1011: + saveTrackDrummap((MusECore::MidiTrack*)t, false); + break; + + case 1012: + loadTrackDrummap((MusECore::MidiTrack*)t); + break; + + case 1013: + if (QMessageBox::warning(this, tr("Drum map"), + tr("Reset the track's drum map with GM defaults?"), + QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok) == QMessageBox::Ok) + { + ((MusECore::MidiTrack*)t)->init_drummap(); + MusEGlobal::song->update(SC_DRUMMAP); + } + break; + + case 1014: + copyTrackDrummap((MusECore::MidiTrack*)t, true); + break; + + case 1015: + copyTrackDrummap((MusECore::MidiTrack*)t, false); + break; + default: printf("action %d\n", n); break; @@ -1385,6 +1427,119 @@ void TList::mousePressEvent(QMouseEvent* ev) redraw(); } +void TList::loadTrackDrummap(MusECore::MidiTrack* t, const char* fn_) +{ + QString fn; + + if (fn_==NULL) + fn=MusEGui::getOpenFileName("drummaps", MusEGlobal::drum_map_file_pattern, + this, tr("Muse: Load Track's Drum Map"), 0); + else + fn=QString(fn_); + + if (fn.isEmpty()) + { + printf("ERROR: TList::loadTrackDrummap(): empty filename\n"); + return; + } + + bool popenFlag; + FILE* f = MusEGui::fileOpen(this, fn, QString(".map"), "r", popenFlag, true); + if (f == 0) + { + printf("ERROR: TList::loadTrackDrummap() could not open file %s!\n", fn.toAscii().data()); + return; + } + + MusECore::Xml xml(f); + int mode = 0; + for (;;) { + MusECore::Xml::Token token = xml.parse(); + const QString& tag = xml.s1(); + switch (token) { + case MusECore::Xml::Error: + case MusECore::Xml::End: + return; + case MusECore::Xml::TagStart: + if (mode == 0 && tag == "muse") + mode = 1; + else if (mode == 1 && tag == "our_drummap") { + t->readOurDrumMap(xml, true); + mode = 0; + } + else + xml.unknown("TList::loadTrackDrummap"); + break; + case MusECore::Xml::Attribut: + break; + case MusECore::Xml::TagEnd: + if (!mode && tag == "muse") + goto ende; + default: + break; + } + } + ende: + if (popenFlag) + pclose(f); + else + fclose(f); + + MusEGlobal::song->update(SC_DRUMMAP); +} + +void TList::saveTrackDrummap(MusECore::MidiTrack* t, bool full, const char* fn_) +{ + QString fn; + if (fn_==NULL) + fn = MusEGui::getSaveFileName(QString("drummaps"), MusEGlobal::drum_map_file_save_pattern, + this, tr("MusE: Store Track's Drum Map")); + else + fn = QString(fn_); + + if (fn.isEmpty()) + return; + + bool popenFlag; + FILE* f = MusEGui::fileOpen(this, fn, QString(".map"), "w", popenFlag, false, true); + if (f == 0) + return; + + MusECore::Xml xml(f); + xml.header(); + xml.tag(0, "muse version=\"1.0\""); + t->writeOurDrumMap(1, xml, full); + xml.tag(0, "/muse"); + + if (popenFlag) + pclose(f); + else + fclose(f); +} + +void TList::copyTrackDrummap(MusECore::MidiTrack* t, bool full) +{ + char* tmp1 = tmpnam(NULL); + char tmp2[1000]; + strcpy(tmp2, tmp1); + strcat(tmp2, ".map"); + if (MusEGlobal::debugMsg) + printf("in TList::copyTrackDrummap(); filename is %s\n",tmp2); + + saveTrackDrummap(t, full, tmp2); + + for (MusECore::iTrack it = MusEGlobal::song->tracks()->begin(); it!=MusEGlobal::song->tracks()->end(); it++) + if ((*it)->selected() && (*it)->type()==MusECore::Track::NEW_DRUM) + { + if (MusEGlobal::debugMsg) + printf(" processing track...\n"); + + loadTrackDrummap((MusECore::MidiTrack*)(*it), tmp2); + } + + remove(tmp2); +} + //--------------------------------------------------------- // selectTrack //--------------------------------------------------------- diff --git a/muse2/muse/arranger/tlist.h b/muse2/muse/arranger/tlist.h index 2aeae939..864e287b 100644 --- a/muse2/muse/arranger/tlist.h +++ b/muse2/muse/arranger/tlist.h @@ -118,6 +118,9 @@ class TList : public QWidget { void songChanged(int flags); void changeAutomation(QAction*); void changeAutomationColor(QAction*); + void loadTrackDrummap(MusECore::MidiTrack*, const char* filename=NULL); + void saveTrackDrummap(MusECore::MidiTrack*, bool full, const char* filename=NULL); + void copyTrackDrummap(MusECore::MidiTrack*, bool full); signals: ///void selectionChanged(); diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index 9965fd99..a9eba278 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -4610,8 +4610,6 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo * o clearly state in the changelog: when having multiple drumeditors open, * the mute-column may not work, because another editor is overriding this. * o respect "_drummap_tied_to_patch": IMPLEMENT - * o allow loading and saving track-drumlists to external files - * 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, diff --git a/muse2/muse/track.cpp b/muse2/muse/track.cpp index 8f213616..2df8a718 100644 --- a/muse2/muse/track.cpp +++ b/muse2/muse/track.cpp @@ -820,14 +820,14 @@ void MidiTrack::writeOurDrumSettings(int level, Xml& xml) const { xml.tag(level++, "our_drum_settings"); - xml.intTag(level, "tied", _drummap_tied_to_patch); + writeOurDrumMap(level, xml, false); - writeOurDrumMap(level, xml); + xml.intTag(level, "tied", _drummap_tied_to_patch); xml.etag(level, "our_drum_settings"); } -void MidiTrack::writeOurDrumMap(int level, Xml& xml) const +void MidiTrack::writeOurDrumMap(int level, Xml& xml, bool full) const { xml.tag(level++, "our_drummap"); @@ -849,23 +849,23 @@ void MidiTrack::writeOurDrumMap(int level, Xml& xml) const (dm->lv1 != idm->lv1) || (dm->lv2 != idm->lv2) || (dm->lv3 != idm->lv3) || (dm->lv4 != idm->lv4) || (dm->enote != idm->enote) || (dm->mute != idm->mute) || - _drummap_hidden[i] ) + _drummap_hidden[i] || full) { xml.tag(level++, "entry pitch=\"%d\"", i); // when any of these "if"s changes, also update the large "if" // above (this scope's parent) - if (dm->name != idm->name) xml.strTag(level, "name", dm->name); - if (dm->vol != idm->vol) xml.intTag(level, "vol", dm->vol); - if (dm->quant != idm->quant) xml.intTag(level, "quant", dm->quant); - if (dm->len != idm->len) xml.intTag(level, "len", dm->len); - if (dm->lv1 != idm->lv1) xml.intTag(level, "lv1", dm->lv1); - if (dm->lv2 != idm->lv2) xml.intTag(level, "lv2", dm->lv2); - if (dm->lv3 != idm->lv3) xml.intTag(level, "lv3", dm->lv3); - if (dm->lv4 != idm->lv4) xml.intTag(level, "lv4", dm->lv4); - if (dm->enote != idm->enote) xml.intTag(level, "enote", dm->enote); - if (dm->mute != idm->mute) xml.intTag(level, "mute", dm->mute); - if (_drummap_hidden[i]) xml.intTag(level, "hide", _drummap_hidden[i]); + if (full || dm->name != idm->name) xml.strTag(level, "name", dm->name); + if (full || dm->vol != idm->vol) xml.intTag(level, "vol", dm->vol); + if (full || dm->quant != idm->quant) xml.intTag(level, "quant", dm->quant); + if (full || dm->len != idm->len) xml.intTag(level, "len", dm->len); + if (full || dm->lv1 != idm->lv1) xml.intTag(level, "lv1", dm->lv1); + if (full || dm->lv2 != idm->lv2) xml.intTag(level, "lv2", dm->lv2); + if (full || dm->lv3 != idm->lv3) xml.intTag(level, "lv3", dm->lv3); + if (full || dm->lv4 != idm->lv4) xml.intTag(level, "lv4", dm->lv4); + if (full || dm->enote != idm->enote) xml.intTag(level, "enote", dm->enote); + if (full || dm->mute != idm->mute) xml.intTag(level, "mute", dm->mute); + if (full || _drummap_hidden[i]) xml.intTag(level, "hide", _drummap_hidden[i]); // anote is ignored anyway, as dm->anote == i, and this is // already stored in the begin tag (pitch=...) @@ -989,9 +989,10 @@ void MidiTrack::readOurDrumSettings(Xml& xml) } } -void MidiTrack::readOurDrumMap(Xml& xml) +void MidiTrack::readOurDrumMap(Xml& xml, bool dont_init) { - init_drummap(false); + if (!dont_init) init_drummap(false); + _drummap_tied_to_patch=false; for (;;) { diff --git a/muse2/muse/track.h b/muse2/muse/track.h index 73f18cc2..1826f081 100644 --- a/muse2/muse/track.h +++ b/muse2/muse/track.h @@ -235,13 +235,13 @@ class MidiTrack : public Track { int drum_in_map[128]; void init(); - void init_drummap(bool write_ordering=false); + void init_drummap(bool write_ordering); // function without argument in public void remove_ourselves_from_drum_ordering(); void writeOurDrumSettings(int level, Xml& xml) const; - void writeOurDrumMap(int level, Xml& xml) const; void readOurDrumSettings(Xml& xml); - void readOurDrumMap(Xml& xml); + //void writeOurDrumMap(int level, Xml& xml, bool full) const; //below in public: + //void readOurDrumMap(Xml& xml, bool dont_init=false); //below in public: public: MidiTrack(); @@ -314,6 +314,13 @@ class MidiTrack : public Track { bool* drummap_hidden() { return _drummap_hidden; } int map_drum_in(int enote) { return drum_in_map[enote]; } void update_drum_in_map(); + + void init_drummap() { init_drummap(false); } // function with argument in private + + //void writeOurDrumSettings(int level, Xml& xml) const; // above in private: + //void readOurDrumSettings(Xml& xml); // above in private: + void writeOurDrumMap(int level, Xml& xml, bool full) const; + void readOurDrumMap(Xml& xml, bool dont_init=false); }; } // namespace MusECore -- cgit v1.2.3 From 3dd4d0393c2824e98022d921667826a568843a7c Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Tue, 11 Oct 2011 13:35:11 +0000 Subject: added new drum tracks to appearance settings --- muse2/muse/appearance.cpp | 12 ++++++++++-- muse2/muse/midiedit/scoreedit.cpp | 1 - 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/appearance.cpp b/muse2/muse/appearance.cpp index ab2f8872..49397c0f 100644 --- a/muse2/muse/appearance.cpp +++ b/muse2/muse/appearance.cpp @@ -216,6 +216,7 @@ Appearance::Appearance(Arranger* a, QWidget* parent) new IdListViewItem(0x411, id, "background"); new IdListViewItem(0x412, id, "midi background"); new IdListViewItem(0x413, id, "drum background"); + new IdListViewItem(0x41e, id, "new drum background"); new IdListViewItem(0x414, id, "wave background"); new IdListViewItem(0x415, id, "output background"); new IdListViewItem(0x416, id, "input background"); @@ -224,6 +225,7 @@ Appearance::Appearance(Arranger* a, QWidget* parent) new IdListViewItem(0x419, id, "synth background"); new IdListViewItem(0x41a, id, "selected track background"); new IdListViewItem(0x41b, id, "selected track foreground"); + // 0x41e is already used (between 413 and 414) id = new IdListViewItem(0, itemList, "BigTime"); new IdListViewItem(0x100, id, "background"); new IdListViewItem(0x101, id, "foreground"); @@ -237,12 +239,14 @@ Appearance::Appearance(Arranger* a, QWidget* parent) new IdListViewItem(0x500, id, "background"); new IdListViewItem(0x501, id, "midi label"); new IdListViewItem(0x502, id, "drum label"); + new IdListViewItem(0x509, id, "new drum label"); new IdListViewItem(0x503, id, "wave label"); new IdListViewItem(0x504, id, "audio output label"); new IdListViewItem(0x505, id, "audio input label"); new IdListViewItem(0x506, id, "group label"); new IdListViewItem(0x507, id, "aux label"); new IdListViewItem(0x508, id, "synth label"); + // 0x509 is already used (between 502 and 503) colorNameLineEdit->setEnabled(false); @@ -842,7 +846,8 @@ void Appearance::colorItemSelectionChanged() case 0x300: color = &config->waveEditBackgroundColor; break; case 0x411: color = &config->trackBg; break; case 0x412: color = &config->midiTrackBg; break; - case 0x413: color = &config->drumTrackBg; break; //FINDMICHJETZT add newDrum... + case 0x413: color = &config->drumTrackBg; break; + case 0x41e: color = &config->newDrumTrackBg;break; case 0x414: color = &config->waveTrackBg; break; case 0x415: color = &config->outputTrackBg; break; case 0x416: color = &config->inputTrackBg; break; @@ -853,16 +858,19 @@ void Appearance::colorItemSelectionChanged() case 0x41b: color = &config->selectTrackFg; break; case 0x41c: color = &config->partCanvasBg; break; case 0x41d: color = &config->ctrlGraphFg; break; + // 0x41e is already used (between 413 and 414) case 0x500: color = &config->mixerBg; break; case 0x501: color = &config->midiTrackLabelBg; break; - case 0x502: color = &config->drumTrackLabelBg; break; //FINDMICHJETZT add newDrum... + case 0x502: color = &config->drumTrackLabelBg; break; + case 0x509: color = &config->newDrumTrackLabelBg;break; case 0x503: color = &config->waveTrackLabelBg; break; case 0x504: color = &config->outputTrackLabelBg; break; case 0x505: color = &config->inputTrackLabelBg; break; case 0x506: color = &config->groupTrackLabelBg; break; case 0x507: color = &config->auxTrackLabelBg; break; case 0x508: color = &config->synthTrackLabelBg; break; + // 0x509 is already used (between 502 and 503) default: color = 0; diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index 2be4bf60..962a7ae3 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -4607,7 +4607,6 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo * 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 in appearance.cpp: add the new stuff for drumTrackLabelBg and drumTrackBg * o find and fix FINDMICHJETZT * o fix all segfaults and non-working stuff! * - creating, changing types to and from, erasing NEW_DRUM tracks -- cgit v1.2.3 From 88041047222b78104191f449d3dbd7953d78a6e4 Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Tue, 11 Oct 2011 14:06:30 +0000 Subject: some testing and crash-fixes --- muse2/muse/arranger/arrangerview.cpp | 4 ++-- muse2/muse/arranger/pcanvas.cpp | 7 ++----- muse2/muse/arranger/tlist.cpp | 11 ++++++----- muse2/muse/midi.cpp | 2 +- muse2/muse/track.cpp | 3 +-- 5 files changed, 12 insertions(+), 15 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/arranger/arrangerview.cpp b/muse2/muse/arranger/arrangerview.cpp index a565da13..51fc3bb0 100644 --- a/muse2/muse/arranger/arrangerview.cpp +++ b/muse2/muse/arranger/arrangerview.cpp @@ -146,9 +146,9 @@ ArrangerView::ArrangerView(QWidget* parent) editInsertEMAction = new QAction(QIcon(*editpasteIconSet), tr("&Insert Empty Measure"), this); editDeleteSelectedAction = new QAction(QIcon(*edit_track_delIcon), tr("Delete Selected Tracks"), this); - editShrinkPartsAction = new QAction(tr("Shrink selected parts"), this); //FINDMICH TODO tooltips! + editShrinkPartsAction = new QAction(tr("Shrink selected parts"), this); editExpandPartsAction = new QAction(tr("Expand selected parts"), this); - editCleanPartsAction = new QAction(tr("Clean selected parts"), this); + editCleanPartsAction = new QAction(tr("Purge hidden events from selected parts"), this); addTrack = new QMenu(tr("Add Track"), this); diff --git a/muse2/muse/arranger/pcanvas.cpp b/muse2/muse/arranger/pcanvas.cpp index 8226c440..987a7e9a 100644 --- a/muse2/muse/arranger/pcanvas.cpp +++ b/muse2/muse/arranger/pcanvas.cpp @@ -392,13 +392,13 @@ MusECore::UndoOp PartCanvas::moveItem(CItem* item, const QPoint& newpos, DragTyp if (t == MOVE_COPY || t == MOVE_CLONE) { // These will not increment ref count, and will not chain clones... - // TODO FINDMICH: is this still correct (by flo93)? i doubt it! + // TODO: is comment this still correct (by flo93)? i doubt it! result=MusECore::UndoOp(MusECore::UndoOp::AddPart,dpart); } else if (t == MOVE_MOVE) { dpart->setSelected(spart->selected()); // These will increment ref count if not a clone, and will chain clones... - // TODO FINDMICH: is this still correct (by flo93)? i doubt it! + // TODO: is this comment still correct (by flo93)? i doubt it! result=MusECore::UndoOp(MusECore::UndoOp::ModifyPart,spart, dpart, true, false); spart->setSelected(false); @@ -854,9 +854,6 @@ void PartCanvas::mousePress(QMouseEvent* event) QPoint pt = event->pos(); CItem* item = items.find(pt); - //if (item == 0 && _tool!=AutomationTool) // FINDMICHJETZT. neccessary? (flo93) - // return; - switch (_tool) { default: if (item) diff --git a/muse2/muse/arranger/tlist.cpp b/muse2/muse/arranger/tlist.cpp index 1b2358f3..c209ba9c 100644 --- a/muse2/muse/arranger/tlist.cpp +++ b/muse2/muse/arranger/tlist.cpp @@ -1888,7 +1888,7 @@ void TList::classesPopupMenu(MusECore::Track* t, int x, int y) return; int n = act->data().toInt(); - if ((MusECore::Track::TrackType(n) == MusECore::Track::MIDI || MusECore::Track::TrackType(n) == MusECore::Track::NEW_DRUM) && t->type() == MusECore::Track::DRUM) { //FINDMICHJETZT passt das? + if ((MusECore::Track::TrackType(n) == MusECore::Track::MIDI || MusECore::Track::TrackType(n) == MusECore::Track::NEW_DRUM) && t->type() == MusECore::Track::DRUM) { // // Drum -> Midi // @@ -1926,7 +1926,7 @@ void TList::classesPopupMenu(MusECore::Track* t, int x, int y) MusEGlobal::audio->msgIdle(false); MusEGlobal::song->update(SC_EVENT_MODIFIED); } - else if (MusECore::Track::TrackType(n) == MusECore::Track::DRUM && (t->type() == MusECore::Track::MIDI || t->type() == MusECore::Track::NEW_DRUM)) { //FINDMICHJETZT passt das? + else if (MusECore::Track::TrackType(n) == MusECore::Track::DRUM && (t->type() == MusECore::Track::MIDI || t->type() == MusECore::Track::NEW_DRUM)) { // // Midi -> Drum // @@ -1984,11 +1984,12 @@ void TList::classesPopupMenu(MusECore::Track* t, int x, int y) MusEGlobal::audio->msgIdle(false); MusEGlobal::song->update(SC_EVENT_MODIFIED); } - else // MIDI -> NEW_DRUM or vice versa. added by flo. FINDMICHJETZT does this work properly? + else // MIDI -> NEW_DRUM or vice versa. added by flo. { - MusECore::Track* t2 = t->clone(false); + MusEGlobal::audio->msgIdle(true); t->setType(MusECore::Track::TrackType(n)); - MusEGlobal::audio->msgChangeTrack(t2, t, true); + MusEGlobal::audio->msgIdle(false); + MusEGlobal::song->update(SC_TRACK_MODIFIED); } } diff --git a/muse2/muse/midi.cpp b/muse2/muse/midi.cpp index 52d6e4f8..28269b20 100644 --- a/muse2/muse/midi.cpp +++ b/muse2/muse/midi.cpp @@ -991,7 +991,7 @@ void Audio::processMidi() event.setA(MusEGlobal::drumMap[(unsigned int)MusEGlobal::drumInmap[pitch]].anote); event.setChannel(channel); } - else if (track->type() == Track::NEW_DRUM) //FINDMICH DOES THAT WORK? + else if (track->type() == Track::NEW_DRUM) { event.setA(track->map_drum_in(event.dataA())); diff --git a/muse2/muse/track.cpp b/muse2/muse/track.cpp index 2df8a718..31504309 100644 --- a/muse2/muse/track.cpp +++ b/muse2/muse/track.cpp @@ -244,8 +244,7 @@ Track::Track(const Track& t, bool cloneParts) // A couple of schemes were conceived to deal with cloneList being invalid, but the best way is // to not alter the part list here. It's a big headache because: Either the parts in the cloneList // need to be reliably looked up replaced with the new ones, or the clipboard and cloneList must be cleared. - // Fortunately the ONLY parts of muse using this function are track rename (in TrackList and TrackInfo) and - // changing track type from MIDI to NEW_DRUM or vice versa (NOT something -> DRUM or vice versa). + // Fortunately the ONLY part of muse using this function is track rename (in TrackList and TrackInfo). // So we can get away with leaving this out: //for (iPart ip = _parts.begin(); ip != _parts.end(); ++ip) // ip->second->setTrack(this); -- cgit v1.2.3 From 4b27437712d5341129b019ec98fb8e4d3fa7ad0d Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Tue, 11 Oct 2011 15:33:08 +0000 Subject: improved drum canvas moving --- muse2/muse/midiedit/dcanvas.cpp | 55 ++++++++++++++++++++++++++++----------- muse2/muse/midiedit/dcanvas.h | 2 +- muse2/muse/midiedit/ecanvas.cpp | 4 ++- muse2/muse/midiedit/ecanvas.h | 3 ++- muse2/muse/midiedit/prcanvas.cpp | 12 +++++---- muse2/muse/midiedit/prcanvas.h | 2 +- muse2/muse/midiedit/scoreedit.cpp | 3 +++ muse2/muse/widgets/canvas.cpp | 11 ++++---- 8 files changed, 63 insertions(+), 29 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp index 03432bbd..03d38fbf 100644 --- a/muse2/muse/midiedit/dcanvas.cpp +++ b/muse2/muse/midiedit/dcanvas.cpp @@ -22,6 +22,7 @@ #include <QPainter> #include <QApplication> +#include <QMessageBox> #include <QClipboard> #include <QDrag> #include <QDragLeaveEvent> @@ -115,6 +116,8 @@ DrumCanvas::DrumCanvas(MidiEditor* pr, QWidget* parent, int sx, { drumEditor=dynamic_cast<DrumEdit*>(pr); + _setCurPartIfOnlyOneEventIsSelected=false; + old_style_drummap_mode = drumEditor->old_style_drummap_mode(); if (old_style_drummap_mode) @@ -257,7 +260,11 @@ MusECore::Undo DrumCanvas::moveCanvasItems(CItemList& items, int dp, int dx, Dra // Do not process if the event has already been processed (meaning it's an event in a clone part)... if (idl == doneList.end()) { - operations.push_back(moveItem(ci, newpos, dtype)); + if (moveItem(operations, ci, newpos, dtype) == false) //error? + { + QMessageBox::warning(this, tr("Moving items failed"), tr("The selection couldn't be moved, because at least one note would be moved into a track which is different from both the original track and the current part's track.\nChanging the current part with ALT+LEFT/RIGHT may help.")); + return MusECore::Undo(); //return empty list + } doneList.push_back(ci); } ci->move(newpos); @@ -289,29 +296,38 @@ MusECore::Undo DrumCanvas::moveCanvasItems(CItemList& items, int dp, int dx, Dra // moveItem //--------------------------------------------------------- -MusECore::UndoOp DrumCanvas::moveItem(CItem* item, const QPoint& pos, DragType dtype) +bool DrumCanvas::moveItem(MusECore::Undo& operations, CItem* item, const QPoint& pos, DragType dtype) { DEvent* nevent = (DEvent*) item; - MusECore::MidiPart* part = (MusECore::MidiPart*)nevent->part(); + MusECore::MidiPart* part = (MusECore::MidiPart*)nevent->part(); + MusECore::MidiPart* dest_part = part; + int nheight = y2pitch(pos.y()); + + if (!instrument_map[nheight].tracks.contains(dest_part->track())) + { + if (debugMsg) + printf("trying to move an event into a different track. checking if curPart is set correctly...\n"); + + if (!instrument_map[nheight].tracks.contains(curPart->track())) + { + printf ("ERROR: tried to move an event into a track which is different from both the initial part's and the curPart's track! ignoring this one...\n"); + return false; + } + else + dest_part=(MusECore::MidiPart*)curPart; + } + MusECore::Event event = nevent->event(); int x = pos.x(); if (x < 0) x = 0; - int ntick = editor->rasterVal(x) - part->tick(); + int ntick = editor->rasterVal(x) - dest_part->tick(); if (ntick < 0) ntick = 0; - int nheight = y2pitch(pos.y()); MusECore::Event newEvent = event.clone(); - - MusECore::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 MusECore::UndoOp(); - } + int ev_pitch = instrument_map[nheight].pitch; @@ -324,10 +340,19 @@ MusECore::UndoOp DrumCanvas::moveItem(CItem* item, const QPoint& pos, DragType d // printf("DrumCanvas::moveItem Error! New event end:%d exceeds length:%d of part:%s\n", newEvent.endTick(), part->lenTick(), part->name().toLatin1().constData()); if (dtype == MOVE_COPY || dtype == MOVE_CLONE) - return MusECore::UndoOp(MusECore::UndoOp::AddEvent, newEvent, part, false, false); + operations.push_back(MusECore::UndoOp(MusECore::UndoOp::AddEvent, newEvent, dest_part, false, false)); else - return MusECore::UndoOp(MusECore::UndoOp::ModifyEvent, newEvent, event, part, false, false); + { + if (dest_part == part) + operations.push_back(MusECore::UndoOp(MusECore::UndoOp::ModifyEvent, newEvent, event, part, false, false)); + else + { + operations.push_back(MusECore::UndoOp(MusECore::UndoOp::DeleteEvent, event, part, false, false)); + operations.push_back(MusECore::UndoOp(MusECore::UndoOp::AddEvent, newEvent, dest_part, false, false)); + } } + return true; +} //--------------------------------------------------------- // newItem diff --git a/muse2/muse/midiedit/dcanvas.h b/muse2/muse/midiedit/dcanvas.h index 2911862e..9053b3bf 100644 --- a/muse2/muse/midiedit/dcanvas.h +++ b/muse2/muse/midiedit/dcanvas.h @@ -110,7 +110,7 @@ class DrumCanvas : public EventCanvas { void drawTopItem(QPainter& p, const QRect& rect); virtual void drawMoving(QPainter&, const CItem*, const QRect&); virtual MusECore::Undo moveCanvasItems(CItemList&, int, int, DragType); - virtual MusECore::UndoOp moveItem(CItem*, const QPoint&, DragType); + virtual bool moveItem(MusECore::Undo&, CItem*, const QPoint&, DragType); virtual CItem* newItem(const QPoint&, int); virtual void resizeItem(CItem*, bool, bool); virtual void newItem(CItem*, bool); diff --git a/muse2/muse/midiedit/ecanvas.cpp b/muse2/muse/midiedit/ecanvas.cpp index 61891b2e..9941f7e5 100644 --- a/muse2/muse/midiedit/ecanvas.cpp +++ b/muse2/muse/midiedit/ecanvas.cpp @@ -56,6 +56,7 @@ EventCanvas::EventCanvas(MidiEditor* pr, QWidget* parent, int sx, _steprec = false; _midiin = false; _playEvents = false; + _setCurPartIfOnlyOneEventIsSelected = true; curVelo = 70; setBg(Qt::white); @@ -204,7 +205,7 @@ void EventCanvas::songChanged(int flags) start_tick = MusEGlobal::song->roundDownBar(start_tick); end_tick = MusEGlobal::song->roundUpBar(end_tick); - if (n == 1) { + if (n == 1 && _setCurPartIfOnlyOneEventIsSelected) { x = nevent->x(); event = nevent->event(); part = (MusECore::MidiPart*)nevent->part(); @@ -214,6 +215,7 @@ void EventCanvas::songChanged(int flags) curPartChanged(); } } + emit selectionChanged(x, event, part); if (curPart == 0) curPart = (MusECore::MidiPart*)(editor->parts()->begin()->second); diff --git a/muse2/muse/midiedit/ecanvas.h b/muse2/muse/midiedit/ecanvas.h index 1c66e9b4..2c783332 100644 --- a/muse2/muse/midiedit/ecanvas.h +++ b/muse2/muse/midiedit/ecanvas.h @@ -69,13 +69,14 @@ class EventCanvas : public Canvas { int curVelo; bool _steprec; bool _midiin; + bool _setCurPartIfOnlyOneEventIsSelected; void updateSelection(); virtual void addItem(MusECore::Part*, MusECore::Event&) = 0; // Added by T356. virtual QPoint raster(const QPoint&) const; virtual MusECore::Undo moveCanvasItems(CItemList&, int, int, DragType) = 0; - virtual MusECore::UndoOp moveItem(CItem*, const QPoint&, DragType) = 0; + virtual bool moveItem(MusECore::Undo&, CItem*, const QPoint&, DragType) = 0; virtual void endMoveItems(const QPoint&, DragType, int dir); public slots: diff --git a/muse2/muse/midiedit/prcanvas.cpp b/muse2/muse/midiedit/prcanvas.cpp index 9acaf186..223ae519 100644 --- a/muse2/muse/midiedit/prcanvas.cpp +++ b/muse2/muse/midiedit/prcanvas.cpp @@ -423,7 +423,7 @@ MusECore::Undo PianoCanvas::moveCanvasItems(MusEGui::CItemList& items, int dp, i // Do not process if the event has already been processed (meaning it's an event in a clone part)... if (idl == doneList.end()) { - operations.push_back(moveItem(ci, newpos, dtype)); + moveItem(operations, ci, newpos, dtype); // always returns true. if not, change is necessary here! doneList.push_back(ci); } ci->move(newpos); @@ -456,7 +456,7 @@ MusECore::Undo PianoCanvas::moveCanvasItems(MusEGui::CItemList& items, int dp, i // called after moving an object //--------------------------------------------------------- -MusECore::UndoOp PianoCanvas::moveItem(MusEGui::CItem* item, const QPoint& pos, DragType dtype) +bool PianoCanvas::moveItem(MusECore::Undo& operations, MusEGui::CItem* item, const QPoint& pos, DragType dtype) { NEvent* nevent = (NEvent*) item; MusECore::Event event = nevent->event(); @@ -492,10 +492,12 @@ MusECore::UndoOp PianoCanvas::moveItem(MusEGui::CItem* item, const QPoint& pos, // printf("PianoCanvas::moveItem Error! New event end:%d exceeds length:%d of part:%s\n", newEvent.endTick(), part->lenTick(), part->name().toLatin1().constData()); if (dtype == MOVE_COPY || dtype == MOVE_CLONE) - return MusECore::UndoOp(MusECore::UndoOp::AddEvent, newEvent, part, false, false); + operations.push_back(MusECore::UndoOp(MusECore::UndoOp::AddEvent, newEvent, part, false, false)); else - return MusECore::UndoOp(MusECore::UndoOp::ModifyEvent, newEvent, event, part, false, false); - } + operations.push_back(MusECore::UndoOp(MusECore::UndoOp::ModifyEvent, newEvent, event, part, false, false)); + + return true; +} //--------------------------------------------------------- // newItem(p, state) diff --git a/muse2/muse/midiedit/prcanvas.h b/muse2/muse/midiedit/prcanvas.h index 18d4f130..e9bd654d 100644 --- a/muse2/muse/midiedit/prcanvas.h +++ b/muse2/muse/midiedit/prcanvas.h @@ -73,7 +73,7 @@ class PianoCanvas : public EventCanvas { void drawTopItem(QPainter &p, const QRect &rect); virtual void drawMoving(QPainter&, const CItem*, const QRect&); virtual MusECore::Undo moveCanvasItems(CItemList&, int, int, DragType); - virtual MusECore::UndoOp moveItem(CItem*, const QPoint&, DragType); + virtual bool moveItem(MusECore::Undo&, CItem*, const QPoint&, DragType); virtual CItem* newItem(const QPoint&, int); virtual void resizeItem(CItem*, bool noSnap, bool); virtual void newItem(CItem*, bool noSnap); diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index 962a7ae3..a7b848f5 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -4595,6 +4595,9 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo * * CURRENT TODO * o my record flag handling + * o option for disabling old-style / new-style drum tracks? + * o steprec and mouse-inserting notes should automatically find out + * the proper destination part, or create a new one in dcanvas.cpp * * > o drum editor: channel-stuff * o clearly state in the changelog: when having multiple drumeditors open, diff --git a/muse2/muse/widgets/canvas.cpp b/muse2/muse/widgets/canvas.cpp index 41c5f4a4..9a1935a3 100644 --- a/muse2/muse/widgets/canvas.cpp +++ b/muse2/muse/widgets/canvas.cpp @@ -750,11 +750,6 @@ void Canvas::viewMousePressEvent(QMouseEvent* event) switch (_tool) { case PointerTool: if (curItem) { - if (curItem->part() != curPart) { - curPart = curItem->part(); - curPartId = curPart->sn(); - curPartChanged(); - } itemPressed(curItem); // Changed by T356. Alt is default reserved for moving the whole window in KDE. Changed to Shift-Alt. // Hmm, nope, shift-alt is also reserved sometimes. Must find a way to bypass, @@ -1226,6 +1221,12 @@ void Canvas::viewMouseReleaseEvent(QMouseEvent* event) case DRAG_MOVE_START: case DRAG_COPY_START: case DRAG_CLONE_START: + if (curItem->part() != curPart) { + curPart = curItem->part(); + curPartId = curPart->sn(); + curPartChanged(); + } + if (!ctrl) deselectAll(); -- cgit v1.2.3 From abedca49b707bd5bced2bee2caa8bb4417dcfa51 Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Tue, 11 Oct 2011 16:02:53 +0000 Subject: improved creating new notes in drum canvas --- muse2/muse/helper.cpp | 36 ++++++++++++++++++++++++++++++++++++ muse2/muse/helper.h | 8 ++++++++ muse2/muse/midiedit/dcanvas.cpp | 37 ++++++++++++++++++++++++------------- 3 files changed, 68 insertions(+), 13 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/helper.cpp b/muse2/muse/helper.cpp index e3cdee7e..1298b2d2 100644 --- a/muse2/muse/helper.cpp +++ b/muse2/muse/helper.cpp @@ -111,6 +111,42 @@ bool drummaps_almost_equal(DrumMap* one, DrumMap* two, int len) } +QSet<Part*> parts_at_tick(unsigned tick) +{ + using MusEGlobal::song; + + QSet<Track*> tmp; + for (iTrack it=song->tracks()->begin(); it!=song->tracks()->end(); it++) + tmp.insert(*it); + + return parts_at_tick(tick, tmp); +} + +QSet<Part*> parts_at_tick(unsigned tick, Track* track) +{ + QSet<Track*> tmp; + tmp.insert(track); + + return parts_at_tick(tick, tmp); +} + +QSet<Part*> parts_at_tick(unsigned tick, const QSet<Track*>& tracks) +{ + QSet<Part*> result; + + for (QSet<Track*>::const_iterator it=tracks.begin(); it!=tracks.end(); it++) + { + Track* track=*it; + + for (iPart p_it=track->parts()->begin(); p_it!=track->parts()->end(); p_it++) + if (tick >= p_it->second->tick() && tick <= p_it->second->endTick()) + result.insert(p_it->second); + } + + return result; +} + + } // namespace MusECore namespace MusEGui { diff --git a/muse2/muse/helper.h b/muse2/muse/helper.h index f014ee1e..a051cd15 100644 --- a/muse2/muse/helper.h +++ b/muse2/muse/helper.h @@ -24,6 +24,7 @@ #define __HELPER_H__ #include <set> +#include <QSet> #include "drummap.h" @@ -35,11 +36,18 @@ class QWidget; namespace MusECore { class Part; +class Track; + + QString pitch2string(int v); Part* partFromSerialNumber(int serial); bool any_event_selected(const std::set<Part*>&, bool in_range=false); bool drummaps_almost_equal(DrumMap* one, DrumMap* two, int drummap_size=128); + +QSet<Part*> parts_at_tick(unsigned tick); +QSet<Part*> parts_at_tick(unsigned tick, const Track* track); +QSet<Part*> parts_at_tick(unsigned tick, const QSet<Track*>& tracks); } namespace MusEGui { diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp index 03d38fbf..0d2f7640 100644 --- a/muse2/muse/midiedit/dcanvas.cpp +++ b/muse2/muse/midiedit/dcanvas.cpp @@ -380,20 +380,31 @@ CItem* DrumCanvas::newItem(int tick, int instrument, int velocity) { 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(); - MusECore::Event e(MusECore::Note); - e.setTick(tick); - e.setPitch(instrument_map[instrument].pitch); - e.setVelo(velocity); - e.setLenTick(ourDrumMap[instrument].len); - - return new DEvent(e, curPart, instrument); + if (debugMsg) + printf("tried to create a new Item which cannot be inside the current track. looking for destination part...\n"); + + QSet<MusECore::Part*> parts = parts_at_tick(tick, instrument_map[instrument].tracks); + + if (parts.count() != 1) + { + QMessageBox::warning(this, tr("Creating event failed"), tr("Couldn't create the event, because the currently selected part isn't the same track, and the selected instrument could be either on no or on multiple parts, which is ambiguous.\nSelect the destination part, then try again.")); + return NULL; + } + else + { + setCurrentPart(*parts.begin()); + } } + // else or if we found an alternative part (which has now been set as curPart) + + tick -= curPart->tick(); + MusECore::Event e(MusECore::Note); + e.setTick(tick); + e.setPitch(instrument_map[instrument].pitch); + e.setVelo(velocity); + e.setLenTick(ourDrumMap[instrument].len); + + return new DEvent(e, curPart, instrument); } //--------------------------------------------------------- -- cgit v1.2.3 From 784df1e40bbd403c34850c62c8fda3452d4f372b Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Tue, 11 Oct 2011 16:42:43 +0000 Subject: improved steprecording in drum editor --- muse2/muse/midiedit/dcanvas.cpp | 85 +++++++++++++++++++++++++++++++++------- muse2/muse/midiedit/prcanvas.cpp | 4 +- muse2/muse/steprec.cpp | 7 ++++ 3 files changed, 80 insertions(+), 16 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp index 0d2f7640..ec17b655 100644 --- a/muse2/muse/midiedit/dcanvas.cpp +++ b/muse2/muse/midiedit/dcanvas.cpp @@ -857,12 +857,24 @@ void DrumCanvas::keyPressed(int index, int velocity) // play note: MusECore::MidiPlayEvent e(0, port, channel, 0x90, pitch, velocity); MusEGlobal::audio->msgPlayMidiEvent(&e); - - if (_steprec && pos[0] >= start_tick /* && pos[0] < end_tick [removed by flo93: this is handled in steprec->record] */ && - curPart && instrument_map[index].tracks.contains(curPart->track()) ) + + + if (_steprec) /* && pos[0] >= start_tick && pos[0] < end_tick [removed by flo93: this is handled in steprec->record] */ + { + if ( curPart && instrument_map[index].tracks.contains(curPart->track()) ) steprec->record(curPart,instrument_map[index].pitch,ourDrumMap[index].len,editor->raster(),velocity,MusEGlobal::globalKeyState&Qt::ControlModifier,MusEGlobal::globalKeyState&Qt::ShiftModifier, -1 /* invalid pitch as "really played" -> the "insert rest" feature is never triggered */); - - } + else + { + QSet<MusECore::Part*> parts = parts_at_tick(pos[0], instrument_map[index].tracks); + + if (parts.count() != 1) + QMessageBox::warning(this, tr("Recording event failed"), tr("Couldn't record the event, because the currently selected part isn't the same track, and the instrument to be recorded could be either on no or on multiple parts, which is ambiguous.\nSelect the destination part, then try again.")); + else + steprec->record(*parts.begin(), instrument_map[index].pitch,ourDrumMap[index].len,editor->raster(),velocity,MusEGlobal::globalKeyState&Qt::ControlModifier,MusEGlobal::globalKeyState&Qt::ShiftModifier, -1 /* invalid pitch as "really played" -> the "insert rest" feature is never triggered */); + + } + } +} //--------------------------------------------------------- // keyReleased @@ -1326,26 +1338,71 @@ void DrumCanvas::moveAwayUnused() // midiNote //--------------------------------------------------------- void DrumCanvas::midiNote(int pitch, int velo) - { +{ + using MusECore::Track; + using MusECore::Part; + if (debugMsg) printf("DrumCanvas::midiNote: pitch=%i, velo=%i\n", pitch, velo); - if (_midiin && _steprec && curPart - && !MusEGlobal::audio->isPlaying() && velo && pos[0] >= start_tick - /* && pos[0] < end_tick [removed by flo93: this is handled in steprec->record()] */ - && !(MusEGlobal::globalKeyState & Qt::AltModifier)) { - + if (_midiin && _steprec && !MusEGlobal::audio->isPlaying() && velo && !(MusEGlobal::globalKeyState & Qt::AltModifier) /* && pos[0] >= start_tick && pos[0] < end_tick [removed by flo93: this is handled in steprec->record()] */ ) + { + if (pitch == MusEGlobal::rcSteprecNote) // skip the fancy code below, simply record a rest + { + if (curPart) + steprec->record(curPart,0xdead,0xbeef,editor->raster(),velo,MusEGlobal::globalKeyState&Qt::ControlModifier,MusEGlobal::globalKeyState&Qt::ShiftModifier, pitch); + } + else + { + QSet<Track*> possible_dest_tracks; + Part* rec_part=NULL; + int rec_index=-1; + int ourDrumMapSize=getOurDrumMapSize(); int i; for (i=0;i<ourDrumMapSize;i++) { if ( instrument_map[i].tracks.contains(curPart->track()) && ourDrumMap[i].enote==pitch) + { + rec_part=curPart; + rec_index=i; break; + } + else if (ourDrumMap[i].enote==pitch) + possible_dest_tracks.unite(instrument_map[i].tracks); } - if (i!=ourDrumMapSize) - steprec->record(curPart,instrument_map[i].pitch,ourDrumMap[i].len,editor->raster(),velo,MusEGlobal::globalKeyState&Qt::ControlModifier,MusEGlobal::globalKeyState&Qt::ShiftModifier, pitch); - } + if (rec_part == NULL) // if recording to curPart isn't possible + { + QSet<Part*> possible_dest_parts = parts_at_tick(pos[0], possible_dest_tracks); + + if (possible_dest_parts.count() != 1) + QMessageBox::warning(this, tr("Recording event failed"), tr("Couldn't record the event, because the currently selected part isn't the same track, and the instrument to be recorded could be either on no or on multiple parts, which is ambiguous.\nSelect the destination part, then try again.")); + else + { + rec_part = *possible_dest_parts.begin(); + Track* dest_track=rec_part->track(); + + for (i=0;i<ourDrumMapSize;i++) + if ( instrument_map[i].tracks.contains(dest_track) && ourDrumMap[i].enote==pitch) + { + rec_index=i; + break; + } + + if (rec_index==-1) + { + printf("ERROR: THIS SHOULD NEVER HAPPEN: i found a destination part for step recording, but now i can't find the instrument any more in DrumCanvas::midiNote()?!\n"); + QMessageBox::critical(this, tr("Internal error"), tr("Wtf, some nasty internal error which is actually impossible occurred. Check console output. Nothing recorded.")); + rec_part=NULL; + } + } + } + + if (rec_part != NULL) + steprec->record(rec_part,instrument_map[rec_index].pitch,ourDrumMap[rec_index].len,editor->raster(),velo,MusEGlobal::globalKeyState&Qt::ControlModifier,MusEGlobal::globalKeyState&Qt::ShiftModifier, pitch); + } } +} int DrumCanvas::pitch_and_track_to_instrument(int pitch, MusECore::Track* track) diff --git a/muse2/muse/midiedit/prcanvas.cpp b/muse2/muse/midiedit/prcanvas.cpp index 223ae519..e2a05bda 100644 --- a/muse2/muse/midiedit/prcanvas.cpp +++ b/muse2/muse/midiedit/prcanvas.cpp @@ -736,8 +736,8 @@ void PianoCanvas::pianoPressed(int pitch, int velocity, bool shift) MusECore::MidiPlayEvent e(0, port, channel, 0x90, pitch, velocity); MusEGlobal::audio->msgPlayMidiEvent(&e); - if (_steprec && pos[0] >= start_tick /* && pos[0] < end_tick [removed by flo93: this is handled in steprec->record] */ && curPart) - steprec->record(curPart,pitch,editor->raster(),editor->raster(),velocity,MusEGlobal::globalKeyState&Qt::ControlModifier,shift); + if (_steprec && curPart /* && pos[0] >= start_tick && pos[0] < end_tick [removed by flo93: this is handled in steprec->record] */) + steprec->record(curPart,pitch,editor->raster(),editor->raster(),velocity,MusEGlobal::globalKeyState&Qt::ControlModifier,shift, -1 /* anything which is != rcSteprecNote */); } //--------------------------------------------------------- diff --git a/muse2/muse/steprec.cpp b/muse2/muse/steprec.cpp index c07a5bb8..723fe650 100644 --- a/muse2/muse/steprec.cpp +++ b/muse2/muse/steprec.cpp @@ -61,6 +61,13 @@ void StepRec::record(Part* part, int pitch, int len, int step, int velo, bool ct unsigned lasttick=0; Undo operations; + if (tick < part->tick()) //insert note before the part to insert? + { + if (MusEGlobal::debugMsg) + printf("StepRec::record(): tick (%i) is before part (begin tick is %i), ignoring...\n",tick, part->tick()); + return; + } + // if incoming_pitch wasn't specified, set it to pitch if (incoming_pitch == 1337) incoming_pitch=pitch; -- cgit v1.2.3 From d3a9aa4568b325c183b758f6d05a1af4a457b245 Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Wed, 12 Oct 2011 16:48:45 +0000 Subject: drum map saving/loading only shown when appropriate, and moved --- muse2/muse/midiedit/drumedit.cpp | 70 +++++++++++++++++++++------------------ muse2/muse/midiedit/drumedit.h | 2 +- muse2/muse/midiedit/scoreedit.cpp | 3 +- 3 files changed, 40 insertions(+), 35 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/midiedit/drumedit.cpp b/muse2/muse/midiedit/drumedit.cpp index e7e517ff..58875b4d 100644 --- a/muse2/muse/midiedit/drumedit.cpp +++ b/muse2/muse/midiedit/drumedit.cpp @@ -170,20 +170,6 @@ DrumEdit::DrumEdit(MusECore::PartList* pl, QWidget* parent, const char* name, un _ignore_hide = _ignore_hide_init; //---------Pulldown Menu---------------------------- - menuFile = menuBar()->addMenu(tr("&File")); - - loadAction = menuFile->addAction(QIcon(*openIcon), tr("Load Map")); - saveAction = menuFile->addAction(QIcon(*saveIcon), tr("Save Map")); - resetAction = menuFile->addAction(tr("Reset GM Map")); - - connect(loadAction, SIGNAL(triggered()), signalMapper, SLOT(map())); - connect(saveAction, SIGNAL(triggered()), signalMapper, SLOT(map())); - connect(resetAction, SIGNAL(triggered()), signalMapper, SLOT(map())); - - signalMapper->setMapping(loadAction, DrumCanvas::CMD_LOAD); - signalMapper->setMapping(saveAction, DrumCanvas::CMD_SAVE); - signalMapper->setMapping(resetAction, DrumCanvas::CMD_RESET); - menuEdit = menuBar()->addMenu(tr("&Edit")); menuEdit->addActions(MusEGlobal::undoRedo->actions()); @@ -247,11 +233,25 @@ DrumEdit::DrumEdit(MusECore::PartList* pl, QWidget* parent, const char* name, un if (old_style_drummap_mode()) { - QAction* reorderListAction = menuFunctions->addAction(tr("Re-order list")); + loadAction = menuFunctions->addAction(QIcon(*openIcon), tr("Load Map")); + saveAction = menuFunctions->addAction(QIcon(*saveIcon), tr("Save Map")); + resetAction = menuFunctions->addAction(tr("Reset GM Map")); + + connect(loadAction, SIGNAL(triggered()), signalMapper, SLOT(map())); + connect(saveAction, SIGNAL(triggered()), signalMapper, SLOT(map())); + connect(resetAction, SIGNAL(triggered()), signalMapper, SLOT(map())); + + signalMapper->setMapping(loadAction, DrumCanvas::CMD_LOAD); + signalMapper->setMapping(saveAction, DrumCanvas::CMD_SAVE); + signalMapper->setMapping(resetAction, DrumCanvas::CMD_RESET); + + QAction* reorderListAction = menuFunctions->addAction(tr("Re-order map")); connect(reorderListAction, SIGNAL(triggered()), signalMapper, SLOT(map())); signalMapper->setMapping(reorderListAction, DrumCanvas::CMD_REORDER_LIST); menuFunctions->addSeparator(); } + else + loadAction=saveAction=resetAction=NULL; fixedAction = menuFunctions->addAction(tr("Set Fixed Length")); veloAction = menuFunctions->addAction(tr("Modify Velocity")); @@ -334,25 +334,31 @@ DrumEdit::DrumEdit(MusECore::PartList* pl, QWidget* parent, const char* name, un //--------------------------------------------------- // Toolbars //--------------------------------------------------- + + if (old_style_drummap_mode()) + { + QToolBar* maptools = addToolBar(tr("Drum map tools")); + maptools->setObjectName("Drum map tools"); + + QToolButton *ldm = new QToolButton(); + ldm->setToolTip(tr("Load Drummap")); + ldm->setIcon(*openIcon); + connect(ldm, SIGNAL(clicked()), SLOT(load())); + maptools->addWidget(ldm); + + QToolButton *sdm = new QToolButton(); + sdm->setToolTip(tr("Store Drummap")); + sdm->setIcon(*saveIcon); + connect(sdm, SIGNAL(clicked()), SLOT(save())); + maptools->addWidget(sdm); + + maptools->addAction(QWhatsThis::createAction()); + } + tools = addToolBar(tr("Drum tools")); tools->setObjectName("Drum tools"); - - QToolButton *ldm = new QToolButton(); - ldm->setToolTip(tr("Load Drummap")); - ldm->setIcon(*openIcon); - connect(ldm, SIGNAL(clicked()), SLOT(load())); - tools->addWidget(ldm); - - QToolButton *sdm = new QToolButton(); - sdm->setToolTip(tr("Store Drummap")); - sdm->setIcon(*saveIcon); - connect(sdm, SIGNAL(clicked()), SLOT(save())); - tools->addWidget(sdm); - - tools->addAction(QWhatsThis::createAction()); - tools->addSeparator(); tools->addActions(MusEGlobal::undoRedo->actions()); tools->addSeparator(); @@ -1341,8 +1347,8 @@ void DrumEdit::keyPressEvent(QKeyEvent* event) void DrumEdit::initShortcuts() { - loadAction->setShortcut(shortcuts[SHRT_OPEN].key); - saveAction->setShortcut(shortcuts[SHRT_SAVE].key); + if (loadAction) loadAction->setShortcut(shortcuts[SHRT_OPEN].key); + if (saveAction) saveAction->setShortcut(shortcuts[SHRT_SAVE].key); cutAction->setShortcut(shortcuts[SHRT_CUT].key); copyAction->setShortcut(shortcuts[SHRT_COPY].key); diff --git a/muse2/muse/midiedit/drumedit.h b/muse2/muse/midiedit/drumedit.h index 2c1f3060..b860da80 100644 --- a/muse2/muse/midiedit/drumedit.h +++ b/muse2/muse/midiedit/drumedit.h @@ -99,7 +99,7 @@ class DrumEdit : public MidiEditor { MusECore::Event selEvent; MusECore::MidiPart* selPart; int selTick; - QMenu* menuEdit, *menuFunctions, *menuFile, *menuSelect; + QMenu* menuEdit, *menuFunctions, *menuSelect; MusEGui::NoteInfo* info; QToolButton* srec; diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index a7b848f5..6957e9c1 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -4594,10 +4594,9 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo * from clipboard failed. ignoring this one... ) [ not reproducible ] * * CURRENT TODO + * o drum controllers * o my record flag handling * o option for disabling old-style / new-style drum tracks? - * o steprec and mouse-inserting notes should automatically find out - * the proper destination part, or create a new one in dcanvas.cpp * * > o drum editor: channel-stuff * o clearly state in the changelog: when having multiple drumeditors open, -- cgit v1.2.3 From 1c547a97cf011a07fa7269df343820470856dd36 Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Thu, 13 Oct 2011 14:37:39 +0000 Subject: Song::remapPortDrumCtrlEvents() now also processes hidden events --- muse2/muse/instruments/minstrument.cpp | 8 ++++---- muse2/muse/song.cpp | 7 ++++--- 2 files changed, 8 insertions(+), 7 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/instruments/minstrument.cpp b/muse2/muse/instruments/minstrument.cpp index 8e8bb6c3..c479ebc6 100644 --- a/muse2/muse/instruments/minstrument.cpp +++ b/muse2/muse/instruments/minstrument.cpp @@ -932,14 +932,14 @@ QString MidiInstrument::getPatchName(int channel, int prog, MType mode, bool dru return "<unknown>"; } -//--------------------------------------------------------- -// populatePatchPopup -//--------------------------------------------------------- - } // namespace MusECore namespace MusEGui { +//--------------------------------------------------------- +// populatePatchPopup +//--------------------------------------------------------- + void populatePatchPopup(MusECore::MidiInstrument* midiInstrument, PopupMenu* menu, int chan, MType songType, bool drum) { menu->clear(); diff --git a/muse2/muse/song.cpp b/muse2/muse/song.cpp index c9efe288..98ad007a 100644 --- a/muse2/muse/song.cpp +++ b/muse2/muse/song.cpp @@ -635,9 +635,10 @@ void Song::remapPortDrumCtrlEvents(int mapidx, int newnote, int newchan, int new { const Event& ev = ie->second; // Added by T356. Do not handle events which are past the end of the part. - //FINDMICHJETZT why not? - if(ev.tick() >= len) - break; + // Commented out by flo: yes, DO handle them! these are "hidden events" + // which may be revealed later again! + // if(ev.tick() >= len) + // break; if(ev.type() != Controller) continue; -- cgit v1.2.3 From 5c191a7c5b525cfc833ed4d3be171101058e9779 Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Thu, 13 Oct 2011 17:10:30 +0000 Subject: removed or fixed many FINDMICH markers. NEEDS TESTING! --- muse2/muse/ctrl/ctrlpanel.cpp | 19 +++++++++++++++++-- muse2/muse/liste/editevent.cpp | 8 ++++---- muse2/muse/midi.cpp | 29 +++++++++++++++++++++++------ muse2/muse/midiedit/scoreedit.cpp | 2 ++ muse2/muse/part.cpp | 8 ++++---- muse2/muse/song.cpp | 22 ++++++++++++---------- muse2/muse/songfile.cpp | 2 +- muse2/muse/track.cpp | 10 +++++----- muse2/muse/track.h | 1 + muse2/muse/widgets/mtrackinfo.cpp | 18 +++++++++--------- 10 files changed, 78 insertions(+), 41 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/ctrl/ctrlpanel.cpp b/muse2/muse/ctrl/ctrlpanel.cpp index 88787c47..5e07e5f3 100644 --- a/muse2/muse/ctrl/ctrlpanel.cpp +++ b/muse2/muse/ctrl/ctrlpanel.cpp @@ -171,7 +171,7 @@ void CtrlPanel::heartBeat() int outport; int chan; int cdi = editor->curDrumInstrument(); - if(_track->type() == MusECore::Track::DRUM && ((_ctrl->num() & 0xff) == 0xff) && cdi != -1) //FINDMICHJETZT was ist das? und ähnliche dinger + if(_track->type() == MusECore::Track::DRUM && ((_ctrl->num() & 0xff) == 0xff) && cdi != -1) { outport = MusEGlobal::drumMap[cdi].port; chan = MusEGlobal::drumMap[cdi].channel; @@ -539,6 +539,21 @@ void CtrlPanel::setHeight(int h) } #if 0 +/* WARNING: INVALID CODE! *\ + * the code which has been disabled by the above #if 0 is partly * + * OBSOLETE! it lacks support for new-style drum tracks, especially * + * the drum-controller-handling for these! * + * * + * when you ever enable that code again, first check the changes * + * flo93 did somewhere between revision 1188 and 1188+something * + * (let's say, 1195; it's NOT the revision in which this comment * + * has been introduced) in experimental to the currently enabled * + * code below. then apply similar changes to the currently disabled * +\* code here! */ +#error "INVALID CODE. please check the comment in ctrlpanel.cpp which starts with 'WARNING: INVALID CODE'" +just to be sure: dear compiler, please refuse to compile. +dear user: read the comment above! + struct CI { QString s; bool used; @@ -562,7 +577,7 @@ void CtrlPanel::ctrlPopup() int channel = track->outChannel(); MusECore::MidiPort* port = &MusEGlobal::midiPorts[track->outPort()]; int curDrumInstrument = editor->curDrumInstrument(); - bool isDrum = track->type() == MusECore::Track::DRUM; //FINDMICHJETZT ist das wichtig? + bool isDrum = track->type() == MusECore::Track::DRUM; QMenu* pop = new QMenu; //pop->clear(); diff --git a/muse2/muse/liste/editevent.cpp b/muse2/muse/liste/editevent.cpp index ce53069d..32a328a8 100644 --- a/muse2/muse/liste/editevent.cpp +++ b/muse2/muse/liste/editevent.cpp @@ -614,12 +614,12 @@ EditCtrlDialog::EditCtrlDialog(int tick, const MusECore::Event& event, } ///pop = new QMenu(this); - //pop->setCheckable(false);//not necessary in Qt4 + //pop->setCheckable(false); //not necessary in Qt4 MusECore::MidiTrack* track = part->track(); int portn = track->outPort(); MusECore::MidiPort* port = &MusEGlobal::midiPorts[portn]; - bool isDrum = track->type() == MusECore::Track::DRUM; //FINDMICHJETZT was soll das? + bool isDrum = track->isDrumTrack(); MusECore::MidiCtrlValListList* cll = port->controller(); ctrlList->clear(); @@ -835,7 +835,7 @@ void EditCtrlDialog::updatePatch() int port = track->outPort(); int channel = track->outChannel(); MusECore::MidiInstrument* instr = MusEGlobal::midiPorts[port].instrument(); - patchName->setText(instr->getPatchName(channel, val, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM)); //FINDMICHJETZT was soll das? + patchName->setText(instr->getPatchName(channel, val, MusEGlobal::song->mtype(), track->isDrumTrack())); int hb = ((val >> 16) & 0xff) + 1; if (hb == 0x100) @@ -874,7 +874,7 @@ void EditCtrlDialog::instrPopup() ///instr->populatePatchPopup(pop, channel, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM); //QMenu* pup = new QMenu(this); MusEGui::PopupMenu* pup = new MusEGui::PopupMenu(this); - populatePatchPopup(instr, pup, channel, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM); //FINDMICHJETZT was soll das? + populatePatchPopup(instr, pup, channel, MusEGlobal::song->mtype(), track->isDrumTrack()); ///if(pop->actions().count() == 0) /// return; diff --git a/muse2/muse/midi.cpp b/muse2/muse/midi.cpp index 28269b20..d5ed119d 100644 --- a/muse2/muse/midi.cpp +++ b/muse2/muse/midi.cpp @@ -372,7 +372,7 @@ void buildMidiEventList(EventList* del, const MPEventList* el, MidiTrack* track, int ctl = ev.dataA(); e.setA(ctl); - if(track->type() == Track::DRUM) //FINDMICHJETZT drum controller? + if(track->type() == Track::DRUM) { // Is it a drum controller event, according to the track port's instrument? MidiController *mc = MusEGlobal::midiPorts[track->outPort()].drumController(ctl); @@ -808,7 +808,7 @@ void Audio::collectEvents(MusECore::MidiTrack* track, unsigned int cts, unsigned case Controller: { - if (track->type() == Track::DRUM) //FINDMICHJETZT was ist das? drumcontroller -_- + if (track->type() == Track::DRUM) { int ctl = ev.dataA(); // Is it a drum controller event, according to the track port's instrument? @@ -1026,10 +1026,9 @@ void Audio::processMidi() event.setB(velo); } } - else - if(event.type() == MusECore::ME_CONTROLLER) + else if(event.type() == MusECore::ME_CONTROLLER) { - if(track->type() == Track::DRUM) //FINDMICHJETZT was ist das? + if(track->type() == Track::DRUM) { ctl = event.dataA(); // Regardless of what port the event came from, is it a drum controller event @@ -1049,6 +1048,24 @@ void Audio::processMidi() event.setChannel(channel); } } + else if (track->type() == Track::NEW_DRUM) //FINDMICHJETZT TEST + { + ctl = event.dataA(); + if (tport->drumController(ctl)) // is it a drum controller? + { + int pitch = ctl & 0x7f; // pitch is now the incoming pitch + pitch = track->map_drum_in(pitch); // pitch is now the mapped (recorded) pitch + event.setA(ctl & ~0xff | pitch); // map the drum ctrl's value accordingly + + if (MusEGlobal::config.newDrumRecordCondition & MusECore::DONT_REC_HIDDEN && + track->drummap_hidden()[pitch] ) + continue; // skip that event, proceed with the next + + if (MusEGlobal::config.newDrumRecordCondition & MusECore::DONT_REC_MUTED && + track->drummap()[pitch].mute ) + continue; // skip that event, proceed with the next + } + } } // MusE uses a fixed clocks per quarternote of 24. @@ -1092,7 +1109,7 @@ void Audio::processMidi() // to the track port so buildMidiEventList will accept it. Even though // the port may have no device "<none>". // - if (track->type() == Track::DRUM) //FINDMICHJETZT was ist das? + if (track->type() == Track::DRUM) //FINDMICHJETZT no changes. TEST { // Is it a drum controller event? if(mc) diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index 6957e9c1..9fd0b3ed 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -4595,6 +4595,8 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo * * CURRENT TODO * o drum controllers + * update ctrlcanvas/panel + * test! * o my record flag handling * o option for disabling old-style / new-style drum tracks? * diff --git a/muse2/muse/part.cpp b/muse2/muse/part.cpp index 3601ff57..6407dadc 100644 --- a/muse2/muse/part.cpp +++ b/muse2/muse/part.cpp @@ -403,7 +403,7 @@ void addPortCtrlEvents(Event& event, Part* part, bool doClones) MidiPort* mp = &MusEGlobal::midiPorts[port]; // Is it a drum controller event, according to the track port's instrument? - if(mt->type() == Track::DRUM) //FINDMICHJETZT was ist das? + if(mt->type() == Track::DRUM) { MidiController* mc = mp->drumController(cntrl); if(mc) @@ -471,7 +471,7 @@ void addPortCtrlEvents(Part* part, bool doClones) MidiPort* mp = &MusEGlobal::midiPorts[port]; // Is it a drum controller event, according to the track port's instrument? - if(mt->type() == Track::DRUM) //FINDMICHJETZT was ist das? + if(mt->type() == Track::DRUM) { MidiController* mc = mp->drumController(cntrl); if(mc) @@ -530,7 +530,7 @@ void removePortCtrlEvents(Event& event, Part* part, bool doClones) MidiPort* mp = &MusEGlobal::midiPorts[port]; // Is it a drum controller event, according to the track port's instrument? - if(mt->type() == Track::DRUM) //FINDMICHJETZT was ist das? + if(mt->type() == Track::DRUM) { MidiController* mc = mp->drumController(cntrl); if(mc) @@ -599,7 +599,7 @@ void removePortCtrlEvents(Part* part, bool doClones) MidiPort* mp = &MusEGlobal::midiPorts[port]; // Is it a drum controller event, according to the track port's instrument? - if(mt->type() == Track::DRUM) //FINDMICHJETZT was ist das? + if(mt->type() == Track::DRUM) { MidiController* mc = mp->drumController(cntrl); if(mc) diff --git a/muse2/muse/song.cpp b/muse2/muse/song.cpp index 98ad007a..b48f134b 100644 --- a/muse2/muse/song.cpp +++ b/muse2/muse/song.cpp @@ -446,7 +446,7 @@ bool Song::addEvent(Event& event, Part* part) MidiPort* mp = &MusEGlobal::midiPorts[track->outPort()]; // Is it a drum controller event, according to the track port's instrument? - if(track->type() == Track::DRUM) //FINDMICHJETZT was ist das? + if(track->type() == Track::DRUM) { MidiController* mc = mp->drumController(cntrl); if(mc) @@ -519,7 +519,7 @@ void Song::changeEvent(Event& oldEvent, Event& newEvent, Part* part) int cntrl = oldEvent.dataA(); MidiPort* mp = &MusEGlobal::midiPorts[track->outPort()]; // Is it a drum controller event, according to the track port's instrument? - if(track->type() == Track::DRUM) //FINDMICHJETZT was ist das? + if(track->type() == Track::DRUM) { MidiController* mc = mp->drumController(cntrl); if(mc) @@ -546,7 +546,7 @@ void Song::changeEvent(Event& oldEvent, Event& newEvent, Part* part) int val = newEvent.dataB(); MidiPort* mp = &MusEGlobal::midiPorts[track->outPort()]; // Is it a drum controller event, according to the track port's instrument? - if(track->type() == Track::DRUM) //FINDMICHJETZT was ist das? + if(track->type() == Track::DRUM) { MidiController* mc = mp->drumController(cntrl); if(mc) @@ -580,7 +580,7 @@ void Song::deleteEvent(Event& event, Part* part) MidiPort* mp = &MusEGlobal::midiPorts[track->outPort()]; // Is it a drum controller event, according to the track port's instrument? - if(track->type() == Track::DRUM) //FINDMICHJETZT was ist das? + if(track->type() == Track::DRUM) { MidiController* mc = mp->drumController(cntrl); if(mc) @@ -621,7 +621,7 @@ void Song::remapPortDrumCtrlEvents(int mapidx, int newnote, int newchan, int new for(ciMidiTrack it = _midis.begin(); it != _midis.end(); ++it) { MidiTrack* mt = *it; - if(mt->type() != Track::DRUM) //FINDMICHJETZT was ist das? drumcontroller? + if(mt->type() != Track::DRUM) continue; MidiPort* trackmp = &MusEGlobal::midiPorts[mt->outPort()]; @@ -630,7 +630,7 @@ void Song::remapPortDrumCtrlEvents(int mapidx, int newnote, int newchan, int new { MidiPart* part = (MidiPart*)(ip->second); const EventList* el = part->cevents(); - unsigned len = part->lenTick(); + // unsigned len = part->lenTick(); // Commented out by flo, see below for(ciEvent ie = el->begin(); ie != el->end(); ++ie) { const Event& ev = ie->second; @@ -693,7 +693,7 @@ void Song::changeAllPortDrumCtrlEvents(bool add, bool drumonly) for(ciMidiTrack it = _midis.begin(); it != _midis.end(); ++it) { MidiTrack* mt = *it; - if(mt->type() != Track::DRUM) //FINDMICHJETZT was ist das? drumcontroller + if(mt->type() != Track::DRUM) continue; trackmp = &MusEGlobal::midiPorts[mt->outPort()]; @@ -703,13 +703,15 @@ void Song::changeAllPortDrumCtrlEvents(bool add, bool drumonly) { MidiPart* part = (MidiPart*)(ip->second); const EventList* el = part->cevents(); - unsigned len = part->lenTick(); + // unsigned len = part->lenTick(); // Commented out by flo, see below for(ciEvent ie = el->begin(); ie != el->end(); ++ie) { const Event& ev = ie->second; // Added by T356. Do not handle events which are past the end of the part. - if(ev.tick() >= len) - break; + // Commented out by flo: yes, DO handle them! these are "hidden events" + // which may be revealed later again! + // if(ev.tick() >= len) + // break; if(ev.type() != Controller) continue; diff --git a/muse2/muse/songfile.cpp b/muse2/muse/songfile.cpp index 3096312e..b5c3382d 100644 --- a/muse2/muse/songfile.cpp +++ b/muse2/muse/songfile.cpp @@ -725,7 +725,7 @@ void Part::read(Xml& xml, int, bool toTrack) // int newPartOffset newPartOffset=this->tick(); int ctl = e.dataA(); - if(mt->type() == Track::DRUM) //FINDMICHJETZT commented out: was ist das? + if(mt->type() == Track::DRUM) { // Is it a drum controller event, according to the track port's instrument? MidiController* mc = mp->drumController(ctl); diff --git a/muse2/muse/track.cpp b/muse2/muse/track.cpp index 31504309..4140732d 100644 --- a/muse2/muse/track.cpp +++ b/muse2/muse/track.cpp @@ -78,7 +78,7 @@ void addPortCtrlEvents(MidiTrack* t) MidiPort* mp = &MusEGlobal::midiPorts[t->outPort()]; // Is it a drum controller event, according to the track port's instrument? - if(t->type() == Track::DRUM) //FINDMICHJETZT was soll das? drumcontroller -_- + if(t->type() == Track::DRUM) { MidiController* mc = mp->drumController(cntrl); if(mc) @@ -126,7 +126,7 @@ void removePortCtrlEvents(MidiTrack* t) MidiPort* mp = &MusEGlobal::midiPorts[t->outPort()]; // Is it a drum controller event, according to the track port's instrument? - if(t->type() == Track::DRUM) //FINDMICHJETZT was soll das? drumcontroller... + if(t->type() == Track::DRUM) { MidiController* mc = mp->drumController(cntrl); if(mc) @@ -504,7 +504,7 @@ void MidiTrack::init_drummap(bool write_ordering) void MidiTrack::update_drum_in_map() { for (int i=0;i<127;i++) - drum_in_map[_drummap[i].enote]=i; + drum_in_map[(int)_drummap[i].enote]=i; } //--------------------------------------------------------- @@ -667,7 +667,7 @@ void MidiTrack::addPortCtrlEvents() MidiPort* mp = &MusEGlobal::midiPorts[_outPort]; // Is it a drum controller event, according to the track port's instrument? - if(type() == DRUM) //FINDMICHJETZT commented out. was soll das? + if(type() == DRUM) { MidiController* mc = mp->drumController(cntrl); if(mc) @@ -708,7 +708,7 @@ void MidiTrack::removePortCtrlEvents() MidiPort* mp = &MusEGlobal::midiPorts[_outPort]; // Is it a drum controller event, according to the track port's instrument? - if(type() == DRUM) //FINDMICHJETZT commented out: was soll das? + if(type() == DRUM) { MidiController* mc = mp->drumController(cntrl); if(mc) diff --git a/muse2/muse/track.h b/muse2/muse/track.h index 1826f081..bbda67e4 100644 --- a/muse2/muse/track.h +++ b/muse2/muse/track.h @@ -202,6 +202,7 @@ class Track { int channels() const { return _channels; } virtual void setChannels(int n); bool isMidiTrack() const { return type() == MIDI || type() == DRUM || type() == NEW_DRUM; } + bool isDrumTrack() const { return type() == DRUM || type() == NEW_DRUM; } virtual bool canRecord() const { return false; } virtual AutomationType automationType() const = 0; virtual void setAutomationType(AutomationType t) = 0; diff --git a/muse2/muse/widgets/mtrackinfo.cpp b/muse2/muse/widgets/mtrackinfo.cpp index 33462d0c..d0c0e070 100644 --- a/muse2/muse/widgets/mtrackinfo.cpp +++ b/muse2/muse/widgets/mtrackinfo.cpp @@ -345,7 +345,7 @@ void MidiTrackInfo::heartBeat() else { MusECore::MidiInstrument* instr = mp->instrument(); - QString name = instr->getPatchName(outChannel, nprogram, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM); //FINDMICHJETZT was soll das? + QString name = instr->getPatchName(outChannel, nprogram, MusEGlobal::song->mtype(), track->isDrumTrack()); if(name.isEmpty()) { const QString n("???"); @@ -391,7 +391,7 @@ void MidiTrackInfo::heartBeat() //else //{ MusECore::MidiInstrument* instr = mp->instrument(); - QString name = instr->getPatchName(outChannel, program, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM); //FINDMICHJETZT was soll das? + QString name = instr->getPatchName(outChannel, program, MusEGlobal::song->mtype(), track->isDrumTrack()); if(iPatch->text() != name) iPatch->setText(name); @@ -762,7 +762,7 @@ void MidiTrackInfo::iProgHBankChanged() MusEGlobal::audio->msgPlayMidiEvent(&ev); MusECore::MidiInstrument* instr = mp->instrument(); - iPatch->setText(instr->getPatchName(channel, program, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM)); //FINDMICHJETZT was soll das? + iPatch->setText(instr->getPatchName(channel, program, MusEGlobal::song->mtype(), track->isDrumTrack())); // updateTrackInfo(); } @@ -840,7 +840,7 @@ void MidiTrackInfo::iProgLBankChanged() MusEGlobal::audio->msgPlayMidiEvent(&ev); MusECore::MidiInstrument* instr = mp->instrument(); - iPatch->setText(instr->getPatchName(channel, program, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM)); //FINDMICHJETZT was soll das? + iPatch->setText(instr->getPatchName(channel, program, MusEGlobal::song->mtype(), track->isDrumTrack())); // updateTrackInfo(); } @@ -918,7 +918,7 @@ void MidiTrackInfo::iProgramChanged() MusEGlobal::audio->msgPlayMidiEvent(&ev); MusECore::MidiInstrument* instr = mp->instrument(); - iPatch->setText(instr->getPatchName(channel, program, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM)); //FINDMICHJETZT was soll das? + iPatch->setText(instr->getPatchName(channel, program, MusEGlobal::song->mtype(), track->isDrumTrack())); } // updateTrackInfo(); @@ -1086,8 +1086,8 @@ void MidiTrackInfo::instrPopup() //QMenu* pup = new QMenu; PopupMenu* pup = new PopupMenu(true); - //instr->populatePatchPopup(pop, channel, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM); - populatePatchPopup(instr, pup, channel, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM); //FINDMICHJETZT was soll das? + //instr->populatePatchPopup(pop, channel, MusEGlobal::song->mtype(), track->isDrumTrack()); + populatePatchPopup(instr, pup, channel, MusEGlobal::song->mtype(), track->isDrumTrack()); //if(pop->actions().count() == 0) // return; @@ -1411,7 +1411,7 @@ void MidiTrackInfo::updateTrackInfo(int flags) else { MusECore::MidiInstrument* instr = mp->instrument(); - iPatch->setText(instr->getPatchName(outChannel, nprogram, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM)); //FINDMICHJETZT was soll das? + iPatch->setText(instr->getPatchName(outChannel, nprogram, MusEGlobal::song->mtype(), track->isDrumTrack())); } } else @@ -1427,7 +1427,7 @@ void MidiTrackInfo::updateTrackInfo(int flags) //else //{ MusECore::MidiInstrument* instr = mp->instrument(); - iPatch->setText(instr->getPatchName(outChannel, program, MusEGlobal::song->mtype(), track->type() == MusECore::Track::DRUM)); //FINDMICHJETZT was soll das? + iPatch->setText(instr->getPatchName(outChannel, program, MusEGlobal::song->mtype(), track->isDrumTrack())); int hb = ((program >> 16) & 0xff) + 1; if (hb == 0x100) -- cgit v1.2.3 From f6fd0c7b4979612ed34a222c02d43e81ebaddf7e Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Sun, 16 Oct 2011 19:22:35 +0000 Subject: ctrlcanvas stuff. not ready yet BUGGY! problem is: while changing entries, ourDrumMap may be reallocated which causes abort()s and/or bugs. --- muse2/muse/ctrl/ctrlcanvas.cpp | 71 +++++++++++++------- muse2/muse/ctrl/ctrlcanvas.h | 6 +- muse2/muse/ctrl/ctrledit.cpp | 6 +- muse2/muse/ctrl/ctrlpanel.cpp | 132 ++++++++++++++++++++++++-------------- muse2/muse/ctrl/ctrlpanel.h | 4 +- muse2/muse/midiedit/dcanvas.cpp | 43 ++++++++++--- muse2/muse/midiedit/dlist.cpp | 24 +++++-- muse2/muse/midiedit/drumedit.h | 3 + muse2/muse/midiedit/scoreedit.cpp | 1 + 9 files changed, 202 insertions(+), 88 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/ctrl/ctrlcanvas.cpp b/muse2/muse/ctrl/ctrlcanvas.cpp index 9c5d636f..6e09e337 100644 --- a/muse2/muse/ctrl/ctrlcanvas.cpp +++ b/muse2/muse/ctrl/ctrlcanvas.cpp @@ -39,6 +39,7 @@ #include "gconfig.h" #include "ctrlpanel.h" #include "midiedit/drummap.h" +#include "drumedit.h" static MusECore::MidiCtrlValList veloList(MusECore::CTRL_VELOCITY); // dummy @@ -211,6 +212,11 @@ CtrlCanvas::CtrlCanvas(MidiEditor* e, QWidget* parent, int xmag, noEvents=false; //_isFirstMove = true; //_lastDelta = QPoint(0, 0); + + if (dynamic_cast<DrumEdit*>(editor) && dynamic_cast<DrumEdit*>(editor)->old_style_drummap_mode()==false) + filterTrack=true; + else + filterTrack=false; ctrl = &veloList; _controller = &MusECore::veloCtrl; @@ -231,10 +237,10 @@ CtrlCanvas::CtrlCanvas(MidiEditor* e, QWidget* parent, int xmag, connect(MusEGlobal::song, SIGNAL(songChanged(int)), SLOT(songChanged(int))); connect(MusEGlobal::muse, SIGNAL(configChanged()), SLOT(configChanged())); - curDrumInstrument = editor->curDrumInstrument(); - //printf("CtrlCanvas::CtrlCanvas curDrumInstrument:%d\n", curDrumInstrument); + setCurDrumPitch(editor->curDrumInstrument()); + //printf("CtrlCanvas::CtrlCanvas curDrumPitch:%d\n", curDrumPitch); - connect(editor, SIGNAL(curDrumInstrumentChanged(int)), SLOT(setCurDrumInstrument(int))); + connect(editor, SIGNAL(curDrumInstrumentChanged(int)), SLOT(setCurDrumPitch(int))); updateItems(); } @@ -537,15 +543,21 @@ void CtrlCanvas::partControllers(const MusECore::MidiPart* part, int num, int* d int di; int n; - if((mt->type() != MusECore::Track::DRUM) && curDrumInstrument != -1) //FINDMICHJETZT was ist das? + if(!mt->isDrumTrack() && curDrumPitch != -1) printf("keyfilter != -1 in non drum track?\n"); - if((mt->type() == MusECore::Track::DRUM) && (curDrumInstrument != -1) && ((num & 0xff) == 0xff)) //FINDMICHJETZT was ist das? + if((mt->type() == MusECore::Track::DRUM) && (curDrumPitch != -1) && ((num & 0xff) == 0xff)) + { + di = (num & ~0xff) | curDrumPitch; + n = (num & ~0xff) | MusEGlobal::drumMap[curDrumPitch].anote; // construct real controller number + //num = (num & ~0xff) | curDrumPitch); // construct real controller number + mp = &MusEGlobal::midiPorts[MusEGlobal::drumMap[curDrumPitch].port]; + } + else if ((mt->type() == MusECore::Track::NEW_DRUM) && (curDrumPitch != -1) && ((num & 0xff) == 0xff)) //FINDMICHJETZT does this work? { - di = (num & ~0xff) | curDrumInstrument; - n = (num & ~0xff) | MusEGlobal::drumMap[curDrumInstrument].anote; // construct real controller number - //num = (num & ~0xff) | curDrumInstrument); // construct real controller number - mp = &MusEGlobal::midiPorts[MusEGlobal::drumMap[curDrumInstrument].port]; + di = (num & ~0xff) | curDrumPitch; + n = (num & ~0xff) | curDrumPitch; + mp = &MusEGlobal::midiPorts[mt->outPort()]; } else { @@ -601,6 +613,10 @@ void CtrlCanvas::updateItems() CEvent* lastce = 0; MusECore::MidiPart* part = (MusECore::MidiPart*)(p->second); + + if (filterTrack && part->track() != curTrack) + continue; + MusECore::EventList* el = part->events(); //MusECore::MidiController* mc; MusECore::MidiCtrlValList* mcvl; @@ -617,15 +633,15 @@ void CtrlCanvas::updateItems() if(_cnum == MusECore::CTRL_VELOCITY && e.type() == MusECore::Note) { - //printf("CtrlCanvas::updateItems MusECore::CTRL_VELOCITY curDrumInstrument:%d\n", curDrumInstrument); + //printf("CtrlCanvas::updateItems MusECore::CTRL_VELOCITY curDrumPitch:%d\n", curDrumPitch); newev = 0; - if(curDrumInstrument == -1) + if(curDrumPitch == -1) { // This is interesting - it would allow ALL drum note velocities to be shown. // But currently the drum list ALWAYS has a selected item so this is not supposed to happen. items.add(newev = new CEvent(e, part, e.velo())); } - else if (e.dataA() == curDrumInstrument) //same note + else if (e.dataA() == curDrumPitch) //same note items.add(newev = new CEvent(e, part, e.velo())); if(newev && e.selected()) selection.push_back(newev); @@ -795,7 +811,7 @@ void CtrlCanvas::viewMouseMoveEvent(QMouseEvent* event) if (!moving) break; drag = DRAG_LASSO; - // weiter mit DRAG_LASSO: + // fallthrough case DRAG_LASSO: lasso.setRect(start.x(), start.y(), dist.x(), dist.y()); redraw(); @@ -857,7 +873,7 @@ void CtrlCanvas::viewMouseReleaseEvent(QMouseEvent* event) case DRAG_LASSO_START: lasso.setRect(-1, -1, -1, -1); - + //fallthrough case DRAG_LASSO: if(_controller) // p4.0.27 { @@ -1690,8 +1706,8 @@ void CtrlCanvas::pdrawItems(QPainter& p, const QRect& rect, const MusECore::Midi MusECore::MidiTrack* mt = part->track(); MusECore::MidiPort* mp; - if((mt->type() == MusECore::Track::DRUM) && (curDrumInstrument != -1) && ((_cnum & 0xff) == 0xff)) //FINDMICHJETZT was ist das? - mp = &MusEGlobal::midiPorts[MusEGlobal::drumMap[curDrumInstrument].port]; + if((mt->type() == MusECore::Track::DRUM) && (curDrumPitch != -1) && ((_cnum & 0xff) == 0xff)) + mp = &MusEGlobal::midiPorts[MusEGlobal::drumMap[curDrumPitch].port]; else mp = &MusEGlobal::midiPorts[mt->outPort()]; @@ -1857,7 +1873,7 @@ void CtrlCanvas::pdraw(QPainter& p, const QRect& rect) { MusECore::MidiPart* part = (MusECore::MidiPart*)(ip->second); //if((velo && part == curPart) || (!velo && part != curPart)) - if(part == curPart) + if(part == curPart || (filterTrack && part->track() != curTrack)) continue; // Draw items for all parts - other than current part pdrawItems(p, rect, part, velo, !velo); @@ -1978,13 +1994,24 @@ void CtrlCanvas::draw(QPainter& p, const QRect& rect) } //--------------------------------------------------------- -// setCurDrumInstrument +// setCurDrumPitch //--------------------------------------------------------- -void CtrlCanvas::setCurDrumInstrument(int di) +void CtrlCanvas::setCurDrumPitch(int instrument) +{ + DrumEdit* drumedit = dynamic_cast<DrumEdit*>(editor); + if (drumedit == NULL || drumedit->old_style_drummap_mode()) + curDrumPitch = instrument; + else // new style drummap mode { - curDrumInstrument = di; - //printf("CtrlCanvas::setCurDrumInstrument curDrumInstrument:%d\n", curDrumInstrument); + if (drumedit->get_instrument_map()[instrument].tracks.contains(curTrack)) + curDrumPitch = drumedit->get_instrument_map()[instrument].pitch; + else + curDrumPitch = -1; + } + + + //printf("CtrlCanvas::setCurDrumPitch curDrumPitch:%d\n", curDrumPitch); // // check if current controller is only valid for @@ -2000,6 +2027,6 @@ void CtrlCanvas::setCurDrumInstrument(int di) // } // Removed by T356 //songChanged(-1); - } +} } // namespace MusEGui diff --git a/muse2/muse/ctrl/ctrlcanvas.h b/muse2/muse/ctrl/ctrlcanvas.h index 815898ac..79910b94 100644 --- a/muse2/muse/ctrl/ctrlcanvas.h +++ b/muse2/muse/ctrl/ctrlcanvas.h @@ -121,6 +121,7 @@ class CtrlCanvas : public MusEGui::View { int line2y; bool drawLineMode; bool noEvents; + bool filterTrack; void viewMousePressEvent(QMouseEvent* event); void viewMouseMoveEvent(QMouseEvent*); @@ -161,7 +162,7 @@ class CtrlCanvas : public MusEGui::View { QPoint start; MusEGui::Tool tool; unsigned pos[3]; - int curDrumInstrument; //Used by the drum-editor to view velocity of only one key (one drum) + int curDrumPitch; //Used by the drum-editor to view velocity of only one key (one drum) void leaveEvent(QEvent*e); QPoint raster(const QPoint&) const; @@ -179,7 +180,7 @@ class CtrlCanvas : public MusEGui::View { private slots: void songChanged(int type); void configChanged(); - void setCurDrumInstrument(int); + void setCurDrumPitch(int); public slots: void setTool(int t); @@ -199,6 +200,7 @@ class CtrlCanvas : public MusEGui::View { MusECore::MidiCtrlValList* ctrlValList() { return ctrl; } MusECore::MidiController* controller() { return _controller; } MusECore::MidiTrack* track() const { return curTrack; } + int getCurDrumPitch() const { return curDrumPitch; } }; } // namespace MusEGui diff --git a/muse2/muse/ctrl/ctrledit.cpp b/muse2/muse/ctrl/ctrledit.cpp index 7c960dd8..5ce6a7bb 100644 --- a/muse2/muse/ctrl/ctrledit.cpp +++ b/muse2/muse/ctrl/ctrledit.cpp @@ -55,8 +55,10 @@ CtrlEdit::CtrlEdit(QWidget* parent, MidiEditor* e, int xmag, setObjectName(name); setAttribute(Qt::WA_DeleteOnClose); QHBoxLayout* hbox = new QHBoxLayout; - panel = new CtrlPanel(0, e, "panel"); - canvas = new CtrlCanvas(e, 0, xmag, "ctrlcanvas", panel); + canvas = new CtrlCanvas(e, 0, xmag, "ctrlcanvas"); + panel = new CtrlPanel(0, e, canvas, "panel"); + canvas->setPanel(panel); + QWidget* vscale = new MusEGui::VScale; hbox->setContentsMargins(0, 0, 0, 0); diff --git a/muse2/muse/ctrl/ctrlpanel.cpp b/muse2/muse/ctrl/ctrlpanel.cpp index 5e07e5f3..ed83bab8 100644 --- a/muse2/muse/ctrl/ctrlpanel.cpp +++ b/muse2/muse/ctrl/ctrlpanel.cpp @@ -64,7 +64,7 @@ namespace MusEGui { // CtrlPanel //--------------------------------------------------------- -CtrlPanel::CtrlPanel(QWidget* parent, MidiEditor* e, const char* name) +CtrlPanel::CtrlPanel(QWidget* parent, MidiEditor* e, CtrlCanvas* c, const char* name) : QWidget(parent) { setObjectName(name); @@ -72,6 +72,7 @@ CtrlPanel::CtrlPanel(QWidget* parent, MidiEditor* e, const char* name) //ctrlMainPop = 0; //ctrlSubPop = 0; editor = e; + ctrlcanvas = c; setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding)); QVBoxLayout* vbox = new QVBoxLayout; QHBoxLayout* bbox = new QHBoxLayout; @@ -170,11 +171,11 @@ void CtrlPanel::heartBeat() { int outport; int chan; - int cdi = editor->curDrumInstrument(); - if(_track->type() == MusECore::Track::DRUM && ((_ctrl->num() & 0xff) == 0xff) && cdi != -1) + int cdp = ctrlcanvas->getCurDrumPitch(); + if(_track->type() == MusECore::Track::DRUM && ((_ctrl->num() & 0xff) == 0xff) && cdp != -1) { - outport = MusEGlobal::drumMap[cdi].port; - chan = MusEGlobal::drumMap[cdi].channel; + outport = MusEGlobal::drumMap[cdp].port; + chan = MusEGlobal::drumMap[cdp].channel; } else { @@ -248,11 +249,11 @@ void CtrlPanel::labelDoubleClicked() int outport; int chan; - int cdi = editor->curDrumInstrument(); - if(_track->type() == MusECore::Track::DRUM && ((_ctrl->num() & 0xff) == 0xff) && cdi != -1) + int cdp = ctrlcanvas->getCurDrumPitch(); + if(_track->type() == MusECore::Track::DRUM && ((_ctrl->num() & 0xff) == 0xff) && cdp != -1) { - outport = MusEGlobal::drumMap[cdi].port; - chan = MusEGlobal::drumMap[cdi].channel; + outport = MusEGlobal::drumMap[cdp].port; + chan = MusEGlobal::drumMap[cdp].channel; } else { @@ -352,11 +353,11 @@ void CtrlPanel::ctrlChanged(double val) int outport; int chan; - int cdi = editor->curDrumInstrument(); - if(_track->type() == MusECore::Track::DRUM && ((_ctrl->num() & 0xff) == 0xff) && cdi != -1) + int cdp = ctrlcanvas->getCurDrumPitch(); + if(_track->type() == MusECore::Track::DRUM && ((_ctrl->num() & 0xff) == 0xff) && cdp != -1) { - outport = MusEGlobal::drumMap[cdi].port; - chan = MusEGlobal::drumMap[cdi].channel; + outport = MusEGlobal::drumMap[cdp].port; + chan = MusEGlobal::drumMap[cdp].channel; } else { @@ -421,13 +422,19 @@ void CtrlPanel::setHWController(MusECore::MidiTrack* t, MusECore::MidiController MusECore::MidiPort* mp; int ch; - int cdi = editor->curDrumInstrument(); + int cdp = ctrlcanvas->getCurDrumPitch(); _dnum = _ctrl->num(); - if(_track->type() == MusECore::Track::DRUM && ((_dnum & 0xff) == 0xff) && cdi != -1) + if(_track->type() == MusECore::Track::DRUM && ((_dnum & 0xff) == 0xff) && cdp != -1) { - _dnum = (_dnum & ~0xff) | MusEGlobal::drumMap[cdi].anote; - mp = &MusEGlobal::midiPorts[MusEGlobal::drumMap[cdi].port]; - ch = MusEGlobal::drumMap[cdi].channel; + _dnum = (_dnum & ~0xff) | MusEGlobal::drumMap[cdp].anote; + mp = &MusEGlobal::midiPorts[MusEGlobal::drumMap[cdp].port]; + ch = MusEGlobal::drumMap[cdp].channel; + } + else if(_track->type() == MusECore::Track::NEW_DRUM && ((_dnum & 0xff) == 0xff) && cdp != -1) + { + _dnum = (_dnum & ~0xff) | cdp; //FINDMICHJETZT does that work? + mp = &MusEGlobal::midiPorts[_track->outPort()]; + ch = _track->outChannel(); } else { @@ -576,8 +583,9 @@ void CtrlPanel::ctrlPopup() MusECore::MidiTrack* track = (MusECore::MidiTrack*)(part->track()); int channel = track->outChannel(); MusECore::MidiPort* port = &MusEGlobal::midiPorts[track->outPort()]; - int curDrumInstrument = editor->curDrumInstrument(); + int curDrumPitch = ctrlcanvas->getCurDrumPitch(); bool isDrum = track->type() == MusECore::Track::DRUM; + bool isNewDrum = track->type() == MusECore::Track::NEW_DRUM; QMenu* pop = new QMenu; //pop->clear(); @@ -595,12 +603,20 @@ void CtrlPanel::ctrlPopup() MusECore::MidiController* c = port->midiController(cl->num()); // dont show drum specific controller if not a drum track if ((c->num() & 0xff) == 0xff) { - if (!isDrum) - continue; - // only show controller for curDrumInstrument: - if ((cl->num() & 0xff) != MusEGlobal::drumMap[curDrumInstrument].anote) { - continue; - } + if (isDrum) + { + // only show controller for curDrumPitch: + if ((curDrumPitch == -1) || ((cl->num() & 0xff) != MusEGlobal::drumMap[curDrumPitch].anote)) + continue; + } + else if (isNewDrum) + { + // only show controller for curDrumPitch: FINDMICH does this work? + if ((curDrumPitch == -1) || ((cl->num() & 0xff) != curDrumPitch)) + continue; + } + else + continue; } isList i = sList.begin(); for (; i != sList.end(); ++i) { @@ -663,8 +679,10 @@ void CtrlPanel::ctrlPopup() for (iMusECore::MidiController ci = mcl->begin(); ci != mcl->end(); ++ci) { int num = ci->second->num(); - if (isDrum && ((num & 0xff) == 0xff)) - num = (num & ~0xff) + MusEGlobal::drumMap[curDrumInstrument].anote; + if (isDrum && ((num & 0xff) == 0xff) && curDrumPitch!=-1) + num = (num & ~0xff) + MusEGlobal::drumMap[curDrumPitch].anote; + if (isNewDrum && ((num & 0xff) == 0xff) && curDrumPitch!=-1) //FINDMICHJETZT does this work? + num = (num & ~0xff) + curDrumPitch; if(cll->find(channel, num) == cll->end()) pop1->addAction(ci->second->name()); @@ -677,8 +695,10 @@ void CtrlPanel::ctrlPopup() c = ci->second; if (c->name() == s) { int num = c->num(); - if (isDrum && ((num & 0xff) == 0xff)) - num = (num & ~0xff) + MusEGlobal::drumMap[curDrumInstrument].anote; + if (isDrum && ((num & 0xff) == 0xff) && curDrumPitch!=-1) + num = (num & ~0xff) + MusEGlobal::drumMap[curDrumPitch].anote; + if (isNewDrum && ((num & 0xff) == 0xff) && curDrumPitch!=-1) //FINDMICHJETZT does this work? + num = (num & ~0xff) + curDrumPitch; if(cll->find(channel, num) == cll->end()) { @@ -734,8 +754,9 @@ void CtrlPanel::ctrlPopup() MusECore::MidiTrack* track = (MusECore::MidiTrack*)(part->track()); int channel = track->outChannel(); MusECore::MidiPort* port = &MusEGlobal::midiPorts[track->outPort()]; - int curDrumInstrument = editor->curDrumInstrument(); - bool isDrum = track->type() == MusECore::Track::DRUM; //FINDMICHJETZT ist das wichtig? + int curDrumPitch = ctrlcanvas->getCurDrumPitch(); + bool isDrum = track->type() == MusECore::Track::DRUM; + bool isNewDrum = track->type() == MusECore::Track::NEW_DRUM; MusECore::MidiInstrument* instr = port->instrument(); MusECore::MidiControllerList* mcl = instr->controller(); @@ -751,12 +772,20 @@ void CtrlPanel::ctrlPopup() MusECore::MidiController* c = port->midiController(cl->num()); // dont show drum specific controller if not a drum track if ((c->num() & 0xff) == 0xff) { - if (!isDrum) - continue; - // only show controller for curDrumInstrument: - if ((cl->num() & 0xff) != MusEGlobal::drumMap[curDrumInstrument].anote) { - continue; - } + if (isDrum) + { + // only show controller for curDrumPitch: + if ((curDrumPitch == -1) || ((cl->num() & 0xff) != MusEGlobal::drumMap[curDrumPitch].anote)) + continue; + } + else if (isNewDrum) + { + // only show controller for curDrumPitch: FINDMICH does this work? + if ((curDrumPitch == -1) || ((cl->num() & 0xff) != curDrumPitch)) + continue; + } + else + continue; } isList i = sList.begin(); for (; i != sList.end(); ++i) { @@ -866,10 +895,12 @@ void CtrlPanel::ctrlPopup() int num = ci->second->num(); if((num & 0xff) == 0xff) { - // dont show drum specific controller if not a drum track - if(!isDrum) + if (isDrum && curDrumPitch!=-1) + num = (num & ~0xff) + MusEGlobal::drumMap[curDrumPitch].anote; + else if (isNewDrum && curDrumPitch!=-1) + num = (num & ~0xff) + curDrumPitch; //FINDMICH does this work? + else // dont show drum specific controller if not a drum track continue; - num = (num & ~0xff) + MusEGlobal::drumMap[curDrumInstrument].anote; } if(cll->find(channel, num) == cll->end()) @@ -896,8 +927,10 @@ void CtrlPanel::ctrlPopup() { c = ci->second; int num = c->num(); - if (isDrum && ((num & 0xff) == 0xff)) - num = (num & ~0xff) + MusEGlobal::drumMap[curDrumInstrument].anote; + if (isDrum && ((num & 0xff) == 0xff) && curDrumPitch!=-1) + num = (num & ~0xff) + MusEGlobal::drumMap[curDrumPitch].anote; + else if (isNewDrum && ((num & 0xff) == 0xff) && curDrumPitch!=-1) + num = (num & ~0xff) + curDrumPitch; //FINDMICHJETZT does this work? if(num != rv2) continue; @@ -933,8 +966,11 @@ void CtrlPanel::ctrlPopup() if (act2) { int rv2 = act2->data().toInt(); int num = rv2; - if (isDrum && ((num & 0xff) == 0xff)) - num = (num & ~0xff) + MusEGlobal::drumMap[curDrumInstrument].anote; + if (isDrum && ((num & 0xff) == 0xff) && curDrumPitch!=-1) + num = (num & ~0xff) + MusEGlobal::drumMap[curDrumPitch].anote; + if (isNewDrum && ((num & 0xff) == 0xff) && curDrumPitch!=-1) + num = (num & ~0xff) + curDrumPitch; //FINDMICHJETZT does this work? + if(cll->find(channel, num) == cll->end()) { MusECore::MidiCtrlValList* vl = new MusECore::MidiCtrlValList(num); @@ -981,11 +1017,11 @@ void CtrlPanel::ctrlRightClicked(const QPoint& p, int /*id*/) if(!editor->curCanvasPart() || !_ctrl) return; - int cdi = editor->curDrumInstrument(); + int cdp = ctrlcanvas->getCurDrumPitch(); int ctlnum = _ctrl->num(); - if(_track->type() == MusECore::Track::DRUM && ((ctlnum & 0xff) == 0xff) && cdi != -1) - //ctlnum = (ctlnum & ~0xff) | MusEGlobal::drumMap[cdi].enote; - ctlnum = (ctlnum & ~0xff) | cdi; + if(_track->type() == MusECore::Track::DRUM && ((ctlnum & 0xff) == 0xff) && cdp != -1) + //ctlnum = (ctlnum & ~0xff) | MusEGlobal::drumMap[cdp].enote; + ctlnum = (ctlnum & ~0xff) | cdp; MusECore::MidiPart* part = dynamic_cast<MusECore::MidiPart*>(editor->curCanvasPart()); MusEGlobal::song->execMidiAutomationCtlPopup(0, part, p, ctlnum); diff --git a/muse2/muse/ctrl/ctrlpanel.h b/muse2/muse/ctrl/ctrlpanel.h index c28708cb..ab6c1777 100644 --- a/muse2/muse/ctrl/ctrlpanel.h +++ b/muse2/muse/ctrl/ctrlpanel.h @@ -37,6 +37,7 @@ namespace MusEGui { class DoubleLabel; class Knob; class MidiEditor; +class CtrlCanvas; //--------------------------------------------------------- // CtrlPanel @@ -48,6 +49,7 @@ class CtrlPanel: public QWidget { //QMenu* pop; QPushButton* selCtrl; MidiEditor* editor; + CtrlCanvas* ctrlcanvas; MusECore::MidiTrack* _track; MusECore::MidiController* _ctrl; @@ -77,7 +79,7 @@ class CtrlPanel: public QWidget { void ctrlPopup(); public: - CtrlPanel(QWidget*, MidiEditor*, const char* name = 0); + CtrlPanel(QWidget*, MidiEditor*, CtrlCanvas*, const char* name = 0); void setHWController(MusECore::MidiTrack* t, MusECore::MidiController* ctrl); }; diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp index ec17b655..d024422c 100644 --- a/muse2/muse/midiedit/dcanvas.cpp +++ b/muse2/muse/midiedit/dcanvas.cpp @@ -304,7 +304,9 @@ bool DrumCanvas::moveItem(MusECore::Undo& operations, CItem* item, const QPoint& MusECore::MidiPart* dest_part = part; int nheight = y2pitch(pos.y()); - + if (nheight<0) nheight=0; + if (nheight>=getOurDrumMapSize()) nheight=getOurDrumMapSize()-1; + if (!instrument_map[nheight].tracks.contains(dest_part->track())) { if (debugMsg) @@ -361,6 +363,9 @@ bool DrumCanvas::moveItem(MusECore::Undo& operations, CItem* item, const QPoint& CItem* DrumCanvas::newItem(const QPoint& p, int state) { int instr = y2pitch(p.y()); //MusEGlobal::drumInmap[y2pitch(p.y())]; + if ((instr<0) || (instr>=getOurDrumMapSize())) + return NULL; + int velo = ourDrumMap[instr].lv4; if (state == Qt::ShiftModifier) velo = ourDrumMap[instr].lv3; @@ -378,6 +383,9 @@ CItem* DrumCanvas::newItem(const QPoint& p, int state) CItem* DrumCanvas::newItem(int tick, int instrument, int velocity) { + if ((instrument<0) || (instrument>=getOurDrumMapSize())) + return NULL; + if (!old_style_drummap_mode && !instrument_map[instrument].tracks.contains(curPart->track())) { if (debugMsg) @@ -634,6 +642,8 @@ int DrumCanvas::y2pitch(int y) const int pitch = y/TH; if (pitch >= instrument_map.size()) pitch = instrument_map.size()-1; + else if (pitch<0) + pitch = 0; return pitch; } @@ -849,6 +859,9 @@ void DrumCanvas::keyPressed(int index, int velocity) { using MusECore::MidiTrack; + if ((index<0) || (index>=getOurDrumMapSize())) + return; + // called from DList - play event int port = old_style_drummap_mode ? ourDrumMap[index].port : dynamic_cast<MidiTrack*>(*instrument_map[index].tracks.begin())->outPort(); int channel = old_style_drummap_mode ? ourDrumMap[index].channel : dynamic_cast<MidiTrack*>(*instrument_map[index].tracks.begin())->outChannel(); @@ -884,6 +897,9 @@ void DrumCanvas::keyReleased(int index, bool) { using MusECore::MidiTrack; + if ((index<0) || (index>=getOurDrumMapSize())) + return; + // called from DList - silence playing event int port = old_style_drummap_mode ? ourDrumMap[index].port : dynamic_cast<MidiTrack*>(*instrument_map[index].tracks.begin())->outPort(); int channel = old_style_drummap_mode ? ourDrumMap[index].channel : dynamic_cast<MidiTrack*>(*instrument_map[index].tracks.begin())->outChannel(); @@ -1006,15 +1022,24 @@ void DrumCanvas::mapChanged(int spitch, int dpitch) } // 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()); + // which will be immediately AFTER our dragged instrument. or it's invalid + if (dpitch < getOurDrumMapSize()) + { + 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; - } + break; + } + } + else + { + global_drum_ordering_t::iterator it=global_drum_ordering.end(); + while (!order_temp.empty()) + it=global_drum_ordering.insert(it, order_temp.takeLast()); + } diff --git a/muse2/muse/midiedit/dlist.cpp b/muse2/muse/midiedit/dlist.cpp index 2d4561e0..bcdbad79 100644 --- a/muse2/muse/midiedit/dlist.cpp +++ b/muse2/muse/midiedit/dlist.cpp @@ -296,7 +296,9 @@ void DList::viewMousePressEvent(QMouseEvent* ev) int x = ev->x(); int y = ev->y(); int button = ev->button(); - unsigned instrument = y / TH; + int instrument = y / TH; + if (instrument >= ourDrumMapSize) instrument=ourDrumMapSize-1; + if (instrument < 0) instrument=0; MusECore::DrumMap* dm = &ourDrumMap[instrument]; MusECore::DrumMap dm_old = *dm; @@ -551,7 +553,7 @@ void DList::viewMousePressEvent(QMouseEvent* ev) } if (!old_style_drummap_mode && dm_old != *dm) //something changed and we're in new style mode? - dcanvas->propagate_drummap_change(dm-ourDrumMap, (dm_old.enote != dm->enote)); + dcanvas->propagate_drummap_change(instrument, (dm_old.enote != dm->enote)); MusEGlobal::song->update(SC_DRUMMAP); //redraw(); //this is done by the songChanged slot @@ -588,6 +590,9 @@ void DList::viewMouseDoubleClickEvent(QMouseEvent* ev) //--------------------------------------------------------- void DList::lineEdit(int line, int section) { + if (line >= ourDrumMapSize) line=ourDrumMapSize-1; + if (line < 0) line=0; + MusECore::DrumMap* dm = &ourDrumMap[line]; editEntry = dm; if (editor == 0) { @@ -656,6 +661,9 @@ void DList::lineEdit(int line, int section) //--------------------------------------------------------- void DList::pitchEdit(int line, int section) { + if (line >= ourDrumMapSize) line=ourDrumMapSize-1; + if (line < 0) line=0; + MusECore::DrumMap* dm = &ourDrumMap[line]; editEntry = dm; if (pitch_editor == 0) { @@ -710,7 +718,7 @@ int DList::x2col(int x) const void DList::setCurDrumInstrument(int instr) { - if (instr < 0 || instr >= ourDrumMapSize -1) + if (instr < 0 || instr >= ourDrumMapSize) return; // illegal instrument MusECore::DrumMap* dm = &ourDrumMap[instr]; if (currentlySelected != dm) { @@ -1022,7 +1030,14 @@ void DList::viewMouseReleaseEvent(QMouseEvent* ev) dInstrument = (y+TH/2) / TH; if (dInstrument < 0) dInstrument=0; - if (dInstrument >= ourDrumMapSize) dInstrument=ourDrumMapSize-1; + if (old_style_drummap_mode) + { + if (dInstrument >= ourDrumMapSize) dInstrument=ourDrumMapSize-1; + } + else + { + if (dInstrument > ourDrumMapSize) dInstrument=ourDrumMapSize; // allow moving something below the last element + } int cur_sel = (!old_style_drummap_mode && dInstrument>sInstrument) ? dInstrument-1 : dInstrument; @@ -1077,6 +1092,7 @@ void DList::ourDrumMapChanged(bool instrMapChanged) editEntry=NULL; if (selIdx >= ourDrumMapSize) selIdx=ourDrumMapSize-1; + if (selIdx < 0) selIdx=0; currentlySelected = &ourDrumMap[selIdx]; redraw(); diff --git a/muse2/muse/midiedit/drumedit.h b/muse2/muse/midiedit/drumedit.h index b860da80..08f485e7 100644 --- a/muse2/muse/midiedit/drumedit.h +++ b/muse2/muse/midiedit/drumedit.h @@ -33,6 +33,7 @@ #include "header.h" #include "shortcuts.h" #include "event.h" +#include "dcanvas.h" //FINDMICH UGLY. remove! class QCloseEvent; class QLabel; @@ -182,6 +183,8 @@ class DrumEdit : public MidiEditor { bool old_style_drummap_mode(); group_mode_t group_mode() { return _group_mode; } bool ignore_hide() { return _ignore_hide; } + + QVector<instrument_number_mapping_t>& get_instrument_map() { return static_cast<DrumCanvas*>(canvas)->get_instrument_map(); } //FINDMICH UGLY }; } // namespace MusEGui diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index 9fd0b3ed..2d24fa54 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -4597,6 +4597,7 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo * o drum controllers * update ctrlcanvas/panel * test! + * o don't mix DRUM and NEW_DRUM in drumeditor! * o my record flag handling * o option for disabling old-style / new-style drum tracks? * -- cgit v1.2.3 From 9977c7114089b8708d310268833b83343caa0fd1 Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Sun, 16 Oct 2011 20:24:28 +0000 Subject: small fixes --- muse2/muse/ctrl/ctrlcanvas.cpp | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/ctrl/ctrlcanvas.cpp b/muse2/muse/ctrl/ctrlcanvas.cpp index 6e09e337..f592d4d3 100644 --- a/muse2/muse/ctrl/ctrlcanvas.cpp +++ b/muse2/muse/ctrl/ctrlcanvas.cpp @@ -337,7 +337,7 @@ void CtrlCanvas::setMidiController(int num) _panel->setHWController(curTrack, &MusECore::veloCtrl); else _panel->setHWController(curTrack, _controller); - } + } } //--------------------------------------------------------- @@ -546,14 +546,14 @@ void CtrlCanvas::partControllers(const MusECore::MidiPart* part, int num, int* d if(!mt->isDrumTrack() && curDrumPitch != -1) printf("keyfilter != -1 in non drum track?\n"); - if((mt->type() == MusECore::Track::DRUM) && (curDrumPitch != -1) && ((num & 0xff) == 0xff)) + 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 //num = (num & ~0xff) | curDrumPitch); // construct real controller number mp = &MusEGlobal::midiPorts[MusEGlobal::drumMap[curDrumPitch].port]; } - else if ((mt->type() == MusECore::Track::NEW_DRUM) && (curDrumPitch != -1) && ((num & 0xff) == 0xff)) //FINDMICHJETZT does this work? + else if ((mt->type() == MusECore::Track::NEW_DRUM) && (curDrumPitch > 0) && ((num & 0xff) == 0xff)) //FINDMICHJETZT does this work? { di = (num & ~0xff) | curDrumPitch; n = (num & ~0xff) | curDrumPitch; @@ -635,13 +635,13 @@ void CtrlCanvas::updateItems() { //printf("CtrlCanvas::updateItems MusECore::CTRL_VELOCITY curDrumPitch:%d\n", curDrumPitch); newev = 0; - if(curDrumPitch == -1) + if (curDrumPitch == -1) // and NOT >0 { // This is interesting - it would allow ALL drum note velocities to be shown. // But currently the drum list ALWAYS has a selected item so this is not supposed to happen. items.add(newev = new CEvent(e, part, e.velo())); } - else if (e.dataA() == curDrumPitch) //same note + else if (e.dataA() == curDrumPitch) //same note. if curDrumPitch==-2, this never is true items.add(newev = new CEvent(e, part, e.velo())); if(newev && e.selected()) selection.push_back(newev); @@ -692,7 +692,7 @@ void CtrlCanvas::updateSelections() void CtrlCanvas::viewMousePressEvent(QMouseEvent* event) { - if(!_controller) // p4.0.27 + if(!_controller || curDrumPitch==-2) // p4.0.27 return; start = event->pos(); @@ -800,7 +800,7 @@ void CtrlCanvas::viewMousePressEvent(QMouseEvent* event) void CtrlCanvas::viewMouseMoveEvent(QMouseEvent* event) { - if(!_controller) // p4.0.27 + if(!_controller || curDrumPitch==-2) // p4.0.27 return; QPoint pos = event->pos(); @@ -1706,7 +1706,7 @@ void CtrlCanvas::pdrawItems(QPainter& p, const QRect& rect, const MusECore::Midi MusECore::MidiTrack* mt = part->track(); MusECore::MidiPort* mp; - if((mt->type() == MusECore::Track::DRUM) && (curDrumPitch != -1) && ((_cnum & 0xff) == 0xff)) + if((mt->type() == MusECore::Track::DRUM) && (curDrumPitch > 0) && ((_cnum & 0xff) == 0xff)) mp = &MusEGlobal::midiPorts[MusEGlobal::drumMap[curDrumPitch].port]; else mp = &MusEGlobal::midiPorts[mt->outPort()]; @@ -1939,11 +1939,15 @@ void CtrlCanvas::drawOverlay(QPainter& p) int y = fontMetrics().lineSpacing() + 2; p.drawText(2, y, s); - if (noEvents) { + if (curDrumPitch==-2) + { + p.drawText(2 , y * 2, tr("Make the current part's track match the selected drumlist entry")); + } + else if (noEvents) { //p.setFont(MusEGlobal::config.fonts[3]); //p.setPen(Qt::black); //p.drawText(width()/2-100,height()/2-10, "Use shift + pencil or line tool to draw new events"); - p.drawText(2 , y * 2, "Use shift + pencil or line tool to draw new events"); + p.drawText(2 , y * 2, tr("Use pencil or line tool to draw new events")); } } @@ -1961,9 +1965,16 @@ QRect CtrlCanvas::overlayRect() const //r.translate(2, 2); // top/left margin int y = fm.lineSpacing() + 2; r.translate(2, y); - if (noEvents) + if (curDrumPitch==-2) + { + QRect r2(fm.boundingRect(QString(tr("Make the current part's track match the selected drumlist entry")))); + //r2.translate(width()/2-100, height()/2-10); + r2.translate(2, y * 2); + r |= r2; + } + else if (noEvents) { - QRect r2(fm.boundingRect(QString("Use shift + pencil or line tool to draw new events"))); + QRect r2(fm.boundingRect(QString(tr("Use pencil or line tool to draw new events")))); //r2.translate(width()/2-100, height()/2-10); r2.translate(2, y * 2); r |= r2; @@ -2007,7 +2018,7 @@ void CtrlCanvas::setCurDrumPitch(int instrument) if (drumedit->get_instrument_map()[instrument].tracks.contains(curTrack)) curDrumPitch = drumedit->get_instrument_map()[instrument].pitch; else - curDrumPitch = -1; + curDrumPitch = -2; // this means "invalid", but not "unused" } -- cgit v1.2.3 From c0cf8683409dfb74cae82e4b2adcd457a3e1d2b6 Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Sun, 25 Dec 2011 14:20:33 +0000 Subject: ctrlcanvas now reacts properly on ALT-left/right part changes --- muse2/muse/ctrl/ctrlcanvas.cpp | 7 +++++++ muse2/muse/ctrl/ctrlcanvas.h | 1 + muse2/muse/ctrl/ctrledit.cpp | 5 +++++ muse2/muse/ctrl/ctrledit.h | 1 + muse2/muse/midiedit/dcanvas.cpp | 1 + muse2/muse/midiedit/drumedit.cpp | 1 + muse2/muse/midiedit/prcanvas.cpp | 1 + muse2/muse/midiedit/scoreedit.cpp | 23 ++++++++++++++++++++--- muse2/muse/widgets/canvas.h | 4 +++- 9 files changed, 40 insertions(+), 4 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/ctrl/ctrlcanvas.cpp b/muse2/muse/ctrl/ctrlcanvas.cpp index 9896de9a..ddecdbf6 100644 --- a/muse2/muse/ctrl/ctrlcanvas.cpp +++ b/muse2/muse/ctrl/ctrlcanvas.cpp @@ -2041,4 +2041,11 @@ void CtrlCanvas::setCurDrumPitch(int instrument) //songChanged(-1); } +void CtrlCanvas::curPartHasChanged(MusECore::Part*) +{ + setCurTrackAndPart(); + setCurDrumPitch(editor->curDrumInstrument()); + songChanged(SC_EVENT_MODIFIED); +} + } // namespace MusEGui diff --git a/muse2/muse/ctrl/ctrlcanvas.h b/muse2/muse/ctrl/ctrlcanvas.h index 1fcaf1d8..50b71bbe 100644 --- a/muse2/muse/ctrl/ctrlcanvas.h +++ b/muse2/muse/ctrl/ctrlcanvas.h @@ -188,6 +188,7 @@ class CtrlCanvas : public MusEGui::View { void setTool(int t); void setPos(int, unsigned, bool adjustScrollbar); void setController(int ctrl); + void curPartHasChanged(MusECore::Part*); signals: void followEvent(int); diff --git a/muse2/muse/ctrl/ctrledit.cpp b/muse2/muse/ctrl/ctrledit.cpp index 5ce6a7bb..5fbdecaf 100644 --- a/muse2/muse/ctrl/ctrledit.cpp +++ b/muse2/muse/ctrl/ctrledit.cpp @@ -182,4 +182,9 @@ void CtrlEdit::setController(const QString& name) } } +void CtrlEdit::curPartHasChanged(MusECore::Part* p) +{ + canvas->curPartHasChanged(p); +} + } // namespace MusEGui diff --git a/muse2/muse/ctrl/ctrledit.h b/muse2/muse/ctrl/ctrledit.h index 1f7a67a9..a0a941cc 100644 --- a/muse2/muse/ctrl/ctrledit.h +++ b/muse2/muse/ctrl/ctrledit.h @@ -60,6 +60,7 @@ class CtrlEdit : public QWidget { void setXMag(int val) { canvas->setXMag(val); } void setCanvasWidth(int w); void setController(int /*n*/); + void curPartHasChanged(MusECore::Part*); signals: void timeChanged(unsigned); diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp index bc8bbdb0..bdf16b6e 100644 --- a/muse2/muse/midiedit/dcanvas.cpp +++ b/muse2/muse/midiedit/dcanvas.cpp @@ -1155,6 +1155,7 @@ void DrumCanvas::modifySelected(NoteInfo::ValType type, int delta) void DrumCanvas::curPartChanged() { + EventCanvas::curPartChanged(); editor->setWindowTitle(getCaption()); } diff --git a/muse2/muse/midiedit/drumedit.cpp b/muse2/muse/midiedit/drumedit.cpp index 7adab525..4015bbc1 100644 --- a/muse2/muse/midiedit/drumedit.cpp +++ b/muse2/muse/midiedit/drumedit.cpp @@ -1076,6 +1076,7 @@ CtrlEdit* DrumEdit::addCtrl() connect(tools2, SIGNAL(toolChanged(int)), ctrlEdit, SLOT(setTool(int))); connect(dlist, SIGNAL(curDrumInstrumentChanged(int)), SLOT(setCurDrumInstrument(int))); connect(dlist, SIGNAL(curDrumInstrumentChanged(int)), canvas, SLOT(setCurDrumInstrument(int))); + connect(canvas, SIGNAL(curPartHasChanged(MusECore::Part*)), ctrlEdit, SLOT(curPartHasChanged(MusECore::Part*))); //printf("DrumEdit::addCtrl curDrumInstrument:%d\n", dlist->getSelectedInstrument()); diff --git a/muse2/muse/midiedit/prcanvas.cpp b/muse2/muse/midiedit/prcanvas.cpp index 2c32a1cf..fe7f6979 100644 --- a/muse2/muse/midiedit/prcanvas.cpp +++ b/muse2/muse/midiedit/prcanvas.cpp @@ -1081,6 +1081,7 @@ void PianoCanvas::itemMoved(const MusEGui::CItem* item, const QPoint& pos) void PianoCanvas::curPartChanged() { + EventCanvas::curPartChanged(); editor->setWindowTitle(getCaption()); } diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index ff1893ce..2d544c90 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -4655,6 +4655,20 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo // every time something changes. +/* STUFF I WANT TO WORK + * + * x multiple new drum tracks can be displayed seperately in ONE drum + * editor + * x reorder drummap + * ? support and correctly map e-note on record and steprec + * ? only record nonmuted/whatever notes + * ? support drum controllers + * o refuse to mix up old-style and new-style drum tracks in ONE editor + * o drummap saving and loading (per-track) + * o drummap import/export + * o drummap automatically adapting to the chosen midi synth / patch + */ + /* BUGS and potential bugs * o tied notes don't work properly when there's a key-change in * between, for example, when a cis is tied to a des @@ -4665,6 +4679,9 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo * from clipboard failed. ignoring this one... ) [ not reproducible ] * * CURRENT TODO + * o having the same drum track in two editors open, using "hide all" + * on the first (while the second is in "only shown"-mode), this + * has no effect in the second. * o drum controllers * update ctrlcanvas/panel * test! @@ -4675,9 +4692,9 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo * o quantize must round UP, not down when at 0.5 * o my record flag handling * o option for disabling old-style / new-style drum tracks? - * ! o using super glue while a score editor displaying the glued parts - * is open lets muse segfault. this may or may not be fixed in - * the release branch :/ + * ! o once, using super glue while a score editor displaying the glued + * parts is open let muse segfault. this may or may not be fixed + * now. check! * * > o drum editor: channel-stuff * o clearly state in the changelog: when having multiple drumeditors open, diff --git a/muse2/muse/widgets/canvas.h b/muse2/muse/widgets/canvas.h index 38024feb..2ab4820c 100644 --- a/muse2/muse/widgets/canvas.h +++ b/muse2/muse/widgets/canvas.h @@ -172,7 +172,7 @@ class Canvas : public View { virtual void itemPressed(const CItem*) {} virtual void itemReleased(const CItem*, const QPoint&) {} virtual void itemMoved(const CItem*, const QPoint&) {} - virtual void curPartChanged() {} + virtual void curPartChanged() { emit curPartHasChanged(curPart); } public slots: void setTool(int t); @@ -188,6 +188,8 @@ class Canvas : public View { void horizontalScrollNoLimit(unsigned); void horizontalZoomIn(); void horizontalZoomOut(); + void curPartHasChanged(MusECore::Part*); + public: Canvas(QWidget* parent, int sx, int sy, const char* name = 0); virtual ~Canvas(); -- cgit v1.2.3 From 3b3339b7632165130cc2857be4df4ca47f2d974c Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Sun, 25 Dec 2011 16:03:56 +0000 Subject: fixed other editors not being updated when using the "hide all" etc menu commands --- muse2/muse/midiedit/drumedit.cpp | 8 ++++---- muse2/muse/midiedit/drummap.cpp | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/midiedit/drumedit.cpp b/muse2/muse/midiedit/drumedit.cpp index 4015bbc1..8f6d09ee 100644 --- a/muse2/muse/midiedit/drumedit.cpp +++ b/muse2/muse/midiedit/drumedit.cpp @@ -1470,7 +1470,7 @@ void DrumEdit::showAllInstruments() track->drummap_hidden()[i]=false; } - ((DrumCanvas*)(canvas))->rebuildOurDrumMap(); + MusEGlobal::song->update(SC_DRUMMAP); } void DrumEdit::hideAllInstruments() @@ -1489,7 +1489,7 @@ void DrumEdit::hideAllInstruments() track->drummap_hidden()[i]=true; } - ((DrumCanvas*)(canvas))->rebuildOurDrumMap(); + MusEGlobal::song->update(SC_DRUMMAP); } void DrumEdit::hideUnusedInstruments() @@ -1522,7 +1522,7 @@ void DrumEdit::hideUnusedInstruments() track->drummap_hidden()[i]=hide[i]; } - ((DrumCanvas*)(canvas))->rebuildOurDrumMap(); + MusEGlobal::song->update(SC_DRUMMAP); } void DrumEdit::hideEmptyInstruments() @@ -1555,7 +1555,7 @@ void DrumEdit::hideEmptyInstruments() track->drummap_hidden()[i]=hide[i]; } - ((DrumCanvas*)(canvas))->rebuildOurDrumMap(); + MusEGlobal::song->update(SC_DRUMMAP); } diff --git a/muse2/muse/midiedit/drummap.cpp b/muse2/muse/midiedit/drummap.cpp index 47232011..2705a252 100644 --- a/muse2/muse/midiedit/drummap.cpp +++ b/muse2/muse/midiedit/drummap.cpp @@ -314,11 +314,10 @@ void resetGMDrumMap() // operator == //--------------------------------------------------------- -//bool const DrumMap::operator==(const DrumMap& map) const bool DrumMap::operator==(const DrumMap& map) const { return - (name == map.name) + name == map.name && vol == map.vol && quant == map.quant && len == map.len -- cgit v1.2.3 From c233aa121b59559bd29b675d2047efaf741e8879 Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Sun, 25 Dec 2011 16:49:22 +0000 Subject: invalid pointer fixes --- muse2/muse/midiedit/dcanvas.cpp | 2 +- muse2/muse/midiedit/dlist.cpp | 31 +++++++++++++++++++++++++++---- 2 files changed, 28 insertions(+), 5 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp index bdf16b6e..4c033946 100644 --- a/muse2/muse/midiedit/dcanvas.cpp +++ b/muse2/muse/midiedit/dcanvas.cpp @@ -1605,7 +1605,7 @@ void DrumCanvas::rebuildOurDrumMap() if (instrument_map!=old_instrument_map) { - if (debugMsg) printf("rebuilt drummap and instrument map, size is now %i\n",size); + if (debugMsg) printf("rebuilt drummap and instrument map, size is now %i\n",size); songChanged(SC_EVENT_INSERTED); // force an update of the itemlist emit ourDrumMapChanged(true); diff --git a/muse2/muse/midiedit/dlist.cpp b/muse2/muse/midiedit/dlist.cpp index bcdbad79..2cbaceda 100644 --- a/muse2/muse/midiedit/dlist.cpp +++ b/muse2/muse/midiedit/dlist.cpp @@ -299,11 +299,12 @@ void DList::viewMousePressEvent(QMouseEvent* ev) int instrument = y / TH; if (instrument >= ourDrumMapSize) instrument=ourDrumMapSize-1; if (instrument < 0) instrument=0; - MusECore::DrumMap* dm = &ourDrumMap[instrument]; - MusECore::DrumMap dm_old = *dm; setCurDrumInstrument(instrument); + MusECore::DrumMap* dm = &ourDrumMap[instrument]; + MusECore::DrumMap dm_old = *dm; + startY = y; sInstrument = instrument; drag = START_DRAG; @@ -724,7 +725,8 @@ void DList::setCurDrumInstrument(int instr) if (currentlySelected != dm) { currentlySelected = dm; emit curDrumInstrumentChanged(instr); - MusEGlobal::song->update(SC_DRUMMAP); + //MusEGlobal::song->update(SC_DRUMMAP); //FINDMICHJETZT what for?? wtf? + redraw(); // FINDMICHJETZT using redraw() instead of the above. } } @@ -1084,12 +1086,33 @@ int DList::getSelectedInstrument() void DList::ourDrumMapChanged(bool instrMapChanged) { int selIdx = currentlySelected - ourDrumMap; + int editIdx = editEntry ? (editEntry - ourDrumMap) : -1; ourDrumMap=dcanvas->getOurDrumMap(); ourDrumMapSize=dcanvas->getOurDrumMapSize(); if (instrMapChanged) - editEntry=NULL; + { + if (editEntry!=NULL) + { + printf("THIS SHOULD NEVER HAPPEN: DList::ourDrumMapChanged(true) caused editEntry to be\n" + " invalidated. The current active editor will have no\n" + " effect, expect potential breakage...\n"); + editEntry=NULL; + } + } + else // that is: if (!instrMapChanged) + { + // if the instrumentMap has not changed, then its size and so + // ourDrumMapSize cannot have changed as well. + if (editIdx >= ourDrumMapSize) + { + printf("THIS SHOULD NEVER HAPPEN: editIdx got out of bounds although ourDrumMapSize\n" + " cannot have changed (actually)\n"); + editIdx=-1; + } + editEntry=(editIdx>=0) ? &ourDrumMap[editIdx] : NULL; + } if (selIdx >= ourDrumMapSize) selIdx=ourDrumMapSize-1; if (selIdx < 0) selIdx=0; -- cgit v1.2.3 From f7bd12297b81b95371713af725c47f8c56a77550 Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Sun, 25 Dec 2011 17:11:35 +0000 Subject: fixed segfault when dealing with empty drumlists --- muse2/muse/midiedit/dlist.cpp | 26 ++++++++++++++++++++------ muse2/muse/midiedit/scoreedit.cpp | 6 ++---- 2 files changed, 22 insertions(+), 10 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/midiedit/dlist.cpp b/muse2/muse/midiedit/dlist.cpp index 2cbaceda..2eb5e64a 100644 --- a/muse2/muse/midiedit/dlist.cpp +++ b/muse2/muse/midiedit/dlist.cpp @@ -299,6 +299,7 @@ void DList::viewMousePressEvent(QMouseEvent* ev) int instrument = y / TH; if (instrument >= ourDrumMapSize) instrument=ourDrumMapSize-1; if (instrument < 0) instrument=0; + if (ourDrumMapSize==0) return; setCurDrumInstrument(instrument); @@ -593,6 +594,7 @@ void DList::lineEdit(int line, int section) { if (line >= ourDrumMapSize) line=ourDrumMapSize-1; if (line < 0) line=0; + if (ourDrumMapSize==0) return; MusECore::DrumMap* dm = &ourDrumMap[line]; editEntry = dm; @@ -664,6 +666,7 @@ void DList::pitchEdit(int line, int section) { if (line >= ourDrumMapSize) line=ourDrumMapSize-1; if (line < 0) line=0; + if (ourDrumMapSize==0) return; MusECore::DrumMap* dm = &ourDrumMap[line]; editEntry = dm; @@ -978,8 +981,16 @@ DList::DList(QHeaderView* h, QWidget* parent, int ymag, DrumCanvas* dcanvas_, bo editor = 0; pitch_editor = 0; editEntry = 0; - // always select a drum instrument - currentlySelected = &ourDrumMap[0]; + if (ourDrumMapSize!=0) + { + // always select a drum instrument + currentlySelected = &ourDrumMap[0]; + } + else + { + currentlySelected = NULL; + } + selectedColumn = -1; } @@ -1000,7 +1011,7 @@ void DList::viewMouseMoveEvent(QMouseEvent* ev) curY = ev->y(); int delta = curY - startY; switch (drag) { - case START_DRAG: + case START_DRAG: // this cannot happen if ourDrumMapSize==0 if (delta < 0) delta = -delta; if (delta <= 2) @@ -1077,7 +1088,7 @@ void DList::viewMouseReleaseEvent(QMouseEvent* ev) int DList::getSelectedInstrument() { - if (currentlySelected == 0) + if (currentlySelected == NULL) return -1; return MusEGlobal::drumInmap[int(currentlySelected->enote)]; } @@ -1085,7 +1096,7 @@ int DList::getSelectedInstrument() void DList::ourDrumMapChanged(bool instrMapChanged) { - int selIdx = currentlySelected - ourDrumMap; + int selIdx = currentlySelected ? (currentlySelected - ourDrumMap) : -1; int editIdx = editEntry ? (editEntry - ourDrumMap) : -1; ourDrumMap=dcanvas->getOurDrumMap(); @@ -1116,7 +1127,10 @@ void DList::ourDrumMapChanged(bool instrMapChanged) if (selIdx >= ourDrumMapSize) selIdx=ourDrumMapSize-1; if (selIdx < 0) selIdx=0; - currentlySelected = &ourDrumMap[selIdx]; + currentlySelected = (ourDrumMapSize!=0) ? &ourDrumMap[selIdx] : NULL; + + if (ourDrumMapSize==0) + drag = NORMAL; redraw(); } diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index 2d544c90..716ac65d 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -4679,15 +4679,13 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo * from clipboard failed. ignoring this one... ) [ not reproducible ] * * CURRENT TODO - * o having the same drum track in two editors open, using "hide all" - * on the first (while the second is in "only shown"-mode), this - * has no effect in the second. * o drum controllers * update ctrlcanvas/panel * test! - * o drum editor is buggy. propagate_drum_map may operate on old values + * * drum editor is buggy. propagate_drum_map may operate on old values * ("BUGGY! problem is: while changing entries, ourDrumMap may be reallocated which causes abort()s and/or bugs.") + [ seems to work, needs further testing! ] * o don't mix DRUM and NEW_DRUM in drumeditor! * o quantize must round UP, not down when at 0.5 * o my record flag handling -- cgit v1.2.3 From c836582af5661f1ca0e7d93c2674c947462faeb0 Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Sun, 25 Dec 2011 19:13:12 +0000 Subject: added config option for switching between "prefer old/new drumtracks" and "only show new/old drumtracks". defaults to "prefer new" --- muse2/muse/arranger/arrangerview.cpp | 2 +- muse2/muse/conf.cpp | 3 ++ muse2/muse/gconfig.cpp | 3 +- muse2/muse/gconfig.h | 8 ++++ muse2/muse/helper.cpp | 46 ++++++++++++++++------- muse2/muse/helper.h | 2 +- muse2/muse/widgets/genset.cpp | 26 +++++++++++++ muse2/muse/widgets/gensetbase.ui | 67 ++++++++++++++++++++++++++-------- muse2/muse/widgets/musewidgetsplug.cpp | 3 +- 9 files changed, 128 insertions(+), 32 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/arranger/arrangerview.cpp b/muse2/muse/arranger/arrangerview.cpp index 1bb45863..7b8abb63 100644 --- a/muse2/muse/arranger/arrangerview.cpp +++ b/muse2/muse/arranger/arrangerview.cpp @@ -641,7 +641,7 @@ void ArrangerView::clearScoreMenuMappers() void ArrangerView::populateAddTrack() { - QActionGroup *grp = MusEGui::populateAddTrack(addTrack, true); + QActionGroup *grp = MusEGui::populateAddTrack(addTrack, true, true); connect(addTrack, SIGNAL(triggered(QAction *)), SLOT(addNewTrack(QAction *))); trackMidiAction = grp->actions()[0]; diff --git a/muse2/muse/conf.cpp b/muse2/muse/conf.cpp index 5376734c..e9ec1396 100644 --- a/muse2/muse/conf.cpp +++ b/muse2/muse/conf.cpp @@ -969,6 +969,8 @@ void readConfiguration(Xml& xml, bool readOnlySequencer, bool doReadGlobalConfig MusEGlobal::config.rangeMarkerWithoutMMB = xml.parseInt(); else if (tag == "addHiddenTracks") MusEGlobal::config.addHiddenTracks = xml.parseInt(); + else if (tag == "drumTrackPreference") + MusEGlobal::config.drumTrackPreference = (MusEGlobal::drumTrackPreference_t) xml.parseInt(); else if (tag == "unhideTracks") MusEGlobal::config.unhideTracks = xml.parseInt(); @@ -1312,6 +1314,7 @@ void MusE::writeGlobalConfiguration(int level, MusECore::Xml& xml) const xml.intTag(level, "unhideTracks", MusEGlobal::config.unhideTracks); xml.intTag(level, "addHiddenTracks", MusEGlobal::config.addHiddenTracks); + xml.intTag(level, "drumTrackPreference", MusEGlobal::config.drumTrackPreference); xml.intTag(level, "waveTracksVisible", MusECore::WaveTrack::visible()); xml.intTag(level, "auxTracksVisible", MusECore::AudioAux::visible()); diff --git a/muse2/muse/gconfig.cpp b/muse2/muse/gconfig.cpp index 843c2278..68ac6315 100644 --- a/muse2/muse/gconfig.cpp +++ b/muse2/muse/gconfig.cpp @@ -192,7 +192,8 @@ GlobalConfigValues config = { false, // rangeMarkerWithoutMMB MusECore::DONT_REC_MUTED_OR_HIDDEN, true, // addHiddenTracks - true // unhideTracks + true, // unhideTracks + MusEGlobal::PREFER_NEW // drumTrackPreference }; //GlobalConfigValues globalConfig = config; diff --git a/muse2/muse/gconfig.h b/muse2/muse/gconfig.h index f611687f..4ba9efea 100644 --- a/muse2/muse/gconfig.h +++ b/muse2/muse/gconfig.h @@ -47,6 +47,13 @@ enum newDrumRecordCondition_t namespace MusEGlobal { +enum drumTrackPreference_t +{ + PREFER_OLD = 0, + PREFER_NEW = 1, + ONLY_OLD = 2, + ONLY_NEW = 3 +}; //--------------------------------------------------------- // MixerConfig //--------------------------------------------------------- @@ -180,6 +187,7 @@ struct GlobalConfigValues { MusECore::newDrumRecordCondition_t newDrumRecordCondition; bool addHiddenTracks; bool unhideTracks; + drumTrackPreference_t drumTrackPreference; }; diff --git a/muse2/muse/helper.cpp b/muse2/muse/helper.cpp index a0d85133..05cecc08 100644 --- a/muse2/muse/helper.cpp +++ b/muse2/muse/helper.cpp @@ -238,7 +238,7 @@ QMenu* populateAddSynth(QWidget* parent) // this is also used in "mixer" //--------------------------------------------------------- -QActionGroup* populateAddTrack(QMenu* addTrack, bool populateAll) +QActionGroup* populateAddTrack(QMenu* addTrack, bool populateAll, bool evenIgnoreDrumPreference) { QActionGroup* grp = new QActionGroup(addTrack); if (MusEGlobal::config.addHiddenTracks) @@ -249,18 +249,38 @@ QActionGroup* populateAddTrack(QMenu* addTrack, bool populateAll) qApp->translate("@default", QT_TRANSLATE_NOOP("@default", "Add Midi Track"))); midi->setData(MusECore::Track::MIDI); grp->addAction(midi); - } - if (populateAll || MusECore::MidiTrack::visible()) { - QAction* drum = addTrack->addAction(QIcon(*addtrack_drumtrackIcon), - qApp->translate("@default", QT_TRANSLATE_NOOP("@default", "Add Drum Track"))); - drum->setData(MusECore::Track::DRUM); - grp->addAction(drum); - } - if (populateAll || MusECore::MidiTrack::visible()) { - QAction* newdrum = addTrack->addAction(QIcon(*addtrack_drumtrackIcon), - qApp->translate("@default", QT_TRANSLATE_NOOP("@default", "Add New Style Drum Track"))); - newdrum->setData(MusECore::Track::NEW_DRUM); - grp->addAction(newdrum); + + + if (!evenIgnoreDrumPreference && (MusEGlobal::config.drumTrackPreference==MusEGlobal::PREFER_OLD || MusEGlobal::config.drumTrackPreference==MusEGlobal::ONLY_OLD)) + { + QAction* drum = addTrack->addAction(QIcon(*addtrack_drumtrackIcon), + qApp->translate("@default", QT_TRANSLATE_NOOP("@default", "Add Drum Track"))); + drum->setData(MusECore::Track::DRUM); + grp->addAction(drum); + } + + if (!evenIgnoreDrumPreference && (MusEGlobal::config.drumTrackPreference==MusEGlobal::PREFER_NEW || MusEGlobal::config.drumTrackPreference==MusEGlobal::ONLY_NEW)) + { + QAction* newdrum = addTrack->addAction(QIcon(*addtrack_drumtrackIcon), + qApp->translate("@default", QT_TRANSLATE_NOOP("@default", "Add Drum Track"))); + newdrum->setData(MusECore::Track::NEW_DRUM); + grp->addAction(newdrum); + } + + if (evenIgnoreDrumPreference || MusEGlobal::config.drumTrackPreference==MusEGlobal::PREFER_NEW) + { + QAction* drum = addTrack->addAction(QIcon(*addtrack_drumtrackIcon), + qApp->translate("@default", QT_TRANSLATE_NOOP("@default", "Add Old Style Drum Track"))); + drum->setData(MusECore::Track::DRUM); + grp->addAction(drum); + } + if (evenIgnoreDrumPreference || MusEGlobal::config.drumTrackPreference==MusEGlobal::PREFER_OLD) + { + QAction* newdrum = addTrack->addAction(QIcon(*addtrack_drumtrackIcon), + qApp->translate("@default", QT_TRANSLATE_NOOP("@default", "Add New Style Drum Track"))); + newdrum->setData(MusECore::Track::NEW_DRUM); + grp->addAction(newdrum); + } } if (populateAll || MusECore::WaveTrack::visible()) { QAction* wave = addTrack->addAction(QIcon(*addtrack_wavetrackIcon), diff --git a/muse2/muse/helper.h b/muse2/muse/helper.h index ad531fae..8ef39346 100644 --- a/muse2/muse/helper.h +++ b/muse2/muse/helper.h @@ -53,7 +53,7 @@ QSet<Part*> parts_at_tick(unsigned tick, const QSet<Track*>& tracks); namespace MusEGui { QMenu* populateAddSynth(QWidget* parent); -QActionGroup* populateAddTrack(QMenu* addTrack, bool populateAll=false); +QActionGroup* populateAddTrack(QMenu* addTrack, bool populateAll=false, bool evenIgnoreDrumPreference=false); QStringList localizedStringListFromCharArray(const char** array, const char* context); QString getFilterExtension(const QString &filter); QString browseProjectFolder(QWidget* parent = 0); diff --git a/muse2/muse/widgets/genset.cpp b/muse2/muse/widgets/genset.cpp index df7dea78..422f5110 100644 --- a/muse2/muse/widgets/genset.cpp +++ b/muse2/muse/widgets/genset.cpp @@ -184,6 +184,14 @@ Shorter periods are desirable.</string> addHiddenCheckBox->setChecked(MusEGlobal::config.addHiddenTracks); unhideTracksCheckBox->setChecked(MusEGlobal::config.unhideTracks); + + switch (MusEGlobal::config.drumTrackPreference) + { + case MusEGlobal::ONLY_NEW: onlyNewDrumBtn->setChecked(true); break; + case MusEGlobal::ONLY_OLD: onlyOldDrumBtn->setChecked(true); break; + case MusEGlobal::PREFER_NEW: preferNewDrumBtn->setChecked(true); break; + case MusEGlobal::PREFER_OLD: preferOldDrumBtn->setChecked(true); break; + } //updateSettings(); // TESTING @@ -332,6 +340,14 @@ void GlobalSettingsConfig::updateSettings() addHiddenCheckBox->setChecked(MusEGlobal::config.addHiddenTracks); unhideTracksCheckBox->setChecked(MusEGlobal::config.unhideTracks); + switch (MusEGlobal::config.drumTrackPreference) + { + case MusEGlobal::ONLY_NEW: onlyNewDrumBtn->setChecked(true); break; + case MusEGlobal::ONLY_OLD: onlyOldDrumBtn->setChecked(true); break; + case MusEGlobal::PREFER_NEW: preferNewDrumBtn->setChecked(true); break; + case MusEGlobal::PREFER_OLD: preferOldDrumBtn->setChecked(true); break; + } + updateMdiSettings(); } @@ -474,6 +490,16 @@ void GlobalSettingsConfig::apply() MusEGlobal::muse->setHeartBeat(); // set guiRefresh MusEGlobal::midiSeq->msgSetRtc(); // set midi tick rate + if (onlyNewDrumBtn->isChecked()) + MusEGlobal::config.drumTrackPreference=MusEGlobal::ONLY_NEW; + else if (onlyOldDrumBtn->isChecked()) + MusEGlobal::config.drumTrackPreference=MusEGlobal::ONLY_OLD; + else if (preferOldDrumBtn->isChecked()) + MusEGlobal::config.drumTrackPreference=MusEGlobal::PREFER_OLD; + else if (preferNewDrumBtn->isChecked()) + MusEGlobal::config.drumTrackPreference=MusEGlobal::PREFER_NEW; + + applyMdiSettings(); MusEGlobal::muse->changeConfig(true); // save settings diff --git a/muse2/muse/widgets/gensetbase.ui b/muse2/muse/widgets/gensetbase.ui index 1abc3cd1..aec753f1 100644 --- a/muse2/muse/widgets/gensetbase.ui +++ b/muse2/muse/widgets/gensetbase.ui @@ -1442,19 +1442,6 @@ left button behave like the middle button in such areas.</string> </property> </widget> </item> - <item row="9" column="0"> - <spacer name="verticalSpacer_2"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> <item row="7" column="1"> <widget class="QCheckBox" name="addHiddenCheckBox"> <property name="text"> @@ -1486,6 +1473,56 @@ left button behave like the middle button in such areas.</string> </layout> </widget> </item> + <item> + <widget class="QGroupBox" name="groupBox_4"> + <property name="title"> + <string>Drum tracks</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QRadioButton" name="onlyOldDrumBtn"> + <property name="text"> + <string>Only offer old-style drumtracks</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QRadioButton" name="onlyNewDrumBtn"> + <property name="text"> + <string>Only offer new-style drumtracks</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QRadioButton" name="preferOldDrumBtn"> + <property name="text"> + <string>Prefer old-style drumtracks</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QRadioButton" name="preferNewDrumBtn"> + <property name="text"> + <string>Prefer new-style drumtracks</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <spacer name="verticalSpacer_2"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> </layout> </widget> <widget class="QWidget" name="tab_2"> @@ -1544,8 +1581,8 @@ left button behave like the middle button in such areas.</string> <rect> <x>0</x> <y>0</y> - <width>96</width> - <height>26</height> + <width>486</width> + <height>375</height> </rect> </property> <layout class="QHBoxLayout" name="horizontalLayout_3"> diff --git a/muse2/muse/widgets/musewidgetsplug.cpp b/muse2/muse/widgets/musewidgetsplug.cpp index 5267436f..6cdc3812 100644 --- a/muse2/muse/widgets/musewidgetsplug.cpp +++ b/muse2/muse/widgets/musewidgetsplug.cpp @@ -220,7 +220,8 @@ MusEGlobal::GlobalConfigValues config = { false, // rangeMarkerWithoutMMB MusECore::DONT_REC_MUTED_OR_HIDDEN, true, // addHiddenTracks - true // unhideTracks + true, // unhideTracks + MusEGlobal::PREFER_NEW // drumTrackPreference }; //--------------------------------------------------------- -- cgit v1.2.3 From 6d181986beeacc4508aa6c3df71b8b56f6acfd0a Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Sun, 25 Dec 2011 20:02:44 +0000 Subject: disallowed mixing old-style and new-style drum tracks in one editor --- muse2/muse/midiedit/drumedit.cpp | 56 ++++++++++++++++++++++++++++++++------- muse2/muse/midiedit/drumedit.h | 7 +++-- muse2/muse/midiedit/scoreedit.cpp | 6 ++--- 3 files changed, 54 insertions(+), 15 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/midiedit/drumedit.cpp b/muse2/muse/midiedit/drumedit.cpp index 8f6d09ee..3bb48705 100644 --- a/muse2/muse/midiedit/drumedit.cpp +++ b/muse2/muse/midiedit/drumedit.cpp @@ -233,6 +233,48 @@ DrumEdit::DrumEdit(MusECore::PartList* pl, QWidget* parent, const char* name, un menuFunctions = menuBar()->addMenu(tr("Fu&nctions")); menuFunctions->setTearOffEnabled(true); + + + + // throw out new-style and midi tracks if there are old-style tracks present + bool has_old_style_tracks=false; + for (MusECore::ciPart p = parts()->begin(); p != parts()->end(); ++p) + if (p->second->track()->type()==MusECore::Track::DRUM) + { + has_old_style_tracks=true; + break; + } + + if (has_old_style_tracks) + { + bool thrown_out=false; + bool again; + do + { + again=false; + for (MusECore::ciPart p = parts()->begin(); p != parts()->end();p++) + if (p->second->track()->type()!=MusECore::Track::DRUM) + { + parts()->remove(p->second); + thrown_out=true; + again=true; + break; + } + } while (again); + + if (thrown_out) + { + QTimer* timer = new QTimer(this); + timer->setSingleShot(true); + connect(timer,SIGNAL(timeout()), this, SLOT(display_old_new_conflict_message())); + timer->start(10); + } + } + + _old_style_drummap_mode=has_old_style_tracks; + + + if (old_style_drummap_mode()) { @@ -1407,15 +1449,6 @@ void DrumEdit::setStep(QString v) canvas->setFocus(); } -bool DrumEdit::old_style_drummap_mode() -{ - for (MusECore::ciPart p = parts()->begin(); p != parts()->end(); ++p) - if (p->second->track()->type()==MusECore::Track::DRUM) - return true; - - return false; -} - void DrumEdit::ourDrumMapChanged(bool instrMapChanged) { if (instrMapChanged) @@ -1559,4 +1592,9 @@ void DrumEdit::hideEmptyInstruments() } +void DrumEdit::display_old_new_conflict_message() +{ + QMessageBox::information(this, tr("Not all parts are displayed"), tr("You selected both old-style-drumtracks and others (that is: new-style or midi tracks), but they cannot displayed in the same drum edit.\nI'll only display the old-style drumtracks in this editor, dropping the others.")); +} + } // namespace MusEGui diff --git a/muse2/muse/midiedit/drumedit.h b/muse2/muse/midiedit/drumedit.h index 59590d34..5bdd54a8 100644 --- a/muse2/muse/midiedit/drumedit.h +++ b/muse2/muse/midiedit/drumedit.h @@ -96,6 +96,7 @@ class DrumEdit : public MidiEditor { private: group_mode_t _group_mode; bool _ignore_hide; + bool _old_style_drummap_mode; MusECore::Event selEvent; MusECore::MidiPart* selPart; @@ -135,7 +136,7 @@ class DrumEdit : public MidiEditor { void setHeaderToolTips(); void setHeaderWhatsThis(); - + private slots: void setRaster(int); void noteinfoChanged(MusEGui::NoteInfo::ValType type, int val); @@ -159,6 +160,8 @@ class DrumEdit : public MidiEditor { void hideAllInstruments(); void hideUnusedInstruments(); void hideEmptyInstruments(); + + void display_old_new_conflict_message(); public slots: void setSelection(int, MusECore::Event&, MusECore::Part*); @@ -180,7 +183,7 @@ class DrumEdit : public MidiEditor { static void readConfiguration(MusECore::Xml& xml); static void writeConfiguration(int, MusECore::Xml&); - bool old_style_drummap_mode(); + bool old_style_drummap_mode() { return _old_style_drummap_mode; } group_mode_t group_mode() { return _group_mode; } bool ignore_hide() { return _ignore_hide; } diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index 716ac65d..f17ea6f8 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -4684,12 +4684,10 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo * test! * * drum editor is buggy. propagate_drum_map may operate on old values * ("BUGGY! problem is: while changing entries, ourDrumMap - may be reallocated which causes abort()s and/or bugs.") - [ seems to work, needs further testing! ] - * o don't mix DRUM and NEW_DRUM in drumeditor! + * may be reallocated which causes abort()s and/or bugs.") + * [ seems to work, needs further testing! ] * o quantize must round UP, not down when at 0.5 * o my record flag handling - * o option for disabling old-style / new-style drum tracks? * ! o once, using super glue while a score editor displaying the glued * parts is open let muse segfault. this may or may not be fixed * now. check! -- cgit v1.2.3 From 76db51dade62c59e2673da986ab215acc41fd05c Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Sun, 25 Dec 2011 20:22:02 +0000 Subject: (for the quick glance: "the quantize-fix") qu4n71z3 n0w r0und5 up wh3n 1t h4s t0 d3c1d3 wh37h3r t0 l3ng7h3n 0r sh0r73n a n0t3 by 7h3 s4m3 l3ng7h. 7h47 15, wh3n qu4n71z1ng f0r f0ur7hs, 4n 31g7h 15 n0t 4ny m0r3 qu4n71z3d t0 a v3ry sh0r7 n073, bu7 t0 a f0ur7h. btw, 7h15 c0mm17 15 v3rrrry 31337 :D --- muse2/muse/functions.cpp | 16 ++++++++-------- muse2/muse/midiedit/scoreedit.cpp | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/functions.cpp b/muse2/muse/functions.cpp index 77825f52..71621b0d 100644 --- a/muse2/muse/functions.cpp +++ b/muse2/muse/functions.cpp @@ -177,7 +177,7 @@ bool quantize_notes(const set<Part*>& parts) { if (!MusEGui::quantize_dialog->exec()) return false; -// (1<<MusEGui::quantize_dialog->raster_power2) + int raster = MusEGui::rasterVals[MusEGui::quantize_dialog->raster_index]; quantize_notes(parts, MusEGui::quantize_dialog->range, (MusEGlobal::config.division*4)/raster, MusEGui::quantize_dialog->quant_len, MusEGui::quantize_dialog->strength, MusEGui::quantize_dialog->swing, @@ -568,16 +568,16 @@ unsigned quantize_tick(unsigned tick, unsigned raster, int swing) int tick_dest2 = tick_dest1 + raster + raster*swing/100; int tick_dest3 = tick_dest1 + raster*2; - int tick_diff1 = tick_dest1 - tick; - int tick_diff2 = tick_dest2 - tick; - int tick_diff3 = tick_dest3 - tick; + int tick_diff1 = abs(tick_dest1 - (int)tick); + int tick_diff2 = abs(tick_dest2 - (int)tick); + int tick_diff3 = abs(tick_dest3 - (int)tick); - if ((abs(tick_diff1) <= abs(tick_diff2)) && (abs(tick_diff1) <= abs(tick_diff3))) //tick_dest1 is the nearest tick - return tick_dest1; - else if ((abs(tick_diff2) <= abs(tick_diff1)) && (abs(tick_diff2) <= abs(tick_diff3))) //tick_dest2 is the nearest tick + if ((tick_diff3 <= tick_diff1) && (tick_diff3 <= tick_diff2)) //tick_dest3 is the nearest tick + return tick_dest3; + else if ((tick_diff2 <= tick_diff1) && (tick_diff2 <= tick_diff3)) //tick_dest2 is the nearest tick return tick_dest2; else - return tick_dest3; + return tick_dest1; } bool quantize_notes(const set<Part*>& parts, int range, int raster, bool quant_len, int strength, int swing, int threshold) diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index f17ea6f8..9c3668e6 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -4663,7 +4663,7 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo * ? support and correctly map e-note on record and steprec * ? only record nonmuted/whatever notes * ? support drum controllers - * o refuse to mix up old-style and new-style drum tracks in ONE editor + * x refuse to mix up old-style and new-style drum tracks in ONE editor * o drummap saving and loading (per-track) * o drummap import/export * o drummap automatically adapting to the chosen midi synth / patch -- cgit v1.2.3 From ef3de045fb88680a549435fa9099908643ee311f Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Mon, 26 Dec 2011 18:37:06 +0000 Subject: tiny fix --- muse2/muse/midiedit/scoreedit.cpp | 13 +++++++------ muse2/muse/track.cpp | 2 ++ 2 files changed, 9 insertions(+), 6 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index 9c3668e6..57659f8c 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -4685,17 +4685,18 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo * * drum editor is buggy. propagate_drum_map may operate on old values * ("BUGGY! problem is: while changing entries, ourDrumMap * may be reallocated which causes abort()s and/or bugs.") - * [ seems to work, needs further testing! ] - * o quantize must round UP, not down when at 0.5 - * o my record flag handling - * ! o once, using super glue while a score editor displaying the glued + * [ seems to work now, needs further testing! ] + * > o my record flag handling + * o once, using super glue while a score editor displaying the glued * parts is open let muse segfault. this may or may not be fixed * now. check! + * state of revision #1337: no segfaults, but the score editors + * close and lots of "ERROR" messages. * - * > o drum editor: channel-stuff + * o drum editor: channel-stuff * o clearly state in the changelog: when having multiple drumeditors open, * the mute-column may not work, because another editor is overriding this. - * o respect "_drummap_tied_to_patch": IMPLEMENT + * > o respect "_drummap_tied_to_patch": IMPLEMENT * 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, diff --git a/muse2/muse/track.cpp b/muse2/muse/track.cpp index 07a2dff0..4dd2e0c5 100644 --- a/muse2/muse/track.cpp +++ b/muse2/muse/track.cpp @@ -636,6 +636,8 @@ void MidiTrack::init_drummap(bool write_ordering) for (int i=0;i<128;i++) _drummap_hidden[i]=false; + + _drummap_tied_to_patch=true; } void MidiTrack::update_drum_in_map() -- cgit v1.2.3 From 6f35a1b2b84ab6cfc5d77fd46d5e31887a1590e1 Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Fri, 30 Dec 2011 17:55:58 +0000 Subject: instruments can load their patch'es drummaps automatic setting of drummap according to patch this is turned off when the user manually changes the drummap TODO: let him turn it on again moved MidiTrack::read/writeOurDrummap out to helper.cpp extended xg.idf and gs.idf to ship the drummaps still work in progress, but should be usable and stable, though incomplete --- muse2/muse/CMakeLists.txt | 2 + muse2/muse/app.cpp | 2 + muse2/muse/helper.cpp | 199 ++++++++++++- muse2/muse/helper.h | 12 +- muse2/muse/instruments/minstrument.cpp | 188 ++++++++++++- muse2/muse/instruments/minstrument.h | 47 ++++ muse2/muse/midiedit/dcanvas.cpp | 21 +- muse2/muse/midiedit/dlist.cpp | 2 + muse2/muse/midiedit/drumedit.cpp | 2 +- muse2/muse/midiedit/drummap.cpp | 73 ++++- muse2/muse/midiedit/drummap.h | 7 +- muse2/muse/midiedit/scoreedit.cpp | 4 +- muse2/muse/song.cpp | 1 + muse2/muse/track.cpp | 246 +++++++--------- muse2/muse/track.h | 10 + muse2/muse/trackdrummapupdater.cpp | 61 ++++ muse2/muse/trackdrummapupdater.h | 43 +++ muse2/share/instruments/gs.idf | 367 ++++++++++++++++++++++++ muse2/share/instruments/xg.idf | 501 +++++++++++++++++++++++++++++++++ 19 files changed, 1611 insertions(+), 177 deletions(-) create mode 100644 muse2/muse/trackdrummapupdater.cpp create mode 100644 muse2/muse/trackdrummapupdater.h (limited to 'muse2') diff --git a/muse2/muse/CMakeLists.txt b/muse2/muse/CMakeLists.txt index 187bd41e..36645db4 100644 --- a/muse2/muse/CMakeLists.txt +++ b/muse2/muse/CMakeLists.txt @@ -65,6 +65,7 @@ QT4_WRAP_CPP ( muse_moc_headers plugin.h song.h transport.h + trackdrummapupdater.h value.h steprec.h ) @@ -132,6 +133,7 @@ file (GLOB core_source_files thread.cpp ticksynth.cpp track.cpp + trackdrummapupdater.cpp transport.cpp undo.cpp value.cpp diff --git a/muse2/muse/app.cpp b/muse2/muse/app.cpp index f63eb6e2..6a4e7c06 100644 --- a/muse2/muse/app.cpp +++ b/muse2/muse/app.cpp @@ -81,6 +81,7 @@ #include "tools.h" #include "widgets/unusedwavefiles.h" #include "functions.h" +#include "trackdrummapupdater.h" namespace MusECore { extern void initMidiSynth(); @@ -346,6 +347,7 @@ MusE::MusE(int /*argc*/, char** /*argv*/) : QMainWindow() MusEGlobal::heartBeatTimer->setObjectName("timer"); connect(MusEGlobal::heartBeatTimer, SIGNAL(timeout()), MusEGlobal::song, SLOT(beat())); connect(this, SIGNAL(activeTopWinChanged(MusEGui::TopWin*)), SLOT(activeTopWinChangedSlot(MusEGui::TopWin*))); + new MusECore::TrackDrummapUpdater(); // no need for keeping the reference, the thing autoconnects on its own. #ifdef ENABLE_PYTHON //--------------------------------------------------- diff --git a/muse2/muse/helper.cpp b/muse2/muse/helper.cpp index 05cecc08..7d07a6ce 100644 --- a/muse2/muse/helper.cpp +++ b/muse2/muse/helper.cpp @@ -116,15 +116,12 @@ 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) +bool drummaps_almost_equal(const DrumMap* one, const DrumMap* two, int len) { for (int i=0; i<len; i++) - { - DrumMap tmp = one[i]; - tmp.mute=two[i].mute; - if (tmp!=two[i]) + if (!one[i].almost_equals(two[i])) return false; - } + return true; } @@ -164,6 +161,196 @@ QSet<Part*> parts_at_tick(unsigned tick, const QSet<Track*>& tracks) return result; } +bool parse_range(const QString& str, int* from, int* to) +{ + int idx = str.indexOf("-"); + if (idx<0) // no "-" in str + { + bool ok; + int i = str.toInt(&ok); + if (!ok) + { + *from=-1; *to=-1; + return false; + } + else + { + *from=i; *to=i; + return true; + } + } + else // there is a "-" in str + { + QString str1=str.mid(0,idx); + QString str2=str.mid(idx+1); + + bool ok; + int i = str1.toInt(&ok); + if (!ok) + { + *from=-1; *to=-1; + return false; + } + else + { + *from=i; + + i = str2.toInt(&ok); + if (!ok) + { + *from=-1; *to=-1; + return false; + } + else + { + *to=i; + return true; + } + } + } +} + +void write_new_style_drummap(int level, Xml& xml, const char* tagname, + DrumMap* drummap, bool* drummap_hidden, bool full) +{ + xml.tag(level++, tagname); + + for (int i=0;i<128;i++) + { + DrumMap* dm = &drummap[i]; + const DrumMap* idm = &iNewDrumMap[i]; + + if ( (dm->name != idm->name) || (dm->vol != idm->vol) || + (dm->quant != idm->quant) || (dm->len != idm->len) || + (dm->lv1 != idm->lv1) || (dm->lv2 != idm->lv2) || + (dm->lv3 != idm->lv3) || (dm->lv4 != idm->lv4) || + (dm->enote != idm->enote) || (dm->mute != idm->mute) || + (drummap_hidden && drummap_hidden[i]) || full) + { + xml.tag(level++, "entry pitch=\"%d\"", i); + + // when any of these "if"s changes, also update the large "if" + // above (this scope's parent) + if (full || dm->name != idm->name) xml.strTag(level, "name", dm->name); + if (full || dm->vol != idm->vol) xml.intTag(level, "vol", dm->vol); + if (full || dm->quant != idm->quant) xml.intTag(level, "quant", dm->quant); + if (full || dm->len != idm->len) xml.intTag(level, "len", dm->len); + if (full || dm->lv1 != idm->lv1) xml.intTag(level, "lv1", dm->lv1); + if (full || dm->lv2 != idm->lv2) xml.intTag(level, "lv2", dm->lv2); + if (full || dm->lv3 != idm->lv3) xml.intTag(level, "lv3", dm->lv3); + if (full || dm->lv4 != idm->lv4) xml.intTag(level, "lv4", dm->lv4); + if (full || dm->enote != idm->enote) xml.intTag(level, "enote", dm->enote); + if (full || dm->mute != idm->mute) xml.intTag(level, "mute", dm->mute); + if (drummap_hidden && + (full || drummap_hidden[i])) xml.intTag(level, "hide", drummap_hidden[i]); + + // anote is ignored anyway, as dm->anote == i, and this is + // already stored in the begin tag (pitch=...) + + // channel and port are ignored as well, as they're not used + // in new-style-drum-mode + + xml.tag(level--, "/entry"); + } + } + + xml.etag(level, tagname); +} + +void read_new_style_drummap(Xml& xml, const char* tagname, + DrumMap* drummap, bool* drummap_hidden) +{ + for (;;) + { + Xml::Token token = xml.parse(); + if (token == Xml::Error || token == Xml::End) + break; + const QString& tag = xml.s1(); + switch (token) + { + case Xml::TagStart: + if (tag == "entry") // then read that entry with a nested loop + { + DrumMap* dm=NULL; + bool* hidden=NULL; + for (;;) // nested loop + { + Xml::Token token = xml.parse(); + const QString& tag = xml.s1(); + switch (token) + { + case Xml::Error: + case Xml::End: + goto end_of_nested_for; + + case Xml::Attribut: + if (tag == "pitch") + { + int pitch = xml.s2().toInt() & 0x7f; + if (pitch < 0 || pitch > 127) + printf("ERROR: THIS SHOULD NEVER HAPPEN: invalid pitch in read_new_style_drummap()!\n"); + else + { + dm = &drummap[pitch]; + hidden = drummap_hidden ? &drummap_hidden[pitch] : NULL; + } + } + break; + + case Xml::TagStart: + if (dm==NULL) + printf("ERROR: THIS SHOULD NEVER HAPPEN: no valid 'pitch' attribute in <entry> tag, but sub-tags follow in read_new_style_drummap()!\n"); + else if (tag == "name") + dm->name = xml.parse(QString("name")); + else if (tag == "vol") + dm->vol = (unsigned char)xml.parseInt(); + else if (tag == "quant") + dm->quant = xml.parseInt(); + else if (tag == "len") + dm->len = xml.parseInt(); + else if (tag == "lv1") + dm->lv1 = xml.parseInt(); + else if (tag == "lv2") + dm->lv2 = xml.parseInt(); + else if (tag == "lv3") + dm->lv3 = xml.parseInt(); + else if (tag == "lv4") + dm->lv4 = xml.parseInt(); + else if (tag == "enote") + dm->enote = xml.parseInt(); + else if (tag == "mute") + dm->mute = xml.parseInt(); + else if (tag == "hide") + { + if (hidden) *hidden = xml.parseInt(); + } + else + xml.unknown("read_new_style_drummap"); + break; + + case Xml::TagEnd: + if (tag == "entry") + goto end_of_nested_for; + + default: + break; + } + } // end of nested loop + end_of_nested_for: ; + } // end of 'if (tag == "entry")' + else + xml.unknown("read_new_style_drummap"); + break; + + case Xml::TagEnd: + if (tag == tagname) + return; + + default: + break; + } + } +} } // namespace MusECore diff --git a/muse2/muse/helper.h b/muse2/muse/helper.h index 8ef39346..2a26c08e 100644 --- a/muse2/muse/helper.h +++ b/muse2/muse/helper.h @@ -44,11 +44,21 @@ QString pitch2string(int v); Part* partFromSerialNumber(int serial); bool any_event_selected(const std::set<Part*>&, bool in_range=false); -bool drummaps_almost_equal(DrumMap* one, DrumMap* two, int drummap_size=128); +bool drummaps_almost_equal(const DrumMap* one, const DrumMap* two, int drummap_size=128); + +// drummap_hidden may be NULL. +void write_new_style_drummap(int level, Xml& xml, const char* tagname, + DrumMap* drummap, bool* drummap_hidden=NULL, bool full=false); +void read_new_style_drummap(Xml& xml, const char* tagname, + DrumMap* drummap, bool* drummap_hidden=NULL); + QSet<Part*> parts_at_tick(unsigned tick); QSet<Part*> parts_at_tick(unsigned tick, const Track* track); QSet<Part*> parts_at_tick(unsigned tick, const QSet<Track*>& tracks); + +bool parse_range(const QString& str, int* from, int* to); // returns true if successful, false on error + } namespace MusEGui { diff --git a/muse2/muse/instruments/minstrument.cpp b/muse2/muse/instruments/minstrument.cpp index a01903ae..3876fb28 100644 --- a/muse2/muse/instruments/minstrument.cpp +++ b/muse2/muse/instruments/minstrument.cpp @@ -41,6 +41,8 @@ #include "midictrl.h" #include "gconfig.h" #include "popupmenu.h" +#include "drummap.h" +#include "helper.h" namespace MusECore { @@ -364,6 +366,7 @@ void MidiInstrument::init() MidiController* prog = new MidiController("Program", CTRL_PROGRAM, 0, 0xffffff, 0); _controller->add(prog); _dirty = false; + } MidiInstrument::MidiInstrument() @@ -408,8 +411,20 @@ MidiInstrument::~MidiInstrument() if (_initScript) delete _initScript; + + clear_delete_patch_drummap_mapping(); } +void MidiInstrument::clear_delete_patch_drummap_mapping() +{ + for (std::list<patch_drummap_mapping_t>::iterator it = patch_drummap_mapping.begin(); + it!=patch_drummap_mapping.end(); it++) + delete[] it->drummap; + + patch_drummap_mapping.clear(); +} + + /* //--------------------------------------------------------- // uniqueCopy @@ -515,7 +530,20 @@ MidiInstrument& MidiInstrument::assign(const MidiInstrument& ins) _name = ins._name; _filePath = ins._filePath; - + + clear_delete_patch_drummap_mapping(); + // do a deep copy + for (std::list<patch_drummap_mapping_t>::const_iterator it = ins.patch_drummap_mapping.begin(); + it!=ins.patch_drummap_mapping.end(); it++) + { + patch_drummap_mapping_t temp = *it; + temp.drummap=new DrumMap[128]; + for (int i=0;i<128;i++) + temp.drummap[i]=it->drummap[i]; + } + + + // Hmm, dirty, yes? But init sets it to false... //_dirty = ins._dirty; //_dirty = false; @@ -733,6 +761,123 @@ void MidiInstrument::readMidiState(Xml& xml) } } +void MidiInstrument::readDrummaps(Xml& xml) +{ + clear_delete_patch_drummap_mapping(); + + for (;;) + { + Xml::Token token = xml.parse(); + const QString& tag = xml.s1(); + switch (token) + { + case Xml::Error: + case Xml::End: + return; + + case Xml::TagStart: + if (tag == "entry") + patch_drummap_mapping.push_back(readDrummapsEntry(xml)); + else + xml.unknown("MidiInstrument::readDrummaps"); + break; + + case Xml::TagEnd: + if (tag == "Drummaps") + return; + + default: + break; + } + } + printf("ERROR: THIS CANNOT HAPPEN: exited infinite loop in MidiInstrument::readDrummaps()!\n" + " not returning anything. expect undefined behaviour or even crashes.\n"); +} + +patch_drummap_mapping_t MidiInstrument::readDrummapsEntry(Xml& xml) +{ + using std::list; + + list<patch_collection_t> collection; + DrumMap* drummap=new DrumMap[128]; + for (int i=0;i<128;i++) + drummap[i]=iNewDrumMap[i]; + + for (;;) + { + Xml::Token token = xml.parse(); + const QString& tag = xml.s1(); + switch (token) + { + case Xml::Error: + case Xml::End: + return patch_drummap_mapping_t(collection, drummap); + + case Xml::TagStart: + if (tag == "patch_collection") + collection.push_back(readDrummapsEntryPatchCollection(xml)); + else if (tag == "drummap") + read_new_style_drummap(xml, "drummap", drummap); + else + xml.unknown("MidiInstrument::readDrummapsEntry"); + break; + + case Xml::TagEnd: + if (tag == "entry") + return patch_drummap_mapping_t(collection, drummap); + + default: + break; + } + } + printf("ERROR: THIS CANNOT HAPPEN: exited infinite loop in MidiInstrument::readDrummapsEntry()!\n" + " not returning anything. expect undefined behaviour or even crashes.\n"); + return patch_drummap_mapping_t(); +} + +patch_collection_t MidiInstrument::readDrummapsEntryPatchCollection(Xml& xml) +{ + int first_prog=0, last_prog=256; // this means: + int first_lbank=0, last_lbank=256; // "does not matter" + int first_hbank=0, last_hbank=256; + + for (;;) + { + Xml::Token token = xml.parse(); + const QString& tag = xml.s1(); + switch (token) + { + case Xml::Error: + case Xml::End: + return patch_collection_t(-1,-1,-1,-1,-1,-1); // an invalid collection + + case Xml::TagStart: + xml.unknown("MidiInstrument::readDrummapsEntryPatchCollection"); + break; + + case Xml::Attribut: + if (tag == "prog") + parse_range(xml.s2(), &first_prog, &last_prog); + else if (tag == "lbank") + parse_range(xml.s2(), &first_lbank, &last_lbank); + else if (tag == "hbank") + parse_range(xml.s2(), &first_hbank, &last_hbank); + break; + + case Xml::TagEnd: + if (tag == "patch_collection") + return patch_collection_t(first_prog, last_prog, first_lbank, last_lbank, first_hbank, last_hbank); + + default: + break; + } + } + + printf("ERROR: THIS CANNOT HAPPEN: exited infinite loop in MidiInstrument::readDrummapsEntryPatchCollection()!\n" + " not returning anything. expect undefined behaviour or even crashes.\n"); +} + + //--------------------------------------------------------- // read //--------------------------------------------------------- @@ -785,6 +930,9 @@ void MidiInstrument::read(Xml& xml) _controller->add(mc); } + else if (tag == "Drummaps") { + readDrummaps(xml); + } else if (tag == "Init") readEventList(xml, _midiInit, "Init"); else if (tag == "Reset") @@ -794,7 +942,7 @@ void MidiInstrument::read(Xml& xml) else if (tag == "InitScript") { if (_initScript) delete _initScript; - QByteArray ba = xml.parse1().toLatin1(); + QByteArray ba = xml.parse1().toLatin1(); const char* istr = ba.constData(); int len = strlen(istr) +1; if (len > 1) { @@ -998,4 +1146,40 @@ void MidiInstrument::populatePatchPopup(MusEGui::PopupMenu* menu, int chan, MTyp } +const DrumMap* MidiInstrument::drummap_for_patch(int patch) const +{ + using std::list; + + int program = (patch & 0x0000FF); + int lbank = (patch & 0x00FF00) >> 8; + int hbank = (patch & 0xFF0000) >> 16; + + for (list<patch_drummap_mapping_t>::const_iterator it=patch_drummap_mapping.begin(); + it!=patch_drummap_mapping.end(); it++) + { + for (list<patch_collection_t>::const_iterator it2=it->affected_patches.begin(); + it2!=it->affected_patches.end(); it2++) + { + // if the entry matches our patch + if ( (program >= it2->first_program && program <= it2->last_program) && + (hbank >= it2->first_hbank && hbank <= it2->last_hbank) && + (lbank >= it2->first_lbank && lbank <= it2->last_lbank) ) + { + return it->drummap; + } + } + } + + // if nothing was found + return iNewDrumMap; +} + +patch_drummap_mapping_t::patch_drummap_mapping_t() +{ + drummap=new DrumMap[128]; + for (int i=0;i<128;i++) + drummap[i]=iNewDrumMap[i]; +} + + } // namespace MusECore diff --git a/muse2/muse/instruments/minstrument.h b/muse2/muse/instruments/minstrument.h index 385e67b4..9a65598b 100644 --- a/muse2/muse/instruments/minstrument.h +++ b/muse2/muse/instruments/minstrument.h @@ -40,6 +40,7 @@ class MidiControllerList; class MidiPort; class MidiPlayEvent; class Xml; +class DrumMap; //--------------------------------------------------------- @@ -80,6 +81,43 @@ struct SysEx { unsigned char* data; }; + + +struct patch_collection_t +{ + int first_program; + int last_program; + int first_hbank; + int last_hbank; + int first_lbank; + int last_lbank; + + patch_collection_t(int p1=0, int p2=127, int l1=0, int l2=127, int h1=0, int h2=127) + { + first_program=p1; + last_program=p2; + first_lbank=l1; + last_lbank=l2; + first_hbank=h1; + last_hbank=h2; + } + +}; + +struct patch_drummap_mapping_t +{ + std::list<patch_collection_t> affected_patches; + DrumMap* drummap; + + patch_drummap_mapping_t(const std::list<patch_collection_t>& a, DrumMap* d) + { + affected_patches=a; + drummap=d; + } + + patch_drummap_mapping_t(); +}; + //--------------------------------------------------------- // MidiInstrument //--------------------------------------------------------- @@ -88,6 +126,7 @@ class MidiInstrument { PatchGroupList pg; MidiControllerList* _controller; QList<SysEx*> _sysex; + std::list<patch_drummap_mapping_t> patch_drummap_mapping; bool _dirty; int _nullvalue; @@ -103,6 +142,12 @@ class MidiInstrument { char* _initScript; QString _name; QString _filePath; + + void clear_delete_patch_drummap_mapping(); + + void readDrummaps(Xml& xml); + patch_drummap_mapping_t readDrummapsEntry(Xml& xml); + patch_collection_t readDrummapsEntryPatchCollection(Xml& xml); public: MidiInstrument(); @@ -123,6 +168,8 @@ class MidiInstrument { void removeSysex(SysEx* sysex) { _sysex.removeAll(sysex); } void addSysex(SysEx* sysex) { _sysex.append(sysex); } + const DrumMap* drummap_for_patch(int patch) const; + EventList* midiInit() const { return _midiInit; } EventList* midiReset() const { return _midiReset; } EventList* midiState() const { return _midiState; } diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp index 4c033946..ad0226da 100644 --- a/muse2/muse/midiedit/dcanvas.cpp +++ b/muse2/muse/midiedit/dcanvas.cpp @@ -1008,6 +1008,19 @@ void DrumCanvas::mapChanged(int spitch, int dpitch) using MusEGlobal::global_drum_ordering_t; using MusEGlobal::global_drum_ordering; + for (QSet<MusECore::Track*>::iterator it=instrument_map[spitch].tracks.begin(); + it!=instrument_map[spitch].tracks.end(); it++) + { + if (dynamic_cast<MusECore::MidiTrack*>(*it)) + dynamic_cast<MusECore::MidiTrack*>(*it)->set_drummap_ordering_tied_to_patch(false); + } + for (QSet<MusECore::Track*>::iterator it=instrument_map[dpitch].tracks.begin(); + it!=instrument_map[dpitch].tracks.end(); it++) + { + if (dynamic_cast<MusECore::MidiTrack*>(*it)) + dynamic_cast<MusECore::MidiTrack*>(*it)->set_drummap_ordering_tied_to_patch(false); + } + MusECore::DrumMap dm_temp = ourDrumMap[spitch]; instrument_number_mapping_t im_temp = instrument_map[spitch]; @@ -1450,9 +1463,13 @@ void DrumCanvas::propagate_drummap_change(int instr, bool update_druminmap) for (QSet<MusECore::Track*>::const_iterator it = tracks.begin(); it != tracks.end(); it++) { - dynamic_cast<MusECore::MidiTrack*>(*it)->drummap()[index] = ourDrumMap[instr]; + MusECore::MidiTrack* mt=dynamic_cast<MusECore::MidiTrack*>(*it); + // if we're not only changing "mute" state... + if (!mt->drummap()[index].almost_equals(ourDrumMap[instr])) + mt->set_drummap_tied_to_patch(false); + mt->drummap()[index] = ourDrumMap[instr]; if (update_druminmap) - dynamic_cast<MusECore::MidiTrack*>(*it)->update_drum_in_map(); + mt->update_drum_in_map(); } } diff --git a/muse2/muse/midiedit/dlist.cpp b/muse2/muse/midiedit/dlist.cpp index 2eb5e64a..fc6384f7 100644 --- a/muse2/muse/midiedit/dlist.cpp +++ b/muse2/muse/midiedit/dlist.cpp @@ -401,6 +401,7 @@ void DList::viewMousePressEvent(QMouseEvent* ev) { MusECore::MidiTrack* mt = dynamic_cast<MusECore::MidiTrack*>(*it); mt->drummap()[mt->map_drum_in(val)].enote=dm->enote; + mt->set_drummap_tied_to_patch(false); } // propagating this is unneccessary as it's already done. // updating the drumInmap is unneccessary, as the propagate call below @@ -900,6 +901,7 @@ void DList::pitchEdited() { MusECore::MidiTrack* mt = dynamic_cast<MusECore::MidiTrack*>(*it); mt->drummap()[mt->map_drum_in(val)].enote=editEntry->enote; + mt->set_drummap_tied_to_patch(false); } // propagating this is unneccessary as it's already done. // updating the drumInmap is unneccessary, as the propagate call below diff --git a/muse2/muse/midiedit/drumedit.cpp b/muse2/muse/midiedit/drumedit.cpp index 3bb48705..1f159d1a 100644 --- a/muse2/muse/midiedit/drumedit.cpp +++ b/muse2/muse/midiedit/drumedit.cpp @@ -644,7 +644,7 @@ DrumEdit::DrumEdit(MusECore::PartList* pl, QWidget* parent, const char* name, un void DrumEdit::songChanged1(int bits) { - if(_isDeleting) // Ignore while while deleting to prevent crash. + if(_isDeleting) // Ignore while deleting to prevent crash. return; if (bits & SC_SOLO) diff --git a/muse2/muse/midiedit/drummap.cpp b/muse2/muse/midiedit/drummap.cpp index 2705a252..d86bcd65 100644 --- a/muse2/muse/midiedit/drummap.cpp +++ b/muse2/muse/midiedit/drummap.cpp @@ -43,15 +43,13 @@ namespace MusECore { const DrumMap blankdm = { QString(""), 100, 16, 32, 9, 0, 70, 90, 127, 110, 127, 127, false }; -// this map must have 128 entries, as it's used for initalising new-style-drummaps as well. -// new-style-drummaps only have 128 entries. also, the every "out-note" ("anote") must be -// represented exactly once in that map, and there may be no duplicate or unused "out-notes". -// reason: the track's drummap are inited as follows: iterate through the full idrumMap[], -// tracks_drummap[ idrumMap[i].anote ] = idrumMap[i] -// if you ever want to change this, you will need to go through track.cpp/.h and -// {dlist,dcanvas,drumedit,drummap}{.cpp,.h} (and possibly some more) and find every usage -// of idrumMap by new style drummaps, and fix the problem. a possible fix would be duplicating -// idrumMap, change idrumMap, and use the duplicate for the new style stuff instead. +// this map should have 128 entries, as it's used for initalising iNewDrumMap as well. +// iNewDrumMap only has 128 entries. also, the every "out-note" ("anote") should be +// represented exactly once in idrumMap, and there shall be no duplicate or unused +// "out-notes". +// reason: iNewDrumMap is inited as follows: iterate through the full idrumMap[], +// iNewDrumMap[ idrumMap[i].anote ] = idrumMap[i] +// if you ever want to change this, you will need to fix the initNewDrumMap() function. const DrumMap idrumMap[DRUM_MAPSIZE] = { { QString("Acoustic Bass Drum"), 100, 16, 32, 9, 0, 70, 90, 127, 110, 35, 35, false }, { QString("Bass Drum 1"), 100, 16, 32, 9, 0, 70, 90, 127, 110, 36, 36, false }, @@ -261,6 +259,55 @@ const DrumMap idrumMap[DRUM_MAPSIZE] = { { QString(""), 100, 16, 32, 9, 0, 70, 90, 127, 110, 34, 34, false } }; +DrumMap iNewDrumMap[128]; + +void initNewDrumMap() +{ + bool done[128]; + for (int i=0;i<128;i++) done[i]=false; + + for (int i=0;i<DRUM_MAPSIZE;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 + { + if (done[idx]==true) + { + printf("ERROR: iNewDrumMap[%i] is already initalized!\n" + " this will be probably not a problem, but some programmer didn't read\n" + " flo's comment at drummap.cpp, above idrumMap[].\n", idx); + } + else + { + iNewDrumMap[idx]=idrumMap[i]; + done[idx]=true; + } + } + } + + for (int i=0;i<128;i++) + { + if (done[i]==false) + { + printf("ERROR: iNewDrumMap[%i] is uninitalized!\n" + " this will be probably not a problem, but some programmer didn't read\n" + " flo's comment at drummap.cpp, above idrumMap[].\n", i); + iNewDrumMap[i].name=""; + iNewDrumMap[i].vol=100; + iNewDrumMap[i].quant=16; + iNewDrumMap[i].len=32; + iNewDrumMap[i].lv1=70; + iNewDrumMap[i].lv2=90; + iNewDrumMap[i].lv3=127; + iNewDrumMap[i].lv4=110; + iNewDrumMap[i].enote=i; + iNewDrumMap[i].anote=i; + } + } +} + //--------------------------------------------------------- // initDrumMap @@ -332,6 +379,14 @@ bool DrumMap::operator==(const DrumMap& map) const && mute == map.mute; } +bool DrumMap::almost_equals(const DrumMap& map) const +{ + DrumMap tmp=map; + tmp.mute=this->mute; + return tmp==*this; +} + + //--------------------------------------------------------- // writeDrumMap //--------------------------------------------------------- diff --git a/muse2/muse/midiedit/drummap.h b/muse2/muse/midiedit/drummap.h index 3b6ffaf3..7f28b068 100644 --- a/muse2/muse/midiedit/drummap.h +++ b/muse2/muse/midiedit/drummap.h @@ -49,12 +49,15 @@ struct DrumMap { bool operator==(const DrumMap& map) const; bool operator!=(const DrumMap& map) const { return !operator==(map); } + bool almost_equals(const DrumMap& map) const; }; -// please let this at "128". idrumMap must have length 128 (see drummap.cpp for details) +// please let this at "128". idrumMap should have length 128 (see drummap.cpp for details) #define DRUM_MAPSIZE 128 -extern const DrumMap idrumMap[DRUM_MAPSIZE]; //FINDMICH dummy! +extern DrumMap iNewDrumMap[128]; +extern void initNewDrumMap(); + extern void initDrumMap(); extern void writeDrumMap(int level, Xml& xml, bool external); extern void readDrumMap(Xml& xml, bool external); diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index c10adafd..055134e2 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -4686,8 +4686,8 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo * ("BUGGY! problem is: while changing entries, ourDrumMap * may be reallocated which causes abort()s and/or bugs.") * [ seems to work now, needs further testing! ] - * > o my record flag handling - * o once, using super glue while a score editor displaying the glued + * x my record flag handling + * * once, using super glue while a score editor displaying the glued * parts is open let muse segfault. this may or may not be fixed * now. check! * state of revision #1337: no segfaults, but the score editors diff --git a/muse2/muse/song.cpp b/muse2/muse/song.cpp index 484e2d42..69900bbc 100644 --- a/muse2/muse/song.cpp +++ b/muse2/muse/song.cpp @@ -2074,6 +2074,7 @@ void Song::clear(bool signal, bool clear_all) // _tempo = 500000; // default tempo 120 dirty = false; initDrumMap(); + initNewDrumMap(); if (signal) { emit loopChanged(false); recordChanged(false); diff --git a/muse2/muse/track.cpp b/muse2/muse/track.cpp index 4dd2e0c5..595a25e7 100644 --- a/muse2/muse/track.cpp +++ b/muse2/muse/track.cpp @@ -34,6 +34,8 @@ #include "globaldefs.h" #include "route.h" #include "drummap.h" +#include "midictrl.h" +#include "helper.h" namespace MusECore { @@ -618,19 +620,28 @@ void MidiTrack::init() _recEcho = true; } +void MidiTrack::init_drum_ordering() +{ + // first display entries with non-empty names, then with empty names. + + remove_ourselves_from_drum_ordering(); + + for (int i=0;i<128;i++) + if (_drummap[i].name!="" && _drummap[i].name!="?") // non-empty name? + MusEGlobal::global_drum_ordering.push_back(std::pair<MidiTrack*,int>(this,i)); + + for (int i=0;i<128;i++) + if (!(_drummap[i].name!="" && _drummap[i].name!="?")) // empty name? + MusEGlobal::global_drum_ordering.push_back(std::pair<MidiTrack*,int>(this,i)); +} + void MidiTrack::init_drummap(bool write_ordering) { 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]; - - if (write_ordering) - MusEGlobal::global_drum_ordering.push_back(std::pair<MidiTrack*,int>(this,idx)); - } + _drummap[i]=iNewDrumMap[i]; + + if (write_ordering) + init_drum_ordering(); update_drum_in_map(); @@ -638,6 +649,7 @@ void MidiTrack::init_drummap(bool write_ordering) _drummap_hidden[i]=false; _drummap_tied_to_patch=true; + _drummap_ordering_tied_to_patch=true; } void MidiTrack::update_drum_in_map() @@ -945,62 +957,14 @@ void MidiTrack::writeOurDrumSettings(int level, Xml& xml) const writeOurDrumMap(level, xml, false); xml.intTag(level, "tied", _drummap_tied_to_patch); + xml.intTag(level, "ordering_tied", _drummap_ordering_tied_to_patch); xml.etag(level, "our_drum_settings"); } void MidiTrack::writeOurDrumMap(int level, Xml& xml, bool full) const { - xml.tag(level++, "our_drummap"); - - for (int i=0;i<128;i++) - { - int j; - for (j=0;j<128;j++) - if (idrumMap[j].anote == i) break; - - if (j==128) - printf("THIS SHOULD NEVER HAPPEN: couldn't find initial drum map entry in MidiTrack::writeOurDrumMap()\n"); - else - { - DrumMap* dm = &_drummap[i]; - const DrumMap* idm = &idrumMap[j]; - - if ( (dm->name != idm->name) || (dm->vol != idm->vol) || - (dm->quant != idm->quant) || (dm->len != idm->len) || - (dm->lv1 != idm->lv1) || (dm->lv2 != idm->lv2) || - (dm->lv3 != idm->lv3) || (dm->lv4 != idm->lv4) || - (dm->enote != idm->enote) || (dm->mute != idm->mute) || - _drummap_hidden[i] || full) - { - xml.tag(level++, "entry pitch=\"%d\"", i); - - // when any of these "if"s changes, also update the large "if" - // above (this scope's parent) - if (full || dm->name != idm->name) xml.strTag(level, "name", dm->name); - if (full || dm->vol != idm->vol) xml.intTag(level, "vol", dm->vol); - if (full || dm->quant != idm->quant) xml.intTag(level, "quant", dm->quant); - if (full || dm->len != idm->len) xml.intTag(level, "len", dm->len); - if (full || dm->lv1 != idm->lv1) xml.intTag(level, "lv1", dm->lv1); - if (full || dm->lv2 != idm->lv2) xml.intTag(level, "lv2", dm->lv2); - if (full || dm->lv3 != idm->lv3) xml.intTag(level, "lv3", dm->lv3); - if (full || dm->lv4 != idm->lv4) xml.intTag(level, "lv4", dm->lv4); - if (full || dm->enote != idm->enote) xml.intTag(level, "enote", dm->enote); - if (full || dm->mute != idm->mute) xml.intTag(level, "mute", dm->mute); - if (full || _drummap_hidden[i]) xml.intTag(level, "hide", _drummap_hidden[i]); - - // anote is ignored anyway, as dm->anote == i, and this is - // already stored in the begin tag (pitch=...) - - // channel and port are ignored as well, as they're not used - // in new-style-drum-mode - - xml.tag(level--, "/entry"); - } - } - } - - xml.etag(level, "our_drummap"); + write_new_style_drummap(level, xml, "our_drummap", _drummap, _drummap_hidden, full); } //--------------------------------------------------------- @@ -1095,6 +1059,8 @@ void MidiTrack::readOurDrumSettings(Xml& xml) case Xml::TagStart: if (tag == "tied") _drummap_tied_to_patch = xml.parseInt(); + else if (tag == "ordering_tied") + _drummap_ordering_tied_to_patch = xml.parseInt(); else if (tag == "our_drummap") readOurDrumMap(xml); else @@ -1115,98 +1081,9 @@ void MidiTrack::readOurDrumMap(Xml& xml, bool dont_init) { if (!dont_init) init_drummap(false); _drummap_tied_to_patch=false; - - for (;;) - { - Xml::Token token = xml.parse(); - if (token == Xml::Error || token == Xml::End) - break; - const QString& tag = xml.s1(); - switch (token) - { - case Xml::TagStart: - if (tag == "entry") // then read that entry with a nested loop - { - DrumMap* dm=NULL; - bool* hidden=NULL; - for (;;) // nested loop - { - Xml::Token token = xml.parse(); - const QString& tag = xml.s1(); - switch (token) - { - case Xml::Error: - case Xml::End: - goto end_of_nested_for; - - case Xml::Attribut: - if (tag == "pitch") - { - int pitch = xml.s2().toInt() & 0x7f; - if (pitch < 0 || pitch > 127) - printf("ERROR: THIS SHOULD NEVER HAPPEN: invalid pitch in MidiTrack::readOurDrumMap()!\n"); - else - { - dm = &_drummap[pitch]; - hidden = &_drummap_hidden[pitch]; - } - } - break; - - case Xml::TagStart: - if (dm==NULL) - printf("ERROR: THIS SHOULD NEVER HAPPEN: no valid 'pitch' attribute in <entry> tag, but sub-tags follow in MidiTrack::readOurDrumMap()!\n"); - else if (tag == "name") - dm->name = xml.parse(QString("name")); - else if (tag == "vol") - dm->vol = (unsigned char)xml.parseInt(); - else if (tag == "quant") - dm->quant = xml.parseInt(); - else if (tag == "len") - dm->len = xml.parseInt(); - else if (tag == "lv1") - dm->lv1 = xml.parseInt(); - else if (tag == "lv2") - dm->lv2 = xml.parseInt(); - else if (tag == "lv3") - dm->lv3 = xml.parseInt(); - else if (tag == "lv4") - dm->lv4 = xml.parseInt(); - else if (tag == "enote") - dm->enote = xml.parseInt(); - else if (tag == "mute") - dm->mute = xml.parseInt(); - else if (tag == "hide") - *hidden = xml.parseInt(); - else - xml.unknown("MidiTrack::readOurDrumMap"); - break; - - case Xml::TagEnd: - if (tag == "entry") - goto end_of_nested_for; - - default: - break; - } - } // end of nested loop - end_of_nested_for: ; - } // end of 'if (tag == "entry")' - else - xml.unknown("MidiTrack::readOurDrumMap"); - break; - - case Xml::TagEnd: - if (tag == "our_drummap") - { - update_drum_in_map(); - return; - } - - default: - break; - } - } + _drummap_ordering_tied_to_patch=false; + read_new_style_drummap(xml, "our_drummap", _drummap, _drummap_hidden); + update_drum_in_map(); } @@ -1395,4 +1272,69 @@ void Track::writeRouting(int level, Xml& xml) const } } +int MidiTrack::getFirstControllerValue(int ctrl, int def) +{ + int val=def; + unsigned tick=-1; // maximum integer + + for (iPart pit=parts()->begin(); pit!=parts()->end(); pit++) + { + Part* part=pit->second; + if (part->tick() > tick) break; // ignore this and the rest. we won't find anything new. + for (iEvent eit=part->events()->begin(); eit!=part->events()->end(); eit++) + { + if (eit->first+part->tick() >= tick) break; + // else if (eit->first+part->tick() < tick) and + if (eit->second.type()==Controller && eit->second.dataA()==ctrl) + { + val = eit->second.dataB(); + tick = eit->first+part->tick(); + break; + } + } + } + + return val; +} + + +// returns true if the autoupdate changed something +bool MidiTrack::auto_update_drummap() +{ + if (_drummap_tied_to_patch) + { + int patch = getFirstControllerValue(CTRL_PROGRAM,0); + const DrumMap* new_drummap = MusEGlobal::midiPorts[_outPort].instrument()->drummap_for_patch(patch); + + if (!drummaps_almost_equal(new_drummap, this->drummap(), 128)) + { + for (int i=0;i<128;i++) + { + bool temp_mute=_drummap[i].mute; + _drummap[i]=new_drummap[i]; + _drummap[i].mute=temp_mute; + } + + if (_drummap_ordering_tied_to_patch) + init_drum_ordering(); + + return true; + } + } + + return false; +} + +void MidiTrack::set_drummap_tied_to_patch(bool val) +{ + _drummap_tied_to_patch=val; + if (val) auto_update_drummap(); +} + +void MidiTrack::set_drummap_ordering_tied_to_patch(bool val) +{ + _drummap_ordering_tied_to_patch=val; + if (val && _drummap_tied_to_patch) init_drum_ordering(); +} + } // namespace MusECore diff --git a/muse2/muse/track.h b/muse2/muse/track.h index f2e12e3a..1df8cad0 100644 --- a/muse2/muse/track.h +++ b/muse2/muse/track.h @@ -236,11 +236,13 @@ class MidiTrack : public Track { DrumMap* _drummap; // _drummap[foo].anote is always equal to foo bool* _drummap_hidden; // _drummap und _drummap_hidden will be an array[128] bool _drummap_tied_to_patch; //if true, changing patch also changes drummap + bool _drummap_ordering_tied_to_patch; //if true, changing patch also changes drummap-ordering int drum_in_map[128]; void init(); void init_drummap(bool write_ordering); // function without argument in public void remove_ourselves_from_drum_ordering(); + void init_drum_ordering(); void writeOurDrumSettings(int level, Xml& xml) const; void readOurDrumSettings(Xml& xml); @@ -310,6 +312,8 @@ class MidiTrack : public Track { virtual bool canRecord() const { return true; } static void setVisible(bool t) { _isVisible = t; } static bool visible() { return _isVisible; } + + int getFirstControllerValue(int ctrl, int def=-1); void setClef(clefTypes i) { clefType = i; } clefTypes getClef() { return clefType; } @@ -320,6 +324,12 @@ class MidiTrack : public Track { void update_drum_in_map(); void init_drummap() { init_drummap(false); } // function with argument in private + + bool auto_update_drummap(); + void set_drummap_tied_to_patch(bool); + bool drummap_tied_to_patch() { return _drummap_tied_to_patch; } + void set_drummap_ordering_tied_to_patch(bool); + bool drummap_ordering_tied_to_patch() { return _drummap_ordering_tied_to_patch; } //void writeOurDrumSettings(int level, Xml& xml) const; // above in private: //void readOurDrumSettings(Xml& xml); // above in private: diff --git a/muse2/muse/trackdrummapupdater.cpp b/muse2/muse/trackdrummapupdater.cpp new file mode 100644 index 00000000..35d5c056 --- /dev/null +++ b/muse2/muse/trackdrummapupdater.cpp @@ -0,0 +1,61 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: trackdrummapupdater.cpp,v 1.59.2.52 2011/12/27 20:25:58 flo93 Exp $ +// +// (C) Copyright 2011 Florian Jung (florian.a.jung (at) web.de) +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; version 2 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//========================================================= + +#include "trackdrummapupdater.h" +#include "song.h" +#include "globals.h" + +namespace MusECore { + +using MusEGlobal::song; + +TrackDrummapUpdater::TrackDrummapUpdater() +{ + connect(song,SIGNAL(songChanged(int)), this, SLOT(songChanged(int))); +} + +void TrackDrummapUpdater::songChanged(int flags) +{ + if (flags & (SC_TRACK_INSERTED | SC_TRACK_REMOVED | SC_TRACK_MODIFIED | + SC_PART_INSERTED | SC_PART_REMOVED | SC_PART_MODIFIED | + SC_EVENT_INSERTED | SC_EVENT_REMOVED | SC_EVENT_MODIFIED ) ) + { + bool changed=false; + for (iTrack t=song->tracks()->begin(); t!=song->tracks()->end(); t++) + { + MidiTrack* track=dynamic_cast<MidiTrack*>(*t); + if (track && track->auto_update_drummap()) + changed=true; + } + + if (changed) + { + // allow recursion. there will be no more recursion, because this + // is only executed when something other than SC_DRUMMAP happens + song->update(SC_DRUMMAP, true); + } + + } +} + +} //namespace MusECore diff --git a/muse2/muse/trackdrummapupdater.h b/muse2/muse/trackdrummapupdater.h new file mode 100644 index 00000000..caa2ac28 --- /dev/null +++ b/muse2/muse/trackdrummapupdater.h @@ -0,0 +1,43 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: trackdrummapupdater.h,v 1.59.2.52 2011/12/27 20:25:58 flo93 Exp $ +// +// (C) Copyright 2011 Florian Jung (florian.a.jung (at) web.de) +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; version 2 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//========================================================= + +#ifndef __TRACKDRUMMAPUPDATER_H__ +#define __TRACKDRUMMAPUPDATER_H__ + +#include <QObject> + +namespace MusECore { + +class TrackDrummapUpdater : public QObject +{ + Q_OBJECT + + public: + TrackDrummapUpdater(); + + private slots: + void songChanged(int flags); +}; + +} //namespace MusECore +#endif diff --git a/muse2/share/instruments/gs.idf b/muse2/share/instruments/gs.idf index 3368b7c9..1e8a54c0 100644 --- a/muse2/share/instruments/gs.idf +++ b/muse2/share/instruments/gs.idf @@ -214,5 +214,372 @@ <Controller name="DrumChorusSend" type="NRPN" h="30" l="pitch" /> <Controller name="Pitch" type="Pitch" /> <Controller name="Program" type="Program" /> + <Drummaps> + <entry> + <patch_collection hbank="127" prog="0-7" /> + <drummap> + <entry pitch="27"> <name>High Q</name> </entry> + <entry pitch="28"> <name>Slap</name> </entry> + <entry pitch="29"> <name>Scratch Push</name> </entry> + <entry pitch="30"> <name>Scratch Pull</name> </entry> + <entry pitch="31"> <name>Sticks</name> </entry> + <entry pitch="32"> <name>Square Click</name> </entry> + <entry pitch="33"> <name>Metronome Click</name> </entry> + <entry pitch="34"> <name>Metronome Bell</name> </entry> + <entry pitch="35"> <name>Kick Drum 2</name> </entry> + <entry pitch="36"> <name>Kick Drum 1</name> </entry> + <entry pitch="38"> <name>Snare Drum 1</name> </entry> + <entry pitch="40"> <name>Snare Drum 2</name> </entry> + <entry pitch="41"> <name>Low Tom 2</name> </entry> + <entry pitch="43"> <name>Low Tom 1</name> </entry> + <entry pitch="45"> <name>Mid Tom 2</name> </entry> + <entry pitch="47"> <name>Mid Tom 1</name> </entry> + <entry pitch="48"> <name>High Tom 2</name> </entry> + <entry pitch="50"> <name>High Tom 1</name> </entry> + <entry pitch="82"> <name>Shaker</name> </entry> + <entry pitch="83"> <name>Jingle Bell</name> </entry> + <entry pitch="84"> <name>Belltree</name> </entry> + <entry pitch="85"> <name>Castanets</name> </entry> + <entry pitch="86"> <name>Mute Surdo</name> </entry> + <entry pitch="87"> <name>Open Surdo</name> </entry> + </drummap> + </entry> + + <entry> + <patch_collection hbank="127" prog="8-15" /> + <drummap> + <entry pitch="27"> <name>High Q</name> </entry> + <entry pitch="28"> <name>Slap</name> </entry> + <entry pitch="29"> <name>Scratch Push</name> </entry> + <entry pitch="30"> <name>Scratch Pull</name> </entry> + <entry pitch="31"> <name>Sticks</name> </entry> + <entry pitch="32"> <name>Square Click</name> </entry> + <entry pitch="33"> <name>Metronome Click</name> </entry> + <entry pitch="34"> <name>Metronome Bell</name> </entry> + <entry pitch="35"> <name>Kick Drum 2</name> </entry> + <entry pitch="36"> <name>Kick Drum 1</name> </entry> + <entry pitch="38"> <name>Snare Drum 1</name> </entry> + <entry pitch="40"> <name>Snare Drum 2</name> </entry> + <entry pitch="41"> <name>Room Low Tom 2</name> </entry> + <entry pitch="43"> <name>Room Low Tom 1</name> </entry> + <entry pitch="45"> <name>Room Mid Tom 2</name> </entry> + <entry pitch="47"> <name>Room Mid Tom 1</name> </entry> + <entry pitch="48"> <name>Room High Tom 2</name> </entry> + <entry pitch="50"> <name>Room High Tom 1</name> </entry> + <entry pitch="82"> <name>Shaker</name> </entry> + <entry pitch="83"> <name>Jingle Bell</name> </entry> + <entry pitch="84"> <name>Belltree</name> </entry> + <entry pitch="85"> <name>Castanets</name> </entry> + <entry pitch="86"> <name>Mute Surdo</name> </entry> + <entry pitch="87"> <name>Open Surdo</name> </entry> + </drummap> + </entry> + + <entry> + <patch_collection hbank="127" prog="16-23" /> + <drummap> + <entry pitch="27"> <name>High Q</name> </entry> + <entry pitch="28"> <name>Slap</name> </entry> + <entry pitch="29"> <name>Scratch Push</name> </entry> + <entry pitch="30"> <name>Scratch Pull</name> </entry> + <entry pitch="31"> <name>Sticks</name> </entry> + <entry pitch="32"> <name>Square Click</name> </entry> + <entry pitch="33"> <name>Metronome Click</name> </entry> + <entry pitch="34"> <name>Metronome Bell</name> </entry> + <entry pitch="35"> <name>Kick Drum 2</name> </entry> + <entry pitch="36"> <name>Mondo Kick</name> </entry> + <entry pitch="38"> <name>Gated Snare</name> </entry> + <entry pitch="40"> <name>Snare Drum 2</name> </entry> + <entry pitch="41"> <name>Room Low Tom 2</name> </entry> + <entry pitch="43"> <name>Room Low Tom 1</name> </entry> + <entry pitch="45"> <name>Room Mid Tom 2</name> </entry> + <entry pitch="47"> <name>Room Mid Tom 1</name> </entry> + <entry pitch="48"> <name>Room High Tom 2</name> </entry> + <entry pitch="50"> <name>Room High Tom 1</name> </entry> + <entry pitch="82"> <name>Shaker</name> </entry> + <entry pitch="83"> <name>Jingle Bell</name> </entry> + <entry pitch="84"> <name>Belltree</name> </entry> + <entry pitch="85"> <name>Castanets</name> </entry> + <entry pitch="86"> <name>Mute Surdo</name> </entry> + <entry pitch="87"> <name>Open Surdo</name> </entry> + </drummap> + </entry> + + <entry> + <patch_collection hbank="127" prog="24" /> + <drummap> + <entry pitch="27"> <name>High Q</name> </entry> + <entry pitch="28"> <name>Slap</name> </entry> + <entry pitch="29"> <name>Scratch Push</name> </entry> + <entry pitch="30"> <name>Scratch Pull</name> </entry> + <entry pitch="31"> <name>Sticks</name> </entry> + <entry pitch="32"> <name>Square Click</name> </entry> + <entry pitch="33"> <name>Metronome Click</name> </entry> + <entry pitch="34"> <name>Metronome Bell</name> </entry> + <entry pitch="35"> <name>Kick Drum 2</name> </entry> + <entry pitch="36"> <name>Elec. Bass Drum</name> </entry> + <entry pitch="38"> <name>Elec. Snare</name> </entry> + <entry pitch="40"> <name>Gated Snare</name> </entry> + <entry pitch="41"> <name>Elec. Low Tom 2</name> </entry> + <entry pitch="43"> <name>Elec. Low Tom 1</name> </entry> + <entry pitch="45"> <name>Elec. Mid Tom 2</name> </entry> + <entry pitch="47"> <name>Elec. Mid Tom 1</name> </entry> + <entry pitch="48"> <name>Elec. High Tom 2</name> </entry> + <entry pitch="50"> <name>Elec. High Tom 1</name> </entry> + <entry pitch="52"> <name>Reverse Cymbal</name> </entry> + <entry pitch="82"> <name>Shaker</name> </entry> + <entry pitch="83"> <name>Jingle Bell</name> </entry> + <entry pitch="84"> <name>Belltree</name> </entry> + <entry pitch="85"> <name>Castanets</name> </entry> + <entry pitch="86"> <name>Mute Surdo</name> </entry> + <entry pitch="87"> <name>Open Surdo</name> </entry> + </drummap> + </entry> + + <entry> + <patch_collection hbank="127" prog="25-31" /> + <drummap> + <entry pitch="27"> <name>High Q</name> </entry> + <entry pitch="28"> <name>Slap</name> </entry> + <entry pitch="29"> <name>Scratch Push</name> </entry> + <entry pitch="30"> <name>Scratch Pull</name> </entry> + <entry pitch="31"> <name>Sticks</name> </entry> + <entry pitch="32"> <name>Square Click</name> </entry> + <entry pitch="33"> <name>Metronome Click</name> </entry> + <entry pitch="34"> <name>Metronome Bell</name> </entry> + <entry pitch="35"> <name>Kick Drum 2</name> </entry> + <entry pitch="36"> <name>808 Bass Drum</name> </entry> + <entry pitch="37"> <name>808 Rim Shot</name> </entry> + <entry pitch="38"> <name>808 Snare Drum</name> </entry> + <entry pitch="40"> <name>Snare Drum 2</name> </entry> + <entry pitch="41"> <name>808 Low Tom 2</name> </entry> + <entry pitch="42"> <name>808 Closed Hi-Hat</name> </entry> + <entry pitch="43"> <name>808 Low Tom 1</name> </entry> + <entry pitch="44"> <name>808 Pedal Hi-Hat</name> </entry> + <entry pitch="45"> <name>808 Tom 2</name> </entry> + <entry pitch="46"> <name>808 Open Hi-Hat</name> </entry> + <entry pitch="47"> <name>808 Mid Tom 1</name> </entry> + <entry pitch="48"> <name>808 High Tom 2</name> </entry> + <entry pitch="49"> <name>808 Cymbal</name> </entry> + <entry pitch="50"> <name>808 High Tom 1</name> </entry> + <entry pitch="52"> <name>Reverse Cymbal</name> </entry> + <entry pitch="56"> <name>808 Cowbell</name> </entry> + <entry pitch="62"> <name>808 High Conga</name> </entry> + <entry pitch="63"> <name>808 Mid Conga</name> </entry> + <entry pitch="64"> <name>808 Low Conga</name> </entry> + <entry pitch="70"> <name>808 Maracas</name> </entry> + <entry pitch="82"> <name>Shaker</name> </entry> + <entry pitch="83"> <name>Jingle Bell</name> </entry> + <entry pitch="84"> <name>Belltree</name> </entry> + <entry pitch="85"> <name>Castanets</name> </entry> + <entry pitch="86"> <name>Mute Surdo</name> </entry> + <entry pitch="87"> <name>Open Surdo</name> </entry> + </drummap> + </entry> + + <entry> + <patch_collection hbank="127" prog="32-39" /> + <drummap> + <entry pitch="27"> <name>High Q</name> </entry> + <entry pitch="28"> <name>Slap</name> </entry> + <entry pitch="29"> <name>Scratch Push</name> </entry> + <entry pitch="30"> <name>Scratch Pull</name> </entry> + <entry pitch="31"> <name>Sticks</name> </entry> + <entry pitch="32"> <name>Square Click</name> </entry> + <entry pitch="33"> <name>Metronome Click</name> </entry> + <entry pitch="34"> <name>Metronome Bell</name> </entry> + <entry pitch="35"> <name>Jazz Bass Drum 2</name> </entry> + <entry pitch="36"> <name>Jazz Bass Drum 1</name> </entry> + <entry pitch="38"> <name>Snare Drum 1</name> </entry> + <entry pitch="40"> <name>Snare Drum 2</name> </entry> + <entry pitch="41"> <name>Low Tom 2</name> </entry> + <entry pitch="43"> <name>Low Tom 1</name> </entry> + <entry pitch="45"> <name>Mid Tom 2</name> </entry> + <entry pitch="47"> <name>Mid Tom 1</name> </entry> + <entry pitch="48"> <name>High Tom 2</name> </entry> + <entry pitch="50"> <name>High Tom 1</name> </entry> + <entry pitch="82"> <name>Shaker</name> </entry> + <entry pitch="83"> <name>Jingle Bell</name> </entry> + <entry pitch="84"> <name>Belltree</name> </entry> + <entry pitch="85"> <name>Castanets</name> </entry> + <entry pitch="86"> <name>Mute Surdo</name> </entry> + <entry pitch="87"> <name>Open Surdo</name> </entry> + </drummap> + </entry> + + <entry> + <patch_collection hbank="127" prog="40-47" /> + <drummap> + <entry pitch="27"> <name>High Q</name> </entry> + <entry pitch="28"> <name>Slap</name> </entry> + <entry pitch="29"> <name>Scratch Push</name> </entry> + <entry pitch="30"> <name>Scratch Pull</name> </entry> + <entry pitch="31"> <name>Sticks</name> </entry> + <entry pitch="32"> <name>Square Click</name> </entry> + <entry pitch="33"> <name>Metronome Click</name> </entry> + <entry pitch="34"> <name>Metronome Bell</name> </entry> + <entry pitch="35"> <name>Jazz Bass Drum 2</name> </entry> + <entry pitch="36"> <name>Jazz Bass Drum 1</name> </entry> + <entry pitch="38"> <name>Brush Tap</name> </entry> + <entry pitch="39"> <name>Brush Slap</name> </entry> + <entry pitch="40"> <name>Brush Swirl</name> </entry> + <entry pitch="41"> <name>Low Tom 2</name> </entry> + <entry pitch="43"> <name>Low Tom 1</name> </entry> + <entry pitch="45"> <name>Mid Tom 2</name> </entry> + <entry pitch="47"> <name>Mid Tom 1</name> </entry> + <entry pitch="48"> <name>High Tom 2</name> </entry> + <entry pitch="50"> <name>High Tom 1</name> </entry> + <entry pitch="82"> <name>Shaker</name> </entry> + <entry pitch="83"> <name>Jingle Bell</name> </entry> + <entry pitch="84"> <name>Belltree</name> </entry> + <entry pitch="85"> <name>Castanets</name> </entry> + <entry pitch="86"> <name>Mute Surdo</name> </entry> + <entry pitch="87"> <name>Open Surdo</name> </entry> + </drummap> + </entry> + + <entry> + <patch_collection hbank="127" prog="48-55" /> + <drummap> + <entry pitch="27"> <name>Closed Hi-Hat</name> </entry> + <entry pitch="28"> <name>Pedal Hi-Hat</name> </entry> + <entry pitch="29"> <name>Open Hi-Hat</name> </entry> + <entry pitch="30"> <name>Ride Cymbal</name> </entry> + <entry pitch="31"> <name>Sticks</name> </entry> + <entry pitch="32"> <name>Square Click</name> </entry> + <entry pitch="33"> <name>Metronome Click</name> </entry> + <entry pitch="34"> <name>Metronome Bell</name> </entry> + <entry pitch="35"> <name>Concert Bass Drum 2</name> </entry> + <entry pitch="36"> <name>Concert Bass Drum 1</name> </entry> + <entry pitch="38"> <name>Concert Snare Drum</name> </entry> + <entry pitch="39"> <name>Castanets</name> </entry> + <entry pitch="40"> <name>Concert Snare Drum</name> </entry> + <entry pitch="41"> <name>Timpani F</name> </entry> + <entry pitch="42"> <name>Timpani F#</name> </entry> + <entry pitch="43"> <name>Timpani G</name> </entry> + <entry pitch="44"> <name>Timpani G#</name> </entry> + <entry pitch="45"> <name>Timpani A</name> </entry> + <entry pitch="46"> <name>Timpani A#</name> </entry> + <entry pitch="47"> <name>Timpani B</name> </entry> + <entry pitch="48"> <name>Timpani C</name> </entry> + <entry pitch="49"> <name>Timpani C#</name> </entry> + <entry pitch="50"> <name>Timpani D</name> </entry> + <entry pitch="51"> <name>Timpani D#</name> </entry> + <entry pitch="52"> <name>Timpani E</name> </entry> + <entry pitch="53"> <name>Timpani F</name> </entry> + <entry pitch="57"> <name>Concert Cymbal 2</name> </entry> + <entry pitch="59"> <name>Concert Cymbal 1</name> </entry> + <entry pitch="82"> <name>Shaker</name> </entry> + <entry pitch="83"> <name>Jingle Bell</name> </entry> + <entry pitch="84"> <name>Belltree</name> </entry> + <entry pitch="85"> <name>Castanets</name> </entry> + <entry pitch="86"> <name>Mute Surdo</name> </entry> + <entry pitch="87"> <name>Open Surdo</name> </entry> + </drummap> + </entry> + + <entry> + <patch_collection hbank="127" prog="56-126" /> + <drummap> + <entry pitch="35"> <name></name> </entry> + <entry pitch="36"> <name></name> </entry> + <entry pitch="37"> <name></name> </entry> + <entry pitch="38"> <name></name> </entry> + <entry pitch="39"> <name>High Q</name> </entry> + <entry pitch="40"> <name>Slap</name> </entry> + <entry pitch="41"> <name>Scratch Push</name> </entry> + <entry pitch="42"> <name>Scratch Pull</name> </entry> + <entry pitch="43"> <name>Sticks</name> </entry> + <entry pitch="44"> <name>Square Click</name> </entry> + <entry pitch="45"> <name>Metronome Click</name> </entry> + <entry pitch="46"> <name>Metronome Bell</name> </entry> + <entry pitch="47"> <name>Guitar Fret Noise</name> </entry> + <entry pitch="48"> <name>Guitar Cut Noise Up</name> </entry> + <entry pitch="49"> <name>Guitar Cut Noise Down</name> </entry> + <entry pitch="50"> <name>Double Bass String Slap</name> </entry> + <entry pitch="51"> <name>Flute Key Click</name> </entry> + <entry pitch="52"> <name>Laughing</name> </entry> + <entry pitch="53"> <name>Screaming</name> </entry> + <entry pitch="54"> <name>Punch</name> </entry> + <entry pitch="55"> <name>Heartbeat</name> </entry> + <entry pitch="56"> <name>Footsteps 1</name> </entry> + <entry pitch="57"> <name>Footsteps 2</name> </entry> + <entry pitch="58"> <name>Applause</name> </entry> + <entry pitch="59"> <name>Door Creaking</name> </entry> + <entry pitch="60"> <name>Door Closing</name> </entry> + <entry pitch="61"> <name>Scratch</name> </entry> + <entry pitch="62"> <name>Wind Chimes</name> </entry> + <entry pitch="63"> <name>Car Engine</name> </entry> + <entry pitch="64"> <name>Car Brakes</name> </entry> + <entry pitch="65"> <name>Car Passing</name> </entry> + <entry pitch="66"> <name>Car Crash</name> </entry> + <entry pitch="67"> <name>Siren</name> </entry> + <entry pitch="68"> <name>Train</name> </entry> + <entry pitch="69"> <name>Jet Plane</name> </entry> + <entry pitch="70"> <name>Helicopter</name> </entry> + <entry pitch="71"> <name>Starship</name> </entry> + <entry pitch="72"> <name>Gun Shot</name> </entry> + <entry pitch="73"> <name>Machine Gun</name> </entry> + <entry pitch="74"> <name>Laser Gun</name> </entry> + <entry pitch="75"> <name>Explosion</name> </entry> + <entry pitch="76"> <name>Dog Bark</name> </entry> + <entry pitch="77"> <name>Horse Gallop</name> </entry> + <entry pitch="78"> <name>Birds Tweet</name> </entry> + <entry pitch="79"> <name>Rain</name> </entry> + <entry pitch="80"> <name>Thunder</name> </entry> + <entry pitch="81"> <name>Wind</name> </entry> + <entry pitch="82"> <name>Seashore</name> </entry> + <entry pitch="83"> <name>Stream</name> </entry> + <entry pitch="84"> <name>Bubble</name> </entry> + </drummap> + </entry> + + <entry> + <patch_collection hbank="127" prog="127" /> + <drummap> + <entry pitch="52"> <name></name> </entry> + <entry pitch="53"> <name></name> </entry> + <entry pitch="55"> <name></name> </entry> + <entry pitch="57"> <name></name> </entry> + <entry pitch="58"> <name></name> </entry> + <entry pitch="59"> <name></name> </entry> + <entry pitch="73"> <name>Quijada</name> </entry> + <entry pitch="74"> <name></name> </entry> + <entry pitch="76"> <name>Laughing</name> </entry> + <entry pitch="77"> <name>Screaming</name> </entry> + <entry pitch="78"> <name>Punch</name> </entry> + <entry pitch="79"> <name>Heartbeat</name> </entry> + <entry pitch="80"> <name>Footsteps 1</name> </entry> + <entry pitch="81"> <name>Footsteps 2</name> </entry> + <entry pitch="82"> <name>Applause</name> </entry> + <entry pitch="83"> <name>Door Creaking</name> </entry> + <entry pitch="84"> <name>Door Closing</name> </entry> + <entry pitch="85"> <name>Scratch</name> </entry> + <entry pitch="86"> <name>Wind Chimes</name> </entry> + <entry pitch="87"> <name>Car Engine</name> </entry> + <entry pitch="88"> <name>Car Brakes</name> </entry> + <entry pitch="89"> <name>Car Passing</name> </entry> + <entry pitch="90"> <name>Car Crash</name> </entry> + <entry pitch="91"> <name>Siren</name> </entry> + <entry pitch="92"> <name>Train</name> </entry> + <entry pitch="93"> <name>Jet Plane</name> </entry> + <entry pitch="94"> <name>Helicopter</name> </entry> + <entry pitch="95"> <name>Starship</name> </entry> + <entry pitch="96"> <name>Gun Shot</name> </entry> + <entry pitch="97"> <name>Machine Gun</name> </entry> + <entry pitch="98"> <name>Laser Gun</name> </entry> + <entry pitch="99"> <name>Explosion</name> </entry> + <entry pitch="100"> <name>Dog Bark</name> </entry> + <entry pitch="101"> <name>Horse Gallop</name> </entry> + <entry pitch="102"> <name>Birds Tweet</name> </entry> + <entry pitch="103"> <name>Rain</name> </entry> + <entry pitch="104"> <name>Thunder</name> </entry> + <entry pitch="105"> <name>Wind</name> </entry> + <entry pitch="106"> <name>Seashore</name> </entry> + <entry pitch="107"> <name>Stream</name> </entry> + <entry pitch="108"> <name>Bubble</name> </entry> + </drummap> + </entry> + </MidiInstrument> </muse> diff --git a/muse2/share/instruments/xg.idf b/muse2/share/instruments/xg.idf index 4f5f586e..c281df66 100644 --- a/muse2/share/instruments/xg.idf +++ b/muse2/share/instruments/xg.idf @@ -602,5 +602,506 @@ <Controller name="Drum VariationSendLev" type="NRPN" h="31" l="pitch" /> <Controller name="Pitch" type="Pitch" /> <Controller name="Program" type="Program" /> + + <Drummaps> + <entry> + <patch_collection hbank="127" prog="0" /> + <drummap> + <entry pitch="13"> <name>Mute Surdo</name> </entry> + <entry pitch="14"> <name>Open Surdo</name> </entry> + <entry pitch="15"> <name>High Q</name> </entry> + <entry pitch="16"> <name>Whip Slap</name> </entry> + <entry pitch="17"> <name>Scratch Push</name> </entry> + <entry pitch="18"> <name>Scratch Pull</name> </entry> + <entry pitch="19"> <name>Finger Snap</name> </entry> + <entry pitch="20"> <name>Click Noise</name> </entry> + <entry pitch="21"> <name>Metronome Click</name> </entry> + <entry pitch="22"> <name>Metronome Bell</name> </entry> + <entry pitch="23"> <name>Seq Click L</name> </entry> + <entry pitch="24"> <name>Seq Click H</name> </entry> + <entry pitch="25"> <name>Brush Tap</name> </entry> + <entry pitch="26"> <name>Brush Swirl L</name> </entry> + <entry pitch="27"> <name>Brush Slap</name> </entry> + <entry pitch="28"> <name>Brush Swirl H</name> </entry> + <entry pitch="29"> <name>Snare Roll</name> </entry> + <entry pitch="30"> <name>Castanet</name> </entry> + <entry pitch="31"> <name>Snare L</name> </entry> + <entry pitch="32"> <name>Sticks</name> </entry> + <entry pitch="33"> <name>Bass Drum L</name> </entry> + <entry pitch="34"> <name>Open Rim Shot</name> </entry> + <entry pitch="35"> <name>Bass Drum M</name> </entry> + <entry pitch="36"> <name>Bass Drum H</name> </entry> + <entry pitch="38"> <name>Snare M</name> </entry> + <entry pitch="40"> <name>Snare H</name> </entry> + <entry pitch="82"> <name>Shaker</name> </entry> + <entry pitch="83"> <name>Jingle Bell</name> </entry> + <entry pitch="84"> <name>Belltree</name> </entry> + </drummap> + </entry> + + <entry> + <patch_collection hbank="127" prog="1-7" /> + <drummap> + <entry pitch="13"> <name>Mute Surdo</name> </entry> + <entry pitch="14"> <name>Open Surdo</name> </entry> + <entry pitch="15"> <name>High Q</name> </entry> + <entry pitch="16"> <name>Whip Slap</name> </entry> + <entry pitch="17"> <name>Scratch Push</name> </entry> + <entry pitch="18"> <name>Scratch Pull</name> </entry> + <entry pitch="19"> <name>Finger Snap</name> </entry> + <entry pitch="20"> <name>Click Noise</name> </entry> + <entry pitch="21"> <name>Metronome Click</name> </entry> + <entry pitch="22"> <name>Metronome Bell</name> </entry> + <entry pitch="23"> <name>Seq Click L</name> </entry> + <entry pitch="24"> <name>Seq Click H</name> </entry> + <entry pitch="25"> <name>Brush Tap</name> </entry> + <entry pitch="26"> <name>Brush Swirl L</name> </entry> + <entry pitch="27"> <name>Brush Slap</name> </entry> + <entry pitch="28"> <name>Brush Swirl H</name> </entry> + <entry pitch="29"> <name>Snare Roll 2</name> </entry> + <entry pitch="30"> <name>Castanet</name> </entry> + <entry pitch="31"> <name>Snare L 2</name> </entry> + <entry pitch="32"> <name>Sticks</name> </entry> + <entry pitch="33"> <name>Bass Drum L</name> </entry> + <entry pitch="34"> <name>Open Rim Shot 2</name> </entry> + <entry pitch="35"> <name>Bass Drum M 2</name> </entry> + <entry pitch="36"> <name>Bass Drum H 2</name> </entry> + <entry pitch="38"> <name>Snare M 2</name> </entry> + <entry pitch="40"> <name>Snare H 2</name> </entry> + <entry pitch="82"> <name>Shaker</name> </entry> + <entry pitch="83"> <name>Jingle Bell</name> </entry> + <entry pitch="84"> <name>Belltree</name> </entry> + </drummap> + </entry> + + <entry> + <patch_collection hbank="127" prog="8-15" /> + <drummap> + <entry pitch="13"> <name>Mute Surdo</name> </entry> + <entry pitch="14"> <name>Open Surdo</name> </entry> + <entry pitch="15"> <name>High Q</name> </entry> + <entry pitch="16"> <name>Whip Slap</name> </entry> + <entry pitch="17"> <name>Scratch Push</name> </entry> + <entry pitch="18"> <name>Scratch Pull</name> </entry> + <entry pitch="19"> <name>Finger Snap</name> </entry> + <entry pitch="20"> <name>Click Noise</name> </entry> + <entry pitch="21"> <name>Metronome Click</name> </entry> + <entry pitch="22"> <name>Metronome Bell</name> </entry> + <entry pitch="23"> <name>Seq Click L</name> </entry> + <entry pitch="24"> <name>Seq Click H</name> </entry> + <entry pitch="25"> <name>Brush Tap</name> </entry> + <entry pitch="26"> <name>Brush Swirl L</name> </entry> + <entry pitch="27"> <name>Brush Slap</name> </entry> + <entry pitch="28"> <name>Brush Swirl H</name> </entry> + <entry pitch="29"> <name>Snare Roll</name> </entry> + <entry pitch="30"> <name>Castanet</name> </entry> + <entry pitch="31"> <name>Snare L</name> </entry> + <entry pitch="32"> <name>Sticks</name> </entry> + <entry pitch="33"> <name>Bass Drum L</name> </entry> + <entry pitch="34"> <name>Open Rim Shot</name> </entry> + <entry pitch="35"> <name>Bass Drum M</name> </entry> + <entry pitch="36"> <name>Room Bass Drum</name> </entry> + <entry pitch="38"> <name>Room Snare L</name> </entry> + <entry pitch="40"> <name>Room Snare H</name> </entry> + <entry pitch="41"> <name>Room Tom 1</name> </entry> + <entry pitch="43"> <name>Room Tom 2</name> </entry> + <entry pitch="45"> <name>Room Tom 3</name> </entry> + <entry pitch="47"> <name>Room Tom 4</name> </entry> + <entry pitch="48"> <name>Room Tom 5</name> </entry> + <entry pitch="50"> <name>Room Tom 6</name> </entry> + <entry pitch="82"> <name>Shaker</name> </entry> + <entry pitch="83"> <name>Jingle Bell</name> </entry> + <entry pitch="84"> <name>Belltree</name> </entry> + </drummap> + </entry> + + <entry> + <patch_collection hbank="127" prog="16-23" /> + <drummap> + <entry pitch="13"> <name>Mute Surdo</name> </entry> + <entry pitch="14"> <name>Open Surdo</name> </entry> + <entry pitch="15"> <name>High Q</name> </entry> + <entry pitch="16"> <name>Whip Slap</name> </entry> + <entry pitch="17"> <name>Scratch Push</name> </entry> + <entry pitch="18"> <name>Scratch Pull</name> </entry> + <entry pitch="19"> <name>Finger Snap</name> </entry> + <entry pitch="20"> <name>Click Noise</name> </entry> + <entry pitch="21"> <name>Metronome Click</name> </entry> + <entry pitch="22"> <name>Metronome Bell</name> </entry> + <entry pitch="23"> <name>Seq Click L</name> </entry> + <entry pitch="24"> <name>Seq Click H</name> </entry> + <entry pitch="25"> <name>Brush Tap</name> </entry> + <entry pitch="26"> <name>Brush Swirl L</name> </entry> + <entry pitch="27"> <name>Brush Slap</name> </entry> + <entry pitch="28"> <name>Brush Swirl H</name> </entry> + <entry pitch="29"> <name>Snare Roll</name> </entry> + <entry pitch="30"> <name>Castanet</name> </entry> + <entry pitch="31"> <name>Rock Snare M</name> </entry> + <entry pitch="32"> <name>Sticks</name> </entry> + <entry pitch="33"> <name>Rock Bass Drum M</name> </entry> + <entry pitch="34"> <name>Open Rim Shot</name> </entry> + <entry pitch="35"> <name>Bass Drum H 3</name> </entry> + <entry pitch="36"> <name>Rock Bass Drum</name> </entry> + <entry pitch="38"> <name>Rock Snare L</name> </entry> + <entry pitch="40"> <name>Rock Snare Rim</name> </entry> + <entry pitch="41"> <name>Rock Tom 1</name> </entry> + <entry pitch="43"> <name>Rock Tom 2</name> </entry> + <entry pitch="45"> <name>Rock Tom 3</name> </entry> + <entry pitch="47"> <name>Rock Tom 4</name> </entry> + <entry pitch="48"> <name>Rock Tom 5</name> </entry> + <entry pitch="50"> <name>Rock Tom 6</name> </entry> + <entry pitch="82"> <name>Shaker</name> </entry> + <entry pitch="83"> <name>Jingle Bell</name> </entry> + <entry pitch="84"> <name>Belltree</name> </entry> + </drummap> + </entry> + + <entry> + <patch_collection hbank="127" prog="24" /> + <drummap> + <entry pitch="13"> <name>Mute Surdo</name> </entry> + <entry pitch="14"> <name>Open Surdo</name> </entry> + <entry pitch="15"> <name>High Q</name> </entry> + <entry pitch="16"> <name>Whip Slap</name> </entry> + <entry pitch="17"> <name>Scratch Push</name> </entry> + <entry pitch="18"> <name>Scratch Pull</name> </entry> + <entry pitch="19"> <name>Finger Snap</name> </entry> + <entry pitch="20"> <name>Click Noise</name> </entry> + <entry pitch="21"> <name>Metronome Click</name> </entry> + <entry pitch="22"> <name>Metronome Bell</name> </entry> + <entry pitch="23"> <name>Seq Click L</name> </entry> + <entry pitch="24"> <name>Seq Click H</name> </entry> + <entry pitch="25"> <name>Brush Tap</name> </entry> + <entry pitch="26"> <name>Brush Swirl L</name> </entry> + <entry pitch="27"> <name>Brush Slap</name> </entry> + <entry pitch="28"> <name>Reverse Cymbal</name> </entry> + <entry pitch="29"> <name>Snare Roll</name> </entry> + <entry pitch="30"> <name>High Q</name> </entry> + <entry pitch="31"> <name>Snare M</name> </entry> + <entry pitch="32"> <name>Sticks</name> </entry> + <entry pitch="33"> <name>Bass Drum H 4</name> </entry> + <entry pitch="34"> <name>Open Rim Shot</name> </entry> + <entry pitch="35"> <name>Rock Bass Drum</name> </entry> + <entry pitch="36"> <name>Gated Bass Drum</name> </entry> + <entry pitch="38"> <name>Rock Snare L</name> </entry> + <entry pitch="40"> <name>Rock Snare H</name> </entry> + <entry pitch="41"> <name>Elec. Tom 1</name> </entry> + <entry pitch="43"> <name>Elec. Tom 2</name> </entry> + <entry pitch="45"> <name>Elec. Tom 3</name> </entry> + <entry pitch="47"> <name>Elec. Tom 4</name> </entry> + <entry pitch="48"> <name>Elec. Tom 5</name> </entry> + <entry pitch="50"> <name>Elec. Tom 6</name> </entry> + <entry pitch="78"> <name>Scratch Push</name> </entry> + <entry pitch="79"> <name>Scratch Pull</name> </entry> + <entry pitch="82"> <name>Shaker</name> </entry> + <entry pitch="83"> <name>Jingle Bell</name> </entry> + <entry pitch="84"> <name>Belltree</name> </entry> + </drummap> + </entry> + + <entry> + <patch_collection hbank="127" prog="25-31" /> + <drummap> + <entry pitch="13"> <name>Mute Surdo</name> </entry> + <entry pitch="14"> <name>Open Surdo</name> </entry> + <entry pitch="15"> <name>High Q</name> </entry> + <entry pitch="16"> <name>Whip Slap</name> </entry> + <entry pitch="17"> <name>Scratch Push</name> </entry> + <entry pitch="18"> <name>Scratch Pull</name> </entry> + <entry pitch="19"> <name>Finger Snap</name> </entry> + <entry pitch="20"> <name>Click Noise</name> </entry> + <entry pitch="21"> <name>Metronome Click</name> </entry> + <entry pitch="22"> <name>Metronome Bell</name> </entry> + <entry pitch="23"> <name>Seq Click L</name> </entry> + <entry pitch="24"> <name>Seq Click H</name> </entry> + <entry pitch="25"> <name>Brush Tap</name> </entry> + <entry pitch="26"> <name>Brush Swirl L</name> </entry> + <entry pitch="27"> <name>Brush Slap</name> </entry> + <entry pitch="28"> <name>Reverse Cymbal</name> </entry> + <entry pitch="29"> <name>Snare Roll</name> </entry> + <entry pitch="30"> <name>High Q</name> </entry> + <entry pitch="31"> <name>Rock Snare H</name> </entry> + <entry pitch="32"> <name>Sticks</name> </entry> + <entry pitch="33"> <name>Bass Drum M</name> </entry> + <entry pitch="34"> <name>Open Rim Shot</name> </entry> + <entry pitch="35"> <name>Analog Bass Drum L</name> </entry> + <entry pitch="36"> <name>Analog Bass Drum H</name> </entry> + <entry pitch="37"> <name>Analog Side Stick</name> </entry> + <entry pitch="38"> <name>Analog Snare L</name> </entry> + <entry pitch="40"> <name>Analog Snare H</name> </entry> + <entry pitch="41"> <name>Analog Tom 1</name> </entry> + <entry pitch="42"> <name>Analog Hi-Hat Closed 1</name> </entry> + <entry pitch="43"> <name>Analog Tom 2</name> </entry> + <entry pitch="44"> <name>Analog Hi-Hat Closed 2</name> </entry> + <entry pitch="45"> <name>Analog Tom 3</name> </entry> + <entry pitch="46"> <name>Analog Hi-Hat Open</name> </entry> + <entry pitch="47"> <name>Analog Tom 4</name> </entry> + <entry pitch="48"> <name>Analog Tom 5</name> </entry> + <entry pitch="49"> <name>Analog Cymbal</name> </entry> + <entry pitch="50"> <name>Analog Tom 6</name> </entry> + <entry pitch="56"> <name>Analog Cowbell</name> </entry> + <entry pitch="62"> <name>Analog Conga H</name> </entry> + <entry pitch="63"> <name>Analog Conga M</name> </entry> + <entry pitch="64"> <name>Analog Conga L</name> </entry> + <entry pitch="70"> <name>Analog Maracas</name> </entry> + <entry pitch="75"> <name>Analog Claves</name> </entry> + <entry pitch="78"> <name>Scratch Push</name> </entry> + <entry pitch="79"> <name>Scratch Pull</name> </entry> + <entry pitch="82"> <name>Shaker</name> </entry> + <entry pitch="83"> <name>Jingle Bell</name> </entry> + <entry pitch="84"> <name>Belltree</name> </entry> + </drummap> + </entry> + + <entry> + <patch_collection hbank="127" prog="32-39" /> + <drummap> + <entry pitch="13"> <name>Mute Surdo</name> </entry> + <entry pitch="14"> <name>Open Surdo</name> </entry> + <entry pitch="15"> <name>High Q</name> </entry> + <entry pitch="16"> <name>Whip Slap</name> </entry> + <entry pitch="17"> <name>Scratch Push</name> </entry> + <entry pitch="18"> <name>Scratch Pull</name> </entry> + <entry pitch="19"> <name>Finger Snap</name> </entry> + <entry pitch="20"> <name>Click Noise</name> </entry> + <entry pitch="21"> <name>Metronome Click</name> </entry> + <entry pitch="22"> <name>Metronome Bell</name> </entry> + <entry pitch="23"> <name>Seq Click L</name> </entry> + <entry pitch="24"> <name>Seq Click H</name> </entry> + <entry pitch="25"> <name>Brush Tap</name> </entry> + <entry pitch="26"> <name>Brush Swirl L</name> </entry> + <entry pitch="27"> <name>Brush Slap</name> </entry> + <entry pitch="28"> <name>Brush Swirl H</name> </entry> + <entry pitch="29"> <name>Snare Roll</name> </entry> + <entry pitch="30"> <name>Castanet</name> </entry> + <entry pitch="31"> <name>Snare L</name> </entry> + <entry pitch="32"> <name>Sticks</name> </entry> + <entry pitch="33"> <name>Bass Drum L</name> </entry> + <entry pitch="34"> <name>Open Rim Shot</name> </entry> + <entry pitch="35"> <name>Bass Drum M</name> </entry> + <entry pitch="36"> <name>Jazz Bass Drum</name> </entry> + <entry pitch="38"> <name>Snare M</name> </entry> + <entry pitch="40"> <name>Snare H</name> </entry> + <entry pitch="41"> <name>Jazz Tom 1</name> </entry> + <entry pitch="43"> <name>Jazz Tom 2</name> </entry> + <entry pitch="45"> <name>Jazz Tom 3</name> </entry> + <entry pitch="47"> <name>Jazz Tom 4</name> </entry> + <entry pitch="48"> <name>Jazz Tom 5</name> </entry> + <entry pitch="50"> <name>Jazz Tom 6</name> </entry> + <entry pitch="82"> <name>Shaker</name> </entry> + <entry pitch="83"> <name>Jingle Bell</name> </entry> + <entry pitch="84"> <name>Belltree</name> </entry> + </drummap> + </entry> + + <entry> + <patch_collection hbank="127" prog="40-47" /> + <drummap> + <entry pitch="13"> <name>Mute Surdo</name> </entry> + <entry pitch="14"> <name>Open Surdo</name> </entry> + <entry pitch="15"> <name>High Q</name> </entry> + <entry pitch="16"> <name>Whip Slap</name> </entry> + <entry pitch="17"> <name>Scratch Push</name> </entry> + <entry pitch="18"> <name>Scratch Pull</name> </entry> + <entry pitch="19"> <name>Finger Snap</name> </entry> + <entry pitch="20"> <name>Click Noise</name> </entry> + <entry pitch="21"> <name>Metronome Click</name> </entry> + <entry pitch="22"> <name>Metronome Bell</name> </entry> + <entry pitch="23"> <name>Seq Click L</name> </entry> + <entry pitch="24"> <name>Seq Click H</name> </entry> + <entry pitch="25"> <name>Brush Tap</name> </entry> + <entry pitch="26"> <name>Brush Swirl L</name> </entry> + <entry pitch="27"> <name>Brush Slap</name> </entry> + <entry pitch="28"> <name>Brush Swirl H</name> </entry> + <entry pitch="29"> <name>Snare Roll</name> </entry> + <entry pitch="30"> <name>Castanet</name> </entry> + <entry pitch="31"> <name>Brush Slap L</name> </entry> + <entry pitch="32"> <name>Sticks</name> </entry> + <entry pitch="33"> <name>Bass Drum L</name> </entry> + <entry pitch="34"> <name>Open Rim Shot</name> </entry> + <entry pitch="35"> <name>Bass Drum M</name> </entry> + <entry pitch="36"> <name>Soft Bass Drum</name> </entry> + <entry pitch="38"> <name>Brush Slap</name> </entry> + <entry pitch="40"> <name>Brush Tap</name> </entry> + <entry pitch="41"> <name>Brush Tom 1</name> </entry> + <entry pitch="43"> <name>Brush Tom 2</name> </entry> + <entry pitch="45"> <name>Brush Tom 3</name> </entry> + <entry pitch="47"> <name>Brush Tom 4</name> </entry> + <entry pitch="48"> <name>Brush Tom 5</name> </entry> + <entry pitch="50"> <name>Brush Tom 6</name> </entry> + <entry pitch="82"> <name>Shaker</name> </entry> + <entry pitch="83"> <name>Jingle Bell</name> </entry> + <entry pitch="84"> <name>Belltree</name> </entry> + </drummap> + </entry> + + <entry> + <patch_collection hbank="127" prog="48-127" /> + <drummap> + <entry pitch="13"> <name>Mute Surdo</name> </entry> + <entry pitch="14"> <name>Open Surdo</name> </entry> + <entry pitch="15"> <name>High Q</name> </entry> + <entry pitch="16"> <name>Whip Slap</name> </entry> + <entry pitch="17"> <name>Scratch Push</name> </entry> + <entry pitch="18"> <name>Scratch Pull</name> </entry> + <entry pitch="19"> <name>Finger Snap</name> </entry> + <entry pitch="20"> <name>Click Noise</name> </entry> + <entry pitch="21"> <name>Metronome Click</name> </entry> + <entry pitch="22"> <name>Metronome Bell</name> </entry> + <entry pitch="23"> <name>Seq Click L</name> </entry> + <entry pitch="24"> <name>Seq Click H</name> </entry> + <entry pitch="25"> <name>Brush Tap</name> </entry> + <entry pitch="26"> <name>Brush Swirl L</name> </entry> + <entry pitch="27"> <name>Brush Slap</name> </entry> + <entry pitch="28"> <name>Brush Swirl H</name> </entry> + <entry pitch="29"> <name>Snare Roll</name> </entry> + <entry pitch="30"> <name>Castanet</name> </entry> + <entry pitch="31"> <name>Snare L</name> </entry> + <entry pitch="32"> <name>Sticks</name> </entry> + <entry pitch="33"> <name>Bass Drum L 2</name> </entry> + <entry pitch="34"> <name>Open Rim Shot</name> </entry> + <entry pitch="35"> <name>Gran Cassa</name> </entry> + <entry pitch="36"> <name>Gran Cassa Mute</name> </entry> + <entry pitch="38"> <name>Marching Snare H</name> </entry> + <entry pitch="40"> <name>Marching Snare M</name> </entry> + <entry pitch="41"> <name>Jazz Tom 1</name> </entry> + <entry pitch="43"> <name>Jazz Tom 2</name> </entry> + <entry pitch="45"> <name>Jazz Tom 3</name> </entry> + <entry pitch="47"> <name>Jazz Tom 4</name> </entry> + <entry pitch="48"> <name>Jazz Tom 5</name> </entry> + <entry pitch="49"> <name>Hand Cym. Open L</name> </entry> + <entry pitch="50"> <name>Jazz Tom 6</name> </entry> + <entry pitch="51"> <name>Hand Cym. Closed L</name> </entry> + <entry pitch="57"> <name>Hand Cym. Open H</name> </entry> + <entry pitch="59"> <name>Hand Cym. Closed H</name> </entry> + <entry pitch="82"> <name>Shaker</name> </entry> + <entry pitch="83"> <name>Jingle Bell</name> </entry> + <entry pitch="84"> <name>Belltree</name> </entry> + </drummap> + </entry> + + <entry> + <patch_collection hbank="126" prog="0" /> + <drummap> + <entry pitch="35"> <name></name> </entry> + <entry pitch="36"> <name>Guitar Cutting Noise</name> </entry> + <entry pitch="37"> <name>Guitar Cutting Noise 2</name> </entry> + <entry pitch="38"> <name>Dist. Cut Noise</name> </entry> + <entry pitch="39"> <name>String Slap</name> </entry> + <entry pitch="40"> <name>Bass Slide</name> </entry> + <entry pitch="41"> <name>Pick Scrape</name> </entry> + <entry pitch="42"> <name></name> </entry> + <entry pitch="43"> <name></name> </entry> + <entry pitch="44"> <name></name> </entry> + <entry pitch="45"> <name></name> </entry> + <entry pitch="46"> <name></name> </entry> + <entry pitch="47"> <name></name> </entry> + <entry pitch="48"> <name></name> </entry> + <entry pitch="49"> <name></name> </entry> + <entry pitch="50"> <name></name> </entry> + <entry pitch="51"> <name></name> </entry> + <entry pitch="52"> <name>FL.Key Click</name> </entry> + <entry pitch="53"> <name></name> </entry> + <entry pitch="54"> <name></name> </entry> + <entry pitch="55"> <name></name> </entry> + <entry pitch="56"> <name></name> </entry> + <entry pitch="57"> <name></name> </entry> + <entry pitch="58"> <name></name> </entry> + <entry pitch="59"> <name></name> </entry> + <entry pitch="60"> <name></name> </entry> + <entry pitch="61"> <name></name> </entry> + <entry pitch="62"> <name></name> </entry> + <entry pitch="63"> <name></name> </entry> + <entry pitch="64"> <name></name> </entry> + <entry pitch="65"> <name></name> </entry> + <entry pitch="66"> <name></name> </entry> + <entry pitch="67"> <name></name> </entry> + <entry pitch="68"> <name>Rain</name> </entry> + <entry pitch="69"> <name>Thunder</name> </entry> + <entry pitch="70"> <name>Wind</name> </entry> + <entry pitch="71"> <name>Stream</name> </entry> + <entry pitch="72"> <name>Bubble</name> </entry> + <entry pitch="73"> <name>Feed</name> </entry> + <entry pitch="74"> <name></name> </entry> + <entry pitch="75"> <name></name> </entry> + <entry pitch="76"> <name></name> </entry> + <entry pitch="77"> <name></name> </entry> + <entry pitch="78"> <name></name> </entry> + <entry pitch="79"> <name></name> </entry> + <entry pitch="80"> <name></name> </entry> + <entry pitch="81"> <name></name> </entry> + <entry pitch="82"> <name></name> </entry> + <entry pitch="83"> <name></name> </entry> + <entry pitch="84"> <name>Dog</name> </entry> + <entry pitch="85"> <name>Horse Gallop</name> </entry> + <entry pitch="86"> <name>Bird 2</name> </entry> + <entry pitch="87"> <name>Kitty</name> </entry> + <entry pitch="88"> <name>Growl</name> </entry> + <entry pitch="89"> <name>Haunted</name> </entry> + <entry pitch="90"> <name>Ghost</name> </entry> + <entry pitch="91"> <name>Maou</name> </entry> + </drummap> + </entry> + + <entry> + <patch_collection hbank="126" prog="1" /> + <drummap> + <entry pitch="35"> <name></name> </entry> + <entry pitch="36"> <name>Dial Tone</name> </entry> + <entry pitch="37"> <name>Door Creaking</name> </entry> + <entry pitch="38"> <name>Door Slam</name> </entry> + <entry pitch="39"> <name>Scratch</name> </entry> + <entry pitch="40"> <name>Scratch 2</name> </entry> + <entry pitch="41"> <name>Windchime</name> </entry> + <entry pitch="42"> <name>Telephone Ring 2</name> </entry> + <entry pitch="43"> <name></name> </entry> + <entry pitch="44"> <name></name> </entry> + <entry pitch="45"> <name></name> </entry> + <entry pitch="46"> <name></name> </entry> + <entry pitch="47"> <name></name> </entry> + <entry pitch="48"> <name></name> </entry> + <entry pitch="49"> <name></name> </entry> + <entry pitch="50"> <name></name> </entry> + <entry pitch="51"> <name></name> </entry> + <entry pitch="52"> <name>Engine Start</name> </entry> + <entry pitch="53"> <name>Tire Screech</name> </entry> + <entry pitch="54"> <name>Car Passing</name> </entry> + <entry pitch="55"> <name>Crash</name> </entry> + <entry pitch="56"> <name>Siren</name> </entry> + <entry pitch="57"> <name>Train</name> </entry> + <entry pitch="58"> <name>Jetplane</name> </entry> + <entry pitch="59"> <name>Starship</name> </entry> + <entry pitch="60"> <name>Burst Noise</name> </entry> + <entry pitch="61"> <name>Coaster</name> </entry> + <entry pitch="62"> <name>SbMarine</name> </entry> + <entry pitch="63"> <name></name> </entry> + <entry pitch="64"> <name></name> </entry> + <entry pitch="65"> <name></name> </entry> + <entry pitch="66"> <name></name> </entry> + <entry pitch="67"> <name></name> </entry> + <entry pitch="68"> <name>Laughing</name> </entry> + <entry pitch="69"> <name>Screaming</name> </entry> + <entry pitch="70"> <name>Punch</name> </entry> + <entry pitch="71"> <name>Heartbeat</name> </entry> + <entry pitch="72"> <name>Footsteps</name> </entry> + <entry pitch="73"> <name>Applaus2</name> </entry> + <entry pitch="74"> <name></name> </entry> + <entry pitch="75"> <name></name> </entry> + <entry pitch="76"> <name></name> </entry> + <entry pitch="77"> <name></name> </entry> + <entry pitch="78"> <name></name> </entry> + <entry pitch="79"> <name></name> </entry> + <entry pitch="80"> <name></name> </entry> + <entry pitch="81"> <name></name> </entry> + <entry pitch="82"> <name></name> </entry> + <entry pitch="83"> <name></name> </entry> + <entry pitch="84"> <name>Machine Gun</name> </entry> + <entry pitch="85"> <name>Laser Gun</name> </entry> + <entry pitch="86"> <name>Explosion</name> </entry> + <entry pitch="87"> <name>Firework</name> </entry> + </drummap> + </entry> + + </Drummaps> </MidiInstrument> </muse> -- cgit v1.2.3 From 30ce0c7640d9d7d8e409d485fe044426b33ea522 Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Fri, 30 Dec 2011 18:29:26 +0000 Subject: removed silly song-type-depencency in MidiInstrument::getPatchName and MidiInstrument::populatePatchPopup() --- muse2/muse/instruments/minstrument.cpp | 53 ++++++++++------------------------ muse2/share/instruments/gm.idf | 3 ++ 2 files changed, 19 insertions(+), 37 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/instruments/minstrument.cpp b/muse2/muse/instruments/minstrument.cpp index 3876fb28..3906c399 100644 --- a/muse2/muse/instruments/minstrument.cpp +++ b/muse2/muse/instruments/minstrument.cpp @@ -49,8 +49,6 @@ namespace MusECore { MidiInstrumentList midiInstruments; MidiInstrument* genericMidiInstrument; -static const char* gmdrumname = "GM-drums"; - //--------------------------------------------------------- // string2sysex //--------------------------------------------------------- @@ -1054,8 +1052,6 @@ QString MidiInstrument::getPatchName(int channel, int prog, MType mode, bool dru tmask = 4; break; case MT_GM: - if(drumchan) - return gmdrumname; tmask = 1; break; default: @@ -1067,10 +1063,8 @@ QString MidiInstrument::getPatchName(int channel, int prog, MType mode, bool dru const PatchList& pl = (*i)->patches; for (ciPatch ipl = pl.begin(); ipl != pl.end(); ++ipl) { const Patch* mp = *ipl; - if ((mp->typ & tmask) - && (pr == mp->prog) - && ((drum && mode != MT_GM) || - (mp->drum == drumchan)) + if ( (pr == mp->prog) + && (mp->drum == drum) && (hbank == mp->hbank || !hb || mp->hbank == -1) && (lbank == mp->lbank || !lb || mp->lbank == -1)) @@ -1084,49 +1078,35 @@ QString MidiInstrument::getPatchName(int channel, int prog, MType mode, bool dru // populatePatchPopup //--------------------------------------------------------- -void MidiInstrument::populatePatchPopup(MusEGui::PopupMenu* menu, int chan, MType songType, bool drum) +void MidiInstrument::populatePatchPopup(MusEGui::PopupMenu* menu, int, MType, bool drum) { menu->clear(); - int mask = 0; - bool drumchan = chan == 9; - switch (songType) { - case MT_XG: mask = 4; break; - case MT_GS: mask = 2; break; - case MT_GM: - if(drumchan) - { - int id = (0xff << 16) + (0xff << 8) + 0x00; // First patch - QAction* act = menu->addAction(gmdrumname); - //act->setCheckable(true); - act->setData(id); - return; - } - mask = 1; - break; - case MT_UNKNOWN: mask = 7; break; - } + if (pg.size() > 1) { for (ciPatchGroup i = pg.begin(); i != pg.end(); ++i) { PatchGroup* pgp = *i; - //QMenu* pm = menu->addMenu(pgp->name); MusEGui::PopupMenu* pm = new MusEGui::PopupMenu(pgp->name, menu, menu->stayOpen()); // Use the parent stayOpen here. - menu->addMenu(pm); - pm->setFont(MusEGlobal::config.fonts[0]); const PatchList& pl = pgp->patches; + bool added=false; for (ciPatch ipl = pl.begin(); ipl != pl.end(); ++ipl) { const Patch* mp = *ipl; - if ((mp->typ & mask) && - ((drum && songType != MT_GM) || - (mp->drum == drumchan)) ) + if (mp->drum == drum) { int id = ((mp->hbank & 0xff) << 16) + ((mp->lbank & 0xff) << 8) + (mp->prog & 0xff); QAction* act = pm->addAction(mp->name); - //act->setCheckable(true); act->setData(id); + added=true; } - } + if (added) + { + menu->addMenu(pm); + pm->setFont(MusEGlobal::config.fonts[0]); + } + else + delete pm; + } } else if (pg.size() == 1 ){ @@ -1134,11 +1114,10 @@ void MidiInstrument::populatePatchPopup(MusEGui::PopupMenu* menu, int chan, MTyp const PatchList& pl = pg.front()->patches; for (ciPatch ipl = pl.begin(); ipl != pl.end(); ++ipl) { const Patch* mp = *ipl; - if (mp->typ & mask) { + if (mp->drum == drum) { int id = ((mp->hbank & 0xff) << 16) + ((mp->lbank & 0xff) << 8) + (mp->prog & 0xff); QAction* act = menu->addAction(mp->name); - //act->setCheckable(true); act->setData(id); } } diff --git a/muse2/share/instruments/gm.idf b/muse2/share/instruments/gm.idf index 04bf23ff..69e02503 100644 --- a/muse2/share/instruments/gm.idf +++ b/muse2/share/instruments/gm.idf @@ -161,6 +161,9 @@ <Patch name="Applaus" prog="126" /> <Patch name="Gunshot" prog="127" /> </PatchGroup> + <PatchGroup name="Drums"> + <Patch name="Drums" prog="0" drum="1" /> + </PatchGroup> <Controller name="Modulation" l="1" /> <Controller name="PortamentoTime" l="5" /> <Controller name="MainVolume" l="7" init="100" /> -- cgit v1.2.3 From 14ed268100ece710a009c287fa4d61d7254f7aa1 Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Fri, 30 Dec 2011 18:51:46 +0000 Subject: fixed gs.idf --- muse2/muse/midiedit/scoreedit.cpp | 4 +++- muse2/muse/xml.cpp | 2 +- muse2/share/instruments/gs.idf | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index 055134e2..45ccd4d6 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -4679,7 +4679,9 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo * from clipboard failed. ignoring this one... ) [ not reproducible ] * * CURRENT TODO - * o drum controllers + * o write instrument drummaps + * o GUI for editing instrument drummaps + * * drum controllers * update ctrlcanvas/panel * test! * * drum editor is buggy. propagate_drum_map may operate on old values diff --git a/muse2/muse/xml.cpp b/muse2/muse/xml.cpp index 45bed368..1a989366 100644 --- a/muse2/muse/xml.cpp +++ b/muse2/muse/xml.cpp @@ -225,7 +225,7 @@ Xml::Token Xml::parse() bool endFlag = false; nextc(); if (c == EOF) { - printf("unexpected EOF reading *.med file at level %d, line %d, <%s><%s><%s>\n", + printf("unexpected EOF reading xml file at level %d, line %d, <%s><%s><%s>\n", level, _line, _tag.toLatin1().constData(), _s1.toLatin1().constData(), _s2.toLatin1().constData()); return level == 0 ? End : Error; } diff --git a/muse2/share/instruments/gs.idf b/muse2/share/instruments/gs.idf index 1e8a54c0..9314e282 100644 --- a/muse2/share/instruments/gs.idf +++ b/muse2/share/instruments/gs.idf @@ -580,6 +580,6 @@ <entry pitch="108"> <name>Bubble</name> </entry> </drummap> </entry> - + </Drummaps> </MidiInstrument> </muse> -- cgit v1.2.3 From 952e6deeb8eae2e72fa12054699c7740e4d7eea1 Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Mon, 2 Jan 2012 21:26:08 +0000 Subject: added drummap page to instrument editor adapted dlist to be reusable added dtor to patch_drummap_mapping_t changed affected_patches from list to single entry TODO: maybe move dlist and stuff out of midiedit still TODO: offer a way to re-tie drumlist-ordering to the instrument --- muse2/muse/helper.cpp | 2 +- muse2/muse/instruments/editinstrument.cpp | 399 +++++++++++++++++- muse2/muse/instruments/editinstrument.h | 27 +- muse2/muse/instruments/editinstrumentbase.ui | 592 ++++++++++++++++++++++++++- muse2/muse/instruments/minstrument.cpp | 147 +++++-- muse2/muse/instruments/minstrument.h | 18 +- muse2/muse/midiedit/dlist.cpp | 76 +++- muse2/muse/midiedit/dlist.h | 5 +- 8 files changed, 1200 insertions(+), 66 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/helper.cpp b/muse2/muse/helper.cpp index 7d07a6ce..ce96d6fe 100644 --- a/muse2/muse/helper.cpp +++ b/muse2/muse/helper.cpp @@ -250,7 +250,7 @@ void write_new_style_drummap(int level, Xml& xml, const char* tagname, // channel and port are ignored as well, as they're not used // in new-style-drum-mode - xml.tag(level--, "/entry"); + xml.tag(--level, "/entry"); } } diff --git a/muse2/muse/instruments/editinstrument.cpp b/muse2/muse/instruments/editinstrument.cpp index b90b872e..8a8b4be0 100644 --- a/muse2/muse/instruments/editinstrument.cpp +++ b/muse2/muse/instruments/editinstrument.cpp @@ -32,6 +32,9 @@ #include <QMessageBox> #include <QLineEdit> #include <QWhatsThis> +#include <QStringListModel> +#include <QScrollBar> +#include <list> #include "editinstrument.h" #include "minstrument.h" @@ -42,10 +45,15 @@ #include "gconfig.h" #include "icons.h" +#include "dlist.h" +#include "drummap.h" +#include "header.h" +#include "drumedit.h" // FINDMICHJETZT only needed for COL_FOO. fix that! + namespace MusEGui { enum { - COL_NAME = 0, COL_TYPE, + COL_CNAME = 0, COL_TYPE, COL_HNUM, COL_LNUM, COL_MIN, COL_MAX, COL_DEF }; @@ -72,10 +80,10 @@ EditInstrument::EditInstrument(QWidget* parent, Qt::WFlags fl) // populate instrument list // Populate common controller list. for(int i = 0; i < 128; ++i) - { - QListWidgetItem *lci = new QListWidgetItem(MusECore::midiCtrlName(i)); - listController->addItem(lci); - } + { + QListWidgetItem *lci = new QListWidgetItem(MusECore::midiCtrlName(i)); + listController->addItem(lci); + } oldMidiInstrument = 0; oldPatchItem = 0; for (MusECore::iMidiInstrument i = MusECore::midiInstruments.begin(); i != MusECore::midiInstruments.end(); ++i) { @@ -105,8 +113,66 @@ EditInstrument::EditInstrument(QWidget* parent, Qt::WFlags fl) // workingInstrument.assign( *wip ); + dlist_header = new Header(dlistContainer, "header"); + dlist_header->setFixedHeight(31); + dlist_header->setColumnLabel(tr("Name"), COL_NAME, 120); + dlist_header->setColumnLabel(tr("Vol"), COL_VOLUME); + dlist_header->setColumnLabel(tr("Quant"), COL_QUANT, 30); + dlist_header->setColumnLabel(tr("E-Note"), COL_INPUTTRIGGER, 50); + dlist_header->setColumnLabel(tr("Len"), COL_NOTELENGTH); + dlist_header->setColumnLabel(tr("A-Note"), COL_NOTE, 50); + dlist_header->setColumnLabel(tr("LV1"), COL_LEVEL1); + dlist_header->setColumnLabel(tr("LV2"), COL_LEVEL2); + dlist_header->setColumnLabel(tr("LV3"), COL_LEVEL3); + dlist_header->setColumnLabel(tr("LV4"), COL_LEVEL4); + dlist_header->hideSection(COL_OUTPORT); + dlist_header->hideSection(COL_OUTCHANNEL); + dlist_header->hideSection(COL_HIDE); + dlist_header->hideSection(COL_MUTE); + dlist_header->hide(); + + + connect(patchFromBox, SIGNAL(valueChanged(int)), this, SLOT(patchCollectionSpinboxChanged(int))); + connect(patchToBox, SIGNAL(valueChanged(int)), this, SLOT(patchCollectionSpinboxChanged(int))); + connect(lbankFromBox, SIGNAL(valueChanged(int)), this, SLOT(patchCollectionSpinboxChanged(int))); + connect(lbankToBox, SIGNAL(valueChanged(int)), this, SLOT(patchCollectionSpinboxChanged(int))); + connect(hbankFromBox, SIGNAL(valueChanged(int)), this, SLOT(patchCollectionSpinboxChanged(int))); + connect(hbankToBox, SIGNAL(valueChanged(int)), this, SLOT(patchCollectionSpinboxChanged(int))); + connect(patchCheckbox, SIGNAL(toggled(bool)), this, SLOT(patchCollectionCheckboxChanged(bool))); + connect(lbankCheckbox, SIGNAL(toggled(bool)), this, SLOT(patchCollectionCheckboxChanged(bool))); + connect(hbankCheckbox, SIGNAL(toggled(bool)), this, SLOT(patchCollectionCheckboxChanged(bool))); + + connect(addCollBtn, SIGNAL(clicked()), this, SLOT(addPatchCollection())); + connect(rmCollBtn, SIGNAL(clicked()), this, SLOT(delPatchCollection())); + connect(copyCollBtn, SIGNAL(clicked()), this, SLOT(copyPatchCollection())); + connect(collUpBtn, SIGNAL(clicked()), this, SLOT(patchCollectionUp())); + connect(collDownBtn, SIGNAL(clicked()), this, SLOT(patchCollectionDown())); + + connect(patchCollections, SIGNAL(activated(const QModelIndex&)), this, SLOT(patchActivated(const QModelIndex&))); + connect(patchCollections, SIGNAL(clicked (const QModelIndex&)), this, SLOT(patchActivated(const QModelIndex&))); + + patch_coll_model=new QStringListModel(); + patchCollections->setModel(patch_coll_model); + patchCollections->setEditTriggers(QAbstractItemView::NoEditTriggers); + connect(instrumentList, SIGNAL(itemSelectionChanged()), SLOT(instrumentChanged())); connect(patchView, SIGNAL(itemSelectionChanged()), SLOT(patchChanged())); + + dlist_vscroll = new QScrollBar(Qt::Vertical, this); + dlist_vscroll->setMaximum(128*TH); + dlist_vscroll->hide(); + + dlist_grid = new QGridLayout(dlistContainer); + dlist_grid->setContentsMargins(0, 0, 0, 0); + dlist_grid->setSpacing(0); + dlist_grid->setRowStretch(1, 100); + dlist_grid->setColumnStretch(0, 100); + dlist_grid->addWidget(dlist_header, 0, 0); + dlist_grid->addWidget(dlist_vscroll, 1,1); + + dlist=NULL; + + //instrumentChanged(); changeInstrument(); @@ -151,6 +217,306 @@ EditInstrument::EditInstrument(QWidget* parent, Qt::WFlags fl) //connect(newSysex, SIGNAL(clicked()), SLOT(newSysexClicked())); } + +void EditInstrument::patchCollectionSpinboxChanged(int) +{ + if (patchFromBox->value() > patchToBox->value()) + patchToBox->setValue(patchFromBox->value()); + + if (lbankFromBox->value() > lbankToBox->value()) + lbankToBox->setValue(lbankFromBox->value()); + + if (hbankFromBox->value() > hbankToBox->value()) + hbankToBox->setValue(hbankFromBox->value()); + + storePatchCollection(); +} + +void EditInstrument::patchCollectionCheckboxChanged(bool) +{ + storePatchCollection(); +} + +void EditInstrument::storePatchCollection() +{ + using MusECore::patch_drummap_mapping_t; + + int idx=patchCollections->currentIndex().row(); + std::list<patch_drummap_mapping_t>* pdm = workingInstrument.get_patch_drummap_mapping(); + if (idx>=0 && (unsigned)idx<pdm->size()) + { + std::list<patch_drummap_mapping_t>::iterator it=pdm->begin(); + advance(it,idx); + + if (patchCheckbox->isChecked()) + { + it->affected_patches.first_program=patchFromBox->value()-1; + it->affected_patches.last_program=patchToBox->value()-1; + } + else + { + it->affected_patches.first_program=0; + it->affected_patches.last_program=127; + } + + if (lbankCheckbox->isChecked()) + { + it->affected_patches.first_lbank=lbankFromBox->value()-1; + it->affected_patches.last_lbank=lbankToBox->value()-1; + } + else + { + it->affected_patches.first_lbank=0; + it->affected_patches.last_lbank=127; + } + + if (hbankCheckbox->isChecked()) + { + it->affected_patches.first_hbank=hbankFromBox->value()-1; + it->affected_patches.last_hbank=hbankToBox->value()-1; + } + else + { + it->affected_patches.first_hbank=0; + it->affected_patches.last_hbank=127; + } + + workingInstrument.setDirty(true); + repopulatePatchCollections(); + } +} + +void EditInstrument::fetchPatchCollection() +{ + using MusECore::patch_drummap_mapping_t; + + int idx=patchCollections->currentIndex().row(); + std::list<patch_drummap_mapping_t>* pdm = workingInstrument.get_patch_drummap_mapping(); + if (idx>=0 && (unsigned)idx<pdm->size()) + { + std::list<patch_drummap_mapping_t>::iterator it=pdm->begin(); + advance(it,idx); + + patchFromBox->blockSignals(true); + patchToBox->blockSignals(true); + lbankFromBox->blockSignals(true); + lbankToBox->blockSignals(true); + hbankFromBox->blockSignals(true); + hbankToBox->blockSignals(true); + + patchFromBox->setValue(it->affected_patches.first_program+1); + patchToBox->setValue(it->affected_patches.last_program+1); + + lbankFromBox->setValue(it->affected_patches.first_lbank+1); + lbankToBox->setValue(it->affected_patches.last_lbank+1); + + hbankFromBox->setValue(it->affected_patches.first_hbank+1); + hbankToBox->setValue(it->affected_patches.last_hbank+1); + + patchFromBox->blockSignals(false); + patchToBox->blockSignals(false); + lbankFromBox->blockSignals(false); + lbankToBox->blockSignals(false); + hbankFromBox->blockSignals(false); + hbankToBox->blockSignals(false); + + + patchCheckbox->setChecked(it->affected_patches.first_program>0 || it->affected_patches.last_program < 127); + lbankCheckbox->setChecked(it->affected_patches.first_lbank>0 || it->affected_patches.last_lbank < 127); + hbankCheckbox->setChecked(it->affected_patches.first_hbank>0 || it->affected_patches.last_hbank < 127); + } +} + +void EditInstrument::patchActivated(const QModelIndex& idx) +{ + using MusECore::patch_drummap_mapping_t; + + if (idx.row()>=0) + { + using MusECore::DrumMap; + + std::list<patch_drummap_mapping_t>* tmp = workingInstrument.get_patch_drummap_mapping(); + std::list<patch_drummap_mapping_t>::iterator it=tmp->begin(); + if ((unsigned)idx.row()>=tmp->size()) + printf("THIS SHOULD NEVER HAPPEN: idx.row()>=tmp->size() in EditInstrument::patchActivated()\n"); + + advance(it, idx.row()); + DrumMap* dm=it->drummap; + + + if (dlist) + { + dlist->hide(); + delete dlist; + dlist=NULL; + } + + dlist=new DList(dlist_header,dlistContainer,1,dm); + + dlist->setYPos(dlist_vscroll->value()); + + connect(dlist_vscroll, SIGNAL(valueChanged(int)), dlist, SLOT(setYPos(int))); + dlist_grid->addWidget(dlist, 1, 0); + + + dlist_header->show(); + dlist->show(); + dlist_vscroll->show(); + + collUpBtn->setEnabled(idx.row()>0); + collDownBtn->setEnabled(idx.row()<patch_coll_model->rowCount()-1); + rmCollBtn->setEnabled(true); + copyCollBtn->setEnabled(true); + patchCollectionContainer->setEnabled(true); + + fetchPatchCollection(); + } +} + +void EditInstrument::addPatchCollection() +{ + using MusECore::patch_drummap_mapping_t; + + int idx=patchCollections->currentIndex().row(); + + std::list<patch_drummap_mapping_t>* tmp = workingInstrument.get_patch_drummap_mapping(); + std::list<patch_drummap_mapping_t>::iterator it=tmp->begin(); + advance(it,idx+1); + tmp->insert(it,patch_drummap_mapping_t()); + + repopulatePatchCollections(); + patchCollections->setCurrentIndex(patch_coll_model->index(idx+1)); + patchActivated(patchCollections->currentIndex()); + + workingInstrument.setDirty(true); +} + +void EditInstrument::delPatchCollection() +{ + using MusECore::patch_drummap_mapping_t; + + int idx=patchCollections->currentIndex().row(); + if (idx>=0) + { + if (dlist) + { + dlist->hide(); + delete dlist; + dlist=NULL; + } + + dlist_header->hide(); + dlist_vscroll->hide(); + + rmCollBtn->setEnabled(false); + copyCollBtn->setEnabled(false); + patchCollectionContainer->setEnabled(false); + collUpBtn->setEnabled(false); + collDownBtn->setEnabled(false); + + std::list<patch_drummap_mapping_t>* tmp = workingInstrument.get_patch_drummap_mapping(); + std::list<patch_drummap_mapping_t>::iterator it=tmp->begin(); + advance(it,idx); + tmp->erase(it); + + repopulatePatchCollections(); + + patchActivated(patchCollections->currentIndex()); + workingInstrument.setDirty(true); + } +} + +void EditInstrument::copyPatchCollection() +{ + using MusECore::patch_drummap_mapping_t; + + int idx=patchCollections->currentIndex().row(); + + std::list<patch_drummap_mapping_t>* tmp = workingInstrument.get_patch_drummap_mapping(); + std::list<patch_drummap_mapping_t>::iterator it=tmp->begin(); + advance(it,idx); + patch_drummap_mapping_t tmp2(*it); + it++; + tmp->insert(it,tmp2); + + patch_coll_model->insertRow(idx+1); + patch_coll_model->setData(patch_coll_model->index(idx+1), patch_coll_model->index(idx).data()); + patchCollections->setCurrentIndex(patch_coll_model->index(idx+1)); + patchActivated(patchCollections->currentIndex()); + workingInstrument.setDirty(true); +} + +void EditInstrument::patchCollectionUp() +{ + using MusECore::patch_drummap_mapping_t; + + std::list<patch_drummap_mapping_t>* pdm = workingInstrument.get_patch_drummap_mapping(); + int idx=patchCollections->currentIndex().row(); + + if (idx>=1) + { + std::list<patch_drummap_mapping_t>::iterator it=pdm->begin(); + advance(it,idx-1); + std::list<patch_drummap_mapping_t>::iterator it2=it; + it2++; + + //it2 is the element to move, it is the element to put before. + + pdm->insert(it,*it2); + pdm->erase(it2); + + repopulatePatchCollections(); + + patchCollections->setCurrentIndex(patch_coll_model->index(idx-1)); + patchActivated(patchCollections->currentIndex()); + + workingInstrument.setDirty(true); + } +} + +void EditInstrument::patchCollectionDown() +{ + using MusECore::patch_drummap_mapping_t; + + std::list<patch_drummap_mapping_t>* pdm = workingInstrument.get_patch_drummap_mapping(); + int idx=patchCollections->currentIndex().row(); + + if ((unsigned)idx<pdm->size()-1) + { + std::list<patch_drummap_mapping_t>::iterator it=pdm->begin(); + advance(it,idx); + std::list<patch_drummap_mapping_t>::iterator it2=it; + it2++; it2++; + + //it is the element to move, it2 is the element to put before (might be end()) + + pdm->insert(it2,*it); + pdm->erase(it); + + repopulatePatchCollections(); + + patchCollections->setCurrentIndex(patch_coll_model->index(idx+1)); + patchActivated(patchCollections->currentIndex()); + + workingInstrument.setDirty(true); + } +} + +void EditInstrument::repopulatePatchCollections() +{ + using MusECore::patch_drummap_mapping_t; + + int idx=patchCollections->currentIndex().row(); + QStringList strlist; + + std::list<patch_drummap_mapping_t>* pdm = workingInstrument.get_patch_drummap_mapping(); + for (std::list<patch_drummap_mapping_t>::iterator it=pdm->begin(); it!=pdm->end(); it++) + strlist << it->affected_patches.to_string(); + + patch_coll_model->setStringList(strlist); + patchCollections->setCurrentIndex(patch_coll_model->index(idx)); +} + //--------------------------------------------------------- // helpWhatsThis //--------------------------------------------------------- @@ -1014,6 +1380,25 @@ void EditInstrument::changeInstrument() */ + + repopulatePatchCollections(); + if (dlist) + { + dlist->hide(); + delete dlist; + dlist=NULL; + } + + dlist_header->hide(); + dlist_vscroll->hide(); + + rmCollBtn->setEnabled(false); + copyCollBtn->setEnabled(false); + patchCollectionContainer->setEnabled(false); + collUpBtn->setEnabled(false); + collDownBtn->setEnabled(false); + + } //--------------------------------------------------------- @@ -1801,9 +2186,9 @@ void EditInstrument::ctrlNameReturn() } c->setName(ctrlName->text()); - item->setText(COL_NAME, ctrlName->text()); + item->setText(COL_CNAME, ctrlName->text()); //c->setName(s); - //item->setText(COL_NAME, s); + //item->setText(COL_CNAME, s); workingInstrument.setDirty(true); } diff --git a/muse2/muse/instruments/editinstrument.h b/muse2/muse/instruments/editinstrument.h index ba53aae1..ab5edf39 100644 --- a/muse2/muse/instruments/editinstrument.h +++ b/muse2/muse/instruments/editinstrument.h @@ -31,9 +31,14 @@ class QDialog; class QMenu; class QCloseEvent; +class QGridLayout; +class QStringListModel; namespace MusEGui { +class Header; +class DList; + //--------------------------------------------------------- // EditInstrument //--------------------------------------------------------- @@ -44,6 +49,15 @@ class EditInstrument : public QMainWindow, public Ui::EditInstrumentBase { MusECore::MidiInstrument workingInstrument; QListWidgetItem* oldMidiInstrument; QTreeWidgetItem* oldPatchItem; + + Header* dlist_header; + DList* dlist; + QScrollBar* dlist_vscroll; + QGridLayout* dlist_grid; + QStringListModel* patch_coll_model; + + + void closeEvent(QCloseEvent*); int checkDirty(MusECore::MidiInstrument*, bool isClose = false); bool fileSave(MusECore::MidiInstrument*, const QString&); @@ -61,7 +75,6 @@ class EditInstrument : public QMainWindow, public Ui::EditInstrumentBase { void setDefaultPatchControls(int); QString getPatchName(int); void deleteInstrument(QListWidgetItem*); - ///QMenu* patchpopup; private slots: virtual void fileNew(); @@ -99,6 +112,18 @@ class EditInstrument : public QMainWindow, public Ui::EditInstrumentBase { //void newSysexClicked(); void ctrlNullParamHChanged(int); void ctrlNullParamLChanged(int); + + void patchCollectionSpinboxChanged(int); + void patchCollectionCheckboxChanged(bool); + void patchActivated(const QModelIndex&); + void addPatchCollection(); + void delPatchCollection(); + void copyPatchCollection(); + void patchCollectionUp(); + void patchCollectionDown(); + void repopulatePatchCollections(); + void storePatchCollection(); + void fetchPatchCollection(); public: EditInstrument(QWidget* parent = 0, Qt::WFlags fl = Qt::Window); diff --git a/muse2/muse/instruments/editinstrumentbase.ui b/muse2/muse/instruments/editinstrumentbase.ui index 3337cfc0..5295abb2 100644 --- a/muse2/muse/instruments/editinstrumentbase.ui +++ b/muse2/muse/instruments/editinstrumentbase.ui @@ -1370,6 +1370,404 @@ Typically, set to 127/127, or an unused </item> </layout> </widget> + <widget class="QWidget" name="drumTab"> + <attribute name="title"> + <string>Drummaps</string> + </attribute> + <layout class="QHBoxLayout" name="horizontalLayout_4"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QLabel" name="label"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Patch Collections:</string> + </property> + </widget> + </item> + <item> + <widget class="QListView" name="patchCollections"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout"> + <property name="spacing"> + <number>0</number> + </property> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QPushButton" name="addCollBtn"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>&Add</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="copyCollBtn"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>&Copy</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="rmCollBtn"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>&Remove</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QPushButton" name="collUpBtn"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>&Up</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="collDownBtn"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>&Down</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </item> + <item> + <widget class="QWidget" name="patchCollectionContainer" native="true"> + <property name="enabled"> + <bool>false</bool> + </property> + <layout class="QGridLayout" name="gridLayout_"> + <property name="margin"> + <number>0</number> + </property> + <item row="0" column="0"> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="0" column="0"> + <widget class="QCheckBox" name="patchCheckbox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Patch:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLabel" name="label_5"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>from</string> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QSpinBox" name="patchFromBox"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>128</number> + </property> + </widget> + </item> + <item row="0" column="3"> + <widget class="QLabel" name="label_8"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>to</string> + </property> + </widget> + </item> + <item row="0" column="4"> + <widget class="QSpinBox" name="patchToBox"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>128</number> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QCheckBox" name="hbankCheckbox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Bank Hi:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLabel" name="label_6"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>from</string> + </property> + </widget> + </item> + <item row="1" column="2"> + <widget class="QSpinBox" name="hbankFromBox"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>128</number> + </property> + </widget> + </item> + <item row="1" column="3"> + <widget class="QLabel" name="label_9"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>to</string> + </property> + </widget> + </item> + <item row="1" column="4"> + <widget class="QSpinBox" name="hbankToBox"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>128</number> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QCheckBox" name="lbankCheckbox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Bank Lo:</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QLabel" name="label_7"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>from</string> + </property> + </widget> + </item> + <item row="2" column="2"> + <widget class="QSpinBox" name="lbankFromBox"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>128</number> + </property> + </widget> + </item> + <item row="2" column="3"> + <widget class="QLabel" name="label_10"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>to</string> + </property> + </widget> + </item> + <item row="2" column="4"> + <widget class="QSpinBox" name="lbankToBox"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>128</number> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QWidget" name="dlistContainer" native="true"/> + </item> + </layout> + </item> + </layout> + </widget> </widget> </widget> </item> @@ -1396,7 +1794,7 @@ Typically, set to 127/127, or an unused <x>0</x> <y>0</y> <width>802</width> - <height>21</height> + <height>25</height> </rect> </property> <property name="defaultUp"> @@ -1645,5 +2043,197 @@ Typically, set to 127/127, or an unused </hint> </hints> </connection> + <connection> + <sender>patchCheckbox</sender> + <signal>toggled(bool)</signal> + <receiver>label_5</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>214</x> + <y>411</y> + </hint> + <hint type="destinationlabel"> + <x>289</x> + <y>412</y> + </hint> + </hints> + </connection> + <connection> + <sender>patchCheckbox</sender> + <signal>toggled(bool)</signal> + <receiver>patchFromBox</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>214</x> + <y>411</y> + </hint> + <hint type="destinationlabel"> + <x>343</x> + <y>412</y> + </hint> + </hints> + </connection> + <connection> + <sender>patchCheckbox</sender> + <signal>toggled(bool)</signal> + <receiver>label_8</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>214</x> + <y>411</y> + </hint> + <hint type="destinationlabel"> + <x>390</x> + <y>412</y> + </hint> + </hints> + </connection> + <connection> + <sender>patchCheckbox</sender> + <signal>toggled(bool)</signal> + <receiver>patchToBox</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>214</x> + <y>411</y> + </hint> + <hint type="destinationlabel"> + <x>436</x> + <y>412</y> + </hint> + </hints> + </connection> + <connection> + <sender>lbankCheckbox</sender> + <signal>toggled(bool)</signal> + <receiver>lbankFromBox</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>221</x> + <y>469</y> + </hint> + <hint type="destinationlabel"> + <x>343</x> + <y>470</y> + </hint> + </hints> + </connection> + <connection> + <sender>lbankCheckbox</sender> + <signal>toggled(bool)</signal> + <receiver>lbankToBox</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>221</x> + <y>469</y> + </hint> + <hint type="destinationlabel"> + <x>436</x> + <y>470</y> + </hint> + </hints> + </connection> + <connection> + <sender>lbankCheckbox</sender> + <signal>toggled(bool)</signal> + <receiver>label_7</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>221</x> + <y>469</y> + </hint> + <hint type="destinationlabel"> + <x>289</x> + <y>470</y> + </hint> + </hints> + </connection> + <connection> + <sender>lbankCheckbox</sender> + <signal>toggled(bool)</signal> + <receiver>label_10</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>221</x> + <y>469</y> + </hint> + <hint type="destinationlabel"> + <x>390</x> + <y>470</y> + </hint> + </hints> + </connection> + <connection> + <sender>hbankCheckbox</sender> + <signal>toggled(bool)</signal> + <receiver>hbankFromBox</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>220</x> + <y>440</y> + </hint> + <hint type="destinationlabel"> + <x>343</x> + <y>441</y> + </hint> + </hints> + </connection> + <connection> + <sender>hbankCheckbox</sender> + <signal>toggled(bool)</signal> + <receiver>hbankToBox</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>220</x> + <y>440</y> + </hint> + <hint type="destinationlabel"> + <x>436</x> + <y>441</y> + </hint> + </hints> + </connection> + <connection> + <sender>hbankCheckbox</sender> + <signal>toggled(bool)</signal> + <receiver>label_6</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>220</x> + <y>440</y> + </hint> + <hint type="destinationlabel"> + <x>289</x> + <y>441</y> + </hint> + </hints> + </connection> + <connection> + <sender>hbankCheckbox</sender> + <signal>toggled(bool)</signal> + <receiver>label_9</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>220</x> + <y>440</y> + </hint> + <hint type="destinationlabel"> + <x>390</x> + <y>441</y> + </hint> + </hints> + </connection> </connections> </ui> diff --git a/muse2/muse/instruments/minstrument.cpp b/muse2/muse/instruments/minstrument.cpp index 3906c399..bd4b3bd4 100644 --- a/muse2/muse/instruments/minstrument.cpp +++ b/muse2/muse/instruments/minstrument.cpp @@ -410,17 +410,9 @@ MidiInstrument::~MidiInstrument() if (_initScript) delete _initScript; - clear_delete_patch_drummap_mapping(); + patch_drummap_mapping.clear(); } -void MidiInstrument::clear_delete_patch_drummap_mapping() -{ - for (std::list<patch_drummap_mapping_t>::iterator it = patch_drummap_mapping.begin(); - it!=patch_drummap_mapping.end(); it++) - delete[] it->drummap; - - patch_drummap_mapping.clear(); -} /* @@ -529,16 +521,7 @@ MidiInstrument& MidiInstrument::assign(const MidiInstrument& ins) _name = ins._name; _filePath = ins._filePath; - clear_delete_patch_drummap_mapping(); - // do a deep copy - for (std::list<patch_drummap_mapping_t>::const_iterator it = ins.patch_drummap_mapping.begin(); - it!=ins.patch_drummap_mapping.end(); it++) - { - patch_drummap_mapping_t temp = *it; - temp.drummap=new DrumMap[128]; - for (int i=0;i<128;i++) - temp.drummap[i]=it->drummap[i]; - } + patch_drummap_mapping=ins.patch_drummap_mapping; @@ -761,7 +744,7 @@ void MidiInstrument::readMidiState(Xml& xml) void MidiInstrument::readDrummaps(Xml& xml) { - clear_delete_patch_drummap_mapping(); + patch_drummap_mapping.clear(); for (;;) { @@ -796,7 +779,7 @@ patch_drummap_mapping_t MidiInstrument::readDrummapsEntry(Xml& xml) { using std::list; - list<patch_collection_t> collection; + patch_collection_t collection; DrumMap* drummap=new DrumMap[128]; for (int i=0;i<128;i++) drummap[i]=iNewDrumMap[i]; @@ -813,7 +796,7 @@ patch_drummap_mapping_t MidiInstrument::readDrummapsEntry(Xml& xml) case Xml::TagStart: if (tag == "patch_collection") - collection.push_back(readDrummapsEntryPatchCollection(xml)); + collection=readDrummapsEntryPatchCollection(xml); else if (tag == "drummap") read_new_style_drummap(xml, "drummap", drummap); else @@ -875,6 +858,43 @@ patch_collection_t MidiInstrument::readDrummapsEntryPatchCollection(Xml& xml) " not returning anything. expect undefined behaviour or even crashes.\n"); } +void MidiInstrument::writeDrummaps(int level, Xml& xml) const +{ + xml.tag(level++, "Drummaps"); + + for (std::list<patch_drummap_mapping_t>::const_iterator it=patch_drummap_mapping.begin(); + it!=patch_drummap_mapping.end(); it++) + { + xml.tag(level++, "entry"); + + const patch_collection_t* ap = &it->affected_patches; + QString tmp="<patch_collection "; + if (ap->first_program==ap->last_program) + tmp+="prog=\""+QString::number(ap->first_program)+"\" "; + else if (! (ap->first_program==0 && ap->last_program>=127)) + tmp+="prog=\""+QString::number(ap->first_program)+"-"+QString::number(ap->last_program)+"\" "; + + if (ap->first_lbank==ap->last_lbank) + tmp+="lbank=\""+QString::number(ap->first_lbank)+"\" "; + else if (! (ap->first_lbank==0 && ap->last_lbank>=127)) + tmp+="lbank=\""+QString::number(ap->first_lbank)+"-"+QString::number(ap->last_lbank)+"\" "; + + if (ap->first_hbank==ap->last_hbank) + tmp+="hbank=\""+QString::number(ap->first_hbank)+"\" "; + else if (! (ap->first_hbank==0 && ap->last_hbank>=127)) + tmp+="hbank=\""+QString::number(ap->first_hbank)+"-"+QString::number(ap->last_hbank)+"\" "; + + tmp+="/>\n"; + + xml.nput(level, tmp.toAscii().data()); + + write_new_style_drummap(level, xml, "drummap", it->drummap); + + xml.etag(--level, "entry"); + } + + xml.etag(--level, "Drummaps"); +} //--------------------------------------------------------- // read @@ -1018,6 +1038,9 @@ void MidiInstrument::write(int level, Xml& xml) //(*ic)->write(xml); ic->second->write(level, xml); //xml.etag("MidiInstrument"); + + writeDrummaps(level, xml); + level--; xml.etag(level, "MidiInstrument"); //xml.etag("muse"); @@ -1136,16 +1159,13 @@ const DrumMap* MidiInstrument::drummap_for_patch(int patch) const for (list<patch_drummap_mapping_t>::const_iterator it=patch_drummap_mapping.begin(); it!=patch_drummap_mapping.end(); it++) { - for (list<patch_collection_t>::const_iterator it2=it->affected_patches.begin(); - it2!=it->affected_patches.end(); it2++) + const patch_collection_t* ap = &it->affected_patches; + // if the entry matches our patch + if ( (program >= ap->first_program && program <= ap->last_program) && + (hbank >= ap->first_hbank && hbank <= ap->last_hbank) && + (lbank >= ap->first_lbank && lbank <= ap->last_lbank) ) { - // if the entry matches our patch - if ( (program >= it2->first_program && program <= it2->last_program) && - (hbank >= it2->first_hbank && hbank <= it2->last_hbank) && - (lbank >= it2->first_lbank && lbank <= it2->last_lbank) ) - { - return it->drummap; - } + return it->drummap; } } @@ -1160,5 +1180,70 @@ patch_drummap_mapping_t::patch_drummap_mapping_t() drummap[i]=iNewDrumMap[i]; } +patch_drummap_mapping_t::patch_drummap_mapping_t(const patch_drummap_mapping_t& that) +{ + drummap=new DrumMap[128]; + for (int i=0;i<128;i++) + drummap[i]=that.drummap[i]; + + affected_patches=that.affected_patches; +} + +patch_drummap_mapping_t& patch_drummap_mapping_t::operator=(const patch_drummap_mapping_t& that) +{ + if (drummap) + delete [] drummap; + + drummap=new DrumMap[128]; + for (int i=0;i<128;i++) + drummap[i]=that.drummap[i]; + + affected_patches=that.affected_patches; + + return *this; +} + +patch_drummap_mapping_t::~patch_drummap_mapping_t() +{ + delete [] drummap; +} + +QString patch_collection_t::to_string() +{ + QString tmp; + + if (first_program==0 && last_program>=127 && + first_lbank==0 && last_lbank>=127 && + first_hbank==0 && last_hbank>=127) + tmp="default"; + else + { + tmp+="prog: "; + if (first_program==last_program) + tmp+=QString::number(first_program+1); + else if (! (first_program==0 && last_program>=127)) + tmp+=QString::number(first_program+1)+"-"+QString::number(last_program+1); + else + tmp+="*"; + + tmp+=" bank="; + if (first_lbank==last_lbank) + tmp+=QString::number(first_lbank+1); + else if (! (first_lbank==0 && last_lbank>=127)) + tmp+=QString::number(first_lbank+1)+"-"+QString::number(last_lbank+1); + else + tmp+="*"; + + tmp+="/"; + if (first_hbank==last_hbank) + tmp+=QString::number(first_hbank+1); + else if (! (first_hbank==0 && last_hbank>=127)) + tmp+=QString::number(first_hbank+1)+"-"+QString::number(last_hbank+1); + else + tmp+="*"; + + } + return tmp; +} } // namespace MusECore diff --git a/muse2/muse/instruments/minstrument.h b/muse2/muse/instruments/minstrument.h index 9a65598b..f793a7b6 100644 --- a/muse2/muse/instruments/minstrument.h +++ b/muse2/muse/instruments/minstrument.h @@ -27,8 +27,7 @@ #include "globaldefs.h" #include <list> #include <vector> - -class QString; +#include <QString> namespace MusEGui { class PopupMenu; @@ -101,21 +100,26 @@ struct patch_collection_t first_hbank=h1; last_hbank=h2; } - + + QString to_string(); }; struct patch_drummap_mapping_t { - std::list<patch_collection_t> affected_patches; + patch_collection_t affected_patches; DrumMap* drummap; - patch_drummap_mapping_t(const std::list<patch_collection_t>& a, DrumMap* d) + patch_drummap_mapping_t(const patch_collection_t& a, DrumMap* d) { affected_patches=a; drummap=d; } + patch_drummap_mapping_t(const patch_drummap_mapping_t& that); patch_drummap_mapping_t(); + ~patch_drummap_mapping_t(); + + patch_drummap_mapping_t& operator=(const patch_drummap_mapping_t& that); }; //--------------------------------------------------------- @@ -143,8 +147,7 @@ class MidiInstrument { QString _name; QString _filePath; - void clear_delete_patch_drummap_mapping(); - + void writeDrummaps(int level, Xml& xml) const; void readDrummaps(Xml& xml); patch_drummap_mapping_t readDrummapsEntry(Xml& xml); patch_collection_t readDrummapsEntryPatchCollection(Xml& xml); @@ -195,6 +198,7 @@ class MidiInstrument { void write(int level, Xml&); PatchGroupList* groups() { return &pg; } + std::list<patch_drummap_mapping_t>* get_patch_drummap_mapping() { return &patch_drummap_mapping; } }; //--------------------------------------------------------- diff --git a/muse2/muse/midiedit/dlist.cpp b/muse2/muse/midiedit/dlist.cpp index fc6384f7..ad0d05dd 100644 --- a/muse2/muse/midiedit/dlist.cpp +++ b/muse2/muse/midiedit/dlist.cpp @@ -395,6 +395,8 @@ void DList::viewMousePressEvent(QMouseEvent* ev) } else { + if (dcanvas) + { //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 (QSet<MusECore::Track*>::iterator it = dcanvas->get_instrument_map()[instrument].tracks.begin(); it!=dcanvas->get_instrument_map()[instrument].tracks.end(); it++) @@ -408,6 +410,16 @@ void DList::viewMousePressEvent(QMouseEvent* ev) // does this for us. // updating ourDrumMap is unneccessary because the song->update(SC_DRUMMAP) // does this for us. + } + else + { + for (int i=0;i<128;i++) + if (ourDrumMap[i].enote==val) + { + ourDrumMap[i].enote=dm->enote; + break; + } + } } dm->enote = val; @@ -510,14 +522,14 @@ void DList::viewMousePressEvent(QMouseEvent* ev) if (velo > 127 ) velo = 127; emit keyPressed(instrument, velo); //Mapping done on other side, send index } - else if (button == Qt::MidButton) // hide that instrument + else if (button == Qt::MidButton && dcanvas) // hide that instrument { QSet<MusECore::Track*>* group = &dcanvas->get_instrument_map()[instrument].tracks; int pitch = dcanvas->get_instrument_map()[instrument].pitch; for (QSet<MusECore::Track*>::iterator track=group->begin(); track!=group->end(); track++) dynamic_cast<MusECore::MidiTrack*>(*track)->drummap_hidden()[pitch] = true; } - else if (button == Qt::RightButton) + else if (button == Qt::RightButton && dcanvas) { bool hidden=false; bool shown=false; @@ -555,7 +567,7 @@ void DList::viewMousePressEvent(QMouseEvent* ev) break; } - if (!old_style_drummap_mode && dm_old != *dm) //something changed and we're in new style mode? + if (!old_style_drummap_mode && dm_old != *dm && dcanvas) //something changed and we're in new style mode? dcanvas->propagate_drummap_change(instrument, (dm_old.enote != dm->enote)); MusEGlobal::song->update(SC_DRUMMAP); @@ -834,7 +846,7 @@ void DList::returnPressed() break; } - if (editEntryOld != *editEntry) + if (editEntryOld != *editEntry && dcanvas) dcanvas->propagate_drummap_change(editEntry-ourDrumMap, false); selectedColumn = -1; @@ -895,6 +907,8 @@ void DList::pitchEdited() } else { + if (dcanvas) + { //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 (QSet<MusECore::Track*>::iterator it = dcanvas->get_instrument_map()[instrument].tracks.begin(); it!=dcanvas->get_instrument_map()[instrument].tracks.end(); it++) @@ -908,6 +922,16 @@ void DList::pitchEdited() // does this for us. // updating ourDrumMap is unneccessary because the song->update(SC_DRUMMAP) // does this for us. + } + else + { + for (int i=0;i<128;i++) + if (ourDrumMap[i].enote==val) + { + ourDrumMap[i].enote=editEntry->enote; + break; + } + } } editEntry->enote = val; break; @@ -917,7 +941,7 @@ void DList::pitchEdited() break; } - if (editEntryOld != *editEntry) + if (editEntryOld != *editEntry && dcanvas) dcanvas->propagate_drummap_change(editEntry-ourDrumMap, (editEntryOld.enote!=editEntry->enote)); selectedColumn = -1; @@ -960,19 +984,12 @@ void DList::songChanged(int flags) // DList //--------------------------------------------------------- -DList::DList(QHeaderView* h, QWidget* parent, int ymag, DrumCanvas* dcanvas_, bool oldstyle) - : MusEGui::View(parent, 1, ymag) - { +void DList::init(QHeaderView* h, QWidget* parent) +{ setBg(Qt::white); - - dcanvas=dcanvas_; - ourDrumMap=dcanvas->getOurDrumMap(); - ourDrumMapSize=dcanvas->getOurDrumMapSize(); - old_style_drummap_mode=oldstyle; - connect(dcanvas, SIGNAL(ourDrumMapChanged(bool)), SLOT(ourDrumMapChanged(bool))); - - if (!h){ - h = new QHeaderView(Qt::Horizontal, parent);} + if (!h) + h = new QHeaderView(Qt::Horizontal, parent); + header = h; //ORCAN- CHECK if really needed: header->setTracking(true); connect(header, SIGNAL(sectionResized(int,int,int)), @@ -983,6 +1000,7 @@ DList::DList(QHeaderView* h, QWidget* parent, int ymag, DrumCanvas* dcanvas_, bo editor = 0; pitch_editor = 0; editEntry = 0; + if (ourDrumMapSize!=0) { // always select a drum instrument @@ -994,6 +1012,30 @@ DList::DList(QHeaderView* h, QWidget* parent, int ymag, DrumCanvas* dcanvas_, bo } selectedColumn = -1; + +} + +DList::DList(QHeaderView* h, QWidget* parent, int ymag, DrumCanvas* dcanvas_, bool oldstyle) + : MusEGui::View(parent, 1, ymag) + { + dcanvas=dcanvas_; + ourDrumMap=dcanvas->getOurDrumMap(); + ourDrumMapSize=dcanvas->getOurDrumMapSize(); + old_style_drummap_mode=oldstyle; + connect(dcanvas, SIGNAL(ourDrumMapChanged(bool)), SLOT(ourDrumMapChanged(bool))); + + init(h, parent); + } + +DList::DList(QHeaderView* h, QWidget* parent, int ymag, MusECore::DrumMap* dm, int dmSize) + : MusEGui::View(parent, 1, ymag) + { + dcanvas=NULL; + ourDrumMap=dm; + ourDrumMapSize=dmSize; + old_style_drummap_mode=false; + + init(h, parent); } //--------------------------------------------------------- diff --git a/muse2/muse/midiedit/dlist.h b/muse2/muse/midiedit/dlist.h index 35a67023..cfa10c96 100644 --- a/muse2/muse/midiedit/dlist.h +++ b/muse2/muse/midiedit/dlist.h @@ -120,6 +120,8 @@ class DList : public View { int x2col(int x) const; void devicesPopupMenu(MusECore::DrumMap* t, int x, int y, bool changeAll); + void init(QHeaderView*, QWidget*); + //void setCurDrumInstrument(int n); private slots: @@ -144,7 +146,8 @@ class DList : public View { void lineEdit(int line, int section); void pitchEdit(int line, int section); void setCurDrumInstrument(int n); - DList(QHeaderView*, QWidget* parent, int ymag, MusEGui::DrumCanvas* dcanvas, bool oldstyle); + DList(QHeaderView*, QWidget* parent, int ymag, DrumCanvas* dcanvas, bool oldstyle); + DList(QHeaderView* h, QWidget* parent, int ymag, MusECore::DrumMap* dm, int dmSize=128); ~DList(); int getSelectedInstrument(); -- cgit v1.2.3 From 845d28b2fba8f2c1d4211aee7beb5ab041315531 Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Tue, 3 Jan 2012 17:25:00 +0000 Subject: cleanup --- muse2/muse/instruments/editinstrument.cpp | 1 - muse2/muse/midiedit/dlist.h | 20 ++++++++++++++++++++ muse2/muse/midiedit/drumedit.h | 20 +------------------- 3 files changed, 21 insertions(+), 20 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/instruments/editinstrument.cpp b/muse2/muse/instruments/editinstrument.cpp index 8a8b4be0..ac3ec68f 100644 --- a/muse2/muse/instruments/editinstrument.cpp +++ b/muse2/muse/instruments/editinstrument.cpp @@ -48,7 +48,6 @@ #include "dlist.h" #include "drummap.h" #include "header.h" -#include "drumedit.h" // FINDMICHJETZT only needed for COL_FOO. fix that! namespace MusEGui { diff --git a/muse2/muse/midiedit/dlist.h b/muse2/muse/midiedit/dlist.h index cfa10c96..d864f23e 100644 --- a/muse2/muse/midiedit/dlist.h +++ b/muse2/muse/midiedit/dlist.h @@ -47,6 +47,26 @@ namespace MusEGui { class ScrollScale; class DrumCanvas; + +enum DrumColumn { + COL_HIDE = 0, + COL_MUTE, + COL_NAME, + COL_VOLUME, + COL_QUANT, + COL_INPUTTRIGGER, + COL_NOTELENGTH, + COL_NOTE, + COL_OUTCHANNEL, + COL_OUTPORT, + COL_LEVEL1, + COL_LEVEL2, + COL_LEVEL3, + COL_LEVEL4, + COL_NONE = -1 +}; + + //--------------------------------------------------------- // DLineEdit //--------------------------------------------------------- diff --git a/muse2/muse/midiedit/drumedit.h b/muse2/muse/midiedit/drumedit.h index 5bdd54a8..f4e2646b 100644 --- a/muse2/muse/midiedit/drumedit.h +++ b/muse2/muse/midiedit/drumedit.h @@ -33,7 +33,7 @@ #include "header.h" #include "shortcuts.h" #include "event.h" -#include "dcanvas.h" //FINDMICH UGLY. remove! +#include "dcanvas.h" class QCloseEvent; class QLabel; @@ -65,24 +65,6 @@ class ScrollScale; class Splitter; class Toolbar1; -enum DrumColumn { - COL_HIDE = 0, - COL_MUTE, - COL_NAME, - COL_VOLUME, - COL_QUANT, - COL_INPUTTRIGGER, - COL_NOTELENGTH, - COL_NOTE, - COL_OUTCHANNEL, - COL_OUTPORT, - COL_LEVEL1, - COL_LEVEL2, - COL_LEVEL3, - COL_LEVEL4, - COL_NONE = -1 -}; - //--------------------------------------------------------- // DrumEdit //--------------------------------------------------------- -- cgit v1.2.3 From fb6be39db34e23725ffdd9c8ac3023d672036210 Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Tue, 3 Jan 2012 19:23:06 +0000 Subject: added "reset drummap ordering", changed "reset drummap" from "to GM default" to "to instrument default" (that is, turn tied_to_patch on) --- muse2/muse/arranger/tlist.cpp | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/arranger/tlist.cpp b/muse2/muse/arranger/tlist.cpp index 3b33fc66..3deeb65a 100644 --- a/muse2/muse/arranger/tlist.cpp +++ b/muse2/muse/arranger/tlist.cpp @@ -1576,12 +1576,19 @@ void TList::mousePressEvent(QMouseEvent* ev) if (t->type()==MusECore::Track::NEW_DRUM) { + QAction* tmp; p->addAction(tr("Save track's drumlist"))->setData(1010); p->addAction(tr("Save track's drumlist differences to initial state"))->setData(1011); p->addAction(tr("Load track's drumlist"))->setData(1012); - p->addAction(tr("Reset track's drumlist"))->setData(1013); + tmp=p->addAction(tr("Reset track's drumlist")); + tmp->setData(1013); + tmp->setEnabled(!((MusECore::MidiTrack*)t)->drummap_tied_to_patch()); + tmp=p->addAction(tr("Reset track's drumlist-ordering")); + tmp->setData(1016); + tmp->setEnabled(!((MusECore::MidiTrack*)t)->drummap_ordering_tied_to_patch()); p->addAction(tr("Copy track's drumlist to all selected tracks"))->setData(1014); p->addAction(tr("Copy track's drumlist's differences to all selected tracks"))->setData(1015); + // 1016 is occupied. p->addSeparator(); } @@ -1623,10 +1630,20 @@ void TList::mousePressEvent(QMouseEvent* ev) case 1013: if (QMessageBox::warning(this, tr("Drum map"), - tr("Reset the track's drum map with GM defaults?"), + tr("Reset the track's drum map with instrument defaults?"), QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok) == QMessageBox::Ok) { - ((MusECore::MidiTrack*)t)->init_drummap(); + ((MusECore::MidiTrack*)t)->set_drummap_tied_to_patch(true); + MusEGlobal::song->update(SC_DRUMMAP); + } + break; + + case 1016: + if (QMessageBox::warning(this, tr("Drum map"), + tr("Reset the track's drum map ordering?"), + QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok) == QMessageBox::Ok) + { + ((MusECore::MidiTrack*)t)->set_drummap_ordering_tied_to_patch(true); MusEGlobal::song->update(SC_DRUMMAP); } break; -- cgit v1.2.3 From 3be3458373d1df2569b6066910de1d5ac52bbb34 Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Tue, 3 Jan 2012 20:11:30 +0000 Subject: cleanup --- muse2/ChangeLog | 16 ++++++++++++ muse2/muse/arranger/tlist.cpp | 6 +---- muse2/muse/midiedit/dcanvas.h | 10 +++++--- muse2/muse/midiedit/drumedit.h | 2 +- muse2/muse/midiedit/scoreedit.cpp | 51 +++------------------------------------ 5 files changed, 27 insertions(+), 58 deletions(-) (limited to 'muse2') diff --git a/muse2/ChangeLog b/muse2/ChangeLog index 1445633b..4b9646f4 100644 --- a/muse2/ChangeLog +++ b/muse2/ChangeLog @@ -1,4 +1,20 @@ 03.01.2012: + - ADDED NEW STYLE DRUM TRACKS: (flo93) + + multiple tracks can be displayed in one editor + their drum sound columns can be reordered, mixed up, hidden. + drumtracks can be grouped by channel, not at all, or maximally + each track owns its own drummap + added drummap-definitions to instrument files (gs and xg.idf) + drumtracks' drummap can be automatically set according to + the currently used patch/program/bank + new-style-drumtracks can ignore muted, hidden or both sounds when + recording + + KNOWN ISSUES: when having multiple drumeditors open, the mute-column + may not work, because another editor is overriding this. + this is not a bug. + - Global Cut: Fixed crashes with markers. Re-did marker section in structure.cpp:adjustGlobalLists(). (Tim) TODO: Still get tempo, key, and sig not found warnings. 02.01.2012: diff --git a/muse2/muse/arranger/tlist.cpp b/muse2/muse/arranger/tlist.cpp index 3deeb65a..fe8b4731 100644 --- a/muse2/muse/arranger/tlist.cpp +++ b/muse2/muse/arranger/tlist.cpp @@ -718,10 +718,6 @@ void TList::portsPopupMenu(MusECore::Track* t, int x, int y) case MusECore::Track::MIDI: case MusECore::Track::DRUM: case MusECore::Track::NEW_DRUM: - // FINDMICHJETZT: this is a notice for flo's experimental - // branch! don't forget NEW_DRUM here! - // please don't remove this. i'll do it when - // the time is there. case MusECore::Track::AUDIO_SOFTSYNTH: { MusECore::MidiTrack* track = (MusECore::MidiTrack*)t; @@ -742,7 +738,7 @@ void TList::portsPopupMenu(MusECore::Track* t, int x, int y) QMenu* p = MusECore::midiPortsPopup(this, port); // 0, port); - if (t->type()==MusECore::Track::MIDI || t->type()==MusECore::Track::DRUM) //FINDMICHJETZT + if (t->isMidiTrack()) { // extend that menu a bit diff --git a/muse2/muse/midiedit/dcanvas.h b/muse2/muse/midiedit/dcanvas.h index 0fd4c9e0..ae647709 100644 --- a/muse2/muse/midiedit/dcanvas.h +++ b/muse2/muse/midiedit/dcanvas.h @@ -162,11 +162,13 @@ class DrumCanvas : public EventCanvas { virtual void keyPress(QKeyEvent* event); MusECore::Event *getEventAtCursorPos(); void selectCursorEvent(MusECore::Event *ev); + int pitch_and_track_to_instrument(int pitch, MusECore::Track* track); - MusECore::DrumMap* getOurDrumMap() { return ourDrumMap; } //FINDMICH UGLY - int getOurDrumMapSize() { return instrument_map.size(); } //FINDMICH UGLY - QVector<instrument_number_mapping_t>& get_instrument_map() { return instrument_map; } //FINDMICH UGLY - void propagate_drummap_change(int instrument, bool update_druminmap); //FINDMICH move to drumedit + + MusECore::DrumMap* getOurDrumMap() { return ourDrumMap; } + int getOurDrumMapSize() { return instrument_map.size(); } + QVector<instrument_number_mapping_t>& get_instrument_map() { return instrument_map; } + void propagate_drummap_change(int instrument, bool update_druminmap); void rebuildOurDrumMap(); }; diff --git a/muse2/muse/midiedit/drumedit.h b/muse2/muse/midiedit/drumedit.h index f4e2646b..33491581 100644 --- a/muse2/muse/midiedit/drumedit.h +++ b/muse2/muse/midiedit/drumedit.h @@ -169,7 +169,7 @@ class DrumEdit : public MidiEditor { group_mode_t group_mode() { return _group_mode; } bool ignore_hide() { return _ignore_hide; } - QVector<instrument_number_mapping_t>& get_instrument_map() { return static_cast<DrumCanvas*>(canvas)->get_instrument_map(); } //FINDMICH UGLY + QVector<instrument_number_mapping_t>& get_instrument_map() { return static_cast<DrumCanvas*>(canvas)->get_instrument_map(); } }; } // namespace MusEGui diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index 45ccd4d6..7e40a41f 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -4655,20 +4655,6 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo // every time something changes. -/* STUFF I WANT TO WORK - * - * x multiple new drum tracks can be displayed seperately in ONE drum - * editor - * x reorder drummap - * ? support and correctly map e-note on record and steprec - * ? only record nonmuted/whatever notes - * ? support drum controllers - * x refuse to mix up old-style and new-style drum tracks in ONE editor - * o drummap saving and loading (per-track) - * o drummap import/export - * o drummap automatically adapting to the chosen midi synth / patch - */ - /* BUGS and potential bugs * o tied notes don't work properly when there's a key-change in * between, for example, when a cis is tied to a des @@ -4679,46 +4665,15 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo * from clipboard failed. ignoring this one... ) [ not reproducible ] * * CURRENT TODO - * o write instrument drummaps - * o GUI for editing instrument drummaps - * * drum controllers - * update ctrlcanvas/panel - * test! - * * drum editor is buggy. propagate_drum_map may operate on old values - * ("BUGGY! problem is: while changing entries, ourDrumMap - * may be reallocated which causes abort()s and/or bugs.") - * [ seems to work now, needs further testing! ] - * x my record flag handling - * * once, using super glue while a score editor displaying the glued - * parts is open let muse segfault. this may or may not be fixed - * now. check! - * state of revision #1337: no segfaults, but the score editors - * close and lots of "ERROR" messages. - * - * o drum editor: channel-stuff - * o clearly state in the changelog: when having multiple drumeditors open, - * the mute-column may not work, because another editor is overriding this. - * > o respect "_drummap_tied_to_patch": IMPLEMENT - * 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 test drum controllers + * o test old- and new drumtrack recording, steprecording + * * > o fix valgrind problems (the two "FINDMICHJETZT" lines in scoreedit.cpp) * > o add a songposition scrollbar-toolbar (in different sizes) * this might be equivalent to "redo transport menu" (below). * > o add toolbar(s) for tempo- etc spinboxes from the transport window * - * * o find and fix FINDMICHJETZT - * o fix all segfaults and non-working stuff! - * - creating, changing types to and from, erasing NEW_DRUM tracks - * - move parts around - * - playing them. mute? - * - recording/echoing/steprec them - * - load, save them - * o fix valgrind problems * * IMPORTANT TODO * o allow steprec-insert-rest-note to be set to "off" / "unused" -- cgit v1.2.3 From b68a212e2d1a400145cc8010f74c0b15fe2ce284 Mon Sep 17 00:00:00 2001 From: Florian Jung <flo@windfisch.org> Date: Tue, 3 Jan 2012 20:16:20 +0000 Subject: reverted commit #1350 ("removed silly song-type-depencency...") i still think it's silly, but there needs to be a proper solution... --- muse2/muse/instruments/minstrument.cpp | 53 ++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 16 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/instruments/minstrument.cpp b/muse2/muse/instruments/minstrument.cpp index bd4b3bd4..1349c9c9 100644 --- a/muse2/muse/instruments/minstrument.cpp +++ b/muse2/muse/instruments/minstrument.cpp @@ -49,6 +49,8 @@ namespace MusECore { MidiInstrumentList midiInstruments; MidiInstrument* genericMidiInstrument; +static const char* gmdrumname = "GM-drums"; + //--------------------------------------------------------- // string2sysex //--------------------------------------------------------- @@ -1075,6 +1077,8 @@ QString MidiInstrument::getPatchName(int channel, int prog, MType mode, bool dru tmask = 4; break; case MT_GM: + if(drumchan) + return gmdrumname; tmask = 1; break; default: @@ -1086,8 +1090,10 @@ QString MidiInstrument::getPatchName(int channel, int prog, MType mode, bool dru const PatchList& pl = (*i)->patches; for (ciPatch ipl = pl.begin(); ipl != pl.end(); ++ipl) { const Patch* mp = *ipl; - if ( (pr == mp->prog) - && (mp->drum == drum) + if ((mp->typ & tmask) + && (pr == mp->prog) + && ((drum && mode != MT_GM) || + (mp->drum == drumchan)) && (hbank == mp->hbank || !hb || mp->hbank == -1) && (lbank == mp->lbank || !lb || mp->lbank == -1)) @@ -1101,35 +1107,49 @@ QString MidiInstrument::getPatchName(int channel, int prog, MType mode, bool dru // populatePatchPopup //--------------------------------------------------------- -void MidiInstrument::populatePatchPopup(MusEGui::PopupMenu* menu, int, MType, bool drum) +void MidiInstrument::populatePatchPopup(MusEGui::PopupMenu* menu, int chan, MType songType, bool drum) { menu->clear(); - + int mask = 0; + bool drumchan = chan == 9; + switch (songType) { + case MT_XG: mask = 4; break; + case MT_GS: mask = 2; break; + case MT_GM: + if(drumchan) + { + int id = (0xff << 16) + (0xff << 8) + 0x00; // First patch + QAction* act = menu->addAction(gmdrumname); + //act->setCheckable(true); + act->setData(id); + return; + } + mask = 1; + break; + case MT_UNKNOWN: mask = 7; break; + } if (pg.size() > 1) { for (ciPatchGroup i = pg.begin(); i != pg.end(); ++i) { PatchGroup* pgp = *i; + //QMenu* pm = menu->addMenu(pgp->name); MusEGui::PopupMenu* pm = new MusEGui::PopupMenu(pgp->name, menu, menu->stayOpen()); // Use the parent stayOpen here. + menu->addMenu(pm); + pm->setFont(MusEGlobal::config.fonts[0]); const PatchList& pl = pgp->patches; - bool added=false; for (ciPatch ipl = pl.begin(); ipl != pl.end(); ++ipl) { const Patch* mp = *ipl; - if (mp->drum == drum) + if ((mp->typ & mask) && + ((drum && songType != MT_GM) || + (mp->drum == drumchan)) ) { int id = ((mp->hbank & 0xff) << 16) + ((mp->lbank & 0xff) << 8) + (mp->prog & 0xff); QAction* act = pm->addAction(mp->name); + //act->setCheckable(true); act->setData(id); - added=true; } + } - if (added) - { - menu->addMenu(pm); - pm->setFont(MusEGlobal::config.fonts[0]); - } - else - delete pm; - } } else if (pg.size() == 1 ){ @@ -1137,10 +1157,11 @@ void MidiInstrument::populatePatchPopup(MusEGui::PopupMenu* menu, int, MType, bo const PatchList& pl = pg.front()->patches; for (ciPatch ipl = pl.begin(); ipl != pl.end(); ++ipl) { const Patch* mp = *ipl; - if (mp->drum == drum) { + if (mp->typ & mask) { int id = ((mp->hbank & 0xff) << 16) + ((mp->lbank & 0xff) << 8) + (mp->prog & 0xff); QAction* act = menu->addAction(mp->name); + //act->setCheckable(true); act->setData(id); } } -- cgit v1.2.3