ivory (amp, cps, vibRate, glisDur, cpsCoeff) = sig amp * mean 
    --    vibrato env                amplitude env               freq bias   phase   vibrato coeff   wave
    [ alg (linseg [0, idur, 5])      (lincone 0 0.7 1 0.3 0)     0           0       1               sine
    , alg (lincone 0 0.6 6 0.4 0)    (lincone 0 0.9 1 0.1 0)     0.009       0.2     0.9             (sines [10, 9 .. 1])
    , alg (lincone 9 0.7 1 0.3 1)    (linenIdur 0.5 0.333)       0.007       0.3     1.2             (sines [10, 0, 9, 0, 8, 0, 7, 0, 6, 0, 5])
    , alg (expcone 1 0.4 3 0.6 0.02) 
          (expcone 0.0001 0.8 1 0.2 0.0001)                      0.005       0.5     0.97            (sines [10, 10, 9, 0, 0, 0, 3, 2, 0, 0, 1])  
    , alg (expcone 1 0.4 3 0.6 0.02) 
          (expdur [0.001, 0.5, 1, 0.1, 0.6, 0.2, 0.97, 0.2, 0.001])
                                                                 0.003       0.8     0.99            (sines [10, 0, 0, 0, 5, 0, 0, 0, 0, 0, 3])
    , alg (expcone 4 0.91 1 0.09 1)  
          (expdur [0.001, 0.6, 1, 0.2, 0.8, 0.1, 0.98, 0.1, 0.001])
                                                                 0.001       1.3     1.4             (sines [10, 0, 0, 0, 0, 3, 1])
    ]
    where
        alg :: Sig -> Sig -> D -> D -> D -> Tab -> Sig    
        alg vibrEnv ampEnv cpsBias phsBias vibrCoeff wave = 
            ampEnv * (oscBy wave ((sig (cps + cpsBias) + vibr) * glis) `withD` phsBias)
            where glis = expseg [1, glisDur, 1, idur - glisDur, cpsCoeff]
                  vibr = vibrEnv * osc (sig $ vibRate * vibrCoeff)
                
        cone a x1 b x2 c = [a, x1 * idur, b, x2 * idur, c]
        lincone a x1 b x2 c = linseg $ cone a x1 b x2 c
        expcone a x1 b x2 c = expseg $ cone a x1 b x2 c
        linenIdur a b = linen 1 (a * idur) idur (b * idur)


-- snow flakes
ivory (amp, cps, vibRate, glisDur, cpsCoeff) = sig amp * mean 
    --    vibrato env                amplitude env               freq bias   phase   vibrato coeff   wave
    [ alg (linseg [0, idur, 5])      (lincone 0 0.7 1 0.3 0)     0           0       1               sine
    , alg (lincone 0 0.6 6 0.4 0)    (lincone 0 0.9 1 0.1 0)     0.009       0.2     0.9             (sines [10, 9 .. 1])
    , alg (lincone 9 0.7 1 0.3 1)    (linenIdur 0.5 0.333)       0.007       0.3     1.2             (sines [10, 0, 9, 0, 8, 0, 7, 0, 6, 0, 5])
    , alg (expcone 1 0.4 3 0.6 0.02) 
          (expcone 0.0001 0.8 1 0.2 0.0001)                      0.005       0.5     0.97            (sines [10, 10, 9, 0, 0, 0, 3, 2, 0, 0, 1])  
    , alg (expcone 1 0.4 3 0.6 0.02) 
          (expdur [0.001, 0.5, 1, 0.1, 0.6, 0.2, 0.97, 0.2, 0.001])
                                                                 0.003       0.8     0.99            (sines [10, 0, 0, 0, 5, 0, 0, 0, 0, 0, 3])
    , alg (expcone 4 0.91 1 0.09 1)  
          (expdur [0.001, 0.6, 1, 0.2, 0.8, 0.1, 0.98, 0.1, 0.001])
                                                                 0.001       1.3     1.4             (sines [10, 0, 0, 0, 0, 3, 1])
    ]
    where
        alg :: Sig -> Sig -> D -> D -> D -> Tab -> Sig    
        alg vibrEnv ampEnv cpsBias phsBias vibrCoeff wave = 
            ampEnv * (oscBy wave ((sig (cps + cpsBias) + vibr) * glis) `withD` phsBias)
            where glis = expseg [1, glisDur, 1, idur - glisDur, cpsCoeff]
                  vibr = vibrEnv * osc (sig $ vibRate * vibrCoeff)
                
        cone a x1 b x2 c = [a, x1 * idur, b, x2 * idur, c]
        lincone a x1 b x2 c = linseg $ cone a x1 b x2 c
        expcone a x1 b x2 c = expseg $ cone a x1 b x2 c
        linenIdur a b = linen 1 (a * idur) idur (b * idur)


-- snow flakes
ivory (amp, cps, vibRate, glisDur, cpsCoeff) = sig amp * mean 
    --    vibrato env                amplitude env               freq bias   phase   vibrato coeff   wave
    [ alg (linseg [0, idur, 5])      (lincone 0 0.7 1 0.3 0)     0           0       1               sine
    , alg (lincone 0 0.6 6 0.4 0)    (lincone 0 0.9 1 0.1 0)     0.009       0.2     0.9             (sines [10, 9 .. 1])
    , alg (lincone 9 0.7 1 0.3 1)    (linenIdur 0.5 0.333)       0.007       0.3     1.2             (sines [10, 0, 9, 0, 8, 0, 7, 0, 6, 0, 5])
    , alg (expcone 1 0.4 3 0.6 0.02) 
          (expcone 0.0001 0.8 1 0.2 0.0001)                      0.005       0.5     0.97            (sines [10, 10, 9, 0, 0, 0, 3, 2, 0, 0, 1])  
    , alg (expcone 1 0.4 3 0.6 0.02) 
          (expdur [0.001, 0.5, 1, 0.1, 0.6, 0.2, 0.97, 0.2, 0.001])
                                                                 0.003       0.8     0.99            (sines [10, 0, 0, 0, 5, 0, 0, 0, 0, 0, 3])
    , alg (expcone 4 0.91 1 0.09 1)  
          (expdur [0.001, 0.6, 1, 0.2, 0.8, 0.1, 0.98, 0.1, 0.001])
                                                                 0.001       1.3     1.4             (sines [10, 0, 0, 0, 0, 3, 1])
    ]
    where
        alg :: Sig -> Sig -> D -> D -> D -> Tab -> Sig    
        alg vibrEnv ampEnv cpsBias phsBias vibrCoeff wave = 
            ampEnv * (oscBy wave ((sig (cps + cpsBias) + vibr) * glis) `withD` phsBias)
            where glis = expseg [1, glisDur, 1, idur - glisDur, cpsCoeff]
                  vibr = vibrEnv * osc (sig $ vibRate * vibrCoeff)
                
        cone a x1 b x2 c = [a, x1 * idur, b, x2 * idur, c]
        lincone a x1 b x2 c = linseg $ cone a x1 b x2 c
        expcone a x1 b x2 c = expseg $ cone a x1 b x2 c
        linenIdur a b = linen 1 (a * idur) idur (b * idur)


-- snow flakes