{-# LANGUAGE EmptyDataDecls, FlexibleInstances #-}

module Euterpea.IO.Audio.Types where

import Control.Arrow.ArrowP
import Control.SF.SF


class Clock p where
    rate :: p -> Double  -- sampling rate


data AudRate
data CtrRate

instance Clock AudRate where
    rate :: AudRate -> Double
rate AudRate
_ = Double
44100

instance Clock CtrRate where
    rate :: CtrRate -> Double
rate CtrRate
_ = Double
4410

type AudSF a b  = SigFun AudRate a b
type CtrSF a b  = SigFun CtrRate a b

type Signal clk a b    = ArrowP SF clk a b
type SigFun clk a b    = ArrowP SF clk a b

-- Arbitrary number of channels (say, 5.1) can be supported by just adding more

-- instances of the AudioSample type class.


class AudioSample a where
    zero :: a
    mix :: a -> a -> a
    collapse :: a -> [Double]
    numChans :: a -> Int   
      -- allows us to reify the number of channels from the type.


instance AudioSample Double where
    zero :: Double
zero = Double
0
    mix :: Double -> Double -> Double
mix = Double -> Double -> Double
forall a. Num a => a -> a -> a
(+)
    collapse :: Double -> [Double]
collapse Double
a = [Double
a]
    numChans :: Double -> Int
numChans Double
_ = Int
1

instance AudioSample (Double,Double) where
    zero :: (Double, Double)
zero = (Double
0,Double
0)
    mix :: (Double, Double) -> (Double, Double) -> (Double, Double)
mix (Double
a,Double
b) (Double
c,Double
d) = (Double
aDouble -> Double -> Double
forall a. Num a => a -> a -> a
+Double
c,Double
bDouble -> Double -> Double
forall a. Num a => a -> a -> a
+Double
d)
    collapse :: (Double, Double) -> [Double]
collapse (Double
a,Double
b) = [Double
a,Double
b]
    numChans :: (Double, Double) -> Int
numChans (Double, Double)
_ = Int
2

-- Some useful type synonyms:

type Mono p = Signal p () Double
type Stereo p = Signal p () (Double,Double)