
Hi. This is more a math question then a Haskell specific thing. However, Haskell fits nicely to write down the problem as executable "pseudo" code, so here I am, knowing that you all can read this and actually grasp the problem at hand (which I obviously dont). I stumbled across this while naively playing with C++ infinite ranges, starting with std::ranges::views::iota. So there I was, happily playing with signal generation, until I went stuck here: Modulating oscillation frequency while trying to stay stateless. But code says more then a foreign language, so: #!/usr/bin/env stack -- stack --resolver lts-19.8 runghc import Data.Ratio n = [0 ..] d = 10 -- EXAMPLE, usually 48000 t = (% d) <$> n sine f = (\x -> sin $ 2*pi * fromRational x * f x) <$> t sine1 = sine $ const 1 -- OK -- Lets devise a method to specify a value changing over time data I = No | Lin | Exp erp No a _ _ = a erp Lin a b mu = (1 - mu) * a + mu * b erp Exp a b mu = a * ((b / a) ** mu) data Curve a = Curve a [(I, Double, a)] at (Curve p1 []) _ = p1 at (Curve p1 ((i, d, p2):xs)) t = go 0 d p1 p2 i d xs where go t1 t2 p1 p2 i d xs | t < t2 = erp i p1 p2 $ (t - t1) / d | null xs = p1 | (i', d', p2') <- head xs = go t2 (t2 + d') p2 p2' i' d' $ tail xs -- Frequency modulation? c = Curve 1 [(Exp, 1.0, 2), (Exp, 1.0, 1)] sine2 = sine $ at c . fromRational -- WRONG!🙅 -- Whenever a change occurs, phase is incorrect -- because current step doesn't know about the past main = do print $ take 10 $ sine1 print $ at c 0.5 == at c 1.5 print $ take 10 $ sine2 -- The naive question of an experimenting non-math coder person is: -- Can a version of `at` be written which compensates for the phase -- differences which runs in O(n) where n is the number of curve points? -- Intuitively this should be possible given `d` (denominator). at' :: Curve a -> Ratio b -> a at' c t = undefined -- CYa, ⡍⠁⠗⠊⠕