-- | -- Module : DobutokO.Sound.Effects.Silence -- Copyright : (c) OleksandrZhabenko 2020 -- License : MIT -- Stability : Experimental -- Maintainer : olexandr543@yahoo.com -- -- Helps to create experimental music. -- Can be used for applying the SoX \"silence\" effect. -- {-# OPTIONS_GHC -threaded #-} {-# LANGUAGE CPP, FlexibleInstances, MultiParamTypeClasses #-} module DobutokO.Sound.Effects.Silence 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) import DobutokO.Sound.ToRange import DobutokO.Sound.Effects.Timespec (TimeSpec(..),NextTSpec) #ifdef __GLASGOW_HASKELL__ #if __GLASGOW_HASKELL__==708 /* code that applies only to GHC 7.8.* */ mconcat = concat #endif #endif data LeftIntact = L | Nl deriving Eq instance Show LeftIntact where show L = "-l " show _ = "" data Threshold a = T1 a | D1 a | P1 a deriving Eq instance Show (Threshold Float) where show (T1 x) = mconcat [show (truncate . abs $ x), " "] show (P1 x) = showFFloat Nothing (toRange 100.0 . abs $ x) "% " show (D1 x) = showFFloat Nothing (if x == 0.0 then -0.01 else -abs x) "d " type Threshold1 = Threshold Float thresholdC :: Threshold a -> String thresholdC (T1 _) = "T1" thresholdC (D1 _) = "D1" thresholdC _ = "P1" threshold1 :: Threshold a -> a threshold1 (T1 x) = x threshold1 (D1 x) = x threshold1 (P1 x) = x thresholdSet1 :: a -> Threshold a -> Threshold a thresholdSet1 x (T1 _) = T1 x thresholdSet1 x (D1 _) = D1 x thresholdSet1 x (P1 _) = P1 x data Duration a b = B a | T2 b | M a b deriving Eq -- there is a not clearly documented possibility to specify also hours as duration, but it is rarely used and so is omitted. instance Show (Duration Int Float) where show (B n) = mconcat [show (abs n), " "] show (T2 x) = showFFloat Nothing (abs x) "t " show (M n x) = mconcat [show (abs n), ":", showFFloat Nothing (abs x) " "] type Duration2 = Duration Int Float durationC :: Duration a b -> String durationC (B _) = "B" durationC (T2 _) = "T2" durationC _ = "M" duration1 :: Duration a b -> Maybe a duration1 (B x) = Just x duration1 (M x _) = Just x duration1 _ = Nothing duration2 :: Duration a b -> Maybe b duration2 (T2 y) = Just y duration2 (M _ y) = Just y duration2 _ = Nothing durationSet :: a -> b -> Int -> Duration a b durationSet x y n | n == 1 = B x | n == 2 = T2 y | otherwise = M x y durationSet1d :: a -> Duration a b -> Duration a b durationSet1d x (B _) = B x durationSet1d x (T2 y) = M x y durationSet1d x (M _ y) = M x y durationSet2d :: b -> Duration a b -> Duration a b durationSet2d y (B x) = M x y durationSet2d y (T2 _) = T2 y durationSet2d y (M x _) = M x y -- | Analogical to 'TSpec' but without the first argument (it is unneeded here). data STSpec a b = STs b | STm a b | STh a a b | SS a deriving Eq instance Show (STSpec Int Float) where show (STs y) = showFFloat Nothing (abs y) "t" show (STm y z) = mconcat [show (abs y),":",showFFloat Nothing (abs z) "t"] show (STh y1 y2 z) = mconcat [show (abs y1),":",show (abs y2),":",showFFloat Nothing (abs z) "t"] -- is rarely used, but is technically possible. show (SS y) = mconcat [show (abs y),"s"] type Above1TSpec = STSpec Int Float instance Show (TimeSpec Above1TSpec NextTSpec) where show (TS1 x) = mconcat [show x, " "] show (TS2 x ys) = mconcat [show x,mconcat . map show $ ys, " "] type STSpecification1 = TimeSpec Above1TSpec NextTSpec data STSpec2 a b = STs2 b | STm2 a b | STh2 a a b | SS2 a deriving Eq instance Show (STSpec2 Int Float) where show (STs2 y) = showFFloat Nothing y "t" show (STm2 y z) = mconcat [show y,":",showFFloat Nothing (abs z) "t"] show (STh2 y1 y2 z) = mconcat [show y1,":",show (abs y2),":",showFFloat Nothing (abs z) "t"] -- is rarely used, but is technically possible. show (SS2 y) = mconcat [show y,"s"] type BelowTSpec = STSpec2 Int Float instance Show (TimeSpec BelowTSpec NextTSpec) where show (TS1 x) = mconcat [show x, " "] show (TS2 x ys) = mconcat [show x,mconcat . map show $ ys, " "] type STSpecification2 = TimeSpec BelowTSpec NextTSpec data AboveTSpec1 a b c = Z | A a b c deriving Eq instance Show (AboveTSpec1 STSpecification1 Duration2 Threshold1) where show (A x y z) = mconcat [show x, show y, show z] show _ = "0 " type ATSpec = AboveTSpec1 STSpecification1 Duration2 Threshold1 aboveTSpec1 :: AboveTSpec1 a b c -> Maybe a aboveTSpec1 (A x _ _) = Just x aboveTSpec1 _ = Nothing aboveTSpec2 :: AboveTSpec1 a b c -> Maybe b aboveTSpec2 (A _ y _) = Just y aboveTSpec2 _ = Nothing aboveTSpec3 :: AboveTSpec1 a b c -> Maybe c aboveTSpec3 (A _ _ z) = Just z aboveTSpec3 _ = Nothing aboveTSpecSet1 :: a -> b -> c -> AboveTSpec1 a b c aboveTSpecSet1 = A aboveTSpecSet1a :: a -> AboveTSpec1 a b c -> AboveTSpec1 a b c aboveTSpecSet1a x (A _ y z) = A x y z aboveTSpecSet1a _ _ = Z aboveTSpecSet2a :: b -> AboveTSpec1 a b c -> AboveTSpec1 a b c aboveTSpecSet2a y (A x _ z) = A x y z aboveTSpecSet2a _ _ = Z aboveTSpecSet3a :: c -> AboveTSpec1 a b c -> AboveTSpec1 a b c aboveTSpecSet3a z (A x y _) = A x y z aboveTSpecSet3a _ _ = Z data BelowTSpec1 a b c = Z2 | BL a b c deriving Eq instance Show (BelowTSpec1 STSpecification2 Duration2 Threshold1) where show (BL x y z) = mconcat [show x, show y, show z] show _ = "" type BTSpec = BelowTSpec1 STSpecification2 Duration2 Threshold1 belowTSpec1 :: BelowTSpec1 a b c -> Maybe a belowTSpec1 (BL x _ _) = Just x belowTSpec1 _ = Nothing belowTSpec2 :: BelowTSpec1 a b c -> Maybe b belowTSpec2 (BL _ y _) = Just y belowTSpec2 _ = Nothing belowTSpec3 :: BelowTSpec1 a b c -> Maybe c belowTSpec3 (BL _ _ z) = Just z belowTSpec3 _ = Nothing belowTSpecSet1 :: a -> b -> c -> BelowTSpec1 a b c belowTSpecSet1 = BL belowTSpecSet1b :: a -> BelowTSpec1 a b c -> BelowTSpec1 a b c belowTSpecSet1b x (BL _ y z) = BL x y z belowTSpecSet1b _ _ = Z2 belowTSpecSet2b :: b -> BelowTSpec1 a b c -> BelowTSpec1 a b c belowTSpecSet2b y (BL x _ z) = BL x y z belowTSpecSet2b _ _ = Z2 belowTSpecSet3b :: c -> BelowTSpec1 a b c -> BelowTSpec1 a b c belowTSpecSet3b z (BL x y _) = BL x y z belowTSpecSet3b _ _ = Z2 data Silence a b c = SL2 a b | SL3 a b c deriving Eq instance Show (Silence LeftIntact ATSpec BTSpec) where show (SL2 x y) = mconcat ["silence ", show x, show y] show (SL3 x y z) = mconcat ["silence ", show x, show y, show z] type Silence3 = Silence LeftIntact ATSpec BTSpec silenceC :: Silence a b c -> String silenceC (SL2 _ _) = "SL2" silenceC (SL3 _ _ _) = "SL3" silence1 :: Silence a b c -> a silence1 (SL2 x _) = x silence1 (SL3 x _ _) = x silence2 :: Silence a b c -> b silence2 (SL2 _ y) = y silence2 (SL3 _ y _) = y silence3 :: Silence a b c -> Maybe c silence3 (SL3 _ _ z) = Just z silence3 _ = Nothing silenceSet1 :: a -> Silence a b c -> Silence a b c silenceSet1 x (SL2 _ y) = SL2 x y silenceSet1 x (SL3 _ y z) = SL3 x y z silenceSet2 :: b -> Silence a b c -> Silence a b c silenceSet2 y (SL2 x _) = SL2 x y silenceSet2 y (SL3 x _ z) = SL3 x y z silenceSet3 :: c -> Silence a b c -> Silence a b c silenceSet3 z (SL2 x y) = SL3 x y z silenceSet3 z (SL3 x y _) = SL3 x y z showSLQ :: Silence3 -> [String] showSLQ = words . show