-- | Effects
module Csound.Air.Pan(    
    HeadPanSpec(..),
    headPan, headPan', staticHeadPan,
    headPan2, headPan2', staticHeadPan2,
    headPanNet, headPanNet2
) where

import Csound.Typed
import Csound.Air.Wav(toMono)

-- | The same as headPan but for stereo signals.
headPan2 :: (Sig, Sig) -> Sig2 -> Sig2
headPan2 :: Sig2 -> Sig2 -> Sig2
headPan2 Sig2
point = Sig2 -> Sig -> Sig2
headPan Sig2
point (Sig -> Sig2) -> (Sig2 -> Sig) -> Sig2 -> Sig2
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sig2 -> Sig
toMono

-- | The same as headPan' but for stereo signals.
headPan2' :: HeadPanSpec -> (Sig, Sig) -> Sig2 -> Sig2
headPan2' :: HeadPanSpec -> Sig2 -> Sig2 -> Sig2
headPan2' HeadPanSpec
spec Sig2
point = HeadPanSpec -> Sig2 -> Sig -> Sig2
headPan' HeadPanSpec
spec Sig2
point (Sig -> Sig2) -> (Sig2 -> Sig) -> Sig2 -> Sig2
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sig2 -> Sig
toMono

-- | The same as staticHeadPan but for stereo signals.
staticHeadPan2 :: (D, D) -> Sig2 -> Sig2
staticHeadPan2 :: (D, D) -> Sig2 -> Sig2
staticHeadPan2 (D, D)
point = (D, D) -> Sig -> Sig2
staticHeadPan (D, D)
point (Sig -> Sig2) -> (Sig2 -> Sig) -> Sig2 -> Sig2
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sig2 -> Sig
toMono

-- | Net of sounds evenly distributed oround the head.
-- First argument is a pair of numbers (column, rows) in the matrix.
-- The second argument is a matrix written in a single list.
-- The rows are for elevation and the columns are for azimuth.
--
-- A ghci session example:
--
-- > let f t x = mul 0.4 $ sched (\_ -> return $ fades 0.07 0.1 * tri x) $ withDur 0.2 $ metro t
-- > dac $ headPanNet (3, 2) [f 1 220, f 0.75 330, f 0.5 440, f 0.2 660, delaySnd 0.75 $ f 2 (220 * 5/4),delaySnd 0.4 $  f 1 (220 * 9/8)]
headPanNet :: (Int, Int) -> [Sig] -> Sig2
headPanNet :: (Int, Int) -> [Sig] -> Sig2
headPanNet (Int
m, Int
n) [Sig]
sigs = [Sig2] -> Sig2
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum ([Sig2] -> Sig2) -> [Sig2] -> Sig2
forall a b. (a -> b) -> a -> b
$ ((D, D) -> Sig -> Sig2) -> [(D, D)] -> [Sig] -> [Sig2]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (D, D) -> Sig -> Sig2
staticHeadPan [(Double -> D
double Double
a, Double -> D
double Double
b) | Double
a <- Int -> [Double]
forall {b} {a}. (Fractional b, Integral a) => a -> [b]
xs Int
m, Double
b <- Int -> [Double]
forall {b} {a}. (Fractional b, Integral a) => a -> [b]
xs Int
n] [Sig]
sigs
    where xs :: a -> [b]
xs a
t = (a -> b) -> [a] -> [b]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (( b -> b -> b
forall a. Fractional a => a -> a -> a
/ a -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
t) (b -> b) -> (a -> b) -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral) [a
0 .. (a
t a -> a -> a
forall a. Num a => a -> a -> a
- a
1)]
  
-- | The same as headPanNet but for stereo signals.
headPanNet2 :: (Int, Int) -> [Sig2] -> Sig2
headPanNet2 :: (Int, Int) -> [Sig2] -> Sig2
headPanNet2 (Int
m, Int
n) [Sig2]
sigs = (Int, Int) -> [Sig] -> Sig2
headPanNet (Int
m, Int
n) ((Sig2 -> Sig) -> [Sig2] -> [Sig]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Sig2 -> Sig
toMono [Sig2]
sigs)