packages feed

dobutokO2 0.2.0.0 → 0.3.0.0

raw patch · 4 files changed

+157/−83 lines, 4 files

Files

CHANGELOG.md view
@@ -7,3 +7,8 @@ ## 0.2.0.0 -- 2020-03-05  * Second version. Added the functionality connected with octaves. Some documentation and code improvements.++## 0.3.0.0 -- 2020-03-06++* Third version. Added the opportunity to specify more parameters: additionally basic sound duration and the level of obertones influence the generated sounds.+Fixed issues with possibly incorrect argument sending to the SoX executable. Some documentation and code improvements.
DobutokO/Sound.hs view
@@ -17,11 +17,13 @@   , oberTones   , oberSoXSynth   , oberSoXSynthN+  -- *** Uses a file for information   , oberSoXSynthNGen   -- ** For the unique for the String structure timbre   , uniqOberTonesV   , uniqOberSoXSynth   , uniqOberSoXSynthN+  -- *** Uses a file for information   , uniqOberSoXSynthNGen   -- ** Work with octaves   , octavesT@@ -39,6 +41,7 @@   , prependZeroes ) where +import Numeric import Control.Exception (onException) import System.Environment (getArgs) import Data.List (isPrefixOf,sort)@@ -173,10 +176,10 @@       v0    = oberTones note0       v1    = oberTones note1       oberSoXSynthHelp vec = V.imapM_ (\i (noteN, amplN) -> readProcessWithExitCode (fromJust (showE "sox"))-        ["-r22050", "-n", "test0" ++ show (i + 2) ++ ".wav", "synth", "0.5","sine", show noteN, "vol", show amplN] "") vec+        ["-r22050", "-n", "test0" ++ show (i + 2) ++ ".wav", "synth", "0.5","sine", showFFloat (Just 4) noteN $ show 0, "vol", showFFloat (Just 4) amplN $ show 0] "") vec       oberSoXSynthHelp2 vec = V.imapM_ (\i (noteN, amplN) -> readProcessWithExitCode (fromJust (showE "sox"))-        ["-r22050", "-n", "test1" ++ show (i + 2) ++ ".wav", "synth", "0.5","sine", show noteN, "vol", show amplN] "") vec-  _ <- readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "test01.wav", "synth", "0.5","sine", show note0, "synth", "0.5","sine", "mix", show note1] ""+        ["-r22050", "-n", "test1" ++ show (i + 2) ++ ".wav", "synth", "0.5","sine", showFFloat (Just 4) noteN $ show 0, "vol", showFFloat (Just 4) amplN $ show 0] "") vec+  _ <- readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "test01.wav", "synth", "0.5","sine", showFFloat (Just 4) note0 $ show 0, "synth", "0.5","sine", "mix", showFFloat (Just 4) note1 $ show 0] ""   oberSoXSynthHelp v0   oberSoXSynthHelp2 v1   paths0 <- listDirectory "."@@ -185,42 +188,51 @@   mapM_ removeFile paths  -- | Function to create a melody for the given arguments. 'String' is used to provide a rhythm. The main component of the sound includes the lower pure quint, which--- can be in the same octave or in the one with the number lower by one.-oberSoXSynthN :: Int -> String -> V.Vector Double -> IO ()-oberSoXSynthN n zs vec0 = V.imapM_ (\j x -> do   -  let note0 = closestNote x                     -- zs is obtained from the command line arguments-      note1 = pureQuintNote note0-      v0    = oberTones note0-      v1    = oberTones note1-      (t, ws) = splitAt 1 . syllableStr n $ zs-      zeroN = numVZeroesPre vec0-      v2    = V.map (\yy -> 0.5 * fromIntegral (yy * n) / fromIntegral (head t)) . V.fromList $ ws-      oberSoXSynthHelpN vec = V.imapM_ (\i (noteN, amplN) -> readProcessWithExitCode (fromJust (showE "sox"))-        ["-r22050", "-n", "test" ++ prependZeroes zeroN (show (i + 2)) ++ ".wav", "synth", show (V.unsafeIndex v2 i),"sine", show noteN, "vol", show amplN] "") vec-      oberSoXSynthHelpN2 vec = V.imapM_ (\i (noteN, amplN) -> readProcessWithExitCode (fromJust (showE "sox"))-        ["-r22050", "-n", "testQ" ++ prependZeroes zeroN (show (i + 2)) ++ ".wav", "synth", show (V.unsafeIndex v2 i),"sine", show noteN, "vol", show amplN] "")   vec  -  _ <- readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "test" ++ prependZeroes zeroN "1" ++  ".wav", "synth", "0.5","sine", show note0, "synth"  , "0.5","sine", "mix", show note1] ""-  oberSoXSynthHelpN v0-  oberSoXSynthHelpN2 v1-  paths0 <- listDirectory "."-  let paths = sort . filter (isPrefixOf "test") $ paths0-  _ <- readProcessWithExitCode (fromJust (showE "sox")) (["--combine", "mix"] ++ paths ++ ["result" ++ prependZeroes zeroN (show j) ++ ".wav","vol","0.3"]) ""-  mapM_ removeFile paths ) vec0+-- can be in the same octave or in the one with the number lower by one. The first 'Double' argument from the range [0.01..1.0] is used as a maximum amplitude+-- for obertones. If it is set to 1.0 the obertones amplitudes are just the maximum ones, otherwise they are multiplied by the parameter and this results+-- in their becoming more silent ones. The second 'Double' argument is a basic sound duration. The default one is 0.5 (second).+oberSoXSynthN :: Int -> Double -> Double -> String -> V.Vector Double -> IO ()+oberSoXSynthN n ampL time3 zs vec0+ | compare ampL 0.01 /= LT && compare ampL 1.0 /= GT =  V.imapM_ (\j x -> do   +    let note0 = closestNote x                     -- zs is obtained from the command line arguments+        note1 = pureQuintNote note0+        v0    = oberTones note0+        v1    = oberTones note1+        (t, ws) = splitAt 1 . syllableStr n $ zs+        zeroN = numVZeroesPre vec0+        v2    = V.map (\yy -> time3 * fromIntegral (yy * n) / fromIntegral (head t)) . V.fromList $ ws+        oberSoXSynthHelpN vec = V.imapM_ (\i (noteN, amplN) -> readProcessWithExitCode (fromJust (showE "sox"))+          ["-r22050", "-n", "test" ++ prependZeroes zeroN (show (i + 2)) ++ ".wav", "synth", showFFloat (Just 4) (V.unsafeIndex v2 i) $ show 0,"sine", showFFloat (Just 4) noteN $ show 0, "vol", showFFloat (Just 4) (amplN * ampL) $ show 0] "") vec+        oberSoXSynthHelpN2 vec = V.imapM_ (\i (noteN, amplN) -> readProcessWithExitCode (fromJust (showE "sox"))+          ["-r22050", "-n", "testQ" ++ prependZeroes zeroN (show (i + 2)) ++ ".wav", "synth", showFFloat (Just 4) (V.unsafeIndex v2 i) $ show 0,"sine", showFFloat (Just 4) noteN $ show 0, "vol", showFFloat (Just 4) (amplN * ampL) $ show 0] "") vec  +    _ <- readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "test" ++ prependZeroes zeroN "1" ++  ".wav", "synth", showFFloat (Just 4) time3 $ show 0,"sine", showFFloat (Just 4) note0 $ show 0, "synth"    , showFFloat (Just 4) time3 $ show 0,"sine", "mix", showFFloat (Just 4) note1 $ show 0] ""+    oberSoXSynthHelpN v0+    oberSoXSynthHelpN2 v1+    paths0 <- listDirectory "."+    let paths = sort . filter (isPrefixOf "test") $ paths0+    _ <- readProcessWithExitCode (fromJust (showE "sox")) (["--combine", "mix"] ++ paths ++ ["result" ++ prependZeroes zeroN (show j) ++ ".wav","vol","0.3"]) ""+    mapM_ removeFile paths ) vec0+ | otherwise = let ampL1 = ampL - (fromIntegral . truncate $ ampL) in+    if ampL1 < 0.01 then oberSoXSynthN n 0.01 time3 zs vec0+    else oberSoXSynthN n ampL1 time3 zs vec0  -- | Similar to 'oberSoXSynthN', but uses a sound file to obtain the information analogous to 'V.Vector' in the latter one. Besides, the function lifts--- the frequencies to the octave with the given by 'Int' parameter number (better to use from the range [1..8]). -oberSoXSynthNGen :: FilePath -> Int -> String -> IO ()-oberSoXSynthNGen file m zs = do+-- the frequencies to the octave with the given by 'Int' parameter number (better to use from the range [1..8]). The first 'Double' argument from+-- the range [0.01..1.0] is used as a maximum amplitude for obertones. If it is set to 1.0 the obertones amplitudes are just maximum ones,+-- otherwise they are multiplied by the parameter and this results in their becoming more silent ones.+-- The second 'Double' argument is a basic sound duration. The default one is 0.5 (second).+oberSoXSynthNGen :: FilePath -> Int -> Double -> Double -> String -> IO ()+oberSoXSynthNGen file m ampL time3 zs = do   duration0 <- durationA file   let n = truncate (duration0 / 0.001)-  vecA <- V.generateM n (\k -> do { (_, _, herr) <- readProcessWithExitCode (fromJust (showE "sox")) [file, "-n", "trim", show (fromIntegral k * 0.001),+  vecA <- V.generateM n (\k -> do { (_, _, herr) <- readProcessWithExitCode (fromJust (showE "sox")) [file, "-n", "trim", showFFloat (Just 4) (fromIntegral k * 0.001) $ show 0,     "0.001", "stat"] ""   ; let line0s = lines herr         noteN1  = takeWhile isDigit . dropWhile (not . isDigit) . concat . drop 13 . take 14 $ line0s   ; if null noteN1 then return (11440::Int)       else let noteN2  = read (takeWhile isDigit . dropWhile (not . isDigit) . concat . drop 13 . take 14 $ line0s)::Int in return noteN2 })   let vecB = putInOctaveV m . V.map fromIntegral . V.filter (/= (11440::Int)) $ vecA-  oberSoXSynthN n zs vecB+  oberSoXSynthN n ampL time3 zs vecB   path2s <- listDirectory "."   let paths3 = sort . filter (isPrefixOf "result") $ path2s   _ <- readProcessWithExitCode (fromJust (showE "sox")) (paths3 ++ ["end.wav"]) ""@@ -256,10 +268,10 @@       v0    = uniqOberTonesV note0 wws       v1    = uniqOberTonesV note1 wws       uniqOberSoXSynthHelp vec = V.imapM_ (\i (noteN, amplN) -> readProcessWithExitCode (fromJust (showE "sox"))-        ["-r22050", "-n", "test0" ++ show (i + 2) ++ ".wav", "synth", "0.5","sine", show noteN, "vol", show amplN] "") vec+        ["-r22050", "-n", "test0" ++ show (i + 2) ++ ".wav", "synth", "0.5","sine", showFFloat (Just 4) noteN $ show 0, "vol", showFFloat (Just 4) amplN $ show 0] "") vec       uniqOberSoXSynthHelp2 vec = V.imapM_ (\i (noteN, amplN) -> readProcessWithExitCode (fromJust (showE "sox"))-        ["-r22050", "-n", "test1" ++ show (i + 2) ++ ".wav", "synth", "0.5","sine", show noteN, "vol", show amplN] "") vec-  _ <- readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "test-.wav", "synth", "0.5","sine", show note0, "synth", "0.5","sine", "mix", show note1] ""+        ["-r22050", "-n", "test1" ++ show (i + 2) ++ ".wav", "synth", "0.5","sine", showFFloat (Just 4) noteN $ show 0, "vol", showFFloat (Just 4) amplN $ show 0] "") vec+  _ <- readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "test-.wav", "synth", "0.5","sine", showFFloat (Just 4) note0 $ show 0, "synth", "0.5","sine", "mix", showFFloat (Just 4) note1 $ show 0] ""   uniqOberSoXSynthHelp v0   uniqOberSoXSynthHelp2 v1   paths0 <- listDirectory "."@@ -269,35 +281,43 @@  -- | Function to create a melody for the given arguments. The first 'String' is used to provide a rhythm. The second one -- to provide a timbre. -- The timbre for another given text usually differs, but can be the same. This gives an opportunity to practically and quickly--- synthesize differently sounding intervals.--- The main component of the sound is in the given octave with a number given+-- synthesize differently sounding intervals. The first 'Double' argument from the range [0.01..1.0] is used as a maximum amplitude for obertones.+-- If it is set to 1.0 the obertones amplitudes are just maximum ones, otherwise they are multiplied by the parameter and this results in+-- their becoming more silent ones. The main component of the sound is in the given octave with a number given -- by 'Int' parameter. Besides, another main component of the sound includes the lower pure quint, which can be in the same octave or in the one with--- the number lower by one.-uniqOberSoXSynthN :: Int -> String -> String -> V.Vector Double -> IO ()-uniqOberSoXSynthN n zs wws vec0 = V.imapM_ (\j x -> do   -  let note0 = closestNote x                         -- zs ? vec0 -- are they related to the one object? No, they are obtained from different sources.-      note1 = pureQuintNote note0-      v0    = uniqOberTonesV note0 wws-      v1    = uniqOberTonesV note1 wws-      (t, ws) = splitAt 1 . syllableStr n $ zs-      zeroN = numVZeroesPre vec0-      v2    = V.map (\yy -> 0.5 * fromIntegral (yy * n) / fromIntegral (head t)) . V.fromList $ ws-      uniqOberSoXSynthHelpN vec = V.imapM_ (\i (noteN, amplN) -> readProcessWithExitCode (fromJust (showE "sox"))-        ["-r22050", "-n", "test" ++ prependZeroes zeroN (show (i + 2)) ++ ".wav", "synth", show (V.unsafeIndex v2 i),"sine", show noteN, "vol", show amplN] "") vec-      uniqOberSoXSynthHelpN2 vec = V.imapM_ (\i (noteN, amplN) -> readProcessWithExitCode (fromJust (showE "sox"))-        ["-r22050", "-n", "testQ" ++ prependZeroes zeroN (show (i + 2)) ++ ".wav", "synth", show (V.unsafeIndex v2 i),"sine", show noteN, "vol", show amplN] "") vec  -  _ <- readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "test" ++ prependZeroes zeroN "1" ++  ".wav", "synth", "0.5","sine", show note0, "synth", "0.5","sine", "mix", show note1] ""-  uniqOberSoXSynthHelpN v0-  uniqOberSoXSynthHelpN2 v1-  paths0 <- listDirectory "."-  let paths = sort . filter (isPrefixOf "test") $ paths0-  _ <- readProcessWithExitCode (fromJust (showE "sox")) (["--combine", "mix"] ++ paths ++ ["result" ++ prependZeroes zeroN (show j) ++ ".wav","vol","0.3"]) ""-  mapM_ removeFile paths ) vec0+-- the number lower by one. The second 'Double' argument is a basic sound duration. The default one is 0.5 (second).+uniqOberSoXSynthN :: Int -> Double -> Double -> String -> String -> V.Vector Double -> IO ()+uniqOberSoXSynthN n ampL time3 zs wws vec0+ | compare ampL 0.01 /= LT && compare ampL 1.0 /= GT = V.imapM_ (\j x -> do   +    let note0 = closestNote x                         -- zs ? vec0 -- are they related to the one object? No, they are obtained from different sources.+        note1 = pureQuintNote note0+        v0    = uniqOberTonesV note0 wws+        v1    = uniqOberTonesV note1 wws+        (t, ws) = splitAt 1 . syllableStr n $ zs+        zeroN = numVZeroesPre vec0+        v2    = V.map (\yy -> time3 * fromIntegral (yy * n) / fromIntegral (head t)) . V.fromList $ ws+        uniqOberSoXSynthHelpN vec = V.imapM_ (\i (noteN, amplN) -> readProcessWithExitCode (fromJust (showE "sox"))+          ["-r22050", "-n", "test" ++ prependZeroes zeroN (show (i + 2)) ++ ".wav", "synth", showFFloat (Just 4) (V.unsafeIndex v2 i) $ show 0,"sine", showFFloat (Just 4) noteN $ show 0, "vol", showFFloat (Just 4) (amplN * ampL) $ show 0] "") vec+        uniqOberSoXSynthHelpN2 vec = V.imapM_ (\i (noteN, amplN) -> readProcessWithExitCode (fromJust (showE "sox"))+          ["-r22050", "-n", "testQ" ++ prependZeroes zeroN (show (i + 2)) ++ ".wav", "synth", showFFloat (Just 4) (V.unsafeIndex v2 i) $ show 0,"sine", showFFloat (Just 4) noteN $ show 0, "vol", showFFloat (Just 4) (amplN * ampL) $ show 0] "") vec  +    _ <- readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "test" ++ prependZeroes zeroN "1" ++  ".wav", "synth", showFFloat (Just 4) time3 $ show 0,"sine", showFFloat (Just 4) note0 $ show 0, "synth",   showFFloat (Just 4) time3 $ show 0,"sine", "mix", showFFloat (Just 4) note1 $ show 0] ""+    uniqOberSoXSynthHelpN v0+    uniqOberSoXSynthHelpN2 v1+    paths0 <- listDirectory "."+    let paths = sort . filter (isPrefixOf "test") $ paths0+    _ <- readProcessWithExitCode (fromJust (showE "sox")) (["--combine", "mix"] ++ paths ++ ["result" ++ prependZeroes zeroN (show j) ++ ".wav","vol","0.3"]) ""+    mapM_ removeFile paths ) vec0+ | otherwise = let ampL1 = ampL - (fromIntegral . truncate $ ampL) in+    if ampL1 < 0.01 then uniqOberSoXSynthN n 0.01 time3 zs wws vec0+    else uniqOberSoXSynthN n ampL1 time3 zs wws vec0  -- | Similar to 'uniqOberSoXSynthN', but uses a sound file to obtain the information analogous to 'V.Vector' in the latter one. --- Besides, the function lifts the frequencies to the octave with the given by 'Int' parameter number (better to use from the range [1..8]). -uniqOberSoXSynthNGen :: FilePath -> Int -> String -> String -> IO ()-uniqOberSoXSynthNGen file m zs wws = do+-- Besides, the function lifts the frequencies to the octave with the given by 'Int' parameter number (better to use from the range [1..8]).+-- The first 'Double' argument from the range [0.01..1.0] is used as a maximum amplitude for obertones. If it is set to 1.0 the+-- obertones amplitudes are just the maximum ones, otherwise they are multiplied by the parameter and this results in their becoming more silent ones.+-- The second 'Double' argument is a basic sound duration. The default one is 0.5 (second).+uniqOberSoXSynthNGen :: FilePath -> Int -> Double -> Double -> String -> String -> IO ()+uniqOberSoXSynthNGen file m ampL time3 zs wws = do   duration0 <- durationA file   let n = truncate (duration0 / 0.001)   vecA <- V.generateM n (\k -> do {@@ -308,7 +328,7 @@     ; if null noteN0 then return (11440::Int)       else let noteN1  = read (takeWhile isDigit . dropWhile (not . isDigit) . concat . drop 13 . take 14 $ line0s)::Int in return noteN1 })   let vecB = putInOctaveV m . V.map fromIntegral . V.filter (/= (11440::Int)) $ vecA-  uniqOberSoXSynthN n zs wws vecB+  uniqOberSoXSynthN n ampL time3 zs wws vecB   path2s <- listDirectory "."   let paths3 = sort . filter (isPrefixOf "result") $ path2s   _ <- readProcessWithExitCode (fromJust (showE "sox")) (paths3 ++ ["end.wav"]) ""@@ -322,13 +342,17 @@       file = concat . drop 1 . take 2 $ args   case arg1 of     "1" -> do-      [_,_,octave] <- mapM (recAndProcess file) [1..3]+      [_,_,octave,ampLS,time2] <- mapM (recAndProcess file) [1..5]       let octave1 = read octave::Int-      oberSoXSynthNGen (file ++ ".wav") octave1 (unwords . drop 2 $ args)+          ampL = read ampLS::Double+          time3 = read time2::Double+      oberSoXSynthNGen (file ++ ".wav") octave1 ampL time3 (unwords . drop 2 $ args)     _ -> do-      [_,_,octave,wws] <- mapM (recAndProcess file) [1..4]+      [_,_,octave,ampLS,time2,wws] <- mapM (recAndProcess file) [1..6]       let octave1 = read octave::Int-      uniqOberSoXSynthNGen (file ++ ".wav") octave1 (unwords . drop 2 $ args) wws+          ampL = read ampLS::Double+          time3 = read time2::Double+      uniqOberSoXSynthNGen (file ++ ".wav") octave1 ampL time3 (unwords . drop 2 $ args) wws  -- | Function records and processes the sound data needed to generate the \"end.wav\" file in the 'dobutokO2' function. recAndProcess :: String -> Int -> IO String@@ -352,36 +376,67 @@   | x == 2 = onException (do           putStr "Please, specify the control parameter for the SoX \"noisered\" effect in the range from 0.0 to 1.0. "      putStrLn "The greater value causes more reduction with possibly removing some important sound data. The default value is 0.5"+     putStrLn "To use the default value, you can simply press Ether."      ctrlN <- getLine-     let noiseP = tail . dropWhile (/= '.') . filter (\t -> isDigit t || t == '.') $ ctrlN-     controlNoiseReduction $ '0':noiseP-     norm "_x.wav"-     if isPrefixOf "nx." file-       then putStr ""-       else renameFile "8_x.wav" (file ++ ".wav")-     removeFile "x.wav"-     removeFile "_x.wav"-     dir <- listDirectory "."-     let paths4 = filter (isPrefixOf "nx.") dir-     mapM_ removeFile paths4-     putStrLn ""-     return "") (do-       putStrLn "The process was not successful may be because of the not valid data. Please, specify the valid data as requested."-       putStrLn "_______________________________________________________________________"-       recAndProcess file 2)+     if null ctrlN then return ""+     else let noiseP = tail . dropWhile (/= '.') . filter (\t -> isDigit t || t == '.') $ ctrlN in do {+          controlNoiseReduction $ '0':noiseP ;+          norm "_x.wav" ;+          if isPrefixOf "nx." file +            then putStr "" +            else renameFile "8_x.wav" (file ++ ".wav") ;+          removeFile "x.wav" ;+          removeFile "_x.wav" ;+          dir <- listDirectory "." ;+          let paths4 = filter (isPrefixOf "nx.") dir in do {+          mapM_ removeFile paths4 ;+          putStrLn "" ;+          return "" } }) (do+            putStrLn "The process was not successful may be because of the not valid data. Please, specify the valid data as requested."+            putStrLn "_______________________________________________________________________"+            recAndProcess file 2)   | x == 3 = onException (do      putStr "Please, specify the octave number, to which you would like all the main components (not taking into account their respective lower pure quints) "      putStrLn "should belong. The number should be better in the range [1..8]"      octave0 <- getChar-     let octave = (read [octave0]::Int) `mod` 9+     let octave = (read [octave0]::Int) `rem` 9      return $ show octave ) (do        putStrLn "The process was not successful may be because of the not valid data. Please, specify the valid data as requested."        putStrLn "_______________________________________________________________________"        recAndProcess file 3)+  | x == 4 = onException (do+     putStr "Please, specify the amplitude for the generated obertones as an Int number in the range [0..99]."+     putStrLn "The default one is 99"+     putStrLn "To use the default value, you can simply press Ether."+     amplOb0 <- getLine+     if null amplOb0 then return "1.0"+     else let amplOb = (read (take 2 . filter isDigit $ amplOb0)::Int) `rem` 100 in+          case amplOb of+            99 -> return "1.0"+            _ -> if compare (amplOb `quot` 9) 1 == LT then return $ "0.0" ++ show (amplOb + 1)+                 else return $ "0." ++ show (amplOb + 1)) (do+               putStrLn "The process was not successful may be because of the not valid data. Please, specify the valid data as requested."+               putStrLn "_______________________________________________________________________"+               recAndProcess file 4)+  | x == 5 = onException (do+     putStr "Please, specify the basic duration for the generated sounds as a Double number in the range [0.1..4.0]."+     putStrLn "The default one is 0.5"+     putStrLn "To use the default value, you can simply press Ether."+     time0 <- getLine+     if null time0 then return "0.5"+     else let time1 = (read (filter (\z -> isDigit z || z == '.') $ time0)::Double) in+          if compare time1 0.1 /= LT && compare time1 4.0 /= GT then return (showFFloat (Just 4) time1 $ show 0)+          else let mantissa = time1 - (fromIntegral . truncate $ time1)+                   ceilP    = truncate time1 `rem` 4 in+               if ceilP == 0 then return ("0." ++ (showFFloat (Just 4) mantissa $ show 0))+               else return $ (showFFloat (Just 4) ceilP $ show 0) ++ "." ++ (showFFloat (Just 4) mantissa $ show 0)) (do+               putStrLn "The process was not successful may be because of the not valid data. Please, specify the valid data as requested."+               putStrLn "_______________________________________________________________________"+               recAndProcess file 5)   | otherwise = onException (do      putStrLn "Please, input the Ukrainian text that will be used to create a special timbre for the notes: "      wws <- getLine      return wws) (do        putStrLn "The process was not successful may be because of the not valid data. Please, specify the valid data as requested."        putStrLn "_______________________________________________________________________"-       recAndProcess file 4)+       recAndProcess file 100)
README.markdown view
@@ -11,11 +11,25 @@  dobutokO2 {1 | 2} {name-of-the-file-to-be-recorded-to-obtain-sound-information-from-without-file-extension} {Ukrainian text} -After its executing (it takes some time) there is a file "end.wav" in the directory.+The first command line argument equals to 1 means that the executable+will use the oberTones funcions, so for the given parameters the obertones+are the same for every call. Otherwise, it uses uniqOberTones functions, which+can have different obertones because of the input additional text. The last one+is used to generate the obertones. In such a case, another text gives the+other obertones.++After the program executing (it takes some time) there is a file "end.wav" in the directory. This is the resulting melody generated.  The program now lifts the frequencies to the octave with the number, which you can specify during its execution.++You can specify some controlling parameters during the program execution. This+leads to different sounding.++You can use the default values (backward compatible with the 0.2.0.0 version)+by simply pressing Enter while being prompted and the informational message+contains the line about the default value.  ** Note: 
dobutokO2.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/  name:                dobutokO2-version:             0.2.0.0+version:             0.3.0.0 synopsis:            A program and a library to create experimental music from a mono audio and a Ukrainian text description:         It can also create a timbre for the notes homepage:            https://hackage.haskell.org/package/dobutokO2