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

Feature: Glue notes in Piano-Roll #5482

Closed
wants to merge 10 commits into from
Closed

Feature: Glue notes in Piano-Roll #5482

wants to merge 10 commits into from

Conversation

zonkmachine
Copy link
Member

@zonkmachine zonkmachine commented May 2, 2020

#5216 by CYBERDEViLNL rebased on c755b56 and merge conflict solved.

@LmmsBot
Copy link

LmmsBot commented May 2, 2020

🤖 Hey, I'm @LmmsBot from github.com/lmms/bot and I made downloads for this pull request, click me to make them magically appear! 🎩

Linux

Windows

🤖
{"platform_name_to_artifacts": {"Linux": [{"artifact": {"title": {"title": "(AppImage)", "platform_name": "Linux"}, "link": {"link": "https://8583-15778896-gh.circle-artifacts.com/0/lmms-1.2.2.697-linux-x86_64.AppImage"}}, "build_link": "https://circleci.com/gh/LMMS/lmms/8583?utm_campaign=vcs-integration-link&utm_medium=referral&utm_source=github-build-link"}], "Windows": [{"artifact": {"title": {"title": "32-bit", "platform_name": "Windows"}, "link": {"link": "https://8586-15778896-gh.circle-artifacts.com/0/lmms-1.2.2.697-mingw-win32.exe"}}, "build_link": "https://circleci.com/gh/LMMS/lmms/8586?utm_campaign=vcs-integration-link&utm_medium=referral&utm_source=github-build-link"}, {"artifact": {"title": {"title": "64-bit", "platform_name": "Windows"}, "link": {"link": "https://8584-15778896-gh.circle-artifacts.com/0/lmms-1.2.2.697-mingw-win64.exe"}}, "build_link": "https://circleci.com/gh/LMMS/lmms/8584?utm_campaign=vcs-integration-link&utm_medium=referral&utm_source=github-build-link"}, {"artifact": {"title": {"title": "32-bit", "platform_name": "Windows"}, "link": {"link": "https://ci.appveyor.com/api/buildjobs/rvl9pyn7l7oph3ef/artifacts/build/lmms-1.2.2-msvc2017-win32.exe"}}, "build_link": "https://ci.appveyor.com/project/Lukas-W/lmms/builds/35046280"}, {"artifact": {"title": {"title": "64-bit", "platform_name": "Windows"}, "link": {"link": "https://ci.appveyor.com/api/buildjobs/nlrihueeaua22yif/artifacts/build/lmms-1.2.2-msvc2017-win64.exe"}}, "build_link": "https://ci.appveyor.com/project/Lukas-W/lmms/builds/35046280"}, {"artifact": {"title": {"title": "32-bit", "platform_name": "Windows"}, "link": {"link": "https://ci.appveyor.com/api/buildjobs/oah37bsb653sg31o/artifacts/build/lmms-1.2.2-msvc2017-win32.exe"}}, "build_link": "https://ci.appveyor.com/project/Lukas-W/lmms/builds/35046281"}, {"artifact": {"title": {"title": "64-bit", "platform_name": "Windows"}, "link": {"link": "https://ci.appveyor.com/api/buildjobs/skuktovhgbfajglk/artifacts/build/lmms-1.2.2-msvc2017-win64.exe"}}, "build_link": "https://ci.appveyor.com/project/Lukas-W/lmms/builds/35046281"}]}, "commit_sha": "d86ba8c17d461922e082b5a93c894b6c63506627"}

@zonkmachine
Copy link
Member Author

zonkmachine commented May 26, 2020

I have tested the glue feature and it works well. I think it's good to merge. The original developer has left GitHub and wont be able to respond so If someone wants to fix anything, just push to this branch.

@zonkmachine
Copy link
Member Author

Merge?

@Spekular
Copy link
Member

Spekular commented Jun 13, 2020

Does this work for the following cases? I fail to see how this logic could merge more than two consecutive notes with the loop it currently uses:

image
(Merging three notes on left should result in the note on the right. Ascending sequence above to disambiguate how the notes are stacked)

Something about the buildbot build makes it crash when I open LMMS or I'd test myself.

(EDIT: I misread the loop, I see now that note is only incremented when there are no more overlapping notes, I assumed both note and nextNote were incremented each time)

@zonkmachine
Copy link
Member Author

Does this work for the following cases?

Yes.

Something about the buildbot build makes it crash when I open LMMS or I'd test myself.

I have seen crashes and I've had to launch lmms with a file known to work as an argument to make it launch. Not with this build though.

@zonkmachine
Copy link
Member Author

Oh. It doesn't seem to work well with beat notes though. The result is really inconsistent there.

@zonkmachine
Copy link
Member Author

Yeah, look at the length I managed to create on the first beat note when trying to glue it to a normal one.

<pattern steps="16" type="0" name="Kicker" pos="0" muted="0">
  <note len="-168" key="57" vol="100" pos="12" pan="0"/>
  <note len="-192" key="57" vol="100" pos="108" pan="0"/>
</pattern>

@Spekular
Copy link
Member

Did you merge with an eight note? Beat notes have a length of -192, IIRC, so the math checks out if so (not that it makes this a good result, haha).

I wonder how much effort it would take to make beat notes a subclass of Note so length and endPos could be overriden. Or even simpler, add a boolean (isBeatNote, for example) so they can have positive lengths. Might be out of scope for this PR but they really cause a lot of trouble with the current hacky implementation.

@zonkmachine
Copy link
Member Author

Did you merge with an eight note? Beat notes have a length of -192, IIRC, so the math checks out if so (not that it makes this a good result, haha).

No, more like a whole note.

@zonkmachine
Copy link
Member Author

zonkmachine commented Jun 13, 2020

Oh, dear!

This project
gluetest-02.mmp.zip
gluebug1

<Ctrl> + A
<Shift> + G
gluebug2

Edit: fixed in 587c559

@PhysSong
Copy link
Member

PhysSong commented Jun 25, 2020

I changed the if statement a little bit and was able to get the behavior identical to FL.

diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp
index 30da834df..86cf08c28 100644
--- a/src/gui/editors/PianoRoll.cpp
+++ b/src/gui/editors/PianoRoll.cpp
@@ -703,11 +703,10 @@ void PianoRoll::glueNotes()
 			if ((*note)->key() == (*nextNote)->key()
 				&& (*nextNote)->pos() >= (*note)->pos()
 				&& (*nextNote)->pos() <= (*note)->pos()
-				+ (*note)->length())
+				+ qMax(MidiTime(0), (*note)->length()))
 			{
-				(*note)->setLength((*note)->length() +
-						((*nextNote)->pos() + (*nextNote)->length()) -
-						((*note)->pos() + (*note)->length()));
+				(*note)->setLength(qMax((*note)->length(),
+					MidiTime((*nextNote)->endPos() - (*note)->pos())));
 				noteToRemove.push_back(*nextNote);
 				++nextNote;
 			}

I also suggest gluing all notes if no notes are selected.

@PhysSong
Copy link
Member

I've updated this PR with the changes I suggested.

@zonkmachine
Copy link
Member Author

Fixed a merge conflict.

@zonkmachine
Copy link
Member Author

I've tested this PR again and the only problem I saw earlier was fixed by @PhysSong in 587c559

@zonkmachine
Copy link
Member Author

Merge?

@Spekular
Copy link
Member

Sounds good to me!

Copy link
Contributor

@IanCaio IanCaio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a particular conditional that I believe always return true on the method. I'd understand if it was kept to make the logic more explicit for future readers, but I think a comment would be better suited for that. Besides that, the rest of the code LGTM 👍

{
// key and position match for glue
if ((*note)->key() == (*nextNote)->key()
&& (*nextNote)->pos() >= (*note)->pos()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will that conditional ever be false? Since the notes were previously ordered by key and by pos, if two notes have the same key isn't it always true that the next note will have a position equal or greater than the previous note?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment highlighted all 4 lines, so to make it clearer the conditional I meant is (*nextNote)->pos() >= (*note)->pos() which will be evaluated if the keys are the same on the two notes.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is redundant, but I think there should be a comment which explains what you said.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, what needs to be done here? Remove && (*nextNote)->pos() >= (*note)->pos() and improve the comment?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think just removing that part of the conditional and having the comment explaining that you don't need to check if the next note is after the first because they are ordered already. Removes an unnecessary comparison but leaves an explanation why.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK. Hopefully fixed in d86ba8c

@PhysSong
Copy link
Member

Any ideas how we should deal with per-note pitch automation? Should we ignore it for now?

@IanCaio
Copy link
Contributor

IanCaio commented Aug 17, 2020

Any ideas how we should deal with per-note pitch automation? Should we ignore it for now?

IMHO it could be just removed from any glued note. It's to be expected that pitch automations would be lost in a note glue operation, and removing it we avoid the inconsistency of it being kept if it's in the first note or being removed if it's in the second one. So just removing it altogether sounds like a good idea to me.

Quickly looking at the code I think it has to be done like this?

// While glueing the note
sharedObject::unref( (*note)->detuning() );

Personally, I even think that this sharedObject call should be added to Note.h as a helper method, something like removeDetune(), to make the code less obscure to readers.

@zonkmachine
Copy link
Member Author

Any ideas how we should deal with per-note pitch automation? Should we ignore it for now?

I think we can ignore it for now. The effect of notes with pitch automation in a glue operation isn't hard to predict.

Implement proposed changes by @IanCaio
@zonkmachine
Copy link
Member Author

Now merge? :)

Copy link
Member

@Spekular Spekular left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

Copy link
Contributor

@IanCaio IanCaio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM too!

@zonkmachine zonkmachine mentioned this pull request Oct 18, 2020
@zonkmachine
Copy link
Member Author

Rebased in a separate PR #5721. Closing this one.

@PhysSong PhysSong deleted the glue branch December 19, 2020 03:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants