Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix #304906 Update Piano Levels Filter to shift to the new Fraction based note measurement system #6043

Merged
merged 1 commit into from
May 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions libmscore/duration.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class DurationElement : public Element {

Fraction actualTicks() const;

//Length expressed as a fraction of a whole note
virtual Fraction ticks() const { return _duration; }
Fraction globalTicks() const;
void setTicks(const Fraction& f) { _duration = f; }
Expand Down
12 changes: 9 additions & 3 deletions libmscore/fraction.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,20 +188,26 @@ class Fraction {
return *this;
}

#if 0

Fraction& operator/=(int val)
{
_denominator *= val;
if (_denominator < 0) {
blackears marked this conversation as resolved.
Show resolved Hide resolved
_denominator = -_denominator;
_numerator = -_numerator;
}
reduce();
return *this;
}
#endif



Fraction operator+(const Fraction& v) const { return Fraction(*this) += v; }
Fraction operator-(const Fraction& v) const { return Fraction(*this) -= v; }
Fraction operator-() const { return Fraction(-_numerator, _denominator); }
Fraction operator*(const Fraction& v) const { return Fraction(*this) *= v; }
Fraction operator/(const Fraction& v) const { return Fraction(*this) /= v; }
// Fraction operator/(int v) const { return Fraction(*this) /= v; }
Fraction operator/(int v) const { return Fraction(*this) /= v; }


//---------------------------------------------------------
Expand Down
9 changes: 3 additions & 6 deletions mscore/pianoroll/pianolevels.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,9 +183,6 @@ void PianoLevels::paintEvent(QPaintEvent* e)
//Round down to first bar to be a multiple of barSkip
bar1 = (bar1 / barSkip) * barSkip;

// int subExp = qMin((int)floor(log2(pixPerBeat / minBeatGap)), _subBeats);
// int numSubBeats = pow(2, subExp);

for (int bar = bar1; bar <= bar2; bar += barSkip) {
Pos stick(_score->tempomap(), _score->sigmap(), bar, 0, 0);

Expand Down Expand Up @@ -222,13 +219,13 @@ void PianoLevels::paintEvent(QPaintEvent* e)
//draw horiz lines
PianoLevelsFilter* filter = PianoLevelsFilter::FILTER_LIST[_levelsIndex];

QFont f("FreeSans", 7);
p.setFont(f);

int div = filter->divisionGap();
int minGuide = (int)floor(filter->minRange() / (qreal)div);
int maxGuide = (int)ceil(filter->maxRange() / (qreal)div);

QFont f("FreeSans", 7);
p.setFont(f);

for (int i = minGuide; i <= maxGuide; ++i) {
p.setPen(i == 0 || i == minGuide || i == maxGuide ? penLineMajor : penLineMinor);

Expand Down
44 changes: 38 additions & 6 deletions mscore/pianoroll/pianolevelschooser.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "pianolevelschooser.h"
#include "pianolevelsfilter.h"
#include "pianoview.h"

#include "libmscore/score.h"

Expand All @@ -11,7 +12,7 @@ namespace Ms {

PianoLevelsChooser::PianoLevelsChooser(QWidget *parent)
: QWidget(parent)
{
{
setupUi(this);

_levelsIndex = 0;
Expand All @@ -24,24 +25,55 @@ PianoLevelsChooser::PianoLevelsChooser(QWidget *parent)

connect(levelsCombo, SIGNAL(activated(int)), SLOT(setLevelsIndex(int)));
connect(setEventsBn, SIGNAL(clicked(bool)), SLOT(setEventDataPressed()));
}
}

//---------------------------------------------------------
// setPianoView
//---------------------------------------------------------

void PianoLevelsChooser::setPianoView(PianoView* pianoView)
{
_pianoView = pianoView;
}

//---------------------------------------------------------
// PianoLevelsChooser
// updateSetboxValue
//---------------------------------------------------------

void PianoLevelsChooser::updateSetboxValue()
blackears marked this conversation as resolved.
Show resolved Hide resolved
{
QList<PianoItem*> items = _pianoView->getSelectedItems();

if (items.size() == 1) {
PianoLevelsFilter* filter = PianoLevelsFilter::FILTER_LIST[_levelsIndex];

PianoItem* item = items[0];
Note* note = item->note();

NoteEvent* event = item->getTweakNoteEvent();
int value = filter->value(_staff, note, event);
eventValSpinBox->setValue(value);
}

}


//---------------------------------------------------------
// setLevelsIndex
//---------------------------------------------------------

void PianoLevelsChooser::setLevelsIndex(int index)
{
{
if (_levelsIndex != index) {
_levelsIndex = index;
updateSetboxValue();
emit levelsIndexChanged(index);
}
}
}


//---------------------------------------------------------
// PianoLevelsChooser
// setEventDataPressed
//---------------------------------------------------------

void PianoLevelsChooser::setEventDataPressed()
Expand Down
4 changes: 4 additions & 0 deletions mscore/pianoroll/pianolevelschooser.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

namespace Ms {

class PianoView;

//---------------------------------------------------------
// PianoLevelsChooser
Expand All @@ -37,16 +38,19 @@ class PianoLevelsChooser : public QWidget, public Ui::PianoLevelsChooser

int _levelsIndex;
Staff* _staff;
PianoView* _pianoView = nullptr;

public:
Staff* staff() { return _staff; }
void setStaff(Staff* staff) { _staff = staff; }
void setPianoView(PianoView* pianoView);

signals:
void levelsIndexChanged(int);
void notesChanged();

public slots:
void updateSetboxValue();
void setLevelsIndex(int index);
void setEventDataPressed();

Expand Down
74 changes: 29 additions & 45 deletions mscore/pianoroll/pianolevelsfilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,29 @@
namespace Ms {


static const char* STRN_NOTE_ON_NAME = QT_TRANSLATE_NOOP("PianoLevelsFilter", "Note start time");
static const char* STRN_NOTE_ON_TT = QT_TRANSLATE_NOOP("PianoLevelsFilter", "Add (or subtract) a bit to the start time of a note");
static const char* STRN_NOTE_ON_NAME = QT_TRANSLATE_NOOP("PianoLevelsFilter", "Position");
static const char* STRN_NOTE_ON_TT = QT_TRANSLATE_NOOP("PianoLevelsFilter", "Move the selected note(s) forward or backward by thousandths of the full note duration");

static const char* STRN_LEN_MUL_NAME = QT_TRANSLATE_NOOP("PianoLevelsFilter", "Length (multiplier)");
static const char* STRN_LEN_MUL_TT = QT_TRANSLATE_NOOP("PianoLevelsFilter", "Multiply the note length by a bit");
static const char* STRN_LEN_MUL_NAME = QT_TRANSLATE_NOOP("PianoLevelsFilter", "Duration (multiplier)");
static const char* STRN_LEN_MUL_TT = QT_TRANSLATE_NOOP("PianoLevelsFilter", "Multiply the duration by thousandths of the full note duration");

static const char* STRN_LEN_OFF_NAME = QT_TRANSLATE_NOOP("PianoLevelsFilter", "Length (offset)");
static const char* STRN_LEN_OFF_TT = QT_TRANSLATE_NOOP("PianoLevelsFilter", "Add (or subtract) a bit from the end of the note");
static const char* STRN_LEN_OFF_NAME = QT_TRANSLATE_NOOP("PianoLevelsFilter", "Duration");
static const char* STRN_LEN_OFF_TT = QT_TRANSLATE_NOOP("PianoLevelsFilter", "Shorten or lengthen by thousandths of a whole note");

static const char* STRN_VEL_DYN_NAME = QT_TRANSLATE_NOOP("PianoLevelsFilter", "Velocity (relative)");
static const char* STRN_VEL_DYN_TT = QT_TRANSLATE_NOOP("PianoLevelsFilter", "Raise or lower loudness relative to current dynamics value");
static const char* STRN_VEL_DYN_TT = QT_TRANSLATE_NOOP("PianoLevelsFilter", "Increase or decrease the velocity by the specified value");

static const char* STRN_VEL_ABS_NAME = QT_TRANSLATE_NOOP("PianoLevelsFilter", "Velocity (absolute)");
static const char* STRN_VEL_ABS_TT = QT_TRANSLATE_NOOP("PianoLevelsFilter", "Ignore dynamic markings and use this as the MIDI output value");
static const char* STRN_VEL_ABS_TT = QT_TRANSLATE_NOOP("PianoLevelsFilter", "Ignore dynamic markings and set the velocity directly");


PianoLevelsFilter* PianoLevelsFilter::FILTER_LIST[] = {
new PianoLevelFilterLen,
new PianoLevelFilterLenOfftime,
new PianoLevelFilterLenWholenote,
new PianoLevelFilterLenMultiplier,
new PianoLevelFilterVeloOffset,
new PianoLevelFilterVeloUser,
new PianoLevelFilterOnTime,
0 //end of list indicator
nullptr //end of list indicator
};

//---------------------------------------------------------
Expand Down Expand Up @@ -82,7 +82,7 @@ void PianoLevelFilterOnTime::setValue(Staff* staff, Note* note, NoteEvent* evt,
// name
//---------------------------------------------------------

QString PianoLevelFilterLen::name()
QString PianoLevelFilterLenMultiplier::name()
{
return qApp->translate("PianoLevelsFilter", STRN_LEN_MUL_NAME);
}
Expand All @@ -91,7 +91,7 @@ QString PianoLevelFilterLen::name()
// tooltip
//---------------------------------------------------------

QString PianoLevelFilterLen::tooltip()
QString PianoLevelFilterLenMultiplier::tooltip()
{
return qApp->translate("PianoLevelsFilter", STRN_LEN_MUL_TT);
}
Expand All @@ -100,7 +100,7 @@ QString PianoLevelFilterLen::tooltip()
// value
//---------------------------------------------------------

int PianoLevelFilterLen::value(Staff* /*staff*/, Note* /*note*/, NoteEvent* evt)
int PianoLevelFilterLenMultiplier::value(Staff* /*staff*/, Note* /*note*/, NoteEvent* evt)
{
return evt->len();
}
Expand All @@ -109,7 +109,7 @@ int PianoLevelFilterLen::value(Staff* /*staff*/, Note* /*note*/, NoteEvent* evt)
// setValue
//---------------------------------------------------------

void PianoLevelFilterLen::setValue(Staff* staff, Note* note, NoteEvent* evt, int value)
void PianoLevelFilterLenMultiplier::setValue(Staff* staff, Note* note, NoteEvent* evt, int value)
{
Score* score = staff->score();

Expand All @@ -126,7 +126,7 @@ void PianoLevelFilterLen::setValue(Staff* staff, Note* note, NoteEvent* evt, int
// name
//---------------------------------------------------------

QString PianoLevelFilterLenOfftime::name()
QString PianoLevelFilterLenWholenote::name()
{
return qApp->translate("PianoLevelsFilter", STRN_LEN_OFF_NAME);
}
Expand All @@ -135,59 +135,43 @@ QString PianoLevelFilterLenOfftime::name()
// tooltip
//---------------------------------------------------------

QString PianoLevelFilterLenOfftime::tooltip()
QString PianoLevelFilterLenWholenote::tooltip()
{
return qApp->translate("PianoLevelsFilter", STRN_LEN_OFF_TT);
}

//---------------------------------------------------------
// maxRange
//---------------------------------------------------------

int PianoLevelFilterLenOfftime::maxRange()
{
return MScore::division;
}

//---------------------------------------------------------
// divisionGap
//---------------------------------------------------------

int PianoLevelFilterLenOfftime::divisionGap()
{
return MScore::division / 4;
}


//---------------------------------------------------------
// value
//---------------------------------------------------------

int PianoLevelFilterLenOfftime::value(Staff* /*staff*/, Note* note, NoteEvent* evt)
int PianoLevelFilterLenWholenote::value(Staff* /*staff*/, Note* note, NoteEvent* evt)
{
Chord* chord = note->chord();
int ticks = chord->ticks().ticks();
int gate = evt->len();
int offTicks = ticks - (ticks * gate / 1000);
Fraction noteLen = chord->ticks();
int evtLen = evt->len();
Fraction offsetLen = noteLen - (noteLen * evtLen / 1000);

return offTicks;
return -offsetLen.numerator() * 1000 / offsetLen.denominator();
}

//---------------------------------------------------------
// setValue
//---------------------------------------------------------

void PianoLevelFilterLenOfftime::setValue(Staff* staff, Note* note, NoteEvent* evt, int value)
void PianoLevelFilterLenWholenote::setValue(Staff* staff, Note* note, NoteEvent* evt, int value)
{
Chord* chord = note->chord();
int ticks = chord->ticks().ticks();
int onTicks = qMax(ticks - value, 1);
int gate = 1000 * onTicks / ticks;
Fraction noteLen = chord->ticks();
Fraction cutLen(-value, 1000);
Fraction playLen = noteLen - cutLen;
Fraction evtLenFrac = playLen / noteLen;
int evtLen = qMax(evtLenFrac.numerator() * 1000 / evtLenFrac.denominator(), 1);

Score* score = staff->score();

NoteEvent ne = *evt;
ne.setLen(gate);
ne.setLen(evtLen);

score->startCmd();
score->undo(new ChangeNoteEvent(note, evt, ne));
Expand Down
10 changes: 5 additions & 5 deletions mscore/pianoroll/pianolevelsfilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class PianoLevelFilterOnTime : public PianoLevelsFilter {
//---------------------------------------------------------


class PianoLevelFilterLen : public PianoLevelsFilter {
class PianoLevelFilterLenMultiplier : public PianoLevelsFilter {
Q_DECLARE_TR_FUNCTIONS(PianoLevelFilterLen)

public:
Expand All @@ -92,15 +92,15 @@ class PianoLevelFilterLen : public PianoLevelsFilter {
//---------------------------------------------------------


class PianoLevelFilterLenOfftime : public PianoLevelsFilter {
class PianoLevelFilterLenWholenote : public PianoLevelsFilter {
Q_DECLARE_TR_FUNCTIONS(PianoLevelFilterLenOfftime)

public:
QString name() override;
QString tooltip() override;
int maxRange() override;
int minRange() override { return 0; }
int divisionGap() override;
int maxRange() override { return 1000; }
int minRange() override { return -1000; }
int divisionGap() override { return 1000 / 4; }
bool isPerEvent() override { return true; }
int value(Staff* staff, Note* note, NoteEvent* evt) override;
void setValue(Staff* staff, Note* note, NoteEvent* evt, int value) override;
Expand Down
2 changes: 2 additions & 0 deletions mscore/pianoroll/pianoroll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ PianorollEditor::PianorollEditor(QWidget* parent)

// levels area
pianoLevelsChooser = new PianoLevelsChooser;
pianoLevelsChooser->setPianoView(pianoView);
pianoLevelsChooser->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
pianoLevelsChooser->setFixedWidth(PIANO_KEYBOARD_WIDTH);

Expand Down Expand Up @@ -692,6 +693,7 @@ void PianorollEditor::updateSelection()
veloType->setEnabled(enabled);
onTime->setEnabled(enabled);
tickLen->setEnabled(enabled);
pianoLevelsChooser->updateSetboxValue();
}

//---------------------------------------------------------
Expand Down