On Friday 24 July 2009, Gabriel M. Beddingfield wrote: > Hi Jakob, > > On Fri, 24 Jul 2009, Jakob Lund wrote: > > Yes.. So the idea is that eventually we wouldn't need copies of the notes > > at all? I guess that could be nice. But what if a note was deleted (from > > the GUI) while the song is playing (eg. if that note had already been > > scheduled > > [snip] > > No, I think the idea was to trim down Note so that it's lightweight and > easy to copy around (rather than passing around a Note*). So, for > instance, when the Note gets scheduled... the data is copied to the > SeqScript (not the pointer to Note*). SeqScriptPrivate is a container for > SeqEvent, which has a Note as a member (not a Note*). > > The idea is: once the note is copied to SeqScript from an input, the > outputs would just refer to that one and there would not be any need to > copy it again. (However, the Sampler isn't quite there yet...)
Oh, now I'm getting it... I was still thinking about the sampler referring to th Note*s, but now I realize that it now has a list<Note> to keep the information. That could work! > > > But still, all those note off events bother me - when scheduling a note, > > old note-off's lying between the new note-on and the new note-off would > > have to be deleted. Going through the script (ie. linked-list) again and > > again to do this could be overly expensive, don't you think? > > By design, SeqScript is supposed to handle this case. If a note-on/off > pair has been scheduled, and a new note-on comes in between, it is > supposed to delete the note-off for you. > > I haven't studied the speed of doing this, but off the cuff it would > happen in linear time, O(N). Further, I expect that the number of > events (N) in SeqScript will typically be 128 or less.[1] The operation > would be to iterate through and (probably) compare an integer or two. > > So, no, it doesn't sound overly expensive. But, I can see where there's a > possibility that I could be wrong about this. If every insertion is O(N), N insertions would be O(N^2), right? I realize this may or may not be a problem, but It doesn't feel right, even for (a pathological) worst case, in a real time context... We ought to have note insertion in O(1) (or actually O(lgN) because they get sorted) ?! :-) An alternative to the note-off events could be to keep the note length with the notes themselves, converting them to frame values if necessary on output from seqScript. The quirk here (which I _think_ is how hydrogen currently behaves) is that if a note plays on some instrument before a previous note on that instrument has rung out, two copies of the sample will play, possibly causing weird phaser effects.. > > >> When scheduling notes, SongSequencer has to look ahead an appropriate > >> amount and schedule all those events (rendering any randomization values > >> now). So, there will probably be a cursor where SongSequencer says to > >> itself, "I've already scheduled up to.... here." > > > > IMO, scheduling notes to frames during lookahead is _not_ what we want! > > Tempo changes happen, and if they come from the GUI or from JACK, there's > > no way that the sequencer can now about it in advance (!), so all the > > positions of notes scheduled ahead will be wrong! We still need the > > intermediate priority queue (proposedly it be based on ticks, not ticks + > > frames as in that dodgy "functor" patch I was sending you last week :-) ) > > This is a very valid point. Up to now I've been ignoring this issue > because it's the same behavior as H2 currently does. It would be nice to > improve that behavior, though. > > However, I don't like the idea of two queues. What if, instead, SeqScript > offered two "views" of the same thing. Like this.... > > Inputs: Notes/events are scheduled by tick + milliseconds (float) by the > inputs (like a Song or MIDI input). The tick can either be a BBT-like > thing... or perhaps something like "tick offset to in the current process > cycle." Very good idea! Inputs hould have to use _either_ ticks or ms/frames, though, because given both, the seqScript wouldn't know how to sort properly. Also, it (the seqScript) would have to keep two sorted lists (because the relationship between the two might shift at any time), one by ticks and one by ms/frame values. At output, the tick-based list would get serialized to frames (up to nframes) and then merged into the other one. Internally, the seqScript could map from B:b:t, that the song sequencer gives, to a "running tick number" that could be used for sorting the list, and that is easily translated into frame number, once the BPM is known. > > Outputs: SeqScript (not the outputs) translates these to frame offsets > when fed to the outputs. > > Thus, SeqScript (instead of SongSequencer) is responsible to map ticks to > frames. This allows it to respond to tempo change events. > > The nice thing about this way is that it frees the Inputs from having to > even think about frames. It does it all in ticks and milliseconds (as it > should be). This helps, too, with MIDI snap-to operations (which were > more difficult when MIDI Inputs were sequenced by frame). It also allows > us to respond to tempo changes. > > Hmmm.... I dunno. What do you think? > > > bit) I guess it's justified :-) > > Thanks! :-) > > Peace, > Gabriel > > [1] Suppose 4 instruments have a 32nd note run while going 180 bpm. > > 32 notes/beat x 4 inst x 2 on/off pairs x 180 bpm / (60 sec/min) > = 768 event pairs per second > > Suppose 48000 Hz, buffer size 1024, and lookahead 100 ms. > SeqScript will need to have schedule window that is: > > (1024 / 48000) sec + .100 sec = .0213 sec + .100 sec > = .1213 sec > > So, SeqScript would need to hold about: > > 768 ev/sec x .1213 sec = 93.2 events. > This is going to be great :) Yeehaw! -- Jakob ------------------------------------------------------------------------------ _______________________________________________ Hydrogen-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/hydrogen-devel
