-
-
Notifications
You must be signed in to change notification settings - Fork 259
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
Add rolled function with variants #820
Conversation
rolledWith f t = withEvents aux | ||
where aux es = concatMap (steppityIn) (groupBy (\a b -> whole a == whole b) $ sortOn whole (f es)) | ||
steppityIn xs = mapMaybe (\(n, x) -> shiftIt n (length xs) x) $ enumerate xs | ||
shiftIt n d (Event c (Just (Arc s e)) a' v) = do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This gives a 'Pattern match(es) are non-exhaustive' warning, I think this will break on continuous events (those with whole arc of Nothing
). Probably adding a catchall of shiftIt _ _ ev = ev
is enough.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I resolved this issue. This will ignore the rolled function for continuous events like
n (rolledBy "1" (irand 8) |+ "[0,8, 12]")
-- ~0>1~|n: Note {unNote = 2.0}n
-- ~0>1~|n: Note {unNote = 10.0}n
-- ~0>1~|n: Note {unNote = 14.0}n
src/Sound/Tidal/UI.hs
Outdated
@ | ||
|
||
And you can use `rolledBy` or `rolledBy'` to specify the length of the roll. The value in the passed pattern | ||
is the divisor of the cycle length. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think specifying the ratio directly would be more idiomatic - e.g. 1/4
or q
rather than 4
for a quarter of a cycle.
shiftIt n d (Event c (Just (Arc s e)) a' v) = do | ||
a'' <- subArc (Arc newS e) a' | ||
return (Event c (Just $ Arc newS e) a'' v) | ||
where newS = s + (dur * fromIntegral n) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this will result in patterns which aren't well formed, by moving events outside the original query.
Fixing this would be a little complicated I think. The query would need to be made bigger, subtracting the roll duration from the start and adding the duration to the end of the query arc. Then after the calculation done, resulting events trimmed to the original query, and removed completely if they're outside that original query.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello @yaxu ! I'm just taking the time to try to finish this topic. My understanding is that the behavior you describe should already be implemented. For example s "superpiano" <| n (rolledBy "[1.5]" "[0,1,2]")
will result in
(0>1)|n: Note {unNote = 0.0}n, s: "superpiano"
(½>1)|n: Note {unNote = 1.0}n, s: "superpiano
So, practically, when the time arc of the pattern gets bigger (in theory), the overhanging events are truncated.
And that's what you meant, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm finding it hard to get my head around this in the time I have available..
But what I meant is something like.. Tidal calculates events in a window given by the query. This makes functions like this quite difficult, when we want to cause a new event to happen after an existing one, in at least two ways. We might query a timespan that does not contain any events, but there was one happening just before that timespan that should cause one in the window we're asking for. But we don't know about that. The other problem is that we might have an event in the window but it should cause an event outside that window. From what I could tell, both are an issue here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll merge for now and will try to make a failling test at some point
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now I play with it, it seems I was misunderstanding something, it seems to work fine. Sorry for holding this up!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Amazing work - thanks Thomas and Alex
rolledWith :: ([Event a] -> [EventF (ArcF Time) a]) -> Ratio Integer -> Pattern a -> Pattern a | ||
rolledWith f t = withEvents aux | ||
where aux es = concatMap (steppityIn) (groupBy (\a b -> whole a == whole b) $ (f es)) | ||
steppityIn xs = mapMaybe (\(n, ev) -> (timeguard n xs ev t)) $ enumerate xs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added this zero check to make this possible:
s "superpiano" <| n (rolledBy "0" "[0,1,2,3]")
Otherwise we would receive an exception anyways.
Just a little advice, since this feature seems tricky, why not adding some tests to demonstrate the functionality? |
@ndr-brt thanks for the advice! I added the tests. |
rolledWith :: Ratio Integer -> Pattern a -> Pattern a | ||
rolledWith t = withEvents aux | ||
where aux es = concatMap (steppityIn) (groupBy (\a b -> whole a == whole b) $ ((isRev t) es)) | ||
isRev b = (\x -> if x > 0 then id else reverse ) b |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's better to control the order (playing in reverse or not) within the mini notation. With this lambda it's possible to do this rolledBy "-0.5" $ n ("[0,1,2,3]")
. This will result in:
(0>1)|n: Note {unNote = 3.0}n
(⅛>1)|n: Note {unNote = 2.0}n
(¼>1)|n: Note {unNote = 1.0}n
(⅜>1)|n: Note {unNote = 0.0}n
@left_adjont @satoruki @cleary and me (mrreason aka @thgrund) created this
rolled
functions to give chords a harp-like effect. This was initiated in Discord here: https://discord.com/channels/779427371270275082/797978366023434240/798986145907736592Then there was a discussion started in the TidalClub forum:
https://club.tidalcycles.org/t/share-your-creations/1281/418