diff options
-rw-r--r-- | muse2/muse/midiedit/dcanvas.cpp | 4 | ||||
-rw-r--r-- | muse2/muse/midiedit/prcanvas.cpp | 7 | ||||
-rw-r--r-- | muse2/muse/midiedit/scoreedit.cpp | 4 | ||||
-rw-r--r-- | muse2/muse/steprec.cpp | 248 |
4 files changed, 144 insertions, 119 deletions
diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp index 4b5c3ea9..b9ff5a20 100644 --- a/muse2/muse/midiedit/dcanvas.cpp +++ b/muse2/muse/midiedit/dcanvas.cpp @@ -731,7 +731,7 @@ void DrumCanvas::keyPressed(int index, int velocity) MidiPlayEvent e(0, port, channel, 0x90, pitch, velocity); audio->msgPlayMidiEvent(&e); - if (_steprec && pos[0] >= start_tick && pos[0] < end_tick && curPart) + 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,globalKeyState&Qt::ControlModifier,globalKeyState&Qt::ShiftModifier); } @@ -1120,7 +1120,7 @@ void DrumCanvas::midiNote(int pitch, int velo) if (_midiin && _steprec && curPart && !audio->isPlaying() && velo && pos[0] >= start_tick - && pos[0] < end_tick + /* && pos[0] < end_tick [removed by flo93: this is handled in steprec->record] */ && !(globalKeyState & Qt::AltModifier)) { steprec->record(curPart,drumInmap[pitch],drumMap[(int)drumInmap[pitch]].len,editor->raster(),velo,globalKeyState&Qt::ControlModifier,globalKeyState&Qt::ShiftModifier); } diff --git a/muse2/muse/midiedit/prcanvas.cpp b/muse2/muse/midiedit/prcanvas.cpp index a659ad26..73e70e84 100644 --- a/muse2/muse/midiedit/prcanvas.cpp +++ b/muse2/muse/midiedit/prcanvas.cpp @@ -66,7 +66,7 @@ void PianoCanvas::addItem(Part* part, Event& event) NEvent* ev = new NEvent(event, part, pitch2y(event.pitch())); items.add(ev); - int diff = event.endTick()-part->lenTick(); + int diff = event.tick()-part->lenTick(); if (diff > 0) {// too short part? extend it //printf("addItem - this code should not be run!\n"); //Part* newPart = part->clone(); @@ -655,9 +655,8 @@ void PianoCanvas::pianoPressed(int pitch, int velocity, bool shift) MidiPlayEvent e(0, port, channel, 0x90, pitch, velocity); audio->msgPlayMidiEvent(&e); - if (_steprec && pos[0] >= start_tick && pos[0] < end_tick && curPart) { + 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,globalKeyState&Qt::ControlModifier,shift); - } } //--------------------------------------------------------- @@ -881,7 +880,7 @@ void PianoCanvas::midiNote(int pitch, int velo) if (_midiin && _steprec && curPart && !audio->isPlaying() && velo && pos[0] >= start_tick - && pos[0] < end_tick + /* && pos[0] < end_tick [removed by flo93: this is handled in steprec->record] */ && !(globalKeyState & Qt::AltModifier)) { steprec->record(curPart,pitch,editor->raster(),editor->raster(),velo,globalKeyState&Qt::ControlModifier,globalKeyState&Qt::ShiftModifier); } diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index c2380539..d7131db9 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -4456,7 +4456,8 @@ void staff_t::update_part_indices() * between, for example, when a cis is tied to a des * * CURRENT TODO - * o do autoexpand in steprec.cpp and scoreedit.cpp + * o do autoexpand in scoreedit.cpp + * o draw the edge of parts hiding notes "jagged" (hasHiddenNotes() is interesting for this) * * IMPORTANT TODO * o shrink a part from its beginning as well! watch out for clones! @@ -4477,6 +4478,7 @@ void staff_t::update_part_indices() * o transpose etc. must also transpose key-pressure events * o transpose: support in-key-transpose * o thin out: remove unneeded ctrl messages + * o make muse usable without the middle mouse button * * less important stuff * o quantize-templates (everything is forced into a specified diff --git a/muse2/muse/steprec.cpp b/muse2/muse/steprec.cpp index 29cb9540..c1fc23b1 100644 --- a/muse2/muse/steprec.cpp +++ b/muse2/muse/steprec.cpp @@ -9,6 +9,7 @@ #include "part.h" #include "event.h" #include "globals.h" +#include "functions.h" #include "song.h" #include "audio.h" @@ -39,121 +40,144 @@ void StepRec::timeout() void StepRec::record(Part* part, int pitch, int len, int step, int velo, bool ctrl, bool shift) { - unsigned tick = song->cpos(); - - if (pitch!=rcSteprecNote) { - chord_timer->stop(); - - - // - // extend len of last note? - // - EventList* events = part->events(); - if (ctrl) { - for (iEvent i = events->begin(); i != events->end(); ++i) { - Event ev = i->second; - if (!ev.isNote()) - continue; - if (ev.pitch() == pitch && ((ev.tick() + ev.lenTick()) == tick)) { - Event e = ev.clone(); - e.setLenTick(ev.lenTick() + len); - // Indicate do undo, and do not do port controller values and clone parts. - audio->msgChangeEvent(ev, e, part, true, false, false); - - if (!shift) { - chord_timer_set_to_tick = tick + step; - chord_timer->start(); - } - return; - } - } - } + unsigned tick = song->cpos(); + unsigned lasttick=0; + Undo operations; + + if (pitch!=rcSteprecNote) + { + chord_timer->stop(); + + // extend len of last note? + EventList* events = part->events(); + if (ctrl) + { + for (iEvent i = events->begin(); i != events->end(); ++i) + { + Event ev = i->second; + if (ev.isNote() && ev.pitch() == pitch && ((ev.tick() + ev.lenTick() + part->tick()) == tick)) + { + Event e = ev.clone(); + e.setLenTick(ev.lenTick() + len); + operations.push_back(UndoOp(UndoOp::ModifyEvent, e,ev, part, false, false)); + + if (!shift) + { + chord_timer_set_to_tick = tick + step; + chord_timer->start(); + } + + lasttick=tick+len - part->tick(); + goto steprec_record_foot; + } + } + } - // - // if we already entered the note, delete it - // - EventRange range = events->equal_range(tick); - for (iEvent i = range.first; i != range.second; ++i) { - Event ev = i->second; - if (ev.isNote() && ev.pitch() == pitch) { - // Indicate do undo, and do not do port controller values and clone parts. - //audio->msgDeleteEvent(ev, part); - audio->msgDeleteEvent(ev, part, true, false, false); + if (tick<=part->endTick()) + { + // if we already entered the note, delete it + // if we would find a note after part->lenTick(), the above "if" + // avoids this. this has to be avoided because then part->hasHiddenNotes() is true + // which results in forbidding any action beyond its end + EventRange range = events->equal_range(tick - part->tick()); + for (iEvent i = range.first; i != range.second; ++i) + { + Event ev = i->second; + if (ev.isNote() && ev.pitch() == pitch) + { + audio->msgDeleteEvent(ev, part, true, false, false); - if (!shift) { - chord_timer_set_to_tick = tick + step; - chord_timer->start(); - } - - return; - } - } - - Event e(Note); - e.setTick(tick - part->tick()); - e.setPitch(pitch); - e.setVelo(velo); - e.setLenTick(len); - // Indicate do undo, and do not do port controller values and clone parts. - //audio->msgAddEvent(e, part); - audio->msgAddEvent(e, part, true, false, false); - - if (! (globalKeyState & Qt::ShiftModifier)) { - chord_timer_set_to_tick = tick + step; - chord_timer->start(); - } - } - else { // equals if (pitch==rcSteprecNote) - bool held_notes=false; - if (note_held_down!=NULL) - { - for (int i=0;i<128;i++) - if (note_held_down[i]) { held_notes=true; break; } - } - else - held_notes=false; - - - if (held_notes) - { - chord_timer->stop(); - - // extend len of last note(s) - using std::set; - - set<Event*> extend_set; - EventList* events = part->events(); - for (iEvent i = events->begin(); i != events->end(); ++i) { - Event& ev = i->second; - if (!ev.isNote()) - continue; + if (!shift) + { + chord_timer_set_to_tick = tick + step; + chord_timer->start(); + } + + return; + } + } + } + + + Event e(Note); + e.setTick(tick - part->tick()); + e.setPitch(pitch); + e.setVelo(velo); + e.setLenTick(len); + operations.push_back(UndoOp(UndoOp::AddEvent, e, part, false, false)); + lasttick=e.endTick(); + + if (! (globalKeyState & Qt::ShiftModifier)) + { + chord_timer_set_to_tick = tick + step; + chord_timer->start(); + } + + goto steprec_record_foot; // this is actually unneccessary, but for clarity + } + else // equals if (pitch==rcSteprecNote) + { + bool held_notes=false; + if (note_held_down!=NULL) + { + for (int i=0;i<128;i++) + if (note_held_down[i]) { held_notes=true; break; } + } + else + held_notes=false; + - if (note_held_down[ev.pitch()] && ((ev.tick() + ev.lenTick()) == tick)) - extend_set.insert(&ev); - } - for (set<Event*>::iterator it=extend_set.begin(); it!=extend_set.end(); it++) - { - Event& ev=**it; - Event e = ev.clone(); - e.setLenTick(ev.lenTick() + len); - // Indicate do undo, and do not do port controller values and clone parts. - audio->msgChangeEvent(ev, e, part, true, false, false); - } + if (held_notes) + { + chord_timer->stop(); + + // extend len of last note(s) + using std::set; + + set<Event*> extend_set; + EventList* events = part->events(); + for (iEvent i = events->begin(); i != events->end(); ++i) + { + Event& ev = i->second; + if (ev.isNote() && note_held_down[ev.pitch()] && ((ev.tick() + ev.lenTick() + part->tick()) == tick)) + extend_set.insert(&ev); + } + + for (set<Event*>::iterator it=extend_set.begin(); it!=extend_set.end(); it++) + { + Event& ev=**it; + Event e = ev.clone(); + e.setLenTick(ev.lenTick() + len); + operations.push_back(UndoOp(UndoOp::ModifyEvent,e, ev, part, false, false)); + } - if (!shift) { - chord_timer_set_to_tick = tick + step; - chord_timer->start(); - } - return; - - } - else // equals if (!held_notes) - { - chord_timer->stop(); + if (!shift) + { + chord_timer_set_to_tick = tick + step; + chord_timer->start(); + } + + lasttick=tick+len - part->tick(); + goto steprec_record_foot; // this is actually unneccessary, but for clarity + } + else // equals if (!held_notes) + { + chord_timer->stop(); - //simply proceed, inserting a rest - Pos p(song->cpos() + step, true); - song->setPos(0, p, true, false, true); - } - } + // simply proceed, inserting a rest + Pos p(song->cpos() + step, true); + song->setPos(0, p, true, false, true); + + return; + } + } + + steprec_record_foot: + if (!((lasttick > part->lenTick()) && part->hasHiddenNotes())) // allowed? + { + if (lasttick > part->lenTick()) // we have to expand the part? + schedule_resize_all_same_len_clone_parts(part, lasttick, operations); + + song->applyOperationGroup(operations); + } } |