{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeFamilies, NoMonoLocalBinds #-}

{-# LANGUAGE NoIncoherentInstances #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
{-# LANGUAGE NoUndecidableInstances #-}

module Vivid.UGens.Conversion (
     a2k
---   , degreeToKey
   , k2a
---   , t2a
---   , t2k
   ) where


import Vivid.SC.SynthDef.Types (CalculationRate(..))
import Vivid.SynthDef

import qualified Data.ByteString.UTF8 as UTF8


-- | Convert an audio rate signal to a control rate signal
a2k :: ToSig s a => s -> SDBody' a Signal
a2k :: s -> SDBody' a Signal
a2k = CalculationRate
AR CalculationRate -> CalculationRate -> s -> SDBody' a Signal
forall s (a :: [Symbol]).
ToSig s a =>
CalculationRate -> CalculationRate -> s -> SDBody' a Signal
`to` CalculationRate
KR

--- degreeToKey ::
--- degreeToKey =

-- | Convert a control rate signal to an audio rate signal
k2a :: ToSig s a => s -> SDBody' a Signal
k2a :: s -> SDBody' a Signal
k2a = CalculationRate
KR CalculationRate -> CalculationRate -> s -> SDBody' a Signal
forall s (a :: [Symbol]).
ToSig s a =>
CalculationRate -> CalculationRate -> s -> SDBody' a Signal
`to` CalculationRate
AR

--- t2a ::
--- t2a =
--- t2k ::
--- t2k =

to :: ToSig s a => CalculationRate -> CalculationRate -> (s -> SDBody' a Signal)
to :: CalculationRate -> CalculationRate -> s -> SDBody' a Signal
to CalculationRate
fromRate CalculationRate
toRate = \s
s -> do
   Signal
s' <- s -> SDBody' a Signal
forall s (args :: [Symbol]).
ToSig s args =>
s -> SDBody' args Signal
toSig s
s
   Signal -> SDBody' a CalculationRate
forall (args :: [Symbol]). Signal -> SDBody' args CalculationRate
getCalcRate Signal
s' SDBody' a CalculationRate
-> (CalculationRate
    -> StateT ([Int], SynthDef a, VarSet a) Identity ())
-> StateT ([Int], SynthDef a, VarSet a) Identity ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
      CalculationRate
rate | CalculationRate
rate CalculationRate -> CalculationRate -> Bool
forall a. Eq a => a -> a -> Bool
== CalculationRate
fromRate -> () -> StateT ([Int], SynthDef a, VarSet a) Identity ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
      CalculationRate
_ -> [Char] -> StateT ([Int], SynthDef a, VarSet a) Identity ()
forall a. HasCallStack => [Char] -> a
error ([Char] -> StateT ([Int], SynthDef a, VarSet a) Identity ())
-> [Char] -> StateT ([Int], SynthDef a, VarSet a) Identity ()
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
forall a. Monoid a => [a] -> a
mconcat [
          CalculationRate -> [Char]
forall a. Show a => a -> [Char]
show CalculationRate
fromRate,[Char]
"->",CalculationRate -> [Char]
forall a. Show a => a -> [Char]
show CalculationRate
toRate
         ,[Char]
" called without a "
         ,CalculationRate -> [Char]
forall a. Show a => a -> [Char]
show CalculationRate
fromRate,[Char]
" input"
         ]
   UGen -> SDBody' a Signal
forall (args :: [Symbol]). UGen -> SDBody' args Signal
addUGen (UGen -> SDBody' a Signal) -> UGen -> SDBody' a Signal
forall a b. (a -> b) -> a -> b
$ UGenName -> CalculationRate -> [Signal] -> Int -> UGen
UGen (ByteString -> UGenName
UGName_S ByteString
letters) CalculationRate
toRate [Signal
s'] Int
1
 where
   letters :: ByteString
letters = [Char] -> ByteString
UTF8.fromString [CalculationRate -> Char
calcLetter CalculationRate
fromRate,Char
'2',CalculationRate -> Char
calcLetter CalculationRate
toRate]
   calcLetter :: CalculationRate -> Char
calcLetter = \case
      CalculationRate
KR -> Char
'K'
      CalculationRate
AR -> Char
'A'
      CalculationRate
IR -> [Char] -> Char
forall a. HasCallStack => [Char] -> a
error [Char]
"ir?!?!"
      CalculationRate
DR -> [Char] -> Char
forall a. HasCallStack => [Char] -> a
error [Char]
"dominican republic?!?!"