diff options
author | Gregor Kleen <gkleen@yggdrasil.li> | 2015-06-21 19:40:40 +0200 |
---|---|---|
committer | Gregor Kleen <gkleen@yggdrasil.li> | 2015-06-21 19:40:40 +0200 |
commit | 4658cc95745dbdffd7bc1be2e61fa463b28b4a16 (patch) | |
tree | 0656da1577123f9f4eb05b72d66ad6c4682c5661 /src/Trivmix | |
parent | 5aeef88338cd761066ba196472e22f2c55fc846a (diff) | |
download | trivmix-4658cc95745dbdffd7bc1be2e61fa463b28b4a16.tar trivmix-4658cc95745dbdffd7bc1be2e61fa463b28b4a16.tar.gz trivmix-4658cc95745dbdffd7bc1be2e61fa463b28b4a16.tar.bz2 trivmix-4658cc95745dbdffd7bc1be2e61fa463b28b4a16.tar.xz trivmix-4658cc95745dbdffd7bc1be2e61fa463b28b4a16.zip |
Added adjmix
Diffstat (limited to 'src/Trivmix')
-rw-r--r-- | src/Trivmix/Types.hs | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/src/Trivmix/Types.hs b/src/Trivmix/Types.hs new file mode 100644 index 0000000..66accdf --- /dev/null +++ b/src/Trivmix/Types.hs | |||
@@ -0,0 +1,90 @@ | |||
1 | {-# LANGUAGE FlexibleInstances, UndecidableInstances #-} | ||
2 | |||
3 | module Trivmix.Types | ||
4 | ( Level | ||
5 | , toFloat | ||
6 | , Adjustment(..) | ||
7 | , doAdjustment | ||
8 | , module Data.Default | ||
9 | ) where | ||
10 | |||
11 | import Data.Fixed | ||
12 | import Data.CaseInsensitive ( CI ) | ||
13 | import qualified Data.CaseInsensitive as CI | ||
14 | |||
15 | import Data.Default | ||
16 | |||
17 | import Data.Function (on) | ||
18 | |||
19 | data Level = Lin Float | DB Float | ||
20 | |||
21 | instance Num Level where | ||
22 | (+) = asFloat (+) | ||
23 | (-) = asFloat (-) | ||
24 | (*) = asFloat (*) | ||
25 | abs = Lin . abs . toFloat | ||
26 | signum = Lin . signum . toFloat | ||
27 | fromInteger = Lin . fromInteger | ||
28 | |||
29 | asFloat :: (Float -> Float -> Float) -> Level -> Level -> Level | ||
30 | asFloat f (Lin x) (Lin y) = Lin $ f x y | ||
31 | asFloat f x y = DB $ (f `on` toFloat) x y | ||
32 | |||
33 | toFloat :: Level -> Float | ||
34 | toFloat (Lin x) = x | ||
35 | toFloat (DB x) = x | ||
36 | |||
37 | withPrec :: (Num a, RealFrac a, HasResolution b) => a -> Fixed b | ||
38 | withPrec x = withResolution $ \p' -> MkFixed $ toInteger $ round $ x * (fromInteger p') | ||
39 | |||
40 | withType :: (p a -> f a) -> f a | ||
41 | withType f = f undefined | ||
42 | |||
43 | withResolution :: (HasResolution a) => (Integer -> f a) -> f a | ||
44 | withResolution f = withType (f . resolution) | ||
45 | |||
46 | instance Show Level where | ||
47 | show (Lin x) = show x | ||
48 | show (DB x) = (show $ (withPrec x' :: Milli)) ++ "dB" | ||
49 | where | ||
50 | x' = 20 * (logBase 10 x) | ||
51 | |||
52 | instance Read Level where | ||
53 | readsPrec i = map toL . readsPrec i | ||
54 | where | ||
55 | toL :: (Float, String) -> (Level, String) | ||
56 | toL (f, str) | ||
57 | | ((==) `on` CI.mk) prec unit = (DB $ 10 ** (0.05 * f), rest) | ||
58 | | otherwise = (Lin f, str) | ||
59 | where | ||
60 | prec = take lU str | ||
61 | rest = drop lU str | ||
62 | unit = "dB" | ||
63 | lU = length unit | ||
64 | |||
65 | instance Eq Level where | ||
66 | (Lin a) == (Lin b) = a == b | ||
67 | (Lin a) == (DB b) = a == b | ||
68 | (DB a) == (Lin b) = a == b | ||
69 | (DB a) == (DB b) = a == b | ||
70 | |||
71 | instance Default Level where | ||
72 | def = Lin 0 | ||
73 | |||
74 | data Adjustment a = Set a | ||
75 | | Add a | ||
76 | | Sub a | ||
77 | deriving (Show, Eq) | ||
78 | |||
79 | class Adjustable a where | ||
80 | add :: a -> a -> a | ||
81 | sub :: a -> a -> a | ||
82 | |||
83 | instance Num a => Adjustable a where | ||
84 | add = (+) | ||
85 | sub = (-) | ||
86 | |||
87 | doAdjustment :: Adjustable a => a -> Adjustment a -> a | ||
88 | doAdjustment _ (Set y) = y | ||
89 | doAdjustment x (Add y) = add x y | ||
90 | doAdjustment x (Sub y) = sub x y | ||