packages feed

dobutokO4 (empty) → 0.1.0.0

raw patch · 6 files changed

+457/−0 lines, 6 filesdep +basedep +directorydep +dobutokO2setup-changed

Dependencies added: base, directory, dobutokO2, mmsyn3, mmsyn7l, process, vector, vector-doublezip

Files

+ ChangeLog.md view
@@ -0,0 +1,5 @@+# Revision history for dobutokO4++## 0.1.0.0 -- YYYY-mm-dd++* First version. Released on an unsuspecting world.
+ DobutokO/Sound/Faded.hs view
@@ -0,0 +1,236 @@+-- |+-- Module      :  DobutokO.Sound.Faded+-- Copyright   :  (c) OleksandrZhabenko 2020+-- License     :  MIT+-- Stability   :  Experimental+-- Maintainer  :  olexandr543@yahoo.com+--+-- Helps to create experimental music. +-- Uses SoX fade (in a special 2D way) and frequency modulation.++{-# OPTIONS_GHC -threaded #-}+{-# LANGUAGE CPP #-}++module DobutokO.Sound.Faded (+  -- * Create special faded effects+  overChangeVolG+  , overChangeVolGC+  , overChangeVolGF+  , overChangeVol+  , overChangeVolC+  , overChangeVolF+  -- * Mixing function+  , mixGTest+  -- * Generate several files+  , basicF+  , basicFC+  , basicF2+  , basicF2C+  -- * Auxiliary functions+  , endingWF+  , charFadeType+  , argString+  , freqChange+) 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 System.Exit (ExitCode (ExitSuccess))+import Data.List (isPrefixOf,isSuffixOf)+import Data.Maybe (fromJust)+import System.Process+import EndOfExe (showE)+import MMSyn7l (fadeEndsTMB,fadeEndsTMN)+import Numeric (showFFloat)+import qualified Data.Vector as V+import System.Directory+import DobutokO.Sound.Functional.Basics+import DobutokO.Sound.IntermediateF (soxBasicParams)+import Data.Vector.DoubleZip (evalSndFV)++#ifdef __GLASGOW_HASKELL__+#if __GLASGOW_HASKELL__==708+/* code that applies only to GHC 7.8.* */+mconcat = concat+#endif+#endif++-- | Generates sound the volume of which comes through the given 2D points in the time-volume scale with possibily changing frequency (they are specified by +-- the first and the second 'Double' arguments). Uses SoX inside especially \"fade\" and \"synth\" effects. For the equal frequencies generates specifically +-- faded output. +overChangeVolG :: String -> String -> Int -> Double -> Double -> Double -> Double -> ((Double,Double), (Double,Double)) -> IO ()+overChangeVolG ys cs j freq1 freq2 x0 xdelta ((t0,v0), (t1,v1)) + | x0 /= 0 && compare (abs x0) 1.0 /= GT && compare freq1 16 == GT && compare freq1 20000 == LT = +  case compare (v1 * v0) 0 of +    GT -> do+     (code1,_,herr1) <- readProcessWithExitCode (fromJust (showE "sox")) (soxBasicParams ys ["","-n","test1.wav","synth", +       showFFloat Nothing (if t1 == t0 then abs x0 else abs (t1 - t0)) "", "sine", showFFloat (Just 4) freq1 (freqChange (drop 1 cs) freq2 freq1), "fade", +        charFadeType (if null cs then 'l' else head cs)] ++ +         if compare ((v1 - v0) * (t1 - t0)) 0 /= LT then [showFFloat Nothing (if compare (abs (t1 - t0)) xdelta /= GT then abs x0 else abs (t1 - t0)) ""] +           else ["0", "-0.0", showFFloat Nothing (if compare (abs (t1 - t0)) xdelta /= GT then abs x0 else abs (t1 - t0)) "", "vol", +             showFFloat (Just 4) (signum v1 * abs (v1 - v0)) ""]) ""+     if code1 /= ExitSuccess then error $ "DobutokO.Sound.Times.overChangeVol: " ++ herr1+     else do+      (code2,_,herr2) <- readProcessWithExitCode (fromJust (showE "sox")) (soxBasicParams ys ["","-n","test0.wav","synth", +        showFFloat Nothing (if compare (abs (t1 - t0)) xdelta /= GT then abs x0 else abs (t1 - t0)) "", "sine", +          showFFloat (Just 4) freq1 (freqChange (drop 1 cs) freq2 freq1), "vol", showFFloat (Just 4) (min v0 v1) ""]) ""+      if code2 == ExitSuccess +        then do+          (code3,_,herr3) <- readProcessWithExitCode (fromJust (showE "sox")) ["-m","test0" ++ endingWF ys,"test1" ++ endingWF ys, "testG" ++ +            prependZeroes 6 (show j) ++ endingWF ys, "vol", "2"] ""+          if code3 == ExitSuccess +            then removeFile ("test0" ++ endingWF ys) >> removeFile ("test1" ++ endingWF ys)+            else error $ "DobutokO.Sound.Times.overChangeVol: " ++ herr3+        else print herr2 >> error "DobutokO.Sound.Times.overChangeVol: Operation not successful. "+    LT -> do  +     overChangeVolG ys cs j freq1 freq2 x0 xdelta ((t0,v0), ((v0 * t1 - v1 * t0) / (v0 - v1),0)) >> renameFile ("testG" ++ prependZeroes 6 (show j) ++ +       endingWF ys) ("temp0" ++ endingWF ys)+     overChangeVolG ys cs j freq1 freq2 x0 xdelta (((v0 * t1 - v1 * t0) / (v0 - v1),0), (t1,v1)) >> renameFile ("testG" ++ prependZeroes 6 (show j) ++ +       endingWF ys) ("temp1" ++ endingWF ys)+     (code1,_,herr1) <- readProcessWithExitCode (fromJust (showE "sox")) ["temp0" ++ endingWF ys,"temp1" ++ endingWF ys, "testG" ++ +       prependZeroes 6 (show j) ++ endingWF ys] ""+     if code1 == ExitSuccess then removeFile ("temp0" ++ endingWF ys) >> removeFile ("temp1" ++ endingWF ys)+     else error $ "DobutokO.Sound.Times.overChangeVol: " ++ herr1 +    _  -> +     case v1 of +      0 -> +       if v0 == 0 +        then do+          (code1,_,herr1) <- readProcessWithExitCode (fromJust (showE "sox")) (soxBasicParams ys ["","-n","testG" ++ prependZeroes 6 (show j) ++ +            ".wav","delay", showFFloat Nothing (if compare (abs (t1 - t0)) xdelta /= GT then abs x0 else abs (t1 - t0)) "", "trim", showFFloat Nothing +              (if compare (abs (t1 - t0)) xdelta /= GT then abs x0 else abs (t1 - t0)) ""]) ""+          if code1 /= ExitSuccess then error $ "DobutokO.Sound.Times.overChangeVol: " ++ herr1+          else return ()+        else do +          (code1,_,herr1) <- readProcessWithExitCode (fromJust (showE "sox")) (soxBasicParams ys ["","-n","testG" ++ prependZeroes 6 (show j) ++ +            ".wav","synth", showFFloat Nothing (if compare (abs (t1 - t0)) xdelta /= GT then abs x0 else abs (t1 - t0)) "", "sine", +              showFFloat (Just 4) freq1 (freqChange (drop 1 cs) freq2 freq1), "fade", charFadeType (if null cs then 'l' else head cs)] ++ +               if compare t0 t1 == GT then [showFFloat Nothing +                (if compare (abs (t1 - t0)) xdelta /= GT then abs x0 else abs (t1 - t0)) ""] else ["0", "-0.0", showFFloat Nothing +                  (if compare (abs (t1 - t0)) xdelta /= GT then abs x0 else abs (t1 - t0)) "", "vol", showFFloat (Just 4) v0 ""]) ""+          if code1 /= ExitSuccess then error $ "DobutokO.Sound.Times.overChangeVol: " ++ herr1+          else return ()+      _ -> do+       (code1,_,herr1) <- readProcessWithExitCode (fromJust (showE "sox")) (soxBasicParams ys ["","-n","testG" ++ prependZeroes 6 (show j) ++ ".wav",+         "synth", showFFloat Nothing (if compare (abs (t1 - t0)) xdelta /= GT then abs x0 else abs (t1 - t0)) "", "sine", +          showFFloat (Just 4) freq1 (freqChange (drop 1 cs) freq2 freq1), "fade", charFadeType (if null cs then 'l' else head cs)] ++ +           if compare t1 t0 == GT +            then [showFFloat Nothing (if compare (abs (t1 - t0)) xdelta /= GT then abs x0 +             else abs (t1 - t0)) ""] else ["0", "-0.0", showFFloat Nothing (if compare (abs (t1 - t0)) xdelta /= GT then abs x0 else abs (t1 - t0)) "", +               "vol", showFFloat (Just 4) v1 ""]) ""+       if code1 /= ExitSuccess then error $ "DobutokO.Sound.Times.overChangeVol: " ++ herr1+       else return ()+ | otherwise = error "DobutokO.Sound.Times.overChangeVol: sound for these conditions is not defined. "++freqChange :: String -> Double -> Double -> String+freqChange xs freq freq1 + | compare freq 16 /= LT && compare freq 20000 /= GT = if freq /= freq1 then+   case xs of +    "l" -> ':':showFFloat (Just 4) freq ""+    "s" -> '+':showFFloat (Just 4) freq ""+    "e" -> '/':showFFloat (Just 4) freq ""+    _ -> '-':showFFloat (Just 4) freq "" +     else ""+ | otherwise = error "DobutokO.Sound.Faded.freqChange: undefined for this value of the frequency (the first Double argument). "++-- | Generates sound the volume of which comes through the given 2D points in the time-volume scale. Uses SoX inside especially \"fade\" +-- and \"synth\" effects. A frequency does not change and is specified (in Hz) by the first 'Double' argument.+overChangeVol :: String -> Char -> Int -> Double -> Double -> Double -> ((Double,Double), (Double,Double)) -> IO () +overChangeVol ys c j freq1 = overChangeVolG ys [c] j freq1 freq1++-- | Generates sound the volume of which comes through the given 2D points in the time-volume scale. Uses SoX inside especially \"fade\" +-- and \"synth\" effects. A frequency does not change and is specified (in Hz) by the first 'Double' argument. Is a curried variant of the +-- 'overChangeVol' in its two last arguments.+overChangeVolC :: String -> Char -> Int -> Double -> Double -> Double -> (Double,Double) -> (Double,Double) -> IO ()+overChangeVolC ys c j freq x0 xdelta w1 = overChangeVol ys c j freq x0 xdelta . (,) w1++-- | Generates sound the volume of which comes through the given 2D points in the time-volume scale with possibily changing frequency (they are specified by +-- the first and the second 'Double' arguments). Uses SoX inside especially \"fade\" and \"synth\" effects. For the equal frequencies generates specifically +-- faded output. Is a curried variant of the 'overChangeVolG' in its two last arguments.+overChangeVolGC :: String -> String -> Int -> Double -> Double -> Double -> Double -> (Double,Double) -> (Double,Double) -> IO ()+overChangeVolGC ys cs j freq1 freq2 x0 xdelta w1 = overChangeVolG ys cs j freq1 freq2 x0 xdelta . (,) w1++-- | Generates sound the volume of which comes through the given 2D points in the time-volume scale. Uses SoX inside especially \"fade\" +-- and \"synth\" effects. Is a somewhat flipped variant of the 'overChangeVol' with changed order of the arguments (is provided here for convenience).+overChangeVolF :: String -> Char -> Int -> Double -> Double -> (Double,Double) -> (Double,Double) ->  Double -> IO ()+overChangeVolF ys c j x0 xdelta w1 w2 freq  = overChangeVol ys c j freq x0 xdelta (w1,w2)++-- | Generates sound the volume of which comes through the given 2D points in the time-volume scale with possibily changing frequency (they are specified by +-- the first and the second 'Double' arguments). Uses SoX inside especially \"fade\" and \"synth\" effects. For the equal frequencies generates specifically +-- faded output. Is a somewhat flipped variant of the 'overChangeVolG' with changed order of the arguments (is provided here for convenience).+overChangeVolGF :: String -> String -> Int -> Double -> Double -> (Double,Double) -> (Double,Double) ->  Double -> Double -> IO ()+overChangeVolGF ys cs j x0 xdelta w1 w2 freq1 freq2  = overChangeVolG ys cs j freq1 freq2 x0 xdelta (w1,w2)++-- | A simplified variant of the 'soxBasicParameters' function with defining only file extension.+endingWF :: String -> String+endingWF ys + | not (null ys) = if last ys == 'f' then ".flac" else ".wav"+ | otherwise = ".wav"++-- | Converts a character into a corresponding string using as a default one \"l\" (a logarithmic one). An output can specify then the fade type for SoX.+charFadeType :: Char -> String+charFadeType c = +  case c of+   'h' -> "h"+   'p' -> "p"+   't' -> "t"+   _  -> "l"++-- | Using SoX mixes all the \"testG*\" (of the WAV or FLAC extension specified by the 'String' argument -- see 'endingWF') in the current directory. +-- If there are \"resultG.*" (wav or flac respectively) file in the directory, it is overwritten. Also the "testG*" files are deleted afterwards if the +-- mixing is successful.+mixGTest :: String -> IO ()+mixGTest ys = do+  dir <- listDirectory "."+  (code1,_,herr1) <- readProcessWithExitCode (fromJust (showE "sox")) (mconcat [["-m"], filter (\xs -> "testG" `isPrefixOf` xs && +    endingWF ys `isSuffixOf` xs) dir, ["resultG" ++ endingWF ys]]) ""+  if code1 /= ExitSuccess then error $ "DobutokO.Sound.Times.mixGTest: " ++ herr1+  else mapM_ removeFile . filter (\xs -> "testG" `isPrefixOf` xs && endingWF ys `isSuffixOf` xs) $ dir+  +-- | Generates a sequence of sounds using 'overChangeVol' so that their time-volume characteristic is going through the 2D points obtained +-- with the last two arguments.+-- Uses 'fadeEndsTMB', the arguments for which are specified by the second symbol in the second 'String' and by the third 'Double' argument.+basicF :: String -> String -> Double -> Double -> Double -> Double -> (Double -> Double) -> V.Vector Double -> IO ()+basicF ys x2s freq x0 xdelta per f v = do+  let (xs1,xs2) = splitAt 1 x2s+      c1 = if null xs1 then 'l' else head xs1+      c2 = if null xs2 then 'l' else head xs2+  v1 <- evalSndFV f v+  V.imapM_ (\i x -> do+    overChangeVol ys c1 i freq x0 xdelta x+    fadeEndsTMB c2 per $ "testG" ++ prependZeroes 6 (show i) ++ endingWF ys) v1++-- | Splits its argument (like 'splitAt') into two 'String' with the length of (if possible) 4 and 2 characters. The rest of the argument is not used.+argString :: String -> (String,String)+argString xs = (take 4 xs,take 2 . drop 4 $ xs)++-- | Generates a sequence of sounds using 'overChangeVol' so that their time-volume characteristic is going through the 2D points obtained +-- with the last two arguments.+-- The 'String' should consist of 6 alphanumeric characters. The first four as for the 'soxBasicParams' and the last two -- letters from the \"hlpqt\". +-- Otherwise, the default values are used (\"221w\" for the first and \"ll\" for the second one).+basicFC :: String -> Double -> Double -> Double -> Double -> (Double -> Double) -> V.Vector Double -> IO ()+basicFC xs freq x0 xdelta per f v = let (ys,x2s) = argString xs in basicF ys x2s freq x0 xdelta per f v++-- | Generates a sequence of sounds using 'overChangeVol' so that their time-volume characteristic is going through the 2D points obtained +-- with the last two arguments.+-- Uses 'fadeEndsTMN', the arguments for which are specified by the second symbol in the second 'String' and by the third and fourth 'Double' arguments.+basicF2 :: String -> String -> Double -> Double -> Double -> Double -> Double -> (Double -> Double) -> V.Vector Double -> IO ()+basicF2 ys x2s freq x0 xdelta per1 per2 f v = do+  let (xs1,xs2) = splitAt 1 x2s+      c1 = if null xs1 then 'l' else head xs1+      c2 = if null xs2 then 'l' else head xs2+  v1 <- evalSndFV f v+  V.imapM_ (\i x -> do+    overChangeVol ys c1 i freq x0 xdelta x+    fadeEndsTMN c2 per1 per2 $ "testG" ++ prependZeroes 6 (show i) ++ endingWF ys) v1++-- | Generates a sequence of sounds using 'overChangeVol' so that their time-volume characteristic is going through the 2D points obtained +-- with the last two arguments.+-- The 'String' should consist of 6 alphanumeric characters. The first four as for the 'soxBasicParams' and the last two -- letters from the \"hlpqt\". +-- Otherwise, the default values are used (\"221w\" for the first and \"ll\" for the second one).+basicF2C :: String -> Double -> Double -> Double -> Double -> Double -> (Double -> Double) -> V.Vector Double -> IO ()+basicF2C xs freq x0 xdelta per1 per2 f v = let (ys,x2s) = argString xs in basicF2 ys x2s freq x0 xdelta per1 per2 f v
+ DobutokO/Sound/Presentation.hs view
@@ -0,0 +1,169 @@+-- |+-- Module      :  DobutokO.Sound.Presentation+-- Copyright   :  (c) OleksandrZhabenko 2020+-- License     :  MIT+-- Stability   :  Experimental+-- Maintainer  :  olexandr543@yahoo.com+--+-- Helps to create experimental music. +-- These module contains different representations for the data.++{-# OPTIONS_GHC -threaded #-}++module DobutokO.Sound.Presentation (+  -- * Sound repesentations+  SoundI (..)+  , SoundFN (..)+  , SoundT (..)+  -- * Sound time intervals representations+  , Timity (..)+  , Timity1 (..)+  , IntervalTim (..)+  , IntervalTimI (..)+  , IntervalG (..)+) where++import Data.Bifunctor +import Numeric (showFFloat)+import DobutokO.Sound.Functional.Basics++-- | An 'Int' parameter is an index of the 'SoundI' sound file in the sorted in the ascending order 'V.Vector' of them (the corresponding files or their +-- names) representing the whole composition.+data SoundI = Si Int Double Double OvertonesO | SAi Int Double Double Double OvertonesO | SAbi Int Double Double Double OvertonesO+  deriving Eq++----------------------------------------------------------------------------------++-- | An 'FilePath' parameter is a name of the sound file in the current directory with the filetype (supported by SoX) being given by 'String' representing +-- the whole composition.+data SoundFN = Sn FilePath String Double Double | SAn FilePath String Double Double Double | SAbn FilePath String Double Double Double+  deriving Eq++----------------------------------------------------------------------------------++-- | The first 'Double' parameter is a time moment (starting from 0) of the playing the sound being represented by 'OvertonesO', the second one is its +-- duration. The third one is its maximum amplitude by an absolute value. The fourth one is the minimum duration that can provide a needed human +-- feeling of perception (some impression) for the sound. The further one(s) is(are) some adjustment(s) parameter.+data SoundT = StO Double Double Double Double OvertonesO | SAtO Double Double Double Double Double OvertonesO | +  SAbtO Double Double Double Double Double OvertonesO deriving Eq++----------------------------------------------------------------------------------++-- | The first 'Double' parameter is a time moment (starting from 0) of the playing the sound, the second one is its duration in seconds (with a negative +-- values corresponding to the pause duration --- the silent \"sound\"), the third one is the minimum duration that can provide a needed human +-- feeling of perception (some impression) for the sound.+data Timity = Time Double Double Double deriving Eq++instance Ord Timity where +  compare (Time t01 t11 t21) (Time t02 t12 t22) +    | t01 /= t02 = compare t01 t02+    | abs t11 /= abs t12 = compare (abs t11) (abs t12)+    | otherwise = compare (abs t22) (abs t21)++instance Show Timity where+  show (Time t0 t1 t2) = showFFloat Nothing t0 ":(" ++ showFFloat Nothing t1 "):(" ++ showFFloat Nothing t2 ")"++-- | The first 'Double' parameter is a time moment (starting from 0) of the playing the sound, the second one is its duration in seconds (with a negative +-- values corresponding to the pause duration --- the silent \"sound\"), the third one is a parameter to specify more complex behaviour for the sound. +data Timity1 a = Time1 Double Double a ++instance (Eq a) => Eq (Timity1 a) where+  (==) (Time1 x1 x2 a0) (Time1 x3 x4 a1)+    | a0 /= a1 = False+    | x1 /= x3 = False+    | otherwise = x2 == x4++instance (Ord a) => Ord (Timity1 a) where +  compare (Time1 t01 t11 a0) (Time1 t02 t12 a1) +    | t01 /= t02 = compare t01 t02+    | abs t11 /= abs t12 = compare (abs t11) (abs t12)+    | otherwise = compare a0 a1++instance (Show a) => Show (Timity1 a) where+  show (Time1 t0 t1 a1) = showFFloat Nothing t0 ":(" ++ showFFloat Nothing t1 "):(" ++ show a1 ++ ")"  ++instance Functor Timity1 where+  fmap f (Time1 t1 t2 a0) = Time1 t1 t2 (f a0)++-- | Idempotent semigroup (band) (x <> x = x) if @Semigroup a@ is idempotent (is a band).+instance (Semigroup a) => Semigroup (Timity1 a) where+  (<>) (Time1 t01 t11 a0) (Time1 t02 t12 a1) = Time1 (min t01 t02) ((signum (t11 * t12)) * (max (t01 + (abs t11)) (t02 + (abs t12)) - min t01 t02)) +          (a0 <> a1)++-- | 'Double' interval representation with no order of the arguments preserved.+data IntervalTim = I Double Double++instance Eq IntervalTim where+  (==) (I x1 x2) (I y1 y2) +    | x1 /= y1 = if x1 == y2 then x2 == y1 else False+    | otherwise = x2 == y2++instance Ord IntervalTim where +  compare (I x01 x02) (I x11 x12) +    | min x01 x02 == min x11 x12 = compare (max x01 x02) (max x11 x12)+    | otherwise = compare (min x01 x02) (min x11 x12)++instance Show IntervalTim where+  show (I x1 x2) +    | compare x1 x2 /= GT = "[" ++ showFFloat Nothing x1 ", " ++ showFFloat Nothing x2 "]"+    | otherwise = "[" ++ showFFloat Nothing x2 ", " ++ showFFloat Nothing x1 "]"++-- | Idempotent semigroup (x <> x = x) -- band. +instance Semigroup IntervalTim where+  (<>) (I x01 x02) (I x11 x12) = I (minimum [x01,x02,x11,x12]) (maximum [x01,x02,x11,x12])+  +-- | Another 'Double' interval representation with no order of the arguments preserved. Has different instance of 'Semigroup' than 'IntervalTim'.+data IntervalTimI = II Double Double +  +instance Eq IntervalTimI where+  (==) (II x1 x2) (II y1 y2) +    | x1 /= y1 = if x1 == y2 then x2 == y1 else False+    | otherwise = x2 == y2++instance Ord IntervalTimI where +  compare (II x01 x02) (II x11 x12) +    | min x01 x02 == min x11 x12 = compare (max x01 x02) (max x11 x12)+    | otherwise = compare (min x01 x02) (min x11 x12)++instance Show IntervalTimI where+  show (II x1 x2) +    | compare x1 x2 /= GT = "[" ++ showFFloat Nothing x1 ", " ++ showFFloat Nothing x2 "]"+    | otherwise = "[" ++ showFFloat Nothing x2 ", " ++ showFFloat Nothing x1 "]"++-- | Idempotent semigroup (x <> x = x) -- band. +instance Semigroup IntervalTimI where+  (<>) (II x01 x02) (II x11 x12) = II (max (min x01 x02) (min x11 x12)) (min (max x01 x02) (max x11 x12))  +  +-- | The first 'Double' parameter is some adjustment parameter for the playing sound being represented by 'OvertonesO'.+data SoundTim = StOm Timity Double OvertonesO | SAtOm Timity Double Double OvertonesO | SAbtOm Timity Double Double OvertonesO+  deriving (Eq, Ord, Show)++----------------------------------------------------------------------------------++-- | Generalized interval representation.+data IntervalG a b = IG a b ++instance (Eq a, Eq b) => Eq (IntervalG a b) where+  (==) (IG a0 b0) (IG a1 b1) +    | a0 /= a1 = False+    | otherwise = b0 == b1++instance (Ord a, Ord b) => Ord (IntervalG a b) where+  compare (IG a0 b0) (IG a1 b1) +    | a0 /= a1 = compare a0 a1+    | otherwise = compare b0 b1++instance (Show a, Show b) => Show (IntervalG a b) where+  show (IG x y) = "[|" ++ show x ++ " __ " ++ show y ++ "|]"++-- | Idempotent semigroup (x <> x = x) and rectangular band (x <> y <> z = x <> z)+-- For more information, please, refer to: https://en.wikipedia.org/wiki/Band_(mathematics)+instance Semigroup (IntervalG a b) where+  (<>) (IG x0 _) (IG _ w1) = IG x0 w1++instance Functor (IntervalG a) where+  fmap f (IG a b) = IG a (f b)++instance Bifunctor IntervalG where+  bimap f g (IG x y) = IG (f x) (g y)+  
+ LICENSE view
@@ -0,0 +1,20 @@+Copyright (c) 2020 OleksandrZhabenko++Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+"Software"), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be included+in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ dobutokO4.cabal view
@@ -0,0 +1,25 @@+-- Initial dobutokO4.cabal generated by cabal init.  For further+-- documentation, see http://haskell.org/cabal/users-guide/++name:                dobutokO4+version:             0.1.0.0+synopsis:            Helps to create experimental music. Uses SoX inside.+description:         Uses SoX fade (in a special 2D way) and frequency modulation. Provides a special representation for the composition.+homepage:            https://hackage.haskell.org/package/dobutokO4+license:             MIT+license-file:        LICENSE+author:              OleksandrZhabenko+maintainer:          olexandr543@yahoo.com+-- copyright:+category:            Sound+build-type:          Simple+extra-source-files:  ChangeLog.md+cabal-version:       >=1.10++library+  exposed-modules:     DobutokO.Sound.Faded, DobutokO.Sound.Presentation+  -- other-modules:+  other-extensions:    CPP+  build-depends:       base >=4.7 && <4.15, vector >=0.11 && <0.14, process >=1.4 && <1.9, mmsyn3 >=0.1.5 && <1, directory >=1.2.7 && <1.7, mmsyn7l >=0.6.1 && <1, dobutokO2 >=0.41 && <1, vector-doublezip >= 0.1 && <1+  -- hs-source-dirs:+  default-language:    Haskell2010