Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Only one "modifier" is allowed per "slice" in mininotation #176

Closed
Tracked by #30
bpow opened this issue Aug 6, 2022 · 8 comments · Fixed by #350
Closed
Tracked by #30

Only one "modifier" is allowed per "slice" in mininotation #176

bpow opened this issue Aug 6, 2022 · 8 comments · Fixed by #350
Labels
compatibility Mainline Tidal Compatibility enhancement improves an existing feature

Comments

@bpow
Copy link
Contributor

bpow commented Aug 6, 2022

This could be reasonably tagged as "compatibility" because the behavior differs from the mininotation in tidal. That also means it is related to #30. I am not sure how much the lack of complete compatibility with tidal should be considered a strudel issue here, though, since I don't think the tidal behavior is very well defined.

Tidal's mininotation allows (some but not all) combinations and orderings of modifiers to a single "slice". I'm using the terminology from within the peggy grammar, where a "slice" would be something like a5 and the modifier something like @2 or ? or (5,8).

For instance, tidal allows/parses "[c(5,8),e*2(5,8)]", which results in a pattern like:

|c-..c-c-..c-c-..|c-..c-c-..c-c-..|c-..c-c-..c-c-..|c-..c-c-..c-c-..
|ee..eeee..eeee..|ee..eeee..eeee..|ee..eeee..eeee..|ee..eeee..eeee..

In the case of the repeat and euclidean operators, they cannot be put in the other order (e.g., e(5,8)*2 parses neither in tidal nor strudel).

Tidal does allow some combinations of modifiers to have different combinations (c?*2 d and c*2? d both parse in tidal and have different outputs). They essentially end up getting interpreted the same as [c?]*2 and [c*2]? respectively (that is, the first modifier binds "more tightly").

For what it is worth, both tidal and strudel can handle the more explicit formulations of for combining euclidian and repeat modifiers with extra square brackets, like "[[e4*2](5,8),[c3(5,8)]*2]".

@felixroos felixroos added enhancement improves an existing feature compatibility Mainline Tidal Compatibility labels Aug 6, 2022
@felixroos
Copy link
Collaborator

I think it's generally desirable to allow multiple modifiers without brackets, because it's less to type so I added both compatibility and enhancement as labels. It might be that some combinations are ambiguous, but maybe not.

@yaxu
Copy link
Member

yaxu commented Aug 7, 2022

I'd say e.g. e(5,8)*2 not parsing in tidal is a bug. In lieu of a formalised defnition I wonder if we could make a file that's a list of equivalent mininotation expressions that could be turned into tests for strudel, vortex (tagging @munshkr) and tidal.

It could be CSV e.g.

"x(3,8)*2", "x ~ ~ x  ~ ~ x ~ x ~ ~ x  ~ ~ x ~"

I think it would be really good if the mininotations work the same way across hosts, so that people can collaborate across them by sharing rhythms and meters as mininotation strings.

@munshkr
Copy link
Member

munshkr commented Aug 7, 2022

Totally agree that in the future it'd be great to formalize the mininotation grammar definition and expected output across implementations of Tidal :) I was thinking of the CSV file with a more general representation, with the following columns:

  • Mininotation string (e.g. x(3,8)*2)
  • Query timespan (e.g. [0, 1], or [0, 4])
  • Expected events list in a standardized JSONL representation:
[
 [ [0, (1/16)], [0, (1/16)], 'x' ],
 [ [(3/16), (1/4)], [(3/16), (1/4)], 'x' ],
 [ [(3/8), (7/16)], [(3/8), (7/16)], 'x' ],
 [ [(1/2), (9/16)], [(1/2), (9/16)], 'x' ],
 [ [(11/16), (3/4)], [(11/16), (3/4)], 'x' ],
 [ [(7/8), (15/16)], [(7/8), (15/16)], 'x' ]
]

where each event is represented with the whole, part and value, and the whole and part timespans as lists of two floats.

It's a bit harder to maintain and read in and of itself, but I believe it'd allow us to test other dfferent and more complex expressions than the euclid one, and it simplifies generating the code for each test case on Strudel, Vortex and Tidal. We could even have a script that updates this CSV and sets the expected events based on the output of the current implementation, to have a starting point.

edit: Maybe instead of a CSV, just a JSONL:

[
  { 
    "expr": "e(3,8)*2",
    "span": [0, 1],
    "events": [
       [ [0, (1/16)], [0, (1/16)], 'x' ],
       [ [(3/16), (1/4)], [(3/16), (1/4)], 'x' ],
       [ [(3/8), (7/16)], [(3/8), (7/16)], 'x' ],
       [ [(1/2), (9/16)], [(1/2), (9/16)], 'x' ],
       [ [(11/16), (3/4)], [(11/16), (3/4)], 'x' ],
       [ [(7/8), (15/16)], [(7/8), (15/16)], 'x' ]
     ]
  }
]

@felixroos
Copy link
Collaborator

felixroos commented Aug 7, 2022

I like the idea of having this layer of formalization, also JSON(L) seems like a good fit.

We would need some alternative way to express ratios though, as JSON(L) does not understand rational numbers.
Alternative ideas:

  1. [n,d] array: [ [0, [1,16]], [0, [1,16]], "x" ]
  2. strings fractions [ [0, "1/16"], [0, "1/16"], "x" ]
  3. abused decimal numbers [ [0, 1.16], [0, 1.16], "x" ]
  4. floats: [[0, 0.0625], [0, 0.0625], "x" ]

after writing this, I realized you already wrote floats, but it might still make sense to at least look at alternatives. Floats can get pretty long, also they could be a problem across different languages when it comes to rounding / different float representations?
In strudels snapshot tests we are using this string format:

"0/1 -> 1/2: D3",
"-1/4 -> 0/1: Bb3",
"1/4 -> 3/4: F3",
"0/1 -> 1/4: F4",
"1/2 -> 1/1: C4"

Those are only the whole timespans though

@munshkr
Copy link
Member

munshkr commented Aug 7, 2022

I like the string fractions format, it's a bit less verbose than having a list for the numerator and denominator. We could check if the value is a string and parse it to a proper fraction representation then.

@yaxu
Copy link
Member

yaxu commented Aug 7, 2022

Just wondering if it'd be easier to expand the mininotation to be able to specify event fragments?

@felixroos
Copy link
Collaborator

Just wondering if it'd be easier to expand the mininotation to be able to specify event fragments?

Could you make an example? I don't really understand ..

@yaxu
Copy link
Member

yaxu commented Aug 8, 2022

Sure, lets say a[[x,y]] makes an event that is a fragment of a, with a part that starts x into the whole and ends y into the whole. Then the first cycle of "a[[0,0.5]]" would give a part of (0,1) and whole of (0,2). Then these would be equivalent:

"a b/2"
"a <b[[0,0.5]] b[[0.5, 1]]>"

As ever, it's hard to come up with nice brackets for this. Perl-style regex uses emoji-parens, e.g. (?: ) for group without capture, (?=) for lookahead and (?!) for negative lookahead. At least I think they're supposed to be emoji..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compatibility Mainline Tidal Compatibility enhancement improves an existing feature
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants