summaryrefslogtreecommitdiff
path: root/muse2
diff options
context:
space:
mode:
authorFlorian Jung <flo@windfisch.org>2011-05-17 12:37:51 +0000
committerFlorian Jung <flo@windfisch.org>2011-05-17 12:37:51 +0000
commit231ee5b6243fd9ce02ffad93f99ec6055bc40fe0 (patch)
tree36aa7614e97dad6abd69b9a3ec3e710e4bc25efd /muse2
parent35d776fdb75f4e90954b402a883b1fce72de8239 (diff)
implemented change existing note's velocity
Diffstat (limited to 'muse2')
-rw-r--r--muse2/muse/arranger/pcanvas.cpp2
-rw-r--r--muse2/muse/functions.cpp36
-rw-r--r--muse2/muse/functions.h2
-rw-r--r--muse2/muse/midiedit/scoreedit.cpp137
-rw-r--r--muse2/muse/midiedit/scoreedit.h17
-rw-r--r--muse2/muse/song.cpp1
-rw-r--r--muse2/muse/waveedit/waveview.cpp1
7 files changed, 157 insertions, 39 deletions
diff --git a/muse2/muse/arranger/pcanvas.cpp b/muse2/muse/arranger/pcanvas.cpp
index a37e237e..40319d1e 100644
--- a/muse2/muse/arranger/pcanvas.cpp
+++ b/muse2/muse/arranger/pcanvas.cpp
@@ -1714,7 +1714,7 @@ void PartCanvas::drawMidiPart(QPainter& p, const QRect&, EventList* events, Midi
using std::map;
using std::pair;
- iEvent ito(events->lower_bound(to)); //FINDMICH
+ iEvent ito(events->lower_bound(to));
bool isdrum = (mt->type() == Track::DRUM);
int lowest_pitch=127;
diff --git a/muse2/muse/functions.cpp b/muse2/muse/functions.cpp
index e14f32b8..55daee2c 100644
--- a/muse2/muse/functions.cpp
+++ b/muse2/muse/functions.cpp
@@ -197,6 +197,42 @@ void modify_velocity(const set<Part*>& parts, int range, int rate, int offset)
}
}
+void modify_off_velocity(const set<Part*>& parts, int range, int rate, int offset)
+{
+ map<Event*, Part*> events = get_events(parts, range);
+
+ if ( (!events.empty()) && ((rate!=100) || (offset!=0)) )
+ {
+ song->startUndo();
+
+ for (map<Event*, Part*>::iterator it=events.begin(); it!=events.end(); it++)
+ {
+ Event& event=*(it->first);
+ Part* part=it->second;
+
+ int velo = event.veloOff();
+
+ velo = (velo * rate) / 100;
+ velo += offset;
+
+ if (velo <= 0)
+ velo = 1;
+ else if (velo > 127)
+ velo = 127;
+
+ if (event.veloOff() != velo)
+ {
+ Event newEvent = event.clone();
+ newEvent.setVeloOff(velo);
+ // Indicate no undo, and do not do port controller values and clone parts.
+ audio->msgChangeEvent(event, newEvent, part, false, false, false);
+ }
+ }
+
+ song->endUndo(SC_EVENT_MODIFIED);
+ }
+}
+
void modify_notelen(const set<Part*>& parts, int range, int rate, int offset)
{
map<Event*, Part*> events = get_events(parts, range);
diff --git a/muse2/muse/functions.h b/muse2/muse/functions.h
index 14797a15..9477767a 100644
--- a/muse2/muse/functions.h
+++ b/muse2/muse/functions.h
@@ -34,9 +34,11 @@ void init_function_dialogs(QWidget* parent);
std::set<Part*> partlist_to_set(PartList* pl);
+std::map<Event*, Part*> get_events(const std::set<Part*>& parts, int range);
//these functions simply do their job, non-interactively
void modify_velocity(const std::set<Part*>& parts, int range, int rate, int offset=0);
+void modify_off_velocity(const std::set<Part*>& parts, int range, int rate, int offset=0);
void modify_notelen(const std::set<Part*>& parts, int range, int rate, int offset=0);
void quantize_notes(const std::set<Part*>& parts, int range, int raster, int strength=100, int swing=0, int threshold=0);
void erase_notes(const std::set<Part*>& parts, int range);
diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp
index 29cf32e4..01b69e90 100644
--- a/muse2/muse/midiedit/scoreedit.cpp
+++ b/muse2/muse/midiedit/scoreedit.cpp
@@ -68,7 +68,8 @@ QString IntToQStr(int i);
-
+#define APPLY_TO_SELECTED_STRING tr("Apply to selected notes:")
+#define APPLY_TO_NEW_STRING tr("Apply to new notes:")
//PIXELS_PER_NOTEPOS must be greater or equal to 3*NOTE_XLEN + 2*NOTE_SHIFT
@@ -166,7 +167,7 @@ ScoreEdit::ScoreEdit(QWidget* parent, const char* name, unsigned initPos)
setCentralWidget(mainw);
-
+ apply_velo=false;
score_canvas=new ScoreCanvas(this, mainw, 1, 1);
@@ -220,17 +221,18 @@ ScoreEdit::ScoreEdit(QWidget* parent, const char* name, unsigned initPos)
addToolBarBreak();
- QToolBar* newnote_toolbar = addToolBar(tr("New note settings"));
- newnote_toolbar->setObjectName("New note settings");
- newnote_toolbar->addWidget(new QLabel(tr("Note length:"), newnote_toolbar));
+ QToolBar* note_settings_toolbar = addToolBar(tr("Note settings"));
+ //don't change that name, or you will lose toolbar settings
+ note_settings_toolbar->setObjectName("New note settings");
+ note_settings_toolbar->addWidget(new QLabel(tr("Note length:"), note_settings_toolbar));
len_actions=new QActionGroup(this);
- n1_action = newnote_toolbar->addAction("1", menu_mapper, SLOT(map()));
- n2_action = newnote_toolbar->addAction("2", menu_mapper, SLOT(map()));
- n4_action = newnote_toolbar->addAction("4", menu_mapper, SLOT(map()));
- n8_action = newnote_toolbar->addAction("8", menu_mapper, SLOT(map()));
- n16_action = newnote_toolbar->addAction("16", menu_mapper, SLOT(map()));
- n32_action = newnote_toolbar->addAction("32", menu_mapper, SLOT(map()));
- nlast_action = newnote_toolbar->addAction(tr("last"), menu_mapper, SLOT(map()));
+ n1_action = note_settings_toolbar->addAction("1", menu_mapper, SLOT(map()));
+ n2_action = note_settings_toolbar->addAction("2", menu_mapper, SLOT(map()));
+ n4_action = note_settings_toolbar->addAction("4", menu_mapper, SLOT(map()));
+ n8_action = note_settings_toolbar->addAction("8", menu_mapper, SLOT(map()));
+ n16_action = note_settings_toolbar->addAction("16", menu_mapper, SLOT(map()));
+ n32_action = note_settings_toolbar->addAction("32", menu_mapper, SLOT(map()));
+ nlast_action = note_settings_toolbar->addAction(tr("last"), menu_mapper, SLOT(map()));
menu_mapper->setMapping(n1_action, CMD_NOTELEN_1);
menu_mapper->setMapping(n2_action, CMD_NOTELEN_2);
menu_mapper->setMapping(n4_action, CMD_NOTELEN_4);
@@ -256,22 +258,37 @@ ScoreEdit::ScoreEdit(QWidget* parent, const char* name, unsigned initPos)
nlast_action->setChecked(true);
menu_command(CMD_NOTELEN_LAST);
- newnote_toolbar->addSeparator();
+ note_settings_toolbar->addSeparator();
+
+ apply_velo_to_label = new QLabel(APPLY_TO_NEW_STRING, note_settings_toolbar);
+ int w1 = apply_velo_to_label->fontMetrics().width(APPLY_TO_NEW_STRING);
+ int w2 = apply_velo_to_label->fontMetrics().width(APPLY_TO_SELECTED_STRING);
+ if (w1>w2)
+ apply_velo_to_label->setFixedWidth(w1+5);
+ else
+ apply_velo_to_label->setFixedWidth(w2+5);
- newnote_toolbar->addWidget(new QLabel(tr("Velocity:"), newnote_toolbar));
+ note_settings_toolbar->addWidget(apply_velo_to_label);
+ note_settings_toolbar->addWidget(new QLabel(tr("Velocity:"), note_settings_toolbar));
velo_spinbox = new QSpinBox(this);
velo_spinbox->setRange(0, 127);
velo_spinbox->setSingleStep(1);
- connect(velo_spinbox, SIGNAL(valueChanged(int)), score_canvas, SLOT(set_newnote_velo(int)));
- newnote_toolbar->addWidget(velo_spinbox);
+ //we do not use the valueChanged signal, because that would generate
+ //many many undos when using the spin buttons.
+ connect(velo_spinbox, SIGNAL(editingFinished()), SLOT(velo_box_changed()));
+ connect(this,SIGNAL(velo_changed(int)), score_canvas, SLOT(set_velo(int)));
+ note_settings_toolbar->addWidget(velo_spinbox);
velo_spinbox->setValue(64);
- newnote_toolbar->addWidget(new QLabel(tr("Off-Velocity:"), newnote_toolbar));
+ note_settings_toolbar->addWidget(new QLabel(tr("Off-Velocity:"), note_settings_toolbar));
velo_off_spinbox = new QSpinBox(this);
velo_off_spinbox->setRange(0, 127);
velo_off_spinbox->setSingleStep(1);
- connect(velo_off_spinbox, SIGNAL(valueChanged(int)), score_canvas, SLOT(set_newnote_velo_off(int)));
- newnote_toolbar->addWidget(velo_off_spinbox);
+ //we do not use the valueChanged signal, because that would generate
+ //many many undos when using the spin buttons.
+ connect(velo_off_spinbox, SIGNAL(editingFinished()), SLOT(velo_off_box_changed()));
+ connect(this,SIGNAL(velo_off_changed(int)), score_canvas, SLOT(set_velo_off(int)));
+ note_settings_toolbar->addWidget(velo_off_spinbox);
velo_off_spinbox->setValue(64);
@@ -347,7 +364,8 @@ ScoreEdit::ScoreEdit(QWidget* parent, const char* name, unsigned initPos)
if (!default_toolbar_state.isEmpty())
restoreState(default_toolbar_state);
-
+
+ connect(song, SIGNAL(songChanged(int)), SLOT(song_changed(int)));
score_canvas->fully_recalculate();
score_canvas->goto_tick(initPos,true);
@@ -356,6 +374,9 @@ ScoreEdit::ScoreEdit(QWidget* parent, const char* name, unsigned initPos)
set_name(name, false, true);
else
init_name();
+
+
+ apply_velo=true;
}
void ScoreEdit::add_parts(PartList* pl, bool all_in_one)
@@ -415,6 +436,46 @@ ScoreEdit::~ScoreEdit()
}
+void ScoreEdit::velo_box_changed()
+{
+ emit velo_changed(velo_spinbox->value());
+}
+
+void ScoreEdit::velo_off_box_changed()
+{
+ emit velo_off_changed(velo_off_spinbox->value());
+}
+
+void ScoreEdit::song_changed(int flags)
+{
+ if (flags & (SC_SELECTION | SC_EVENT_MODIFIED | SC_EVENT_REMOVED))
+ {
+ map<Event*, Part*> selection=get_events(score_canvas->get_all_parts(),1);
+ if (selection.empty())
+ {
+ apply_velo_to_label->setText(APPLY_TO_NEW_STRING);
+ }
+ else
+ {
+ apply_velo_to_label->setText(APPLY_TO_SELECTED_STRING);
+
+ int velo=-1;
+ int velo_off=-1;
+ for (map<Event*, Part*>::iterator it=selection.begin(); it!=selection.end(); it++)
+ if (it->first->type()==Note)
+ {
+ if (velo==-1) velo=it->first->velo();
+ else if ((velo>=0) && (velo!=it->first->velo())) velo=-2;
+
+ if (velo_off==-1) velo_off=it->first->veloOff();
+ else if ((velo_off>=0) && (velo_off!=it->first->veloOff())) velo_off=-2;
+ }
+
+ if (velo>=0) velo_spinbox->setValue(velo);
+ if (velo_off>=0) velo_off_spinbox->setValue(velo_off);
+ }
+ }
+}
void ScoreEdit::canvas_width_changed(int width)
{
@@ -700,6 +761,9 @@ void ScoreCanvas::write_staves(int level, Xml& xml) const
void ScoreEdit::readStatus(Xml& xml)
{
+ bool apply_velo_temp=apply_velo;
+ apply_velo=false;
+
for (;;)
{
Xml::Token token = xml.parse();
@@ -788,6 +852,7 @@ void ScoreEdit::readStatus(Xml& xml)
break;
}
}
+ apply_velo=apply_velo_temp;
}
void ScoreEdit::read_configuration(Xml& xml)
@@ -911,7 +976,7 @@ ScoreCanvas::ScoreCanvas(ScoreEdit* pr, QWidget* parent_widget,
undo_started=false;
undo_flags=0;
-
+
selected_part=NULL;
last_len=384;
@@ -922,8 +987,8 @@ ScoreCanvas::ScoreCanvas(ScoreEdit* pr, QWidget* parent_widget,
//called again. but for safety...
set_pixels_per_whole(300); //same as above. but safety rocks
- set_newnote_velo(64);
- set_newnote_velo_off(64);
+ set_velo(64);
+ set_velo_off(64);
dragging_staff=false;
@@ -3393,8 +3458,8 @@ void ScoreCanvas::mousePressEvent (QMouseEvent* event)
Event newevent(Note);
newevent.setPitch(y_to_pitch(y,tick, staff_it->clef));
- newevent.setVelo(newnote_velo);
- newevent.setVeloOff(newnote_velo_off);
+ newevent.setVelo(note_velo);
+ newevent.setVeloOff(note_velo_off);
newevent.setTick(relative_tick);
newevent.setLenTick((new_len>0)?new_len:last_len);
newevent.setSelected(true);
@@ -3442,6 +3507,9 @@ void ScoreCanvas::mousePressEvent (QMouseEvent* event)
}
}
}
+
+ if (event->button()==Qt::LeftButton)
+ song->update(SC_SELECTION);
}
void ScoreCanvas::mouseReleaseEvent (QMouseEvent* event)
@@ -4010,14 +4078,20 @@ void ScoreCanvas::maybe_close_if_empty()
}
}
-void ScoreCanvas::set_newnote_velo(int velo)
+void ScoreCanvas::set_velo(int velo)
{
- newnote_velo=velo;
+ note_velo=velo;
+
+ if (parent->get_apply_velo())
+ modify_velocity(get_all_parts(),1, 0,velo);
}
-void ScoreCanvas::set_newnote_velo_off(int velo)
+void ScoreCanvas::set_velo_off(int velo)
{
- newnote_velo_off=velo;
+ note_velo_off=velo;
+
+ if (parent->get_apply_velo())
+ modify_off_velocity(get_all_parts(),1, 0,velo);
}
void ScoreCanvas::deselect_all()
@@ -4125,7 +4199,7 @@ void staff_t::apply_lasso(QRect rect, set<Event*>& already_processed)
* between, for example, when a cis is tied to a des
*
* CURRENT TODO
- * o let the user change velocity of already existent notes
+ * x nothing atm
*
* IMPORTANT TODO
* o add a select-clef-toolbox for tracks
@@ -4135,6 +4209,7 @@ void staff_t::apply_lasso(QRect rect, set<Event*>& already_processed)
* o support edge-scrolling when opening a lasso
*
* less important stuff
+ * o add functions like crescendo, set velo, mod/set velo-off
* o deal with expanding parts
* o use bars instead of flags over groups of 8ths / 16ths etc
* o support different keys in different tracks at the same time
@@ -4168,7 +4243,6 @@ void staff_t::apply_lasso(QRect rect, set<Event*>& already_processed)
* GUI stuff
* o velocity/release-velo for already existing notes
* - do this by right-click -> some dialog shows up?
- * - or by selecting the note and changing the values in the same widget which also is used for new notes?
* - or by controller graphs, as used by the piano roll
*/
@@ -4220,4 +4294,3 @@ void staff_t::apply_lasso(QRect rect, set<Event*>& already_processed)
* REASON: this is only a nice-to-have, which can however be
* easily implemented when 4) is done
*/
-
diff --git a/muse2/muse/midiedit/scoreedit.h b/muse2/muse/midiedit/scoreedit.h
index 91d399e6..bdffd7b4 100644
--- a/muse2/muse/midiedit/scoreedit.h
+++ b/muse2/muse/midiedit/scoreedit.h
@@ -110,6 +110,9 @@ class ScoreEdit : public TopWin
QScrollBar* yscroll;
ScoreCanvas* score_canvas;
+ QLabel* apply_velo_to_label;
+ bool apply_velo;
+
static set<QString> names;
static int width_init, height_init;
static QByteArray default_toolbar_state;
@@ -122,16 +125,21 @@ class ScoreEdit : public TopWin
private slots:
void menu_command(int);
+ void velo_box_changed();
+ void velo_off_box_changed();
signals:
void deleted(unsigned long);
void name_changed();
+ void velo_changed(int);
+ void velo_off_changed(int);
public slots:
void canvas_width_changed(int);
void viewport_width_changed(int);
void canvas_height_changed(int);
void viewport_height_changed(int);
+ void song_changed(int);
public:
ScoreEdit(QWidget* parent = 0, const char* name = 0, unsigned initPos = MAXINT);
@@ -144,6 +152,7 @@ class ScoreEdit : public TopWin
void add_parts(PartList* pl, bool all_in_one=false);
QString get_name() { return name; }
+ bool get_apply_velo() { return apply_velo; }
};
@@ -601,8 +610,8 @@ class ScoreCanvas : public View
int _quant_power2;
int _pixels_per_whole;
- int newnote_velo;
- int newnote_velo_off;
+ int note_velo;
+ int note_velo_off;
std::map<int,int> pos_add_list;
@@ -705,8 +714,8 @@ class ScoreCanvas : public View
void preamble_timesig_slot(bool);
void set_pixels_per_whole(int);
- void set_newnote_velo(int);
- void set_newnote_velo_off(int);
+ void set_velo(int);
+ void set_velo_off(int);
signals:
void xscroll_changed(int);
diff --git a/muse2/muse/song.cpp b/muse2/muse/song.cpp
index e6fa9cab..1c451f55 100644
--- a/muse2/muse/song.cpp
+++ b/muse2/muse/song.cpp
@@ -3769,7 +3769,6 @@ void Song::executeScript(const char* scriptfile, PartList* parts, int quant, boo
QStringList sl = line.split(" ");
Event e(Controller);
- int tick = sl[1].toInt();
int a = sl[2].toInt();
int b = sl[3].toInt();
int c = sl[4].toInt();
diff --git a/muse2/muse/waveedit/waveview.cpp b/muse2/muse/waveedit/waveview.cpp
index 0c387f72..1c7f74f2 100644
--- a/muse2/muse/waveedit/waveview.cpp
+++ b/muse2/muse/waveedit/waveview.cpp
@@ -392,7 +392,6 @@ void WaveView::wheelEvent(QWheelEvent* ev)
int keyState = ev->modifiers();
bool shift = keyState & Qt::ShiftModifier;
- bool alt = keyState & Qt::AltModifier;
bool ctrl = keyState & Qt::ControlModifier;
if (shift) { // scroll vertically