Skip to content
This repository was archived by the owner on Jun 13, 2025. It is now read-only.

Commit e6c05de

Browse files
committed
stepJoin experiment
1 parent 5dae76f commit e6c05de

File tree

3 files changed

+36
-5
lines changed

3 files changed

+36
-5
lines changed

src/Sound/Tidal/Core.hs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,9 @@ pattern to multiple patterns at once:
422422
> ] # speed "[[1 0.8], [1.5 2]*2]/3"
423423
-}
424424
stack :: [Pattern a] -> Pattern a
425-
stack = foldr overlay silence
425+
stack pats = (foldr overlay silence pats) {tactus = t}
426+
where t | length pats == 0 = Nothing
427+
| otherwise = foldl1 lcmr <$> (sequence $ map tactus pats)
426428

427429
-- ** Manipulating time
428430

src/Sound/Tidal/Stepwise.hs

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,17 @@
1919

2020
module Sound.Tidal.Stepwise where
2121

22-
import Data.List (transpose)
23-
import Data.Maybe (fromMaybe)
22+
import Data.Containers.ListUtils (nubOrd)
23+
import Data.List (sort, transpose)
24+
import Data.Maybe (catMaybes, fromMaybe, isJust)
2425

2526
import Sound.Tidal.Core
2627
import Sound.Tidal.Pattern
27-
import Sound.Tidal.UI (while)
28-
import Sound.Tidal.Utils (applyWhen)
28+
import Sound.Tidal.UI (while)
29+
import Sound.Tidal.Utils (applyWhen, pairs)
30+
31+
_lcmtactus :: [Pattern a] -> Maybe Time
32+
_lcmtactus pats = foldl1 lcmr <$> (sequence $ map tactus pats)
2933

3034
s_cat :: [Pattern a] -> Pattern a
3135
s_cat pats = timecat $ map (\pat -> (fromMaybe 1 $ tactus pat, pat)) pats
@@ -111,3 +115,24 @@ s_expand = patternify _s_expand
111115

112116
s_contract :: Pattern Rational -> Pattern a -> Pattern a
113117
s_contract = patternify _s_contract
118+
119+
stepJoin :: Pattern (Pattern a) -> Pattern a
120+
stepJoin pp = Pattern q Nothing Nothing
121+
where q st@(State a c) = query (timecat $ retime $ slices $ query (rotL (sam $ start a) pp) (st {arc = Arc 0 1})) st
122+
retime :: [(Time, Pattern a)] -> [(Time, Pattern a)]
123+
retime xs = map (\(dur, pat) -> adjust dur pat) xs
124+
where occupied_perc = sum $ map fst $ filter (isJust . tactus . snd) xs
125+
occupied_tactus = sum $ catMaybes $ map (tactus . snd) xs
126+
total_tactus = occupied_tactus / occupied_perc
127+
adjust dur pat@(Pattern {tactus = Just t}) = (t, pat)
128+
adjust dur pat = (dur*total_tactus, pat)
129+
-- break up events at all start/end points, into groups, including empty ones.
130+
slices :: [Event (Pattern a)] -> [(Time, Pattern a)]
131+
slices evs = map (\s -> ((snd s - fst s), stack $ map value $ fit s evs)) $ pairs $ sort $ nubOrd $ 0:1:concatMap (\ev -> start (part ev):stop (part ev):[]) evs
132+
-- list of slices of events within the given range
133+
fit :: (Rational, Rational) -> [Event (Pattern a)] -> [Event (Pattern a)]
134+
fit (b,e) evs = catMaybes $ map (match (b,e)) evs
135+
-- slice of event within the given range
136+
match :: (Rational, Rational) -> Event (Pattern a) -> Maybe (Event (Pattern a))
137+
match (b,e) ev = do a <- subArc (Arc b e) $ part ev
138+
return ev {part = a}

src/Sound/Tidal/Utils.hs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,7 @@ fromRight b _ = b
106106
applyWhen :: Bool -> (a -> a) -> a -> a
107107
applyWhen True f x = f x
108108
applyWhen False _ x = x
109+
110+
-- pair up neighbours in list
111+
pairs :: [a] -> [(a,a)]
112+
pairs rs = zip rs (tail rs)

0 commit comments

Comments
 (0)