alda-lang / alda-core

The core machinery of Alda
80 stars 26 forks source link

Global attribute timing issues #24

Closed daveyarwood closed 4 years ago

daveyarwood commented 7 years ago

Moved from https://github.com/alda-lang/alda/issues/283.

@elyisgreat pointed out an unintuitive aspect of global attributes, which is that they can only affect instrument parts below them in the score. In other words, in the following score:

trumpet: c8 c c c (tempo! 250) c c c c c
trombone: c8 c c c c c c c c 

Both the trumpet and the trombone part speed up at the global tempo change after 4 eighth notes. However, in this score:

trumpet: c8 c c c c c c c c 
trombone: c8 c c c (tempo! 250) c c c c c

The global tempo change does not affect the trumpet part because the trumpet's notes are already "in place" by the time the trombone part is evaluated. The global tempo change at 2 beats into the score will only affect subsequent instrument parts.

See the original issue for further discussion. I do not think it is possible to get the "expected" behavior without substantially changing the way we determine the offset of notes in a score.

This would also have the unpleasant side effect that the timing (and other properties) of the notes in a score could now be different depending on how much of the score is evaluated at a time.

In the case of the example above, the trumpet line either would or not jump to 250 bpm after four notes, depending on whether or not the trombone line were evaluated as part of the same score, or added after-the-fact (e.g. in an Alda REPL).

I am leaning against moving forward with this change, but would be interested in hearing other perspectives on this.

elydpg commented 7 years ago

Now that I think about it more, it makes more intuitive sense for global attribute calls (at least for tempo) to apply to all instruments at that time and not have the weird event thing. This is due to my trying to code global calls around event breakups, making the process more confusing. This would especially help those who don't understand how events work, who would fully expect any global attribute call to happen when it is called. Of course, it carries all the aforementioned problems with that strategy, which would need to be dealt with.

elydpg commented 7 years ago

The entire system would have to be redone anyway were we to implement a system similar to my proposal in alda-lang/alda#179. This issue is thus connected to #13.

elydpg commented 7 years ago

To be honest, I'm now thinking that the easiest solution to this would be to make global attribute calls only legal if they are not interspersed with events; i.e. in the header area. From what I can tell from your examples the global call is really only used in this way.

daveyarwood commented 7 years ago

I could see a use case for using global attributes in the middle of a piece. For example, if the piece has a key signature change, tempo change, etc. and you want to express that the key signature/tempo/etc. changes for all the parts.

elydpg commented 7 years ago

Yes, but as discussed before, this more often than not leads to those bizarre timing issues. Still unsure what the best resolution is.

daveyarwood commented 4 years ago

After having several years to think about this, I've decided to keep the behavior the way it is now -- a global attribute in one part only affects that part and all of the parts below it in a score -- for the reasons I mentioned above.