-- | Resonators
module Csound.Catalog.Reson(
    Reson,
    -- * Vowels

    -- | Resonators for the vowel sounds.
    anO, anA, anE, anIY, anO2, wow,

    -- * Modal synthesis

    -- ** Instruments
    strikeModes, scrapeModes, modesInstr, wetModesInstr,

    -- ** Exciters
    strike, scrape, simpleStrike, simpleScrape,

    -- ** Parameters
    -- | Parameters for the function 'Csound.Air.modes'
    Modes(..), fromModes,
    singleModes, dahinaModes, banyanModes, xylophoneModes, tibetanBowlModes180,
    spinelSphereModes, potLidModes, redCedarWoodPlateModes,
    tubularBellModes, redwoodPlateModes, douglasFirWoodPlateModes,
    uniformWoodenBarModes, uniformAluminumBarModes, vibraphoneModes1,
    vibraphoneModes2, chalandiPlatesModes, tibetanBowlModes152,
    tibetanBowlModes140, wineGlassModes, smallHandbellModes,
    albertClockBellBelfastModes, woodBlockModes
) where

import Csound.Base

-- | List of pairs of
--
-- > [(centerFrequency, bandWidth)]
--
-- It's a list of parameters for a bunch of the band pass filters (like reson, or bp).
-- Reson is intended to be used with functions 'Csound.Air.resons' and 'Csound.Air.resonsBy'.
type Reson = [(Sig, Sig)]

anO, anA, anE, anIY, anO2 :: Reson

anO :: Reson
anO  = [(Sig
280, Sig
20), (Sig
650, Sig
25), (Sig
2200, Sig
30), (Sig
3450, Sig
40), (Sig
4500, Sig
50)]
anA :: Reson
anA  = [(Sig
650, Sig
50), (Sig
1100, Sig
50), (Sig
2860, Sig
50), (Sig
3300, Sig
50), (Sig
4500, Sig
50)]
anE :: Reson
anE  = [(Sig
500, Sig
50), (Sig
1750, Sig
50), (Sig
2450, Sig
50), (Sig
3350, Sig
50), (Sig
5000, Sig
50)]
anIY :: Reson
anIY = [(Sig
330, Sig
50), (Sig
2000, Sig
50), (Sig
2800, Sig
50), (Sig
3650, Sig
50), (Sig
5000, Sig
50)]
anO2 :: Reson
anO2 = [(Sig
400, Sig
50), (Sig
840, Sig
50), (Sig
2800, Sig
50), (Sig
3250, Sig
50), (Sig
4500, Sig
50)]

-- | Produces a 'wow'-effect if modifier rises and then falls down.
--
-- > y = wow modifierSig x
wow :: Sig -> Reson -> Reson
wow :: Sig -> Reson -> Reson
wow Sig
kmod = ((Sig, Sig) -> (Sig, Sig)) -> Reson -> Reson
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((Sig, Sig) -> (Sig, Sig)) -> Reson -> Reson)
-> ((Sig, Sig) -> (Sig, Sig)) -> Reson -> Reson
forall a b. (a -> b) -> a -> b
$ \(Sig
a, Sig
b) -> (Sig
a Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
+ Sig
kmod, Sig
b)

---------------------------------------------------
-- modes instruments

strikeModes :: Modes Sig -> Sig -> Sig
strikeModes :: Modes Sig -> Sig -> Sig
strikeModes Modes Sig
ms Sig
cps = Modes Sig -> Sig -> Sig -> Sig
modesInstr Modes Sig
ms (Sig -> Sig -> Sig
blp Sig
cps Sig
simpleStrike) Sig
cps

scrapeModes :: Modes Sig -> Sig -> SE Sig
scrapeModes :: Modes Sig -> Sig -> SE Sig
scrapeModes Modes Sig
ms Sig
cps = (Sig -> Sig) -> SE Sig -> SE Sig
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Sig
exciter -> Modes Sig -> Sig -> Sig -> Sig
modesInstr Modes Sig
ms Sig
exciter Sig
cps) SE Sig
simpleScrape

modesInstr :: Modes Sig -> Sig -> Sig -> Sig
modesInstr :: Modes Sig -> Sig -> Sig -> Sig
modesInstr = D -> Modes Sig -> Sig -> Sig -> Sig
wetModesInstr D
0.1

wetModesInstr :: D -> Modes Sig -> Sig -> Sig -> Sig
wetModesInstr :: D -> Modes Sig -> Sig -> Sig -> Sig
wetModesInstr D
dryRatio Modes Sig
ms Sig
exciter Sig
cps
    = (Modes Sig -> Sig
forall a. Modes a -> a
modesGain Modes Sig
ms Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
* )
    (Sig -> Sig) -> Sig -> Sig
forall a b. (a -> b) -> a -> b
$ Sig -> (Sig -> Sig) -> Sig -> Sig
dryWet (D -> Sig
sig D
dryRatio) (Reson -> Sig -> Sig -> Sig
modes (Modes Sig -> Reson
forall a. Num a => Modes a -> [(a, a)]
fromModes Modes Sig
ms) Sig
cps) Sig
exciter

---------------------------------------------------
-- exciters

simpleStrike :: Sig
simpleStrike :: Sig
simpleStrike = Sig -> Sig -> Sig
mpulse Sig
1 Sig
0

strike :: D -> SE Sig
strike :: D -> SE Sig
strike D
dt' = do
    Sig
onHighDur   <- Sig -> Sig -> SE Sig
noise Sig
1 Sig
0
    Sig
onNormDur   <- Sig -> Sig -> SE Sig
noise (Sig -> D -> Tab -> D -> Sig
osciln Sig
1 (D
1 D -> D -> D
forall a. Fractional a => a -> a -> a
/ D
dt) Tab
decayShape D
1) Sig
0

    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
$ [(BoolSig, Sig)] -> Sig -> Sig
forall b. Tuple b => [(BoolSig, b)] -> b -> b
guardedTuple
        [ (D -> Sig
sig D
dt Sig -> Sig -> BooleanOf Sig
forall a. OrdB a => a -> a -> BooleanOf a
`lessThan` Sig
0.001,    Sig
onLowDur)
        , (D -> Sig
sig D
dt Sig -> Sig -> BoolSig
forall a bool. (OrdB a, bool ~ BooleanOf a) => a -> a -> bool
>=* Sig
1,        Sig
onHighDur)
        ]                       Sig
onNormDur
    where
        onLowDur :: Sig
onLowDur    = Sig -> Sig -> Sig
mpulse Sig
1 Sig
0
        decayShape :: Tab
decayShape = [Double] -> Tab
estartEnds [Double
1, -Double
0.002, Double
0]

        dt :: D
dt = D -> D -> D
forall a. (IfB a, OrdB a) => a -> a -> a
maxB D
dt' D
0.00001

simpleScrape  :: SE Sig
simpleScrape :: SE Sig
simpleScrape = Sig -> Sig -> SE Sig
scrape Sig
5000 Sig
50

scrape :: Sig -> Sig -> SE Sig
scrape :: Sig -> Sig -> SE Sig
scrape Sig
lpCps Sig
hpCps = (Sig -> Sig) -> SE Sig -> SE Sig
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Sig -> Sig -> Sig
bhp Sig
hpCps (Sig -> Sig) -> (Sig -> Sig) -> Sig -> Sig
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sig -> Sig -> Sig
blp Sig
lpCps) (SE Sig -> SE Sig) -> SE Sig -> SE Sig
forall a b. (a -> b) -> a -> b
$ Sig -> SE Sig
pinkish Sig
0.005

---------------------------------------------------

data Modes a = Modes
    { Modes a -> [a]
modesFrequencies      :: [a]
    , Modes a -> a
modesQualityFactor    :: a
    , Modes a -> [a]
modesQualityRatios    :: [a]
    , Modes a -> a
modesGain             :: a }

fromModes :: Num a => Modes a -> [(a, a)]
fromModes :: Modes a -> [(a, a)]
fromModes Modes a
a = [a] -> [a] -> [(a, a)]
forall a b. [a] -> [b] -> [(a, b)]
zip (Modes a -> [a]
forall a. Modes a -> [a]
modesFrequencies Modes a
a) ((a -> a) -> [a] -> [a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Modes a -> a
forall a. Modes a -> a
modesQualityFactor Modes a
a a -> a -> a
forall a. Num a => a -> a -> a
* ) ([a] -> [a]) -> [a] -> [a]
forall a b. (a -> b) -> a -> b
$ Modes a -> [a]
forall a. Modes a -> [a]
modesQualityRatios Modes a
a)

singleModes, dahinaModes, banyanModes, xylophoneModes, tibetanBowlModes180, spinelSphereModes,
    potLidModes, redCedarWoodPlateModes, tubularBellModes, redwoodPlateModes, douglasFirWoodPlateModes,
    uniformWoodenBarModes, uniformAluminumBarModes, vibraphoneModes1, vibraphoneModes2, chalandiPlatesModes,
    tibetanBowlModes152, tibetanBowlModes140, wineGlassModes, smallHandbellModes, albertClockBellBelfastModes,
    woodBlockModes :: Fractional a => Modes a

singleModes :: Modes a
singleModes = Modes :: forall a. [a] -> a -> [a] -> a -> Modes a
Modes
    { modesFrequencies :: [a]
modesFrequencies      = [a
1, a
1]
    , modesQualityFactor :: a
modesQualityFactor    = a
1000
    , modesQualityRatios :: [a]
modesQualityRatios    = a -> [a]
forall a. a -> [a]
repeat a
1
    , modesGain :: a
modesGain             = a
15 }

dahinaModes :: Modes a
dahinaModes = Modes :: forall a. [a] -> a -> [a] -> a -> Modes a
Modes
    { modesFrequencies :: [a]
modesFrequencies      = [a
1, a
2.89, a
4.95, a
6.99, a
8.01, a
9.02]
    , modesQualityFactor :: a
modesQualityFactor    = a
50
    , modesQualityRatios :: [a]
modesQualityRatios    = a -> [a]
forall a. a -> [a]
repeat a
1
    , modesGain :: a
modesGain             = a
15 }

banyanModes :: Modes a
banyanModes = Modes :: forall a. [a] -> a -> [a] -> a -> Modes a
Modes
    { modesFrequencies :: [a]
modesFrequencies      = [a
1, a
2.0, a
3.01, a
4.01, a
4.69, a
5.63]
    , modesQualityFactor :: a
modesQualityFactor    = a
444
    , modesQualityRatios :: [a]
modesQualityRatios     = a -> [a]
forall a. a -> [a]
repeat a
1
    , modesGain :: a
modesGain             = a
15 }

xylophoneModes :: Modes a
xylophoneModes = Modes :: forall a. [a] -> a -> [a] -> a -> Modes a
Modes
    { modesFrequencies :: [a]
modesFrequencies      = [a
1, a
3.932, a
9.538, a
16.688, a
24.566, a
31.147]
    , modesQualityFactor :: a
modesQualityFactor    = a
200
    , modesQualityRatios :: [a]
modesQualityRatios     = a -> [a]
forall a. a -> [a]
repeat a
1
    , modesGain :: a
modesGain             = a
15 }

-- (180mm)
tibetanBowlModes180 :: Modes a
tibetanBowlModes180 = Modes :: forall a. [a] -> a -> [a] -> a -> Modes a
Modes
    { modesFrequencies :: [a]
modesFrequencies      = [a
1, a
2.77828, a
5.18099, a
8.16289, a
11.66063, a
15.63801, a
19.99]
    , modesQualityFactor :: a
modesQualityFactor    = a
2200
    , modesQualityRatios :: [a]
modesQualityRatios     = a -> [a]
forall a. a -> [a]
repeat a
1
    , modesGain :: a
modesGain             = a
15 }

-- with diameter of 3.6675mm
spinelSphereModes :: Modes a
spinelSphereModes = Modes :: forall a. [a] -> a -> [a] -> a -> Modes a
Modes
    { modesFrequencies :: [a]
modesFrequencies      =
            [a
1, a
1.026513174725, a
1.4224916858532,  a
1.4478690202098,  a
1.4661959580455
            , a
1.499452545408, a
1.7891839345101,  a
1.8768994627782,  a
1.9645945254541
            , a
1.9786543873113,  a
2.0334612432847,  a
2.1452852391916,  a
2.1561524686621
            , a
2.2533435661294,  a
2.2905090816065,  a
2.3331798413917,  a
2.4567715528268
            , a
2.4925556408289,  a
2.5661806088514,  a
2.6055768738808,  a
2.6692760296751
            , a
2.7140956766436,  a
2.7543617293425,  a
2.7710411870043
            ]
    , modesQualityFactor :: a
modesQualityFactor    = a
80
    , modesQualityRatios :: [a]
modesQualityRatios     = a -> [a]
forall a. a -> [a]
repeat a
1
    , modesGain :: a
modesGain             = a
15 }

potLidModes :: Modes a
potLidModes = Modes :: forall a. [a] -> a -> [a] -> a -> Modes a
Modes
    { modesFrequencies :: [a]
modesFrequencies      = [ a
1, a
3.2, a
6.23, a
6.27, a
9.92, a
14.15 ]
    , modesQualityFactor :: a
modesQualityFactor    = a
1500
    , modesQualityRatios :: [a]
modesQualityRatios     = a -> [a]
forall a. a -> [a]
repeat a
1
    , modesGain :: a
modesGain             = a
15 }

redCedarWoodPlateModes :: Modes a
redCedarWoodPlateModes = Modes :: forall a. [a] -> a -> [a] -> a -> Modes a
Modes
    { modesFrequencies :: [a]
modesFrequencies      = [ a
1, a
1.47, a
2.09, a
2.56 ]
    , modesQualityFactor :: a
modesQualityFactor    = a
100
    , modesQualityRatios :: [a]
modesQualityRatios     = a -> [a]
forall a. a -> [a]
repeat a
1
    , modesGain :: a
modesGain             = a
15 }

tubularBellModes :: Modes a
tubularBellModes = Modes :: forall a. [a] -> a -> [a] -> a -> Modes a
Modes
    { modesFrequencies :: [a]
modesFrequencies      = [ a
272a -> a -> a
forall a. Fractional a => a -> a -> a
/a
437, a
538a -> a -> a
forall a. Fractional a => a -> a -> a
/a
437, a
874a -> a -> a
forall a. Fractional a => a -> a -> a
/a
437, a
1281a -> a -> a
forall a. Fractional a => a -> a -> a
/a
437, a
1755a -> a -> a
forall a. Fractional a => a -> a -> a
/a
437, a
2264a -> a -> a
forall a. Fractional a => a -> a -> a
/a
437, a
2813a -> a -> a
forall a. Fractional a => a -> a -> a
/a
437, a
3389a -> a -> a
forall a. Fractional a => a -> a -> a
/a
437, a
4822a -> a -> a
forall a. Fractional a => a -> a -> a
/a
437, a
5255a -> a -> a
forall a. Fractional a => a -> a -> a
/a
437 ]
    , modesQualityFactor :: a
modesQualityFactor    = a
2000
    , modesQualityRatios :: [a]
modesQualityRatios     = a -> [a]
forall a. a -> [a]
repeat a
1
    , modesGain :: a
modesGain             = a
15 }

redwoodPlateModes :: Modes a
redwoodPlateModes = Modes :: forall a. [a] -> a -> [a] -> a -> Modes a
Modes
    { modesFrequencies :: [a]
modesFrequencies      = [ a
1, a
1.47, a
2.11, a
2.57 ]
    , modesQualityFactor :: a
modesQualityFactor    = a
100
    , modesQualityRatios :: [a]
modesQualityRatios     = a -> [a]
forall a. a -> [a]
repeat a
1
    , modesGain :: a
modesGain             = a
15 }

douglasFirWoodPlateModes :: Modes a
douglasFirWoodPlateModes = Modes :: forall a. [a] -> a -> [a] -> a -> Modes a
Modes
    { modesFrequencies :: [a]
modesFrequencies      = [ a
1, a
1.42, a
2.11, a
2.47 ]
    , modesQualityFactor :: a
modesQualityFactor    = a
100
    , modesQualityRatios :: [a]
modesQualityRatios     = a -> [a]
forall a. a -> [a]
repeat a
1
    , modesGain :: a
modesGain             = a
15 }

uniformWoodenBarModes :: Modes a
uniformWoodenBarModes = Modes :: forall a. [a] -> a -> [a] -> a -> Modes a
Modes
    { modesFrequencies :: [a]
modesFrequencies      = [ a
1, a
2.572, a
4.644, a
6.984, a
9.723, a
12 ]
    , modesQualityFactor :: a
modesQualityFactor    = a
300
    , modesQualityRatios :: [a]
modesQualityRatios     = a -> [a]
forall a. a -> [a]
repeat a
1
    , modesGain :: a
modesGain             = a
15 }

uniformAluminumBarModes :: Modes a
uniformAluminumBarModes = Modes :: forall a. [a] -> a -> [a] -> a -> Modes a
Modes
    { modesFrequencies :: [a]
modesFrequencies      = [a
1, a
2.756, a
5.423, a
8.988, a
13.448, a
18.680 ]
    , modesQualityFactor :: a
modesQualityFactor    = a
1000
    , modesQualityRatios :: [a]
modesQualityRatios     = a -> [a]
forall a. a -> [a]
repeat a
1
    , modesGain :: a
modesGain             = a
15 }

vibraphoneModes1 :: Modes a
vibraphoneModes1 = Modes :: forall a. [a] -> a -> [a] -> a -> Modes a
Modes
    { modesFrequencies :: [a]
modesFrequencies      = [a
1, a
3.984, a
10.668, a
17.979, a
23.679, a
33.642]
    , modesQualityFactor :: a
modesQualityFactor    = a
2000
    , modesQualityRatios :: [a]
modesQualityRatios     = a -> [a]
forall a. a -> [a]
repeat a
1
    , modesGain :: a
modesGain             = a
15 }

vibraphoneModes2 :: Modes a
vibraphoneModes2 = Modes :: forall a. [a] -> a -> [a] -> a -> Modes a
Modes
    { modesFrequencies :: [a]
modesFrequencies      = [a
1, a
3.997, a
9.469, a
15.566, a
20.863, a
29.440]
    , modesQualityFactor :: a
modesQualityFactor    = a
2000
    , modesQualityRatios :: [a]
modesQualityRatios     = a -> [a]
forall a. a -> [a]
repeat a
1
    , modesGain :: a
modesGain             = a
15 }

chalandiPlatesModes :: Modes a
chalandiPlatesModes = Modes :: forall a. [a] -> a -> [a] -> a -> Modes a
Modes
    { modesFrequencies :: [a]
modesFrequencies      = [a
1, a
1.72581, a
5.80645, a
7.41935, a
13.91935]
    , modesQualityFactor :: a
modesQualityFactor    = a
500
    , modesQualityRatios :: [a]
modesQualityRatios     = a -> [a]
forall a. a -> [a]
repeat a
1
    , modesGain :: a
modesGain             = a
15 }

tibetanBowlModes152 :: Modes a
tibetanBowlModes152 = Modes :: forall a. [a] -> a -> [a] -> a -> Modes a
Modes
    { modesFrequencies :: [a]
modesFrequencies      = [a
1, a
2.66242, a
4.83757, a
7.51592, a
10.64012, a
14.21019, a
18.14027]
    , modesQualityFactor :: a
modesQualityFactor    = a
2200
    , modesQualityRatios :: [a]
modesQualityRatios     = a -> [a]
forall a. a -> [a]
repeat a
1
    , modesGain :: a
modesGain             = a
15 }

tibetanBowlModes140 :: Modes a
tibetanBowlModes140 = Modes :: forall a. [a] -> a -> [a] -> a -> Modes a
Modes
    { modesFrequencies :: [a]
modesFrequencies      = [a
1, a
2.76515, a
5.12121, a
7.80681, a
10.78409]
    , modesQualityFactor :: a
modesQualityFactor    = a
2200
    , modesQualityRatios :: [a]
modesQualityRatios     = a -> [a]
forall a. a -> [a]
repeat a
1
    , modesGain :: a
modesGain             = a
15 }

wineGlassModes :: Modes a
wineGlassModes = Modes :: forall a. [a] -> a -> [a] -> a -> Modes a
Modes
    { modesFrequencies :: [a]
modesFrequencies      = [a
1, a
2.32, a
4.25, a
6.63, a
9.38]
    , modesQualityFactor :: a
modesQualityFactor    = a
1500
    , modesQualityRatios :: [a]
modesQualityRatios     = a -> [a]
forall a. a -> [a]
repeat a
1
    , modesGain :: a
modesGain             = a
15 }

smallHandbellModes :: Modes a
smallHandbellModes = Modes :: forall a. [a] -> a -> [a] -> a -> Modes a
Modes
    { modesFrequencies :: [a]
modesFrequencies      =
        [ a
1, a
1.0019054878049, a
1.7936737804878, a
1.8009908536585, a
2.5201981707317
        , a
2.5224085365854, a
2.9907012195122, a
2.9940548780488, a
3.7855182926829
        , a
3.8061737804878, a
4.5689024390244, a
4.5754573170732, a
5.0296493902439
        , a
5.0455030487805, a
6.0759908536585, a
5.9094512195122, a
6.4124237804878
        , a
6.4430640243902, a
7.0826219512195, a
7.0923780487805, a
7.3188262195122
        , a
7.5551829268293
        ]
    , modesQualityFactor :: a
modesQualityFactor    = a
2500
    , modesQualityRatios :: [a]
modesQualityRatios     = a -> [a]
forall a. a -> [a]
repeat a
1
    , modesGain :: a
modesGain             = a
15 }

albertClockBellBelfastModes :: Modes a
albertClockBellBelfastModes = Modes :: forall a. [a] -> a -> [a] -> a -> Modes a
Modes
    { modesFrequencies :: [a]
modesFrequencies      =
            [ a
2.043260,a
1.482916,a
1.000000,a
3.328848,a
4.761811,a
1.477056,a
0.612007
            ,a
2.661295,a
1.002793,a
4.023776,a
0.254139,a
2.043916,a
4.032463,a
2.659438
            ,a
4.775560,a
5.500494,a
3.331014,a
0.809697,a
2.391301, a
0.254098,a
1.901476,a
2.366563
            ]
             -- ,0.614968,2.046543,1.814887,3.130744,2.484426,0.558874,0.801697,0.070870,3.617036,2.782656
    , modesQualityFactor :: a
modesQualityFactor    = a
2400
    , modesQualityRatios :: [a]
modesQualityRatios     = a -> [a]
forall a. a -> [a]
repeat a
1
    , modesGain :: a
modesGain             = a
15 }

woodBlockModes :: Modes a
woodBlockModes = Modes :: forall a. [a] -> a -> [a] -> a -> Modes a
Modes
    { modesFrequencies :: [a]
modesFrequencies      = [a
915a -> a -> a
forall a. Fractional a => a -> a -> a
/a
915,a
1540a -> a -> a
forall a. Fractional a => a -> a -> a
/a
915,a
1863a -> a -> a
forall a. Fractional a => a -> a -> a
/a
915,a
3112a -> a -> a
forall a. Fractional a => a -> a -> a
/a
915]
    , modesQualityFactor :: a
modesQualityFactor    = a
60
    , modesQualityRatios :: [a]
modesQualityRatios    = a -> [a]
forall a. a -> [a]
repeat a
1
    , modesGain :: a
modesGain             = a
15 }