dobutokO2 0.5.3.0 → 0.6.0.0
raw patch · 4 files changed
+268/−15 lines, 4 filesdep ~mmsyn7sPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: mmsyn7s
API changes (from Hackage documentation)
+ DobutokO.Sound: oberSoXSynth2 :: Double -> String -> IO ()
+ DobutokO.Sound: oberSoXSynthN2 :: Int -> Double -> Double -> String -> String -> Vector Double -> IO ()
+ DobutokO.Sound: oberSoXSynthNGen2 :: FilePath -> Int -> Double -> Double -> String -> String -> IO ()
+ DobutokO.Sound: oberTones2 :: Double -> String -> Vector (Double, Double)
+ DobutokO.Sound: signsFromString :: Int -> String -> Vector Int
+ DobutokO.Sound: uniqOberSoXSynth2 :: Double -> String -> String -> IO ()
+ DobutokO.Sound: uniqOberSoXSynthN3 :: Int -> Double -> Double -> String -> String -> String -> Vector Double -> IO ()
+ DobutokO.Sound: uniqOberSoXSynthNGen3 :: FilePath -> Int -> Double -> Double -> String -> String -> String -> IO ()
+ DobutokO.Sound: uniqOberTonesV2 :: Double -> String -> String -> Vector (Double, Double)
Files
- CHANGELOG.md +5/−0
- DobutokO/Sound.hs +252/−8
- README.markdown +8/−4
- dobutokO2.cabal +3/−3
CHANGELOG.md view
@@ -42,3 +42,8 @@ * Fifth version revised C. Fixed issue with the noise reduction in the 'recAndProcess' function for the existing at the beginning file (it is not done at all in such a case). ++## 0.6.0.0 -- 2020-03-08++* Sixth version. Added the possibility to use one more String argument (maximum -- the third one) to define different signs for the harmonics coefficients for+the obertones.
DobutokO/Sound.hs view
@@ -17,14 +17,24 @@ , oberTones , oberSoXSynth , oberSoXSynthN+ -- *** For the fixed timbre with different signs for harmonics coefficients+ , oberTones2+ , oberSoXSynth2+ , oberSoXSynthN2 -- *** Uses a file for information , oberSoXSynthNGen+ , oberSoXSynthNGen2 -- ** For the unique for the String structure timbre , uniqOberTonesV , uniqOberSoXSynth , uniqOberSoXSynthN+ -- *** For the unique for the String structure timbre with different signs for harmonics coefficients+ , uniqOberTonesV2+ , uniqOberSoXSynth2+ , uniqOberSoXSynthN3 -- *** Uses a file for information , uniqOberSoXSynthNGen+ , uniqOberSoXSynthNGen3 -- ** Work with octaves , octavesT , octaveUp@@ -38,6 +48,7 @@ , closestNote , pureQuintNote , syllableStr+ , signsFromString , prependZeroes ) where @@ -50,7 +61,7 @@ import qualified Data.Vector as V import System.Process import EndOfExe-import MMSyn7.Syllable+import MMSyn7.Syllable import MMSyn7s import System.Directory import SoXBasics@@ -167,6 +178,42 @@ V.takeWhile (\u -> compare (fst u) (V.unsafeIndex notes 107) /= GT && compare (snd u) 0.001 == GT) . V.unsafeSlice 1 (z2 - 1) . V.zip (V.generate z2 (\i -> note * fromIntegral (i + 1))) $ v2 +-- | Additional function to produce signs from the given 'String' of the Ukrainian text. Ukrainian vowels and voiced consonants gives \"+\" sign (+1), voiceless+-- and sonorous consonants gives \"-\" sign (-1). Voiceless2 gives "0". Other symbols are not taken into account.+signsFromString :: Int -> String -> V.Vector Int+signsFromString n1 ts =+ V.fromList . take n1 . concatMap (fmap (\x ->+ case x of+ Vowel _ -> 1+ Voiced _ -> 1+ VoicedP _ -> 1+ Voiceless _ -> (-1)+ VoicelessP _ -> (-1)+ Sonorous _ -> (-1)+ SonorousP _ -> (-1)+ _ -> 0) . concat . fmap representProlonged) . syllablesUkrP . cycle $ ts++-- | For the given frequency of the note and a Ukrainian text it generates a 'V.Vector' of the tuples, each one of which contains+-- the harmonics' frequency and amplitude. The 'String' is used to produce the signs for harmonics coefficients.+oberTones2 :: Double -> String -> V.Vector (Double, Double)+oberTones2 note ts =+ V.takeWhile (\w -> compare (fst w) (V.unsafeIndex notes 107) /= GT && compare (abs . snd $ w) 0.001 == GT) . V.filter (\(_, t4) -> t4 /= 0.0) .+ V.zip (V.generate 1024 (\i -> note * fromIntegral (i + 2))) $ (V.generate 1024 (\i -> fromIntegral (V.unsafeIndex (signsFromString 1024 ts)+ (i + 1)) / fromIntegral ((i + 1) * (i + 1))))++-- | For the given frequency of the note it generates a 'V.Vector' of the tuples, each one of which contains the harmonics' frequency and amplitude. For every given+-- first 'String' argument structure of the uniqueness (see the documentation for @mmsyn7s@ package and its 'MMSyn7.Syllable' module) it produces the unique timbre.+-- The second 'String' is used to produce the signs for harmonics coefficients.+uniqOberTonesV2 :: Double -> String -> String -> V.Vector (Double, Double)+uniqOberTonesV2 note xs ts = + let ys = uniquenessPeriods xs+ z = sum ys+ v = V.fromList . fmap (\y -> fromIntegral y / fromIntegral z) $ ys+ z2 = V.length v+ v2 = V.generate z2 $ (\i -> (V.unsafeIndex (V.map fromIntegral . signsFromString z2 $ ts) i) * V.unsafeIndex v i / fromIntegral (i + 1)) in+ V.takeWhile (\u -> compare (fst u) (V.unsafeIndex notes 107) /= GT && compare (abs . snd $ u) 0.001 == GT) . V.filter (\(_, t4) -> t4 /= 0.0) .+ V.unsafeSlice 1 (z2 - 1) . V.zip (V.generate z2 (\i -> note * fromIntegral (i + 1))) $ v2+ -- | 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.@@ -188,6 +235,28 @@ _ <- readProcessWithExitCode (fromJust (showE "sox")) (["--combine", "mix"] ++ paths ++ ["result.wav","vol","0.3"]) "" mapM_ removeFile paths +-- | 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.+-- The 'String' argument is used to define signs of the harmonics coefficients for obertones.+oberSoXSynth2 :: Double -> String -> IO ()+oberSoXSynth2 x tts = do+ let note0 = closestNote x+ note1 = pureQuintNote note0+ v0 = oberTones2 note0 tts+ v1 = oberTones2 note1 tts+ oberSoXSynthHelp vec = V.imapM_ (\i (noteN, amplN) -> readProcessWithExitCode (fromJust (showE "sox"))+ ["-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", 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 "."+ let paths = sort . filter (isPrefixOf "test") $ paths0+ _ <- readProcessWithExitCode (fromJust (showE "sox")) (["--combine", "mix"] ++ paths ++ ["result.wav","vol","0.3"]) ""+ 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. 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@@ -224,6 +293,42 @@ if ampL1 < 0.01 then oberSoXSynthN n 0.01 time3 zs vec0 else oberSoXSynthN n ampL1 time3 zs vec0 +-- | 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. 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.+oberSoXSynthN2 :: Int -> Double -> Double -> String -> String -> V.Vector Double -> IO ()+oberSoXSynthN2 n ampL time3 zs tts vec0+ | compare ampL 0.01 /= LT && compare ampL 1.0 /= GT = + let (t, ws) = splitAt 1 . syllableStr n $ zs+ m = length ws+ zeroN = numVZeroesPre vec0+ v2 = V.map (\yy -> time3 * fromIntegral (yy * m) / fromIntegral (head t)) . V.fromList $ ws in V.imapM_ (\j x -> do + let note0 = closestNote x -- zs is obtained from the command line arguments+ note1 = pureQuintNote note0+ v0 = oberTones2 note0 tts+ v1 = oberTones2 note1 tts+ 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 (j `rem` m)) $ 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 (j `rem` m)) $ show 0,+ "sine", showFFloat (Just 4) noteN $ show 0, "vol", showFFloat (Just 4) (amplN * ampL) $ show 0] "") vec + soxSynthHelpMain note01 note02 = readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "testA" ++ prependZeroes zeroN "1" ++ ".wav",+ "synth", showFFloat (Just 4) (V.unsafeIndex v2 (j `rem` m)) $ show 0,"sine", showFFloat (Just 4) note01 $ show 0, "synth", showFFloat (Just 4)+ (V.unsafeIndex v2 (j `rem` m)) $ show 0,"sine", "mix", showFFloat (Just 4) note02 $ show 0] ""+ soxSynthHelpMain note0 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+ | otherwise = let ampL1 = ampL - (fromIntegral . truncate $ ampL) in+ if ampL1 < 0.01 then oberSoXSynthN2 n 0.01 time3 zs tts vec0+ else oberSoXSynthN2 n ampL1 time3 zs tts 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]). 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,@@ -247,7 +352,34 @@ path2s <- listDirectory "." let paths3 = sort . filter (isPrefixOf "result") $ path2s _ <- readProcessWithExitCode (fromJust (showE "sox")) (paths3 ++ ["end.wav"]) ""+ mapM_ removeFile paths3++-- | 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+-- 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). 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.+-- +-- For better usage the 'FilePath' should be a filepath for the .wav file.+-- The second 'String' argument is used to define signs of the harmonics coefficients in the generated sounds.+oberSoXSynthNGen2 :: FilePath -> Int -> Double -> Double -> String -> String -> IO ()+oberSoXSynthNGen2 file m ampL time3 zs tts = do+ duration0 <- durationA file+ let n = truncate (duration0 / 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+ 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 + -- | 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 @@ -267,11 +399,11 @@ then fromJust xx else 0::Int --- | For the given frequency and a Ukrainian text it generates a musical sound with the timbre obtained from the Ukrainian text (see the documentation for @mmsyn7s@--- package). The timbre for another given text usually differs, but can be the same. The last one is only 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+-- | For the given frequency and a Ukrainian text it generates a musical sound with the timbre obtained from the Ukrainian text (see the+-- documentation for @mmsyn7s@ package). The timbre for another given text usually differs, but can be the same. The last one is only+-- 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. uniqOberSoXSynth :: Double -> String -> IO () uniqOberSoXSynth x wws = do@@ -291,6 +423,31 @@ _ <- readProcessWithExitCode (fromJust (showE "sox")) (["--combine", "mix"] ++ paths ++ ["result.wav","vol","0.3"]) "" mapM_ removeFile paths +-- | For the given frequency and a Ukrainian text it generates a musical sound with the timbre obtained from the Ukrainian text (see the+-- documentation for @mmsyn7s@ package). The timbre for another given text usually differs, but can be the same. The last one is only+-- 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.+-- 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+ let note0 = closestNote x+ note1 = pureQuintNote note0+ v0 = uniqOberTonesV2 note0 wws tts+ v1 = uniqOberTonesV2 note1 wws tts+ uniqOberSoXSynthHelp vec = V.imapM_ (\i (noteN, amplN) -> readProcessWithExitCode (fromJust (showE "sox"))+ ["-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", 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 "."+ let paths = sort . filter (isPrefixOf "test") $ paths0+ _ <- readProcessWithExitCode (fromJust (showE "sox")) (["--combine", "mix"] ++ paths ++ ["result.wav","vol","0.3"]) ""+ mapM_ removeFile paths + -- | 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 first 'Double' argument from the range [0.01..1.0] is used as a maximum amplitude for obertones.@@ -330,6 +487,46 @@ if ampL1 < 0.01 then uniqOberSoXSynthN n 0.01 time3 zs wws vec0 else uniqOberSoXSynthN n ampL1 time3 zs wws vec0 +-- | 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 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. 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.+-- 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+ | compare ampL 0.01 /= LT && compare ampL 1.0 /= GT =+ let (t, ws) = splitAt 1 . syllableStr n $ zs+ m = length ws+ zeroN = numVZeroesPre vec0+ v2 = V.map (\yy -> time3 * fromIntegral (yy * m) / fromIntegral (head t)) . V.fromList $ ws in 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 = uniqOberTonesV2 note0 wws tts+ v1 = uniqOberTonesV2 note1 wws tts+ 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 (j `rem` m)) $ 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 (j `rem` m)) $ show 0,+ "sine", showFFloat (Just 4) noteN $ show 0, "vol", showFFloat (Just 4) (amplN * ampL) $ show 0] "") vec + soxSynthHelpMain note01 note02 = readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "testA" +++ prependZeroes zeroN "1" ++ ".wav", "synth", showFFloat (Just 4) (V.unsafeIndex v2 (j `rem` m)) $ show 0,"sine", showFFloat (Just 4) note01 $ show 0,+ "synth", showFFloat (Just 4) (V.unsafeIndex v2 (j `rem` m)) $ show 0,"sine", "mix", showFFloat (Just 4) note02 $ show 0] ""+ soxSynthHelpMain note0 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+ | otherwise = let ampL1 = ampL - (fromIntegral . truncate $ ampL) in+ if ampL1 < 0.01 then uniqOberSoXSynthN3 n 0.01 time3 zs wws tts vec0+ else uniqOberSoXSynthN3 n ampL1 time3 zs wws tts 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]). -- 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@@ -354,8 +551,35 @@ path2s <- listDirectory "." let paths3 = sort . filter (isPrefixOf "result") $ path2s _ <- readProcessWithExitCode (fromJust (showE "sox")) (paths3 ++ ["end.wav"]) ""- mapM_ removeFile paths3 + mapM_ removeFile paths3 +-- | 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]).+-- 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.+--+-- For better usage the 'FilePath' should be a filepath for the .wav file.+-- The third 'String' argument is used to define signs of the harmonics coefficients in the generated sounds.+uniqOberSoXSynthNGen3 :: FilePath -> Int -> Double -> Double -> String -> String -> String -> IO ()+uniqOberSoXSynthNGen3 file m ampL time3 zs wws tts = 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),+ "0.001", "stat"] ""+ ; let line0s = lines herr+ noteN0 = takeWhile isDigit . dropWhile (not . isDigit) . concat . drop 13 . take 14 $ line0s+ ; 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+ 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 + -- | Function that actually makes processing in the @dobutokO2@ executable. 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. dobutokO2 :: IO ()@@ -371,12 +595,24 @@ ampL = read ampLS::Double time3 = read time2::Double oberSoXSynthNGen file octave1 ampL time3 (unwords . drop 2 $ args)- _ -> do+ "2" -> do [_,_,octave,ampLS,time2,wws] <- mapM (recAndProcess file) (if exist2 then [0,2,3,4,5,6] else [1..6]) let octave1 = read octave::Int ampL = read ampLS::Double time3 = read time2::Double uniqOberSoXSynthNGen file octave1 ampL time3 (unwords . drop 2 $ args) wws+ "3" -> do+ [_,_,octave,ampLS,time2,tts] <- mapM (recAndProcess file) (if exist2 then [0,2,3,4,5,7] else [1,2,3,4,5,7])+ let octave1 = read octave::Int+ ampL = read ampLS::Double+ time3 = read time2::Double+ oberSoXSynthNGen2 file octave1 ampL time3 (unwords . drop 2 $ args) tts+ _ -> do+ [_,_,octave,ampLS,time2,wws,tts] <- mapM (recAndProcess file) (if exist2 then [0,2,3,4,5,6,7] else [1..7])+ let octave1 = read octave::Int+ ampL = read ampLS::Double+ time3 = read time2::Double+ uniqOberSoXSynthNGen3 file octave1 ampL time3 (unwords . drop 2 $ args) wws tts -- | Function records and processes the sound data needed to generate the \"end.wav\" file in the 'dobutokO2' function. Please, check before executing -- whether there is no \"x.wav\" file in the current directory, because it can be overwritten.@@ -471,6 +707,14 @@ 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)+ | x == 7 = 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+ putStrLn "The process was not successful may be because of the not valid data. Please, specify the valid data as requested."+ putStrLn "_______________________________________________________________________"+ recAndProcess file 7) | otherwise = onException (do putStrLn "Please, input the Ukrainian text that will be used to create a special timbre for the notes: " wws <- getLine
README.markdown view
@@ -13,19 +13,23 @@ For the executable you enter in the terminal: -dobutokO2 {1 | 2} {fileName} {Ukrainian text}+dobutokO2 {1 | 2 | 3 | 4} {fileName} {Ukrainian text} where filename is: the full name of the file to be recorded in the current directory or the full absolute path to the sound .wav file (or other one format that is supported by your SoX installation) to obtain sound information from. -If the first command line argument equals to "1" then the executable+If the first command line argument equals to "1" or "3" then the executable uses the oberTones funcions, so for the given parameters the obertones-are the same for every call. Otherwise, it uses uniqOberTones functions, which+are the same for every call. The "3" adittionally gives an opportunity+to specify the signs for the harmonics coefficients for obertones by additional+String. Otherwise, it uses uniqOberTones functions, which can have different obertones because of the provided the second, additional, text. The last one is used to generate the obertones. In such a case, another-text gives the other obertones.+text gives the other obertones. If you specify something else, except "1", or "2",+or "3", then the program uses uniqOberTones functions and (similarly to "3" option)+it uses additional String to define signs for the harmonics coefficients for obertones. After the program executing (it takes some time) there is a file "end.wav" in the directory. This is the resulting melody generated.
dobutokO2.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/ name: dobutokO2-version: 0.5.3.0+version: 0.6.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@@ -20,7 +20,7 @@ exposed-modules: Main, DobutokO.Sound -- other-modules: -- other-extensions:- build-depends: base >=4.7 && <4.14, vector >=0.11 && <0.14, process >=1.4 && <1.8, mmsyn3 >=0.1.4 && <1, mmsyn7s >=0.6.4 && <1, directory >=1.2.5 && <1.6, mmsyn7ukr >=0.15.3 && <1+ build-depends: base >=4.7 && <4.14, vector >=0.11 && <0.14, process >=1.4 && <1.8, mmsyn3 >=0.1.4 && <1, mmsyn7s >=0.6.6 && <1, directory >=1.2.5 && <1.6, mmsyn7ukr >=0.15.3 && <1 -- hs-source-dirs: default-language: Haskell2010 @@ -28,6 +28,6 @@ main-is: Main.hs -- other-modules: -- other-extensions:- build-depends: base >=4.7 && <4.14, vector >=0.11 && <0.14, process >=1.4 && <1.8, mmsyn3 >=0.1.4 && <1, mmsyn7s >=0.6.4 && <1, directory >=1.2.5 && <1.6, mmsyn7ukr >=0.15.3 && <1+ build-depends: base >=4.7 && <4.14, vector >=0.11 && <0.14, process >=1.4 && <1.8, mmsyn3 >=0.1.4 && <1, mmsyn7s >=0.6.6 && <1, directory >=1.2.5 && <1.6, mmsyn7ukr >=0.15.3 && <1 -- hs-source-dirs: default-language: Haskell2010