prev (24) slide 25 / 33 next (26)

track lang

data Val =
    -- | Goes in a pitch track val field.  Literal: @*5a@
    VNote Pitch.Note
    ...

class Typecheck a where
    type_check :: Val → Maybe a
    type_name :: a → String

instance Typecheck Pitch.Note where
    type_check (VNote a) = Just a
    type_check _ = Nothing
    type_name _ = "note"

...

call2 :: (Typecheck a, Typecheck b) =>
    [Val] → (Arg a, Arg b) → (a → b → result) → Either TypeError result
call2 vals (arg0, arg1) f = do
    (val0, val1) <- extract2 vals (arg0, arg1)
    return $ f val0 val1

extract2 :: (Typecheck a, Typecheck b) =>
    [Val] → (Arg a, Arg b) → Either TypeError (a, b)
extract2 vals (sig0, sig1) = do
    arg0 : arg1 : _ <- check_args vals [arg_opt sig0, arg_opt sig1]
    liftM2 (,) (extract_arg 0 sig0 arg0) (extract_arg 1 sig1 arg1)


c_echo :: Derive.Call
c_echo args events = TrackLang.call3 args
    ( optional "delay" (signal 1 "echo-delay")
    , optional "feedback" (signal 0.4 "echo-feedback")
    , optional "times" (signal 1 "echo-times")) $ \delay feedback times →
    Call.map_any events () $ Call.with_signals [delay, feedback, times] $
    \[delay, feedback, times] (_, _, event, _) →
        return ((), echo (Signal.y_to_x delay) feedback (floor times) event)
prev (24) slide 25 / 33 next (26)