-- |
-- Module      :  DobutokO.Sound.Effects.Loudness
-- Copyright   :  (c) OleksandrZhabenko 2020
-- License     :  MIT
-- Stability   :  Experimental
-- Maintainer  :  olexandr543@yahoo.com
--
-- Helps to create experimental music. 
-- Can be used for applying the SoX \"loudness\" effect. 
-- 

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

module DobutokO.Sound.Effects.Loudness where

#ifdef __GLASGOW_HASKELL__
#if __GLASGOW_HASKELL__>=710
/* code that applies only to GHC 7.10.* and higher versions */
import GHC.Base (mconcat)
#endif
#endif

import Numeric (showFFloat)

#ifdef __GLASGOW_HASKELL__
#if __GLASGOW_HASKELL__==708
/* code that applies only to GHC 7.8.* */
mconcat = concat
#endif
#endif

data Loudness a = L | L1 a | L2 a a deriving Loudness a -> Loudness a -> Bool
(Loudness a -> Loudness a -> Bool)
-> (Loudness a -> Loudness a -> Bool) -> Eq (Loudness a)
forall a. Eq a => Loudness a -> Loudness a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Loudness a -> Loudness a -> Bool
$c/= :: forall a. Eq a => Loudness a -> Loudness a -> Bool
== :: Loudness a -> Loudness a -> Bool
$c== :: forall a. Eq a => Loudness a -> Loudness a -> Bool
Eq

instance Show (Loudness Float) where
  show :: Loudness Float -> String
show (L1 Float
x)
    | Float -> Float -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Float
x (-Float
50.0) Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
/= Ordering
LT Bool -> Bool -> Bool
&& Float -> Float -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Float
x Float
15.0 Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
/= Ordering
GT = [String] -> String
forall a. Monoid a => [a] -> a
mconcat [String
"loudness ", Maybe Int -> Float -> ShowS
forall a. RealFloat a => Maybe Int -> a -> ShowS
showFFloat Maybe Int
forall a. Maybe a
Nothing Float
x String
" "]
    | Bool
otherwise = String
""
  show (L2 Float
x Float
y)
    | Float -> Float -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Float
x (-Float
50.0) Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
/= Ordering
LT Bool -> Bool -> Bool
&& Float -> Float -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Float
x Float
15.0 Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
/= Ordering
GT Bool -> Bool -> Bool
&& Float -> Float -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Float
y Float
50.0 Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
/= Ordering
LT Bool -> Bool -> Bool
&& Float -> Float -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Float
y Float
75.0 Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
/= Ordering
GT = [String] -> String
forall a. Monoid a => [a] -> a
mconcat [String
"loudness ", Maybe Int -> Float -> ShowS
forall a. RealFloat a => Maybe Int -> a -> ShowS
showFFloat Maybe Int
forall a. Maybe a
Nothing Float
x String
" ", 
       Maybe Int -> Float -> ShowS
forall a. RealFloat a => Maybe Int -> a -> ShowS
showFFloat Maybe Int
forall a. Maybe a
Nothing Float
y String
" "]
    | Bool
otherwise = String
""
  show Loudness Float
_ = String
"loudness "

type Ldness = Loudness Float

loudnessC :: Loudness a -> String
loudnessC :: Loudness a -> String
loudnessC Loudness a
L = String
"L"
loudnessC (L1 a
_) = String
"L1"
loudnessC Loudness a
_ = String
"L2"

loudness1 :: Loudness a -> Maybe a
loudness1 :: Loudness a -> Maybe a
loudness1 (L1 a
x) = a -> Maybe a
forall a. a -> Maybe a
Just a
x
loudness1 (L2 a
x a
_) = a -> Maybe a
forall a. a -> Maybe a
Just a
x
loudness1 Loudness a
_ = Maybe a
forall a. Maybe a
Nothing

loudness2 :: Loudness a -> Maybe a
loudness2 :: Loudness a -> Maybe a
loudness2 (L2 a
_ a
y) = a -> Maybe a
forall a. a -> Maybe a
Just a
y
loudness2 Loudness a
_ = Maybe a
forall a. Maybe a
Nothing

loudnessSet1 :: a -> Loudness a -> Loudness a
loudnessSet1 :: a -> Loudness a -> Loudness a
loudnessSet1 a
x (L2 a
_ a
y) = a -> a -> Loudness a
forall a. a -> a -> Loudness a
L2 a
x a
y
loudnessSet1 a
x Loudness a
_ = a -> Loudness a
forall a. a -> Loudness a
L1 a
x

loudnessSet2 :: a -> Loudness a -> Loudness a
loudnessSet2 :: a -> Loudness a -> Loudness a
loudnessSet2 a
y (L2 a
x a
_) = a -> a -> Loudness a
forall a. a -> a -> Loudness a
L2 a
x a
y
loudnessSet2 a
y (L1 a
x) = a -> a -> Loudness a
forall a. a -> a -> Loudness a
L2 a
x a
y
loudnessSet2 a
_ Loudness a
_ = Loudness a
forall a. Loudness a
L

showLdQ :: Ldness -> [String]
showLdQ :: Loudness Float -> [String]
showLdQ = String -> [String]
words (String -> [String])
-> (Loudness Float -> String) -> Loudness Float -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Loudness Float -> String
forall a. Show a => a -> String
show