MidiWriterJS icon indicating copy to clipboard operation
MidiWriterJS copied to clipboard

Place EndTrackEvent at a particular tick

Open chr15m opened this issue 4 years ago • 9 comments

Thank you for MidiWriterJS, it's fantastic! I'm creating short MIDI loops with it. At the moment if my last note is somewhere in the middle of a loop, the midi track is shorter than it should be. Here's an example of a loop that falls short of the end of the bar:

screenshot

To mitigate this I am placing a note with {duration: "T1", pitch: 0, velocity 0, startTick: (looplength - 1)} which seems to work:

screenshot

It feels like a bit of a hack. I wonder if there should be a way to tell MidiWriterJS that the track should end at a particular tick?

Thanks so much for this library.

chr15m avatar Sep 10 '21 13:09 chr15m

i was thinking a little bit about this, wouldn't fit better in MidiWriterJS a way to autofill emtpy measures? what do you think about this? At the moment I really do not have ideas on how the api could look like, but seems a good idea to me.

It could be the default behaviour of NoteEvent rather than an optional parameter.

thanks

lplume avatar Sep 11 '21 11:09 lplume

Hey @chr15m thanks for your message! I can see what you mean.

@lplume, yea auto-padding a track to the end of the measure would probably be a good default behavior. I wonder if it would also be useful to have aTrack.length property which could override it. Could potentially provide more granular adjustments down to the tick.

I'll take a look shortly and see what we can do.

grimmdude avatar Sep 11 '21 15:09 grimmdude

feel free to ping me again about this or other things, i'd like to code again on midiwriterjs!

lplume avatar Sep 11 '21 15:09 lplume

@lplume awesome, feel free to tackle this one if you like!

grimmdude avatar Sep 11 '21 15:09 grimmdude

@grimmdude @lplume Yeah, this feature is very needed! I'm using MidiWriter to create small midi loops and the same issue arises. Adding a silent note helps, but it's somewhat dirty, especially when imported into the DAW.

davay42 avatar Oct 27 '21 17:10 davay42

a little busy lately, still thinking about this and could be tricky to "automagically" detect when to pad the measure length if needed. Keeping in mind the time signature and how the note-event works. @davay42 since you notice this as well, how do you think midiwriter should behave? Could you give a few examples based on your use cases in the form of "I have to do this [code example]" and how do you think it should be [code example]? That would be very useful. Also @chr15m at the moment do you experience to "hacky" the filling of the track with a 0-pitch note only at the end of it? And of course @grimmdude any thoughts about this? I'm not sure if the feature request it's about filling the last measure only or something more

[edit] im just wondering how the "autofill" should work: should it consider to fill to track lenght only? should it fill every measures if needed? only the last one? Also, yes, the issue clearly mention end track event, am i just wondering a little bit too much ^^'? [/edit]

thanks

lplume avatar Nov 04 '21 01:11 lplume

@lplume yes padding with an empty note feels hacky. Ideally there would be a way to situate the end-track even directly at the time where the user wants it but I don't know if the MIDI format supports this. I note it is possible elsewhere in the API to situate events at specific time points though so it seems like it should be possible.

chr15m avatar Nov 04 '21 02:11 chr15m

@lplume I think just the ability to set the end-of-track event manually at a certain time would be enough for the purpose.

davay42 avatar Nov 04 '21 07:11 davay42

@lplume Interestingly Garage band recognizes the loop length correctly with midiTrack.setTempo(tempo.bpm); midiTrack.setTimeSignature(4, 4) in place. Works even for empty loops. The calculations shouldn't be too fancy here.

The issue arises when I try to import a midi file to my web editor back. So we need to do the calculations ourselves.

davay42 avatar Nov 04 '21 12:11 davay42

I've made some changes in #107 to allow EndTrackEvent to be manually added with a specific delta value. That is, the number of ticks from the previous event.

track.addEvent(new MidiWriter.EndTrackEvent({delta: 128}));

Might still be easier/more readable to pad a track with a silent note @chr15m, but at least this is now an option.

grimmdude avatar Dec 07 '22 18:12 grimmdude

Awesome, thank you, will check it out.

chr15m avatar Dec 08 '22 02:12 chr15m

Awesome, thanks!

davay42 avatar Dec 08 '22 05:12 davay42