packages feed

tidal 1.9.2 → 1.9.3

raw patch · 22 files changed

+437/−354 lines, 22 filesdep ~hoscdep ~primitivePVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: hosc, primitive

API changes (from Hackage documentation)

- Sound.Tidal.Control: reset :: Show a => a -> Pattern b -> Pattern b
- Sound.Tidal.Core: _fast :: Time -> Pattern a -> Pattern a
- Sound.Tidal.Core: _slow :: Time -> Pattern a -> Pattern a
- Sound.Tidal.Core: density :: Pattern Time -> Pattern a -> Pattern a
- Sound.Tidal.Core: fast :: Pattern Time -> Pattern a -> Pattern a
- Sound.Tidal.Core: fastSqueeze :: Pattern Time -> Pattern a -> Pattern a
- Sound.Tidal.Core: rev :: Pattern a -> Pattern a
- Sound.Tidal.Core: silence :: Pattern a
- Sound.Tidal.Core: slow :: Pattern Time -> Pattern a -> Pattern a
- Sound.Tidal.Params: acceleraterecv :: Pattern Int -> ControlPattern
- Sound.Tidal.Params: beginrecv :: Pattern Int -> ControlPattern
- Sound.Tidal.Tempo: ResetCycles :: TempoAction
- Sound.Tidal.Tempo: [nowEnd] :: State -> Micros
- Sound.Tidal.Tempo: instance GHC.Show.Show Sound.OSC.Transport.FD.UDP.UDP
- Sound.Tidal.Tempo: resetCycles :: MVar [TempoAction] -> IO ()
+ Sound.Tidal.Chords: minorMajor7 :: Num a => [a]
+ Sound.Tidal.Control: mt :: Int -> Pattern a -> Pattern a
+ Sound.Tidal.Control: mtrigger :: Int -> Pattern a -> Pattern a
+ Sound.Tidal.Pattern: _fast :: Time -> Pattern a -> Pattern a
+ Sound.Tidal.Pattern: _slow :: Time -> Pattern a -> Pattern a
+ Sound.Tidal.Pattern: density :: Pattern Time -> Pattern a -> Pattern a
+ Sound.Tidal.Pattern: fast :: Pattern Time -> Pattern a -> Pattern a
+ Sound.Tidal.Pattern: fastSqueeze :: Pattern Time -> Pattern a -> Pattern a
+ Sound.Tidal.Pattern: focusArc :: Arc -> Pattern a -> Pattern a
+ Sound.Tidal.Pattern: rev :: Pattern a -> Pattern a
+ Sound.Tidal.Pattern: silence :: Pattern a
+ Sound.Tidal.Pattern: slow :: Pattern Time -> Pattern a -> Pattern a
+ Sound.Tidal.Pattern: withQueryControls :: (ValueMap -> ValueMap) -> Pattern a -> Pattern a
+ Sound.Tidal.Tempo: SetCycle :: Time -> TempoAction
+ Sound.Tidal.Tempo: instance GHC.Show.Show Sound.Osc.Transport.Fd.Udp.Udp
+ Sound.Tidal.Tempo: setCycle :: Time -> MVar [TempoAction] -> IO ()
+ Sound.Tidal.UI: ghostWith :: Time -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a
- Sound.Tidal.Control: ctrigger :: Show a => a -> Pattern b -> Pattern b
+ Sound.Tidal.Control: ctrigger :: Pattern a -> Pattern a
- Sound.Tidal.Control: ftrigger :: Show a => a -> Pattern b -> Pattern b
+ Sound.Tidal.Control: ftrigger :: Pattern a -> Pattern a
- Sound.Tidal.Control: qt :: Show a => a -> Pattern b -> Pattern b
+ Sound.Tidal.Control: qt :: Pattern a -> Pattern a
- Sound.Tidal.Control: qtrigger :: Show a => a -> Pattern b -> Pattern b
+ Sound.Tidal.Control: qtrigger :: Pattern a -> Pattern a
- Sound.Tidal.Control: rtrigger :: Show a => a -> Pattern b -> Pattern b
+ Sound.Tidal.Control: rtrigger :: Pattern a -> Pattern a
- Sound.Tidal.Control: trigger :: Show a => a -> Pattern b -> Pattern b
+ Sound.Tidal.Control: trigger :: Pattern a -> Pattern a
- Sound.Tidal.Control: triggerWith :: Show a => (Time -> Time) -> a -> Pattern b -> Pattern b
+ Sound.Tidal.Control: triggerWith :: (Time -> Time) -> Pattern a -> Pattern a
- Sound.Tidal.Tempo: ActionHandler :: (TickState -> LinkOperations -> ValueMap -> IO ValueMap) -> (LinkOperations -> ValueMap -> ControlPattern -> IO ValueMap) -> (ID -> ControlPattern -> IO ()) -> ActionHandler
+ Sound.Tidal.Tempo: ActionHandler :: (TickState -> LinkOperations -> ValueMap -> IO ValueMap) -> (LinkOperations -> ValueMap -> ControlPattern -> IO ValueMap) -> (ID -> Time -> ControlPattern -> IO ()) -> ActionHandler
- Sound.Tidal.Tempo: State :: Int64 -> Micros -> Micros -> Arc -> Double -> State
+ Sound.Tidal.Tempo: State :: Int64 -> Micros -> Arc -> Double -> State
- Sound.Tidal.Tempo: [updatePattern] :: ActionHandler -> ID -> ControlPattern -> IO ()
+ Sound.Tidal.Tempo: [updatePattern] :: ActionHandler -> ID -> Time -> ControlPattern -> IO ()

Files

BootTidal.hs view
@@ -27,6 +27,7 @@     nudgeAll = streamNudgeAll tidal     all = streamAll tidal     resetCycles = streamResetCycles tidal+    setCycle = streamSetCycle tidal     setcps = asap . cps     getcps = streamGetcps tidal     getnow = streamGetnow tidal
CHANGELOG.md view
@@ -1,19 +1,17 @@ # TidalCycles log of changes -## 1.9.2-+## 1.9.2 - Siteswap c Same with 1.9.1, but now with new tidal-link version 1.0.1 -## 1.9.1-+## 1.9.1 - Siteswap b A quick release to set specific tidal-link version 1.0 in tidal.cabal. Stack seems to want this. -## 1.9.0+## 1.9.0 - Siteswap -## What's Changed+### What's Changed -### General enhancements+#### General enhancements * Rename linux binary name by @ndr-brt in https://github.com/tidalcycles/Tidal/pull/911 * Fix echo by @ndr-brt in https://github.com/tidalcycles/Tidal/pull/910 * If first argument of euclid is negative, apply euclidInv by @polymorphicengine in https://github.com/tidalcycles/Tidal/pull/916@@ -21,39 +19,37 @@ * Make chunk reverse direction with negative number by @ndr-brt in https://github.com/tidalcycles/Tidal/pull/918 * overhaul of the chord parser by @polymorphicengine in https://github.com/tidalcycles/Tidal/pull/931 -### New ableton link support+#### New ableton link support * Use ableton link for scheduling by @Zalastax in https://github.com/tidalcycles/Tidal/pull/898 * tidal-link: add link source files to extra-source-files, fixes #924 by @yaxu in https://github.com/tidalcycles/Tidal/pull/925 * Use target latency in all send modes by @Zalastax in https://github.com/tidalcycles/Tidal/pull/927 * Rename cCyclesPerBeat -> cBeatsPerCycle by @Zalastax in https://github.com/tidalcycles/Tidal/pull/939 -### Emacs plugin updates+#### Emacs plugin updates * formatting fixes in tidal.el by @zzkt in https://github.com/tidalcycles/Tidal/pull/932 * a window-excursion for tidal.el by @zzkt in https://github.com/tidalcycles/Tidal/pull/933 * autoloads for tidal.el by @zzkt in https://github.com/tidalcycles/Tidal/pull/934 * avoid race in loading bootscript during restart by @zzkt in https://github.com/tidalcycles/Tidal/pull/937 -### Tidal-parse (estuary) updates+#### Tidal-parse (estuary) updates * Various updates to tidal-parse by @dktr0 in https://github.com/tidalcycles/Tidal/pull/913 and  https://github.com/tidalcycles/Tidal/pull/941 -### Maintenance+#### Maintenance * Increase upper bounds of text dependency by @yaxu in https://github.com/tidalcycles/Tidal/pull/948 * Use system-cxx-std-lib by @Zalastax in https://github.com/tidalcycles/Tidal/pull/944 * Use c++ extra library for MacOS by @giuseppelillo in https://github.com/tidalcycles/Tidal/pull/946 -## New Contributors+### New Contributors * @Zalastax made their first contribution in https://github.com/tidalcycles/Tidal/pull/898 * @zzkt made their first contribution in https://github.com/tidalcycles/Tidal/pull/932 * @giuseppelillo made their first contribution in https://github.com/tidalcycles/Tidal/pull/946  **Full Changelog**: https://github.com/tidalcycles/Tidal/compare/v1.8.0...v1.9.0 -## 1.8.1-+## 1.8.1 - Sanquhar b * Removed executable from tidal.cabal file (while latest ghc on windows fails to build it)  ## 1.8.0 - Sanquhar- * move tidal-listener code by @polymorphicengine in #885 * Fix a typo incurred (I assume) by a filename change. by @JeffreyBenjaminBrown in #886 * Hide contexts from Events per default by @polymorphicengine in #887@@ -68,7 +64,6 @@ Commit list: https://github.com/tidalcycles/Tidal/compare/1.7.10...v1.8.0  ## 1.7.10 - Tama b- * Derive RealFrac for Note by @ndr-brt in https://github.com/tidalcycles/Tidal/pull/876 * Add timescale and timewin control params by @yaxu in https://github.com/tidalcycles/Tidal/pull/878 * deriving typeclass memberships for ID by @polymorphicengine in https://github.com/tidalcycles/Tidal/pull/879@@ -112,152 +107,149 @@ **Full Changelog**: https://github.com/tidalcycles/Tidal/compare/1.7.8...1.7.9  ## 1.7.8 - Ayatakedai-   * Add pattern id to patterns as _id_, and send it with /code/highlights+* Add pattern id to patterns as _id_, and send it with /code/highlights  ## 1.7.7 - Caramel wafer-   * Support hosc 0.19 in test suite @yaxu+* Support hosc 0.19 in test suite @yaxu  ## 1.7.6 - Tunnocks-   * Fix dot shorthand in int patterns so floating point numbers raise an error @ndr-brt-   * Support factors in ratio shorthand for rational patterns @ndr-brt-   * support hosc 0.19 @yaxu+* Fix dot shorthand in int patterns so floating point numbers raise an error @ndr-brt+* Support factors in ratio shorthand for rational patterns @ndr-brt+* support hosc 0.19 @yaxu  ## 1.7.5 - Dalbeattie-   * Minor change to _splice so that it respects if the speed parameter was already declared @onthepeakofnormal-   * Some tests for chords @cleary-   * Remove direct semigroups dependency @yaxu-   * Derive functor for pattern @yaxu-   * Handle negative ratio shorthands for rationals @ndr_brt-   * drawLine - draw non-events with periods @yaxu-   * Parse chord without root note @yaxu-   * Fix clock sharing between tidal processes @yaxu+* Minor change to _splice so that it respects if the speed parameter was already declared @onthepeakofnormal+* Some tests for chords @cleary+* Remove direct semigroups dependency @yaxu+* Derive functor for pattern @yaxu+* Handle negative ratio shorthands for rationals @ndr_brt+* drawLine - draw non-events with periods @yaxu+* Parse chord without root note @yaxu+* Fix clock sharing between tidal processes @yaxu  ## 1.7.4 - Symonds Yat b-   * Fixes for bipolar waveforms (sine2, etc) @mindofmatthew-   * More playback controls for OSC API @mindofmatthew-   * Disable bus variants for MIDI controls @mindofmatthew+* Fixes for bipolar waveforms (sine2, etc) @mindofmatthew+* More playback controls for OSC API @mindofmatthew+* Disable bus variants for MIDI controls @mindofmatthew  ## 1.7.3 - Symonds Yat-   * Signed ratio shorthands now supported @ndr_brt-   * OSC API - mute/unmute stream @mindofmatthew-   * improve performance of playFor/seqP @yaxu-   * Expand tests with autodiscovered laws @RSWilli-   * Add `getState` to BootTidal @mindofmatthew-   * add fadeTime / fadeInTime / fadeOutTime params for grain envelopes @yaxu-   * Fix for nrpnn and nrpnv params @yaxu-   * Disable busses for MIDI parameters @mindofmatthew+* Signed ratio shorthands now supported @ndr_brt+* OSC API - mute/unmute stream @mindofmatthew+* improve performance of playFor/seqP @yaxu+* Expand tests with autodiscovered laws @RSWilli+* Add `getState` to BootTidal @mindofmatthew+* add fadeTime / fadeInTime / fadeOutTime params for grain envelopes @yaxu+* Fix for nrpnn and nrpnv params @yaxu+* Disable busses for MIDI parameters @mindofmatthew     ## 1.7.2 - IKLECTIK c-   * tidal-parse additions and improved errors, haskellish dependency fix @dktr0-   * spring cleaning and delinting, recreated Time.hs, renamed ControlMap toValueMAp @yaxu-   * start of [major refactoring of chords](https://club.tidalcycles.org/t/rfc-working-on-making-chord-naming-chordlist-more-consistent/2717/56) @cleary-   * fix `.` mininotation operator @zudov-   * stateful event parameters, for counting @yaxu-   * Move some stuff from BootTidal.hs to the tidal library, to reduce dependencies there @yaxu+* tidal-parse additions and improved errors, haskellish dependency fix @dktr0+* spring cleaning and delinting, recreated Time.hs, renamed ControlMap toValueMAp @yaxu+* start of [major refactoring of chords](https://club.tidalcycles.org/t/rfc-working-on-making-chord-naming-chordlist-more-consistent/2717/56) @cleary+* fix `.` mininotation operator @zudov+* stateful event parameters, for counting @yaxu+* Move some stuff from BootTidal.hs to the tidal library, to reduce dependencies there @yaxu  ## 1.7.1 - IKLECTIK b-        * Fix stack build @yaxu-        * Add tidal_status command @yaxu-	* Add cVerbose config setting (default on) @yaxu-	* Fix for emacs plugin @jwaldmann-	* Snowball bugfix @yaxu-	* Migrate to github actions, tested against additional ghc versions @ndr_brt-	* Fix mininotation bug - allow leading/trailing spaces @ndr_brt-	* Make linger work with negative numbers (to linger on end of cycle rather than start) @yaxu-	* Friendlier startup messages @yaxu-	* Compatibility with ghc 9.0.1 @yaxu+* Fix stack build @yaxu+* Add tidal_status command @yaxu+* Add cVerbose config setting (default on) @yaxu+* Fix for emacs plugin @jwaldmann+* Snowball bugfix @yaxu+* Migrate to github actions, tested against additional ghc versions @ndr_brt+* Fix mininotation bug - allow leading/trailing spaces @ndr_brt+* Make linger work with negative numbers (to linger on end of cycle rather than start) @yaxu+* Friendlier startup messages @yaxu+* Compatibility with ghc 9.0.1 @yaxu  ## 1.7 - IKLECTIK-	* Added drum aliases from GM2 percussion spec to `drum` function @lvm-	* `getcps` helper function now in BootTidal.hs @yaxu-	* `getnow` helper function back in BootTidal.hs (returns current cycle) @bgold-cosmos-	* Developments towards tidal api, @yaxu et al-	* `coarse` parameter is now floating point @lwlsn-	* `irand` parameter now patternable @ndr-brt- 	* `note` now produces its own type to avoid conflicts between parsing note names and duration shorthands  @ndr-brt-	* Numerous tidal-parse improvements and additions @dktr0 et al-	* `grain` function for combining begin and end (in terms of begin and duration) @khoparzi-	* Added missing pB and pR functions @thgrund-	* Emacs plugin bugfixes @jwaldmann-	* `binaryN` parameters now fully patternable @ndr-brt-	* `press` and `pressBy` functions for syncopation @yaxu-	* `bite`'s first parameter is now patternable @ndr-brt-	* Most SuperDirt control/effect parameters can now be modified while a sound is playing, using 'bus' functions. @telefon + @yaxu-	* Sound.Tidal.Params is now generated by a script in bin/generate-params.hs @yaxu-	* `qtrigger` is now an alias for `ctrigger`, which now quantises to the _next_ cycle (via ceiling) @thgund / @yaxu-	* There is now also `ftrigger` and `rtrigger` for floor (previous) and round (nearest) cycle-	* `whenmod`'s first two parameters are now rationals, and patternable. @th-four / @yaxu-        * `brand` and `brandBy` for continuous patterns of boolean values @yaxu-        * Two-way protocol between Tidal and SuperDirt, initially to receive available busses @telefon / @yaxu-        * bipolar waveforms - sine2, square2, tri2, saw2, cosine2 @yaxu+* Added drum aliases from GM2 percussion spec to `drum` function @lvm+* `getcps` helper function now in BootTidal.hs @yaxu+* `getnow` helper function back in BootTidal.hs (returns current cycle) @bgold-cosmos+* Developments towards tidal api, @yaxu et al+* `coarse` parameter is now floating point @lwlsn+* `irand` parameter now patternable @ndr-brt+* `note` now produces its own type to avoid conflicts between parsing note names and duration shorthands  @ndr-brt+* Numerous tidal-parse improvements and additions @dktr0 et al+* `grain` function for combining begin and end (in terms of begin and duration) @khoparzi+* Added missing pB and pR functions @thgrund+* Emacs plugin bugfixes @jwaldmann+* `binaryN` parameters now fully patternable @ndr-brt+* `press` and `pressBy` functions for syncopation @yaxu+* `bite`'s first parameter is now patternable @ndr-brt+* Most SuperDirt control/effect parameters can now be modified while a sound is playing, using 'bus' functions. @telefon + @yaxu+* Sound.Tidal.Params is now generated by a script in bin/generate-params.hs @yaxu+* `qtrigger` is now an alias for `ctrigger`, which now quantises to the _next_ cycle (via ceiling) @thgund / @yaxu+* There is now also `ftrigger` and `rtrigger` for floor (previous) and round (nearest) cycle+* `whenmod`'s first two parameters are now rationals, and patternable. @th-four / @yaxu+* `brand` and `brandBy` for continuous patterns of boolean values @yaxu+* Two-way protocol between Tidal and SuperDirt, initially to receive available busses @telefon / @yaxu+* bipolar waveforms - sine2, square2, tri2, saw2, cosine2 @yaxu     ## 1.6.1 - We are not DJs-	* Patternise first parameter of chunk @lwlsn-	* Patternise fit parameter @bgold-cosmos-	* Increase upper bounds of random @yaxu-	* Switch travis to ubuntu bionic @yaxu+* Patternise first parameter of chunk @lwlsn+* Patternise fit parameter @bgold-cosmos+* Increase upper bounds of random @yaxu+* Switch travis to ubuntu bionic @yaxu  ## 1.6.0 - Keep live coding live-	* Rollback to previous pattern on parse error @jwaldmann-	* Increased strictness to catch parse errors earlier @jwaldmann @yaxu-	* Support for superdirt 'panic' @yaxu-	* Increase hosc upper bounds to admin 0.18-	* New function 'splat' @yaxu-	* `quantise` now uses round, add qfloor, qceiling variants and qround alis @lwlsn-	* Add ghc 8.8.3 to travis @jwaldmann-	* Switch `substruct` to use binary pattern @yaxu+* Rollback to previous pattern on parse error @jwaldmann+* Increased strictness to catch parse errors earlier @jwaldmann @yaxu+* Support for superdirt 'panic' @yaxu+* Increase hosc upper bounds to admin 0.18+* New function 'splat' @yaxu+* `quantise` now uses round, add qfloor, qceiling variants and qround alis @lwlsn+* Add ghc 8.8.3 to travis @jwaldmann+* Switch `substruct` to use binary pattern @yaxu  ## 1.5.2 - Rivelin-        * Fix streamAll+* Fix streamAll  ## 1.5.1 - Blacka Moor-	* Bugfix splice+* Bugfix splice  ## 1.5.0 - Active travel-	* Export drawLineSz @mxmxyz-	* tidal-parse additions (bite, splice, pickF, select, squeeze; fixed slice) @dktr0-	* New, more efficient pseudorandom number generator @dktr0-	* Pattern first someCyclesBy param @bgold-cosmos-	* Refactored, more flexible OSC targetting @yaxu-	* Simplify tidal-boot-script in tidal.el @jamagin-	* Support state substitution in mininotation #530 @yaxu-	* Pattern first parameter of splice #656 @yaxu-	* Pattern first parameter of chew @yaxu-	* add 'x' fraction alias for 1/6 @yaxu-	* add dfb alias for delayfeedback param, dt for delaytime @yaxu-	* add unmuteAll and only to BootTidal.hs @yaxu+* Export drawLineSz @mxmxyz+* tidal-parse additions (bite, splice, pickF, select, squeeze; fixed slice) @dktr0+* New, more efficient pseudorandom number generator @dktr0+* Pattern first someCyclesBy param @bgold-cosmos+* Refactored, more flexible OSC targetting @yaxu+* Simplify tidal-boot-script in tidal.el @jamagin+* Support state substitution in mininotation #530 @yaxu+* Pattern first parameter of splice #656 @yaxu+* Pattern first parameter of chew @yaxu+* add 'x' fraction alias for 1/6 @yaxu+* add dfb alias for delayfeedback param, dt for delaytime @yaxu+* add unmuteAll and only to BootTidal.hs @yaxu  ## 1.4.9 - Housebound spirit-	* Simplify 'show'ing of patterns @yaxu-	* New `draw` function for drawing a pattern of single characters as a text-based diagram,-	  with friends `drawLine` and `drawLineSz` for drawing multiple cycles @yaxu-	* Fixes and expansions of ratio aliases - s should be a sixteenth @mxmxyz, w is now 1, f is now 0.2-	* Simplify definition of `accumulate` using scanl @benjwadams-	* The first parameter of `someCyclesBy` is now patternable @bgold-cosmos+* Simplify 'show'ing of patterns @yaxu+* New `draw` function for drawing a pattern of single characters as a text-based diagram, with friends `drawLine` and `drawLineSz` for drawing multiple cycles @yaxu+* Fixes and expansions of ratio aliases - s should be a sixteenth @mxmxyz, w is now 1, f is now 0.2+* Simplify definition of `accumulate` using scanl @benjwadams+* The first parameter of `someCyclesBy` is now patternable @bgold-cosmos  ## 1.4.8 - Limerick-        * Add ratio shorthand to floating point patterns @yaxu-        * Support fractional scales, add Arabic scales @quakehead-        * Additions to tidal-parse including support from overgain, overshape adn rot @dktr0-        * Move prompt-cont setting to end of BootTidal.hs (older versions of Haskell crash out at this point) @ndr-brt-## 1.4.7 - Bleep+* Add ratio shorthand to floating point patterns @yaxu+* Support fractional scales, add Arabic scales @quakehead+* Additions to tidal-parse including support from overgain, overshape adn rot @dktr0+* Move prompt-cont setting to end of BootTidal.hs (older versions of Haskell crash out at this point) @ndr-brt -	* Fix BootTidal.hs - make loadable in atom @bgold-cosmos-	* More additions to tidal-parse @dktr0+## 1.4.7 - Bleep+* Fix BootTidal.hs - make loadable in atom @bgold-cosmos+* More additions to tidal-parse @dktr0  ## 1.4.6 - Megatron--	* Experimental ratio shorthand ref #573 @yaxu-	* Store mininotation source location(s) in events ref #245 @yaxu-	* Add more things to tidal-parse @dktr0 @yaxu-	* Separate out haskell parser from tidal-parse into new hackage module called 'haskellish' @dktr0-	* Support patterning polyrhythmic % steps in mininotation @yaxu-	* Fixes to emacs plugin (tidal.el) @xmacex-	* New parameters for freq, overgain, overshape, and missing midi params including the new nrpn ones @yaxu+* Experimental ratio shorthand ref #573 @yaxu+* Store mininotation source location(s) in events ref #245 @yaxu+* Add more things to tidal-parse @dktr0 @yaxu+* Separate out haskell parser from tidal-parse into new hackage module called 'haskellish' @dktr0+* Support patterning polyrhythmic % steps in mininotation @yaxu+* Fixes to emacs plugin (tidal.el) @xmacex+* New parameters for freq, overgain, overshape, and missing midi params including the new nrpn ones @yaxu  ## 1.4.5 - Porter Brook- * Mini notation - `@` (and its alias `_`) now accepts rational relative durations. E.g. `a b@0.5 c d` to make `b` have a half step (that would be the same as `a@2 b c@2 c@d`). This can also be patterned `a b@<0.5 2> c d` @yaxu #435 * Experimental `reset` function - stick in a pattern so it acts as though the cycle number was reset to 0, from the next cycle @yaxu * Bugfix for setR in BootTidal.hs @yaxu@@ -270,7 +262,6 @@ * Many tidal-parse updates @dktr0  ## 1.4.4 - Chee Dale- * wrandcat (weighted randcat) @yaxu * MIDI Sysex support #558 @yaxu * Elements in an Open Sound Control path address can now be patterned #557@@ -280,39 +271,31 @@ * Add power pattern operators |**, **| and |**| @yaxu  ## 1.4.3 - Stanage Edge- * Fix for xfade / xfadein transition * New function plyWith  ## 1.4.2 - Higger Tor- * Fix for 'nudge'  ## 1.4.1 - Carl Wark- * improvements to handling of cps changes @yaxu #501 * fix for parameter patterning in 'range' @yaxu #547  ## 1.4.0 - Padley Gorge- * fix representation to handle continuous and analog events properly @yaxu  ## 1.3.0 - rolled back to 1.1.2  ## 1.2.0 - Hunters Bar- * Simplify <* and *>, removing any distinction between analogue and digital patterns  ## 1.1.2 - Eccy Road- * Usability fix for `binary` / `binaryN` (use squeezeJoin on input pattern)  ## 1.1.1 - Chelsea Park- * Usability fixes for `binary` / `binaryN` / `ascii` @yaxu  ## 1.1.0 - Brincliffe Edge- * `binary` and `ascii` functions for playing with bit patterns @yaxu * support chord inversions in chord parser @bgold-cosmos * skip ticks when system clock jumps @yaxu@@ -331,7 +314,6 @@ * minitidal refactor, support for parsing more of tidal, tests @dktr0  ## 1.0.14 - IICON- * 'chew' - like bite, but speeds playback rate up and down * variable probability for ? in mini notation * chooseBy takes modulo of index to avoid out of bounds errors@@ -339,32 +321,29 @@ * Fix dependencies for parsec/colour  ## 1.0.13 - 🐝⌛️🦋 #2- * Simplify espgrid support - @yaxu  ## 1.0.12 - 🐝⌛️🦋- * Fix ESPGrid support - @dktr0 * Add 'snowball' function - @XiNNiW  ## 1.0.11 - Cros Bríde- 2019-04-17  Alex McLean  <alex@slab.org>-	* Add `bite` function for slicing patterns (rather than samples)-	* Tweak tidal.el to attempt to infer location of default BootTidal.hs-	* Skip time (forward or backward) if the reference clock jumps suddenly-	* Fix `fit` - @bgold-cosmos-	* Remove 'asap'-	* Add cB for boolean control input-	* `pickF` for choosing between functions with a pattern of integers-	* `select` for choosing between list of patterns with a floating point pattern-	* `squeeze` for choosing between list of patterns with a pattern of integers, where patterns are squeezed into the integer event duration-	* `splice` for choosing between slices of a pattern, where the slices are squeezed into event duration-	* Ord and Eq instances for value type @bgold-cosmos-	* `trigger` - support for resetting envelopes on evaluation-	* Support for rational event values-	* Tweak how `*>` and `<*` deal with analog patterns-	* Caribiner link bridge support+* Add `bite` function for slicing patterns (rather than samples)+* Tweak tidal.el to attempt to infer location of default BootTidal.hs+* Skip time (forward or backward) if the reference clock jumps suddenly+* Fix `fit` - @bgold-cosmos+* Remove 'asap'+* Add cB for boolean control input+* `pickF` for choosing between functions with a pattern of integers+* `select` for choosing between list of patterns with a floating point pattern+* `squeeze` for choosing between list of patterns with a pattern of integers, where patterns are squeezed into the integer event duration+* `splice` for choosing between slices of a pattern, where the slices are squeezed into event duration+* Ord and Eq instances for value type @bgold-cosmos+* `trigger` - support for resetting envelopes on evaluation+* Support for rational event values+* Tweak how `*>` and `<*` deal with analog patterns+* Caribiner link bridge support  ## 1.0.10 - This machine also kills fascists * Add exports to Sound.Tidal.Scales for `getScale` and `scaleTable`@@ -378,10 +357,8 @@ * `djf` control ready for new superdirt dj filter @yaxu * `getScale` for handrolling/adding scales to `scale` function	* Add `djf` control for upcoming superdirt dj filter @yaxu -## 1.0.8 (trying to get back to doing these, -## see also https://tidalcycles.org/index.php/Changes_in_Tidal_1.0.x -## for earlier stuff)-+## 1.0.8 (trying to get back to doing these)+**See also https://tidalcycles.org/index.php/Changes_in_Tidal_1.0.x for earlier stuff)** * Add 'to', 'toArg' and 'from' controls for new superdirt routing experiments - @telephon * Fixes for squeezeJoin (nee unwrap') - @bgold-cosmos * Simplify `cycleChoose`, it is now properly discrete (one event per cycle) - @yaxu@@ -398,7 +375,6 @@ * fix for `sometimesBy` - @yaxu  ## 0.9.10 (and earlier missing versions from this log)- * arpg, a function to arpeggiate * within', an alternate within with a different approach to time, following discussion here https://github.com/tidalcycles/Tidal/issues/313 * sine et al are now generalised so can be used as double or rational patterns@@ -415,7 +391,6 @@ ## 0.9.7  ### Enhancements- * The `note` pattern parameter is no longer an alias for `midinote`,   but an independent parameter for supercollider to handle (in a manner   similar to `up`)@@ -423,14 +398,12 @@ ## 0.9.6  ### Enhancements- * Added `chord` for chord patterns and `scaleP` for scale patterns * The `n` pattern parameter is now floating point  ## 0.9.5  ### Enhancements- * Added `hurry` which both speeds up the sound and the pattern by the given amount. * Added `stripe` which repeats a pattern a given number of times per   cycle, with random but contiguous durations.@@ -444,14 +417,12 @@ ## 0.9.4  ### Fixes- * Swapped `-` for `..` in ranges as quick fix for issue with parsing negative numbers * Removed overloaded list thingie for now, unsure whether it's worth the dependency  ## 0.9.3  ### Enhancements- * The sequence parser can now expand ranges, e.g. `"0-3 4-2"` is   equivalent to `"[0 1 2 3] [4 3 2]"` * Sequences can now be described using list syntax, for example `sound ["bd", "sn"]` is equivalent to `sound "bd sn"`. They *aren't* lists though, so you can't for example do `sound (["bd", "sn"] ++ ["arpy", "cp"])` -- but can do `sound (append ["bd", "sn"]  ["arpy", "cp"])`@@ -462,6 +433,5 @@ * The start of automatic testing for a holy bug-free future  ### Fixes- * Fixed bug that was causing events to double up or get lost,   e.g. where `rev` was combined with certain other functions.
bench/Memory/Tidal/UIB.hs view
@@ -2,8 +2,7 @@  import Weigh  import Tidal.Inputs -import Sound.Tidal.UI-import Sound.Tidal.Core+import Sound.Tidal.Context  fixB :: Weigh ()  fixB = 
bench/Speed/Tidal/UIB.hs view
@@ -4,8 +4,7 @@  import Criterion.Main import Tidal.Inputs-import Sound.Tidal.Core-import Sound.Tidal.UI +import Sound.Tidal.Context  fixB :: [Benchmark] fixB = 
src/Sound/Tidal/Chords.hs view
@@ -95,6 +95,8 @@ minor11 = [0,3,7,10,14,17] minor13 :: Num a => [a] minor13 = [0,3,7,10,14,17,21]+minorMajor7 :: Num a => [a]+minorMajor7 = [0,3,7,11] -- other chords one :: Num a => [a] one = [0]@@ -233,6 +235,9 @@               ("minor13", minor13),               ("min13", minor13),               ("m13", minor13),+              ("minorMajor7", minorMajor7),+              ("minMaj7", minorMajor7),+              ("mmaj7", minorMajor7),               ("one", one),               ("1", one),               ("five", five),
src/Sound/Tidal/Control.hs view
@@ -29,6 +29,7 @@  import Sound.Tidal.Pattern import Sound.Tidal.Core+import Sound.Tidal.Stream (patternTimeID) import Sound.Tidal.UI import qualified Sound.Tidal.Params as P import Sound.Tidal.Utils@@ -412,38 +413,68 @@ msec :: Fractional a => Pattern a -> Pattern a msec p = (realToFrac . (/1000) <$> cF 1 "_cps") *| p -triggerWith :: Show a => (Time -> Time) -> a -> Pattern b -> Pattern b-triggerWith f k pat = pat {query = q}-  where q st = query (rotR (offset st) pat) st-        offset st = fromMaybe 0 $ do v <- Map.lookup ctrl (controls st)-                                     return (f $ fromMaybe 0 $ getR v)-        ctrl = "_t_" ++ show k--trigger :: Show a => a -> Pattern b -> Pattern b+-- | Align the start of a pattern with the time a pattern is evaluated,+-- rather than the global start time. Because of this, the pattern will+-- probably not be aligned to the pattern grid.+trigger :: Pattern a -> Pattern a trigger = triggerWith id -ctrigger :: Show a => a -> Pattern b -> Pattern b-ctrigger = triggerWith $ (fromIntegral :: Int -> Rational) . ceiling--qtrigger :: Show a => a -> Pattern b -> Pattern b+-- | (Alias @__qt__@) Quantise trigger. Aligns the start of the pattern+-- with the next cycle boundary. For example, this pattern will fade in+-- starting with the next cycle after the pattern is evaluated:+-- +-- @+-- d1 $ qtrigger $ s "hh(5, 8)" # amp envL+-- @+-- +-- Note that the pattern will start playing immediately. The /start/ of the+-- pattern aligns with the next cycle boundary, but events will play before+-- if the pattern has events at negative timestamps (which most loops do).+-- These events can be filtered out, for example:+-- +-- @+-- d1 $ qtrigger $ filterWhen (>= 0) $ s "hh(5, 8)"+-- @+qtrigger :: Pattern a -> Pattern a qtrigger = ctrigger -rtrigger :: Show a => a -> Pattern b -> Pattern b+qt :: Pattern a -> Pattern a+qt = qtrigger++-- | Ceiling trigger. Aligns the start of a pattern to the next cycle+-- boundary, just like 'qtrigger'.+ctrigger :: Pattern a -> Pattern a+ctrigger = triggerWith $ (fromIntegral :: Int -> Rational) . ceiling++-- | Rounded trigger. Aligns the start of a pattern to the nearest cycle+-- boundary, either next or previous.+rtrigger :: Pattern a -> Pattern a rtrigger = triggerWith $ (fromIntegral :: Int -> Rational) . round -ftrigger :: Show a => a -> Pattern b -> Pattern b+-- | Floor trigger. Aligns the start of a pattern to the previous cycle+-- boundary.+ftrigger :: Pattern a -> Pattern a ftrigger = triggerWith $ (fromIntegral :: Int -> Rational) . floor -qt :: Show a => a -> Pattern b -> Pattern b-qt = qtrigger+-- | (Alias @__mt__@) Mod trigger. Aligns the start of a pattern to the+-- next cycle boundary where the cycle is evenly divisible by a given+-- number. 'qtrigger' is equivalent to @mtrigger 1@.+mtrigger :: Int -> Pattern a -> Pattern a+mtrigger n = triggerWith $ fromIntegral . nextMod+  where nextMod t = n * ceiling (t / (fromIntegral n)) -reset :: Show a => a -> Pattern b -> Pattern b-reset k pat = pat {query = q}-  where q st = query (rotR (offset st) $ when (<=0) (const silence) pat) st-        f = (fromIntegral :: Int -> Rational) . floor-        offset st = fromMaybe 0 $ do p <- Map.lookup ctrl (controls st)-                                     return (f $ fromMaybe 0 $ getR p)-        ctrl = "_t_" ++ show k+mt :: Int -> Pattern a -> Pattern a+mt = mtrigger++-- | This aligns the start of a pattern to some value relative to the+-- time the pattern is evaluated. The provided function maps the evaluation+-- time (on the global cycle clock) to a new time, and then @triggerWith@+-- aligns the pattern's start to the time that's returned.+triggerWith :: (Time -> Time) -> Pattern a -> Pattern a+triggerWith f pat = pat {query = q}+  where q st = query (rotR (offset st) pat) st+        offset st = fromMaybe 0 $ f+                      <$> (Map.lookup patternTimeID (controls st) >>= getR)  splat :: Pattern Int -> ControlPattern -> ControlPattern -> ControlPattern splat slices epat pat = chop slices pat # bite 1 (const 0 <$> pat) epat
src/Sound/Tidal/Core.hs view
@@ -29,10 +29,6 @@  -- ** Elemental patterns --- | An empty pattern-silence :: Pattern a-silence = empty- -- | Takes a function from time to values, and turns it into a 'Pattern'. sig :: (Time -> a) -> Pattern a sig f = Pattern q@@ -347,67 +343,14 @@ (~>) :: Pattern Time -> Pattern a -> Pattern a (~>) = tParam rotR --- | Speed up a pattern by the given time pattern-fast :: Pattern Time -> Pattern a -> Pattern a-fast = tParam _fast- -- | Slow down a pattern by the factors in the given time pattern, 'squeezing' -- the pattern to fit the slot given in the time pattern-fastSqueeze :: Pattern Time -> Pattern a -> Pattern a-fastSqueeze = tParamSqueeze _fast---- | An alias for @fast@-density :: Pattern Time -> Pattern a -> Pattern a-density = fast--_fast :: Time -> Pattern a -> Pattern a-_fast rate pat | rate == 0 = silence-               | rate < 0 = rev $ _fast (negate rate) pat-               | otherwise = withResultTime (/ rate) $ withQueryTime (* rate) pat---- | Slow down a pattern by the given time pattern-slow :: Pattern Time -> Pattern a -> Pattern a-slow = tParam _slow-_slow :: Time -> Pattern a -> Pattern a-_slow 0 _ = silence-_slow r p = _fast (1/r) p---- | Slow down a pattern by the factors in the given time pattern, 'squeezing'--- the pattern to fit the slot given in the time pattern slowSqueeze :: Pattern Time -> Pattern a -> Pattern a slowSqueeze = tParamSqueeze _slow  -- | An alias for @slow@ sparsity :: Pattern Time -> Pattern a -> Pattern a sparsity = slow---- | @rev p@ returns @p@ with the event positions in each cycle--- reversed (or mirrored).-rev :: Pattern a -> Pattern a-rev p =-  splitQueries $ p {-    query = \st -> map makeWholeAbsolute $-      mapParts (mirrorArc (midCycle $ arc st)) $-      map makeWholeRelative-      (query p st-        {arc = mirrorArc (midCycle $ arc st) (arc st)-        })-    }-  where makeWholeRelative :: Event a -> Event a-        makeWholeRelative e@Event {whole = Nothing} = e-        makeWholeRelative (Event c (Just (Arc s e)) p'@(Arc s' e') v) =-          Event c (Just $ Arc (s'-s) (e-e')) p' v-        makeWholeAbsolute :: Event a -> Event a-        makeWholeAbsolute e@Event {whole = Nothing} = e-        makeWholeAbsolute (Event c (Just (Arc s e)) p'@(Arc s' e') v) =-          Event c (Just $ Arc (s'-e) (e'+s)) p' v-        midCycle :: Arc -> Time-        midCycle (Arc s _) = sam s + 0.5-        mapParts :: (Arc -> Arc) -> [Event a] -> [Event a]-        mapParts f es = (\(Event c w p' v) -> Event c w (f p') v) <$> es-        -- | Returns the `mirror image' of a 'Arc' around the given point in time-        mirrorArc :: Time -> Arc -> Arc-        mirrorArc mid' (Arc s e) = Arc (mid' - (e-mid')) (mid'+(mid'-s))  {- | Plays a portion of a pattern, specified by a time arc (start and end time). The new resulting pattern is played over the time period of the original pattern:
src/Sound/Tidal/Params.hs view
@@ -73,24 +73,49 @@ pX :: String -> Pattern [Word8] -> ControlPattern pX name = fmap (Map.singleton name . VX) -pStateF :: String -> String -> (Maybe Double -> Double) -> ControlPattern-pStateF name sName update = pure $ Map.singleton name $ VState statef+pStateF ::+  String -> -- ^ A parameter, e.g. `note`; a+  -- `String` recognizable by a `ValueMap`.+  String -> -- ^ Identifies the cycling state pattern.+  -- Can be anything the user wants.+  (Maybe Double -> Double) ->+  ControlPattern+pStateF name sName update =+  pure $ Map.singleton name $ VState statef   where statef :: ValueMap -> (ValueMap, Value)-        statef sMap = (Map.insert sName v sMap, v) -          where v = VF $ update $ (Map.lookup sName sMap) >>= getF+        statef sMap = (Map.insert sName v sMap, v)+          where v = VF $ update+                    $ Map.lookup sName sMap >>= getF -pStateList :: String -> String -> [Value] -> ControlPattern-pStateList name sName xs = pure $ Map.singleton name $ VState statef-  where statef :: ValueMap -> (ValueMap, Value)-        statef sMap = (Map.insert sName (VList $ tail looped) sMap, head looped) -          where xs' = fromMaybe xs ((Map.lookup sName sMap) >>= getList)-                -- do this instead of a cycle, so it can get updated with the a list-                looped | null xs' = xs-                       | otherwise = xs'+-- | `pStateList` is made with cyclic lists in mind,+-- but it can even "cycle" through infinite lists.+pStateList ::+  String -> -- ^ A parameter, e.g. `note`; a+  -- `String` recognizable by a `ValueMap`.+  String -> -- ^ Identifies the cycling state pattern.+  -- Can be anything the user wants.+  [Value] -> -- ^ The list to cycle through.+  ControlPattern+pStateList name sName xs =+  pure $ Map.singleton name $ VState statef+  where+    statef :: ValueMap -> (ValueMap, Value)+    statef sMap = ( Map.insert sName+                    (VList $ tail looped) sMap+                  , head looped)+      where xs' = fromMaybe xs+                  $ Map.lookup sName sMap >>= getList+            -- do this instead of a cycle, so it can get updated with the a list+            looped | null xs' = xs+                   | otherwise = xs' +-- | A wrapper for `pStateList` that accepts a `[Double]`+-- rather than a `[Value]`. pStateListF :: String -> String -> [Double] -> ControlPattern pStateListF name sName = pStateList name sName . map VF +-- | A wrapper for `pStateList` that accepts a `[String]`+-- rather than a `[Value]`. pStateListS :: String -> String -> [String] -> ControlPattern pStateListS name sName = pStateList name sName . map VS @@ -200,9 +225,7 @@ accelerateCountTo name ipat = innerJoin $ (\i -> pStateF "accelerate" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat  acceleratebus :: Pattern Int -> Pattern Double -> ControlPattern-acceleratebus busid pat = (pF "accelerate" pat) # (pI "^accelerate" busid)-acceleraterecv :: Pattern Int -> ControlPattern-acceleraterecv busid = pI "^accelerate" busid+acceleratebus _ _ = error $ "Control parameter 'accelerate' can't be sent to a bus."  -- | like @gain@, but linear. amp :: Pattern Double -> ControlPattern@@ -283,9 +306,7 @@ beginCountTo name ipat = innerJoin $ (\i -> pStateF "begin" name (maybe 0 ((`mod'` i) . (+1)))) <$> ipat  beginbus :: Pattern Int -> Pattern Double -> ControlPattern-beginbus busid pat = (pF "begin" pat) # (pI "^begin" busid)-beginrecv :: Pattern Int -> ControlPattern-beginrecv busid = pI "^begin" busid+beginbus _ _ = error $ "Control parameter 'begin' can't be sent to a bus."  -- | Spectral binshift binshift :: Pattern Double -> ControlPattern
src/Sound/Tidal/ParseBP.hs view
@@ -519,20 +519,20 @@ parseChord :: (Enum a, Num a) => MyParser [a] parseChord = do char '\''                 name <- many1 $ letter <|> digit-                let chord = fromMaybe [0] $ lookup name chordTable+                let foundChord = fromMaybe [0] $ lookup name chordTable                 do char '\''                    notFollowedBy space <?> "chord range or 'i' or 'o'"-                   let n = length chord+                   let n = length foundChord                    i <- option n (fromIntegral <$> integer)                    j <- length <$> many (char 'i')                    o <- length <$> many (char 'o')-                   let chord' = take i $ drop j $ concatMap (\x -> map (+ x) chord) [0,12..]+                   let chord' = take i $ drop j $ concatMap (\x -> map (+ x) foundChord) [0,12..]                    -- open voiced chords                    let chordo' = if o > 0 && n > 2 then                                      [ (chord' !! 0 - 12), (chord' !! 2 - 12), (chord' !! 1) ] ++ reverse (take (length chord' - 3) (reverse chord'))                                  else chord'                    return chordo'-                  <|> return chord+                  <|> return foundChord  parseNote :: Num a => MyParser a parseNote = do n <- notenum@@ -684,7 +684,7 @@ parseModOpen = char 'o' >> return Open  parseModRange :: MyParser Modifier-parseModRange = parseIntNote >>= \i -> return $ Range $ fromIntegral i+parseModRange = parseIntNote >>= \i -> return $ Range $ fromIntegral (i :: Integer)  parseModifiers :: MyParser [Modifier] parseModifiers = (many1 parseModOpen) <|> parseModDrop <|> (fmap pure parseModRange) <|> try parseModInvNum <|> (many1 parseModInv)  <?> "modifier"
src/Sound/Tidal/Pattern.hs view
@@ -67,8 +67,36 @@ instance Applicative Pattern where   -- | Repeat the given value once per cycle, forever   pure v = Pattern $ \(State a _) ->-    map (\a' -> Event (Context []) (Just a') (sect a a') v) $ cycleArcsInArc a+    map (\a' -> Event+                (Context [])+                (Just a')+                (sect a a')+                v)+    $ cycleArcsInArc a +  -- | In each of `a <*> b`, `a <* b` and `a *> b`+  -- (using the definitions from this module, not the Prelude),+  -- the time structure of the result+  -- depends on the structures of both `a` and `b`.+  -- They all result in `Event`s with identical `part`s and `value`s.+  -- However, their `whole`s are different.+  --+  -- For instance, `listToPat [(+1), (+2)] <*> "0 10 100"`+  -- gives the following 4-`Event` cycle:+  -- > (0>⅓)|1+  -- > (⅓>½)|11+  -- > (½>⅔)|12+  -- > (⅔>1)|102+  -- If we use `<*` instead, we get this:+  -- > (0>⅓)-½|1+  -- > 0-(⅓>½)|11+  -- > (½>⅔)-1|12+  -- > ½-(⅔>1)|102+  -- And if we use `*>`, we get this:+  -- >   (0>⅓)|1+  -- > (⅓>½)-⅔|11+  -- > ⅓-(½>⅔)|12+  -- >   (⅔>1)|102   (<*>) = applyPatToPatBoth  -- | Like <*>, but the 'wholes' come from the left@@ -199,7 +227,7 @@ squeezeJoin pp = pp {query = q}   where q st = concatMap           (\e@(Event c w p v) ->-             mapMaybe (munge c w p) $ query (compressArc (cycleArc $ wholeOrPart e) v) st {arc = p}+             mapMaybe (munge c w p) $ query (focusArc (wholeOrPart e) v) st {arc = p}           )           (query pp st)         munge oContext oWhole oPart (Event iContext iWhole iPart v) =@@ -342,11 +370,14 @@         atanh _ = noOv "atanh"  --------------------------------------------------------------------------- * Internal functions+-- * Internal/fundamental functions  empty :: Pattern a empty = Pattern {query = const []} +silence :: Pattern a+silence = empty+ queryArc :: Pattern a -> Arc -> [Event a] queryArc p a = query p $ State a Map.empty @@ -375,6 +406,10 @@ withQueryTime :: (Time -> Time) -> Pattern a -> Pattern a withQueryTime f pat = withQueryArc (\(Arc s e) -> Arc (f s) (f e)) pat +-- | Apply a function to the control values of the query+withQueryControls :: (ValueMap -> ValueMap) -> Pattern a -> Pattern a+withQueryControls f pat = pat { query = query pat . (\(State a m) -> State a (f m))}+ -- | @withEvent f p@ returns a new @Pattern@ with each event mapped over -- function @f@. withEvent :: (Event a -> Event b) -> Pattern a -> Pattern b@@ -427,6 +462,35 @@ compressArcTo :: Arc -> Pattern a -> Pattern a compressArcTo (Arc s e) = compressArc (Arc (cyclePos s) (e - sam s)) +focusArc :: Arc -> Pattern a -> Pattern a+focusArc (Arc s e) p = (cyclePos s) `rotR` (_fast (1/(e-s)) p)+++-- | Speed up a pattern by the given time pattern+fast :: Pattern Time -> Pattern a -> Pattern a+fast = tParam _fast++-- | Slow down a pattern by the factors in the given time pattern, 'squeezing'+-- the pattern to fit the slot given in the time pattern+fastSqueeze :: Pattern Time -> Pattern a -> Pattern a+fastSqueeze = tParamSqueeze _fast++-- | An alias for @fast@+density :: Pattern Time -> Pattern a -> Pattern a+density = fast++_fast :: Time -> Pattern a -> Pattern a+_fast rate pat | rate == 0 = silence+               | rate < 0 = rev $ _fast (negate rate) pat+               | otherwise = withResultTime (/ rate) $ withQueryTime (* rate) pat++-- | Slow down a pattern by the given time pattern+slow :: Pattern Time -> Pattern a -> Pattern a+slow = tParam _slow+_slow :: Time -> Pattern a -> Pattern a+_slow 0 _ = silence+_slow r p = _fast (1/r) p+ _fastGap :: Time -> Pattern a -> Pattern a _fastGap 0 _ = empty _fastGap r p = splitQueries $@@ -448,6 +512,33 @@ rotR :: Time -> Pattern a -> Pattern a rotR t = rotL (negate t) +-- | @rev p@ returns @p@ with the event positions in each cycle+-- reversed (or mirrored).+rev :: Pattern a -> Pattern a+rev p =+  splitQueries $ p {+    query = \st -> map makeWholeAbsolute $+      mapParts (mirrorArc (midCycle $ arc st)) $+      map makeWholeRelative+      (query p st+        {arc = mirrorArc (midCycle $ arc st) (arc st)+        })+    }+  where makeWholeRelative :: Event a -> Event a+        makeWholeRelative e@Event {whole = Nothing} = e+        makeWholeRelative (Event c (Just (Arc s e)) p'@(Arc s' e') v) =+          Event c (Just $ Arc (s'-s) (e-e')) p' v+        makeWholeAbsolute :: Event a -> Event a+        makeWholeAbsolute e@Event {whole = Nothing} = e+        makeWholeAbsolute (Event c (Just (Arc s e)) p'@(Arc s' e') v) =+          Event c (Just $ Arc (s'-e) (e'+s)) p' v+        midCycle :: Arc -> Time+        midCycle (Arc s _) = sam s + 0.5+        mapParts :: (Arc -> Arc) -> [Event a] -> [Event a]+        mapParts f es = (\(Event c w p' v) -> Event c w (f p') v) <$> es+        -- | Returns the `mirror image' of a 'Arc' around the given point in time+        mirrorArc :: Time -> Arc -> Arc+        mirrorArc mid' (Arc s e) = Arc (mid' - (e-mid')) (mid'+(mid'-s))  -- | Mark values in the first pattern which match with at least one -- value in the second pattern.
src/Sound/Tidal/Safe/Boot.hs view
@@ -19,6 +19,7 @@     along with this library.  If not, see <http://www.gnu.org/licenses/>. -} +{-# OPTIONS_GHC -Wno-missing-signatures #-} {-# language NoMonomorphismRestriction #-}  module Sound.Tidal.Safe.Boot where@@ -52,7 +53,7 @@ jumpIn i t = transition True (Sound.Tidal.Transition.jumpIn t) i jumpIn' i t = transition True (Sound.Tidal.Transition.jumpIn' t) i jumpMod i t = transition True (Sound.Tidal.Transition.jumpMod t) i-mortal i lifespan release = transition True (Sound.Tidal.Transition.mortal lifespan release) i+mortal i lifespan releaseTime = transition True (Sound.Tidal.Transition.mortal lifespan releaseTime) i interpolate i = transition True (Sound.Tidal.Transition.interpolate) i interpolateIn i t = transition True (Sound.Tidal.Transition.interpolateIn t) i clutch i = transition True (Sound.Tidal.Transition.clutch) i
src/Sound/Tidal/Safe/Context.hs view
@@ -21,6 +21,8 @@  {-# language GeneralizedNewtypeDeriving #-} {-# language NoMonomorphismRestriction #-}+{-# OPTIONS_GHC -Wno-missing-signatures #-}+{-# OPTIONS_GHC -Wno-unused-top-binds #-}  module Sound.Tidal.Safe.Context   ( Op () -- do not export constructor,
src/Sound/Tidal/Simple.hs view
@@ -22,10 +22,10 @@ module Sound.Tidal.Simple where  import Sound.Tidal.Control (chop, hurry)-import Sound.Tidal.Core ((#), (|*), (<~), silence, rev)+import Sound.Tidal.Core ((#), (|*), (<~)) import Sound.Tidal.Params (crush, gain, pan, speed, s) import Sound.Tidal.ParseBP (parseBP_E)-import Sound.Tidal.Pattern (ControlPattern)+import Sound.Tidal.Pattern (ControlPattern, silence, rev) import GHC.Exts ( IsString(..) )  instance {-# OVERLAPPING #-} IsString ControlPattern where
src/Sound/Tidal/Stream.hs view
@@ -34,18 +34,18 @@ import Foreign.C.Types import           System.IO (hPutStrLn, stderr) -import qualified Sound.OSC.FD as O+import qualified Sound.Osc.Fd as O+import qualified Sound.Osc.Time.Timeout as O import qualified Network.Socket          as N  import           Sound.Tidal.Config-import           Sound.Tidal.Core (stack, silence, (#))+import           Sound.Tidal.Core (stack, (#)) import           Sound.Tidal.ID import qualified Sound.Tidal.Link as Link import           Sound.Tidal.Params (pS) import           Sound.Tidal.Pattern import qualified Sound.Tidal.Tempo as T import           Sound.Tidal.Utils ((!!!))--- import qualified Sound.OSC.Datum as O import           Data.List (sortOn) import           System.Random (getStdRandom, randomR) import           Sound.Tidal.Show ()@@ -59,7 +59,7 @@                       sStateMV :: MVar ValueMap,                       -- sOutput :: MVar ControlPattern,                       sLink :: Link.AbletonLink,-                      sListen :: Maybe O.UDP,+                      sListen :: Maybe O.Udp,                       sPMapMV :: MVar PlayMap,                       sActionsMV :: MVar [T.TempoAction],                       sGlobalFMV :: MVar (ControlPattern -> ControlPattern),@@ -67,7 +67,7 @@                      }  data Cx = Cx {cxTarget :: Target,-              cxUDP :: O.UDP,+              cxUDP :: O.Udp,               cxOSCs :: [OSC],               cxAddr :: N.AddrInfo,               cxBusAddr :: Maybe N.AddrInfo@@ -256,13 +256,13 @@                            else                              hPutStrLn stderr "Can't handshake with SuperCollider without control port." -sendO :: Bool -> (Maybe O.UDP) -> Cx -> O.Message -> IO ()+sendO :: Bool -> (Maybe O.Udp) -> Cx -> O.Message -> IO () sendO isBusMsg (Just listen) cx msg = O.sendTo listen (O.Packet_Message msg) (N.addrAddress addr)   where addr | isBusMsg && isJust (cxBusAddr cx) = fromJust $ cxBusAddr cx              | otherwise = cxAddr cx sendO _ Nothing cx msg = O.sendMessage (cxUDP cx) msg -sendBndl :: Bool -> (Maybe O.UDP) -> Cx -> O.Bundle -> IO ()+sendBndl :: Bool -> (Maybe O.Udp) -> Cx -> O.Bundle -> IO () sendBndl isBusMsg (Just listen) cx bndl = O.sendTo listen (O.Packet_Bundle bndl) (N.addrAddress addr)   where addr | isBusMsg && isJust (cxBusAddr cx) = fromJust $ cxBusAddr cx              | otherwise = cxAddr cx@@ -332,11 +332,10 @@                             defaultValue _ = Nothing  playStack :: PlayMap -> ControlPattern-playStack pMap = stack $ map pattern active-  where active = filter (\pState -> if hasSolo pMap-                                    then solo pState-                                    else not (mute pState)-                        ) $ Map.elems pMap+playStack pMap = stack . (map pattern) . (filter active) . Map.elems $ pMap+  where active pState = if hasSolo pMap+                        then solo pState+                        else not (mute pState)  toOSC :: [Int] -> ProcessedEvent -> OSC -> [(Double, Bool, O.Message)] toOSC busses pe osc@(OSC _ _)@@ -400,16 +399,21 @@         ident = fromMaybe "unknown" $ Map.lookup "_id_" (value $ peEvent pe) >>= getS         ts = (peOnWholeOrPartOsc pe) + nudge -- + latency +patternTimeID :: String+patternTimeID = "_t_pattern"+ -- Used for Tempo callback-updatePattern :: Stream -> ID -> ControlPattern -> IO ()-updatePattern stream k pat = do+updatePattern :: Stream -> ID -> Time -> ControlPattern -> IO ()+updatePattern stream k !t pat = do   let x = queryArc pat (Arc 0 0)   pMap <- seq x $ takeMVar (sPMapMV stream)   let playState = updatePS $ Map.lookup (fromID k) pMap   putMVar (sPMapMV stream) $ Map.insert (fromID k) playState pMap   where updatePS (Just playState) = do playState {pattern = pat', history = pat:(history playState)}         updatePS Nothing = PlayState pat' False False [pat']-        pat' = pat # pS "_id_" (pure $ fromID k)+        patControls = Map.singleton patternTimeID (VR t)+        pat' = withQueryControls (Map.union patControls)+                 $ pat # pS "_id_" (pure $ fromID k)  processCps :: T.LinkOperations -> [Event ValueMap] -> IO [ProcessedEvent] processCps ops = mapM processEvent@@ -542,7 +546,7 @@ -- Send events early using timestamp in the OSC bundle - used by Superdirt -- Send events early by adding timestamp to the OSC message - used by Dirt -- Send events live by delaying the thread-send :: Maybe O.UDP -> Cx -> Double -> Double -> (Double, Bool, O.Message) -> IO ()+send :: Maybe O.Udp -> Cx -> Double -> Double -> (Double, Bool, O.Message) -> IO () send listen cx latency extraLatency (time, isBusMsg, m)   | oSchedule target == Pre BundleStamp = sendBndl isBusMsg listen cx $ O.Bundle timeWithLatency [m]   | oSchedule target == Pre MessageStamp = sendO isBusMsg listen cx $ addtime m@@ -551,7 +555,7 @@                                     sendO isBusMsg listen cx m                    return ()     where addtime (O.Message mpath params) = O.Message mpath ((O.int32 sec):((O.int32 usec):params))-          ut = O.ntpr_to_ut timeWithLatency+          ut = O.ntpr_to_posix timeWithLatency           sec :: Int           sec = floor ut           usec :: Int@@ -565,8 +569,11 @@ streamNudgeAll s nudge = T.setNudge (sActionsMV s) nudge  streamResetCycles :: Stream -> IO ()-streamResetCycles s =T.resetCycles (sActionsMV s)+streamResetCycles s = streamSetCycle s 0 +streamSetCycle :: Stream -> Time -> IO ()+streamSetCycle s cyc = T.setCycle cyc (sActionsMV s)+ hasSolo :: Map.Map k PlayState -> Bool hasSolo = (>= 1) . length . filter solo . Map.elems @@ -652,7 +659,7 @@ streamSetR :: Stream -> String -> Pattern Rational -> IO () streamSetR = streamSet -openListener :: Config -> IO (Maybe O.UDP)+openListener :: Config -> IO (Maybe O.Udp) openListener c   | cCtrlListen c = catchAny run (\_ -> do verbose c "That port isn't available, perhaps another Tidal instance is already listening on that port?"                                            return Nothing@@ -686,16 +693,16 @@                                                         return ()           where              bufferIndices [] = []-            bufferIndices (x:xs') | x == (O.ASCII_String $ O.ascii "&controlBusIndices") = catMaybes $ takeWhile isJust $ map O.datum_integral xs'+            bufferIndices (x:xs') | x == (O.AsciiString $ O.ascii "&controlBusIndices") = catMaybes $ takeWhile isJust $ map O.datum_integral xs'                                   | otherwise = bufferIndices xs'         -- External controller commands         act (O.Message "/ctrl" (O.Int32 k:v:[]))           = act (O.Message "/ctrl" [O.string $ show k,v])-        act (O.Message "/ctrl" (O.ASCII_String k:v@(O.Float _):[]))+        act (O.Message "/ctrl" (O.AsciiString k:v@(O.Float _):[]))           = add (O.ascii_to_string k) (VF (fromJust $ O.datum_floating v))-        act (O.Message "/ctrl" (O.ASCII_String k:O.ASCII_String v:[]))+        act (O.Message "/ctrl" (O.AsciiString k:O.AsciiString v:[]))           = add (O.ascii_to_string k) (VS (O.ascii_to_string v))-        act (O.Message "/ctrl" (O.ASCII_String k:O.Int32 v:[]))+        act (O.Message "/ctrl" (O.AsciiString k:O.Int32 v:[]))           = add (O.ascii_to_string k) (VI (fromIntegral v))         -- Stream playback commands         act (O.Message "/mute" (k:[]))@@ -722,7 +729,7 @@                      putMVar (sStateMV stream) $ Map.insert k v sMap                      return ()         withID :: O.Datum -> (ID -> IO ()) -> IO ()-        withID (O.ASCII_String k) func = func $ (ID . O.ascii_to_string) k+        withID (O.AsciiString k) func = func $ (ID . O.ascii_to_string) k         withID (O.Int32 k) func = func $ (ID . show) k         withID _ _ = return () ctrlResponder _ _ _ = return ()
src/Sound/Tidal/Tempo.hs view
@@ -6,7 +6,7 @@  import Control.Concurrent.MVar import qualified Sound.Tidal.Pattern as P-import qualified Sound.OSC.FD as O+import qualified Sound.Osc.Fd as O import Control.Concurrent (forkIO, ThreadId, threadDelay) import Control.Monad (when) import qualified Data.Map.Strict as Map@@ -20,7 +20,6 @@ import Data.Int(Int64)  import Sound.Tidal.StreamTypes-import Sound.Tidal.Core (silence)  {-     Tempo.hs - Tidal's scheduler@@ -40,13 +39,13 @@     along with this library.  If not, see <http://www.gnu.org/licenses/>. -} -instance Show O.UDP where+instance Show O.Udp where   show _ = "-unshowable-"  type TransitionMapper = P.Time -> [P.ControlPattern] -> P.ControlPattern  data TempoAction =-  ResetCycles+  SetCycle P.Time   | SingleTick P.ControlPattern   | SetNudge Double   | StreamReplace ID P.ControlPattern@@ -54,7 +53,6 @@  data State = State {ticks    :: Int64,                     start    :: Link.Micros,-                    nowEnd   :: Link.Micros,                     nowArc   :: P.Arc,                     nudged   :: Double                    }@@ -64,7 +62,7 @@   ActionHandler {     onTick :: TickState -> LinkOperations -> P.ValueMap -> IO P.ValueMap,     onSingleTick :: LinkOperations -> P.ValueMap -> P.ControlPattern -> IO P.ValueMap,-    updatePattern :: ID -> P.ControlPattern -> IO ()+    updatePattern :: ID -> P.Time -> P.ControlPattern -> IO ()   }  data LinkOperations =@@ -78,8 +76,8 @@     cyclesToBeat :: CDouble -> CDouble   } -resetCycles :: MVar [TempoAction] -> IO ()-resetCycles actionsMV = modifyMVar_ actionsMV (\actions -> return $ ResetCycles : actions)+setCycle :: P.Time -> MVar [TempoAction] -> IO ()+setCycle cyc actionsMV = modifyMVar_ actionsMV (\actions -> return $ SetCycle cyc : actions)  setNudge :: MVar [TempoAction] -> Double -> IO () setNudge actionsMV nudge = modifyMVar_ actionsMV (\actions -> return $ SetNudge nudge : actions)@@ -89,6 +87,7 @@   beat <- Link.beatAtTime ss time (cQuantum config)   return $! (toRational beat) / (toRational (cBeatsPerCycle config)) +-- At what time does the cycle occur according to Link? cyclesToTime :: Config -> Link.SessionState -> P.Time -> IO Link.Micros cyclesToTime config ss cyc = do   let beat = (fromRational cyc) * (cBeatsPerCycle config)@@ -117,11 +116,10 @@             now <- Link.clock abletonLink             let startAt = now + processAhead             Link.requestBeatAtTime sessionState 0 startAt quantum-            Link.commitAppSessionState abletonLink sessionState+            Link.commitAndDestroyAppSessionState abletonLink sessionState             putMVar actionsMV []             let st = State {ticks = 0,                        start = now,-                       nowEnd = logicalTime now 1,                        nowArc = P.Arc 0 0,                        nudged = 0                       }@@ -178,9 +176,7 @@                 startCycle = P.stop $ nowArc st             sessionState <- Link.createAndCaptureAppSessionState abletonLink             endCycle <- timeToCycles' config sessionState logicalEnd-            let st' = st {nowArc = P.Arc startCycle endCycle,-                          nowEnd = logicalEnd-                        }+            let st' = st {nowArc = P.Arc startCycle endCycle}             nowOsc <- O.time             nowLink <- Link.clock abletonLink             let ops = LinkOperations {@@ -213,19 +209,24 @@           return $! st'         handleActions :: State -> [TempoAction] -> P.ValueMap -> IO (State, P.ValueMap)         handleActions st [] streamState = return (st, streamState)-        handleActions st (ResetCycles : otherActions) streamState =+        handleActions st (SetCycle cyc : otherActions) streamState =           do             (st', streamState') <- handleActions st otherActions streamState             sessionState <- Link.createAndCaptureAppSessionState abletonLink -            let logicalEnd   = logicalTime (start st') $ ticks st' + 1-                st'' = st' {-                          nowArc = P.Arc 0 0,-                          nowEnd = logicalEnd + frameTimespan-                        }             now <- Link.clock abletonLink-            Link.requestBeatAtTime sessionState 0 now quantum+            let startAt = now + processAhead+                beat = (fromRational cyc) * (cBeatsPerCycle config)+            Link.requestBeatAtTime sessionState beat startAt quantum             Link.commitAndDestroyAppSessionState abletonLink sessionState++                  +            let st'' = st' {+                  ticks = 0,+                  start = now,+                  nowArc = P.Arc cyc cyc+                  }+             return (st'', streamState')         handleActions st (SingleTick pat : otherActions) streamState =           do@@ -269,10 +270,8 @@                 sessionState <- Link.createAndCaptureAppSessionState abletonLink                 cyc <- timeToCycles' config sessionState now                 Link.destroySessionState sessionState-                -- put pattern id and change time in control input-                let streamState'' = Map.insert ("_t_all") (P.VR $! cyc) $ Map.insert ("_t_" ++ fromID k) (P.VR $! cyc) streamState'-                (updatePattern ac) k pat-                return (st', streamState'')+                (updatePattern ac) k cyc pat+                return (st', streamState')               )               (\(e :: E.SomeException) -> do                 hPutStrLn stderr $ "Error in pattern: " ++ show e@@ -284,10 +283,10 @@             let               appendPat flag = if flag then (pat:) else id               updatePS (Just playState) = playState {history = (appendPat historyFlag) (history playState)}-              updatePS Nothing = PlayState {pattern = silence,+              updatePS Nothing = PlayState {pattern = P.silence,                                             mute = False,                                             solo = False,-                                            history = (appendPat historyFlag) (silence:[])+                                            history = (appendPat historyFlag) (P.silence:[])                                           }               transition' pat' = do now <- Link.clock abletonLink                                     ss <- Link.createAndCaptureAppSessionState abletonLink
src/Sound/Tidal/Time.hs view
@@ -38,16 +38,16 @@  -- Utility functions - Time --- | The 'sam' (start of cycle) for the given time value.+-- | The @sam@ (start of cycle) for the given time value. -- Cycles have duration 1, so every integer Time value divides two cycles. sam :: Time -> Time sam = fromIntegral . (floor :: Time -> Int) --- | Turns a number into a (rational) time value. An alias for 'toRational'.+-- | Turns a number into a (rational) time value. An alias for @toRational@. toTime :: Real a => a -> Rational toTime = toRational --- | Turns a (rational) time value into another number. An alias for 'fromRational'.+-- | Turns a (rational) time value into another number. An alias for @fromRational@. fromTime :: Fractional a => Time -> a fromTime = fromRational @@ -102,29 +102,36 @@ cycleArc :: Arc -> Arc cycleArc (Arc s e) = Arc (cyclePos s) (cyclePos s + (e-s)) --- | Returns the numbers of the cycles that the input Arc overlaps--- (excluding the input Arc's endpoint, unless it has duration 0 --+-- | Returns the numbers of the cycles that the input @Arc@ overlaps+-- (excluding the input @Arc@'s endpoint, unless it has duration 0 -- -- see "Edge cases" below).--- The "cycle number" of an Arc is equal to its start value.--- Thus, for instance, `cyclesInArc (Arc 0 1.5) == [0,1]`.--- * Edge cases:---     `cyclesInArc $ Arc 0 1.0001 == [0,1]`---     `cyclesInArc $ Arc 0 1      == [0]` -- the endpoint is excluded---     `cyclesInArc $ Arc 1 1      == [1]` -- unless the Arc has duration 0+-- (The "cycle number" of an @Arc@ is equal to its start value.+-- Thus, for instance, @cyclesInArc (Arc 0 1.5) == [0,1]@.)+--+-- Edge cases:+-- >  cyclesInArc $ Arc 0 1.0001 == [0,1]+-- >  cyclesInArc $ Arc 0 1      == [0] -- the endpoint is excluded+-- >  cyclesInArc $ Arc 1 1      == [1] -- unless the Arc has duration 0+--+-- PITFALL: Don't be fooled by the name. The output cycles+-- are not necessarily completely contained in the input @Arc@,+-- but they definitely overlap it,+-- and they include every cycle that overlaps it. cyclesInArc :: Integral a => Arc -> [a] cyclesInArc (Arc s e)   | s > e = []   | s == e = [floor s]   | otherwise = [floor s .. ceiling e-1] --- | The whole cycles that overlap the input Arc,--- (excluding its endpoint, unless it has duration 0,--- similarly to `cyclesInArc` ----- see that function's description for details).+-- | This provides exactly the same information as @cyclesInArc@,+-- except that this represents its output as @Arc@s,+-- whereas @cyclesInArc@ represents the same information as integral indices.+-- (The @Arc@ from 0 to 1 corresponds to the index 0,+-- the one from 1 to 2 has index 1, etc.) cycleArcsInArc :: Arc -> [Arc] cycleArcsInArc = map (timeToCycleArc . (toTime :: Int -> Time)) . cyclesInArc --- | Splits the given 'Arc' into a list of 'Arc's, at cycle boundaries.+-- | Splits the given @Arc@ into a list of @Arc@s, at cycle boundaries. arcCycles :: Arc -> [Arc] arcCycles (Arc s e) | s >= e = []                 | sam s == sam e = [Arc s e]@@ -135,7 +142,7 @@ arcCyclesZW (Arc s e) | s == e = [Arc s e]                   | otherwise = arcCycles (Arc s e) --- | Similar to 'fmap' but time is relative to the cycle (i.e. the+-- | Similar to @fmap@ but time is relative to the cycle (i.e. the -- sam of the start of the arc) mapCycle :: (Time -> Time) -> Arc -> Arc mapCycle f (Arc s e) = Arc (sam' + f (s - sam')) (sam' + f (e - sam'))
src/Sound/Tidal/UI.hs view
@@ -800,7 +800,7 @@     distrib' (True:a) (x:b) = x : distrib' a b     distrib' (False:a) b = False : distrib' a b     layers = map bjorklund . (zip<*>tail)-    boolsToPat a b' = flip const <$> filterValues (== True) (fastFromList a) <*> b'+    boolsToPat a b' = flip const <$> filterValues (== True) (fastFromList a) <* b'  {- | `euclidInv` fills in the blanks left by `e`  -@@ -1728,11 +1728,15 @@               | otherwise = silence  +-- ghost'' is kept for backwards compatibility ghost'' :: Time -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a-ghost'' a f p = superimpose (((a*2.5) `rotR`) . f) $ superimpose (((a*1.5) `rotR`) . f) p+ghost'' = ghostWith +ghostWith :: Time -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a+ghostWith a f p = superimpose (((a*2.5) `rotR`) . f) $ superimpose (((a*1.5) `rotR`) . f) p+ ghost' :: Time -> Pattern ValueMap -> Pattern ValueMap-ghost' a p = ghost'' a ((|*| P.gain (pure 0.7)) . (|> P.end (pure 0.2)) . (|*| P.speed (pure 1.25))) p+ghost' a p = ghostWith a ((|*| P.gain (pure 0.7)) . (|> P.end (pure 0.2)) . (|*| P.speed (pure 1.25))) p  ghost :: Pattern ValueMap -> Pattern ValueMap ghost = ghost' 0.125
src/Sound/Tidal/Version.hs view
@@ -21,7 +21,7 @@ -}  tidal_version :: String-tidal_version = "1.9.2"+tidal_version = "1.9.3"  tidal_status :: IO () tidal_status = tidal_status_string >>= putStrLn 
test/Sound/Tidal/PatternTest.hs view
@@ -207,6 +207,9 @@                       (Event (Context []) (Just $ Arc (2 % 3) (5 % 6)) (Arc (2 % 3) (5 % 6)) "d"),                       (Event (Context []) (Just $ Arc (5 % 6) (1 % 1)) (Arc (5 % 6) (1 % 1)) "e")                      ]+      it "preserves cycle number of inner patterns" $ do+        (map value $ queryArc (squeezeJoin (pure $ struct "1" $ (sig $ id))) (Arc 3 4))+          `shouldBe` [3.5]      describe ">>=" $ do       it "can apply functions to patterns" $ do
test/Sound/Tidal/StreamTest.hs view
@@ -5,7 +5,7 @@ import Test.Microspec import Sound.Tidal.Stream import Sound.Tidal.Pattern-import qualified Sound.OSC.FD as O+import qualified Sound.Osc.Fd as O import qualified Data.Map.Strict as M  run :: Microspec ()
tidal.cabal view
@@ -1,7 +1,7 @@ cabal-version:       2.0  name:                tidal-version:             1.9.2+version:             1.9.3 synopsis:            Pattern language for improvised music description:         Tidal is a domain specific language for live coding patterns. homepage:            http://tidalcycles.org/@@ -55,7 +55,7 @@       base >=4.8 && <5     , containers < 0.7     , colour < 2.4-    , hosc >= 0.17 && < 0.20+    , hosc >= 0.20 && < 0.21     , text < 2.1     , parsec >= 3.1.12 && < 3.2     , network < 3.2@@ -90,7 +90,7 @@   build-depends:                 base ==4.*               , microspec >= 0.2.0.1-              , hosc >= 0.17 && < 0.20+              , hosc >= 0.20 && < 0.21               , containers               , parsec               , tidal
tidal.el view
@@ -228,7 +228,7 @@        ,(format "Send %s $ silence as a single line." name)        (interactive)        (tidal-send-string ":{")-       (tidal-send-string " mapM_ ($ silence) [,name]")+       (tidal-send-string (concat " mapM_ ($ silence) [" ,name "]"))        (tidal-send-string ":}"))))  (defun tidal-create-runner (name)