-
-
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
Changes from 11 commits
6324a97
64c3816
6eccb9d
79d8a8d
d851c46
d1e02f8
42361cd
e91dcf9
0eba96e
5a3f061
fb85040
88415c4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,8 +25,14 @@ import Prelude hiding ((<*), (*>)) | |
|
||
import Data.Char (digitToInt, isDigit, ord) | ||
import Data.Bits (testBit, Bits, xor, shiftL, shiftR) | ||
|
||
-- import System.Random (randoms, mkStdGen) | ||
-- import Control.Monad.ST | ||
-- import Control.Monad.Primitive (PrimState, PrimMonad) | ||
-- import qualified Data.Vector as V | ||
-- import Data.Word (Word32) | ||
import Data.Ratio ((%), Ratio) | ||
import Data.Fixed (mod') | ||
import Data.Ratio ((%)) | ||
import Data.List (sort, sortOn, findIndices, elemIndex, groupBy, transpose, intercalate, findIndex) | ||
import Data.Maybe (isJust, fromJust, fromMaybe, mapMaybe) | ||
import qualified Data.Text as T | ||
|
@@ -1439,6 +1445,40 @@ _arp name p = arpWith f p | |
thumbup xs = concatMap (\x -> [thumb,x]) $ tail xs | ||
where thumb = head xs | ||
|
||
{- | `rolled` plays each note of a chord quickly in order, as opposed to simultaneously; to give a chord a harp-like effect. | ||
This will played from the lowest note to the highest note of the chord | ||
@ | ||
rolled $ n "c'maj'4" # s "superpiano" | ||
@ | ||
|
||
|
||
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. A negative value will play the arpeggio in reverse order. | ||
|
||
@ | ||
rolledBy "<1 -0.5 0.25 -0.125>" $ note "c'maj9" # s "superpiano" | ||
@ | ||
-} | ||
|
||
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 | ||
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 commentThe reason will be displayed to describe this comment to others. Learn more. I added this zero check to make this possible:
Otherwise we would receive an exception anyways. |
||
timeguard _ _ ev 0 = return ev | ||
timeguard n xs ev _ = (shiftIt n (length xs) ev) | ||
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 commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe 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
|
||
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 commentThe 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 will result in
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 commentThe 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 commentThe 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 commentThe 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 commentThe reason will be displayed to describe this comment to others. Learn more. Amazing work - thanks Thomas and Alex |
||
dur = ((e - s)) / ((1/ (abs t))*fromIntegral d) | ||
shiftIt _ _ ev = return ev | ||
|
||
rolledBy :: Pattern (Ratio Integer) -> Pattern a -> Pattern a | ||
rolledBy pt = tParam rolledWith (segment 1 $ pt) | ||
|
||
rolled :: Pattern a -> Pattern a | ||
rolled = rolledBy (1/4) | ||
|
||
{- TODO ! | ||
|
||
|
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: