| Safe Haskell | None |
|---|---|
| Language | GHC2021 |
Harmonic.Rules.Types.ProgressionContext
Description
A ProgressionContext bundles three bar-aligned Progression layers —
triads, pentatonic strata, and diatonic modes — together with optional
per-bar provenance tracking which tristrata and strata each bar was drawn
from. Every family fills the layers: genP walks curated strata/mode
chroma and carries Just provenance; genE fills partner triads; plain
gen and genJ derive a pentatonic S and a mode M by chordscale
key-area analysis (chordscale),
provenance Nothing. Only raw fromProgression output (hand-built
material not passed through chordscale) still duplicates one
progression across all three layers.
Synopsis
- data Layer
- data Family
- data ProgressionContext = ProgressionContext {}
- layer :: Layer -> ProgressionContext -> Progression
- pcLength :: ProgressionContext -> Int
- fromProgression :: Progression -> ProgressionContext
- liftPC :: (Progression -> Progression) -> ProgressionContext -> ProgressionContext
- liftPCAligned :: (forall a. Seq a -> Seq a) -> ProgressionContext -> ProgressionContext
- liftPCSubst :: (Progression -> Progression) -> ProgressionContext -> ProgressionContext
- normalizeFamily :: ProgressionContext -> ProgressionContext
- pcSplice :: ProgressionContext -> Int -> Int -> ProgressionContext -> ProgressionContext
Documentation
Layer tag selecting one of the three progression layers — or a combination of them — at a call site.
Single layers:
T— Triad layer (cadential harmony, the Rules.Types.Progression result).S— Strata layer (genP: 5-note pentatonic chroma; genE: the less dissonant partner triad).M— Mode layer (genP: 7-note diatonic chroma; genE: the more dissonant partner triad).
Combinations (synthesized per bar by layer):
TS/TM/SM— pointwise pitch-class union of two layers.TSM— union of all three.PT— pivot tones: the pitch classes common to ALL three layers.
A merged bar is rooted on its LOWEST constituent layer's bar root
(T before S before M) — the foundation owns the bass whenever it is
present. On a polytonal (genE) context TS/TM always union to 4 tones,
TSM to 5, and PT holds 2 tones on common-dyad bars or the single hub
tone on base-anchored bars. On a chordscale-derived gen/genJ context
S is the bar's pentatonic, M its mode, and PT the chord tones the
pentatonic keeps. On contexts whose layers still duplicate one
progression (hand-built material without
chordscale) every combination
degrades to that progression.
M replaces the plan's D to avoid clashing with NoteName
(D natural), which is re-exported via Lib for live-coding use.
Generation family a progression belongs to. Families never mix:
regeneration (genFrom) always reproduces
the source's family, and fuse of differing families downgrades to
FTriad. Family drives dispatch in genFrom and in the walking-bass
interface: FJazz contexts walk with a per-bar bass vocabulary
(restored fifths, passing extensions, avoid-tone protection), FStrata
walks via provenance chroma, and everything else — including
downgraded mixes — walks the plain per-bar tone sets at whatever
cardinality each bar carries.
FTriad— plain triadic walk (gen).FExtended— uniform 4-note hand-built material (lead'cues, hand-spliced progressions); arrives only by inference, never stamped.FStrata— strata-first family (genP/genI; carries provenance).FJazz— jazz Change-graph walk (genJ; variable arity 3-6).FPoly— polytonal three-triad family (genE): T carries the foundation walk, S/M carry partner triad chains sharing tones with it per bar. Stamped explicitly by the producer; inference never yields it.
data ProgressionContext Source #
Three bar-aligned progression layers with optional per-bar provenance.
Invariant: progLength triadLayer == progLength strataLayer == progLength modeLayer,
and when pcProvenance = Just sq, Seq.length sq == progLength triadLayer.
Constructors
| ProgressionContext | |
Fields
| |
Instances
| Monoid ProgressionContext Source # | |
Defined in Harmonic.Rules.Types.ProgressionContext Methods mempty :: ProgressionContext # mappend :: ProgressionContext -> ProgressionContext -> ProgressionContext # mconcat :: [ProgressionContext] -> ProgressionContext # | |
| Semigroup ProgressionContext Source # | |
Defined in Harmonic.Rules.Types.ProgressionContext Methods (<>) :: ProgressionContext -> ProgressionContext -> ProgressionContext # sconcat :: NonEmpty ProgressionContext -> ProgressionContext # stimes :: Integral b => b -> ProgressionContext -> ProgressionContext # | |
| Show ProgressionContext Source # | |
Defined in Harmonic.Rules.Types.ProgressionContext Methods showsPrec :: Int -> ProgressionContext -> ShowS # show :: ProgressionContext -> String # showList :: [ProgressionContext] -> ShowS # | |
| Eq ProgressionContext Source # | |
Defined in Harmonic.Rules.Types.ProgressionContext Methods (==) :: ProgressionContext -> ProgressionContext -> Bool # (/=) :: ProgressionContext -> ProgressionContext -> Bool # | |
layer :: Layer -> ProgressionContext -> Progression Source #
Project a ProgressionContext to a single Progression by layer tag.
Single tags project a stored layer; combination tags synthesize per-bar
unions (rooted on the lowest constituent layer's bar — T before S before
M, so the foundation owns the merged bass whenever present); PT
synthesizes the per-bar intersection of all three layers. Total for every
family; on duplicated-layer contexts (the raw fromProgression fallback)
every combination collapses to the stored progression.
pcLength :: ProgressionContext -> Int Source #
Bar count — equal across all three layers by invariant.
fromProgression :: Progression -> ProgressionContext Source #
Wrap a single Progression as a ProgressionContext by duplicating it
into all three layers with no provenance — the RAW constructor. The gen
and genJ producers post-process the result with
chordscale to derive real S/M
layers; hand-built material stays duplicated until passed through the
same combinator.
liftPC :: (Progression -> Progression) -> ProgressionContext -> ProgressionContext Source #
Apply a Progression-transforming function pointwise across all three
layers. Drops provenance, and with it any FStrata claim — a strata
context without provenance is no longer strata material, so the family
normalizes in step. Bar-alignment-preserving combinators should use
liftPCAligned instead, which carries provenance (and the family)
through.
liftPCAligned :: (forall a. Seq a -> Seq a) -> ProgressionContext -> ProgressionContext Source #
Class 1 combinator support: apply ONE bar-order permutation/replication
to all three layers AND the provenance sequence in lockstep. The rank-2
argument cannot inspect elements (parametricity), so it can only
rearrange or duplicate whole bars — per-bar pairings (bar ↔ provenance,
foundation ↔ partners) survive intact and the family stamp stays true.
Chordscale-derived S/M layers (gen / genJ) permute with their bars, so
each bar keeps its own mode/pentatonic; the key BOUNDARIES they encode
reflect the pre-permutation whole-progression analysis — re-apply
chordscale for a fresh reading.
liftPCSubst :: (Progression -> Progression) -> ProgressionContext -> ProgressionContext Source #
Bar substitution breaks both the provenance-backed (FStrata) and the
structural (FPoly) family invariants — the result walks and voices as
plain material, and the tag must not claim otherwise. Chordscale-derived
S/M layers are mapped like any other bars and go stale the same way —
re-apply chordscale after
bar-substituting edits.
pcSplice :: ProgressionContext -> Int -> Int -> ProgressionContext -> ProgressionContext Source #
Splice a range of bars within a ProgressionContext, replacing the
triad / strata / mode layers and the pcProvenance sequence in lockstep.
Range is 1-indexed and wrap-aware (mirrors spliceProgression):
- Non-wrapping (
start <= end): replaces positionsstart..end. - Wrapping (
start > end): replacesstart..Nand1..end.
The triad layer's movement seam is fixed via spliceProgression;
strata / mode layers don't carry meaningful Movement state (their
Cadence is built with Movement = Unison — see mkChromaCS in
Builder) so they use a plain sequence splice.
Provenance follows the same geometry. When either side has
pcProvenance = Nothing, the result is Nothing (the splice can't
reconstruct provenance from a layer-only source).
Caller is responsible for ensuring the inserted ProgressionContext
has length equal to the range size.