alda-lang / alda

A music programming language for musicians. :notes:
https://alda.io
Eclipse Public License 2.0
5.58k stars 284 forks source link

Can't use multiple instrument parts within an event sequence #202

Closed elydpg closed 8 years ago

elydpg commented 8 years ago

I was playing around with event sequences when I came across this:

midi-synth-voice:
[V1: g4 r2. >e4 d8 c4 d4. <b4. r a-4 > e4 d c< b8 > c8~2..< g8 >e4 d c< b8 > c8~2..< a-8 >e4 d c< b8 >
V1: c8~2. < g4 > e4. d8 c d4. e2 d2 < b2. > d8 d4 c2.. e4 d8 c4 d4. c2 < a- > e4 d8 d4. c4]*2

This throws an error, even though it’s really a single event sequence. This does not throw an error

midi-synth-voice:
V1: [g4 r2. >e4 d8 c4 d4. <b4. r a-4 > e4 d c< b8 > c8~2..< g8 >e4 d c< b8 > c8~2..< a-8 >e4 d c< b8 >
    c8~2. < g4 > e4. d8 c d4. e2 d2 < b2. > d8 d4 c2.. e4 d8 c4 d4. c2 < a- > e4 d8 d4. c4]*2

These errors aren’t unexpected. But they raise the question; I’m not sure how event sequences would work across voices/instruments (in this case the parser may not know that it’s the same voice/instrument). I think it could be interesting, though.

daveyarwood commented 8 years ago

I never intended event sequences to work across instruments, since an event has no knowledge of what instrument is supposed to play it. The idea is that (once variables are implemented) you'll be able to define sequences of events and then use them in multiple instrument parts.

I don't think I ever considered the possibility of using voices inside of an event sequence. That seems like something we should be able to do.

elydpg commented 8 years ago

Yeah. I don't think event sequences should work across instruments. I was thinking more of a scenario like this:

piano: [c d e f
trumpet: [c g]*8
piano: g a b c]*2

This doesn't parse. The idea is that the piano has an event sequence independent of the trumpet. I'm not sure if this is a bug or not. If not, I think there should be a syntax to make larger event sequences; say, if you want to repeat an entire section.

daveyarwood commented 8 years ago

Hmm... I think that would be confusing. It would be better to continue not allowing that, as a way of keeping people from doing confusing things, IMHO. I think that not being able to start an event sequence for one instrument, switch over to another, then switch back and continue the event sequence forces you to write scores in a way where it's really obvious where an event sequence starts and ends. For example, in this case you're forced to do this:

piano: [c d e f g a b c]*2
trumpet: [c g]*8

which is a lot more readable. I understand where you're coming from; it's a little less convenient to have to do something like the above when you're dealing with longer instrument parts that you'd rather break up so you can line up the instruments in a particular way. But, I would still rather not support starting an event sequence in one place and resuming it later after having switched to another instrument.

This is another scenario where variables will be really useful. You'll be able to do something like this:

pianoPartA = c d e f
pianoPartB = g a b c

piano: [pianoPartA pianoPartB] * 2
trumpet: [c g] * 8

Variables will allow you to define smaller parts and use them to build up larger scores, working at a higher level of abstraction.

daveyarwood commented 8 years ago

I do think that we should support the use of voice groups inside of an event sequence, though.

elydpg commented 8 years ago

Right. I still think there should be a way to have sequences not bounded by line constraints. Also, can you explain how voice groups inside of an event sequence would work?

daveyarwood commented 8 years ago

I think using variables is going to be the way to go for defining sequences that aren't bound by line constraints. For better readability, you can break your long sequence up into smaller parts and define them as variables, then compose them together all on one line. Perhaps a longer example will help illustrate my point:

(tempo! 80)

gtrA = o2 a8 > e a > c+8~2
gtrB = o2 g+8 > e g+ > c+8~2
gtrC = o2 f+8 > c+ f+ a b4/d+ <
gtrD = o2 e8 b > d a g+2 <

cello: (quant 95) o2 e4 | > c+4. c+8 < b a g+ a | > e2. f+8 g+
acoustic-guitar:  o2 r4 | gtrA                  | gtrB

cello:           a4 c+ d+ | e1
acoustic-guitar: gtrC     | gtrD
daveyarwood commented 8 years ago

Re: voice groups inside of an event sequence, the voice group would begin and end inside of the sequence. This would allow you to define event sequences containing multiple voices, which would be useful for multi-voice instruments like piano and guitar.

elydpg commented 8 years ago

true, however I don't see how I could repeat an entire section of score.I still don't see the reason to disallow broken up event sequences other than bracket matching. Perhaps having a non bracket character, like an ampersand, as an additional method of sequencing might be helpful?

daveyarwood commented 8 years ago

The idea is that you could define your score in parts, each defined as a separate variable, and then compose them together like this:

[ partA partB partC partD ] * 99

My goal is to keep Alda's syntax as simple as possible. The more complicated we make it, the more difficult the language is to use. If it's possible to accomplish something (in this case, repeating an entire section of a score) in a simpler way, I'd rather force people to do it the simple way than make it possible to do it a more complicated and potentially confusing way. My 2¢ :)

elydpg commented 8 years ago

True. It's kind of weird that

piano: [c d e f
piano: g a b c]*2
trumpet: [c g]*8

is invalid but

piano: [c d e f
           g a b c]*2
trumpet: [c g]*8

is valid. I guess I need to know more about the mechanics of events. Also voices. I basically treat them as their own instruments.

daveyarwood commented 8 years ago

The parser doesn't like the first example because it can't make sense of a [ without a corresponding ].

The parser parses each "part" separately -- and by "part" here I don't just mean separate instruments, but literally an instrument declaration like piano: followed by any number of musical events, which can be notes, rests, chords, voice groups, event sequences, etc.

So when trying to parse that example, the parser makes a first pass and determines that there are 3 "parts":

piano: [c d e f
piano: g a b c]*2
trumpet: [c g]*8

It then tries to parse each one separately. [c d e f is not valid Alda syntax, so it fails on the first one.


A voice group is essentially just another event. It starts when you start using a voice, and continues up until you either switch to another instrument or end the voice group by using V0 (which essentially just means "I'm done with using voices, go back to just having a single voice"). You could think of a voice as being sort of like a chord, only instead of having a bunch of separate notes played at the same time, you have a bunch of separate melodies or sequences of notes played at the same time. Does that make sense?

elydpg commented 8 years ago

ah. also don't markers allow a kind of longer-form repetition?

daveyarwood commented 8 years ago

No -- markers do allow you to go back to a previously established point in the score, but there isn't a looping aspect.

elydpg commented 8 years ago

I just figured out how long form repetition "across parts" would work with variables:

pianoPart=o4 c d e f

pianoPart=g a b > c

piano: [pianoPart]*2
trumpet: c < g > c < g > c < g > c < g 

piano: 
trumpet: g > c < g > c < g > c < g > c
elydpg commented 8 years ago

We can finally do this. Should we close this issue?

daveyarwood commented 8 years ago

I'd like to keep this issue open until we've made it possible to include a voice group within an event sequence, e.g.:

p> piano: [V1: c d e V2: e f g]*2
16-Jul-29 09:47:15 skeggox.local ERROR [alda.repl.core] - Invalid Alda syntax.

Worth noting, it is possible to include voices inside of a variable definition, but it is buggy:

p> foo = V1: c d e V2: e f g

p> piano: foo*2
# foo plays ONCE :(

p> foo = V1: c d e V2: e f g V0:

p> piano: foo*2
# foo plays twice :)

The issue seems to be that voice groups do not implicitly end at the end of a variable definition, which can cause unexpected behavior.

elydpg commented 8 years ago

Hm. should this be a separate issue?

daveyarwood commented 8 years ago

Yeah, fair enough -- I'll make a new issue for that and close this one.

elydpg commented 8 years ago

there's still the voices event sequence issue tho...

daveyarwood commented 8 years ago

Opened #255.