From dea19421318fdef6cc0f3d9bbfae29c5470361a3 Mon Sep 17 00:00:00 2001 From: Florian Jung Date: Thu, 28 Jul 2011 17:11:30 +0000 Subject: speeded up structural operations fixed several heavy bugs in structural operations: - global insert freezed muse - global cut and global insert behaved wrong on parts not starting at the zeroth tick - fixed upper_bound vs. lower_bound issues clicking below the track list now deselects all tracks moved checkRegionNotNull() where it belongs --- muse2/muse/app.cpp | 21 +++++ muse2/muse/app.h | 3 +- muse2/muse/arranger/pcanvas.cpp | 4 +- muse2/muse/arranger/tlist.cpp | 3 + muse2/muse/structure.cpp | 165 +++++++++++++++++----------------------- 5 files changed, 97 insertions(+), 99 deletions(-) (limited to 'muse2') diff --git a/muse2/muse/app.cpp b/muse2/muse/app.cpp index fb07955f..3abb116f 100644 --- a/muse2/muse/app.cpp +++ b/muse2/muse/app.cpp @@ -3114,6 +3114,27 @@ void MusE::bounceToFile(AudioOutput* ao) song->setPlay(true); } + +//--------------------------------------------------------- +// checkRegionNotNull +// return true if (rPos - lPos) <= 0 +//--------------------------------------------------------- + +bool MusE::checkRegionNotNull() + { + int start = song->lPos().frame(); + int end = song->rPos().frame(); + if (end - start <= 0) { + QMessageBox::critical(this, + tr("MusE: Bounce"), + tr("set left/right marker for bounce range") + ); + return true; + } + return false; + } + + #ifdef HAVE_LASH //--------------------------------------------------------- // lash_idle_cb diff --git a/muse2/muse/app.h b/muse2/muse/app.h index 3fd93fc8..ccf3706b 100644 --- a/muse2/muse/app.h +++ b/muse2/muse/app.h @@ -64,6 +64,7 @@ class WaveTrack; class AudioOutput; class EditInstrument; class ScoreEdit; +class Undo; #define MENU_ADD_SYNTH_ID_BASE 0x1000 @@ -319,7 +320,7 @@ class MusE : public QMainWindow void execDeliveredScript(int); void execUserScript(int); private: - void adjustGlobalLists(int startPos, int diff); + void adjustGlobalLists(Undo& operations, int startPos, int diff); public slots: bool saveAs(); diff --git a/muse2/muse/arranger/pcanvas.cpp b/muse2/muse/arranger/pcanvas.cpp index 96c30fdb..1f25d6cc 100644 --- a/muse2/muse/arranger/pcanvas.cpp +++ b/muse2/muse/arranger/pcanvas.cpp @@ -374,13 +374,13 @@ UndoOp PartCanvas::moveItem(CItem* item, const QPoint& newpos, DragType t) if (t == MOVE_COPY || t == MOVE_CLONE) { // These will not increment ref count, and will not chain clones... - // TODO: is this still correct (by flo93)? + // TODO FINDMICH: is this still correct (by flo93)? i doubt it! result=UndoOp(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: is this still correct (by flo93)? + // TODO FINDMICH: is this still correct (by flo93)? i doubt it! result=UndoOp(UndoOp::ModifyPart,spart, dpart, true, false); spart->setSelected(false); diff --git a/muse2/muse/arranger/tlist.cpp b/muse2/muse/arranger/tlist.cpp index 4f050c46..d7cda62f 100644 --- a/muse2/muse/arranger/tlist.cpp +++ b/muse2/muse/arranger/tlist.cpp @@ -1069,6 +1069,9 @@ void TList::mousePressEvent(QMouseEvent* ev) //delete synp; delete p; } + else if (button == Qt::LeftButton) { + if (!ctrl) song->deselectTracks(); + } return; } diff --git a/muse2/muse/structure.cpp b/muse2/muse/structure.cpp index 27246315..f8d92497 100644 --- a/muse2/muse/structure.cpp +++ b/muse2/muse/structure.cpp @@ -23,10 +23,9 @@ // helper that adjusts tempo, sig, key and marker // lists everything from startPos is adjusted // 'diff' number of ticks. -// function requires undo to be handled outside //--------------------------------------------------------- -void MusE::adjustGlobalLists(int startPos, int diff) +void MusE::adjustGlobalLists(Undo& operations, int startPos, int diff) { const TempoList* t = &tempomap; const AL::SigList* s = &AL::sigmap; @@ -45,11 +44,11 @@ void MusE::adjustGlobalLists(int startPos, int diff) break; if (tick > startPos && tick +diff < startPos ) { // remove - audio->msgRemoveKey(tick, key, false); + operations.push_back(UndoOp(UndoOp::DeleteKey, tick, key)); } else { - audio->msgRemoveKey(tick, key, false); - audio->msgAddKey(tick+diff, key, false); + operations.push_back(UndoOp(UndoOp::DeleteKey,tick, key)); + operations.push_back(UndoOp(UndoOp::AddKey,tick+diff, key)); } } @@ -62,11 +61,11 @@ void MusE::adjustGlobalLists(int startPos, int diff) break; if (tick > startPos && tick +diff < startPos ) { // remove - audio->msgDeleteTempo(tick, tempo, false); + operations.push_back(UndoOp(UndoOp::DeleteTempo,tick, tempo)); } else { - audio->msgDeleteTempo(tick, tempo, false); - audio->msgAddTempo(tick+diff, tempo, false); + operations.push_back(UndoOp(UndoOp::DeleteTempo,tick, tempo)); + operations.push_back(UndoOp(UndoOp::AddTempo,tick+diff, tempo)); } } @@ -80,11 +79,11 @@ void MusE::adjustGlobalLists(int startPos, int diff) int z = ev->sig.z; int n = ev->sig.n; if (tick > startPos && tick +diff < startPos ) { // remove - audio->msgRemoveSig(tick, z, n, false); + operations.push_back(UndoOp(UndoOp::DeleteSig,tick, z, n)); } else { - audio->msgRemoveSig(tick, z, n, false); - audio->msgAddSig(tick+diff, z, n, false); + operations.push_back(UndoOp(UndoOp::DeleteSig,tick, z, n)); + operations.push_back(UndoOp(UndoOp::AddSig,tick+diff, z, n)); } } @@ -99,12 +98,12 @@ void MusE::adjustGlobalLists(int startPos, int diff) Marker *oldMarker = new Marker(); *oldMarker = *m; markerlist->remove(m); - song->addUndo(UndoOp(UndoOp::ModifyMarker,oldMarker, 0)); + operations.push_back(UndoOp(UndoOp::ModifyMarker,oldMarker, 0)); } else { Marker *oldMarker = new Marker(); *oldMarker = *m; m->setTick(tick + diff); - song->addUndo(UndoOp(UndoOp::ModifyMarker,oldMarker, m)); + operations.push_back(UndoOp(UndoOp::ModifyMarker,oldMarker, m)); } } } @@ -114,7 +113,6 @@ void MusE::adjustGlobalLists(int startPos, int diff) //--------------------------------------------------------- // globalCut // - remove area between left and right locator -// - do not touch muted track // - cut master track //--------------------------------------------------------- @@ -125,8 +123,9 @@ void MusE::globalCut() if ((lpos - rpos) >= 0) return; - song->startUndo(); + Undo operations; TrackList* tracks = song->tracks(); + for (iTrack it = tracks->begin(); it != tracks->end(); ++it) { MidiTrack* track = dynamic_cast(*it); if (track == 0 || track->mute()) @@ -139,7 +138,7 @@ void MusE::globalCut() if (t + l <= lpos) continue; if ((t >= lpos) && ((t+l) <= rpos)) { - audio->msgRemovePart(part, false); + operations.push_back(UndoOp(UndoOp::DeletePart,part)); } else if ((t < lpos) && ((t+l) > lpos) && ((t+l) <= rpos)) { // remove part tail @@ -149,17 +148,10 @@ void MusE::globalCut() // // cut Events in nPart EventList* el = nPart->events(); - iEvent ie = el->lower_bound(t + len); - for (; ie != el->end();) { - iEvent i = ie; - ++ie; - // Indicate no undo, and do not do port controller values and clone parts. - //audio->msgDeleteEvent(i->second, nPart, false); - audio->msgDeleteEvent(i->second, nPart, false, false, false); - } - // Indicate no undo, and do port controller values and clone parts. - //audio->msgChangePart(part, nPart, false); - audio->msgChangePart(part, nPart, false, true, true); + for (iEvent ie = el->lower_bound(len); ie != el->end(); ++ie) + operations.push_back(UndoOp(UndoOp::DeleteEvent,ie->second, nPart, false, false)); + + operations.push_back(UndoOp(UndoOp::ModifyPart,part, nPart, true, true)); } else if ((t < lpos) && ((t+l) > lpos) && ((t+l) > rpos)) { //---------------------- @@ -168,56 +160,61 @@ void MusE::globalCut() MidiPart* nPart = new MidiPart(*(MidiPart*)part); EventList* el = nPart->events(); - iEvent is = el->lower_bound(lpos); - iEvent ie = el->upper_bound(rpos); - for (iEvent i = is; i != ie;) { - iEvent ii = i; - ++i; - // Indicate no undo, and do not do port controller values and clone parts. - //audio->msgDeleteEvent(ii->second, nPart, false); - audio->msgDeleteEvent(ii->second, nPart, false, false, false); - } + iEvent is = el->lower_bound(lpos-t); + iEvent ie = el->lower_bound(rpos-t); //lower bound, because we do NOT want to erase the events at rpos-t + for (iEvent i = is; i != ie; ++i) + operations.push_back(UndoOp(UndoOp::DeleteEvent,i->second, nPart, false, false)); - ie = el->lower_bound(rpos); - for (; ie != el->end();) { - iEvent i = ie; - ++ie; + for (iEvent i = el->lower_bound(rpos-t); i != el->end(); ++i) { Event event = i->second; Event nEvent = event.clone(); nEvent.setTick(nEvent.tick() - (rpos-lpos)); // Indicate no undo, and do not do port controller values and clone parts. - //audio->msgChangeEvent(event, nEvent, nPart, false); - audio->msgChangeEvent(event, nEvent, nPart, false, false, false); + operations.push_back(UndoOp(UndoOp::ModifyEvent,nEvent, event, nPart, false, false)); } nPart->setLenTick(l - (rpos-lpos)); // Indicate no undo, and do port controller values and clone parts. - //audio->msgChangePart(part, nPart, false); - audio->msgChangePart(part, nPart, false, true, true); + operations.push_back(UndoOp(UndoOp::ModifyPart,part, nPart, true, true)); } else if ((t >= lpos) && (t < rpos) && (t+l) > rpos) { - // TODO: remove part head + // remove part head + + MidiPart* nPart = new MidiPart(*(MidiPart*)part); + EventList* el = nPart->events(); + iEvent i_end = el->lower_bound(rpos-t); //lower bound, because we do NOT want to erase the events at rpos-t + for (iEvent it = el->begin(); it!=i_end; it++) + operations.push_back(UndoOp(UndoOp::DeleteEvent,it->second, nPart, false, false)); + + for (iEvent it = el->lower_bound(rpos-t); it!=el->end(); it++) { + Event event = it->second; + Event nEvent = event.clone(); + nEvent.setTick(nEvent.tick() - (rpos-t)); + // Indicate no undo, and do not do port controller values and clone parts. + operations.push_back(UndoOp(UndoOp::ModifyEvent,nEvent, event, nPart, false, false)); + } + + nPart->setLenTick(l - (rpos-t)); + operations.push_back(UndoOp(UndoOp::ModifyPart,part, nPart, true, true)); } else if (t >= rpos) { MidiPart* nPart = new MidiPart(*(MidiPart*)part); int nt = part->tick(); nPart->setTick(nt - (rpos -lpos)); // Indicate no undo, and do port controller values but not clone parts. - //audio->msgChangePart(part, nPart, false); - audio->msgChangePart(part, nPart, false, true, false); + operations.push_back(UndoOp(UndoOp::ModifyPart,part, nPart, true, false)); } } } int diff = lpos - rpos; - adjustGlobalLists(lpos, diff); + adjustGlobalLists(operations, lpos, diff); - song->endUndo(SC_TRACK_MODIFIED | SC_PART_MODIFIED | SC_PART_REMOVED | SC_TEMPO | SC_KEY | SC_SIG); + song->applyOperationGroup(operations); } //--------------------------------------------------------- // globalInsert // - insert empty space at left locator position upto // right locator -// - do not touch muted track // - insert in master track //--------------------------------------------------------- @@ -228,13 +225,11 @@ void MusE::globalInsert() if (lpos >= rpos) return; - song->startUndo(); + Undo operations; TrackList* tracks = song->tracks(); + for (iTrack it = tracks->begin(); it != tracks->end(); ++it) { MidiTrack* track = dynamic_cast(*it); - // - // process only non muted midi tracks - // if (track == 0 || track->mute()) continue; PartList* pl = track->parts(); @@ -249,52 +244,48 @@ void MusE::globalInsert() nPart->setLenTick(l + (rpos-lpos)); EventList* el = nPart->events(); - iEvent i = el->end(); - while (i != el->begin()) { - --i; - if (i->first < lpos) + for (riEvent i = el->rbegin(); i!=el->rend(); ++i) + { + if (i->first < lpos-t) break; Event event = i->second; Event nEvent = i->second.clone(); nEvent.setTick(nEvent.tick() + (rpos-lpos)); - // Indicate no undo, and do not do port controller values and clone parts. - //audio->msgChangeEvent(event, nEvent, nPart, false); - audio->msgChangeEvent(event, nEvent, nPart, false, false, false); + operations.push_back(UndoOp(UndoOp::ModifyEvent, nEvent, event, nPart, false, false)); } - // Indicate no undo, and do port controller values and clone parts. - //audio->msgChangePart(part, nPart, false); - audio->msgChangePart(part, nPart, false, true, true); + operations.push_back(UndoOp(UndoOp::ModifyPart, part, nPart, true, true)); } else if (t > lpos) { MidiPart* nPart = new MidiPart(*(MidiPart*)part); nPart->setTick(t + (rpos -lpos)); - // Indicate no undo, and do port controller values but not clone parts. - //audio->msgChangePart(part, nPart, false); - audio->msgChangePart(part, nPart, false, true, false); + operations.push_back(UndoOp(UndoOp::ModifyPart, part, nPart, true, false)); } } } int diff = rpos - lpos; - adjustGlobalLists(lpos, diff); + adjustGlobalLists(operations, lpos, diff); - song->endUndo(SC_TRACK_MODIFIED | SC_PART_MODIFIED | SC_PART_REMOVED | SC_TEMPO | SC_KEY | SC_SIG ); + song->applyOperationGroup(operations); } //--------------------------------------------------------- // globalSplit // - split all parts at the song position pointer -// - do not touch muted track //--------------------------------------------------------- void MusE::globalSplit() { int pos = song->cpos(); - song->startUndo(); + Undo operations; TrackList* tracks = song->tracks(); + for (iTrack it = tracks->begin(); it != tracks->end(); ++it) { Track* track = *it; + if (track == 0 || track->mute()) + continue; + PartList* pl = track->parts(); for (iPart p = pl->begin(); p != pl->end(); ++p) { Part* part = p->second; @@ -304,15 +295,17 @@ void MusE::globalSplit() Part* p1; Part* p2; track->splitPart(part, pos, p1, p2); - // Indicate no undo, and do port controller values but not clone parts. - //audio->msgChangePart(part, p1, false); - audio->msgChangePart(part, p1, false, true, false); - audio->msgAddPart(p2, false); + + p1->events()->incARef(-1); // the later song->applyOperationGroup() will increment it + p2->events()->incARef(-1); // so we must decrement it first :/ + + operations.push_back(UndoOp(UndoOp::ModifyPart,part, p1, true, false)); + operations.push_back(UndoOp(UndoOp::AddPart,p2)); break; } } } - song->endUndo(SC_TRACK_MODIFIED | SC_PART_MODIFIED | SC_PART_INSERTED); + song->applyOperationGroup(operations); } //--------------------------------------------------------- @@ -346,23 +339,3 @@ void MusE::cutEvents() tr("not implemented") ); } - -//--------------------------------------------------------- -// checkRegionNotNull -// return true if (rPos - lPos) <= 0 -//--------------------------------------------------------- - -bool MusE::checkRegionNotNull() - { - int start = song->lPos().frame(); - int end = song->rPos().frame(); - if (end - start <= 0) { - QMessageBox::critical(this, - tr("MusE: Bounce"), - tr("set left/right marker for bounce range") - ); - return true; - } - return false; - } - -- cgit v1.2.3