dobutokO2 0.11.2.0 → 0.12.0.0
raw patch · 5 files changed
+172/−32 lines, 5 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ DobutokO.Sound.Executable: dobutokO2H7 :: Bool -> String -> FilePath -> IO ()
Files
- CHANGELOG.md +6/−0
- DobutokO/Sound/Executable.hs +135/−29
- README.markdown +16/−1
- dobutokO2.cabal +2/−2
- text.dat.txt +13/−0
CHANGELOG.md view
@@ -123,3 +123,9 @@ * Eleventh version revised C. Fixed issue with being not compiled because of not properly defined arguments for a function 'o2help' in the DobutokO.Sound.Executable module.++## 0.12.0.0 -- 2020-03-17++* Twelfth version. Added a possibility to produce sound in the dobutokO2 function with only one input provided for the first command line option "7". Made+functions in the DobutokO.Sound.Executable module more modular so this grows a possibility to reuse them. Added new functions for the new functionality. Some+documentation improvements. Added as additional file "text.dat.txt" an example of the configuration for "7" first command line input.
DobutokO/Sound/Executable.hs view
@@ -14,8 +14,10 @@ -- * Basic functions for the executable dobutokO2 , recAndProcess+ , dobutokO2H7 ) where +import qualified Data.List as L (groupBy) import CaseBi (getBFst') import Numeric (showFFloat) import Control.Exception (onException)@@ -41,7 +43,7 @@ args = unwords . drop 2 $ arggs exist2 <- doesFileExist file getBFst' (dobutokO2H exist2 args file, V.fromList . fmap (\(xs, f) -> (xs,f exist2 args file)) $ [("0",o2help),("1",dobutokO2H1),("2",dobutokO2H2),- ("3",dobutokO2H3),("4",dobutokO2H4),("5",dobutokO2H5)]) arg1+ ("3",dobutokO2H3),("4",dobutokO2H4),("5",dobutokO2H5),("7",dobutokO2H7)]) arg1 dobutokO2H1 :: Bool -> String -> FilePath -> IO () dobutokO2H1 exist2 args file = do@@ -99,6 +101,80 @@ uniqOberSoXSynthNGen4 file octave1 ampL time3 dAmpl args wws tts vs {-# INLINE dobutokO2H #-} +isNotSeparatorStr :: String -> Bool+isNotSeparatorStr = null . filter (== '@')++isTextPair :: String -> String -> Bool+isTextPair xs ys = isNotSeparatorStr xs && isNotSeparatorStr ys++-- | Used to obtain one multiline specially formatted textual input and do the full processment for the sound. +-- The function generates obertones using additional String and allows maximum control over the parameters.+-- Besides, all the needed information it obtains from the singular formatted input, which can be ended+-- with a keyboard keys combination that means an end of input (e. g. for Unices, that is probably Ctrl + D).+-- \'@\' are separators for the input parts for their respective parts. For more information about the+-- format of the single input, see:+--+-- 'https://drive.google.com/open?id=10Z_GRZR4TKoL5KXfqPm-t-4humuHN0O4'+--+-- The file is also provided with the package as text.dat.txt. +-- The last two or three inputs (an input just here means a textual input between two \'@\') can be omitted,+-- the program will work also but with less control for the user possible. +-- +dobutokO2H7 :: Bool -> String -> FilePath -> IO ()+dobutokO2H7 True args file = do+ putStrLn "Please, specify a prepared textual input. To end the input press a keyboard keys combination that means an end of the input (e. g. for Unices, possibly Ctrl + D). "+ input <- getContents+ let text0 = lines input+ listTxt = filter (isNotSeparatorStr) . map (unwords . words . unlines) . L.groupBy isTextPair $ text0+ l = length listTxt+ case l of+ 4 -> onException (do+ let [octave0,ampLS0,time20,wws] = listTxt+ octave1 = read (d3H octave0)::Int+ ampL = read (d4H ampLS0)::Double+ time3 = read (d5H time20)::Double+ uniqOberSoXSynthNGen file octave1 ampL time3 args wws) (do+ putStrLn "--------------------------------------------------------------------------------------------------------------------"+ putStrLn ""+ putStrLn "The operation was not successful because of the not valid textual input. Please, specify a valid textual input. "+ dobutokO2H7 True args file)+ 5 -> onException (do+ let [octave0,ampLS0,time20,wws,tts0] = listTxt+ octave1 = read (d3H octave0)::Int+ ampL = read (d4H ampLS0)::Double+ time3 = read (d5H time20)::Double+ uniqOberSoXSynthNGen3 file octave1 ampL time3 args wws (d7H tts0)) (do+ putStrLn "--------------------------------------------------------------------------------------------------------------------"+ putStrLn ""+ putStrLn "The operation was not successful because of the not valid textual input. Please, specify a valid textual input. "+ dobutokO2H7 True args file)+ 7 -> onException (do+ let [octave0,ampLS0,time20,wws,tts0,dAmpl0,vs0] = listTxt+ octave1 = read (d3H octave0)::Int+ ampL = read (d4H ampLS0)::Double+ time3 = read (d5H time20)::Double+ dAmpl = read (d8H dAmpl0)::Double+ uniqOberSoXSynthNGen4 file octave1 ampL time3 dAmpl args wws (d7H tts0) (d9H vs0)) (do+ putStrLn "--------------------------------------------------------------------------------------------------------------------"+ putStrLn ""+ putStrLn "The operation was not successful because of the not valid textual input. Please, specify a valid textual input. "+ dobutokO2H7 True args file)+ _ -> do+ putStrLn "--------------------------------------------------------------------------------------------------------------------"+ putStrLn ""+ putStrLn "The operation was not successful because of the not valid textual input. Please, specify a valid textual input. "+ dobutokO2H7 True args file+dobutokO2H7 _ args file = onException (do+ _ <- processD1+ _ <- processD2 file+ dobutokO2H7 True args file) (do+ putStrLn "--------------------------------------------------------------------------------------------------------------------"+ putStrLn ""+ putStr "The operation was not successful because the file with such a name does not exist or was not created by a program. "+ putStrLn "Please, interrupt a program and start again with a better data. "+ dobutokO2H7 False args file)+{-# INLINE dobutokO2H7 #-}+ -- | Takes textual input from the stdin and prints it as one 'String' to the stdout. o2help :: Bool -> String -> FilePath -> IO () o2help _ _ _ = do@@ -141,7 +217,9 @@ return "") (do dir0 <- listDirectory "." let paths5 = filter (isPrefixOf "nx.") dir0- mapM_ removeFile paths5+ paths6 = filter (== "x.wav") dir0+ paths = paths5 ++ paths6+ mapM_ removeFile paths putStrLn "" putStrLn "The process was not successful may be because of the not valid data. Please, specify the valid data as requested." putStrLn "_______________________________________________________________________"@@ -182,89 +260,117 @@ 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 <- getLine- let octave = (read (take 1 octave0)::Int) `rem` 9- return $ show octave ) (do+ return $ d3H octave0 ) (do putStrLn "The process was not successful may be because of the not valid data. Please, specify the valid data as requested." putStrLn "_______________________________________________________________________" processD3) {-# INLINE processD3 #-} +d3H :: String -> String+d3H xs = show $ (read (take 1 xs)::Int) `rem` 9+{-# INLINE d3H #-}+ processD4 :: IO String processD4 = 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 Enter." 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+ return $ d4H amplOb0) (do putStrLn "The process was not successful may be because of the not valid data. Please, specify the valid data as requested." putStrLn "_______________________________________________________________________" processD4)-{-# INLINE processD4 #-} +{-# INLINE processD4 #-} +d4H :: String -> String+d4H xs+ | null xs = "1.0"+ | otherwise = let amplOb = (read (take 2 . filter isDigit $ xs)::Int) `rem` 100 in+ case amplOb of+ 99 -> "1.0"+ _ -> if compare (amplOb `quot` 9) 1 == LT then "0.0" ++ show (amplOb + 1)+ else "0." ++ show (amplOb + 1)+{-# INLINE d4H #-}+ processD5 :: IO String processD5 = 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 Enter." 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::Int) `rem` 4 in- if ceilP == 0 then return ("0." ++ (showFFloat (Just 4) mantissa $ show 0))- else return $ show ceilP ++ "." ++ (showFFloat (Just 4) mantissa $ show 0)) (do+ return $ d5H time0) (do putStrLn "The process was not successful may be because of the not valid data. Please, specify the valid data as requested." putStrLn "_______________________________________________________________________" processD5) {-# INLINE processD5 #-} +d5H :: String -> String+d5H xs+ | null xs = "0.5"+ | otherwise = let time1 = (read (filter (\z -> isDigit z || z == '.') $ xs)::Double) in+ if compare time1 0.1 /= LT && compare time1 4.0 /= GT then showFFloat (Just 4) time1 $ show 0+ else let mantissa = time1 - (fromIntegral . truncate $ time1)+ ceilP = (truncate time1::Int) `rem` 4 in+ if ceilP == 0 then "0." ++ (showFFloat (Just 4) mantissa $ show 0)+ else show ceilP ++ "." ++ (showFFloat (Just 4) mantissa $ show 0)+{-# INLINE d5H #-}+ processD7 :: IO String processD7 = onException (do putStrLn "Please, input the Ukrainian text that will be used to define signs for the harmonics coefficients to produce a special timbre for the notes: " tts <- getLine- if null tts then return "або"- else return tts) (do+ return $ d7H tts) (do putStrLn "The process was not successful may be because of the not valid data. Please, specify the valid data as requested." putStrLn "_______________________________________________________________________" processD7) {-# INLINE processD7 #-} +d7H :: String -> String+d7H xs+ | null xs = "або"+ | otherwise = xs+{-# INLINE d7H #-}+ processD8 :: IO String processD8 = onException (do putStr "Please, specify in how many times the amplitude for the second lower note (if any) is greater than the amplitude for the main note. " putStrLn "The number is in the range [0.1..2.0]. The default one is 1.0" putStrLn "To use the default value, you can simply press Enter." dAmpl0 <- getLine- if null dAmpl0 then return "1.0"- else let dAmpl1 = (read (filter (\z -> isDigit z || z == '.') $ dAmpl0)::Double) in- if compare dAmpl1 0.1 /= LT && compare dAmpl1 2.0 /= GT then return (showFFloat (Just 4) dAmpl1 $ show 0)- else let mantissa = dAmpl1 - (fromIntegral . truncate $ dAmpl1)- ceilP = (truncate dAmpl1::Int) `rem` 2 in- if ceilP == 0 then return ("0." ++ (showFFloat (Just 4) mantissa $ show 0))- else return $ show ceilP ++ "." ++ (showFFloat (Just 4) mantissa $ show 0)) (do+ return $ d8H dAmpl0) (do putStrLn "The process was not successful may be because of the not valid data. Please, specify the valid data as requested." putStrLn "_______________________________________________________________________" processD8) {-# INLINE processD8 #-} +d8H :: String -> String+d8H xs+ | null xs = "1.0"+ | otherwise = let dAmpl1 = (read (filter (\z -> isDigit z || z == '.') $ xs)::Double) in+ if compare dAmpl1 0.1 /= LT && compare dAmpl1 2.0 /= GT then showFFloat (Just 4) dAmpl1 $ show 0+ else let mantissa = dAmpl1 - (fromIntegral . truncate $ dAmpl1)+ ceilP = (truncate dAmpl1::Int) `rem` 2 in+ if ceilP == 0 then "0." ++ (showFFloat (Just 4) mantissa $ show 0)+ else show ceilP ++ "." ++ (showFFloat (Just 4) mantissa $ show 0)+{-# INLINE d8H #-}+ processD9 :: IO String processD9 = onException (do putStrLn "Please, input the Ukrainian text that will be used to define intervals to be used to produce the lower note for the given main one. " putStrLn "The default one is \"й\". " putStrLn "To use the default value, you can simply press Enter." vs <- getLine- if null vs then return "й"- else return vs) (do+ return $ d9H vs) (do putStrLn "The process was not successful may be because of the not valid data. Please, specify the valid data as requested." putStrLn "_______________________________________________________________________" processD9) {-# INLINE processD9 #-}++d9H :: String -> String+d9H xs+ | null xs = "й"+ | otherwise = xs+{-# INLINE d9H #-} processD :: IO String processD = onException (do
README.markdown view
@@ -13,7 +13,7 @@ For the executable you enter in the terminal: -dobutokO2 { 0 | 1 | 2 | 3 | 4 | 5 | 6 } {fileName} {Ukrainian text}+dobutokO2 { 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 } {fileName} {Ukrainian text} where filename is: the full name of the file to be recorded in the current directory or@@ -54,6 +54,21 @@ for the main note and specify the intervals to be used for every note. + "7" -> the program behaves like for the "5" option, but generates+ obertones using additional String and allows maximum control over+ the parameters. Besides, all the needed information it obtains from+ the singular formatted input, which can be ended with a keyboard keys+ combination that means an end of input (e. g. for Unices, that is+ probably Ctrl + D). '@' are separators for the input parts+ for their respective parts. For more information about the+ format of the single input, see:+ https://drive.google.com/open?id=10Z_GRZR4TKoL5KXfqPm-t-4humuHN0O4+ The file is also provided with the package as text.dat.txt.+ The last two or three inputs (an input just here means+ a textual input between two '@') can be omitted, the+ program will work also but with less control for+ the user possible.+ _ -> the program behaves like for the "5" option, but generates obertones using additional String and allows maximum control over the parameters.
dobutokO2.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/ name: dobutokO2-version: 0.11.2.0+version: 0.12.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@@ -13,7 +13,7 @@ -- copyright: category: Sound build-type: Simple-extra-source-files: CHANGELOG.md, README.markdown+extra-source-files: CHANGELOG.md, README.markdown, text.dat.txt cabal-version: >=1.10 library
+ text.dat.txt view
@@ -0,0 +1,13 @@+5+@+69+@+0.39+@+ Тестовий ввід данних, які будуть використані для створення композиції.+@+ Тестовий ввід данних, які будуть використані для створення композиції.+@+0.67+@+ Тестовий ввід данних, які будуть використані для створення композиції.