From f38b8a6957e50771d0c3b40334f9e6ab4188ffba Mon Sep 17 00:00:00 2001
From: Renzo Torr- <56176668+geikha@users.noreply.github.com>
Date: Sun, 19 Jan 2025 21:14:32 -0300
Subject: [PATCH] adds beat function

---
 src/Sound/Tidal/UI.hs | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/src/Sound/Tidal/UI.hs b/src/Sound/Tidal/UI.hs
index a62e3643..fa83705e 100644
--- a/src/Sound/Tidal/UI.hs
+++ b/src/Sound/Tidal/UI.hs
@@ -1460,6 +1460,23 @@ _markovPat :: Int -> Int -> [[Double]] -> Pattern Int
 _markovPat n xi tp = setTactus (toRational n) $ splitQueries $ pattern (\(State a@(Arc s _) _) ->
   queryArc (listToPat $ runMarkov n tp xi (sam s)) a)
 
+{-|
+@beat@ structures a pattern by picking subdivisions of a cycle.
+Takes in a pattern that tells it which parts to play (polyphony is recommeded here),
+and the number of parts by which to subdivide the cycle (also pattern-able).
+For example:
+> d1 $ beat "[3,4.2,9,11,14]" 16 $ s "sd"
+-}
+beat :: Pattern Time -> Pattern Time -> Pattern a -> Pattern a
+beat = patternify2 $ __beat innerJoin
+
+__beat :: (Pattern (Pattern a) -> Pattern a) -> Time -> Time -> Pattern a -> Pattern a
+__beat join t d p = join $ (compress (s,e) . pure) <$> p
+                      where s = t' / d
+                            e  = (t'+1) / d
+                            t' = t `mod'` d
+
+
 {-|
 @mask@ takes a boolean pattern and ‘masks’ another pattern with it. That is,
 events are only carried over if they match within a ‘true’ event in the binary