-
-
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
Note sorting algorithm rework #3881
Conversation
Note that old patches will open up like before and all will be fine. The next time you edit a track however it will be sorted with the new method and this will probably be only an advantage. Probably. Maybe you like the notes to shift around a bit, and you'll only really notice this in arpeggiated tracks with more than two simultaneous notes and under sort mode. |
Got a random crash. I don't think it's related to this PR though. The project had been running for maybe an hour or so. I was looping two 3osc tracks with an automation track for the Master pitch, two notes detuned in the one track and an LFO detuning the other synth.
|
8db7801
to
7922673
Compare
lmms/src/tracks/InstrumentTrack.cpp Line 543 in 54f3ecc
and it may indicate an invalid reference of iterator occured. |
|
#3879 seems related to this NotePlayHandle race condition. |
This should go into master. I'll switch it over. |
7922673
to
697d375
Compare
697d375
to
ab8db48
Compare
I switched back to stable 1.2 and this is ready for a review. Switching sorting order was a matter of flipping over two 'lesser than' signs and this is now less buggy than before. See the note on backward compatibility here. |
ab8db48
to
8661780
Compare
src/tracks/Pattern.cpp
Outdated
@@ -213,7 +213,7 @@ Note * Pattern::addNote( const Note & _new_note, const bool _quant_pos ) | |||
} | |||
|
|||
instrumentTrack()->lock(); | |||
if( m_notes.size() == 0 || m_notes.back()->pos() <= new_note->pos() ) | |||
if( m_notes.size() == 0 || m_notes.back()->pos() < new_note->pos() ) |
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.
As far as I understand the code, all lines 216 to 245 do is insert the new note at the right position (sorted by the criteria in lessThan
). If so, we can reduce this to a single line:
m_notes.insert(std::upper_bound(m_notes.begin(), m_notes.end(), new_note, Note:lessThan), new_note);
This reduces code complexity, improves performance by doing a binary search, and removes the duplicate compare code by using the lessThan
method.
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.
As far as I understand the code, all lines 216 to 245 do is insert the new note at the right position (sorted by the criteria in lessThan).
Yes indeed. Oneliner, nice but I can't make it work.
Computer says no. 8)
/usr/include/c++/4.8/bits/stl_algo.h: In instantiation of ‘_FIter std::upper_bound(_FIter, _FIter, const _Tp&, _Compare) [with _FIter = Note**; _Tp = Note*; _Compare = bool (*)(Note*&, Note*&)]’:
/home/zonkmachine/builds/lmms/lmms/src/tracks/Pattern.cpp:216:90: required from here
/usr/include/c++/4.8/bits/stl_algo.h:2543:31: error: invalid initialization of reference of type ‘Note*&’ from expression of type ‘Note* const’
if (__comp(__val, *__middle))
^
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.
Ah, you'll have to change Note::lessThan
to take const
pointers:
static inline bool lessThan( const Note * lhs, const Note * rhs )
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.
Perfect, thanks!
8661780
to
81966fa
Compare
I took the opportunity to practice and updated the other sorting function to std::sort() as qSort() is obsolete. Now I think I'm done. The notes are correctly sorted for both functions and there is no code changes needed to save/load the patterns correctly. |
Note sorting algorithm rework
Addresses some of the issues in #3880
Sorting after position and key. Probably only needed with the arpeggiator. This works well and doesn't seem to use a whole lot cpu cycles. The notes are sorted on input from mouse or keyboard in
Pattern::addNote()
. Actions on the notes in the Piano Roll also triggers a sort viaPattern::rearrangeAllNotes()
with a helper function in note.h . The sorting is duplicated when adding notes in the Piano Roll and this has its own post in #3880 but is probably a wontfix.I've pulled these against stable-1.2 but they can just as well go into master or be split over the two.