-- | -- Module : DobutokO.Sound.Effects.Stretch -- Copyright : (c) OleksandrZhabenko 2020 -- License : MIT -- Stability : Experimental -- Maintainer : olexandr543@yahoo.com -- -- Helps to create experimental music. -- Can be used for applying the SoX \"stretch\" effect. -- {-# OPTIONS_GHC -threaded #-} {-# LANGUAGE CPP, FlexibleInstances #-} module DobutokO.Sound.Effects.Stretch 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 #ifdef __GLASGOW_HASKELL__ #if __GLASGOW_HASKELL__==708 /* code that applies only to GHC 7.8.* */ mconcat = concat #endif #endif data StretchP a = SR a a a deriving Eq -- | the first argument can be less than 1.0 but it is not recommended. The default value is 20.0. instance Show (StretchP Float) where show (SR x y z) = mconcat [showFFloat Nothing (abs x) " lin ", showFFloat Nothing (toRange 1.0 . abs $ y) " ", showFFloat Nothing (toRange 0.5 . abs $ z) " "] type StretchPF = StretchP Float stretch1 :: StretchP a -> a stretch1 (SR x _ _) = x stretch2 :: StretchP a -> a stretch2 (SR _ y _) = y stretch3 :: StretchP a -> a stretch3 (SR _ _ z) = z stretchSet1 :: a -> StretchP a -> StretchP a stretchSet1 x (SR _ y z) = SR x y z stretchSet2 :: a -> StretchP a -> StretchP a stretchSet2 y (SR x _ z) = SR x y z stretchSet3 :: a -> StretchP a -> StretchP a stretchSet3 z (SR x y _) = SR x y z data Stretch2 a b = SR21 a | SR22 a b deriving Eq instance Show (Stretch2 Float StretchPF) where show (SR21 x) = mconcat ["stretch ", if compare (abs x) 0.001 == LT then "0.001 " else showFFloat Nothing (abs x) " "] show (SR22 x y) = mconcat ["stretch ", if compare (abs x) 0.001 == LT then "0.001 " else showFFloat Nothing (abs x) " ", show y] type Stretch = Stretch2 Float StretchPF stretch2C :: Stretch2 a b -> String stretch2C (SR21 _) = "SR21" stretch2C _ = "SR22" stretch21 :: Stretch2 a b -> a stretch21 (SR21 x) = x stretch21 (SR22 x _) = x stretch22 :: Stretch2 a b -> Maybe b stretch22 (SR22 _ y) = Just y stretch22 _ = Nothing stretch2Set1 :: a -> Stretch2 a b -> Stretch2 a b stretch2Set1 x (SR21 _) = SR21 x stretch2Set1 x (SR22 _ y) = SR22 x y stretch2Set2 :: b -> Stretch2 a b -> Stretch2 a b stretch2Set2 y (SR21 x) = SR22 x y stretch2Set2 y (SR22 x _) = SR22 x y showSTRQ :: Stretch -> [String] showSTRQ = words . show