-
-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Ghost notes for the automation editor #6940
Conversation
Must have feature for anyone who wants to write orchestral music in lmms in any meaningful way. I guess it would be useful for basically everyone. What bothers me here is a rendering, having melody in 1,5 whole tone (C#, D# and E) rendered on entire height of automation editor looks strange. Timing and lenght of notes are right. |
I added a minimum height for scaling, so that notes that are less than 20 key apart are rendered as if they were 20 key apart. This means that close together notes should be rendered correctly. Here is your example: |
This looks much better |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Useful feature! I didn't manage to test it, but code-wise it looks good as far as I could tell. Just left a couple change suggestions.
Co-authored-by: IanCaio <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haven't had the opportunity to test it, but the code LGTM. Approving it with that note so others can test it thoroughly
Done some testing, doesn't encounter bugs in "normal use". Notes intervals properly rendered, notes lenghts properly rendered, melody shape is rendered as it should be, clear button works properly. Also update feature is really nice, I think 'pianoroll ghost notes' should had it added in another PR. |
It works ok, both with regular and time-zero notes. Some thoughts after testing:
|
I think it should be separated, mainly because both had different use cases. Second point, I didn't think about it. What if when user enter detuning mode, active clip become ghost notes? And on exiting detuning mode previous automation ghost notes are restored? |
I'm not sure but I think in the code the detuning simply opens the automation editor with an automation clip that corresponds to the detuning, so there's nothing really signaling that we have entered "detuning mode". There's actually one piece of code that checks whether we are editing detuning by checking if the clip has a track (which is actually kinda wrong, cause there could be other inline automations that are not detuning ig): // Note detuning?
if( m_clip && !m_clip->getTrack() )
{
getGUI()->pianoRoll()->update();
} Because of that, it might require more work to make the ghost notes change to the detuning notes, then change back to the notes it had previously. It's much easier to make it just change automatically to the detuning notes without changing back, so the user would have to set whatever they had before again (it's probably just a couple lines). I'd be fine with that solution for now, and if the OP wants to work further so it changes automatically back then it could be done in a new PR, cause that would require more changes to the automation editor. |
By the way, making it change automatically to the clip being detuned would probably look like this: // src/gui/editors/PianoRoll.cpp - void PianoRoll::mousePressEvent(QMouseEvent* me)
// ...
if( m_editMode == EditMode::Detuning && noteUnderMouse() )
{
static QPointer<AutomationClip> detuningClip = nullptr;
if (detuningClip.data() != nullptr)
{
detuningClip->disconnect(this);
}
Note* n = noteUnderMouse();
if (n->detuning() == nullptr)
{
n->createDetuning();
}
detuningClip = n->detuning()->automationClip();
connect(detuningClip.data(), SIGNAL(dataChanged()), this, SLOT(update()));
getGUI()->automationEditor()->setGhostMidiClip(m_midiClip);
getGUI()->automationEditor()->open(detuningClip);
return;
} Disclaimer: Not tested at all :p |
Not the best solution, but I think that m_editor->m_clip->name() has "Note detuning" as it is used as part of the automation window title. Maybe following this path..... |
That's true, that's better than |
I honestly didn't even know that this feature existed until now. Thanks for all the suggestions, but I ultimately went with a different approach. Instead of using the name to check for detuning, I compare each note that is being detuned with the current ghost clip. If the detuned note is found, This note gets rendered at the start and selected. Here is an example: The only problem with this approach is if you edit a note that is not in the ghost clip, since it then simply shows the clip. This could be fixed by just setting the ghost clip once you start detuning. The scaling is also off when the clip gets rendered, since the automation covers the full keyboard. Maybe I could also change the scaling if you are detuning. Let me know if this is a good solution or if something different would be better. |
I had totally forgot that the detuning would work per note, so having the clip set would not be enough cause of the Offset, nice catch. The solution looks good, you could complement it with the one-liner I posted earlier. Then every time someone started detuning a note the clip would be set automatically. |
I had approved the changes before the detuning was brought up, just sustaining the approval after the last changes. Again, I didn't manage to test it (though I think others have), but code-wise it looks good to me! |
I added additional support for sample tracks, as this was also discussed in #4628. They have the exact same functionality as the ghost notes, and I have noticed no performance issues even with long samples. Could we merge this? It has been finished for a while now with no complaints. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code looks fine. I'm assuming others have tested the feature already?
Edit: Also, could you try resolving the merge conflicts?
I'm testing it right now and it works well. It now has some merge conflict so I suggest I test it some more while @DanielKauss resolves the conflict. |
I have tested it quite a bit, and no one mentioned any issues.
Fixed the conflict. |
Since 6921ce5 the branch wont build with debug flags, [ 99%] Linking CXX executable ../lmms
/usr/bin/ld: CMakeFiles/lmmsobjs.dir/gui/editors/AutomationEditor.cpp.o: in function `lmms::gui::AutomationEditor::paintEvent(QPaintEvent*)':
/home/zonkmachine/builds/lmms/src/gui/editors/AutomationEditor.cpp:1289: undefined reference to `lmms::gui::AutomationEditor::MAX_SAMPLE_HEIGHT'
collect2: error: ld returned 1 exit status
make[2]: *** [src/CMakeFiles/lmms.dir/build.make:628: lmms] Error 1
make[1]: *** [CMakeFiles/Makefile2:2181: src/CMakeFiles/lmms.dir/all] Error 2
make: *** [Makefile:156: all] Error 2 |
I have absolutely 0 idea what caused this. If you put a print before the error line with |
Well that was bizarre. Nice fix. I'm thinking maybe a comment would be a good idea here? |
The reason this succeeds when not building in debug mode is because the compiler inlines |
Ok, makes sense now that you explained it, but I would have never guessed that. Any reason for why we don't just use
Done |
I agree, it's not at all obvious from looking at the code. What clued me in was that it was specifically a linker error, and compilation had succeeded. That meant that the declaration had been found, but the program needed an actual object in the binary for some reason, which did not exist.
You're absolutely right, we should be using |
Merge? |
No objections from me 👍. |
This PR adds the ability to set ghost notes in the automation editor. Closes #4628 and relates to #1959.
It basically mirrors the functionality of the piano roll, except that if you change the midi clip, the automation notes also update, as discussed in #4628.
The vertical scaling is based on the minimum and maximum keys of the clip. The notes are represented only as squares, as I thought it fits better with the style of the editor, however this is subject to change.
This is how it looks at the moment:
If you have any feedback I will take it into account.