diff options
| author | Florian Jung <flo@windfisch.org> | 2011-05-25 17:27:35 +0000 | 
|---|---|---|
| committer | Florian Jung <flo@windfisch.org> | 2011-05-25 17:27:35 +0000 | 
| commit | 3948032d0a2e439069d9a6859f7f35eebb54944d (patch) | |
| tree | c4bb531ecdd05e21333cedacbf27ea01686e7b69 /muse2/muse | |
| parent | 5e47397a7d496b8dcc93e11b89cb0f9159f291e0 (diff) | |
added step recording for drum edit
step-recording stuff has been put into a easy-to-use StepRec class
the midi-in and step-rec buttons are now fully functional again
Diffstat (limited to 'muse2/muse')
| -rw-r--r-- | muse2/muse/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | muse2/muse/midiedit/dcanvas.cpp | 24 | ||||
| -rw-r--r-- | muse2/muse/midiedit/dcanvas.h | 8 | ||||
| -rw-r--r-- | muse2/muse/midiedit/drumedit.cpp | 7 | ||||
| -rw-r--r-- | muse2/muse/midiedit/prcanvas.cpp | 161 | ||||
| -rw-r--r-- | muse2/muse/midiedit/prcanvas.h | 7 | ||||
| -rw-r--r-- | muse2/muse/steprec.cpp | 159 | ||||
| -rw-r--r-- | muse2/muse/steprec.h | 36 | 
8 files changed, 237 insertions, 167 deletions
| diff --git a/muse2/muse/CMakeLists.txt b/muse2/muse/CMakeLists.txt index e6a90a59..cea95083 100644 --- a/muse2/muse/CMakeLists.txt +++ b/muse2/muse/CMakeLists.txt @@ -63,6 +63,7 @@ QT4_WRAP_CPP ( muse_moc_headers        song.h         transport.h         value.h  +      steprec.h         )  ## @@ -135,6 +136,7 @@ file (GLOB core_source_files        waveevent.cpp         wavetrack.cpp         xml.cpp +      steprec.cpp        )  file (GLOB main_source_files        main.cpp diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp index eea29b46..4f904be1 100644 --- a/muse2/muse/midiedit/dcanvas.cpp +++ b/muse2/muse/midiedit/dcanvas.cpp @@ -88,7 +88,11 @@ DrumCanvas::DrumCanvas(MidiEditor* pr, QWidget* parent, int sx,        setVirt(false);        cursorPos= QPoint(0,0);        _stepSize=1; +       +      steprec=new StepRec(NULL); +              songChanged(SC_TRACK_INSERTED); +      connect(song, SIGNAL(midiNote(int, int)), SLOT(midiNote(int,int)));        }  //--------------------------------------------------------- @@ -1063,6 +1067,10 @@ void DrumCanvas::keyPressed(int index, int velocity)        // play note:        MidiPlayEvent e(0, port, channel, 0x90, pitch, velocity);        audio->msgPlayMidiEvent(&e); + +      if (_steprec && pos[0] >= start_tick && pos[0] < end_tick && curPart) +				steprec->record(curPart,index,drumMap[index].len,editor->raster(),velocity,globalKeyState&Qt::ControlModifier,globalKeyState&Qt::ShiftModifier); +                    }  //--------------------------------------------------------- @@ -1503,3 +1511,19 @@ void DrumCanvas::moveAwayUnused()  		used.erase(it++);  	}  } + + +//--------------------------------------------------------- +//   midiNote +//--------------------------------------------------------- +void DrumCanvas::midiNote(int pitch, int 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 +         && !(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/dcanvas.h b/muse2/muse/midiedit/dcanvas.h index b86bc2d7..5a1fefeb 100644 --- a/muse2/muse/midiedit/dcanvas.h +++ b/muse2/muse/midiedit/dcanvas.h @@ -10,6 +10,7 @@  #include "ecanvas.h"  #include "song.h" +#include "steprec.h"  #define TH 18 @@ -40,7 +41,9 @@ class PianoRoll;  //---------------------------------------------------------  class DrumCanvas : public EventCanvas { - +       +      StepRec* steprec; +              // Cursor tool position        QPoint cursorPos;        int _stepSize; @@ -77,6 +80,9 @@ class DrumCanvas : public EventCanvas {     signals:        void newWidth(int); +   private slots: +      void midiNote(int pitch, int velo); +           public slots:        void mapChanged(int, int);        void keyPressed(int, int); diff --git a/muse2/muse/midiedit/drumedit.cpp b/muse2/muse/midiedit/drumedit.cpp index 4d632984..4d2fae93 100644 --- a/muse2/muse/midiedit/drumedit.cpp +++ b/muse2/muse/midiedit/drumedit.cpp @@ -295,21 +295,14 @@ DrumEdit::DrumEdit(PartList* pl, QWidget* parent, const char* name, unsigned ini        srec->setToolTip(tr("Step Record"));        srec->setIcon(*steprecIcon);        srec->setCheckable(true); -      srec->setEnabled(false); //disabled by flo93 (see below)        tools->addWidget(srec);        midiin  = new QToolButton();        midiin->setToolTip(tr("Midi Input"));        midiin->setIcon(*midiinIcon);        midiin->setCheckable(true); -      midiin->setEnabled(false); //disabled by flo93 (see below)        tools->addWidget(midiin); -      // I disabled these buttons because they're without function; -      // muse should not lie to the user pretending some functionality -      // it doesn't have; they should be enabled as soon step-recording -      // has been implemented. -        tools2 = new EditToolBar(this, drumeditTools);        addToolBar(tools2); diff --git a/muse2/muse/midiedit/prcanvas.cpp b/muse2/muse/midiedit/prcanvas.cpp index 7794c520..75ad3c06 100644 --- a/muse2/muse/midiedit/prcanvas.cpp +++ b/muse2/muse/midiedit/prcanvas.cpp @@ -37,8 +37,6 @@  #include "song.h"  #include "audio.h" -#define CHORD_TIMEOUT 75 -  //---------------------------------------------------------  //   NEvent  //--------------------------------------------------------- @@ -87,13 +85,8 @@ PianoCanvas::PianoCanvas(MidiEditor* pr, QWidget* parent, int sx, int sy)        playedPitch = -1;        for (int i=0;i<128;i++) noteHeldDown[i]=false; -      chordTimer = new QTimer(this); -      chordTimer->setSingleShot(true); -      chordTimer->setInterval(CHORD_TIMEOUT); -      chordTimer->stop(); +      steprec=new StepRec(noteHeldDown); -      connect(chordTimer, SIGNAL(timeout()), SLOT(chordTimerTimedOut())); -        songChanged(SC_TRACK_INSERTED);        connect(song, SIGNAL(midiNote(int, int)), SLOT(midiNote(int,int)));        } @@ -778,27 +771,9 @@ void PianoCanvas::pianoPressed(int pitch, int velocity, bool shift)        //MidiPlayEvent e(0, port, channel, 0x90, pitch, 127);        MidiPlayEvent e(0, port, channel, 0x90, pitch, velocity);        audio->msgPlayMidiEvent(&e); - -      if (_steprec && pos[0] >= start_tick && pos[0] < end_tick) { -         if (curPart) { -            int len  = editor->raster(); -            unsigned tick = pos[0] - curPart->tick(); //CDW -            if (shift) -                  tick -= editor->rasterStep(tick); -            Event e(Note); -            e.setTick(tick); -            e.setPitch(pitch); -            e.setVelo(127); -            e.setLenTick(len); -            // Indicate do undo, and do not do port controller values and clone parts.  -            //audio->msgAddEvent(e, curPart); -            audio->msgAddEvent(e, curPart, true, false, false); -            tick += editor->rasterStep(tick) + curPart->tick(); -            if (tick != song->cpos()) { -                  Pos p(tick, true); -                  song->setPos(0, p, true, false, true); -                  } -            } +       +      if (_steprec && pos[0] >= start_tick && pos[0] < end_tick && curPart) { +				 steprec->record(curPart,pitch,editor->raster(),editor->raster(),velocity,globalKeyState&Qt::ControlModifier,shift);           }        } @@ -1077,136 +1052,10 @@ void PianoCanvas::midiNote(int pitch, int velo)           && !audio->isPlaying() && velo && pos[0] >= start_tick           && pos[0] < end_tick           && !(globalKeyState & Qt::AltModifier)) { -					  -         if (pitch!=rcSteprecNote) { -					  chordTimer->stop(); -					   -					  //len has been changed by flo: set to raster() instead of quant() -					  //reason: the quant-toolbar has been removed; the flexibility you -					  //lose with this can be re-gained by applying a "modify note len" -					  //on the notes you have entered. -            unsigned int len   = editor->raster();//prevent compiler warning: comparison singed/unsigned -            unsigned tick      = pos[0]; //CDW -            unsigned starttick = tick; - -            // -            // extend len of last note? -            // -            EventList* events = curPart->events(); -            if (globalKeyState & Qt::ControlModifier) { -                  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()) == /*(int)*/starttick)) { -                              Event e = ev.clone(); -                              e.setLenTick(ev.lenTick() + editor->rasterStep(starttick)); -                              // Indicate do undo, and do not do port controller values and clone parts.  -                              //audio->msgChangeEvent(ev, e, curPart); -                              audio->msgChangeEvent(ev, e, curPart, true, false, false); -                               -                              if (! (globalKeyState & Qt::ShiftModifier)) { -                                    chordTimer_setToTick = tick + editor->rasterStep(tick); -                                    chordTimer->start(); -                                    } -                              return; -                              } -                        } -                  } - -            // -            // 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, curPart); -                        audio->msgDeleteEvent(ev, curPart, true, false, false); - -                        if (! (globalKeyState & Qt::ShiftModifier)) { -                              chordTimer_setToTick = tick + editor->rasterStep(tick); -                              chordTimer->start(); -                              } -                         -                        return; -                        } -                  } -            Event e(Note); -            e.setTick(tick - curPart->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, curPart); -            audio->msgAddEvent(e, curPart, true, false, false); -             -            if (! (globalKeyState & Qt::ShiftModifier)) { -                  chordTimer_setToTick = tick + editor->rasterStep(tick); -                  chordTimer->start(); -                  } -            } -         else { // equals if (pitch==rcSteprecNote) -            bool held_notes=false; -            for (int i=0;i<128;i++) -               if (noteHeldDown[i]) { held_notes=true; break; } -             -            if (held_notes) -            { -                chordTimer->stop(); -                 -                unsigned tick      = pos[0]; - -                // extend len of last note(s) -                using std::set; -                 -                set<Event*> extend_set; -                EventList* events = curPart->events(); -                for (iEvent i = events->begin(); i != events->end(); ++i) { -                      Event& ev = i->second; -                      if (!ev.isNote()) -                            continue; - -                      if (noteHeldDown[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() + editor->rasterStep(tick)); -                    // Indicate do undo, and do not do port controller values and clone parts.  -                    audio->msgChangeEvent(ev, e, curPart, true, false, false); -                } - -                if (! (globalKeyState & Qt::ShiftModifier)) { -                      chordTimer_setToTick = tick + editor->rasterStep(tick); -                      chordTimer->start(); -                      } -                return; -                -            } -            else // equals if (!held_notes) -            { -              chordTimer->stop(); - -              //simply proceed, inserting a rest -              Pos p(pos[0] + editor->rasterStep(pos[0]), true); -              song->setPos(0, p, true, false, true); -            } -            } +					 steprec->record(curPart,pitch,editor->raster(),editor->raster(),velo,globalKeyState&Qt::ControlModifier,globalKeyState&Qt::ShiftModifier);           }        } -void PianoCanvas::chordTimerTimedOut() -{ -	if (chordTimer_setToTick != song->cpos()) -	{ -		Pos p(chordTimer_setToTick, true); -		song->setPos(0, p, true, false, true); -	} -}  /*  //--------------------------------------------------------- diff --git a/muse2/muse/midiedit/prcanvas.h b/muse2/muse/midiedit/prcanvas.h index c6d84e88..b9da00c6 100644 --- a/muse2/muse/midiedit/prcanvas.h +++ b/muse2/muse/midiedit/prcanvas.h @@ -17,6 +17,8 @@  #include <QDragLeaveEvent>  #include <QTimer> +#include "steprec.h" +  #define KH        13  //--------------------------------------------------------- @@ -41,9 +43,9 @@ class PianoCanvas : public EventCanvas {        int colorMode;        int playedPitch; -      QTimer* chordTimer; -      unsigned chordTimer_setToTick;        bool noteHeldDown[128]; +       +      StepRec* steprec;        Q_OBJECT        virtual void viewMouseDoubleClickEvent(QMouseEvent*); @@ -77,7 +79,6 @@ class PianoCanvas : public EventCanvas {     private slots:        void midiNote(int pitch, int velo); -      void chordTimerTimedOut();     signals:        void quantChanged(int); diff --git a/muse2/muse/steprec.cpp b/muse2/muse/steprec.cpp new file mode 100644 index 00000000..29cb9540 --- /dev/null +++ b/muse2/muse/steprec.cpp @@ -0,0 +1,159 @@ +//========================================================= +//  MusE +//  Linux Music Editor +//  steprec.cpp +//  (C) Copyright 2011 Florian Jung (flo93@users.sourceforge.net) +//========================================================= + +#include "steprec.h" +#include "part.h" +#include "event.h" +#include "globals.h" + +#include "song.h" +#include "audio.h" + +#include <set> + +#define CHORD_TIMEOUT 75 + +StepRec::StepRec(bool* note_held_down_array) +{ +	note_held_down=note_held_down_array; + +	chord_timer=new QTimer(this); +	chord_timer->setSingleShot(true); +	chord_timer->setInterval(CHORD_TIMEOUT); +	chord_timer->stop(); +	connect(chord_timer, SIGNAL(timeout()), SLOT(timeout())); +} + +void StepRec::timeout() +{ +	if (chord_timer_set_to_tick != song->cpos()) +	{ +		Pos p(chord_timer_set_to_tick, true); +		song->setPos(0, p, true, false, true); +	} +} + +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; +                              } +                        } +                  } + +            // +            // 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 (!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 (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 (!shift) { +                      chord_timer_set_to_tick = tick + step; +                      chord_timer->start(); +                      } +                return; +                +            } +            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); +            } +            } +} diff --git a/muse2/muse/steprec.h b/muse2/muse/steprec.h new file mode 100644 index 00000000..b09a9edd --- /dev/null +++ b/muse2/muse/steprec.h @@ -0,0 +1,36 @@ +//========================================================= +//  MusE +//  Linux Music Editor +//  steprec.h +//  (C) Copyright 2011 Florian Jung (flo93@users.sourceforge.net) +//========================================================= + +#ifndef __STEPREC_H__ +#define __STEPREC_H__ + +#include <QObject> +#include <QTimer> + +#include "part.h" + + +class StepRec : public QObject +{ +	Q_OBJECT + +	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); +	 +	private slots: +	  void timeout(); +	 +	private: +		QTimer* chord_timer; +		int chord_timer_set_to_tick; +		bool* note_held_down; +		 +}; + +#endif | 
