| Safe Haskell | None |
|---|---|
| Language | GHC2021 |
Harmonic.Interface.Tidal.Utils
Description
Synopsis
- oct :: Pattern Note -> Pattern ValueMap
- pullBy :: Pattern Time -> Pattern a -> Pattern a
- pushBy :: Pattern Time -> Pattern a -> Pattern a
- humanise :: Double -> Pattern ValueMap
- onset :: Pattern a -> Pattern a
- hemidemisemiquaver :: Time
- demisemiquaver :: Time
- semiquaver :: Time
- quaver :: Time
- crotchet :: Time
- minim :: Time
- swing8 :: Pattern Time -> Pattern a -> Pattern a
- swing16 :: Pattern Time -> Pattern a -> Pattern a
- over :: Pattern Double -> [a] -> Pattern a
- (-->) :: Pattern Double -> [a] -> Pattern a
- binaryrange :: Pattern Int -> Pattern Int -> Pattern Bool
- pump :: Pattern Bool -> Pattern Double -> Double -> Pattern Double
- mono' :: Pattern a -> Pattern a
- retrig :: Pattern a -> Pattern a
Transposition
oct :: Pattern Note -> Pattern ValueMap Source #
Transpose by whole octaves. oct 1 is up an octave, oct (-1) down.
The shift is a pattern, so it can move across the cycle: |+ oct "[0 1]*2".
Add onto a pattern:
, cello T (0,1) k vl grid Bass |+ oct (-1)
Time rotation
pullBy :: Pattern Time -> Pattern a -> Pattern a Source #
Rotate a pattern earlier (pullBy) or later (pushBy) in time.
Function forms of the TidalCycles <~ and ~> operators, so they compose
in a modifier chain rather than needing parentheses. The amount is a
pattern, so the rotation can itself vary across the cycle.
, pushBy (1/8) $ harp T (0,1) k vl flow Alto
pushBy :: Pattern Time -> Pattern a -> Pattern a Source #
Rotate a pattern later in time. See pullBy.
Humanisation
humanise :: Double -> Pattern ValueMap Source #
Random per-event velocity jitter, for a less mechanical feel. The argument
scales the spread: humanise 1 varies amp by up to ±0.09. The value
is centred on ZERO — combine with |+ ("|+ humanise 0.2"), never
#, which would replace the amp instead of jittering it.
Onset repair
onset :: Pattern a -> Pattern a Source #
Ensure every event is an onset by aligning whole start with part start, but only at cycle boundaries. Prevents TidalCycles' onset detection from filtering events in cat constructions where inner patterns have period > 1 cycle, without causing MIDI flood from sub-cycle queries.
Note-length constants
hemidemisemiquaver :: Time Source #
demisemiquaver :: Time Source #
semiquaver :: Time Source #
Swing
swing8 :: Pattern Time -> Pattern a -> Pattern a Source #
Swing by musical PROPORTION: 0.5 is straight, 0.667 triplet. Places
the swung note at exactly that proportion of its subdivision.
One cycle is one beat here, so swing8 swings eighth-notes (the "&") and
swing16 swings sixteenths (the "e"/"a"). Jazz eighth-feel —
spang-a-lang, offbeat eighths — takes swing8; a sixteenth shuffle (funk,
UK garage, house, phonk, fusion) takes swing16.
f = swing8 0.6
swing16 :: Pattern Time -> Pattern a -> Pattern a Source #
Swing by musical PROPORTION: 0.5 is straight, 0.667 triplet. Places
the swung note at exactly that proportion of its subdivision.
One cycle is one beat here, so swing8 swings eighth-notes (the "&") and
swing16 swings sixteenths (the "e"/"a"). Jazz eighth-feel —
spang-a-lang, offbeat eighths — takes swing8; a sixteenth shuffle (funk,
UK garage, house, phonk, fusion) takes swing16.
f = swing8 0.6
Selection
over :: Pattern Double -> [a] -> Pattern a Source #
Step through a list under a 0-1 control signal: the signal's range is divided evenly among the elements, so a knob sweeps through them in order. An empty list is silence.
, over qlink1 [flow, grid, lite]
Random gating
binaryrange :: Pattern Int -> Pattern Int -> Pattern Bool Source #
A boolean gate whose density wanders between two step counts, via
binary over a random integer in [lo, hi).
Sidechain
pump :: Pattern Bool -> Pattern Double -> Double -> Pattern Double Source #
A ducking gain envelope — a ghost sidechain. Every onset of the struct
pattern drops the gain to 1 - depth, which then recovers to 1 over the
release rls. A cycle is a beat here (cps = bpm/60), so rls reads
directly in beats: 1 is one beat, 0.25 a quarter of one.
depth is 0 for no duck, 1 to duck to silence, and is a pattern, so it
can ride an LFO or the form.
The result is a 'Pattern Double' meant to drive a gain control. It belongs BESIDE the notes as its own element in a stack, never applied to them:
, s1pump "1 0 0 0" 0.6 0.75 # o
Applying it to a note pattern with |*, *| or # splits every note once
per overlapping envelope step — a held note re-triggers sixteen times, and
drums double-trigger. A hand-written gain pattern coarser than, and aligned
to, the note grid (|* vel "0.45 1 0.8 1") is the way to duck note
velocities.
An rls longer than the gap to the next onset interleaves two envelopes: the
older tail's recovered values arrive after the new duck and cancel it.
Nothing clamps this.
Monophony
mono' :: Pattern a -> Pattern a Source #
Monophonic with latest-note priority: each event's whole is truncated at
the next onset in the pattern, so a new note always starts on time and stops
the one before it — a string being re-fingered, not a queue. Tidal's own
mono is the opposite (first-note priority: a later overlapping event is
delayed or dropped). Simultaneous onsets keep only the first. Legato scales
the truncated whole, so # legato 1 rings exactly to the next note, < 1
leaves a gap, and cranking legato above 1 is unnecessary. Continuous
(whole-less) events pass through untouched.