-
Notifications
You must be signed in to change notification settings - Fork 136
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
"add/remove" events options added to midi event list class #52
base: master
Are you sure you want to change the base?
Conversation
I will think more about the add function later, particularly if people whine for it... They will have to do a lot more whining to get the remove function, as the MidiMessage::clear() is a sufficient substitution. |
Thanks for catching the memory leak. A couple of questions on add/delete:
As regards performance I wrote a very simple test program to check the add() method by just adding 5000 program changes and 5000 notes to the start of a track: Key part of code is below, I don't think that there's any optimisation going on that wouldn't be seen in more typical usage but I would welcome your comments:
Timings came out as follows. I think that the performance is OK ( PC spec is a 3GHz, i5, 16Gbytes RAM ). I haven't checked the deletes but I don't think that they will be much slower.
|
Yes, but if one of these two cases causes concern, you would run the Also, if you are using a indexed for-loop through the events, deleting a MidiEvent from the list would invalidate the indexing (or you would have to be careful about it), but clearing a message in the list will keep the same indexing of events during the loop. For example, I have already used this new feature to remove all tempo meta-messages from a track in a simple loop:
I am just leaving the MidiEvents that used to be tempo messages in the list, since writing out the MidiFile will ignore them. But I could have run MidiFile::removeEmpties() after the loop as well. I then insert a new tempo marking which gets added to the end of the track, which results in me having to re-sort the track to move the tempo marking to the start of the file... |
Yes, the current system of appending new messages to the end of the track list and then sorting by absolute ticks is not a complete solution. So definitely an insert function should be added to the MidiEventList class. If you are adding content to existing MIDI file rather than creating MIDI files, then inserting would be much safer than appending and then sorting. My initial viewpoint when creating the midifile library was for MIDI file creation and data extraction, not editing and then saving the edited files. I can think of two possibilities which can both be done: (1) adding the function from your PR, although I would call it (1) is a general solution that should work in all situations since it give the best control for the addition of the MidiMessage, so it should, of course, be implemented. It can be abused by a programmer by causing inefficiencies when adding events to the list (the larger the file, the more bytes have to be moved around in memory), but in certain cases it will be the best option (such as for my code example from the previous message). (2) would also solve the problem for most cases for which the current system will have problems. This solution would add an index variable to the MIDI event class. This index would be filled in before sorting, and during sorting this variable would be checked if there is a tie in the timestamp for two MidiMessages that occur at the same time. This would preserve the order of the events at the same time from before the sorting. I would also keep the previous sort method as one option for sorting: midifile/src-library/MidiFile.cpp Lines 2811 to 2872 in ccb93a2
This sorting function tries to sort events occurring at the same time into a reasonable order, such as placing note-offs before note-ons when the pitch is the same. I have come across another case that is not yet handled properly: when a sustain pedal down and sustain pedal up occur at the same time, the up should be placed before the down. I will probably deal with such cases by sorting continuous controller messages by message number and then by data content to handle this cases and probably a few others like it. |
Computers are so fast and MIDI data is small (16 ms for 10000 added messages), so in principle the delete() function is not a problem. It is more of an aesthetic one. Also, if the inserted events are near the end of the list, then this will be more efficient than inserting at the beginning of the list each time. It would be interesting to do a similar test by adding the messages to the end of the list and then sorting. Sorting is |
I see that I have already implemented case 2 in the previous-previous message in the last year or so, which is why it was on my mind... Notice at the end of the midifile/src-library/MidiFile.cpp Line 498 in 82baf1a
The midifile/src-library/MidiEventList.cpp Lines 437 to 457 in 82baf1a
This function stores a sequential serial number in the The midifile/src-library/MidiEventList.cpp Lines 543 to 556 in 732faa3
So when calling midifile/src-library/MidiEventList.cpp Lines 557 to 604 in 732faa3
There still is a need for |
Thanks for the very comprehensive replies. It all seems fine to me, a couple of minor comments:
|
The new options need the index into the events list ( and the new event in the "add" case ). If the operation is successful then the new size of the list is returned otherwise -1 is returned.