{-# Language FlexibleInstances #-}
module Csound.Catalog.Wave.VestigeOfTime (
    filteredSaw, filteredSawRising, filteredSawFalling,
    filteredNoise,
    resonInstr, simpleResonInstr, resonVibrato,
    delaySaw, femaleVowel, amBell
) where

import Csound.Base hiding (filt)

import Csound.Catalog.Effect(vibroDelay)
import Csound.Catalog.Reson(Reson)

-- instruments

-- | Filtered saw with rising envelope. Centere frequency starts at 500 Hz
-- and then rises to 5000 by @riseDur@ seconds.
--
-- > filteredSawRising riseDur cps
filteredSawRising :: D -> Sig -> Sig
filteredSawRising :: D -> Sig -> Sig
filteredSawRising D
riseDur = Sig -> Sig -> Sig
filteredSaw ([D] -> Sig
linseg [D
500, D
riseDur, D
5000])

-- | Filtered saw with falling envelope. Centere frequency starts at 5000 Hz
-- and then falls down to 500 by @riseDur@ seconds.
--
-- > filteredSawFalling riseDur cps
filteredSawFalling :: D -> Sig -> Sig
filteredSawFalling :: D -> Sig -> Sig
filteredSawFalling D
fallDur = Sig -> Sig -> Sig
filteredSaw ([D] -> Sig
linseg [D
5000, D
fallDur, D
500])

-- | The saw is filtered with band pass filter. Centere frequency of the filter
-- can vary.
--
-- > filteredSaw centerFrequency sawCps
filteredSaw :: Sig -> Sig -> Sig
filteredSaw :: Sig -> Sig -> Sig
filteredSaw Sig
kcf Sig
cps = Sig
aout
    where
        a1 :: Sig
a1      = Int -> Sig -> (Sig -> Sig) -> Sig -> Sig
chorusPitch Int
3 Sig
0.003 Sig -> Sig
saw Sig
cps
        aout :: Sig
aout    = Sig -> Sig -> Sig -> Sig
reson Sig
a1 Sig
kcf Sig
100 Sig -> D -> Sig
forall a. Tuple a => a -> D -> a
`withD` D
2

-- | The white noise is filtered with band pass filter. Centere frequency of the filter
-- can vary.
--
-- > filteredNoise centerFrequency sawCps
filteredNoise :: Sig -> Sig -> SE Sig
filteredNoise :: Sig -> Sig -> SE Sig
filteredNoise Sig
cfq  Sig
bw = do
    Sig
anoise <- Sig -> SE Sig
rand Sig
1
    Sig -> SE Sig
forall (m :: * -> *) a. Monad m => a -> m a
return (Sig -> SE Sig) -> Sig -> SE Sig
forall a b. (a -> b) -> a -> b
$ Sig -> Sig -> Sig
balance (Sig -> Sig -> Sig -> Sig
reson Sig
anoise Sig
cfq Sig
bw Sig -> D -> Sig
forall a. Tuple a => a -> D -> a
`withD` D
2) Sig
anoise

-- |
-- > simpleResonInstr cycleLength cps
simpleResonInstr :: D -> Sig -> Sig
simpleResonInstr :: D -> Sig -> Sig
simpleResonInstr D
dt = Sig -> Sig -> Sig -> Sig -> Sig -> Sig
resonInstr (Tab -> Sig
f Tab
f21) (Tab -> Sig
f Tab
f22)  (Tab -> Sig
f Tab
f23) Sig
1
    where
        f :: Tab -> Sig
f = D -> Tab -> Sig
onceBy D
dt

        f21 :: Tab
f21 = [Double] -> Tab
lins [Double
1.000, Double
16, Double
0.950, Double
17, Double
0.830, Double
18, Double
0.680, Double
7, Double
0.530, Double
11, Double
0.390, Double
24, Double
0.200, Double
25, Double
0.120, Double
28, Double
0.050, Double
110, Double
0.000 ]

        f22 :: Tab
f22 = [Double] -> Tab
lins [Double
0.000, Double
20, Double
0.790, Double
8, Double
0.920, Double
14, Double
0.980, Double
14, Double
0.880, Double
11, Double
0.730, Double
17, Double
0.580, Double
17, Double
0.420, Double
16, Double
0.280, Double
21, Double
0.210, Double
19, Double
0.140, Double
99, Double
0.000 ]

        f23 :: Tab
f23 = [Double] -> Tab
lins [Double
0.000, Double
46, Double
0.690, Double
14, Double
0.880, Double
22, Double
0.980, Double
17, Double
0.880, Double
17, Double
0.700, Double
14, Double
0.570, Double
19, Double
0.400, Double
16, Double
0.310, Double
25, Double
0.220, Double
30, Double
0.090, Double
36, Double
0.000]



-- | Signal is passed through three band-pass filters.
-- We can alter the relative center frequencies of the filters.
--
-- > resonInstr filt1 filt2 filt3 amp cps = aout
resonInstr :: Sig -> Sig -> Sig -> Sig -> Sig -> Sig
resonInstr :: Sig -> Sig -> Sig -> Sig -> Sig -> Sig
resonInstr Sig
filt1 Sig
filt2 Sig
filt3 Sig
amp Sig
cps = Sig
aout
    where
        asig :: Sig
asig    = Sig
amp Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
* Tab -> Sig -> Sig
oscBy Tab
f19 Sig
cps
        asig2 :: Sig
asig2   = Sig
amp Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
* Sig
0.7 Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
* Sig -> Sig
osc Sig
cps

        phi :: Sig -> Sig -> Sig -> Sig
phi Sig
cf Sig
bw Sig
filt = Sig -> Sig -> Sig -> Sig
reson Sig
asig (Sig
cf Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
* Sig
filt) Sig
bw Sig -> D -> Sig
forall a. Tuple a => a -> D -> a
`withD` D
2
        aout :: Sig
aout = Sig -> Sig -> Sig
balance ([Sig] -> Sig
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum
                            [ Sig
0.6 Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
* Sig -> Sig -> Sig -> Sig
phi Sig
110 Sig
20 Sig
filt1
                            ,       Sig -> Sig -> Sig -> Sig
phi Sig
220 Sig
30 Sig
filt2
                            , Sig
0.6 Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
* Sig -> Sig -> Sig -> Sig
phi Sig
440 Sig
40 Sig
filt3
                            , Sig
0.4 Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
* Sig
asig
                            , Sig
2 Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
* Sig
asig2 ])
                        Sig
asig2

        f19 :: Tab
f19 = [Double] -> Tab
sines [Double
1, Double
0.1, Double
0.1, Double
0.278, Double
0.245, Double
0.3, Double
0.352, Double
0.846, Double
0.669, Double
0, Double
0, Double
0, Double
0.1, Double
0.1, Double
0.1]

-- | Vibrato and resonant filter with varying center frequency.
--
-- > resonVibrato vibDepth vibRate filtCps amp cps = aout
resonVibrato :: Sig -> Sig -> Sig -> Sig -> Sig -> Sig
resonVibrato :: Sig -> Sig -> Sig -> Sig -> Sig -> Sig
resonVibrato Sig
vibDepth Sig
vibRate Sig
filt Sig
amp Sig
cps = Sig -> Sig -> Sig
gain Sig
8 Sig
aout
    where
        asig :: Sig
asig = Sig -> Sig -> (Sig -> Sig) -> Sig -> Sig
forall a. Sig -> Sig -> (Sig -> a) -> Sig -> a
vibrate Sig
vibDepth Sig
vibRate ((Sig
amp Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
* ) (Sig -> Sig) -> (Sig -> Sig) -> Sig -> Sig
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Tab -> Sig -> Sig
oscBy Tab
waveTab) Sig
cps
        aout :: Sig
aout = Sig -> Sig -> Sig -> Sig
reson Sig
asig (Sig
5000 Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
* Sig
filt) Sig
50 Sig -> D -> Sig
forall a. Tuple a => a -> D -> a
`withD` D
2

        waveTab :: Tab
waveTab = [Double] -> Tab
sines [Double
1, Double
0.832, Double
0.5, Double
0.215, Double
0.6, Double
0.133, Double
0.785, Double
0.326, Double
0.018, Double
0.028, Double
0.0647, Double
0.0143, Double
0.0213]

-- | Singing a reson's vowels (see "Csound.Catalog.Reson").
femaleVowel :: Reson -> Sig -> Sig
femaleVowel :: Reson -> Sig -> Sig
femaleVowel Reson
vowel Sig
cps = Sig
aout
    where
        afilt1 :: Sig
afilt1 = Int -> Sig -> (Sig -> Sig) -> Sig -> Sig
chorusPitch Int
3 Sig
0.003 (\Sig
x -> Sig -> Sig -> Sig -> Tab -> Sig
buzz Sig
1 Sig
x Sig
15 Tab
sine) Sig
cps
        aout :: Sig
aout = Sig -> Sig -> Sig
blp Sig
2000 (Sig -> Sig) -> Sig -> Sig
forall a b. (a -> b) -> a -> b
$ (Sig -> Sig -> Sig -> Sig) -> Reson -> Sig -> Sig
forall cps bw.
(cps -> bw -> Sig -> Sig) -> [(cps, bw)] -> Sig -> Sig
resonsBy (\Sig
cf Sig
bw Sig
x -> Sig -> Sig -> Sig -> Sig
reson Sig
x Sig
cf Sig
bw Sig -> D -> Sig
forall a. Tuple a => a -> D -> a
`withD` D
2) Reson
vowel Sig
afilt1

-- | Delayed saw wave.
delaySaw :: Sig -> Sig
delaySaw :: Sig -> Sig
delaySaw Sig
cps = Int -> D -> Sig -> Sig -> Sig -> Sig
vibroDelay Int
6 D
3 Sig
2 Sig
0.25 (Sig -> Sig) -> Sig -> Sig
forall a b. (a -> b) -> a -> b
$ Sig -> Sig
saw Sig
cps

-- | Detuned bell.
--
-- > amBell amp cps
amBell :: D -> Sig -> Sig
amBell :: D -> Sig -> Sig
amBell D
amp Sig
cps = Sig
kenv Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
* Sig
aout
    where
        phi :: Sig -> Sig -> Sig -> Sig
phi Sig
a Sig
b Sig
c = (Sig
a Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
+ Sig
b) Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
* Sig -> Sig
osc (Sig
c Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
+ Sig
cps)
        a5 :: Sig
a5      = Sig -> Sig -> Sig -> Sig
phi Sig
0.25 Sig
0 Sig
1729
        a4 :: Sig
a4      = Sig -> Sig -> Sig -> Sig
phi Sig
0.3  Sig
a5 Sig
973
        a1 :: Sig
a1      = Sig -> Sig -> Sig -> Sig
phi Sig
0.5  Sig
a4 Sig
513
        a2 :: Sig
a2      = Sig -> Sig -> Sig -> Sig
phi Sig
1    Sig
a1 Sig
0
        aout :: Sig
aout    = Sig -> Sig -> Sig
balance Sig
a2 (Sig -> Sig
osc Sig
440)

        kenv :: Sig
kenv    = D -> Sig
sig D
amp Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
* [D] -> Sig
expseg [D
0.0001, D
0.01, D
1,D
amp D -> D -> D
forall a. Num a => a -> a -> a
* D
0.3, D
0.6, D
amp D -> D -> D
forall a. Num a => a -> a -> a
* D
8, D
0.0001]