Closed aengelberg closed 2 years ago
imo it doesn't make sense to have millisecond durations inside crams, since ratios inside crams are relative. This should at least throw a dedicated error though...
I was hoping I could use milliseconds to more explicitly specify the ratios I'm expecting between note durations. e.g. for a 4:3:2 ratio:
{c4ms d3ms e2ms}1
as opposed to something like
{c4 d8. e8}1
which is less intuitive.
Remember that {ax by} means that whenever a plays x times, b should play y times, within the cram. So for your 4:3:2 ratio example, {c2 d3 e4} should work.
{c2 d3 e4} would be a 6:4:3 ratio.
Ah, you're thinking in terms of counts, whereas I'm thinking in terms of the "for every" system I described above. Such are the confusions when the notelength notation is reciprocal...
Personally I think there needs to be a formal way to notate durations in terms of fractions of a bar, however you can try the set-duration
attribute and see if that works. set-duration
works in terms of fractions of a quarter note, so (set-duration 5)
sets a note to 5 quarter notes long. {(set-duration 4) c (set-duration 3) d (set-duration 2) e}
should work, although it's not exactly intuitive.
I was hoping I could use milliseconds to more explicitly specify the ratios I'm expecting between note durations. e.g. for a 4:3:2 ratio:
{c4ms d3ms e2ms}1
I like that idea, but it's interesting to consider how that would interact with standard note lengths. For example, how would the ratios be assigned here?
{c4ms d8 e2ms}
The duration of an 8th note varies depending on the tempo at that moment. In most cases, this is not difficult to calculate -- e.g. if the tempo is 120 bpm, then an 8th note takes 250ms, so the ratio would be 4:250:2.
But, it gets more complicated than that because in Alda, different instruments can be playing at different tempos at the same time. Consider this score:
cello: (tempo 120)
bassoon: (tempo 60)
cello/bassoon: {c4ms d8 e2ms}
Now, the cello's ratio is 4:250:2 and the bassoon's ratio is 4:500:2.
To further complicate things, we're also concerned with the number outside the brackets, i.e. the length of the entire CRAM expression. This can be explicit, e.g. {c d e}2
or implicit, e.g. {c d e}
. When it's implicit, the length is determined just like for notes and rests, where if the length is left out, we use the last declared note length.
This can lead to situations where multiple instruments play at different speeds, depending on their respective implicit note lengths, as shown in this example score:
piano: (set-duration 4)
harp: (set-duration 2) (octave 3)
piano/harp:
{e f g} {a b > c}
harp:
{d e f} {g a b}
Having said all that, I don't think it's necessarily a problem that Alda allows you to get yourself into situations like the ones above. I actually consider it a feature.
As far as I can tell, it should be possible to allow millisecond durations inside of a CRAM, even alongside standard note lengths. It's not an easy to change to make, because the code is currently oriented around counting beats to determine the ratio, but I am on board with making the change.
I probably won't get to this for quite a while -- PR welcome, if someone is willing to tackle it. :)
As far as I can tell, it should be possible to allow millisecond durations inside of a CRAM, even alongside standard note lengths.
I'm curious as to how that would work from a logic perspective. Would millisecond durations inside the cram just override the length of the cram itself? And then only the notes within the cram with relative length would be counted for the ratio and length system? Not sure tbh...
Also @aengelberg in terms of better notation I suggested fractional notelength notation awhile back which you can check out in alda-lang/alda-core#16
Instead of tallying beats, we would tally milliseconds, as I described above.
There are 2 relevant numbers, when it comes to CRAM:
The inner duration, which is the length of its contents.
e.g. in the case of {c4 d42ms e8}1
, assuming a tempo of 120 bpm, the inner duration would be a quarter note (500 ms) + 42ms + an eighth note (250 ms) = 792 ms.
The outer duration, which is how long the CRAM expression lasts, total.
e.g. for {c4 d42ms e8}1
, it's a whole note, which is 2000ms at 120 bpm.
That ratio (e.g. 792 / 2000) is then used to speed up or slow down the notes inside the brackets so that they sum up to the outer duration.
The issue right now is that we don't support ms durations inside a CRAM -- we ignore them and consider them to be 0-length.
@aengelberg I just realized that I totally fixed this in the process of porting Alda to Go. I think this has been fixed since I released Alda 2.0.0 last summer. :tada: