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

Step-oriented functionality #1072

Merged
merged 41 commits into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
cca6485
add tactus field to Pattern
yaxu Apr 9, 2024
df27212
1.10-dev -> dev
yaxu Apr 9, 2024
198263a
add pattern metadata for pure values
yaxu Apr 9, 2024
5c28e1a
preserve tactus from toplevel mininotation sequence
yaxu Apr 9, 2024
037fbb0
stepcat
yaxu Apr 9, 2024
d696aa1
add stepadd/stepsub, and use pure values in patternification where po…
yaxu Apr 10, 2024
aeebac3
rename step to steppify and steps to steppifies. Add new 'steps' that…
yaxu Apr 10, 2024
410e4a5
preserve/calculate tactus correctly across applicatives
yaxu Apr 10, 2024
17d72dc
fix tidal-parse
yaxu Apr 10, 2024
ade3be3
fix tidal-parse
yaxu Apr 10, 2024
08518ba
fix warns
yaxu Apr 10, 2024
71ecdad
steppify -> stepify
yaxu Apr 10, 2024
adc7db3
Merge branch 'dev' of github.com:tidalcycles/tidal into tactus
yaxu Apr 11, 2024
cb0d994
stepify -> sseq, add ps prefix to PlayState fields
yaxu Apr 11, 2024
75176c3
remove cFrameTimespan
yaxu Apr 11, 2024
b0ed36f
suppress name shadow warns
yaxu Apr 11, 2024
323dfb7
fix warns
yaxu Apr 11, 2024
b5ac6f7
add stepalt, steptaper, steptaperlist, stepfirstof/steplastof/stepevery
yaxu Apr 11, 2024
31ac616
fix steptaper
yaxu Apr 11, 2024
7f69539
make firstof/lastof/every more interesting
yaxu Apr 11, 2024
86533ce
rejig stepfirstof etc to count steps not cycles
yaxu Apr 12, 2024
27ae58f
put stepwise in its own module, experiment with using S. prefix
yaxu Apr 12, 2024
25850a5
put stepwise in its own module, experiment with using S. prefix
yaxu Apr 12, 2024
5effc5c
put stepwise in its own module, experiment with using S. prefix
yaxu Apr 12, 2024
12055a7
undo S. experiment
yaxu Apr 12, 2024
a00ed41
separate stepfirstof and stepfirstofstep. need better names for these..
yaxu Apr 13, 2024
82280fc
rename step prefixes to s_, rename tParam to patternify, add patterni…
yaxu Apr 13, 2024
8492584
th -> nth and cycleth -> nthcycle
yaxu Apr 14, 2024
00b079a
s_when -> s_while
yaxu Apr 15, 2024
5dae76f
s_everycycle alias
yaxu Apr 15, 2024
e6c05de
stepJoin experiment
yaxu Apr 17, 2024
cabffb3
set lower bounds of containers, for nubord
yaxu Apr 18, 2024
88f546b
retire ghc 8.4.4 support. add tests for stable ghc 9.x releases
yaxu Apr 18, 2024
9809c08
retire ghc 8.4.4 support. add tests for stable ghc 9.x releases
yaxu Apr 18, 2024
f9f3b3f
ghc 9.6.5 seems to be missing from the github action..
yaxu Apr 18, 2024
2e7f02c
stepJoin experiment continued
yaxu Apr 18, 2024
4f344b4
calculate tactus from the first cycle
yaxu Apr 18, 2024
1be53d1
hard fork nobOrd to get around dependency issue
yaxu Apr 18, 2024
b790733
remove ghc 9.8.2 from tests for now
yaxu Apr 18, 2024
2f69c6f
Merge branch 'dev' into tactus
yaxu Apr 18, 2024
653d8b9
fixes for boot and sew
yaxu Apr 18, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,6 @@ jobs:
- ghc: 8.6.5
cabal: 3.4.0.0
experimental: false
- ghc: 8.4.4
cabal: 3.4.0.0
experimental: false

continue-on-error: ${{ matrix.versions.experimental }}
name: cabal ${{ matrix.versions.cabal }} - ghc ${{ matrix.versions.ghc }}
Expand Down
4 changes: 2 additions & 2 deletions BootTidal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
:set -XOverloadedStrings
:set prompt ""

default (Signal String, Integer, Double)

-- Import all the boot functions and aliases.
import Sound.Tidal.Boot

default (Pattern String, Integer, Double)

-- Create a Tidal Stream with the default settings.
-- Use 'mkTidalWith' to customize these settings.
tidalInst <- mkTidal
Expand Down
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ compiler/interpreter. Some resources for learning Haskell can be found here:
The main repository is maintained on github:
https://github.com/tidalcycles/tidal

**At the time of writing, current work should target the '1.10-dev' branch. The 2.0-dev branch is for experiments towards version 2.0.**
**At the time of writing, current work should target the 'dev' branch.**

The SuperDirt repository is here:
https://github.com/musikinformatik/SuperDirt
Expand Down Expand Up @@ -124,4 +124,4 @@ Push any final changes to the code, updating the following files:

* [The Hackage upload page](https://hackage.haskell.org/upload) contains instructions and links for uploading a release archive. **Start by uploading a package candidate because a package release can't be changed!**
* To distribute a package candidate for testing, find the download link for the `.tar.gz` bundle on the Hackage page for the package candidate. This candidate version can be installed with the following command: `cabal v1-install [url]` (note that at this time, [the v1 install command is necessary for installing a library from a URL](https://github.com/haskell/cabal/issues/8335)).
* Once everyone is happy with the new version, go ahead and upload the archive as a package release and publish the release on GitHub!
* Once everyone is happy with the new version, go ahead and upload the archive as a package release and publish the release on GitHub!
10 changes: 5 additions & 5 deletions src/Sound/Tidal/Boot.hs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE OverloadedStrings #-}

module Sound.Tidal.Boot
( Tidally (..)
Expand Down Expand Up @@ -72,10 +72,10 @@ where
along with this library. If not, see <http://www.gnu.org/licenses/>.
-}

import Prelude hiding (all, (*>), (<*))
import Sound.Tidal.Context hiding (mute, solo)
import Sound.Tidal.ID (ID)
import System.IO (hSetEncoding, stdout, utf8)
import Prelude hiding (all, (*>), (<*))
import Sound.Tidal.Context
import Sound.Tidal.ID (ID)
import System.IO (hSetEncoding, stdout, utf8)

-- | Functions using this constraint can access the in-scope Tidal instance.
-- You must implement an instance of this in 'BootTidal.hs'. Note that GHC
Expand Down
29 changes: 15 additions & 14 deletions src/Sound/Tidal/Context.hs
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,20 @@ module Sound.Tidal.Context (module C) where
along with this library. If not, see <http://www.gnu.org/licenses/>.
-}

import Prelude hiding ((<*), (*>))
import Prelude hiding ((*>), (<*))

import Data.Ratio as C
import Data.Ratio as C

import Sound.Tidal.Stream as C
import Sound.Tidal.Control as C
import Sound.Tidal.Core as C
import Sound.Tidal.Params as C
import Sound.Tidal.ParseBP as C
import Sound.Tidal.Pattern as C
import Sound.Tidal.Scales as C
import Sound.Tidal.Show as C
import Sound.Tidal.Simple as C
import Sound.Tidal.Transition as C
import Sound.Tidal.UI as C
import Sound.Tidal.Version as C
import Sound.Tidal.Control as C
import Sound.Tidal.Core as C
import Sound.Tidal.Params as C
import Sound.Tidal.ParseBP as C
import Sound.Tidal.Pattern as C
import Sound.Tidal.Scales as C
import Sound.Tidal.Show as C
import Sound.Tidal.Simple as C
import Sound.Tidal.Stepwise as C
import Sound.Tidal.Stream as C
import Sound.Tidal.Transition as C
import Sound.Tidal.UI as C
import Sound.Tidal.Version as C
45 changes: 24 additions & 21 deletions src/Sound/Tidal/Control.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
{-# LANGUAGE FlexibleInstances, OverloadedStrings, FlexibleContexts, BangPatterns #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-}

module Sound.Tidal.Control where
{-
Expand All @@ -21,18 +24,18 @@ module Sound.Tidal.Control where
along with this library. If not, see <http://www.gnu.org/licenses/>.
-}

import Prelude hiding ((<*), (*>))
import Prelude hiding ((*>), (<*))

import qualified Data.Map.Strict as Map
import Data.Maybe (fromMaybe, isJust, fromJust)
import Data.Ratio
import qualified Data.Map.Strict as Map
import Data.Maybe (fromJust, fromMaybe, isJust)
import Data.Ratio

import Sound.Tidal.Pattern
import Sound.Tidal.Core
import Sound.Tidal.Stream.Types (patternTimeID)
import Sound.Tidal.UI
import qualified Sound.Tidal.Params as P
import Sound.Tidal.Utils
import Sound.Tidal.Core
import qualified Sound.Tidal.Params as P
import Sound.Tidal.Pattern
import Sound.Tidal.Stream.Types (patternTimeID)
import Sound.Tidal.UI
import Sound.Tidal.Utils

{- | `spin` will "spin" and layer up a pattern the given number of times,
with each successive layer offset in time by an additional @1/n@ of a cycle,
Expand All @@ -44,7 +47,7 @@ around. This function work well on multichannel systems.
> $ sound "drum*3 tabla:4 [arpy:2 ~ arpy] [can:2 can:3]"
-}
spin :: Pattern Int -> ControlPattern -> ControlPattern
spin = tParam _spin
spin = patternify _spin

_spin :: Int -> ControlPattern -> ControlPattern
_spin copies p =
Expand Down Expand Up @@ -87,13 +90,13 @@ _spin copies p =
> d1 $ loopAt 8 $ rev $ chop 32 $ sound "bev"
-}
chop :: Pattern Int -> ControlPattern -> ControlPattern
chop = tParam _chop
chop = patternify _chop

chopArc :: Arc -> Int -> [Arc]
chopArc (Arc s e) n = map (\i -> Arc (s + (e-s)*(fromIntegral i/fromIntegral n)) (s + (e-s)*(fromIntegral (i+1) / fromIntegral n))) [0 .. n-1]

_chop :: Int -> ControlPattern -> ControlPattern
_chop n = withEvents (concatMap chopEvent)
_chop n pat = withTactus (* toRational n) $ withEvents (concatMap chopEvent) pat
where -- for each part,
chopEvent :: Event ValueMap -> [Event ValueMap]
chopEvent (Event c (Just w) p' v) = map (chomp c v (length $ chopArc w n)) $ arcs w p'
Expand Down Expand Up @@ -152,10 +155,10 @@ and manipulates those parts by reversing and rotating the loops:
-}

striate :: Pattern Int -> ControlPattern -> ControlPattern
striate = tParam _striate
striate = patternify _striate

_striate :: Int -> ControlPattern -> ControlPattern
_striate n p = fastcat $ map offset [0 .. n-1]
_striate n p = keepTactus (withTactus (* toRational n) p) $ fastcat $ map offset [0 .. n-1]
where offset i = mergePlayRange (fromIntegral i / fromIntegral n, fromIntegral (i+1) / fromIntegral n) <$> p

mergePlayRange :: (Double, Double) -> ValueMap -> ValueMap
Expand All @@ -180,7 +183,7 @@ internally. This means that you probably shouldn't also specify `begin` or
`end`.
-}
striateBy :: Pattern Int -> Pattern Double -> ControlPattern -> ControlPattern
striateBy = tParam2 _striateBy
striateBy = patternify2 _striateBy

-- | DEPRECATED, use 'striateBy' instead.
striate' :: Pattern Int -> Pattern Double -> ControlPattern -> ControlPattern
Expand All @@ -201,7 +204,7 @@ each sample is chopped into:
-}

gap :: Pattern Int -> ControlPattern -> ControlPattern
gap = tParam _gap
gap = patternify _gap

_gap :: Int -> ControlPattern -> ControlPattern
_gap n p = _fast (toRational n) (cat [pure 1, silence]) |>| _chop n p
Expand Down Expand Up @@ -336,7 +339,7 @@ _slice n i p =
> d1 $ fast 4 $ randslice 32 $ sound "bev"
-}
randslice :: Pattern Int -> ControlPattern -> ControlPattern
randslice = tParam $ \n p -> innerJoin $ (\i -> _slice n i p) <$> _irand n
randslice = patternify $ \n p -> keepTactus (withTactus (* (toRational n)) $ p) $ innerJoin $ (\i -> _slice n i p) <$> _irand n

_splice :: Int -> Pattern Int -> ControlPattern -> Pattern (Map.Map String Value)
_splice bits ipat pat = withEvent f (slice (pure bits) ipat pat) # P.unit (pure "c")
Expand Down Expand Up @@ -441,7 +444,7 @@ smash' n xs p = slowcat $ map (`slow` p') xs
> d1 $ echo 4 (-0.2) 0.5 $ sound "bd sn"
-}
echo :: Pattern Integer -> Pattern Rational -> Pattern Double -> ControlPattern -> ControlPattern
echo = tParam3 _echo
echo = patternify3' _echo

_echo :: Integer -> Rational -> Double -> ControlPattern -> ControlPattern
_echo count time feedback p = _echoWith count time (|* P.gain (pure $ feedback)) p
Expand Down Expand Up @@ -470,7 +473,7 @@ _echoWith count time f p | count <= 1 = p

-- | DEPRECATED, use 'echo' instead
stut :: Pattern Integer -> Pattern Double -> Pattern Rational -> ControlPattern -> ControlPattern
stut = tParam3 _stut
stut = patternify3' _stut

_stut :: Integer -> Double -> Rational -> ControlPattern -> ControlPattern
_stut count feedback steptime p = stack (p:map (\x -> ((x%1)*steptime) `rotR` (p |* P.gain (pure $ scalegain (fromIntegral x)))) [1..(count-1)])
Expand Down
46 changes: 26 additions & 20 deletions src/Sound/Tidal/Core.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{-# LANGUAGE FlexibleInstances, BangPatterns #-}
{-# LANGUAGE FlexibleInstances #-}

{-
Core.hs - For functions judged to be 'core' to tidal functionality.
Expand All @@ -20,11 +20,11 @@

module Sound.Tidal.Core where

import Prelude hiding ((<*), (*>))
import Prelude hiding ((*>), (<*))

import Data.Fixed (mod')
import qualified Data.Map.Strict as Map
import Data.Maybe (fromMaybe)
import Data.Fixed (mod')
import qualified Data.Map.Strict as Map
import Data.Maybe (fromMaybe)
import Sound.Tidal.Pattern

-- ** Elemental patterns
Expand All @@ -37,7 +37,7 @@ import Sound.Tidal.Pattern
> saw = sig $ \t -> mod' (fromRational t) 1
-}
sig :: (Time -> a) -> Pattern a
sig f = Pattern q
sig f = pattern q
where q (State (Arc s e) _)
| s > e = []
| otherwise = [Event (Context []) Nothing (Arc s e) (f (s+((e-s)/2)))]
Expand Down Expand Up @@ -266,7 +266,7 @@ listToPat = fastFromList
-- > d1 $ n "0 ~ 2" # s "superpiano"
fromMaybes :: [Maybe a] -> Pattern a
fromMaybes = fastcat . map f
where f Nothing = silence
where f Nothing = silence
f (Just x) = pure x

{-| A pattern of whole numbers from 0 to the given number, in a single cycle.
Expand Down Expand Up @@ -312,7 +312,8 @@ append a b = cat [a,b]
-}
cat :: [Pattern a] -> Pattern a
cat [] = silence
cat ps = Pattern q
cat (p:[]) = p
cat ps = pattern q
where n = length ps
q st = concatMap (f st) $ arcCyclesZW (arc st)
f st a = query (withResultTime (+offset) p) $ st {arc = Arc (subtract offset (start a)) (subtract offset (stop a))}
Expand Down Expand Up @@ -349,7 +350,9 @@ fastappend = fastAppend
> d1 $ fastcat [sound "bd*2 sn", sound "jvbass*3", sound "drum*2", sound "ht mt"]
-}
fastCat :: [Pattern a] -> Pattern a
fastCat ps = _fast (toTime $ length ps) $ cat ps
fastCat (p:[]) = p
fastCat ps = setTactus t $ _fast (toTime $ length ps) $ cat ps
where t = fromMaybe (toRational $ length ps) $ ((* (toRational $ length ps)) . foldl1 lcmr) <$> (sequence $ map tactus ps)

-- | Alias for @fastCat@
fastcat :: [Pattern a] -> Pattern a
Expand All @@ -371,10 +374,11 @@ fastcat = fastCat

-}
timeCat :: [(Time, Pattern a)] -> Pattern a
timeCat tps = stack $ map (\(s,e,p) -> compressArc (Arc (s/total) (e/total)) p) $ arrange 0 tps
timeCat ((_,p):[]) = p
timeCat tps = setTactus total $ stack $ map (\(s,e,p) -> compressArc (Arc (s/total) (e/total)) p) $ arrange 0 $ filter (\(t, _) -> t > 0) $ tps
where total = sum $ map fst tps
arrange :: Time -> [(Time, Pattern a)] -> [(Time, Time, Pattern a)]
arrange _ [] = []
arrange _ [] = []
arrange t ((t',p):tps') = (t,t+t',p) : arrange (t+t') tps'

-- | Alias for @timeCat@
Expand Down Expand Up @@ -418,17 +422,19 @@ pattern to multiple patterns at once:
> ] # speed "[[1 0.8], [1.5 2]*2]/3"
-}
stack :: [Pattern a] -> Pattern a
stack = foldr overlay silence
stack pats = (foldr overlay silence pats) {tactus = t}
where t | length pats == 0 = Nothing
| otherwise = foldl1 lcmr <$> (sequence $ map tactus pats)

-- ** Manipulating time

-- | Shifts a pattern back in time by the given amount, expressed in cycles
(<~) :: Pattern Time -> Pattern a -> Pattern a
(<~) = tParam rotL
(<~) = patternify' rotL

-- | Shifts a pattern forward in time by the given amount, expressed in cycles
(~>) :: Pattern Time -> Pattern a -> Pattern a
(~>) = tParam rotR
(~>) = patternify' rotR

{-| Slow down a pattern by the factors in the given time pattern, "squeezing"
the pattern to fit the slot given in the time pattern. It is the slow analogue
Expand All @@ -453,7 +459,7 @@ stack = foldr overlay silence
> d1 $ s "bd*4 bd*2 [bd bd/2]"
-}
slowSqueeze :: Pattern Time -> Pattern a -> Pattern a
slowSqueeze = tParamSqueeze _slow
slowSqueeze = patternifySqueeze _slow

-- | An alias for @slow@
sparsity :: Pattern Time -> Pattern a -> Pattern a
Expand All @@ -477,7 +483,7 @@ zoom :: (Time, Time) -> Pattern a -> Pattern a
zoom (s,e) = zoomArc (Arc s e)

zoomArc :: Arc -> Pattern a -> Pattern a
zoomArc (Arc s e) p = splitQueries $
zoomArc (Arc s e) p = withTactus (*d) $ splitQueries $
withResultArc (mapCycle ((/d) . subtract s)) $ withQueryArc (mapCycle ((+s) . (*d))) p
where d = e-s

Expand All @@ -488,7 +494,7 @@ zoomArc (Arc s e) p = splitQueries $
would be empty). The factor should be at least 1.
-}
fastGap :: Pattern Time -> Pattern a -> Pattern a
fastGap = tParam _fastGap
fastGap = patternify _fastGap

-- | An alias for @fastGap@
densityGap :: Pattern Time -> Pattern a -> Pattern a
Expand Down Expand Up @@ -519,7 +525,7 @@ compressTo :: (Time,Time) -> Pattern a -> Pattern a
compressTo (s,e) = compressArcTo (Arc s e)

repeatCycles :: Pattern Int -> Pattern a -> Pattern a
repeatCycles = tParam _repeatCycles
repeatCycles = patternify _repeatCycles

_repeatCycles :: Int -> Pattern a -> Pattern a
_repeatCycles n p = cat (replicate n p)
Expand Down Expand Up @@ -634,10 +640,10 @@ _getP :: a -> (Value -> Maybe a) -> Pattern Value -> Pattern a
_getP d f pat = fromMaybe d . f <$> pat

_cX :: a -> (Value -> Maybe a) -> String -> Pattern a
_cX d f s = Pattern $ \(State a m) -> queryArc (maybe (pure d) (_getP d f . valueToPattern) $ Map.lookup s m) a
_cX d f s = pattern $ \(State a m) -> queryArc (maybe (pure d) (_getP d f . valueToPattern) $ Map.lookup s m) a

_cX_ :: (Value -> Maybe a) -> String -> Pattern a
_cX_ f s = Pattern $ \(State a m) -> queryArc (maybe silence (_getP_ f . valueToPattern) $ Map.lookup s m) a
_cX_ f s = pattern $ \(State a m) -> queryArc (maybe silence (_getP_ f . valueToPattern) $ Map.lookup s m) a

cF :: Double -> String -> Pattern Double
cF d = _cX d getF
Expand Down
Loading
Loading