summaryrefslogtreecommitdiff
path: root/muse2
diff options
context:
space:
mode:
Diffstat (limited to 'muse2')
-rw-r--r--muse2/ChangeLog12
-rw-r--r--muse2/muse/app.cpp21
-rw-r--r--muse2/muse/app.h3
-rw-r--r--muse2/muse/arranger/pcanvas.cpp4
-rw-r--r--muse2/muse/arranger/tlist.cpp3
-rw-r--r--muse2/muse/dssihost.cpp2
-rw-r--r--muse2/muse/midiedit/scoreedit.cpp12
-rw-r--r--muse2/muse/structure.cpp165
-rw-r--r--muse2/synti/deicsonze/deicsonze.cpp2
-rw-r--r--muse2/synti/fluidsynth/fluidsynti.cpp2
-rw-r--r--muse2/synti/organ/organ.cpp2
-rw-r--r--muse2/synti/simpledrums2/simpledrums.cpp2
-rw-r--r--muse2/synti/vam/vam.cpp2
13 files changed, 126 insertions, 106 deletions
diff --git a/muse2/ChangeLog b/muse2/ChangeLog
index 260d7225..7dc46580 100644
--- a/muse2/ChangeLog
+++ b/muse2/ChangeLog
@@ -1,3 +1,15 @@
+28.07.2011:
+ - speeded up structural operations (flo93)
+ - fixed several heavy bugs in structural operations: (flo93)
+ - 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 (flo93)
+ - moved checkRegionNotNull() where it belongs (flo93)
+14.07.2011:
+ - Fixed loading of old songs with synths. (Tim)
+ Added static keyword to array in each synth's oldMidiStateHeader() member.
27.06.2011:
- Massively speeded up muse by using operation groups (flo93)
- Changed behaviour of middle click in all canvases to "delete" (flo93)
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 edf60802..7298194c 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/dssihost.cpp b/muse2/muse/dssihost.cpp
index fd33a135..850fc8b8 100644
--- a/muse2/muse/dssihost.cpp
+++ b/muse2/muse/dssihost.cpp
@@ -1352,7 +1352,7 @@ DssiSynthIF::~DssiSynthIF()
int DssiSynthIF::oldMidiStateHeader(const unsigned char** data) const
{
- unsigned char const d[2] = {MUSE_SYNTH_SYSEX_MFG_ID, DSSI_SYNTH_UNIQUE_ID};
+ static unsigned char const d[2] = {MUSE_SYNTH_SYSEX_MFG_ID, DSSI_SYNTH_UNIQUE_ID};
*data = &d[0];
return 2;
}
diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp
index 811aaa2a..785ac7a5 100644
--- a/muse2/muse/midiedit/scoreedit.cpp
+++ b/muse2/muse/midiedit/scoreedit.cpp
@@ -4469,9 +4469,19 @@ void staff_t::update_part_indices()
* because after A (and B) got resized, the B-resize is invalid!
*
* CURRENT TODO
- * o draw the edge of parts hiding notes "jagged" (hasHiddenNotes() is interesting for this)
+ * o redo transport menu: offer "one beat" and "one bar" steps
+ * maybe also offer scrollbar
+ * o quick "set left/right marker", "select between markers"
+ * or even "set marker and select between immediately"
+ * o support partially selected parts. when moving, automatically split
+ *
+ * o speed up structural operations
+ * o maybe remove "insert empty measure"?
+ * o structural OPs: don't erase note which begins at "end of cut"
+ * o add "move other notes" or "overwrite notes" or "mix with notes" to paste
*
* IMPORTANT TODO
+ * o draw the edge of parts hiding notes "jagged" (hasHiddenNotes() is interesting for this)
* o shrink a part from its beginning as well! watch out for clones!
* o insert empty measure should also work inside parts, that is,
* move notes _within_ parts
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<MidiTrack*>(*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<MidiTrack*>(*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;
- }
-
diff --git a/muse2/synti/deicsonze/deicsonze.cpp b/muse2/synti/deicsonze/deicsonze.cpp
index b723e925..bffedf53 100644
--- a/muse2/synti/deicsonze/deicsonze.cpp
+++ b/muse2/synti/deicsonze/deicsonze.cpp
@@ -265,7 +265,7 @@ DeicsOnze::~DeicsOnze()
int DeicsOnze::oldMidiStateHeader(const unsigned char** data) const
{
- unsigned char const d[2] = {MUSE_SYNTH_SYSEX_MFG_ID, DEICSONZE_UNIQUE_ID};
+ static unsigned char const d[2] = {MUSE_SYNTH_SYSEX_MFG_ID, DEICSONZE_UNIQUE_ID};
*data = &d[0];
return 2;
}
diff --git a/muse2/synti/fluidsynth/fluidsynti.cpp b/muse2/synti/fluidsynth/fluidsynti.cpp
index 35ee16df..63a516ed 100644
--- a/muse2/synti/fluidsynth/fluidsynti.cpp
+++ b/muse2/synti/fluidsynth/fluidsynti.cpp
@@ -144,7 +144,7 @@ bool FluidSynth::init(const char* name)
int FluidSynth::oldMidiStateHeader(const unsigned char** data) const
{
- unsigned char const d[2] = {MUSE_SYNTH_SYSEX_MFG_ID, FLUIDSYNTH_UNIQUE_ID};
+ static unsigned char const d[2] = {MUSE_SYNTH_SYSEX_MFG_ID, FLUIDSYNTH_UNIQUE_ID};
*data = &d[0];
return 2;
}
diff --git a/muse2/synti/organ/organ.cpp b/muse2/synti/organ/organ.cpp
index f3bb3b9f..60f3f52d 100644
--- a/muse2/synti/organ/organ.cpp
+++ b/muse2/synti/organ/organ.cpp
@@ -175,7 +175,7 @@ bool Organ::init(const char* name)
int Organ::oldMidiStateHeader(const unsigned char** data) const
{
- unsigned char const d[3] = {MUSE_SYNTH_SYSEX_MFG_ID, ORGAN_UNIQUE_ID, INIT_DATA_CMD};
+ static unsigned char const d[3] = {MUSE_SYNTH_SYSEX_MFG_ID, ORGAN_UNIQUE_ID, INIT_DATA_CMD};
*data = &d[0];
return 3;
}
diff --git a/muse2/synti/simpledrums2/simpledrums.cpp b/muse2/synti/simpledrums2/simpledrums.cpp
index 80f61102..2da4ed82 100644
--- a/muse2/synti/simpledrums2/simpledrums.cpp
+++ b/muse2/synti/simpledrums2/simpledrums.cpp
@@ -251,7 +251,7 @@ SimpleSynth::~SimpleSynth()
int SimpleSynth::oldMidiStateHeader(const unsigned char** data) const
{
- unsigned char const d[2] = {MUSE_SYNTH_SYSEX_MFG_ID, SIMPLEDRUMS_UNIQUE_ID};
+ static unsigned char const d[2] = {MUSE_SYNTH_SYSEX_MFG_ID, SIMPLEDRUMS_UNIQUE_ID};
*data = &d[0];
return 2;
}
diff --git a/muse2/synti/vam/vam.cpp b/muse2/synti/vam/vam.cpp
index 14280651..78328eb2 100644
--- a/muse2/synti/vam/vam.cpp
+++ b/muse2/synti/vam/vam.cpp
@@ -258,7 +258,7 @@ VAM::~VAM()
int VAM::oldMidiStateHeader(const unsigned char** data) const
{
- unsigned char const d[3] = {MUSE_SYNTH_SYSEX_MFG_ID, VAM_UNIQUE_ID, INIT_DATA_CMD};
+ static unsigned char const d[3] = {MUSE_SYNTH_SYSEX_MFG_ID, VAM_UNIQUE_ID, INIT_DATA_CMD};
*data = &d[0];
return 3;
}