Safe Haskell | Safe-Inferred |
---|
Utilities that emit Signal.Control
s and ControlMod
s.
Synopsis
- type SRate = RealTime.RealTime
- data CurveD = forall arg. CurveD !Text !(Sig.Parser arg) !(arg -> Curve)
- curve_name :: CurveD -> Text
- data Curve
- type CurveF = Double -> Double
- standard_curves :: [(Expr.Symbol, CurveD)]
- type InterpolatorTime a = Either (Sig.Parser DeriveT.Duration) (GetTime a, Text)
- type GetTime a = PassedArgs a -> Deriver DeriveT.Duration
- interpolator_call :: Text -> CurveD -> InterpolatorTime Control -> Generator Control
- from_env :: Sig.Parser (Maybe Signal.Y)
- prev_val :: Maybe Signal.Y -> ControlArgs -> Maybe Signal.Y
- interpolator_variations_ :: Taggable a => (Text -> CurveD -> InterpolatorTime a -> call) -> Expr.Symbol -> CurveD -> [(Expr.Symbol, call)]
- default_interpolation_time :: Typecheck.DefaultReal
- get_prev_val :: Taggable a => PassedArgs a -> Deriver DeriveT.Duration
- interpolator_variations :: [(Expr.Symbol, Generator Control)]
- curve_env :: Sig.Parser Curve
- curve_arg :: Sig.Parser Curve
- pf_linear :: DeriveT.PFunction
- pf_linear_name :: Text
- curve_time_env :: Sig.Parser (Curve, RealTime.RealTime)
- make_curve_call :: Maybe Doc.Doc -> CurveD -> ValCall
- curve_to_pf :: Text -> Curve -> DeriveT.PFunction
- pf_to_curve :: DeriveT.PFunction -> Curve
- place_range :: Typecheck.Normalized -> ScoreTime -> DeriveT.Duration -> Deriver (RealTime.RealTime, RealTime.RealTime)
- make_segment_from :: Curve -> RealTime.RealTime -> Maybe Signal.Y -> RealTime.RealTime -> Signal.Y -> Deriver Signal.Control
- make_segment :: Curve -> RealTime.RealTime -> Signal.Y -> RealTime.RealTime -> Signal.Y -> Deriver Signal.Control
- segment :: SRate -> Curve -> RealTime.RealTime -> Signal.Y -> RealTime.RealTime -> Signal.Y -> Signal.Control
- make_function :: CurveF -> RealTime.RealTime -> Signal.Y -> RealTime.RealTime -> Signal.Y -> RealTime.RealTime -> Signal.Y
- slope_to_limit :: Maybe Signal.Y -> Maybe Signal.Y -> Signal.Y -> Double -> RealTime.RealTime -> RealTime.RealTime -> Signal.Control
- exponential_curve :: CurveD
- exponential_doc :: Doc.Doc
- expon :: Double -> CurveF
- expon2 :: Double -> Double -> CurveF
- sigmoid_curve :: CurveD
- type Point = (Double, Double)
- guess_x :: (Double -> (Double, Double)) -> CurveF
- sigmoid :: Double -> Double -> CurveF
- bezier3 :: Point -> Point -> Point -> Point -> Double -> Point
- breakpoints :: SRate -> Curve -> [(RealTime.RealTime, Signal.Y)] -> Signal.Control
- signal_breakpoints :: Monoid sig => (RealTime.RealTime -> y -> sig) -> (RealTime.RealTime -> y -> RealTime.RealTime -> y -> sig) -> [(RealTime.RealTime, y)] -> sig
- distribute :: RealTime.RealTime -> RealTime.RealTime -> [a] -> [(RealTime.RealTime, a)]
- smooth_absolute :: Curve -> RealTime.RealTime -> RealTime.RealTime -> [(RealTime.RealTime, Signal.Y)] -> Signal.Control
- smooth_relative :: Curve -> RealTime.RealTime -> ScoreT.Function -> [(RealTime.RealTime, Signal.Y)] -> Signal.Control
- split_samples_absolute :: RealTime.RealTime -> [(RealTime.RealTime, y)] -> [(RealTime.RealTime, y)]
- split_samples_relative :: ScoreT.Function -> [(RealTime.RealTime, y)] -> [(RealTime.RealTime, y)]
- modify_with :: Merge -> ScoreT.Control -> RealTime.RealTime -> Signal.Control -> Deriver ()
- multiply_dyn :: RealTime.RealTime -> Signal.Control -> Deriver ()
Documentation
type SRate = RealTime.RealTime Source #
Sampling rate.
Package up a curve name along with arguments.
forall arg. CurveD !Text !(Sig.Parser arg) !(arg -> Curve) |
curve_name :: CurveD -> Text Source #
type CurveF = Double -> Double Source #
Interpolation function. This maps 0--1 to the desired curve, which is also normalized to 0--1.
standard_curves :: [(Expr.Symbol, CurveD)] Source #
interpolator call
type InterpolatorTime a = Either (Sig.Parser DeriveT.Duration) (GetTime a, Text) Source #
Left for an explicit time arg. Right is for an implicit time, inferred from the args, along with an extra bit of documentation to describe it.
type GetTime a = PassedArgs a -> Deriver DeriveT.Duration Source #
interpolator_call :: Text -> CurveD -> InterpolatorTime Control -> Generator Control Source #
from_env :: Sig.Parser (Maybe Signal.Y) Source #
Use this for calls that start from the previous value, to give a way to override that behaviour.
interpolator_variations_ :: Taggable a => (Text -> CurveD -> InterpolatorTime a -> call) -> Expr.Symbol -> CurveD -> [(Expr.Symbol, call)] Source #
Create the standard set of interpolator calls. Generic so it can be used by PitchUtil as well.
get_prev_val :: Taggable a => PassedArgs a -> Deriver DeriveT.Duration Source #
curve as argument
curve_env :: Sig.Parser Curve Source #
For calls whose curve can be configured.
pf_linear_name :: Text Source #
A PFunction is a generic function, so it can't retain the distinction between Function and Linear. So I use a grody hack and keep the distinction in a special name.
curve_to_pf :: Text -> Curve -> DeriveT.PFunction Source #
Stuff a curve function into a PFunction.
pf_to_curve :: DeriveT.PFunction -> Curve Source #
Convert a PFunction back into a curve function.
interpolate
place_range :: Typecheck.Normalized -> ScoreTime -> DeriveT.Duration -> Deriver (RealTime.RealTime, RealTime.RealTime) Source #
Given a placement, start, and duration, return the range thus implied.
make_segment_from :: Curve -> RealTime.RealTime -> Maybe Signal.Y -> RealTime.RealTime -> Signal.Y -> Deriver Signal.Control Source #
Make a curve segment from the previous value, if there was one.
make_segment :: Curve -> RealTime.RealTime -> Signal.Y -> RealTime.RealTime -> Signal.Y -> Deriver Signal.Control Source #
segment :: SRate -> Curve -> RealTime.RealTime -> Signal.Y -> RealTime.RealTime -> Signal.Y -> Signal.Control Source #
Interpolate between the given points.
make_function :: CurveF -> RealTime.RealTime -> Signal.Y -> RealTime.RealTime -> Signal.Y -> RealTime.RealTime -> Signal.Y Source #
slope
slope_to_limit :: Maybe Signal.Y -> Maybe Signal.Y -> Signal.Y -> Double -> RealTime.RealTime -> RealTime.RealTime -> Signal.Control Source #
Make a line with a certain slope, with optional lower and upper limits. TODO I could support Curve but it would make the intercept more complicated.
exponential
expon :: Double -> CurveF Source #
Negative exponents produce a curve that jumps from the "starting point" which doesn't seem too useful, so so hijack the negatives as an easier way to write 1/n. That way n is smoothly departing, while -n is smoothly approaching.
expon2 :: Double -> Double -> CurveF Source #
I could probably make a nicer curve of this general shape if I knew more math.
bezier
guess_x :: (Double -> (Double, Double)) -> CurveF Source #
As far as I can tell, there's no direct way to know what value to give to
the bezier function in order to get a specific x
. So I guess with binary
search.
https://youtu.be/aVwxzDHniEw?t=1119
sigmoid :: Double -> Double -> CurveF Source #
Generate a sigmoid curve. The first weight is the flatness at the start, and the second is the flatness at the end. Both should range from 0--1.
breakpoints
breakpoints :: SRate -> Curve -> [(RealTime.RealTime, Signal.Y)] -> Signal.Control Source #
Create line segments between the given breakpoints.
signal_breakpoints :: Monoid sig => (RealTime.RealTime -> y -> sig) -> (RealTime.RealTime -> y -> RealTime.RealTime -> y -> sig) -> [(RealTime.RealTime, y)] -> sig Source #
distribute :: RealTime.RealTime -> RealTime.RealTime -> [a] -> [(RealTime.RealTime, a)] Source #
Distribute the values evenly over the given time range.
smooth
:: Curve | |
-> RealTime.RealTime | |
-> RealTime.RealTime | If negative, each segment is from this much before the original sample until the sample. If positive, it starts on the sample. If samples are too close, the segments are shortened correspondingly. |
-> [(RealTime.RealTime, Signal.Y)] | |
-> Signal.Control |
Use the function to create a segment between each point in the signal.
Smooth with split_samples_absolute
.
smooth_relative :: Curve -> RealTime.RealTime -> ScoreT.Function -> [(RealTime.RealTime, Signal.Y)] -> Signal.Control Source #
Smooth with split_samples_relative
.
split_samples_absolute :: RealTime.RealTime -> [(RealTime.RealTime, y)] -> [(RealTime.RealTime, y)] Source #
Split apart samples to make a flat segment.
TODO if y=Pitch there's no Eq, so breakpoints winds up sampling flat segments. I could emit Maybe y where Nothing means same as previous.
0 1 2 3 4 5 6 7 8 0-------1-------0 0-----0=1-----1=0 time = -1 0-------0=1-----1=0 time = 1
split_samples_relative :: ScoreT.Function -> [(RealTime.RealTime, y)] -> [(RealTime.RealTime, y)] Source #
Like smooth_absolute
, but the transition time is a 0--1 proportion of the
available time, rather than an absolute time. Also, the transition is
always before the destination sample, unlike absolute, where it's only
before for a negative transition time. This is because I can't transition
after the sample, because the last sample has no next sample to take
a proportional time from!
0 1 2 3 4 5 6 7 8 0-------1-------0 0-----0=1-----1=0 time_at = const 0.25
control mod
:: Merge | |
-> ScoreT.Control | |
-> RealTime.RealTime | Where the modification should end. I don't need a start time since signals already have an implicit start time. |
-> Signal.Control | |
-> Deriver () |
Modify the signal only in the given range.
multiply_dyn :: RealTime.RealTime -> Signal.Control -> Deriver () Source #