dobutokO2 0.12.0.0 → 0.13.0.0
raw patch · 5 files changed
+251/−67 lines, 5 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ DobutokO.Sound: numVZeroesPre :: Vector a -> Int
Files
- CHANGELOG.md +6/−0
- DobutokO/Sound.hs +146/−35
- DobutokO/Sound/Executable.hs +5/−5
- DobutokO/Sound/Functional.hs +93/−26
- dobutokO2.cabal +1/−1
CHANGELOG.md view
@@ -129,3 +129,9 @@ * 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. ++## 0.13.0.0 -- 2020-03-18++* Thirteenth version. Fixed issues connected with that SoX is by default for some distributions unable to work with a quantity of given files significantly more+than 1000. This led to that the program and functions could not work properly with some big amounts of data or sound data source files of some sizes. Now the+program and library work with them in a much more stable manner using temporary additional files. Some documentation, code and export improvements.
DobutokO/Sound.hs view
@@ -59,9 +59,11 @@ , prependZeroes , intervalsFromString , dNote+ , numVZeroesPre ) where import CaseBi+import System.Exit (ExitCode(ExitSuccess)) import Numeric import Control.Exception (onException) import System.Environment (getArgs)@@ -313,7 +315,7 @@ -- | For the given frequency it generates a musical sound with a timbre. 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. Please, check before executing--- whether there is no \"x.wav\", \"test*\", \"result*\" and \"end.wav\" files in the current directory, because they can be overwritten.+-- whether there is no \"x.wav\", \"test*\", \"result*\" files in the current directory, because they can be overwritten. -- The 'String' argument is used to define signs of the harmonics coefficients for obertones. oberSoXSynth2 :: Double -> String -> IO () oberSoXSynth2 x tts = do@@ -339,7 +341,7 @@ -- 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). Please, check before executing--- whether there is no \"x.wav\", \"test*\", \"result*\" and \"end.wav\" files in the current directory, because they can be overwritten.+-- whether there is no \"x.wav\", \"test*\", \"result*\" files in the current directory, because they can be overwritten. oberSoXSynthN :: Int -> Double -> Double -> String -> V.Vector Double -> IO () oberSoXSynthN n ampL time3 zs vec0 | compare (abs ampL) 0.01 /= LT && compare (abs ampL) 1.0 /= GT = @@ -365,8 +367,21 @@ 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+ _ <- readProcessWithExitCode (fromJust (showE "sox")) (["--combine", "mix"] ++ paths ++ ["result0" ++ prependZeroes zeroN (show j) ++ ".wav","vol","0.3"]) ""+ mapM_ removeFile paths+ if j /= 0 && j `rem` 700 == 0+ then do+ path1s <- listDirectory "."+ let path2s = sort . filter (isPrefixOf "result0") $ path1s+ (code,_,_) <- readProcessWithExitCode (fromJust (showE "sox")) (path2s ++ ["result-" ++ prependZeroes zeroN (show (j `quot` 700)) ++ ".wav"]) ""+ case code of+ ExitSuccess -> mapM_ removeFile path2s+ _ -> do+ exi <- doesFileExist $ "result-" ++ prependZeroes zeroN (show (j `quot` 700)) ++ ".wav"+ if exi then removeFile $ "result-" ++ prependZeroes zeroN (show (j `quot` 700)) ++ ".wav"+ else putStr ""+ else putStr ""+ ) vec0 | otherwise = let ampL1 = ampL - (fromIntegral . truncate $ ampL) in if abs ampL1 < 0.01 then oberSoXSynthN n 0.01 time3 zs vec0 else oberSoXSynthN n ampL1 time3 zs vec0@@ -375,7 +390,7 @@ -- 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). Please, check before executing--- whether there is no \"x.wav\", \"test*\", \"result*\" and \"end.wav\" files in the current directory, because they can be overwritten.+-- whether there is no \"x.wav\", \"test*\", \"result*\" files in the current directory, because they can be overwritten. oberSoXSynthN2 :: Int -> Double -> Double -> String -> String -> V.Vector Double -> IO () oberSoXSynthN2 n ampL time3 zs tts vec0 | compare (abs ampL) 0.01 /= LT && compare (abs ampL) 1.0 /= GT = @@ -401,9 +416,21 @@ 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",+ _ <- readProcessWithExitCode (fromJust (showE "sox")) (["--combine", "mix"] ++ paths ++ ["result0" ++ prependZeroes zeroN (show j) ++ ".wav","vol", "0.3"]) ""- mapM_ removeFile paths ) vec0+ mapM_ removeFile paths+ if j /= 0 && j `rem` 700 == 0+ then do+ path1s <- listDirectory "."+ let path2s = sort . filter (isPrefixOf "result0") $ path1s+ (code,_,_) <- readProcessWithExitCode (fromJust (showE "sox")) (path2s ++ ["result-" ++ prependZeroes zeroN (show (j `quot` 700)) ++ ".wav"]) ""+ case code of+ ExitSuccess -> mapM_ removeFile path2s+ _ -> do+ exi <- doesFileExist $ "result-" ++ prependZeroes zeroN (show (j `quot` 700)) ++ ".wav"+ if exi then removeFile $ "result-" ++ prependZeroes zeroN (show (j `quot` 700)) ++ ".wav"+ else putStr ""+ else putStr "") vec0 | otherwise = let ampL1 = ampL - (fromIntegral . truncate $ ampL) in if abs ampL1 < 0.01 then oberSoXSynthN2 n 0.01 time3 zs tts vec0 else oberSoXSynthN2 n ampL1 time3 zs tts vec0 @@ -412,7 +439,7 @@ -- 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). Please, check before executing--- whether there is no \"x.wav\", \"test*\", \"result*\" and \"end.wav\" files in the current directory, because they can be overwritten.+-- whether there is no \"x.wav\", \"test*\", \"result*\" files in the current directory, because they can be overwritten. -- The third 'String' argument is used to define the intervals for the notes if any. -- The third 'Double' parameter basically is used to define in how many times the volume for the second lower note is less than the volume of -- the main note. If it is rather great, it can signal that the volume for the second note obertones are greater than for the main note obetones.@@ -451,8 +478,20 @@ ; 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+ _ <- readProcessWithExitCode (fromJust (showE "sox")) (["--combine", "mix"] ++ paths ++ ["result0" ++ prependZeroes zeroN (show j) ++ ".wav","vol","0.3"]) ""+ mapM_ removeFile paths+ if j /= 0 && j `rem` 700 == 0+ then do+ path1s <- listDirectory "."+ let path2s = sort . filter (isPrefixOf "result0") $ path1s+ (code,_,_) <- readProcessWithExitCode (fromJust (showE "sox")) (path2s ++ ["result-" ++ prependZeroes zeroN (show (j `quot` 700)) ++ ".wav"]) ""+ case code of+ ExitSuccess -> mapM_ removeFile path2s+ _ -> do+ exi <- doesFileExist $ "result-" ++ prependZeroes zeroN (show (j `quot` 700)) ++ ".wav"+ if exi then removeFile $ "result-" ++ prependZeroes zeroN (show (j `quot` 700)) ++ ".wav"+ else putStr ""+ else putStr "") vec0 | otherwise = let ampL1 = ampL - (fromIntegral . truncate $ ampL) in if abs ampL1 < 0.01 then oberSoXSynthN3 n 0.01 time3 dAmpl zs tts vs vec0 else oberSoXSynthN3 n ampL1 time3 dAmpl zs tts vs vec0@@ -479,8 +518,14 @@ oberSoXSynthN n ampL time3 zs vecB path2s <- listDirectory "." let paths3 = sort . filter (isPrefixOf "result") $ path2s- _ <- readProcessWithExitCode (fromJust (showE "sox")) (paths3 ++ ["end.wav"]) ""- mapM_ removeFile paths3+ (code,_,_) <- readProcessWithExitCode (fromJust (showE "sox")) (paths3 ++ ["end.wav"]) ""+ case code of+ ExitSuccess -> mapM_ removeFile paths3+ _ -> do+ exi <- doesFileExist "end.wav"+ if exi then removeFile "end.wav"+ else putStr "Your final file \"end.wav\" was not created by some reason, but the intermediate files in the respective order are present. " >>+ putStrLn "Use them manually as needed." -- | Similar to 'oberSoXSynthN2', 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]). The first 'Double' argument from@@ -505,8 +550,14 @@ oberSoXSynthN2 n ampL time3 zs tts vecB path2s <- listDirectory "." let paths3 = sort . filter (isPrefixOf "result") $ path2s- _ <- readProcessWithExitCode (fromJust (showE "sox")) (paths3 ++ ["end.wav"]) ""- mapM_ removeFile paths3+ (code,_,_) <- readProcessWithExitCode (fromJust (showE "sox")) (paths3 ++ ["end.wav"]) ""+ case code of+ ExitSuccess -> mapM_ removeFile paths3+ _ -> do+ exi <- doesFileExist "end.wav"+ if exi then removeFile "end.wav"+ else putStr "Your final file \"end.wav\" was not created by some reason, but the intermediate files in the respective order are present. " >>+ putStrLn "Use them manually as needed." -- | Similar to 'oberSoXSynthN2', 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]). The first 'Double' argument from@@ -535,8 +586,14 @@ oberSoXSynthN3 n ampL time3 dAmpl zs tts vs vecB path2s <- listDirectory "." let paths3 = sort . filter (isPrefixOf "result") $ path2s- _ <- readProcessWithExitCode (fromJust (showE "sox")) (paths3 ++ ["end.wav"]) ""- mapM_ removeFile paths3 + (code,_,_) <- readProcessWithExitCode (fromJust (showE "sox")) (paths3 ++ ["end.wav"]) ""+ case code of+ ExitSuccess -> mapM_ removeFile paths3+ _ -> do+ exi <- doesFileExist "end.wav"+ if exi then removeFile "end.wav"+ else putStr "Your final file \"end.wav\" was not created by some reason, but the intermediate files in the respective order are present. " >>+ putStrLn "Use them manually as needed." -- | Additional function to prepend zeroes to the given 'String'. The number of them are just that one to fulfill the length to the given 'Int' parameter. prependZeroes :: Int -> String -> String @@ -551,6 +608,7 @@ | otherwise = Just (truncate (log (fromIntegral x) / log 10) + 1) {-# INLINE nOfZeroesLog #-} +-- | Is a minimal number of decimal places that are just enough to represent a length of the 'V.Vector' given. For an 'V.empty' returns 0. numVZeroesPre :: V.Vector a -> Int numVZeroesPre v = let xx = nOfZeroesLog . V.length $ v in@@ -564,7 +622,7 @@ -- if the uniqueness structure and length are the same for both 'String'. Otherwise, they differs. This gives an opportunity to practically -- and quickly synthesize differently sounding intervals. 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. Please, check before executing --- whether there is no \"x.wav\", \"test*\", \"result*\" and \"end.wav\" files in the current directory, because they can be overwritten.+-- whether there is no \"x.wav\", \"test*\", \"result*\" files in the current directory, because they can be overwritten. uniqOberSoXSynth :: Double -> String -> IO () uniqOberSoXSynth x wws = do let note0 = closestNote x@@ -590,7 +648,7 @@ -- if the uniqueness structure and length are the same for both 'String'. Otherwise, they differs. This gives an opportunity to practically -- and quickly synthesize differently sounding intervals. 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. Please, check before executing --- whether there is no \"x.wav\", \"test*\", \"result*\" and \"end.wav\" files in the current directory, because they can be overwritten.+-- whether there is no \"x.wav\", \"test*\", \"result*\" files in the current directory, because they can be overwritten. -- The second 'String' argument is used to define signs for the harmonics coefficients for obertones. uniqOberSoXSynth2 :: Double -> String -> String -> IO () uniqOberSoXSynth2 x wws tts = do@@ -620,7 +678,7 @@ -- 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. The second 'Double' argument is a basic sound duration. The default one is 0.5 (second). Please, check before executing--- whether there is no \"x.wav\", \"test*\", \"result*\" and \"end.wav\" files in the current directory, because they can be overwritten.+-- whether there is no \"x.wav\", \"test*\", \"result*\" files in the current directory, because they can be overwritten. uniqOberSoXSynthN :: Int -> Double -> Double -> String -> String -> V.Vector Double -> IO () uniqOberSoXSynthN n ampL time3 zs wws vec0 | compare (abs ampL) 0.01 /= LT && compare (abs ampL) 1.0 /= GT =@@ -647,8 +705,20 @@ 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+ _ <- readProcessWithExitCode (fromJust (showE "sox")) (["--combine", "mix"] ++ paths ++ ["result0" ++ prependZeroes zeroN (show j) ++ ".wav","vol","0.3"]) ""+ mapM_ removeFile paths+ if j /= 0 && j `rem` 700 == 0+ then do+ path1s <- listDirectory "."+ let path2s = sort . filter (isPrefixOf "result0") $ path1s+ (code,_,_) <- readProcessWithExitCode (fromJust (showE "sox")) (path2s ++ ["result-" ++ prependZeroes zeroN (show (j `quot` 700)) ++ ".wav"]) ""+ case code of+ ExitSuccess -> mapM_ removeFile path2s+ _ -> do+ exi <- doesFileExist $ "result-" ++ prependZeroes zeroN (show (j `quot` 700)) ++ ".wav"+ if exi then removeFile $ "result-" ++ prependZeroes zeroN (show (j `quot` 700)) ++ ".wav"+ else putStr ""+ else putStr "") vec0 | otherwise = let ampL1 = ampL - (fromIntegral . truncate $ ampL) in if abs ampL1 < 0.01 then uniqOberSoXSynthN n 0.01 time3 zs wws vec0 else uniqOberSoXSynthN n ampL1 time3 zs wws vec0@@ -660,7 +730,7 @@ -- 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. The second 'Double' argument is a basic sound duration. The default one is 0.5 (second). Please, check before executing--- whether there is no \"x.wav\", \"test*\", \"result*\" and \"end.wav\" files in the current directory, because they can be overwritten.+-- whether there is no \"x.wav\", \"test*\", \"result*\" files in the current directory, because they can be overwritten. -- The third 'String' argument is used to define signs of the harmonics coefficients in the generated sounds. uniqOberSoXSynthN3 :: Int -> Double -> Double -> String -> String -> String -> V.Vector Double -> IO () uniqOberSoXSynthN3 n ampL time3 zs wws tts vec0@@ -687,8 +757,20 @@ 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+ _ <- readProcessWithExitCode (fromJust (showE "sox")) (["--combine", "mix"] ++ paths ++ ["result0" ++ prependZeroes zeroN (show j) ++ ".wav","vol","0.3"]) ""+ mapM_ removeFile paths+ if j /= 0 && j `rem` 700 == 0+ then do+ path1s <- listDirectory "."+ let path2s = sort . filter (isPrefixOf "result0") $ path1s+ (code,_,_) <- readProcessWithExitCode (fromJust (showE "sox")) (path2s ++ ["result-" ++ prependZeroes zeroN (show (j `quot` 700)) ++ ".wav"]) ""+ case code of+ ExitSuccess -> mapM_ removeFile path2s+ _ -> do+ exi <- doesFileExist $ "result-" ++ prependZeroes zeroN (show (j `quot` 700)) ++ ".wav"+ if exi then removeFile $ "result-" ++ prependZeroes zeroN (show (j `quot` 700)) ++ ".wav"+ else putStr ""+ else putStr "") vec0 | otherwise = let ampL1 = ampL - (fromIntegral . truncate $ ampL) in if abs ampL1 < 0.01 then uniqOberSoXSynthN3 n 0.01 time3 zs wws tts vec0 else uniqOberSoXSynthN3 n ampL1 time3 zs wws tts vec0 @@ -700,7 +782,7 @@ -- 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. The second 'Double' argument is a basic sound duration. The default one is 0.5 (second). Please, check before executing--- whether there is no \"x.wav\", \"test*\", \"result*\" and \"end.wav\" files in the current directory, because they can be overwritten.+-- whether there is no \"x.wav\", \"test*\", \"result*\" files in the current directory, because they can be overwritten. -- The third 'String' argument is used to define signs of the harmonics coefficients in the generated sounds. -- The fourth 'String' argument is used to define the intervals for the notes if any. -- The third 'Double' parameter basically is used to define in how many times the volume for the second lower note is less than the volume of@@ -741,8 +823,20 @@ ; 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+ _ <- readProcessWithExitCode (fromJust (showE "sox")) (["--combine", "mix"] ++ paths ++ ["result0" ++ prependZeroes zeroN (show j) ++ ".wav","vol","0.3"]) ""+ mapM_ removeFile paths+ if j /= 0 && j `rem` 700 == 0+ then do+ path1s <- listDirectory "."+ let path2s = sort . filter (isPrefixOf "result0") $ path1s+ (code,_,_) <- readProcessWithExitCode (fromJust (showE "sox")) (path2s ++ ["result-" ++ prependZeroes zeroN (show (j `quot` 700)) ++ ".wav"]) ""+ case code of+ ExitSuccess -> mapM_ removeFile path2s+ _ -> do+ exi <- doesFileExist $ "result-" ++ prependZeroes zeroN (show (j `quot` 700)) ++ ".wav"+ if exi then removeFile $ "result-" ++ prependZeroes zeroN (show (j `quot` 700)) ++ ".wav"+ else putStr ""+ else putStr "") vec0 | otherwise = let ampL1 = ampL - (fromIntegral . truncate $ ampL) in if abs ampL1 < 0.01 then uniqOberSoXSynthN4 n 0.01 time3 dAmpl zs wws tts vs vec0 else uniqOberSoXSynthN4 n ampL1 time3 dAmpl zs wws tts vs vec0 @@ -791,8 +885,14 @@ uniqOberSoXSynthN n ampL time3 zs wws vecB path2s <- listDirectory "." let paths3 = sort . filter (isPrefixOf "result") $ path2s- _ <- readProcessWithExitCode (fromJust (showE "sox")) (paths3 ++ ["end.wav"]) ""- mapM_ removeFile paths3+ (code,_,_) <- readProcessWithExitCode (fromJust (showE "sox")) (paths3 ++ ["end.wav"]) ""+ case code of+ ExitSuccess -> mapM_ removeFile paths3+ _ -> do+ exi <- doesFileExist "end.wav"+ if exi then removeFile "end.wav"+ else putStr "Your final file \"end.wav\" was not created by some reason, but the intermediate files in the respective order are present. " >>+ putStrLn "Use them manually as needed." -- | 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]).@@ -818,8 +918,14 @@ uniqOberSoXSynthN3 n ampL time3 zs wws tts vecB path2s <- listDirectory "." let paths3 = sort . filter (isPrefixOf "result") $ path2s- _ <- readProcessWithExitCode (fromJust (showE "sox")) (paths3 ++ ["end.wav"]) ""- mapM_ removeFile paths3+ (code,_,_) <- readProcessWithExitCode (fromJust (showE "sox")) (paths3 ++ ["end.wav"]) ""+ case code of+ ExitSuccess -> mapM_ removeFile paths3+ _ -> do+ exi <- doesFileExist "end.wav"+ if exi then removeFile "end.wav"+ else putStr "Your final file \"end.wav\" was not created by some reason, but the intermediate files in the respective order are present. " >>+ putStrLn "Use them manually as needed." -- | 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]).@@ -833,7 +939,7 @@ -- The fourth 'String' argument is used to define the intervals for the notes if any. -- The third 'Double' parameter basically is used to define in how many times the volume for the second lower note is less than the volume of -- the main note. If it is rather great, it can signal that the volume for the second note obertones are greater than for the main note obetones.--- The last one is experimental feature.+-- The last one is an experimental feature. uniqOberSoXSynthNGen4 :: FilePath -> Int -> Double -> Double -> Double -> String -> String -> String -> String -> IO () uniqOberSoXSynthNGen4 file m ampL time3 dAmpl zs wws tts vs = do duration0 <- durationA file@@ -849,6 +955,11 @@ uniqOberSoXSynthN4 n ampL time3 dAmpl zs wws tts vs vecB path2s <- listDirectory "." let paths3 = sort . filter (isPrefixOf "result") $ path2s- _ <- readProcessWithExitCode (fromJust (showE "sox")) (paths3 ++ ["end.wav"]) ""- mapM_ removeFile paths3 -+ (code,_,_) <- readProcessWithExitCode (fromJust (showE "sox")) (paths3 ++ ["end.wav"]) ""+ case code of+ ExitSuccess -> mapM_ removeFile paths3+ _ -> do+ exi <- doesFileExist "end.wav"+ if exi then removeFile "end.wav"+ else putStr "Your final file \"end.wav\" was not created by some reason, but the intermediate files in the respective order are present. " >>+ putStrLn "Use them manually as needed."
DobutokO/Sound/Executable.hs view
@@ -101,14 +101,14 @@ uniqOberSoXSynthNGen4 file octave1 ampL time3 dAmpl args wws tts vs {-# INLINE dobutokO2H #-} -isNotSeparatorStr :: String -> Bool-isNotSeparatorStr = null . filter (== '@')+isDataStr :: String -> Bool+isDataStr = null . filter (== '@') isTextPair :: String -> String -> Bool-isTextPair xs ys = isNotSeparatorStr xs && isNotSeparatorStr ys+isTextPair xs ys = isDataStr xs && isDataStr 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.+-- 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@@ -125,7 +125,7 @@ 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+ listTxt = filter isDataStr . map (unwords . words . unlines) . L.groupBy isTextPair $ text0 l = length listTxt case l of 4 -> onException (do
DobutokO/Sound/Functional.hs view
@@ -22,6 +22,7 @@ , oberSoXSynth2FDN_Sf3 ) where +import System.Exit (ExitCode( ExitSuccess )) import Numeric import Data.List (isPrefixOf,sort,sortBy,nubBy) import Data.Maybe (isNothing,fromJust)@@ -40,7 +41,7 @@ -- Be aware that the result can be rather unpredictable (the program can even obtain segmentation fault) for not very suitable function. -- But for a lot of functions this works well. -- --- It is recommended to fully compute the \"f\" function before using it in the 'oberSoXSynth2FDN'.+-- It is recommended to fully simplify the computation for \"f\" function before using it in the 'oberSoXSynth2FDN'. oberSoXSynth2FDN :: (Double -> V.Vector (Double, Double)) -> (Double, Double) -> String -> IO () oberSoXSynth2FDN f (x, y) zs | V.null . convertToProperUkrainian $ zs = oberSoXSynth x@@ -57,11 +58,11 @@ else g . fromJust $ note1 ts = showFFloat (Just 4) y $ show 0 oberSoXSynthHelp vec =- let l = V.length vec in V.imapM_ (\i (noteN, amplN) -> readProcessWithExitCode (fromJust (showE "sox"))+ let l = V.length vec in V.imapM_ (\i (noteN, !amplN) -> readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "test0" ++ show (i + 2) ++ ".wav", "synth", ts,"sine", showFFloat (Just 4) noteN $ show 0, "vol", showFFloat (Just 4) (amplN / fromIntegral l) $ show 0] "") vec oberSoXSynthHelp2 vec =- let l = V.length vec in V.imapM_ (\i (noteN, amplN) -> readProcessWithExitCode (fromJust (showE "sox"))+ let l = V.length vec in V.imapM_ (\i (noteN, !amplN) -> readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "test1" ++ show (i + 2) ++ ".wav", "synth", ts,"sine", showFFloat (Just 4) noteN $ show 0, "vol", showFFloat (Just 4) (amplN / fromIntegral l) $ show 0] "") vec _ <- readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "testA.wav", "synth", showFFloat (Just 4) y $ show 0,"sine",@@ -88,7 +89,7 @@ -- Be aware that the result can be rather unpredictable (the program can even obtain segmentation fault) for not very suitable function. -- But for a lot of functions this works well. -- --- It is recommended to fully compute the \"f\" function before using it in the 'oberSoXSynth2FDN_B'.+-- It is recommended to fully simplify the computation for \"f\" function before using it in the 'oberSoXSynth2FDN_B'. oberSoXSynth2FDN_B :: (Double -> V.Vector (Double, Double)) -> (Double, Double, Double) -> String -> IO () oberSoXSynth2FDN_B f (x, y, limB) zs | V.null . convertToProperUkrainian $ zs = oberSoXSynth x@@ -135,7 +136,7 @@ -- Be aware that the result can be rather unpredictable (the program can even obtain segmentation fault) for not very suitable function. -- But for a lot of functions this works well. -- --- It is recommended to fully compute the \"f\" function before using it in the 'oberSoXSynth2FDN_S'.+-- It is recommended to fully simplify the computation for \"f\" function before using it in the 'oberSoXSynth2FDN_S'. oberSoXSynth2FDN_S :: (Double -> V.Vector (Double, Double)) -> (Double, Double) -> String -> IO () oberSoXSynth2FDN_S f (x, y) zs | V.null . convertToProperUkrainian $ zs = oberSoXSynth x@@ -145,15 +146,37 @@ v0 = f note0 v1 = if isNothing note1 then V.empty else f . fromJust $ note1- ts = showFFloat (Just 4) y $ show 0 + ts = showFFloat (Just 4) y $ show 0 oberSoXSynthHelp vec =- let l = V.length vec in V.imapM_ (\i (noteN, !amplN) -> readProcessWithExitCode (fromJust (showE "sox"))- ["-r22050", "-n", "test0" ++ show (i + 2) ++ ".wav", "synth", ts,"sine", showFFloat (Just 4) noteN $ show 0,- "vol", showFFloat (Just 4) (amplN / fromIntegral l) $ show 0] "") vec+ let l = V.length vec+ zeroN = numVZeroesPre vec in V.imapM_ (\i (noteN, !amplN) -> if i /= 0 && i `rem` 250 == 0+ then do+ path1s <- listDirectory "."+ let path2s = sort . filter (isPrefixOf "test0") $ path1s+ (code,_,_) <- readProcessWithExitCode (fromJust (showE "sox")) (["--combine", "mix"] ++ path2s ++ ["test-0" ++ prependZeroes zeroN (show (i `quot` 250)) ++ ".wav"]) ""+ case code of+ ExitSuccess -> mapM_ removeFile path2s+ _ -> do+ exi <- doesFileExist $ "test-0" ++ prependZeroes zeroN (show (i `quot` 250)) ++ ".wav"+ if exi then removeFile $ "test-0" ++ prependZeroes zeroN (show (i `quot` 250)) ++ ".wav"+ else putStr ""+ else readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "test0" ++ show (i + 2) ++ ".wav", "synth", ts,"sine",+ showFFloat (Just 4) noteN $ show 0, "vol", showFFloat (Just 4) (amplN / fromIntegral l) $ show 0] "" >> putStr "") vec oberSoXSynthHelp2 vec =- let l = V.length vec in V.imapM_ (\i (noteN, !amplN) -> readProcessWithExitCode (fromJust (showE "sox"))- ["-r22050", "-n", "test1" ++ show (i + 2) ++ ".wav", "synth", ts,"sine", showFFloat (Just 4) noteN $ show 0,- "vol", showFFloat (Just 4) (amplN / fromIntegral l) $ show 0] "") vec+ let l = V.length vec+ zeroN = numVZeroesPre vec in V.imapM_ (\i (noteN, !amplN) -> if i /= 0 && i `rem` 250 == 0+ then do+ path3s <- listDirectory "."+ let path4s = sort . filter (isPrefixOf "test1") $ path3s+ (code,_,_) <- readProcessWithExitCode (fromJust (showE "sox")) (["--combine", "mix"] ++ path4s ++ ["test-1" ++ prependZeroes zeroN (show (i `quot` 250)) ++ ".wav"]) ""+ case code of+ ExitSuccess -> mapM_ removeFile path4s+ _ -> do+ exi <- doesFileExist $ "test-1" ++ prependZeroes zeroN (show (i `quot` 250)) ++ ".wav"+ if exi then removeFile $ "test-1" ++ prependZeroes zeroN (show (i `quot` 250)) ++ ".wav"+ else putStr ""+ else readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "test1" ++ show (i + 2) ++ ".wav", "synth", ts,"sine",+ showFFloat (Just 4) noteN $ show 0, "vol", showFFloat (Just 4) (amplN / fromIntegral l) $ show 0] "" >> putStr "") vec _ <- readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "testA.wav", "synth", showFFloat (Just 4) y $ show 0,"sine", showFFloat (Just 4) note0 $ show 0] "" if isNothing note1 then do@@ -174,7 +197,7 @@ -- Be aware that the result can be rather unpredictable (the program can even obtain segmentation fault) for not very suitable function. -- But for a lot of functions this works well. -- --- It is recommended to fully compute the \"f\" function before using it in the 'oberSoXSynth2FDN_Sf'.+-- It is recommended to fully simplify the computation for \"f\" function before using it in the 'oberSoXSynth2FDN_Sf'. oberSoXSynth2FDN_Sf :: (Double -> V.Vector (Double, Double)) -> (Double, Double) -> String -> IO () oberSoXSynth2FDN_Sf f (x, y) zs | V.null . convertToProperUkrainian $ zs = oberSoXSynth x@@ -186,13 +209,35 @@ else V.filter (\(_,!z) -> compare z 0.001 == GT) . f . fromJust $ note1 ts = showFFloat (Just 4) y $ show 0 oberSoXSynthHelp vec =- let l = V.length vec in V.imapM_ (\i (noteN, !amplN) -> readProcessWithExitCode (fromJust (showE "sox"))- ["-r22050", "-n", "test0" ++ show (i + 2) ++ ".wav", "synth", ts,"sine", showFFloat (Just 4) noteN $ show 0,- "vol", showFFloat (Just 4) (amplN / fromIntegral l) $ show 0] "") vec+ let l = V.length vec+ zeroN = numVZeroesPre vec in V.imapM_ (\i (noteN, !amplN) -> if i /= 0 && i `rem` 250 == 0+ then do+ path1s <- listDirectory "."+ let path2s = sort . filter (isPrefixOf "test0") $ path1s+ (code,_,_) <- readProcessWithExitCode (fromJust (showE "sox")) (["--combine", "mix"] ++ path2s ++ ["test-0" ++ prependZeroes zeroN (show (i `quot` 250)) ++ ".wav"]) ""+ case code of+ ExitSuccess -> mapM_ removeFile path2s+ _ -> do+ exi <- doesFileExist $ "test-0" ++ prependZeroes zeroN (show (i `quot` 250)) ++ ".wav"+ if exi then removeFile $ "test-0" ++ prependZeroes zeroN (show (i `quot` 250)) ++ ".wav"+ else putStr ""+ else readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "test0" ++ show (i + 2) ++ ".wav", "synth", ts,"sine",+ showFFloat (Just 4) noteN $ show 0, "vol", showFFloat (Just 4) (amplN / fromIntegral l) $ show 0] "" >> putStr "") vec oberSoXSynthHelp2 vec =- let l = V.length vec in V.imapM_ (\i (noteN, !amplN) -> readProcessWithExitCode (fromJust (showE "sox"))- ["-r22050", "-n", "test1" ++ show (i + 2) ++ ".wav", "synth", ts,"sine", showFFloat (Just 4) noteN $ show 0,- "vol", showFFloat (Just 4) (amplN / fromIntegral l) $ show 0] "") vec+ let l = V.length vec+ zeroN = numVZeroesPre vec in V.imapM_ (\i (noteN, !amplN) -> if i /= 0 && i `rem` 250 == 0+ then do+ path3s <- listDirectory "."+ let path4s = sort . filter (isPrefixOf "test1") $ path3s+ (code,_,_) <- readProcessWithExitCode (fromJust (showE "sox")) (["--combine", "mix"] ++ path4s ++ ["test-1" ++ prependZeroes zeroN (show (i `quot` 250)) ++ ".wav"]) ""+ case code of+ ExitSuccess -> mapM_ removeFile path4s+ _ -> do+ exi <- doesFileExist $ "test-1" ++ prependZeroes zeroN (show (i `quot` 250)) ++ ".wav"+ if exi then removeFile $ "test-1" ++ prependZeroes zeroN (show (i `quot` 250)) ++ ".wav"+ else putStr ""+ else readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "test1" ++ show (i + 2) ++ ".wav", "synth", ts,"sine",+ showFFloat (Just 4) noteN $ show 0, "vol", showFFloat (Just 4) (amplN / fromIntegral l) $ show 0] "" >> putStr "") vec _ <- readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "testA.wav", "synth", showFFloat (Just 4) y $ show 0,"sine", showFFloat (Just 4) note0 $ show 0] "" if isNothing note1 then do@@ -213,7 +258,7 @@ -- Be aware that the result can be rather unpredictable (the program can even obtain segmentation fault) for not very suitable function. -- But for a lot of functions this works well. -- --- It is recommended to fully compute the \"f\" function before using it in the 'oberSoXSynth2FDN_Sf3'.+-- It is recommended to fully simplify the computation for \"f\" function before using it in the 'oberSoXSynth2FDN_Sf3'. oberSoXSynth2FDN_Sf3 :: (Double -> V.Vector (Double, Double)) -> (Double, Double, Double) -> String -> IO () oberSoXSynth2FDN_Sf3 f (x, y, t0) zs | V.null . convertToProperUkrainian $ zs = oberSoXSynth x@@ -225,13 +270,35 @@ else V.filter (\(_,!z) -> compare (abs z) t0 == GT) . f . fromJust $ note1 ts = showFFloat (Just 4) y $ show 0 oberSoXSynthHelp vec =- let l = V.length vec in V.imapM_ (\i (noteN, !amplN) -> readProcessWithExitCode (fromJust (showE "sox"))- ["-r22050", "-n", "test0" ++ show (i + 2) ++ ".wav", "synth", ts,"sine", showFFloat (Just 4) noteN $ show 0,- "vol", showFFloat (Just 4) (amplN / fromIntegral l) $ show 0] "") vec+ let l = V.length vec+ zeroN = numVZeroesPre vec in V.imapM_ (\i (noteN, !amplN) -> if i /= 0 && i `rem` 250 == 0+ then do+ path1s <- listDirectory "."+ let path2s = sort . filter (isPrefixOf "test0") $ path1s+ (code,_,_) <- readProcessWithExitCode (fromJust (showE "sox")) (["--combine", "mix"] ++ path2s ++ ["test-0" ++ prependZeroes zeroN (show (i `quot` 250)) ++ ".wav"]) ""+ case code of+ ExitSuccess -> mapM_ removeFile path2s+ _ -> do+ exi <- doesFileExist $ "test-0" ++ prependZeroes zeroN (show (i `quot` 250)) ++ ".wav"+ if exi then removeFile $ "test-0" ++ prependZeroes zeroN (show (i `quot` 250)) ++ ".wav"+ else putStr ""+ else readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "test0" ++ show (i + 2) ++ ".wav", "synth", ts,"sine",+ showFFloat (Just 4) noteN $ show 0, "vol", showFFloat (Just 4) (amplN / fromIntegral l) $ show 0] "" >> putStr "") vec oberSoXSynthHelp2 vec =- let l = V.length vec in V.imapM_ (\i (noteN, !amplN) -> readProcessWithExitCode (fromJust (showE "sox"))- ["-r22050", "-n", "test1" ++ show (i + 2) ++ ".wav", "synth", ts,"sine", showFFloat (Just 4) noteN $ show 0,- "vol", showFFloat (Just 4) (amplN / fromIntegral l) $ show 0] "") vec+ let l = V.length vec+ zeroN = numVZeroesPre vec in V.imapM_ (\i (noteN, !amplN) -> if i /= 0 && i `rem` 250 == 0+ then do+ path3s <- listDirectory "."+ let path4s = sort . filter (isPrefixOf "test1") $ path3s+ (code,_,_) <- readProcessWithExitCode (fromJust (showE "sox")) (["--combine", "mix"] ++ path4s ++ ["test-1" ++ prependZeroes zeroN (show (i `quot` 250)) ++ ".wav"]) ""+ case code of+ ExitSuccess -> mapM_ removeFile path4s+ _ -> do+ exi <- doesFileExist $ "test-1" ++ prependZeroes zeroN (show (i `quot` 250)) ++ ".wav"+ if exi then removeFile $ "test-1" ++ prependZeroes zeroN (show (i `quot` 250)) ++ ".wav"+ else putStr ""+ else readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "test1" ++ show (i + 2) ++ ".wav", "synth", ts,"sine",+ showFFloat (Just 4) noteN $ show 0, "vol", showFFloat (Just 4) (amplN / fromIntegral l) $ show 0] "" >> putStr "") vec _ <- readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "testA.wav", "synth", showFFloat (Just 4) y $ show 0,"sine", showFFloat (Just 4) note0 $ show 0] "" if isNothing note1 then do
dobutokO2.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/ name: dobutokO2-version: 0.12.0.0+version: 0.13.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