-- |
-- Module      :  DobutokO.Sound.Effects.Specs
-- Copyright   :  (c) OleksandrZhabenko 2020
-- License     :  MIT
-- Stability   :  Experimental
-- Maintainer  :  olexandr543@yahoo.com
--
-- Helps to create experimental music. 
-- Can be used for applying the SoX effects with the needed specifications. 
-- 

{-# OPTIONS_GHC -threaded #-}
{-# LANGUAGE FlexibleInstances #-}

module DobutokO.Sound.Effects.Specs where

import Numeric (showFFloat)

data Frequency a = FHz a | FkHz a deriving Frequency a -> Frequency a -> Bool
(Frequency a -> Frequency a -> Bool)
-> (Frequency a -> Frequency a -> Bool) -> Eq (Frequency a)
forall a. Eq a => Frequency a -> Frequency a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Frequency a -> Frequency a -> Bool
$c/= :: forall a. Eq a => Frequency a -> Frequency a -> Bool
== :: Frequency a -> Frequency a -> Bool
$c== :: forall a. Eq a => Frequency a -> Frequency a -> Bool
Eq

instance Show (Frequency Float) where
  show :: Frequency Float -> String
show (FHz Float
x) = Maybe Int -> Float -> ShowS
forall a. RealFloat a => Maybe Int -> a -> ShowS
showFFloat Maybe Int
forall a. Maybe a
Nothing Float
x String
" "
  show (FkHz Float
x) = Maybe Int -> Float -> ShowS
forall a. RealFloat a => Maybe Int -> a -> ShowS
showFFloat Maybe Int
forall a. Maybe a
Nothing Float
x String
"k "
  
type Freq1 = Frequency Float  

frequency1 :: Freq1 -> Float
frequency1 :: Frequency Float -> Float
frequency1 (FHz Float
x) = Float
x
frequency1 (FkHz Float
x) = Float
1000.0 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x

frequencySet1 ::  Float -> Freq1 -> Freq1
frequencySet1 :: Float -> Frequency Float -> Frequency Float
frequencySet1 Float
x (FHz Float
_) = Float -> Frequency Float
forall a. a -> Frequency a
FHz Float
x
frequencySet1 Float
x (FkHz Float
_) = Float -> Frequency Float
forall a. a -> Frequency a
FkHz Float
x

data Width a = H a | K a | O a | Q a deriving Width a -> Width a -> Bool
(Width a -> Width a -> Bool)
-> (Width a -> Width a -> Bool) -> Eq (Width a)
forall a. Eq a => Width a -> Width a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Width a -> Width a -> Bool
$c/= :: forall a. Eq a => Width a -> Width a -> Bool
== :: Width a -> Width a -> Bool
$c== :: forall a. Eq a => Width a -> Width a -> Bool
Eq

instance Show (Width Float) where 
  show :: Width Float -> String
show (H Float
x) = Maybe Int -> Float -> ShowS
forall a. RealFloat a => Maybe Int -> a -> ShowS
showFFloat Maybe Int
forall a. Maybe a
Nothing Float
x String
"h"
  show (K Float
x) = Maybe Int -> Float -> ShowS
forall a. RealFloat a => Maybe Int -> a -> ShowS
showFFloat Maybe Int
forall a. Maybe a
Nothing Float
x String
"k"
  show (O Float
x) = Maybe Int -> Float -> ShowS
forall a. RealFloat a => Maybe Int -> a -> ShowS
showFFloat Maybe Int
forall a. Maybe a
Nothing Float
x String
"o"
  show (Q Float
x) = Maybe Int -> Float -> ShowS
forall a. RealFloat a => Maybe Int -> a -> ShowS
showFFloat Maybe Int
forall a. Maybe a
Nothing Float
x String
"q"

type Width1 = Width Float

width1 :: Width a -> a
width1 :: Width a -> a
width1 (H a
x) = a
x
width1 (K a
x) = a
x
width1 (O a
x) = a
x
width1 (Q a
x) = a
x

widthSet1 :: a -> Width a -> Width a
widthSet1 :: a -> Width a -> Width a
widthSet1 a
x (H a
_) = a -> Width a
forall a. a -> Width a
H a
x
widthSet1 a
x (K a
_) = a -> Width a
forall a. a -> Width a
K a
x
widthSet1 a
x (O a
_) = a -> Width a
forall a. a -> Width a
O a
x
widthSet1 a
x (Q a
_) = a -> Width a
forall a. a -> Width a
Q a
x