diff options
Diffstat (limited to 'src/Trivmix/Types.hs')
| -rw-r--r-- | src/Trivmix/Types.hs | 60 |
1 files changed, 32 insertions, 28 deletions
diff --git a/src/Trivmix/Types.hs b/src/Trivmix/Types.hs index fe44a27..5e4660d 100644 --- a/src/Trivmix/Types.hs +++ b/src/Trivmix/Types.hs | |||
| @@ -2,12 +2,12 @@ | |||
| 2 | 2 | ||
| 3 | module Trivmix.Types | 3 | module Trivmix.Types |
| 4 | ( Level' | 4 | ( Level' |
| 5 | , Level(Lin), toLin | 5 | , Level(Lin, toLin) |
| 6 | , toFloat | 6 | , toScientific |
| 7 | , asFloat | 7 | , asScientific |
| 8 | , Balance(..) | 8 | , Balance(..) |
| 9 | , bToFloat | 9 | , bToScientific |
| 10 | , bAsFloat | 10 | , bAsScientific |
| 11 | , Adjustment(..) | 11 | , Adjustment(..) |
| 12 | , doAdjustment | 12 | , doAdjustment |
| 13 | , module Data.Default | 13 | , module Data.Default |
| @@ -27,27 +27,31 @@ import Data.Function (on) | |||
| 27 | 27 | ||
| 28 | import Refined | 28 | import Refined |
| 29 | 29 | ||
| 30 | type Level' = Refined NonNegative Float | 30 | import Data.Scientific |
| 31 | import Data.Scientific.Lift | ||
| 32 | |||
| 33 | |||
| 34 | type Level' = Refined NonNegative Scientific | ||
| 31 | data Level = Lin { toLin :: Level' } | DB { toLin :: Level' } | 35 | data Level = Lin { toLin :: Level' } | DB { toLin :: Level' } |
| 32 | 36 | ||
| 33 | instance Num Level where | 37 | instance Num Level where |
| 34 | (+) = fmap (either error id) . asFloat (+) | 38 | (+) = fmap (either error id) . asScientific (+) |
| 35 | (-) = fmap (either error id) . asFloat (-) | 39 | (-) = fmap (either error id) . asScientific (-) |
| 36 | (*) = fmap (either error id) . asFloat (*) | 40 | (*) = fmap (either error id) . asScientific (*) |
| 37 | abs = id | 41 | abs = id |
| 38 | signum = Lin . either error id . refine . signum . toFloat | 42 | signum = Lin . either error id . refine . signum . toScientific |
| 39 | fromInteger = Lin . either error id . refine . fromInteger | 43 | fromInteger = Lin . either error id . refine . fromInteger |
| 40 | 44 | ||
| 41 | asFloat :: (Float -> Float -> Float) -> Level -> Level -> Either String Level | 45 | asScientific :: (Scientific -> Scientific -> Scientific) -> Level -> Level -> Either String Level |
| 42 | asFloat ((`on` toFloat) -> f) x y = toLvl <$> refine (f x y) | 46 | asScientific ((`on` toScientific) -> f) x y = toLvl <$> refine (f x y) |
| 43 | where | 47 | where |
| 44 | toLvl | 48 | toLvl |
| 45 | | DB _ <- x = DB | 49 | | DB _ <- x = DB |
| 46 | | DB _ <- y = DB | 50 | | DB _ <- y = DB |
| 47 | | otherwise = Lin | 51 | | otherwise = Lin |
| 48 | 52 | ||
| 49 | toFloat :: Level -> Float | 53 | toScientific :: Level -> Scientific |
| 50 | toFloat = unrefine . toLin | 54 | toScientific = unrefine . toLin |
| 51 | 55 | ||
| 52 | withPrec :: (Num a, RealFrac a, HasResolution b) => a -> Fixed b | 56 | withPrec :: (Num a, RealFrac a, HasResolution b) => a -> Fixed b |
| 53 | withPrec x = withResolution $ \p' -> MkFixed $ toInteger $ round $ x * (fromInteger p') | 57 | withPrec x = withResolution $ \p' -> MkFixed $ toInteger $ round $ x * (fromInteger p') |
| @@ -58,11 +62,11 @@ withType f = f undefined | |||
| 58 | withResolution :: (HasResolution a) => (Integer -> f a) -> f a | 62 | withResolution :: (HasResolution a) => (Integer -> f a) -> f a |
| 59 | withResolution f = withType (f . resolution) | 63 | withResolution f = withType (f . resolution) |
| 60 | 64 | ||
| 61 | linToDb :: Level' -> Float | 65 | linToDb :: Level' -> Scientific |
| 62 | linToDb (unrefine -> x) = 20 * (logBase 10 x) | 66 | linToDb (unrefine -> x) = realToFrac (20 * (logBase 10 $ toRealFloat x) :: Double) |
| 63 | 67 | ||
| 64 | dBToLin :: Float -> Level' | 68 | dBToLin :: Scientific -> Level' |
| 65 | dBToLin x = either error id . refine $ 10 ** (0.05 * x) | 69 | dBToLin x = either error id . refine . realToFrac $ (10 ** (0.05 * toRealFloat x) :: Double) |
| 66 | 70 | ||
| 67 | instance Show Level where | 71 | instance Show Level where |
| 68 | show (Lin (unrefine -> x)) = show x | 72 | show (Lin (unrefine -> x)) = show x |
| @@ -93,25 +97,25 @@ instance Default Level where | |||
| 93 | 97 | ||
| 94 | 98 | ||
| 95 | 99 | ||
| 96 | newtype Balance = Balance { unBalance :: Refined ZeroToOne Float } | 100 | newtype Balance = Balance { unBalance :: Refined ZeroToOne Scientific } |
| 97 | deriving (Ord, Eq) | 101 | deriving (Ord, Eq) |
| 98 | 102 | ||
| 99 | bAsFloat :: (Float -> Float -> Float) -> Balance -> Balance -> Either String Balance | 103 | bAsScientific :: (Scientific -> Scientific -> Scientific) -> Balance -> Balance -> Either String Balance |
| 100 | bAsFloat f (unrefine . unBalance -> x) (unrefine . unBalance -> y) = fmap Balance . refine $ f x y | 104 | bAsScientific f (unrefine . unBalance -> x) (unrefine . unBalance -> y) = fmap Balance . refine $ f x y |
| 101 | 105 | ||
| 102 | bToFloat :: Balance -> Float | 106 | bToScientific :: Balance -> Scientific |
| 103 | bToFloat = unrefine . unBalance | 107 | bToScientific = unrefine . unBalance |
| 104 | 108 | ||
| 105 | instance Num Balance where | 109 | instance Num Balance where |
| 106 | (+) = fmap (either error id) . bAsFloat (+) | 110 | (+) = fmap (either error id) . bAsScientific (+) |
| 107 | (-) = fmap (either error id) . bAsFloat (-) | 111 | (-) = fmap (either error id) . bAsScientific (-) |
| 108 | (*) = fmap (either error id) . bAsFloat (*) | 112 | (*) = fmap (either error id) . bAsScientific (*) |
| 109 | abs = id | 113 | abs = id |
| 110 | signum = Balance . either error id . refine . signum . bToFloat | 114 | signum = Balance . either error id . refine . signum . bToScientific |
| 111 | fromInteger = Balance . either error id . refine . fromInteger | 115 | fromInteger = Balance . either error id . refine . fromInteger |
| 112 | 116 | ||
| 113 | instance Show Balance where | 117 | instance Show Balance where |
| 114 | show = show . bToFloat | 118 | show = show . bToScientific |
| 115 | 119 | ||
| 116 | instance Read Balance where | 120 | instance Read Balance where |
| 117 | readsPrec = readPrec_to_S $ do | 121 | readsPrec = readPrec_to_S $ do |
