dobutokO2 0.35.2.0 → 0.36.0.0
raw patch · 7 files changed
+1024/−207 lines, 7 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- DobutokO.Sound.Functional: soxBasicParams :: String -> [String] -> [String]
+ DobutokO.Sound: overSoXSynthN24G :: Int -> Double -> Durations -> String -> Vector Double -> IO ()
+ DobutokO.Sound: overSoXSynthN24GS :: Int -> Double -> Double -> String -> String -> Vector Double -> IO ()
+ DobutokO.Sound: overSoXSynthN34G :: Int -> Double -> Double -> Durations -> String -> String -> Vector Double -> IO ()
+ DobutokO.Sound: overSoXSynthN34GS :: Int -> Double -> Double -> Double -> String -> String -> String -> Vector Double -> IO ()
+ DobutokO.Sound: overSoXSynthN35G :: Int -> Double -> Double -> Durations -> String -> Intervals -> Vector Double -> IO ()
+ DobutokO.Sound: overSoXSynthN35GS :: Int -> Double -> Double -> Double -> String -> String -> Intervals -> String -> Vector Double -> IO ()
+ DobutokO.Sound: overSoXSynthN4G :: Int -> Double -> Durations -> Vector Double -> IO ()
+ DobutokO.Sound: overSoXSynthN4GS :: Int -> Double -> Double -> String -> Vector Double -> IO ()
+ DobutokO.Sound: overSoXSynthNGen2E4G :: FilePath -> Int -> Int -> Double -> Durations -> String -> IO ()
+ DobutokO.Sound: overSoXSynthNGen2E4GS :: FilePath -> Int -> Int -> Double -> Double -> String -> String -> IO ()
+ DobutokO.Sound: overSoXSynthNGen3E4G :: FilePath -> Int -> Int -> Double -> Double -> Durations -> String -> String -> IO ()
+ DobutokO.Sound: overSoXSynthNGen3E4GS :: FilePath -> Int -> Int -> Double -> Double -> Double -> String -> String -> String -> IO ()
+ DobutokO.Sound: overSoXSynthNGen3E5G :: FilePath -> Int -> Int -> Double -> Double -> Durations -> String -> Intervals -> IO ()
+ DobutokO.Sound: overSoXSynthNGen3E5GS :: FilePath -> Int -> Int -> Double -> Double -> Double -> String -> String -> Intervals -> String -> IO ()
+ DobutokO.Sound: overSoXSynthNGen3E6G :: FilePath -> Int -> Int -> Double -> Double -> Durations -> String -> Intervals -> Strengths -> Double -> IO ()
+ DobutokO.Sound: overSoXSynthNGen3E6GS :: FilePath -> Int -> Int -> Double -> Double -> Durations -> String -> Intervals -> String -> Double -> IO ()
+ DobutokO.Sound: overSoXSynthNGenE4G :: FilePath -> Int -> Int -> Double -> Durations -> IO ()
+ DobutokO.Sound: overSoXSynthNGenE4GS :: FilePath -> Int -> Int -> Double -> Double -> String -> IO ()
+ DobutokO.Sound: uniqOverSoXSynthN34G :: Int -> Double -> Durations -> String -> String -> Vector Double -> IO ()
+ DobutokO.Sound: uniqOverSoXSynthN34GS :: Int -> Double -> Double -> String -> String -> String -> Vector Double -> IO ()
+ DobutokO.Sound: uniqOverSoXSynthN44G :: Int -> Double -> Double -> Durations -> String -> String -> String -> Vector Double -> IO ()
+ DobutokO.Sound: uniqOverSoXSynthN44GS :: Int -> Double -> Double -> Double -> String -> String -> String -> String -> Vector Double -> IO ()
+ DobutokO.Sound: uniqOverSoXSynthN45G :: Int -> Double -> Double -> Durations -> String -> String -> Intervals -> Vector Double -> IO ()
+ DobutokO.Sound: uniqOverSoXSynthN45GS :: Int -> Double -> Double -> Double -> String -> String -> String -> Intervals -> String -> Vector Double -> IO ()
+ DobutokO.Sound: uniqOverSoXSynthN4G :: Int -> Double -> Durations -> String -> Vector Double -> IO ()
+ DobutokO.Sound: uniqOverSoXSynthN4GS :: Int -> Double -> Double -> String -> String -> Vector Double -> IO ()
+ DobutokO.Sound: uniqOverSoXSynthNGen3E4G :: FilePath -> Int -> Int -> Double -> Durations -> String -> String -> IO ()
+ DobutokO.Sound: uniqOverSoXSynthNGen3E4GS :: FilePath -> Int -> Int -> Double -> Double -> String -> String -> String -> IO ()
+ DobutokO.Sound: uniqOverSoXSynthNGen4E4G :: FilePath -> Int -> Int -> Double -> Double -> Durations -> String -> String -> String -> IO ()
+ DobutokO.Sound: uniqOverSoXSynthNGen4E4GS :: FilePath -> Int -> Int -> Double -> Double -> Double -> String -> String -> String -> String -> IO ()
+ DobutokO.Sound: uniqOverSoXSynthNGen4E5G :: FilePath -> Int -> Int -> Double -> Double -> Durations -> String -> String -> Intervals -> IO ()
+ DobutokO.Sound: uniqOverSoXSynthNGen4E5GS :: FilePath -> Int -> Int -> Double -> Double -> Double -> String -> String -> String -> Intervals -> String -> IO ()
+ DobutokO.Sound: uniqOverSoXSynthNGen4E6G :: FilePath -> Int -> Int -> Double -> Double -> Durations -> String -> String -> Intervals -> Strengths -> Double -> IO ()
+ DobutokO.Sound: uniqOverSoXSynthNGen4E6GS :: FilePath -> Int -> Int -> Double -> Double -> Double -> String -> String -> String -> Intervals -> String -> String -> Double -> IO ()
+ DobutokO.Sound: uniqOverSoXSynthNGenE4G :: FilePath -> Int -> Int -> Double -> Durations -> String -> IO ()
+ DobutokO.Sound: uniqOverSoXSynthNGenE4GS :: FilePath -> Int -> Int -> Double -> Double -> String -> String -> IO ()
+ DobutokO.Sound.Functional: apply6G :: Strengths -> String -> String -> IO ()
+ DobutokO.Sound.Functional: apply6G2 :: Strengths -> String -> String -> Double -> IO ()
+ DobutokO.Sound.Functional: apply6GS :: String -> String -> String -> IO ()
+ DobutokO.Sound.Functional: apply6GS2 :: String -> String -> String -> Double -> IO ()
+ DobutokO.Sound.Functional: apply6GSilentFile :: FilePath -> Double -> Double -> IO ()
+ DobutokO.Sound.Functional: apply6Gf :: Double -> FilePath -> IO ()
+ DobutokO.Sound.Functional: defInt :: Intervals
+ DobutokO.Sound.Functional: doublesAveragedA :: Vector Double -> Double -> Vector Double
+ DobutokO.Sound.Functional: doublesAveragedG :: Vector Double -> Double -> Vector Double
+ DobutokO.Sound.Functional: duration1000 :: FilePath -> IO Int
+ DobutokO.Sound.Functional: durationsAver :: Durations -> Double -> Durations
+ DobutokO.Sound.Functional: equalize2Vec :: Vector (Vector a) -> Vector (Vector a)
+ DobutokO.Sound.Functional: intervalsFromStringG :: Intervals -> String -> Intervals
+ DobutokO.Sound.Functional: overSoXSynth2FDN5G :: (Double -> OvertonesO) -> (Double, Double) -> Int -> Intervals -> Vector Double -> String -> IO ()
+ DobutokO.Sound.Functional: overSoXSynth2FDN6G :: (Double -> OvertonesO) -> (Double, Double) -> Int -> Intervals -> Vector Double -> String -> Double -> IO ()
+ DobutokO.Sound.Functional: overSoXSynth2FDN6GS :: (Double -> OvertonesO) -> (Double, Double) -> Int -> Intervals -> String -> Vector Double -> String -> String -> IO ()
+ DobutokO.Sound.Functional: overSoXSynth2FDN_B5G :: (Double -> OvertonesO) -> (Double, Double, Double) -> Int -> Intervals -> Vector Double -> String -> IO ()
+ DobutokO.Sound.Functional: overSoXSynth2FDN_B6G :: (Double -> OvertonesO) -> (Double, Double, Double) -> Int -> Intervals -> Vector Double -> String -> Double -> IO ()
+ DobutokO.Sound.Functional: overSoXSynth2FDN_B6GS :: (Double -> OvertonesO) -> (Double, Double, Double) -> Int -> Intervals -> String -> Vector Double -> String -> String -> IO ()
+ DobutokO.Sound.Functional: overSoXSynth2FDN_S5G :: (Double -> OvertonesO) -> (Double, Double) -> Int -> Intervals -> Vector Double -> String -> IO ()
+ DobutokO.Sound.Functional: overSoXSynth2FDN_S6G :: (Double -> OvertonesO) -> (Double, Double) -> Int -> Intervals -> Vector Double -> String -> Double -> IO ()
+ DobutokO.Sound.Functional: overSoXSynth2FDN_S6GS :: (Double -> OvertonesO) -> (Double, Double) -> Int -> Intervals -> String -> Vector Double -> String -> String -> IO ()
+ DobutokO.Sound.Functional: overSoXSynth2FDN_Sf35G :: (Double -> OvertonesO) -> (Double, Double, Double) -> Int -> Intervals -> Vector Double -> String -> IO ()
+ DobutokO.Sound.Functional: overSoXSynth2FDN_Sf36G :: (Double -> OvertonesO) -> (Double, Double, Double) -> Int -> Intervals -> Vector Double -> String -> Double -> IO ()
+ DobutokO.Sound.Functional: overSoXSynth2FDN_Sf36GS :: (Double -> OvertonesO) -> (Double, Double, Double) -> Int -> Intervals -> String -> Vector Double -> String -> String -> IO ()
+ DobutokO.Sound.Functional: overSoXSynthGen2FDN4G :: FilePath -> Int -> Int -> (Double -> OvertonesO) -> Double -> Durations -> String -> IO ()
+ DobutokO.Sound.Functional: overSoXSynthGen2FDN_SG4GS :: FilePath -> Int -> Int -> (Double -> OvertonesO) -> Double -> String -> String -> ((Double -> OvertonesO) -> (Double, Double) -> Int -> String -> IO ()) -> IO ()
+ DobutokO.Sound.Functional: overSoXSynthGen2FDN_SG6G :: FilePath -> Int -> Int -> (Double -> OvertonesO) -> Double -> Durations -> String -> ((Double -> OvertonesO) -> (Double, Double) -> Int -> String -> IO ()) -> Strengths -> Double -> IO ()
+ DobutokO.Sound.Functional: overSoXSynthGen2FDN_SG6GS :: FilePath -> Int -> Int -> (Double -> OvertonesO) -> Double -> String -> String -> ((Double -> OvertonesO) -> (Double, Double) -> Int -> String -> IO ()) -> String -> Double -> IO ()
+ DobutokO.Sound.Functional: silentSound2G :: FilePath -> Double -> String -> IO ()
+ DobutokO.Sound.Functional: str2Durat1 :: String -> Double
+ DobutokO.Sound.Functional: str2Durations :: String -> Double -> Durations
+ DobutokO.Sound.Functional: str2DurationsDef :: Int -> String -> Double -> Durations
+ DobutokO.Sound.Functional: str2Vol1 :: String -> Double
+ DobutokO.Sound.Functional: str2Volume :: String -> Strengths
+ DobutokO.Sound.Functional: strToIntG :: Intervals -> String -> Int
+ DobutokO.Sound.Functional: strengthsAver :: Strengths -> Double -> Strengths
+ DobutokO.Sound.Functional: strengthsDbAver :: StrengthsDb -> Double -> StrengthsDb
+ DobutokO.Sound.Functional: type Durations = Vector Double
+ DobutokO.Sound.Functional: type Intervals = Vector Int
+ DobutokO.Sound.Functional: type Strengths = Vector Double
+ DobutokO.Sound.Functional: type StrengthsDb = Vector Double
+ DobutokO.Sound.Functional: vStrToVIntG :: Intervals -> Vector String -> Intervals
+ DobutokO.Sound.IntermediateF: soxBasicParams :: String -> [String] -> [String]
- DobutokO.Sound.Functional: intervalsFromString :: String -> Vector Int
+ DobutokO.Sound.Functional: intervalsFromString :: String -> Intervals
- DobutokO.Sound.Functional: soundGenF3 :: Vector (Double -> Double) -> Vector Double -> Vector Int -> (Double -> OvertonesO) -> (Double, Double, Double) -> Int -> String -> IO ()
+ DobutokO.Sound.Functional: soundGenF3 :: Vector (Double -> Double) -> Vector Double -> Vector Int -> (Double -> OvertonesO) -> (Double, Double, Double) -> Int -> IO ()
- DobutokO.Sound.Functional: soundGenF31G :: Vector (Double -> Double) -> Vector Double -> Vector Int -> (Double -> OvertonesO) -> (Double, Double, Double) -> Int -> String -> Vector Double -> IO ()
+ DobutokO.Sound.Functional: soundGenF31G :: Vector (Double -> Double) -> Vector Double -> Vector Int -> (Double -> OvertonesO) -> (Double, Double, Double) -> Int -> Vector Double -> IO ()
- DobutokO.Sound.Functional: soundGenF32G :: Vector (Double -> Double) -> Vector Double -> Vector Int -> (Double -> OvertonesO) -> (Double, Double, Double) -> Int -> String -> Vector Double -> String -> IO ()
+ DobutokO.Sound.Functional: soundGenF32G :: Vector (Double -> Double) -> Vector Double -> Vector Int -> (Double -> OvertonesO) -> (Double, Double, Double) -> Int -> Vector Double -> String -> IO ()
- DobutokO.Sound.Functional: vStrToVInt :: Vector String -> Vector Int
+ DobutokO.Sound.Functional: vStrToVInt :: Vector String -> Intervals
Files
- CHANGELOG.md +8/−0
- DobutokO/Sound.hs +452/−105
- DobutokO/Sound/Executable.hs +6/−16
- DobutokO/Sound/Functional.hs +538/−84
- DobutokO/Sound/IntermediateF.hs +14/−1
- README.markdown +5/−0
- dobutokO2.cabal +1/−1
CHANGELOG.md view
@@ -314,3 +314,11 @@ ## 0.35.2.0 -- 2020-04-22 * Thirty-fifth version revised B. Fixed issues with some other wrongly defined parameters for the new MN functions.++## 0.36.0.0 -- 2020-04-25++* Thirty-sixth version. Changed the structure of imported modules: now DobutokO.Sound.Functional imports DobutokO.Sound.IntermediateF and not vice versa +as has been earlier. Added new 4G functions and rewritten a lot of previous ones so that now they support generation not only the sounds but also pauses +and you can specify your own durations. Added new type synonyms and functions to work with them. Added new 5G functions to work with Intervals +and 6G functions to work with Strengths (vulume levels). Some documentation and code improvements.+
DobutokO/Sound.hs view
@@ -69,6 +69,48 @@ , uniqOverSoXSynthNGen4E -- * Auxiliary functions , signsFromString+ -- * New 4G functions to work with Durations+ , overSoXSynthN4G+ , overSoXSynthN24G+ , overSoXSynthN34G+ , overSoXSynthNGenE4G+ , overSoXSynthNGen2E4G+ , overSoXSynthNGen3E4G+ , uniqOverSoXSynthN4G+ , uniqOverSoXSynthN34G+ , uniqOverSoXSynthN44G+ , uniqOverSoXSynthNGenE4G+ , uniqOverSoXSynthNGen3E4G+ , uniqOverSoXSynthNGen4E4G+ -- ** 4G with speech-like composition+ , overSoXSynthN4GS+ , overSoXSynthN24GS+ , overSoXSynthN34GS+ , overSoXSynthNGenE4GS+ , overSoXSynthNGen2E4GS+ , overSoXSynthNGen3E4GS+ , uniqOverSoXSynthN4GS+ , uniqOverSoXSynthN34GS+ , uniqOverSoXSynthN44GS+ , uniqOverSoXSynthNGenE4GS+ , uniqOverSoXSynthNGen3E4GS+ , uniqOverSoXSynthNGen4E4GS+ -- * New 5G functions to work also with Intervals+ , overSoXSynthN35G+ , overSoXSynthNGen3E5G+ , uniqOverSoXSynthN45G+ , uniqOverSoXSynthNGen4E5G+ -- ** 5G with obtained from the text arbitraty length Intervals+ , overSoXSynthN35GS+ , overSoXSynthNGen3E5GS+ , uniqOverSoXSynthN45GS+ , uniqOverSoXSynthNGen4E5GS+ -- * New 6G function to work also with Strengths+ , overSoXSynthNGen3E6G+ , uniqOverSoXSynthNGen4E6G+ -- ** 6G with obtained from the text arbitrary length Strengths+ , overSoXSynthNGen3E6GS+ , uniqOverSoXSynthNGen4E6GS ) where import CaseBi (getBFst')@@ -230,7 +272,7 @@ -- | Similar to 'overSoXSynth' except that takes not necessarily pure lower quint note as the second one, but the one specified by the 'String' parameter -- as an argument to 'dNote'. If you begin the 'String' with space characters, or \"сь\", or \"ць\", or dash, or apostrophe, or soft sign, than there will--- be no interval and the sound will be solely one with its Overtones.+-- be no interval and the sound will be solely one with its 'OvertonesO'. overSoXSynthDN :: Double -> String -> IO () overSoXSynthDN x = overSoXSynth2DN x 0.5 @@ -288,66 +330,82 @@ -- 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*\" files in the current directory, because they can be overwritten. overSoXSynthN :: Int -> Double -> Double -> String -> V.Vector Double -> IO ()-overSoXSynthN n ampL time3 zs vec0+overSoXSynthN n ampL time3 zs = overSoXSynthN4G n ampL (str2DurationsDef n zs time3)++-- | Function to create a melody for the given arguments. 'Durations' is used to provide a rhythm. +overSoXSynthN4G :: Int -> Double -> Durations -> V.Vector Double -> IO ()+overSoXSynthN4G n ampL v2 vec0 | compare (abs ampL) 0.01 /= LT && compare (abs 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 zeroN = numVZeroesPre vec0+ m = V.length v2 in V.imapM_ (\j x -> do let note0 = closestNote x -- zs is obtained from the command line arguments note1 = pureQuintNote note0 v0 = overTones note0 v1 = overTones note1 overSoXSynthHelpN 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)) "",- "sine", showFFloat (Just 4) noteN "", "vol", showFFloat (Just 4) (amplN * ampL) ""] "") vec+ "sine", showFFloat (Just 4) noteN "", "vol", if compare (V.unsafeIndex v2 (j `rem` m)) 0.0 == GT then showFFloat (Just 4) (amplN * ampL) "" else "0"] "") vec overSoXSynthHelpN2 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)) "",- "sine", showFFloat (Just 4) noteN "", "vol", showFFloat (Just 4) (amplN * ampL) ""] "") vec + "sine", showFFloat (Just 4) noteN "", "vol", if compare (V.unsafeIndex v2 (j `rem` m)) 0.0 == GT then showFFloat (Just 4) (amplN * ampL) "" else "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)) "","sine", showFFloat (Just 4) note01 "", "synth",- showFFloat (Just 4) (V.unsafeIndex v2 (j `rem` m)) "","sine", "mix", showFFloat (Just 4) note02 "", "vol","0.5"] ""+ showFFloat (Just 4) (V.unsafeIndex v2 (j `rem` m)) "","sine", "mix", showFFloat (Just 4) note02 "", "vol",if compare (V.unsafeIndex v2 (j `rem` m)) 0.0 == GT + then "0.5" else "0"] "" soxSynthHelpMain note0 note1 overSoXSynthHelpN v0 overSoXSynthHelpN2 v1 mixTest2 zeroN j) vec0 | otherwise = let ampL1 = ampL - (fromIntegral . truncate $ ampL) in- if abs ampL1 < 0.01 then overSoXSynthN n 0.01 time3 zs vec0- else overSoXSynthN n ampL1 time3 zs vec0+ if abs ampL1 < 0.01 then overSoXSynthN4G n 0.01 v2 vec0+ else overSoXSynthN4G n ampL1 v2 vec0 +-- | Variant of the 'overSoXSynthN4G' where 'Durations' are obtained from the 'String' using 'str2Durations' function. Helps to create a speech-like +-- composition.+overSoXSynthN4GS :: Int -> Double -> Double -> String -> V.Vector Double -> IO ()+overSoXSynthN4GS n ampL time3 zs = overSoXSynthN4G n ampL (str2Durations zs time3)+ -- | 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 Overtones. If it is set to 1.0 the overTones 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*\" files in the current directory, because they can be overwritten. overSoXSynthN2 :: Int -> Double -> Double -> String -> String -> V.Vector Double -> IO ()-overSoXSynthN2 n ampL time3 zs tts vec0+overSoXSynthN2 n ampL time3 zs = overSoXSynthN24G n ampL (str2DurationsDef n zs time3)+ +-- | Function to create a melody for the given arguments. 'Durations' is used to provide a rhythm. +overSoXSynthN24G :: Int -> Double -> Durations -> String -> V.Vector Double -> IO ()+overSoXSynthN24G n ampL v2 tts vec0 | compare (abs ampL) 0.01 /= LT && compare (abs 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 zeroN = numVZeroesPre vec0+ m = V.length v2 in V.imapM_ (\j x -> do let note0 = closestNote x -- zs is obtained from the command line arguments note1 = pureQuintNote note0 v0 = overTones2 note0 tts v1 = overTones2 note1 tts overSoXSynthHelpN 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)) "",- "sine",showFFloat (Just 4) noteN "", "vol", showFFloat (Just 4) (amplN * ampL) ""] "") vec+ "sine",showFFloat (Just 4) noteN "", "vol", if compare (V.unsafeIndex v2 (j `rem` m)) 0.0 == GT then showFFloat (Just 4) (amplN * ampL) "" else "0"] "") vec overSoXSynthHelpN2 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)) "",- "sine", showFFloat (Just 4) noteN "", "vol", showFFloat (Just 4) (amplN * ampL) ""] "") vec + "sine", showFFloat (Just 4) noteN "", "vol", if compare (V.unsafeIndex v2 (j `rem` m)) 0.0 == GT then showFFloat (Just 4) (amplN * ampL) "" else "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)) "","sine", showFFloat (Just 4) note01 "",- "synth", showFFloat (Just 4) (V.unsafeIndex v2 (j `rem` m)) "","sine", "mix", showFFloat (Just 4) note02 "", "vol","0.5"] ""+ "synth", showFFloat (Just 4) (V.unsafeIndex v2 (j `rem` m)) "","sine", "mix", showFFloat (Just 4) note02 "", "vol",+ if compare (V.unsafeIndex v2 (j `rem` m)) 0.0 == GT then "0.5" else "0"] "" soxSynthHelpMain note0 note1 overSoXSynthHelpN v0 overSoXSynthHelpN2 v1 mixTest2 zeroN j) vec0 | otherwise = let ampL1 = ampL - (fromIntegral . truncate $ ampL) in- if abs ampL1 < 0.01 then overSoXSynthN2 n 0.01 time3 zs tts vec0- else overSoXSynthN2 n ampL1 time3 zs tts vec0 + if abs ampL1 < 0.01 then overSoXSynthN24G n 0.01 v2 tts vec0+ else overSoXSynthN24G n ampL1 v2 tts vec0 +-- | Variant of the 'overSoXSynthN24G' where 'Durations' are obtained from the 'String' using 'str2Durations' function. Helps to create a speech-like +-- composition.+overSoXSynthN24GS :: Int -> Double -> Double -> String -> String -> V.Vector Double -> IO ()+overSoXSynthN24GS n ampL time3 zs = overSoXSynthN24G n ampL (str2Durations zs time3)+ -- | 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 Overtones. If it is set to 1.0 the overTones amplitudes are just the maximum ones, otherwise they are multiplied by the parameter and this results@@ -358,14 +416,16 @@ -- the main note. If it is rather great, it can signal that the volume for the second note overTones are greater than for the main note obetones. -- The last one is experimental feature. overSoXSynthN3 :: Int -> Double -> Double -> Double -> String -> String -> String -> V.Vector Double -> IO ()-overSoXSynthN3 n ampL time3 dAmpl zs tts vs vec0+overSoXSynthN3 n ampL time3 dAmpl zs = overSoXSynthN34G n ampL dAmpl (str2DurationsDef n zs time3)++-- | Function to create a melody for the given arguments. 'Duraitons' is used to provide a rhythm. +overSoXSynthN34G :: Int -> Double -> Double -> Durations -> String -> String -> V.Vector Double -> IO ()+overSoXSynthN34G n ampL dAmpl v2 tts vs vec0 | compare (abs ampL) 0.01 /= LT && compare (abs ampL) 1.0 /= GT = - let (t, ws) = splitAt 1 . syllableStr n $ zs- m = length ws+ let m = length v2 zeroN = numVZeroesPre vec0 v3 = intervalsFromString vs- l = length vs- v2 = V.map (\yy -> time3 * fromIntegral (yy * m) / fromIntegral (head t)) . V.fromList $ ws in V.imapM_ (\j x -> do + l = length vs in V.imapM_ (\j x -> do let note0 = closestNote x -- zs is obtained from the command line arguments note1 = dNote (V.unsafeIndex v3 (j `rem` l)) note0 v0 = overTones2 note0 tts@@ -373,16 +433,17 @@ else overTones2 (fromJust note1) tts overSoXSynthHelpN 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)) "",- "sine",showFFloat (Just 4) noteN "", "vol", showFFloat (Just 4) (amplN * ampL) ""] "") vec+ "sine",showFFloat (Just 4) noteN "", "vol", if compare (V.unsafeIndex v2 (j `rem` m)) 0.0 == GT then showFFloat (Just 4) (amplN * ampL) "" else "0"] "") vec overSoXSynthHelpN2 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)) "",- "sine", showFFloat (Just 4) noteN "", "vol", showFFloat (Just 4) (if dAmpl * amplN * ampL > 1.0 then 1.0- else dAmpl * amplN * ampL) ""] "") vec + "sine", showFFloat (Just 4) noteN "", "vol", if compare (V.unsafeIndex v2 (j `rem` m)) 0.0 == GT then showFFloat (Just 4) (if dAmpl * amplN * ampL > 1.0 then 1.0+ else dAmpl * amplN * ampL) "" else "0"] "") vec soxSynthHelpMain0 note01 = readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "testA" ++ prependZeroes zeroN "1" ++ ".wav",- "synth", showFFloat (Just 4) (V.unsafeIndex v2 (j `rem` m)) "","sine", showFFloat (Just 4) note01 "", "vol","0.5"] ""+ "synth", showFFloat (Just 4) (V.unsafeIndex v2 (j `rem` m)) "","sine", showFFloat (Just 4) note01 "", "vol",+ if compare (V.unsafeIndex v2 (j `rem` m)) 0.0 == GT then "0.5" else "0"] "" soxSynthHelpMain1 note02 = readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "testB" ++ prependZeroes zeroN "1" ++ ".wav", "synth", showFFloat (Just 4) (V.unsafeIndex v2 (j `rem` m)) "","sine", showFFloat (Just 4) note02 "",- "vol", showFFloat (Just 4) (if dAmpl > 0.5 then 0.5 else dAmpl / 2) ""] ""+ "vol", if compare (V.unsafeIndex v2 (j `rem` m)) 0.0 == GT then showFFloat (Just 4) (if dAmpl > 0.5 then 0.5 else dAmpl / 2) "" else "0"] "" if isNothing note1 then do { soxSynthHelpMain0 note0 ; overSoXSynthHelpN v0 } else do { soxSynthHelpMain0 note0@@ -394,9 +455,59 @@ _ <- readProcessWithExitCode (fromJust (showE "sox")) (["--combine", "mix"] ++ paths ++ ["result0" ++ prependZeroes zeroN (show j) ++ ".wav","vol","0.3"]) "" mapM_ removeFile paths) vec0 | otherwise = let ampL1 = ampL - (fromIntegral . truncate $ ampL) in- if abs ampL1 < 0.01 then overSoXSynthN3 n 0.01 time3 dAmpl zs tts vs vec0- else overSoXSynthN3 n ampL1 time3 dAmpl zs tts vs vec0+ if abs ampL1 < 0.01 then overSoXSynthN34G n 0.01 dAmpl v2 tts vs vec0+ else overSoXSynthN34G n ampL1 dAmpl v2 tts vs vec0 +-- | Generalized variant of the 'overSoXSynthN34G' where you specify your own 'Intervals'. For more information, please, refer to 'intervalsFromStringG'.+overSoXSynthN35G :: Int -> Double -> Double -> Durations -> String -> Intervals -> V.Vector Double -> IO ()+overSoXSynthN35G n ampL dAmpl v2 tts v3 vec0+ | compare (abs ampL) 0.01 /= LT && compare (abs ampL) 1.0 /= GT = + let m = length v2+ zeroN = numVZeroesPre vec0+ l = length v3 in V.imapM_ (\j x -> do + let note0 = closestNote x -- zs is obtained from the command line arguments+ note1 = dNote (V.unsafeIndex v3 (j `rem` l)) note0+ v0 = overTones2 note0 tts+ v1 = if isNothing note1 then V.empty+ else overTones2 (fromJust note1) tts+ overSoXSynthHelpN 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)) "",+ "sine",showFFloat (Just 4) noteN "", "vol", if compare (V.unsafeIndex v2 (j `rem` m)) 0.0 == GT then showFFloat (Just 4) (amplN * ampL) "" else "0"] "") vec+ overSoXSynthHelpN2 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)) "",+ "sine", showFFloat (Just 4) noteN "", "vol", if compare (V.unsafeIndex v2 (j `rem` m)) 0.0 == GT then showFFloat (Just 4) (if dAmpl * amplN * ampL > 1.0 then 1.0+ else dAmpl * amplN * ampL) "" else "0"] "") vec + soxSynthHelpMain0 note01 = readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "testA" ++ prependZeroes zeroN "1" ++ ".wav",+ "synth", showFFloat (Just 4) (V.unsafeIndex v2 (j `rem` m)) "","sine", showFFloat (Just 4) note01 "", "vol",+ if compare (V.unsafeIndex v2 (j `rem` m)) 0.0 == GT then "0.5" else "0"] ""+ soxSynthHelpMain1 note02 = readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "testB" +++ prependZeroes zeroN "1" ++ ".wav", "synth", showFFloat (Just 4) (V.unsafeIndex v2 (j `rem` m)) "","sine", showFFloat (Just 4) note02 "",+ "vol", if compare (V.unsafeIndex v2 (j `rem` m)) 0.0 == GT then showFFloat (Just 4) (if dAmpl > 0.5 then 0.5 else dAmpl / 2) "" else "0"] ""+ if isNothing note1 then do { soxSynthHelpMain0 note0+ ; overSoXSynthHelpN v0 }+ else do { soxSynthHelpMain0 note0+ ; soxSynthHelpMain1 (fromJust note1)+ ; overSoXSynthHelpN v0+ ; overSoXSynthHelpN2 v1}+ paths0 <- listDirectory "."+ let paths = sort . filter (isPrefixOf "test") $ paths0+ _ <- readProcessWithExitCode (fromJust (showE "sox")) (["--combine", "mix"] ++ paths ++ ["result0" ++ prependZeroes zeroN (show j) ++ ".wav","vol","0.3"]) ""+ mapM_ removeFile paths) vec0+ | otherwise = let ampL1 = ampL - (fromIntegral . truncate $ ampL) in+ if abs ampL1 < 0.01 then overSoXSynthN35G n 0.01 dAmpl v2 tts v3 vec0+ else overSoXSynthN35G n ampL1 dAmpl v2 tts v3 vec0++-- | Variant of the 'overSoXSynthN34G' where 'Durations' are obtained from the 'String' using 'str2Durations' function. Helps to create a speech-like +-- composition.+overSoXSynthN34GS :: Int -> Double -> Double -> Double -> String -> String -> String -> V.Vector Double -> IO ()+overSoXSynthN34GS n ampL time3 dAmpl zs = overSoXSynthN34G n ampL dAmpl (str2Durations zs time3)++-- | Variant of the 'overSoXSynthN34G' where intervals are obtained from the basic 'Intervals' with the length no more than 29 and a Ukrainian text +-- specified as the last 'String' argument so that you can produce 'Intervals' of the arbitrary length. For more information, please, refer to +-- 'intervalsFromStringG' and 'strToIntG'.+overSoXSynthN35GS :: Int -> Double -> Double -> Double -> String -> String -> Intervals -> String -> V.Vector Double -> IO ()+overSoXSynthN35GS n ampL time3 dAmpl zs tts v3 vs = overSoXSynthN35G n ampL dAmpl (str2Durations zs time3) tts (intervalsFromStringG v3 vs)+ -- | Similar to 'overSoXSynthN', 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 Overtones. If it is set to 1.0 the overTones amplitudes are just maximum ones,@@ -413,12 +524,28 @@ -- its modifications, please, use 2, 3, 4, 6, or 9. overSoXSynthNGenE :: FilePath -> Int -> Int -> Double -> Double -> String -> IO () overSoXSynthNGenE file m ku ampL time3 zs = do- duration0 <- durationA file- let n = truncate (duration0 / 0.001)+ n <- duration1000 file+ nGenE4Gi n file m ku ampL (str2DurationsDef n zs time3)++-- | Variant of the 'overSoXSynthNGenE4G' where 'Durations' are obtained from the 'String' using 'str2Durations' function. Helps to create a speech-like +-- composition.+overSoXSynthNGenE4GS :: FilePath -> Int -> Int -> Double -> Double -> String -> IO ()+overSoXSynthNGenE4GS file m ku ampL time3 zs = do+ n <- duration1000 file+ nGenE4Gi n file m ku ampL (str2Durations zs time3)++nGenE4Gi :: Int -> FilePath -> Int -> Int -> Double -> Durations -> IO ()+nGenE4Gi n file m ku ampL v2 = do vecA <- freqsFromFile file n let vecB = liftInEnkuV m ku . V.map fromIntegral . V.filter (/= (11440::Int)) $ vecA- overSoXSynthN n ampL time3 zs vecB- endFromResult + overSoXSynthN4G n ampL v2 vecB+ endFromResult + +-- | 4G genaralized version of the 'overSoXSynthNGenE' where you provide your own 'Durations'.+overSoXSynthNGenE4G :: FilePath -> Int -> Int -> Double -> Durations -> IO ()+overSoXSynthNGenE4G file m ku ampL v2 = do+ n <- duration1000 file+ nGenE4Gi n file m ku ampL v2 -- | Similar to 'overSoXSynthN2', 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@@ -437,12 +564,28 @@ -- its modifications, please, use 2, 3, 4, 6, or 9. overSoXSynthNGen2E :: FilePath -> Int -> Int -> Double -> Double -> String -> String -> IO () overSoXSynthNGen2E file m ku ampL time3 zs tts = do- duration0 <- durationA file- let n = truncate (duration0 / 0.001)+ n <- duration1000 file+ nGen2E4Gi n file m ku ampL (str2DurationsDef n zs time3) tts++-- | Variant of the 'overSoXSynthNGen2E4G' where 'Durations' are obtained from the 'String' using 'str2Durations' function. Helps to create a speech-like +-- composition.+overSoXSynthNGen2E4GS :: FilePath -> Int -> Int -> Double -> Double -> String -> String -> IO ()+overSoXSynthNGen2E4GS file m ku ampL time3 zs tts = do+ n <- duration1000 file+ nGen2E4Gi n file m ku ampL (str2Durations zs time3) tts++nGen2E4Gi :: Int -> FilePath -> Int -> Int -> Double -> Durations -> String -> IO ()+nGen2E4Gi n file m ku ampL v2 tts = do vecA <- freqsFromFile file n- let vecB = liftInEnkuV m ku. V.map fromIntegral . V.filter (/= (11440::Int)) $ vecA- overSoXSynthN2 n ampL time3 zs tts vecB- endFromResult + let vecB = liftInEnkuV m ku . V.map fromIntegral . V.filter (/= (11440::Int)) $ vecA+ overSoXSynthN24G n ampL v2 tts vecB+ endFromResult + +-- | 4G genaralized version of the 'overSoXSynthNGen2E' where you provide your own 'Durations'.+overSoXSynthNGen2E4G :: FilePath -> Int -> Int -> Double -> Durations -> String -> IO ()+overSoXSynthNGen2E4G file m ku ampL v2 tts = do+ n <- duration1000 file+ nGen2E4Gi n file m ku ampL v2 tts -- | Similar to 'overSoXSynthN2', 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@@ -465,12 +608,58 @@ -- its modifications, please, use 2, 3, 4, 6, or 9. overSoXSynthNGen3E :: FilePath -> Int -> Int -> Double -> Double -> Double -> String -> String -> String -> IO () overSoXSynthNGen3E file m ku ampL time3 dAmpl zs tts vs = do- duration0 <- durationA file- let n = truncate (duration0 / 0.001)+ n <- duration1000 file+ nGen3E4Gi n file m ku ampL dAmpl (str2DurationsDef n zs time3) tts vs++-- | Variant of the 'overSoXSynthNGen3E4G' where 'Durations' are obtained from the 'String' using 'str2Durations' function. Helps to create a speech-like +-- composition.+overSoXSynthNGen3E4GS :: FilePath -> Int -> Int -> Double -> Double -> Double -> String -> String -> String -> IO ()+overSoXSynthNGen3E4GS file m ku ampL time3 dAmpl zs tts vs = do+ n <- duration1000 file+ nGen3E4Gi n file m ku ampL dAmpl (str2Durations zs time3) tts vs ++nGen3E4Gi :: Int -> FilePath -> Int -> Int -> Double -> Double -> Durations -> String -> String -> IO ()+nGen3E4Gi n file m ku ampL dAmpl v2 tts vs = do vecA <- freqsFromFile file n let vecB = liftInEnkuV m ku . V.map fromIntegral . V.filter (/= (11440::Int)) $ vecA- overSoXSynthN3 n ampL time3 dAmpl zs tts vs vecB- endFromResult+ overSoXSynthN34G n ampL dAmpl v2 tts vs vecB+ endFromResult ++nGen3E5Gi :: Int -> FilePath -> Int -> Int -> Double -> Double -> Durations -> String -> Intervals -> IO ()+nGen3E5Gi n file m ku ampL dAmpl v2 tts v3 = do + vecA <- freqsFromFile file n+ let vecB = liftInEnkuV m ku . V.map fromIntegral . V.filter (/= (11440::Int)) $ vecA+ overSoXSynthN35G n ampL dAmpl v2 tts v3 vecB+ endFromResult ++-- | 4G generalized function for 'overSoXSynthNGen3E' where you provide your own 'Durations'.+overSoXSynthNGen3E4G :: FilePath -> Int -> Int -> Double -> Double -> Durations -> String -> String -> IO ()+overSoXSynthNGen3E4G file m ku ampL dAmpl v2 tts vs = do+ n <- duration1000 file+ nGen3E4Gi n file m ku ampL dAmpl v2 tts vs++-- | 5G generalized function for 'overSoXSynthNGen3E4G' where you provide your own 'Intervals'.+overSoXSynthNGen3E5G :: FilePath -> Int -> Int -> Double -> Double -> Durations -> String -> Intervals -> IO ()+overSoXSynthNGen3E5G file m ku ampL dAmpl v2 tts v3 = do+ n <- duration1000 file+ nGen3E5Gi n file m ku ampL dAmpl v2 tts v3 ++-- | Variant of the 'overSoXSynthNGen3E5G' where 'Intervals' are obtained from the basic 'Intervals' with the length no more than 29 and a Ukrainian text +-- specified as the last 'String' argument so that you can produce 'Intervals' of the arbitrary length. For more information, please, refer to +-- 'intervalsFromStringG' and 'strToIntG'.+overSoXSynthNGen3E5GS :: FilePath -> Int -> Int -> Double -> Double -> Double -> String -> String -> Intervals -> String -> IO ()+overSoXSynthNGen3E5GS file m ku ampL time3 dAmpl zs tts v3 vs = do+ n <- duration1000 file+ nGen3E5Gi n file m ku ampL dAmpl (str2Durations zs time3) tts (intervalsFromStringG v3 vs)+ +-- | 6G generalized function for 'overSoXSynthNGen3E5G' where you provide your own 'Strengths'.+overSoXSynthNGen3E6G :: FilePath -> Int -> Int -> Double -> Double -> Durations -> String -> Intervals -> Strengths -> Double -> IO ()+overSoXSynthNGen3E6G file m ku ampL dAmpl v2 tts v3 v6 limV = + overSoXSynthNGen3E5G file m ku ampL dAmpl v2 tts v3 >> apply6G2 v6 "221w" "result" limV >> endFromResult++-- | A variant of 'overSoXSynthNGen3E6G' where 'Strengths' are obtained from a Ukrainian text specified as the last 'String' argument.+overSoXSynthNGen3E6GS :: FilePath -> Int -> Int -> Double -> Double -> Durations -> String -> Intervals -> String -> Double -> IO ()+overSoXSynthNGen3E6GS file m ku ampL dAmpl v2 tts v3 xxs limV = overSoXSynthNGen3E6G file m ku ampL dAmpl v2 tts v3 (str2Volume xxs) limV -- | 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@@ -484,17 +673,22 @@ note1 = pureQuintNote note0 v0 = uniqOvertonesV note0 wws v1 = uniqOvertonesV note1 wws- uniqOverSoXSynthHelp 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 "", "vol", showFFloat (Just 4) amplN ""] "") vec- uniqOverSoXSynthHelp2 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 "",- "vol", showFFloat (Just 4) amplN ""] "") vec _ <- readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "test-.wav", "synth", "0.5","sine", showFFloat (Just 4) note0 "", "synth", "0.5","sine", "mix", showFFloat (Just 4) note1 "", "vol","0.5"] "" uniqOverSoXSynthHelp v0 uniqOverSoXSynthHelp2 v1 mixTest +uniqOverSoXSynthHelp1 :: String -> OvertonesO -> IO ()+uniqOverSoXSynthHelp1 xs = V.imapM_ (\i (noteN, !amplN) -> readProcessWithExitCode (fromJust (showE "sox"))+ ["-r22050", "-n", xs ++ show (i + 2) ++ ".wav", "synth", "0.5","sine", showFFloat (Just 4) noteN "", "vol", showFFloat (Just 4) amplN ""] "") ++uniqOverSoXSynthHelp :: OvertonesO -> IO ()+uniqOverSoXSynthHelp = uniqOverSoXSynthHelp1 "test0"++uniqOverSoXSynthHelp2 :: OvertonesO -> IO ()+uniqOverSoXSynthHelp2 = uniqOverSoXSynthHelp1 "test1"+ -- | 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@@ -508,12 +702,6 @@ note1 = pureQuintNote note0 v0 = uniqOvertonesV2 note0 wws tts v1 = uniqOvertonesV2 note1 wws tts- uniqOverSoXSynthHelp 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 "",- "vol", showFFloat (Just 4) amplN ""] "") vec- uniqOverSoXSynthHelp2 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 "",- "vol", showFFloat (Just 4) amplN ""] "") vec _ <- readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "test-.wav", "synth", "0.5","sine", showFFloat (Just 4) note0 "", "synth", "0.5","sine", "mix", showFFloat (Just 4) note1 "", "vol","0.5"] "" uniqOverSoXSynthHelp v0@@ -529,32 +717,42 @@ -- 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*\" files in the current directory, because they can be overwritten. uniqOverSoXSynthN :: Int -> Double -> Double -> String -> String -> V.Vector Double -> IO ()-uniqOverSoXSynthN n ampL time3 zs wws vec0+uniqOverSoXSynthN n ampL time3 zs = uniqOverSoXSynthN4G n ampL (str2DurationsDef n zs time3)++-- | Variant of the 'uniqOverSoXSynthN4G' function where 'Durations' are obtained from the 'String' using 'str2Durations' function. Helps to create a speech-like +-- composition.+uniqOverSoXSynthN4GS :: Int -> Double -> Double -> String -> String -> V.Vector Double -> IO ()+uniqOverSoXSynthN4GS n ampL time3 zs = uniqOverSoXSynthN4G n ampL (str2Durations zs time3)++-- | 4G generalized variant of the 'uniqOverSoXSynthN' where you specify your own 'Durations'.+uniqOverSoXSynthN4G :: Int -> Double -> Durations -> String -> V.Vector Double -> IO ()+uniqOverSoXSynthN4G n ampL v2 wws vec0 | compare (abs ampL) 0.01 /= LT && compare (abs 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.+ let m = length v2+ zeroN = numVZeroesPre vec0 in V.imapM_ (\j x -> do + let note0 = closestNote x note1 = pureQuintNote note0 v0 = uniqOvertonesV note0 wws v1 = uniqOvertonesV note1 wws- uniqOverSoXSynthHelpN vec = V.imapM_ (\i (noteN, !amplN) -> readProcessWithExitCode (fromJust (showE "sox"))+ uniqOverSoXSynthHelpN = 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)) "",- "sine", showFFloat (Just 4) noteN "", "vol", showFFloat (Just 4) (amplN * ampL) ""] "") vec- uniqOverSoXSynthHelpN2 vec = V.imapM_ (\i (noteN, !amplN) -> readProcessWithExitCode (fromJust (showE "sox"))+ "sine", showFFloat (Just 4) noteN "", "vol", if compare (V.unsafeIndex v2 (j `rem` m)) 0.0 == GT + then showFFloat (Just 4) (amplN * ampL) "" else "0"] "")+ uniqOverSoXSynthHelpN2 = 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)) "",- "sine", showFFloat (Just 4) noteN "", "vol", showFFloat (Just 4) (amplN * ampL) ""] "") vec + "sine", showFFloat (Just 4) noteN "", "vol", if compare (V.unsafeIndex v2 (j `rem` m)) 0.0 == GT + then showFFloat (Just 4) (amplN * ampL) "" else "0"] "") soxSynthHelpMain note01 note02 = readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "testA" ++ prependZeroes zeroN "1" ++ ".wav", "synth", showFFloat (Just 4) (V.unsafeIndex v2 (j `rem` m)) "","sine", showFFloat (Just 4) note01 $- show 0, "synth", showFFloat (Just 4) (V.unsafeIndex v2 (j `rem` m)) "","sine", "mix", showFFloat (Just 4) note02 "", "vol","0.5"] ""+ show 0, "synth", showFFloat (Just 4) (V.unsafeIndex v2 (j `rem` m)) "","sine", "mix", showFFloat (Just 4) note02 "", "vol",+ if compare (V.unsafeIndex v2 (j `rem` m)) 0.0 == GT then "0.5" else "0"] "" soxSynthHelpMain note0 note1 uniqOverSoXSynthHelpN v0 uniqOverSoXSynthHelpN2 v1 mixTest2 zeroN j) vec0 | otherwise = let ampL1 = ampL - (fromIntegral . truncate $ ampL) in- if abs ampL1 < 0.01 then uniqOverSoXSynthN n 0.01 time3 zs wws vec0- else uniqOverSoXSynthN n ampL1 time3 zs wws vec0+ if abs ampL1 < 0.01 then uniqOverSoXSynthN4G n 0.01 v2 wws vec0+ else uniqOverSoXSynthN4G n ampL1 v2 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@@ -566,32 +764,40 @@ -- 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. uniqOverSoXSynthN3 :: Int -> Double -> Double -> String -> String -> String -> V.Vector Double -> IO ()-uniqOverSoXSynthN3 n ampL time3 zs wws tts vec0+uniqOverSoXSynthN3 n ampL time3 zs = uniqOverSoXSynthN34G n ampL (str2DurationsDef n zs time3)++-- | Variant of the 'uniqOverSoXSynthN34G' where 'Durations' are obtained from the 'String' using 'str2Durations' function. Helps to create a speech-like +-- composition.+uniqOverSoXSynthN34GS :: Int -> Double -> Double -> String -> String -> String -> V.Vector Double -> IO ()+uniqOverSoXSynthN34GS n ampL time3 zs = uniqOverSoXSynthN34G n ampL (str2Durations zs time3)++-- | 4G generalized variant of the 'uniqOverSoXSynthN3' where you specify your own 'Durations'. +uniqOverSoXSynthN34G :: Int -> Double -> Durations -> String -> String -> V.Vector Double -> IO ()+uniqOverSoXSynthN34G n ampL v2 wws tts vec0 | compare (abs ampL) 0.01 /= LT && compare (abs 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 m = length v2+ zeroN = numVZeroesPre vec0 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 = uniqOvertonesV2 note0 wws tts v1 = uniqOvertonesV2 note1 wws tts uniqOverSoXSynthHelpN 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)) "",- "sine", showFFloat (Just 4) noteN "", "vol", showFFloat (Just 4) (amplN * ampL) ""] "") vec+ "sine", showFFloat (Just 4) noteN "", "vol", if compare (V.unsafeIndex v2 (j `rem` m)) 0.0 == GT then showFFloat (Just 4) (amplN * ampL) "" else "0"] "") vec uniqOverSoXSynthHelpN2 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)) "",- "sine", showFFloat (Just 4) noteN "", "vol", showFFloat (Just 4) (amplN * ampL) ""] "") vec + "sine", showFFloat (Just 4) noteN "", "vol", if compare (V.unsafeIndex v2 (j `rem` m)) 0.0 == GT then showFFloat (Just 4) (amplN * ampL) "" else "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)) "","sine", showFFloat (Just 4) note01 $- show 0,"synth", showFFloat (Just 4) (V.unsafeIndex v2 (j `rem` m)) "","sine", "mix", showFFloat (Just 4) note02 "", "vol","0.5"] ""+ show 0,"synth", showFFloat (Just 4) (V.unsafeIndex v2 (j `rem` m)) "","sine", "mix", showFFloat (Just 4) note02 "", "vol",+ if compare (V.unsafeIndex v2 (j `rem` m)) 0.0 == GT then "0.5" else "0"] "" soxSynthHelpMain note0 note1 uniqOverSoXSynthHelpN v0 uniqOverSoXSynthHelpN2 v1 mixTest2 zeroN j) vec0 | otherwise = let ampL1 = ampL - (fromIntegral . truncate $ ampL) in- if abs ampL1 < 0.01 then uniqOverSoXSynthN3 n 0.01 time3 zs wws tts vec0- else uniqOverSoXSynthN3 n ampL1 time3 zs wws tts vec0 + if abs ampL1 < 0.01 then uniqOverSoXSynthN34G n 0.01 v2 wws tts vec0+ else uniqOverSoXSynthN34G n ampL1 v2 wws tts 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@@ -607,32 +813,42 @@ -- the main note. If it is rather great, it can signal that the volume for the second note overTones are greater than for the main note obetones. -- The last one is experimental feature. uniqOverSoXSynthN4 :: Int -> Double -> Double -> Double -> String -> String -> String -> String -> V.Vector Double -> IO ()-uniqOverSoXSynthN4 n ampL time3 dAmpl zs wws tts vs vec0+uniqOverSoXSynthN4 n ampL time3 dAmpl zs = uniqOverSoXSynthN44G n ampL dAmpl (str2DurationsDef n zs time3)++-- | Variant of the 'uniqOverSoXSynthN44G' where 'Durations' are obtained from the 'String' using 'str2Durations' function. Helps to create a speech-like +-- composition.+uniqOverSoXSynthN44GS :: Int -> Double -> Double -> Double -> String -> String -> String -> String -> V.Vector Double -> IO ()+uniqOverSoXSynthN44GS n ampL time3 dAmpl zs = uniqOverSoXSynthN44G n ampL dAmpl (str2Durations zs time3)++-- | 4G generalized variant of the 'uniqOverSoXSynthN4' where you specify your own 'Durations'. +uniqOverSoXSynthN44G :: Int -> Double -> Double -> Durations -> String -> String -> String -> V.Vector Double -> IO ()+uniqOverSoXSynthN44G n ampL dAmpl v2 wws tts vs = uniqOverSoXSynthN45G n ampL dAmpl v2 wws tts (intervalsFromString vs)+ +-- | 5G generalized variant of the 'uniqOverSoXSynthN44G' where you specify your own 'Intervals'. +uniqOverSoXSynthN45G :: Int -> Double -> Double -> Durations -> String -> String -> Intervals -> V.Vector Double -> IO ()+uniqOverSoXSynthN45G n ampL dAmpl v2 wws tts v3 vec0 | compare (abs ampL) 0.01 /= LT && compare (abs ampL) 1.0 /= GT =- let (t, ws) = splitAt 1 . syllableStr n $ zs- m = length ws+ let m = length v2 zeroN = numVZeroesPre vec0- v3 = intervalsFromString vs- l = length vs- 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.+ l = V.length v3 in V.imapM_ (\j x -> do + let note0 = closestNote x note1 = dNote (V.unsafeIndex v3 (j `rem` l)) note0 v0 = uniqOvertonesV2 note0 wws tts v1 = if isNothing note1 then V.empty else uniqOvertonesV2 (fromJust note1) wws tts- uniqOverSoXSynthHelpN vec = V.imapM_ (\i (noteN, !amplN) -> readProcessWithExitCode (fromJust (showE "sox"))+ uniqOverSoXSynthHelpN = 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)) "",- "sine",showFFloat (Just 4) noteN "", "vol", showFFloat (Just 4) (amplN * ampL) ""] "") vec- uniqOverSoXSynthHelpN2 vec = V.imapM_ (\i (noteN, amplN) -> readProcessWithExitCode (fromJust (showE "sox"))+ "sine",showFFloat (Just 4) noteN "", "vol", if compare (V.unsafeIndex v2 (j `rem` m)) 0.0 == GT then showFFloat (Just 4) (amplN * ampL) "" else "0"] "") + uniqOverSoXSynthHelpN2 = 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)) "",- "sine", showFFloat (Just 4) noteN "", "vol", showFFloat (Just 4) (if dAmpl * amplN * ampL > 1.0 then 1.0- else dAmpl * amplN * ampL) ""] "") vec + "sine", showFFloat (Just 4) noteN "", "vol", if compare (V.unsafeIndex v2 (j `rem` m)) 0.0 == GT then showFFloat (Just 4) (if dAmpl * amplN * ampL > 1.0 then 1.0+ else dAmpl * amplN * ampL) "" else "0"] "") soxSynthHelpMain0 note01 = readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "testA" ++ prependZeroes zeroN "1" ++ ".wav", "synth", showFFloat (Just 4) (V.unsafeIndex v2 (j `rem` m)) "","sine", showFFloat (Just 4) note01 "",- "vol","0.5"] ""+ "vol",if compare (V.unsafeIndex v2 (j `rem` m)) 0.0 == GT then "0.5" else "0"] "" soxSynthHelpMain1 note02 = readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "testB" ++ prependZeroes zeroN "1" ++ ".wav", "synth", showFFloat (Just 4) (V.unsafeIndex v2 (j `rem` m)) "","sine", showFFloat (Just 4) note02 "",- "vol", showFFloat (Just 4) (if dAmpl > 0.5 then 0.5 else dAmpl / 2) ""] ""+ "vol", if compare (V.unsafeIndex v2 (j `rem` m)) 0.0 == GT then showFFloat (Just 4) (if dAmpl > 0.5 then 0.5 else dAmpl / 2) "" else "0"] "" if isNothing note1 then do { soxSynthHelpMain0 note0 ; uniqOverSoXSynthHelpN v0 } else do { soxSynthHelpMain0 note0@@ -641,9 +857,61 @@ ; uniqOverSoXSynthHelpN2 v1} mixTest2 zeroN j) vec0 | otherwise = let ampL1 = ampL - (fromIntegral . truncate $ ampL) in- if abs ampL1 < 0.01 then uniqOverSoXSynthN4 n 0.01 time3 dAmpl zs wws tts vs vec0- else uniqOverSoXSynthN4 n ampL1 time3 dAmpl zs wws tts vs vec0 + if abs ampL1 < 0.01 then uniqOverSoXSynthN45G n 0.01 dAmpl v2 wws tts v3 vec0+ else uniqOverSoXSynthN45G n ampL1 dAmpl v2 wws tts v3 vec0 +-- | 6G generalized variant of the 'uniqOverSoXSynthN45G' where you specify your own 'Strengths' and a limit (as the last 'Double') when less volume level +-- sound files are treated as a silent ones and are not adjusted. +uniqOverSoXSynthN46G :: Int -> Double -> Double -> Durations -> String -> String -> Intervals -> V.Vector Double -> Strengths -> Double -> IO ()+uniqOverSoXSynthN46G n ampL dAmpl v2 wws tts v3 vec0 v6 limV+ | V.null v6 = putStrLn "You did not provide a volume adjustments vector! "+ | compare (abs ampL) 0.01 /= LT && compare (abs ampL) 1.0 /= GT =+ let m = length v2+ zeroN = numVZeroesPre vec0+ l = V.length v3 in V.imapM_ (\j x -> do + let note0 = closestNote x+ note1 = dNote (V.unsafeIndex v3 (j `rem` l)) note0+ v0 = uniqOvertonesV2 note0 wws tts+ v1 = if isNothing note1 then V.empty+ else uniqOvertonesV2 (fromJust note1) wws tts+ uniqOverSoXSynthHelpN = 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)) "",+ "sine",showFFloat (Just 4) noteN "", "vol", if compare (V.unsafeIndex v2 (j `rem` m)) 0.0 == GT then showFFloat (Just 4) (amplN * ampL) "" else "0"] "") + uniqOverSoXSynthHelpN2 = 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)) "",+ "sine", showFFloat (Just 4) noteN "", "vol", if compare (V.unsafeIndex v2 (j `rem` m)) 0.0 == GT then showFFloat (Just 4) (if dAmpl * amplN * ampL > 1.0 then 1.0+ else dAmpl * amplN * ampL) "" else "0"] "") + soxSynthHelpMain0 note01 = readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "testA" +++ prependZeroes zeroN "1" ++ ".wav", "synth", showFFloat (Just 4) (V.unsafeIndex v2 (j `rem` m)) "","sine", showFFloat (Just 4) note01 "",+ "vol",if compare (V.unsafeIndex v2 (j `rem` m)) 0.0 == GT then "0.5" else "0"] ""+ soxSynthHelpMain1 note02 = readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "testB" +++ prependZeroes zeroN "1" ++ ".wav", "synth", showFFloat (Just 4) (V.unsafeIndex v2 (j `rem` m)) "","sine", showFFloat (Just 4) note02 "",+ "vol", if compare (V.unsafeIndex v2 (j `rem` m)) 0.0 == GT then showFFloat (Just 4) (if dAmpl > 0.5 then 0.5 else dAmpl / 2) "" else "0"] ""+ if isNothing note1 then do { soxSynthHelpMain0 note0+ ; uniqOverSoXSynthHelpN v0 }+ else do { soxSynthHelpMain0 note0+ ; soxSynthHelpMain1 (fromJust note1)+ ; uniqOverSoXSynthHelpN v0+ ; uniqOverSoXSynthHelpN2 v1}+ mixTest2 zeroN j+ apply6GSilentFile ("result" ++ prependZeroes zeroN (show j) ++ ".wav") limV (V.unsafeIndex v6 (j `rem` V.length v6))) vec0+ | otherwise = let ampL1 = ampL - (fromIntegral . truncate $ ampL) in+ if abs ampL1 < 0.01 then uniqOverSoXSynthN46G n 0.01 dAmpl v2 wws tts v3 vec0 v6 limV+ else uniqOverSoXSynthN46G n ampL1 dAmpl v2 wws tts v3 vec0 v6 limV++-- | Variant of the 'uniqOverSoXSynthN45G' where 'Intervals' are obtained from the 'String' using 'intervalsFromStringG' function. Helps to create a speech-like +-- composition.+uniqOverSoXSynthN45GS :: Int -> Double -> Double -> Double -> String -> String -> String -> Intervals -> String -> V.Vector Double -> IO ()+uniqOverSoXSynthN45GS n ampL time3 dAmpl zs wws tts v3 vs = uniqOverSoXSynthN45G n ampL dAmpl (str2Durations zs time3) wws tts (intervalsFromStringG v3 vs) ++-- | Variant of the 'uniqOverSoXSynthN46G' where 'Strengths' are obtained from the 'String' using 'str2Volume' function. Helps to create a speech-like +-- composition.+uniqOverSoXSynthN46GS :: Int -> Double -> Double -> Double -> String -> String -> String -> Intervals -> String -> V.Vector Double -> String ->+ Double -> IO ()+uniqOverSoXSynthN46GS n ampL time3 dAmpl zs wws tts v3 vs vec0 xxs limV = + uniqOverSoXSynthN46G n ampL dAmpl (str2Durations zs time3) wws tts (intervalsFromStringG v3 vs) vec0 (str2Volume xxs) limV++ -- | Similar to 'uniqOverSoXSynthN', 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 Overtones. If it is set to 1.0 the@@ -660,13 +928,29 @@ -- its modifications, please, use 2, 3, 4, 6, or 9. uniqOverSoXSynthNGenE :: FilePath -> Int -> Int -> Double -> Double -> String -> String -> IO () uniqOverSoXSynthNGenE file m ku ampL time3 zs wws = do- duration0 <- durationA file- let n = truncate (duration0 / 0.001)+ n <- duration1000 file+ unGenNE4Gi n file m ku ampL (str2DurationsDef n zs time3) wws++-- | Variant of the 'uniqOverSoXSynthNGenE4G' where 'Durations' are obtained from the 'String' using 'str2Durations' function. Helps to create a speech-like +-- composition.+uniqOverSoXSynthNGenE4GS :: FilePath -> Int -> Int -> Double -> Double -> String -> String -> IO ()+uniqOverSoXSynthNGenE4GS file m ku ampL time3 zs wws = do+ n <- duration1000 file+ unGenNE4Gi n file m ku ampL (str2Durations zs time3) wws++unGenNE4Gi :: Int -> FilePath -> Int -> Int -> Double -> Durations -> String -> IO ()+unGenNE4Gi n file m ku ampL v2 wws = do vecA <- freqsFromFile file n let vecB = liftInEnkuV m ku . V.map fromIntegral . V.filter (/= (11440::Int)) $ vecA- uniqOverSoXSynthN n ampL time3 zs wws vecB+ uniqOverSoXSynthN4G n ampL v2 wws vecB endFromResult +-- | 4G genaralized version of the 'uniqOverSoXSynthNGenE' where you provide your own 'Durations'.+uniqOverSoXSynthNGenE4G :: FilePath -> Int -> Int -> Double -> Durations -> String -> IO ()+uniqOverSoXSynthNGenE4G file m ku ampL v2 wws = do+ n <- duration1000 file+ unGenNE4Gi n file m ku ampL v2 wws + -- | Similar to 'uniqOverSoXSynthN', 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 Overtones. If it is set to 1.0 the@@ -684,13 +968,29 @@ -- its modifications, please, use 2, 3, 4, 6, or 9. uniqOverSoXSynthNGen3E :: FilePath -> Int -> Int -> Double -> Double -> String -> String -> String -> IO () uniqOverSoXSynthNGen3E file m ku ampL time3 zs wws tts = do- duration0 <- durationA file- let n = truncate (duration0 / 0.001)+ n <- duration1000 file+ unGenN3E4Gi n file m ku ampL (str2DurationsDef n zs time3) wws tts++-- | Variant of the 'uniqOverSoXSynthNGen3E4G' where 'Durations' are obtained from the 'String' using 'str2Durations' function. Helps to create a speech-like +-- composition.+uniqOverSoXSynthNGen3E4GS :: FilePath -> Int -> Int -> Double -> Double -> String -> String -> String -> IO ()+uniqOverSoXSynthNGen3E4GS file m ku ampL time3 zs wws tts = do+ n <- duration1000 file+ unGenN3E4Gi n file m ku ampL (str2Durations zs time3) wws tts++unGenN3E4Gi :: Int -> FilePath -> Int -> Int -> Double -> Durations -> String -> String -> IO ()+unGenN3E4Gi n file m ku ampL v2 wws tts = do vecA <- freqsFromFile file n let vecB = liftInEnkuV m ku . V.map fromIntegral . V.filter (/= (11440::Int)) $ vecA- uniqOverSoXSynthN3 n ampL time3 zs wws tts vecB+ uniqOverSoXSynthN34G n ampL v2 wws tts vecB endFromResult +-- | 4G genaralized version of the 'uniqOverSoXSynthNGen3E' where you provide your own 'Durations'.+uniqOverSoXSynthNGen3E4G :: FilePath -> Int -> Int -> Double -> Durations -> String -> String -> IO ()+uniqOverSoXSynthNGen3E4G file m ku ampL v2 wws tts = do+ n <- duration1000 file+ unGenN3E4Gi n file m ku ampL v2 wws tts + -- | Similar to 'uniqOverSoXSynthN', 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 Overtones. If it is set to 1.0 the@@ -712,9 +1012,56 @@ -- its modifications, please, use 2, 3, 4, 6, or 9. uniqOverSoXSynthNGen4E :: FilePath -> Int -> Int -> Double -> Double -> Double -> String -> String -> String -> String -> IO () uniqOverSoXSynthNGen4E file m ku ampL time3 dAmpl zs wws tts vs = do- duration0 <- durationA file- let n = truncate (duration0 / 0.001)+ n <- duration1000 file+ unGenN4E4Gi n file m ku ampL dAmpl (str2DurationsDef n zs time3) wws tts vs++-- | Variant of the 'uniqOverSoXSynthNGen4E4G' where 'Durations' are obtained from the 'String' using 'str2Durations' function. Helps to create a speech-like +-- composition.+uniqOverSoXSynthNGen4E4GS :: FilePath -> Int -> Int -> Double -> Double -> Double -> String -> String -> String -> String -> IO ()+uniqOverSoXSynthNGen4E4GS file m ku ampL time3 dAmpl zs wws tts vs = do+ n <- duration1000 file+ unGenN4E4Gi n file m ku ampL dAmpl (str2Durations zs time3) wws tts vs++unGenN4E4Gi :: Int -> FilePath -> Int -> Int -> Double -> Double -> Durations -> String -> String -> String -> IO ()+unGenN4E4Gi n file m ku ampL dAmpl v2 wws tts vs = do vecA <- freqsFromFile file n let vecB = liftInEnkuV m ku . V.map fromIntegral . V.filter (/= (11440::Int)) $ vecA- uniqOverSoXSynthN4 n ampL time3 dAmpl zs wws tts vs vecB+ uniqOverSoXSynthN44G n ampL dAmpl v2 wws tts vs vecB endFromResult++unGenN4E5Gi :: Int -> FilePath -> Int -> Int -> Double -> Double -> Durations -> String -> String -> Intervals -> IO ()+unGenN4E5Gi n file m ku ampL dAmpl v2 wws tts v3 = do+ vecA <- freqsFromFile file n+ let vecB = liftInEnkuV m ku . V.map fromIntegral . V.filter (/= (11440::Int)) $ vecA+ uniqOverSoXSynthN45G n ampL dAmpl v2 wws tts v3 vecB+ endFromResult+ +-- | 4G genaralized version of the 'uniqOverSoXSynthNGen4E' where you provide your own 'Durations'.+uniqOverSoXSynthNGen4E4G :: FilePath -> Int -> Int -> Double -> Double -> Durations -> String -> String -> String -> IO ()+uniqOverSoXSynthNGen4E4G file m ku ampL dAmpl v2 wws tts vs = do+ n <- duration1000 file+ unGenN4E4Gi n file m ku ampL dAmpl v2 wws tts vs++-- | 5G genaralized version of the 'uniqOverSoXSynthNGen4E' where you provide your own 'Durations' and 'Intervals'.+uniqOverSoXSynthNGen4E5G :: FilePath -> Int -> Int -> Double -> Double -> Durations -> String -> String -> Intervals -> IO ()+uniqOverSoXSynthNGen4E5G file m ku ampL dAmpl v2 wws tts v3 = do+ n <- duration1000 file+ unGenN4E5Gi n file m ku ampL dAmpl v2 wws tts v3++-- | Variant of the 'uniqOverSoXSynthNGen4E5G' where 'Intervals' are obtained from the 'String' using 'intervalsFromStringG' function. Helps to create a speech-like +-- composition.+uniqOverSoXSynthNGen4E5GS :: FilePath -> Int -> Int -> Double -> Double -> Double -> String -> String -> String -> Intervals -> String -> IO ()+uniqOverSoXSynthNGen4E5GS file m ku ampL time3 dAmpl zs wws tts v3 vs = do+ n <- duration1000 file+ unGenN4E5Gi n file m ku ampL dAmpl (str2Durations zs time3) wws tts (intervalsFromStringG v3 vs)++-- | 6G generalized function for 'uniqOverSoXSynthNGen3E5G' where you provide your own 'Strengths'.+uniqOverSoXSynthNGen4E6G :: FilePath -> Int -> Int -> Double -> Double -> Durations -> String -> String -> Intervals -> Strengths -> Double -> IO ()+uniqOverSoXSynthNGen4E6G file m ku ampL dAmpl v2 wws tts v3 v6 limV = + uniqOverSoXSynthNGen4E5G file m ku ampL dAmpl v2 wws tts v3 >> apply6G2 v6 "221w" "result" limV >> endFromResult++-- | A variant of 'uniqOverSoXSynthNGen3E6G' where 'Strengths' are obtained from a Ukrainian text specified as the last 'String' argument.+uniqOverSoXSynthNGen4E6GS :: FilePath -> Int -> Int -> Double -> Double -> Double -> String -> String -> String -> Intervals -> String -> + String -> Double -> IO ()+uniqOverSoXSynthNGen4E6GS file m ku ampL time3 dAmpl zs wws tts v5 vs xxs limV = + uniqOverSoXSynthNGen4E6G file m ku ampL dAmpl (str2Durations zs time3) wws tts (intervalsFromStringG v5 vs) (str2Volume xxs) limV
DobutokO/Sound/Executable.hs view
@@ -663,10 +663,8 @@ 3 -> fA1 j 4 -> fA1 j _ -> fR1 j)) vecA0- (t, ws) = splitAt 1 . syllableStr n $ zs- m0 = length ws- zeroN = numVZeroesPre vecB- v2 = V.map (\yy -> y * fromIntegral (yy * m0) / fromIntegral (head t)) . V.fromList $ ws in V.imapM_ (\j (x,k) -> do+ v2 = str2DurationsDef n zs y + zeroN = numVZeroesPre vecB in V.imapM_ (\j (x,k) -> do h1 (\u -> k (1.1 * freq0 j)) (x, (V.unsafeIndex v2 (j `rem` (V.length v2)))) j renameFile ("result.wav") $ "result0" ++ prependZeroes zeroN (show (j + 1)) ++ ".wav") vecB endFromResult@@ -695,10 +693,8 @@ 3 -> fA1 j 4 -> fA1 j _ -> fR1 j)) vecA0- (t, ws) = splitAt 1 . syllableStr n $ zs- m0 = length ws zeroN = numVZeroesPre vecB- v2 = V.map (\yy -> y * fromIntegral (yy * m0) / fromIntegral (head t)) . V.fromList $ ws in V.imapM_ (\j (x,k) -> do+ v2 = str2DurationsDef n zs y in V.imapM_ (\j (x,k) -> do h1 (\u -> k (1.1 * freq0 j)) (x, (V.unsafeIndex v2 (j `rem` (V.length v2)))) j renameFile ("result.wav") $ "result0" ++ prependZeroes zeroN (show (j + 1)) ++ ".wav") vecB endFromResult@@ -733,10 +729,8 @@ 3 -> fA1 j 4 -> fA1 j _ -> fR1 j)) vecA0- (t, ws) = splitAt 1 . syllableStr n $ zs- m0 = length ws zeroN = numVZeroesPre vecB- v2 = V.map (\yy -> y * fromIntegral (yy * m0) / fromIntegral (head t)) . V.fromList $ ws in V.imapM_ (\j (x,k) -> do+ v2 = str2DurationsDef n zs y in V.imapM_ (\j (x,k) -> do h2 (k x) (x, (V.unsafeIndex v2 (j `rem` (V.length v2)))) m ku freq1 renameFile ("result.wav") $ "result0" ++ prependZeroes zeroN (show (j + 1)) ++ ".wav") vecB endFromResult @@ -783,10 +777,8 @@ fA1 j = fAddFElems (proj . freq0 $ j) f0 gAdds fR1 j = fRemoveFElems (proj . freq0 $ j) f0 gRems vecB = conversionFII (f0,fA1,fR1) vecA0- (t, ws) = splitAt 1 . syllableStr n $ zs- m0 = length ws zeroN = numVZeroesPre vecB- v2 = V.map (\yy -> y * fromIntegral (yy * m0) / fromIntegral (head t)) . V.fromList $ ws in V.imapM_ (\j (x,k) -> do+ v2 = str2DurationsDef n zs y in V.imapM_ (\j (x,k) -> do h2 (k x) (x, (V.unsafeIndex v2 (j `rem` (V.length v2)))) m ku freq1 renameFile ("result.wav") $ "result0" ++ prependZeroes zeroN (show (j + 1)) ++ ".wav") vecB endFromResult @@ -818,10 +810,8 @@ vecA0 <- fmap (V.map (`quotRem` 108)) ((if m1 == (-1) && n1 == (-1) then readFileDoubles else readFileDoublesMN m1 n1) file) -- >>= print let n = V.length vecA0 vecB = conversionFII (vf,vfA,vfR) vecA0- (t, ws) = splitAt 1 . syllableStr n $ zs- m0 = length ws zeroN = numVZeroesPre vecB- v2 = V.map (\yy -> y * fromIntegral (yy * m0) / fromIntegral (head t)) . V.fromList $ ws in V.imapM_ (\j (x,k) -> do+ v2 = str2DurationsDef n zs y in V.imapM_ (\j (x,k) -> do h2 (k x) (x, (V.unsafeIndex v2 (j `rem` (V.length v2)))) m ku freq1 renameFile ("result.wav") $ "result0" ++ prependZeroes zeroN (show (j + 1)) ++ ".wav") vecB endFromResult
DobutokO/Sound/Functional.hs view
@@ -16,6 +16,10 @@ SoundsO , OvertonesO , NotePairs+ , Durations+ , Strengths+ , StrengthsDb+ , Intervals -- * Work with notes (general) , notes , neighbourNotes@@ -83,19 +87,19 @@ -- ** 1G generalized function with db volume overtones adjustments and several functional parameters , soundGenF31G -- ** Auxiliary functions- , soxBasicParams , adjust_dbVol , partialTest_k , prependZeroes , nOfZeroesLog , numVZeroesPre , syllableStr + , helpF1+ , helpF0+ , doubleVecFromVecOfDouble+ -- *** Working with Intervals , intervalsFromString , vStrToVInt , strToInt- , doubleVecFromVecOfDouble- , helpF1- , helpF0 -- * Working with OvertonesO and function f , maybeFFromStrVec , fVecCoefs@@ -138,6 +142,48 @@ , splitOG12S , splitOG22 , splitOG22S+ -- * New functions for the version 0.36.0.0+ , duration1000+ , durationsAver+ , str2Durat1+ , str2Durations+ , str2DurationsDef+ , str2Vol1+ , str2Volume+ , defInt+ , doublesAveragedA+ , doublesAveragedG+ , equalize2Vec+ , intervalsFromStringG+ , overSoXSynthGen2FDN4G+ , overSoXSynthGen2FDN_SG4GS+ , silentSound2G+ , strToIntG+ , strengthsAver+ , strengthsDbAver+ , vStrToVIntG+ -- * New generalized 5G functions that works with Intervals+ , overSoXSynth2FDN5G+ , overSoXSynth2FDN_B5G+ , overSoXSynth2FDN_S5G+ , overSoXSynth2FDN_Sf35G+ -- * New generalized 6G functions that works with Strengths+ , apply6Gf+ , apply6G+ , apply6G2+ , apply6GS+ , apply6GS2+ , apply6GSilentFile+ , overSoXSynth2FDN6G+ , overSoXSynth2FDN6GS+ , overSoXSynth2FDN_B6G+ , overSoXSynth2FDN_B6GS+ , overSoXSynth2FDN_S6G+ , overSoXSynth2FDN_S6GS+ , overSoXSynth2FDN_Sf36G+ , overSoXSynth2FDN_Sf36GS+ , overSoXSynthGen2FDN_SG6G+ , overSoXSynthGen2FDN_SG6GS ) where import Text.Read (readMaybe)@@ -152,8 +198,9 @@ import EndOfExe import System.Directory import Melodics.Ukrainian (convertToProperUkrainian)-import SoXBasics (durationA)+import SoXBasics (durationA,upperBnd,selMaxAbs) import MMSyn7.Syllable +import DobutokO.Sound.IntermediateF -- | Is used to represent a sequence of intervals, each note being a 'Double' value (its frequency in Hz). type SoundsO = V.Vector (Double, Double)@@ -165,6 +212,20 @@ -- musically connected one with another.. type NotePairs = V.Vector (Double, Double) +-- | Is used to represent a set of durations parameters of the sounds and pauses. The positive value corresponds to the sound +-- and the negative one -- to the pause.+type Durations = V.Vector Double++-- | Is used to represent a set of volumes in the amplitude scale for SoX \"vol\" effect.+type Strengths = V.Vector Double++-- | Is used to represent a set of volumes in the dB scale for SoX \"vol\" effect.+type StrengthsDb = V.Vector Double++-- | Is used to represent a set of intervals for notes (each element is a number of semi-tones between parts of interval). +-- Positive values corresponds to lower notes and negative to higher ones.+type Intervals = V.Vector Int+ -- | Similar to 'overSoXSynth2DN' but instead of 'overTones' function, it uses volatile function @f::Double -> Vector (Double, Double)@ with -- somewhat sophisticated mechanism to normalize the resulting 'V.Vector' elements @(Double, Double)@. The last one is an experimental feature, so -- it is your responsibility to provide a function so that it does not lead to clipping. In such a case, the result of application of the@@ -185,25 +246,12 @@ | y == 0.0 = xss | otherwise = xss ++ ["vol",showFFloat Nothing y "dB"] --- | Is used internally in the functions to specify different SoX parameters for the sound synthesis (rate, bit depth and file extension). Possible--- file extensions are: ".wav" (a default one) and ".flac" (being lossless compressed); rates -- 8000, 11025, 16000, 22050 (a default one), 32000,--- 44100, 48000, 88200, 96000, 176400, 192000 Hz; bit depths -- 16 bits and 24 bits. The first two digits in a 'String' argument encodes rate,--- the next one -- bit depth and the last symbol -- letter \'w\' or \'f\' -- file extension. Because of SoX uses FLAC optionally, before use it, please,--- check whether your installation supports it.-soxBasicParams :: String -> [String] -> [String]-soxBasicParams ys xss - | null xss = []- | otherwise =- let (ts,zs) = splitAt 2 . init $ ys in (getBFst' ("-r22050",V.fromList . zip ["11","16", "17", "19", "32", "44", "48", "80", "96"] $- ["-r11025","-r16000","-r176400","-r192000","-r32000","-r44100","-r48000","-r8000","-r96000"]) ts) : (if zs == "2" then "-b24" else "-b16") :- ((if drop 3 ys == "f" then map (\xs -> if drop (length xs - 4) xs == ".wav" then take (length xs - 4) xs ++ ".flac" else xs) else id) . tail $ xss)- -- | 'V.Vector' of 'Double' is a vector of dB volume adjustments for the corresponding harmonices (overtones). overSoXSynth2FDN1G :: (Double -> OvertonesO) -> (Double, Double) -> Int -> String -> V.Vector Double -> IO () overSoXSynth2FDN1G f (x, y) j zs vdB = overSoXSynth2FDN2G f (x, y) j zs vdB [] -- | Similar to 'overSoXSynth2FDN1G', but additionally allows to specify by the second 'String' argument a quality changes to the generated files--- (please, see 'soxBasicParams').+-- (please, see 'soxBasicParams'). Since version 0.36.0.0 the function supports generation of the pauses. overSoXSynth2FDN2G :: (Double -> OvertonesO) -> (Double, Double) -> Int -> String -> V.Vector Double -> String -> IO () overSoXSynth2FDN2G f (x, y) j zs vdB ys | V.null . convertToProperUkrainian $ zs = overSoXSynth x@@ -221,20 +269,92 @@ ts = showFFloat (Just 4) (abs y) "" overSoXSynthHelp = V.imapM_ (\i (noteN, !amplN) -> readProcessWithExitCode (fromJust (showE "sox")) ((if null ys then id else soxBasicParams ys) ["-r22050", "-n", "test0" ++ show (i + 2) ++ ".wav", "synth", ts,"sine", - showFFloat Nothing noteN "", "vol", showFFloat Nothing amplN ""]) "")+ showFFloat Nothing noteN "", "vol", if compare y 0.0 == GT then showFFloat Nothing amplN "" else "0"]) "") overSoXSynthHelp2 vec vdB = V.imapM_ (\i (noteN, !amplN) -> readProcessWithExitCode (fromJust (showE "sox")) ((if null ys then id else soxBasicParams ys) (adjust_dbVol ["-r22050", "-n", "test1" ++ show (i + 2) ++ ".wav", "synth", ts,"sine", - showFFloat Nothing noteN "","vol", showFFloat Nothing amplN ""] (V.unsafeIndex vdB i))) "") vec+ showFFloat Nothing noteN "","vol", if compare y 0.0 == GT then showFFloat Nothing amplN "" else "0"] (V.unsafeIndex vdB i))) "") vec _ <- readProcessWithExitCode (fromJust (showE "sox")) ((if null ys then id else soxBasicParams ys) ["-r22050", "-n", "testA.wav", "synth", ts, - "sine", showFFloat Nothing note0 ""]) ""+ "sine", showFFloat Nothing note0 "","vol", if compare y 0.0 == GT then "1.0" else "0"]) "" if isNothing note1 then overSoXSynthHelp v0 else do _ <- readProcessWithExitCode (fromJust (showE "sox")) ((if null ys then id else soxBasicParams ys) ["-r22050", "-n", "testB.wav", "synth", ts, - "sine", showFFloat Nothing (fromJust note1) ""]) ""+ "sine", showFFloat Nothing (fromJust note1) "","vol", if compare y 0.0 == GT then "1.0" else "0"]) "" overSoXSynthHelp v0 overSoXSynthHelp2 v1 vdB if null ys then mixTest else mixTest2G ys +-- | Similar to 'overSoXSynth2FDN2G', but additionally allows to specify by the 'Intervals' argument to specify your own intervals. For more information, +-- please, refer to 'intervalsFromStringG'.+overSoXSynth2FDN5G :: (Double -> OvertonesO) -> (Double, Double) -> Int -> Intervals -> V.Vector Double -> String -> IO ()+overSoXSynth2FDN5G f (x, y) j v5 vdB ys+ | V.null v5 = overSoXSynth x+ | otherwise = do+ let note0 = closestNote (if x /= 0.0 then abs x else V.unsafeIndex notes 0)+ l0 = V.length v5+ note1 = dNote (V.unsafeIndex v5 (abs (j `rem` l0))) note0+ g0 = V.fromList . nubBy (\(!x1,_) (!x2,_) -> x1 == x2) . V.toList . V.map (\(noteX, !amplX) ->+ if noteX <= 0.0 then (2 * note0, abs (amplX - (fromIntegral . truncate $ amplX))) else (closestNote noteX,+ abs (amplX - (fromIntegral . truncate $ amplX)))) . f+ g k = V.takeWhile (\(!w,!z) -> compare w (V.unsafeIndex notes 107) /= GT && compare (abs z) 0.001 == GT) .+ V.imap (\i (_,!z0) -> (fromIntegral (i + 1) * (fst . V.unsafeIndex (g0 k) $ 0), z0)) . g0 $ k + v0 = g note0+ v1 = maybe V.empty g note1+ ts = showFFloat (Just 4) (abs y) "" + overSoXSynthHelp = V.imapM_ (\i (noteN, !amplN) -> readProcessWithExitCode (fromJust (showE "sox"))+ ((if null ys then id else soxBasicParams ys) ["-r22050", "-n", "test0" ++ show (i + 2) ++ ".wav", "synth", ts,"sine", + showFFloat Nothing noteN "", "vol", if compare y 0.0 == GT then showFFloat Nothing amplN "" else "0"]) "")+ overSoXSynthHelp2 vec vdB = V.imapM_ (\i (noteN, !amplN) -> readProcessWithExitCode (fromJust (showE "sox"))+ ((if null ys then id else soxBasicParams ys) (adjust_dbVol ["-r22050", "-n", "test1" ++ show (i + 2) ++ ".wav", "synth", ts,"sine", + showFFloat Nothing noteN "","vol", if compare y 0.0 == GT then showFFloat Nothing amplN "" else "0"] (V.unsafeIndex vdB i))) "") vec+ _ <- readProcessWithExitCode (fromJust (showE "sox")) ((if null ys then id else soxBasicParams ys) ["-r22050", "-n", "testA.wav", "synth", ts, + "sine", showFFloat Nothing note0 "","vol", if compare y 0.0 == GT then "1.0" else "0"]) ""+ if isNothing note1 then overSoXSynthHelp v0+ else do + _ <- readProcessWithExitCode (fromJust (showE "sox")) ((if null ys then id else soxBasicParams ys) ["-r22050", "-n", "testB.wav", "synth", ts, + "sine", showFFloat Nothing (fromJust note1) "","vol", if compare y 0.0 == GT then "1.0" else "0"]) ""+ overSoXSynthHelp v0+ overSoXSynthHelp2 v1 vdB+ if null ys then mixTest else mixTest2G ys ++-- | Generalized variant of the 'overSoXSynth2FDN5G' with afterwards 'apply6Gf' usage. +overSoXSynth2FDN6G :: (Double -> OvertonesO) -> (Double, Double) -> Int -> Intervals -> V.Vector Double -> String -> Double -> IO ()+overSoXSynth2FDN6G f (x, y) j v5 vdB ys vol+ | V.null v5 = overSoXSynth x+ | otherwise = do+ let note0 = closestNote (if x /= 0.0 then abs x else V.unsafeIndex notes 0)+ l0 = V.length v5+ note1 = dNote (V.unsafeIndex v5 (abs (j `rem` l0))) note0+ g0 = V.fromList . nubBy (\(!x1,_) (!x2,_) -> x1 == x2) . V.toList . V.map (\(noteX, !amplX) ->+ if noteX <= 0.0 then (2 * note0, abs (amplX - (fromIntegral . truncate $ amplX))) else (closestNote noteX,+ abs (amplX - (fromIntegral . truncate $ amplX)))) . f+ g k = V.takeWhile (\(!w,!z) -> compare w (V.unsafeIndex notes 107) /= GT && compare (abs z) 0.001 == GT) .+ V.imap (\i (_,!z0) -> (fromIntegral (i + 1) * (fst . V.unsafeIndex (g0 k) $ 0), z0)) . g0 $ k + v0 = g note0+ v1 = maybe V.empty g note1+ ts = showFFloat (Just 4) (abs y) "" + overSoXSynthHelp = V.imapM_ (\i (noteN, !amplN) -> readProcessWithExitCode (fromJust (showE "sox"))+ ((if null ys then id else soxBasicParams ys) ["-r22050", "-n", "test0" ++ show (i + 2) ++ ".wav", "synth", ts,"sine", + showFFloat Nothing noteN "", "vol", if compare y 0.0 == GT then showFFloat Nothing amplN "" else "0"]) "")+ overSoXSynthHelp2 vec vdB = V.imapM_ (\i (noteN, !amplN) -> readProcessWithExitCode (fromJust (showE "sox"))+ ((if null ys then id else soxBasicParams ys) (adjust_dbVol ["-r22050", "-n", "test1" ++ show (i + 2) ++ ".wav", "synth", ts,"sine", + showFFloat Nothing noteN "","vol", if compare y 0.0 == GT then showFFloat Nothing amplN "" else "0"] (V.unsafeIndex vdB i))) "") vec+ _ <- readProcessWithExitCode (fromJust (showE "sox")) ((if null ys then id else soxBasicParams ys) ["-r22050", "-n", "testA.wav", "synth", ts, + "sine", showFFloat Nothing note0 "","vol", if compare y 0.0 == GT then "1.0" else "0"]) ""+ if isNothing note1 then overSoXSynthHelp v0+ else do + _ <- readProcessWithExitCode (fromJust (showE "sox")) ((if null ys then id else soxBasicParams ys) ["-r22050", "-n", "testB.wav", "synth", ts, + "sine", showFFloat Nothing (fromJust note1) "","vol", if compare y 0.0 == GT then "1.0" else "0"]) ""+ overSoXSynthHelp v0+ overSoXSynthHelp2 v1 vdB+ if null ys then mixTest else mixTest2G ys+ if compare y 0.0 == GT then apply6Gf vol ("result." ++ if drop 3 ys == "f" then "flac" else "wav") else putStr ""++-- | A variant of the 'overSoXSynth2FDN6G' where volume adjustment is obtained from a Ukrainian text.+overSoXSynth2FDN6GS :: (Double -> OvertonesO) -> (Double, Double) -> Int -> Intervals -> String -> V.Vector Double -> String -> String -> IO ()+overSoXSynth2FDN6GS f (x, y) j v5 xs vdB ys xxs + | V.null . convertToProperUkrainian $ xxs = putStrLn "You provided no information to obtain volume adjustment! "+ | otherwise = overSoXSynth2FDN6G f (x, y) j (intervalsFromStringG v5 xs) vdB ys (str2Vol1 xxs)+ -- | Uses additional 'Int' parameters. The first one is a number of enka (see 'nkyT'). The second one defines, to which n-th elements set -- (see 'nkyT') belongs the obtained higher notes in the intervals. To obtain reasonable results, please, use for the first one 2, 3, 4, 6, 9, or 12. -- The first 'String' parameter is used to produce durations of the notes. The second one is used to define intervals. A 'Double' parameter is a@@ -242,6 +362,13 @@ overSoXSynthGen2FDN :: FilePath -> Int -> Int -> (Double -> OvertonesO) -> Double -> String -> String -> IO () overSoXSynthGen2FDN file m ku f y zs wws = overSoXSynthGen2FDN_SG file m ku f y zs wws overSoXSynth2FDN +-- | Generalized variant of the 'overSoXSynthGen2FDN' with your own specified 'Durations' for the sounds and pauses. +-- Instead of using a Ukrainian text to specify a durations for the sounds (and a rhythm +-- respectively) you provide your own rhythm as 'Durations'. Positive values correspond to durations of the sounds generated +-- and negative values -- to durations of the pauses respectively. +overSoXSynthGen2FDN4G :: FilePath -> Int -> Int -> (Double -> OvertonesO) -> Double -> Durations -> String -> IO ()+overSoXSynthGen2FDN4G file m ku f y v2 wws = overSoXSynthGen2FDN_SG4G file m ku f y v2 wws overSoXSynth2FDN+ -- | Gets 'V.Vector' of 'Int' frequencies from the given 'FilePath' using SoX. The frequencies are \"rough\" according to the SoX documentation and -- the duration is too small so they can be definitely other than expected ones. Is used as a source of variable numbers (somewhat close each to another -- in their order but not neccessarily). .@@ -327,7 +454,7 @@ -- | Creates part of the needed \"test\*\.wav" files in the current directory. partialTest_k :: OvertonesO -> Int -> String -> IO ()-partialTest_k vec k ts = partialTest_k1G vec k ts V.empty+partialTest_k vec k ts = partialTest_k2G vec k ts V.empty [] -- | Generalized version of the 'partialTest_k' with the additional volume adjustment in dB given by 'V.Vector' of 'Double'. partialTest_k1G :: OvertonesO -> Int -> String -> V.Vector Double -> IO ()@@ -355,7 +482,7 @@ else putStrLn herr0 else readProcessWithExitCode (fromJust (showE "sox")) ((if null ys then id else soxBasicParams ys) ((if V.null vdB then id else (\wwws -> adjust_dbVol wwws (V.unsafeIndex vdB i))) ["-r22050", "-n", "test" ++ show k ++ show (i + 2) ++ ".wav",- "synth", ts,"sine", showFFloat Nothing (abs noteN) "", "vol", showFFloat Nothing amplN ""])) "" >> putStr "") vec + "synth", ts,"sine", showFFloat Nothing (abs noteN) "", "vol", showFFloat Nothing amplN ""])) "" >> putStr "") vec -- | Generates a 'V.Vector' of 'OvertonesO' that represents the sound. doubleVecFromVecOfDouble :: (Double -> OvertonesO) -> Double -> V.Vector (Maybe Double) -> V.Vector OvertonesO@@ -382,7 +509,7 @@ overSoXSynth2FDN_B1G f (x, y, limB) j zs vdB = overSoXSynth2FDN_B2G f (x, y, limB) j zs vdB [] -- | Generalized version of the 'overSoXSynth2FDN_B1G' with a possibility to specify sound quality parameters using additional second 'String'--- argument. For more information, please, refer to 'soxBasicParams'.+-- argument. For more information, please, refer to 'soxBasicParams'. overSoXSynth2FDN_B2G :: (Double -> OvertonesO) -> (Double, Double, Double) -> Int -> String -> V.Vector Double -> String -> IO () overSoXSynth2FDN_B2G f (x, y, limB) j zs vdB ys | V.null . convertToProperUkrainian $ zs = overSoXSynth x@@ -403,21 +530,101 @@ ts = showFFloat (Just 4) (abs y) "" overSoXSynthHelp = V.imapM_ (\i (noteN, !amplN) -> readProcessWithExitCode (fromJust (showE "sox")) ((if null ys then id else soxBasicParams ys) ["-r22050", "-n", "test0" ++ show (i + 2) ++ ".wav", "synth", ts,"sine", - showFFloat Nothing noteN "", "vol", showFFloat Nothing amplN ""]) "")+ showFFloat Nothing noteN "", "vol", if compare y 0.0 == GT then showFFloat Nothing amplN "" else "0"]) "") overSoXSynthHelp2 vec vdB = V.imapM_ (\i (noteN, !amplN) -> readProcessWithExitCode (fromJust (showE "sox")) ((if null ys then id else soxBasicParams ys) ((if V.null vdB then id else (\wwws -> adjust_dbVol wwws (V.unsafeIndex vdB i))) ["-r22050", "-n", "test1" ++ show (i + 2) ++ ".wav", "synth", ts,"sine", showFFloat Nothing noteN "", "vol", - showFFloat Nothing amplN ""])) "") vec+ if compare y 0.0 == GT then showFFloat Nothing amplN "" else "0"])) "") vec _ <- readProcessWithExitCode (fromJust (showE "sox")) ((if null ys then id else soxBasicParams ys) ["-r22050", "-n", "testA.wav", "synth", ts,"sine",- showFFloat Nothing note0 ""]) ""+ showFFloat Nothing note0 "","vol", if compare y 0.0 == GT then "1.0" else "0"]) "" if isNothing note1 then overSoXSynthHelp v0 else do _ <- readProcessWithExitCode (fromJust (showE "sox")) ((if null ys then id else soxBasicParams ys) ["-r22050", "-n", "testB.wav", "synth", ts,"sine",- showFFloat Nothing (fromJust note1) ""]) ""+ showFFloat Nothing (fromJust note1) "","vol", if compare y 0.0 == GT then "1.0" else "0"]) "" overSoXSynthHelp v0 overSoXSynthHelp2 v1 vdB if null ys then mixTest else mixTest2G ys +-- | Generalized version of the 'overSoXSynth2FDN_B2G' with a possibility to specify your own 'Intervals'. For more information, please, +-- refer to 'intervalsFromStringG'.+overSoXSynth2FDN_B5G :: (Double -> OvertonesO) -> (Double, Double, Double) -> Int -> Intervals -> V.Vector Double -> String -> IO ()+overSoXSynth2FDN_B5G f (x, y, limB) j v5 vdB ys+ | V.null v5 = overSoXSynth x+ | otherwise = do+ let limA0 = abs ((limB / 10) - (fromIntegral . truncate $ (limB / 10))) * 10+ limA = if compare limA0 0.1 == LT then 0.1 else limA0+ l0 = length v5+ note0 = closestNote (if x /= 0.0 then abs x else V.unsafeIndex notes 0)+ note1 = dNote (V.unsafeIndex v5 (abs (j `rem` l0))) note0+ g0 = V.fromList . nubBy (\(!x1,_) (!x2,_) -> compare (abs (x1 - x2)) limA == LT) . V.toList . V.map (\(noteX, !amplX) ->+ if noteX <= 0.0 then (2 * note0, abs (amplX - (fromIntegral . truncate $ amplX))) else (closestNote noteX,+ abs (amplX - (fromIntegral . truncate $ amplX)))) . f+ v0 = V.takeWhile (\(!w,!z) -> compare w (V.unsafeIndex notes 107) /= GT && compare (abs z) 0.001 == GT) .+ V.imap (\i (_,!z0) -> (fromIntegral (i + 1) * (fst . V.unsafeIndex (g0 note0) $ 0), z0)) . g0 $ note0 + v1 = if isNothing note1 then V.empty+ else V.takeWhile (\(!w,!z) -> compare w (V.unsafeIndex notes 107) /= GT && compare (abs z) 0.001 == GT) .+ V.imap (\i (_,!z0) -> (fromIntegral (i + 1) * (fst . V.unsafeIndex (g0 . fromJust $ note1) $ 0), z0)) . g0 . fromJust $ note1+ ts = showFFloat (Just 4) (abs y) "" + overSoXSynthHelp = V.imapM_ (\i (noteN, !amplN) -> readProcessWithExitCode (fromJust (showE "sox"))+ ((if null ys then id else soxBasicParams ys) ["-r22050", "-n", "test0" ++ show (i + 2) ++ ".wav", "synth", ts,"sine", + showFFloat Nothing noteN "", "vol", if compare y 0.0 == GT then showFFloat Nothing amplN "" else "0"]) "")+ overSoXSynthHelp2 vec vdB = V.imapM_ (\i (noteN, !amplN) -> readProcessWithExitCode (fromJust (showE "sox"))+ ((if null ys then id else soxBasicParams ys) ((if V.null vdB then id else (\wwws -> adjust_dbVol wwws (V.unsafeIndex vdB i))) + ["-r22050", "-n", "test1" ++ show (i + 2) ++ ".wav", "synth", ts,"sine", showFFloat Nothing noteN "", "vol", + if compare y 0.0 == GT then showFFloat Nothing amplN "" else "0"])) "") vec+ _ <- readProcessWithExitCode (fromJust (showE "sox")) ((if null ys then id else soxBasicParams ys) ["-r22050", "-n", "testA.wav", "synth", ts,"sine",+ showFFloat Nothing note0 "","vol", if compare y 0.0 == GT then "1.0" else "0"]) ""+ if isNothing note1 then overSoXSynthHelp v0+ else do + _ <- readProcessWithExitCode (fromJust (showE "sox")) ((if null ys then id else soxBasicParams ys) ["-r22050", "-n", "testB.wav", "synth", ts,"sine",+ showFFloat Nothing (fromJust note1) "","vol", if compare y 0.0 == GT then "1.0" else "0"]) ""+ overSoXSynthHelp v0+ overSoXSynthHelp2 v1 vdB+ if null ys then mixTest else mixTest2G ys ++-- | Generalized variant of the 'overSoXSynth2FDN_B5G' with afterwards 'apply6G' usage. +overSoXSynth2FDN_B6G :: (Double -> OvertonesO) -> (Double, Double, Double) -> Int -> Intervals -> V.Vector Double -> String -> Double -> IO ()+overSoXSynth2FDN_B6G f (x, y, limB) j v5 vdB ys vol + | V.null v5 = overSoXSynth x+ | otherwise = do+ let limA0 = abs ((limB / 10) - (fromIntegral . truncate $ (limB / 10))) * 10+ limA = if compare limA0 0.1 == LT then 0.1 else limA0+ l0 = length v5+ note0 = closestNote (if x /= 0.0 then abs x else V.unsafeIndex notes 0)+ note1 = dNote (V.unsafeIndex v5 (abs (j `rem` l0))) note0+ g0 = V.fromList . nubBy (\(!x1,_) (!x2,_) -> compare (abs (x1 - x2)) limA == LT) . V.toList . V.map (\(noteX, !amplX) ->+ if noteX <= 0.0 then (2 * note0, abs (amplX - (fromIntegral . truncate $ amplX))) else (closestNote noteX,+ abs (amplX - (fromIntegral . truncate $ amplX)))) . f+ v0 = V.takeWhile (\(!w,!z) -> compare w (V.unsafeIndex notes 107) /= GT && compare (abs z) 0.001 == GT) .+ V.imap (\i (_,!z0) -> (fromIntegral (i + 1) * (fst . V.unsafeIndex (g0 note0) $ 0), z0)) . g0 $ note0 + v1 = if isNothing note1 then V.empty+ else V.takeWhile (\(!w,!z) -> compare w (V.unsafeIndex notes 107) /= GT && compare (abs z) 0.001 == GT) .+ V.imap (\i (_,!z0) -> (fromIntegral (i + 1) * (fst . V.unsafeIndex (g0 . fromJust $ note1) $ 0), z0)) . g0 . fromJust $ note1+ ts = showFFloat (Just 4) (abs y) "" + overSoXSynthHelp = V.imapM_ (\i (noteN, !amplN) -> readProcessWithExitCode (fromJust (showE "sox"))+ ((if null ys then id else soxBasicParams ys) ["-r22050", "-n", "test0" ++ show (i + 2) ++ ".wav", "synth", ts,"sine", + showFFloat Nothing noteN "", "vol", if compare y 0.0 == GT then showFFloat Nothing amplN "" else "0"]) "")+ overSoXSynthHelp2 vec vdB = V.imapM_ (\i (noteN, !amplN) -> readProcessWithExitCode (fromJust (showE "sox"))+ ((if null ys then id else soxBasicParams ys) ((if V.null vdB then id else (\wwws -> adjust_dbVol wwws (V.unsafeIndex vdB i))) + ["-r22050", "-n", "test1" ++ show (i + 2) ++ ".wav", "synth", ts,"sine", showFFloat Nothing noteN "", "vol", + if compare y 0.0 == GT then showFFloat Nothing amplN "" else "0"])) "") vec+ _ <- readProcessWithExitCode (fromJust (showE "sox")) ((if null ys then id else soxBasicParams ys) ["-r22050", "-n", "testA.wav", "synth", ts,"sine",+ showFFloat Nothing note0 "","vol", if compare y 0.0 == GT then "1.0" else "0"]) ""+ if isNothing note1 then overSoXSynthHelp v0+ else do + _ <- readProcessWithExitCode (fromJust (showE "sox")) ((if null ys then id else soxBasicParams ys) ["-r22050", "-n", "testB.wav", "synth", ts,"sine",+ showFFloat Nothing (fromJust note1) "","vol", if compare y 0.0 == GT then "1.0" else "0"]) ""+ overSoXSynthHelp v0+ overSoXSynthHelp2 v1 vdB+ if null ys then mixTest else mixTest2G ys + if compare y 0.0 == GT then apply6Gf vol ("result." ++ if drop 3 ys == "f" then "flac" else "wav") else putStr ""++-- | A variant of the 'overSoXSynth2FDN_B6G' where volume adjustment is obtained from a Ukrainian text.+overSoXSynth2FDN_B6GS :: (Double -> OvertonesO) -> (Double, Double, Double) -> Int -> Intervals -> String -> V.Vector Double -> String -> String -> IO ()+overSoXSynth2FDN_B6GS f (x, y, limB) j v5 xs vdB ys xxs+ | V.null . convertToProperUkrainian $ xxs = putStrLn "You provided no information to obtain volume adjustment! "+ | otherwise = overSoXSynth2FDN_B6G f (x, y, limB) j (intervalsFromStringG v5 xs) vdB ys (str2Vol1 xxs)+ -- | Uses additional 'Int' parameters. The first one is a number of enka (see 'nkyT'). The second one defines, to which n-th elements set -- (see 'nkyT') belongs the obtained higher notes in the intervals. To obtain reasonable results, please, use for the first one 2, 3, 4, 6, 9, or 12. -- The first 'String' parameter is used to produce durations of the notes. The second one is used to define intervals. The first 'Double' parameter is a@@ -455,44 +662,139 @@ v1 = maybe V.empty f note1 ts = showFFloat (Just 4) (abs y) "" _ <- readProcessWithExitCode (fromJust (showE "sox")) ((if null ys then id else soxBasicParams ys) ["-r22050", "-n", "testA.wav", "synth", ts,"sine",- showFFloat Nothing note0 ""]) ""+ showFFloat Nothing note0 "","vol", if compare y 0.0 == GT then "1.0" else "0"]) "" if isNothing note1 then partialTest_k2G v0 0 ts vdB ys else do _ <- readProcessWithExitCode (fromJust (showE "sox")) ((if null ys then id else soxBasicParams ys) ["-r22050", "-n", "testB.wav", "synth", ts,"sine",- showFFloat Nothing (fromJust note1) ""]) ""+ showFFloat Nothing (fromJust note1) "","vol", if compare y 0.0 == GT then "1.0" else "0"]) "" partialTest_k2G v0 0 ts vdB ys partialTest_k2G v1 1 ts vdB ys- if null ys then mixTest else mixTest2G ys + if null ys then mixTest else mixTest2G ys + +-- | Generalized version of the 'overSoXSynth2FDN_S2G' where you specify your own 'Intervals'. For more information, please, refer +-- to 'intervalsFromStringG'.+overSoXSynth2FDN_S5G :: (Double -> OvertonesO) -> (Double, Double) -> Int -> Intervals -> V.Vector Double -> String -> IO ()+overSoXSynth2FDN_S5G f (x, y) j v5 vdB ys+ | V.null v5 = overSoXSynth x+ | otherwise = do+ let note0 = closestNote (if x /= 0.0 then abs x else V.unsafeIndex notes 0)+ l0 = length v5+ note1 = dNote (V.unsafeIndex v5 (abs (j `rem` l0))) note0+ v0 = f note0+ v1 = maybe V.empty f note1+ ts = showFFloat (Just 4) (abs y) ""+ _ <- readProcessWithExitCode (fromJust (showE "sox")) ((if null ys then id else soxBasicParams ys) ["-r22050", "-n", "testA.wav", "synth", ts,"sine",+ showFFloat Nothing note0 "","vol", if compare y 0.0 == GT then "1.0" else "0"]) ""+ if isNothing note1 then partialTest_k2G v0 0 ts vdB ys+ else do + _ <- readProcessWithExitCode (fromJust (showE "sox")) ((if null ys then id else soxBasicParams ys) ["-r22050", "-n", "testB.wav", "synth", ts,"sine",+ showFFloat Nothing (fromJust note1) "","vol", if compare y 0.0 == GT then "1.0" else "0"]) ""+ partialTest_k2G v0 0 ts vdB ys+ partialTest_k2G v1 1 ts vdB ys+ if null ys then mixTest else mixTest2G ys +-- | Generalized variant of the 'overSoXSynth2FDN_S5G' with afterwards 'apply6G' usage. Arguments for the latter is the three last function arguments.+overSoXSynth2FDN_S6G :: (Double -> OvertonesO) -> (Double, Double) -> Int -> Intervals -> V.Vector Double -> String -> Double -> IO ()+overSoXSynth2FDN_S6G f (x, y) j v5 vdB ys vol+ | V.null v5 = overSoXSynth x+ | otherwise = do+ let note0 = closestNote (if x /= 0.0 then abs x else V.unsafeIndex notes 0)+ l0 = length v5+ note1 = dNote (V.unsafeIndex v5 (abs (j `rem` l0))) note0+ v0 = f note0+ v1 = maybe V.empty f note1+ ts = showFFloat (Just 4) (abs y) ""+ _ <- readProcessWithExitCode (fromJust (showE "sox")) ((if null ys then id else soxBasicParams ys) ["-r22050", "-n", "testA.wav", "synth", ts,"sine",+ showFFloat Nothing note0 "","vol", if compare y 0.0 == GT then "1.0" else "0"]) ""+ if isNothing note1 then partialTest_k2G v0 0 ts vdB ys+ else do + _ <- readProcessWithExitCode (fromJust (showE "sox")) ((if null ys then id else soxBasicParams ys) ["-r22050", "-n", "testB.wav", "synth", ts,"sine",+ showFFloat Nothing (fromJust note1) "","vol", if compare y 0.0 == GT then "1.0" else "0"]) ""+ partialTest_k2G v0 0 ts vdB ys+ partialTest_k2G v1 1 ts vdB ys+ if null ys then mixTest else mixTest2G ys + if compare y 0.0 == GT then apply6Gf vol ("result." ++ if drop 3 ys == "f" then "flac" else "wav") else putStr ""+ +-- | A variant of the 'overSoXSynth2FDN_S6G' where volume adjustment is obtained from a Ukrainian text.+overSoXSynth2FDN_S6GS :: (Double -> OvertonesO) -> (Double, Double) -> Int -> Intervals -> String -> V.Vector Double -> String -> String -> IO ()+overSoXSynth2FDN_S6GS f (x, y) j v5 xs vdB ys xxs+ | V.null . convertToProperUkrainian $ xxs = putStrLn "You provided no information to obtain volume adjustment! "+ | otherwise = overSoXSynth2FDN_S6G f (x, y) j (intervalsFromStringG v5 xs) vdB ys (str2Vol1 xxs)+ -- | Similar to 'overSoXSynthGen2FDN', but instead of 'overSoXSynth2FDN' uses 'overSoXSynth2FDN_S' function. -overSoXSynthGen2FDN_SG :: FilePath -> Int -> Int -> (Double -> OvertonesO) -> Double -> String -> String -> ((Double -> OvertonesO) -> (Double, Double) -> Int -> String -> IO ()) -> IO ()+overSoXSynthGen2FDN_SG :: FilePath -> Int -> Int -> (Double -> OvertonesO) -> Double -> String -> String -> + ((Double -> OvertonesO) -> (Double, Double) -> Int -> String -> IO ()) -> IO () overSoXSynthGen2FDN_SG file m ku f y zs wws h = do- duration0 <- durationA file- let n = truncate (duration0 / 0.001)+ n <- duration1000 file+ overSoXSynthGen2FDN_SG4G file m ku f y (str2DurationsDef n zs y) wws h++-- | Generalized version of the 'overSoXSynthGen2FDN_SG' where instead of using a Ukrainian text to specify a durations for the sounds (and a rhythm +-- respectively) you provide your own rhythm as 'Durations'. Positive values correspond to durations of the sounds generated +-- and negative values -- to durations of the pauses respectively. Please, use a function @h :: ((Double -> OvertonesO) -> (Double, Double) -> +-- Int -> String -> IO ())@ such that it can create for the given values accorgingly sounds and pauses. Otherwise, please, check whether at +-- least it can deal with such arguments without errors.+overSoXSynthGen2FDN_SG4G :: FilePath -> Int -> Int -> (Double -> OvertonesO) -> Double -> Durations -> String -> + ((Double -> OvertonesO) -> (Double, Double) -> Int -> String -> IO ()) -> IO ()+overSoXSynthGen2FDN_SG4G file m ku f y v2 wws h = do+ n <- duration1000 file vecA <- freqsFromFile file n let vecB = liftInEnkuV m ku . V.map fromIntegral . V.filter (/= (11440::Int)) $ vecA- (t, ws) = splitAt 1 . syllableStr n $ zs- m0 = length ws- zeroN = numVZeroesPre vecB- v2 = V.map (\yy -> y * fromIntegral (yy * m0) / fromIntegral (head t)) . V.fromList $ ws in V.imapM_ (\j x -> do+ zeroN = numVZeroesPre vecB in V.imapM_ (\j x -> do h f (x, (V.unsafeIndex v2 (j `rem` (V.length v2)))) j wws renameFile "result.wav" $ "result0" ++ prependZeroes zeroN (show (j + 1)) ++ ".wav") vecB- endFromResult+ endFromResult +-- | Auxiliary function to get from a sound file specified a duration parameter @n@ that can be used further.+duration1000 :: FilePath -> IO Int+duration1000 file = fmap (\t -> truncate (t / 0.001)) . durationA $ file++-- | A variant of the 'overSoXSynthGen2FDN_SG4G' where instead of providing your own durations as 'Durations' you use a Ukrainian text and +-- a function treats each symbol in it as a duration parameter with its sign. Positive values correspond to durations of the sounds generated +-- and negative values -- to durations of the pauses respectively. Please, use a function @h :: ((Double -> OvertonesO) -> (Double, Double) -> +-- Int -> String -> IO ())@ such that it can create for the given values accorgingly sounds and pauses. Otherwise, please, check whether at +-- least it can deal with such arguments without errors.+overSoXSynthGen2FDN_SG4GS :: FilePath -> Int -> Int -> (Double -> OvertonesO) -> Double -> String -> String -> + ((Double -> OvertonesO) -> (Double, Double) -> Int -> String -> IO ()) -> IO ()+overSoXSynthGen2FDN_SG4GS file m ku f y zs = overSoXSynthGen2FDN_SG4G file m ku f y (str2Durations zs y)++-- | 6G generalized variant of the 'overSoXSynthGen2FDN_SG4G' with volume adjustments given by 'Strengths'.+overSoXSynthGen2FDN_SG6G :: FilePath -> Int -> Int -> (Double -> OvertonesO) -> Double -> Durations -> String -> + ((Double -> OvertonesO) -> (Double, Double) -> Int -> String -> IO ()) -> Strengths -> Double -> IO ()+overSoXSynthGen2FDN_SG6G file m ku f y v2 wws h v6 limV+ | V.null v6 = putStrLn "You did not provide a volume adjustments vector! "+ | otherwise = do+ n <- duration1000 file+ vecA <- freqsFromFile file n+ let vecB = liftInEnkuV m ku . V.map fromIntegral . V.filter (/= (11440::Int)) $ vecA+ zeroN = numVZeroesPre vecB in V.imapM_ (\j x -> do+ h f (x, (V.unsafeIndex v2 (j `rem` (V.length v2)))) j wws+ renameFile "result.wav" $ "result0" ++ prependZeroes zeroN (show (j + 1)) ++ ".wav"+ apply6GSilentFile ("result0" ++ prependZeroes zeroN (show (j + 1)) ++ ".wav") limV (V.unsafeIndex v6 (j `rem` V.length v6))) vecB+ endFromResult ++-- | A variant of the 'overSoXSynthGen2FDN_SG6G' where 'Strengths' are obtained from a Ukrainian text and 'str2Volume'.+overSoXSynthGen2FDN_SG6GS :: FilePath -> Int -> Int -> (Double -> OvertonesO) -> Double -> String -> String -> + ((Double -> OvertonesO) -> (Double, Double) -> Int -> String -> IO ()) -> String -> Double -> IO ()+overSoXSynthGen2FDN_SG6GS file m ku f y zs wws h zzs = overSoXSynthGen2FDN_SG6G file m ku f y (str2Durations zs y) wws h (str2Volume zzs) ++-- | A default way to get 'Durations' for the sounds up to 0.35.2.0 version of the package including. It is based on the number of Ukrainian +-- sounds representations (see, 'convertToProperUkrainian') in a Ukrainian syllables or somewhat generated by the same rules as they. +-- The rhythm using the function is very often not binary but its ratios are almost always a ratios of the small natural numbers (1, 2, 3, 4, 5, 6, 7 etc.).+str2DurationsDef :: Int -> String -> Double -> Durations+str2DurationsDef n zs y = + let (t, ws) = splitAt 1 . syllableStr n $ zs in V.map (\yy -> y * fromIntegral (yy * length ws) / fromIntegral (head t)) . V.fromList $ ws + -- | Generalized variant of the 'overSoXSynthGen2FDN_SG' with a possibility to specify with the third 'String' argument sound quality parameters. -- Besides, the second from the end argument (a function) needs to be one more argument -- just also 'String'. -- For more information, please, refer to 'soxBasicParams'. overSoXSynthGen2FDN_SG2G :: FilePath -> Int -> Int -> (Double -> OvertonesO) -> Double -> String -> String -> ((Double -> OvertonesO) -> (Double, Double) -> Int -> String -> String -> IO ()) -> String -> IO () overSoXSynthGen2FDN_SG2G file m ku f y zs wws h ys = do- duration0 <- durationA file- let n = truncate (duration0 / 0.001)+ n <- duration1000 file vecA <- freqsFromFile file n let vecB = liftInEnkuV m ku . V.map fromIntegral . V.filter (/= (11440::Int)) $ vecA- (t, ws) = splitAt 1 . syllableStr n $ zs- m0 = length ws zeroN = numVZeroesPre vecB- v2 = V.map (\yy -> y * fromIntegral (yy * m0) / fromIntegral (head t)) . V.fromList $ ws in V.imapM_ (\j x -> do+ v2 = str2DurationsDef n zs y in V.imapM_ (\j x -> do h f (x, (V.unsafeIndex v2 (j `rem` (V.length v2)))) j wws ys renameFile ("result." ++ if drop 3 ys == "f" then "flac" else "wav") $ "result0" ++ prependZeroes zeroN (show (j + 1)) ++ if drop 3 ys == "f" then ".flac" else ".wav") vecB@@ -526,14 +828,11 @@ -- | Similar to 'overSoXSynthGen2FDN_S', but instead of 'overSoXSynth2FDN_S' uses 'overSoXSynth2FDN_Sf' function. overSoXSynthGen2FDN_Sf :: FilePath -> Int -> Int -> (Double -> OvertonesO) -> Double -> String -> String -> IO () overSoXSynthGen2FDN_Sf file m ku f y zs wws = do- duration0 <- durationA file- let n = truncate (duration0 / 0.001)+ n <- duration1000 file vecA <- freqsFromFile file n let vecB = liftInEnkuV m ku . V.map fromIntegral . V.filter (/= (11440::Int)) $ vecA- (t, ws) = splitAt 1 . syllableStr n $ zs- m0 = length ws zeroN = numVZeroesPre vecB- v2 = V.map (\yy -> y * fromIntegral (yy * m0) / fromIntegral (head t)) . V.fromList $ ws in V.imapM_ (\j x -> do+ v2 = str2DurationsDef n zs y in V.imapM_ (\j x -> do overSoXSynth2FDN_Sf f (x, (V.unsafeIndex v2 (j `rem` (V.length v2)))) j wws renameFile "result.wav" $ "result0" ++ prependZeroes zeroN (show (j + 1)) ++ ".wav") vecB endFromResult @@ -563,9 +862,39 @@ let l0 = length zs soundGenF32G (V.fromList [\x -> closestNote (if x /= 0.0 then abs x else V.unsafeIndex notes 0),\x -> fromMaybe (V.unsafeIndex notes 0) (dNote (V.unsafeIndex (intervalsFromString zs) (abs (j `rem` l0))) (closestNote (if x /= 0.0 then abs x else V.unsafeIndex notes 0)))])- (V.replicate 2 x) (V.fromList [1,V.unsafeIndex (intervalsFromString zs) (abs (j `rem` l0))]) f (x, y, t0) j zs vdB ys+ (V.replicate 2 x) (V.fromList [1,V.unsafeIndex (intervalsFromString zs) (abs (j `rem` l0))]) f (x, y, t0) j vdB ys if null ys then mixTest else mixTest2G ys +-- | Generalized variant of the 'overSoXSynth2FDN_Sf31G' with a possibility to specify sound quality using the second 'String' parameter.+-- For more information, please, refer to 'soxBasicParams'.+overSoXSynth2FDN_Sf35G :: (Double -> OvertonesO) -> (Double, Double, Double) -> Int -> Intervals -> V.Vector Double -> String -> IO ()+overSoXSynth2FDN_Sf35G f (x, y, t0) j v5 vdB ys+ | V.null v5 = overSoXSynth x+ | otherwise = do+ let l0 = length v5+ soundGenF32G (V.fromList [\x -> closestNote (if x /= 0.0 then abs x else V.unsafeIndex notes 0),\x -> fromMaybe (V.unsafeIndex notes 0)+ (dNote (V.unsafeIndex v5 (abs (j `rem` l0))) (closestNote (if x /= 0.0 then abs x else V.unsafeIndex notes 0)))])+ (V.replicate 2 x) (V.fromList [1,V.unsafeIndex v5 (abs (j `rem` l0))]) f (x, y, t0) j vdB ys+ if null ys then mixTest else mixTest2G ys ++-- | Generalized variant of the 'overSoXSynth2FDN_Sf35G' with afterwards 'apply6G' usage.+overSoXSynth2FDN_Sf36G :: (Double -> OvertonesO) -> (Double, Double, Double) -> Int -> Intervals -> V.Vector Double -> String -> Double -> IO ()+overSoXSynth2FDN_Sf36G f (x, y, t0) j v5 vdB ys vol+ | V.null v5 = overSoXSynth x+ | otherwise = do+ let l0 = length v5+ soundGenF32G (V.fromList [\x -> closestNote (if x /= 0.0 then abs x else V.unsafeIndex notes 0),\x -> fromMaybe (V.unsafeIndex notes 0)+ (dNote (V.unsafeIndex v5 (abs (j `rem` l0))) (closestNote (if x /= 0.0 then abs x else V.unsafeIndex notes 0)))])+ (V.replicate 2 x) (V.fromList [1,V.unsafeIndex v5 (abs (j `rem` l0))]) f (x, y, t0) j vdB ys+ if null ys then mixTest else mixTest2G ys + if compare y 0.0 == GT then apply6Gf vol ("result." ++ if drop 3 ys == "f" then "flac" else "wav") else putStr ""++-- | A variant of the 'overSoXSynth2FDN_Sf36G' where volume adjustment is obtained from a Ukrainian text.+overSoXSynth2FDN_Sf36GS :: (Double -> OvertonesO) -> (Double, Double, Double) -> Int -> Intervals -> String -> V.Vector Double -> String -> String -> IO ()+overSoXSynth2FDN_Sf36GS f (x, y, t0) j v5 xs vdB ys xxs+ | V.null . convertToProperUkrainian $ xxs = putStrLn "You provided no information to obtain volume adjustment! "+ | otherwise = overSoXSynth2FDN_Sf36G f (x, y, t0) j (intervalsFromStringG v5 xs) vdB ys (str2Vol1 xxs)+ helpF1 :: V.Vector (Double -> Double) -> V.Vector Double -> V.Vector Int -> V.Vector (Maybe Double) helpF1 vf vd = V.map (\(f1,x,i2) ->@@ -581,32 +910,30 @@ -- | Can generate multiple notes with their respective overtones that are played simultaneously (e. g. it can be just one note with overtones, -- an interval with overtones, an accord with overtones etc.). This allows to get a rather complex or even complicated behaviour to obtain expressive -- and rich sound.-soundGenF3 :: V.Vector (Double -> Double) -> V.Vector Double -> V.Vector Int -> (Double -> OvertonesO) -> (Double, Double, Double) -> Int ->- String -> IO ()-soundGenF3 vf vd vi f (x, y, t0) j zs = soundGenF32G vf vd vi f (x, y, t0) j zs V.empty []+soundGenF3 :: V.Vector (Double -> Double) -> V.Vector Double -> V.Vector Int -> (Double -> OvertonesO) -> (Double, Double, Double) -> Int -> IO ()+soundGenF3 vf vd vi f (x, y, t0) j = soundGenF32G vf vd vi f (x, y, t0) j V.empty [] -- | Generalized variant of the 'soundGenF3' with volume adjustment in dB given by the second @Vector Double@ for the overtones. soundGenF31G :: V.Vector (Double -> Double) -> V.Vector Double -> V.Vector Int -> (Double -> OvertonesO) -> (Double, Double, Double) -> Int ->- String -> V.Vector Double -> IO ()-soundGenF31G vf vd vi f (x, y, t0) j zs vdB = soundGenF32G vf vd vi f (x, y, t0) j zs vdB [] + V.Vector Double -> IO ()+soundGenF31G vf vd vi f (x, y, t0) j vdB = soundGenF32G vf vd vi f (x, y, t0) j vdB [] --- | Generalized variant of the 'soundGenF31G' with a possibility to specify sound quality using the second 'String' argument. For more information,+-- | Generalized variant of the 'soundGenF31G' with a possibility to specify sound quality using the 'String' argument. For more information, -- please, refer to 'soxBasicParams'. soundGenF32G :: V.Vector (Double -> Double) -> V.Vector Double -> V.Vector Int -> (Double -> OvertonesO) -> (Double, Double, Double) -> Int ->- String -> V.Vector Double -> String -> IO ()-soundGenF32G vf vd vi f (x, y, t0) j zs vdB ys = do+ V.Vector Double -> String -> IO ()+soundGenF32G vf vd vi f (x, y, t0) j vdB ys = do let vD = helpF1 vf vd vi -- Vector of notes played simultaneously (e. g. just one, interval, accord etc.) vDz = V.mapMaybe id vD -- The previous one without Nothings and Justs ilDz = V.length vDz - 1 vNotes = doubleVecFromVecOfDouble f t0 (V.map Just vDz) -- Vector of vectors of pairs (freq,ampl) -- notes and their absence (V.empty) with overtones- l0 = length zs ts = showFFloat (Just 4) (abs y) "" -- duration of the sound to be generated V.imapM_ (\i note1 -> do _ <- readProcessWithExitCode (fromJust (showE "sox")) ((if null ys then id else soxBasicParams ys) ((if V.null vdB then id else (\wwws -> adjust_dbVol wwws (V.unsafeIndex vdB i))) ["-r22050", "-n", "test" ++ helpF0 i ++ ".wav", "synth",ts,- "sine", showFFloat Nothing (V.unsafeIndex vDz i) ""])) ""+ "sine", showFFloat Nothing (V.unsafeIndex vDz i) "","vol", if compare y 0.0 == GT then "1.0" else "0"])) "" partialTest_k2G (V.unsafeIndex vNotes i) i ts vdB ys) vDz - + -- | Similar to 'overSoXSynthGen2FDN_S', but instead of 'overSoXSynth2FDN_S' uses 'overSoXSynth2FDN_Sf3' function. overSoXSynthGen2FDN_Sf3 :: FilePath -> Int -> Int -> (Double -> OvertonesO) -> Double -> Double -> String -> String -> IO () overSoXSynthGen2FDN_Sf3 file m ku f y t0 zs wws = overSoXSynthGen2FDN_Sf3G file m ku f y t0 zs wws overSoXSynth2FDN_Sf3@@ -615,14 +942,11 @@ overSoXSynthGen2FDN_Sf3G :: FilePath -> Int -> Int -> (Double -> OvertonesO) -> Double -> Double -> String -> String -> ((Double -> OvertonesO) -> (Double, Double, Double) -> Int -> String -> IO ()) -> IO () overSoXSynthGen2FDN_Sf3G file m ku f y t0 zs wws h = do- duration0 <- durationA file- let n = truncate (duration0 / 0.001)+ n <- duration1000 file vecA <- freqsFromFile file n let vecB = liftInEnkuV m ku . V.map fromIntegral . V.filter (/= (11440::Int)) $ vecA- (t, ws) = splitAt 1 . syllableStr n $ zs- m0 = length ws zeroN = numVZeroesPre vecB- v2 = V.map (\yy -> y * fromIntegral (yy * m0) / fromIntegral (head t)) . V.fromList $ ws in V.imapM_ (\j x -> do+ v2 = str2DurationsDef n zs y in V.imapM_ (\j x -> do h f (x, (V.unsafeIndex v2 (j `rem` (V.length v2))), t0) j wws renameFile "result.wav" $ "result0" ++ prependZeroes zeroN (show (j + 1)) ++ ".wav") vecB endFromResult@@ -633,14 +957,11 @@ overSoXSynthGen2FDN_Sf3G2G :: FilePath -> Int -> Int -> (Double -> OvertonesO) -> Double -> Double -> String -> String -> ((Double -> OvertonesO) -> (Double, Double, Double) -> Int -> String -> String -> IO ()) -> String -> IO () overSoXSynthGen2FDN_Sf3G2G file m ku f y t0 zs wws h ys = do- duration0 <- durationA file- let n = truncate (duration0 / 0.001)+ n <- duration1000 file vecA <- freqsFromFile file n let vecB = liftInEnkuV m ku . V.map fromIntegral . V.filter (/= (11440::Int)) $ vecA- (t, ws) = splitAt 1 . syllableStr n $ zs- m0 = length ws zeroN = numVZeroesPre vecB- v2 = V.map (\yy -> y * fromIntegral (yy * m0) / fromIntegral (head t)) . V.fromList $ ws in V.imapM_ (\j x -> do+ v2 = str2DurationsDef n zs y in V.imapM_ (\j x -> do h f (x, (V.unsafeIndex v2 (j `rem` (V.length v2))), t0) j wws ys renameFile ("result." ++ if drop 3 ys == "f" then "flac" else "wav") $ "result0" ++ prependZeroes zeroN (show (j + 1)) ++ if drop 3 ys == "f" then ".flac" else ".wav") vecB@@ -760,20 +1081,153 @@ | otherwise = x / 2 {-# INLINE enkuDown #-} +------------------------------------------------------------------------------------------------------------------+ -- | Function is used to get numbers of intervals from a Ukrainian 'String'. It is used internally in the 'uniqOverSoXSynthN4' function.-intervalsFromString :: String -> V.Vector Int-intervalsFromString = vStrToVInt . convertToProperUkrainian+intervalsFromString :: String -> Intervals+intervalsFromString = vStrToVIntG defInt . convertToProperUkrainian -vStrToVInt :: V.Vector String -> V.Vector Int-vStrToVInt = V.map strToInt+-- | Generatlized version of the 'intervalsFromString' with a possibility to specify your own 'Intervals'.+intervalsFromStringG :: Intervals -> String -> Intervals+intervalsFromStringG v = vStrToVIntG v . convertToProperUkrainian +-- | The default way to get 'Intervals' from a converted Ukrainian text.+vStrToVInt :: V.Vector String -> Intervals+vStrToVInt = V.map (strToIntG defInt)++-- | Generatlized version of the 'vStrToVInt' with a possibility to specify your own 'Intervals'.+vStrToVIntG :: Intervals -> V.Vector String -> Intervals+vStrToVIntG v = V.map (strToIntG v)++-- | The default way to get number of semi-tones between notes in a single element of 'Intervals'. strToInt :: String -> Int-strToInt =- getBFst' (0, V.fromList [("а", 12), ("б", 4), ("в", 7), ("г", 3), ("д", 4), ("дж", 5), ("дз", 5), ("е", 12), ("ж", 3), ("з", 8), ("и", 12), - ("й", 7), ("к", 10), ("л", 7), ("м", 7), ("н", 7), ("о", 12), ("п", 10), ("р", 7), ("с", 10), ("т", 2), ("у", 12), ("ф", 2), ("х", 2),- ("ц", 11), ("ч", 11), ("ш", 1), ("і", 12), ("ґ", 9)])-{-# INLINE strToInt #-} +strToInt = strToIntG defInt+{-# INLINE strToInt #-} +-- | Default values for 'strToInt'. All the intervals are not greater than one full octave.+defInt :: Intervals+defInt = V.fromList [12,4,7,3,4,5,5,12,3,8,12,7,10,7,7,7,12,10,7,10,2,12,2,2,11,11,1,12,9]+{-# INLINE defInt #-}++-- | Generatlized version of the 'strToInt' with a possibility to specify your own 'Intervals'.+strToIntG :: Intervals -> String -> Int+strToIntG v =+ getBFst' (0, V.zip (V.fromList ["а","б","в","г","д","дж","дз","е","ж","з","и","й","к","л","м","н","о","п","р","с","т","у","ф","х","ц","ч","ш",+ "і","ґ"]) v)+{-# INLINE strToIntG #-}++---------------------------------------------------------------------------------------------------------------------++-- | Arithmetic average for the 'V.Vector' is used as a weight for a duration. +doublesAveragedA :: V.Vector Double -> Double -> V.Vector Double+doublesAveragedA v4 y3 + | V.null v4 || y3 == 0 = V.empty+ | otherwise = let aver = V.sum v4 / fromIntegral (V.length v4) in if aver == 0.0 then doublesAveragedA (V.filter (/= 0.0) v4) y3 + else V.map (\t4 -> t4 * y3 / aver) v4++-- | Geometric average for the 'V.Vector' is used as a weight for a strength. +doublesAveragedG :: V.Vector Double -> Double -> V.Vector Double+doublesAveragedG v4 y3 + | V.null v4 || y3 == 0 = V.empty+ | otherwise = let aver = V.product v4 ** (fromIntegral 1 / (fromIntegral (V.length v4))) in if aver == 0.0 then doublesAveragedG (V.filter (/= 0.0) v4) y3 + else V.map (\t4 -> t4 * y3 / aver) v4 ++-- | 'Durations' accounting the desired average duration.+durationsAver :: Durations -> Double -> Durations+durationsAver = doublesAveragedA++-- | 'Strengths' accounting the desired average strength.+strengthsAver :: Strengths -> Double -> Strengths+strengthsAver = doublesAveragedG++-- | 'StrengthsDb' accounting the desired average strength in dB.+strengthsDbAver :: StrengthsDb -> Double -> StrengthsDb+strengthsDbAver = doublesAveragedG++-- | Auxiliar function to make all vectors in a 'V.Vector' equal by length (the minimum one).+equalize2Vec :: V.Vector (V.Vector a) -> V.Vector (V.Vector a)+equalize2Vec v = let min = V.minimum . V.map V.length $ v in V.map (V.unsafeSlice 0 min) v++-- | A full conversion to the 'Durations' from a Ukrainian text.+str2Durations :: String -> Double -> Durations+str2Durations xs y + | compare y 0.0 == GT && not (null xs) = durationsAver (V.map str2Durat1 . convertToProperUkrainian $ xs) y+ | otherwise = V.empty++-- | A conversion to the 'Double' that is used inside 'str2Durations'.+str2Durat1 :: String -> Double+str2Durat1 = getBFst' ((-0.153016), V.fromList [("-", (-0.101995)), ("0", (-0.051020)), ("1", (-0.153016)), ("а", 0.138231), ("б", 0.057098), + ("в", 0.082268), ("г", 0.076825), ("д", 0.072063), ("дж", 0.048934), ("дз", 0.055601), ("е", 0.093605), ("ж", 0.070612), ("з", 0.056054), + ("и", 0.099955), ("й", 0.057143), ("к", 0.045397), ("л", 0.064036), ("м", 0.077370), ("н", 0.074240), ("о", 0.116463), ("п", 0.071837), + ("р", 0.049206), ("с", 0.074603), ("сь", 0.074558), ("т", 0.110658), ("у", 0.109070), ("ф", 0.062268), ("х", 0.077188), ("ц", 0.053061), + ("ць", 0.089342), ("ч", 0.057551), ("ш", 0.066077), ("ь", 0.020227), ("і", 0.094150), ("ґ", 0.062948)])++-- | A full conversion to the 'Strengths' from a Ukrainian text.+str2Volume :: String -> Strengths+str2Volume = V.map (getBFst' (0.0, V.fromList [("а", 0.890533), ("б", 0.718872), ("в", (-0.630859)), ("г", (-0.757599)), ("д", (-0.624176)), + ("дж", 0.768127), ("дз", (-0.731262)), ("е", (-0.742523)), ("ж", (-0.837921)), ("з", (-0.528870)), ("и", (-0.770935)), ("й", (-0.708008)), + ("к", 0.886139), ("л", 0.572632), ("м", (-0.782349)), ("н", (-0.797607)), ("о", (-0.579559)), ("п", (-0.212402)), ("р", 0.651062), + ("с", 0.155640), ("сь", (-0.207764)), ("т", 0.304413), ("у", 0.718262), ("ф", (-0.374359)), ("х", (-0.251160)), ("ц", (-0.392365)), + ("ць", 0.381348), ("ч", 0.242615), ("ш", 0.251221), ("ь", 0.495483), ("і", 0.682709), ("ґ", 0.557098)])) . convertToProperUkrainian++-- | A conversion to the 'Double' that is used inside 'str2Volume'.+str2Vol1 :: String -> Double+str2Vol1 = getBFst' (0.0, V.fromList [("а", 0.890533), ("б", 0.718872), ("в", (-0.630859)), ("г", (-0.757599)), ("д", (-0.624176)), + ("дж", 0.768127), ("дз", (-0.731262)), ("е", (-0.742523)), ("ж", (-0.837921)), ("з", (-0.528870)), ("и", (-0.770935)), ("й", (-0.708008)), + ("к", 0.886139), ("л", 0.572632), ("м", (-0.782349)), ("н", (-0.797607)), ("о", (-0.579559)), ("п", (-0.212402)), ("р", 0.651062), + ("с", 0.155640), ("сь", (-0.207764)), ("т", 0.304413), ("у", 0.718262), ("ф", (-0.374359)), ("х", (-0.251160)), ("ц", (-0.392365)), + ("ць", 0.381348), ("ч", 0.242615), ("ш", 0.251221), ("ь", 0.495483), ("і", 0.682709), ("ґ", 0.557098)]) . V.unsafeHead . convertToProperUkrainian++-- | For the given non-existing 'FilePath' for a sound file supported by SoX generates a silence of the specified duration and quality (see, +-- 'soxBasicParams').+silentSound2G :: FilePath -> Double -> String -> IO ()+silentSound2G file y4 ys = do+ _ <- readProcessWithExitCode (fromJust (showE "sox")) + ((if null ys then id else soxBasicParams ys) ["-r22040","-n",file,"synth", showFFloat (Just 1) y4 "","sine","440.0","vol","0"]) ""+ putStr ""++-- | After producing sounds as WAV or FLAC files you can apply to them volume adjustments using 'Strengths'. The first 'String' is used accordingly to +-- 'soxBasicParams' and the second one -- as a prefix of the filenames for the files that the function is applied to. The files must not be silent ones. +-- Otherwise, it leads to likely noise sounding or errors.+apply6G :: Strengths -> String -> String -> IO ()+apply6G v6 ys zs + | V.null v6 = putStrLn "Nothing changed, because the vector of volume adjustments is empty! "+ | otherwise = do+ dir0v <- listVDirectory3G ys zs + V.imapM_ (\i file -> soxE file ["norm","vol", showFFloat (Just 4) (V.unsafeIndex v6 (i `rem` V.length v6)) ""]) dir0v++-- | Apply volume adjustment to the sound file. It must not be silent. Otherwise, it leads to likely noise sounding or errors.+apply6Gf :: Double -> FilePath -> IO ()+apply6Gf vol file = soxE file ["norm","vol", showFFloat (Just 4) vol ""]+ +-- | Variant of the 'apply6G' where you use as a 'Strengths' parameter that one obtained from a Ukrainian text provided as a first 'String' argument. +-- It uses 'str2Volume' inside. The files must not be silent ones. Otherwise, it leads to likely noise sounding or errors.+apply6GS :: String -> String -> String -> IO ()+apply6GS xs = apply6G (str2Volume xs)++apply6GSilentFile :: FilePath -> Double -> Double -> IO ()+apply6GSilentFile file limV vol = do+ upp <- upperBnd file+ ampL2 <- fmap ((\zz -> read zz::Double) . fst) (selMaxAbs file (0,upp))+ if compare (abs ampL2) (abs limV) /= GT then putStr ""+ else apply6Gf vol file++-- | Variant of the 'apply6G' function which can be applied also to the silent files. Whether a file is silent is defined using the 'Double' argument +-- so that if a maximum by absolute value amplitude is less by absolute value than the 'Double' argument then the file is not changed.+apply6G2 :: Strengths -> String -> String -> Double -> IO ()+apply6G2 v6 ys zs limV+ | V.null v6 = putStrLn "Nothing changed, because the vector of volume adjustments is empty! "+ | otherwise = do+ dir0v <- listVDirectory3G ys zs + V.imapM_ (\i file -> apply6GSilentFile file limV (V.unsafeIndex v6 (i `rem` V.length v6))) dir0v++-- | Variant of the 'apply6G2' where you use as a 'Strengths' parameter that one obtained from a Ukrainian text provided as a first 'String' argument. +-- It uses 'str2Volume' inside. +apply6GS2 :: String -> String -> String -> Double -> IO ()+apply6GS2 xs = apply6G2 (str2Volume xs)++-----------------------------------------------------------------------------------------------------------------------+ -- | Returns a 'V.Vector' of tuples with the lowest and highest frequencies for the notes in the sets consisting of @n@ consequential notes -- (including semi-tones). An 'Int' parameter defines this @n@. It can be 2, 3, 4, 6, 9, or 12 (the last one is for default octaves, see 'octavesT'). -- So for different valid @n@ you obtain doubles, triples and so on. The function being applied returns a 'V.Vector' of such sets with@@ -1135,7 +1589,7 @@ _ -> let (k1,k2,k3,k4) = (1,n - 1,0,n) in splitHelp1 k1 k2 k3 k4 v1 (x0,y0) | otherwise = V.singleton v0 --- | Auxiliary function that is used inside 'innerSplit1' and also in 'splitOG1'.+-- | Auxiliary function that is used inside 'splitOG1'. splitHelp1 :: Int -> Int -> Int -> Int -> OvertonesO -> (Double,Double) -> V.Vector OvertonesO splitHelp1 x1 x2 x3 x4 v00 (y5,y6) = let v2 = V.unsafeSlice x1 x2 v00@@ -1145,7 +1599,7 @@ f1Tup (t1, w2) = V.imap (\ i (u1, u2) -> (fst (V.unsafeIndex v3 i) * t1, snd (V.unsafeIndex v3 i) * w2)) v3 in V.map f1Tup (V.unsafeSlice x3 x4 v00) --- | Auxiliary function that is used inside 'innerSplit2' and also in 'splitOG2'.+-- | Auxiliary function that is used inside 'splitOG2'. splitHelp2 :: (OvertonesO -> OvertonesO) -> Int -> Int -> Int -> Int -> OvertonesO -> (Double,Double) -> V.Vector OvertonesO splitHelp2 h1 x1 x2 x3 x4 v00 (y5,y6) = let v2 = V.unsafeSlice x1 x2 v00
DobutokO/Sound/IntermediateF.hs view
@@ -66,6 +66,7 @@ , playCollectDec2G , replaceWithHQs2G -- * SoX effects application+ , soxBasicParams -- ** With \"reverb\" as the first -- *** No file type changes , reverbE@@ -119,7 +120,6 @@ import System.Exit (ExitCode (ExitSuccess)) import System.Info (os) import DobutokO.Sound.ParseList (parseStoLInts)-import DobutokO.Sound.Functional (soxBasicParams) -- | Gets sizes of the \"result\*.wav\" files in the current directory. getFileRSizes :: IO (V.Vector Integer)@@ -596,6 +596,19 @@ _ -> do removeFile $ file ++ "effects" ++ efw2 file putStrLn $ "DobutokO.Sound.IntermediateF.soxE \"" ++ file ++ "\" has not been successful. The file has not been changed at all. "++-- | Is used internally in the functions to specify different SoX parameters for the sound synthesis (rate, bit depth and file extension). Possible+-- file extensions are: ".wav" (a default one) and ".flac" (being lossless compressed); rates -- 8000, 11025, 16000, 22050 (a default one), 32000,+-- 44100, 48000, 88200, 96000, 176400, 192000 Hz; bit depths -- 16 bits and 24 bits. The first two digits in a 'String' argument encodes rate,+-- the next one -- bit depth and the last symbol -- letter \'w\' or \'f\' -- file extension. Because of SoX uses FLAC optionally, before use it, please,+-- check whether your installation supports it.+soxBasicParams :: String -> [String] -> [String]+soxBasicParams ys xss + | null xss = []+ | otherwise =+ let (ts,zs) = splitAt 2 . init $ ys in (getBFst' ("-r22050",V.fromList . zip ["11","16", "17", "19", "32", "44", "48", "80", "96"] $+ ["-r11025","-r16000","-r176400","-r192000","-r32000","-r44100","-r48000","-r8000","-r96000"]) ts) : (if zs == "2" then "-b24" else "-b16") :+ ((if drop 3 ys == "f" then map (\xs -> if drop (length xs - 4) xs == ".wav" then take (length xs - 4) xs ++ ".flac" else xs) else id) . tail $ xss) -- | Similar to 'soxE', but replaces the primary WAV file with the new FLAC file (or vice versa). So if successful the resulting file has another -- extension and type.
README.markdown view
@@ -236,6 +236,11 @@ into several simultaneously sounding similar ones. For more information, please, refer to the DobutokO.Sound.Functional module. +Since the 0.36.0.0 version the library includes functions to provide your own +variants of durations, intervals and volume adjustments and the possibilities +to generate speech-like music with most of parameters obtained from the Ukrainian +language texts.+ ** Note: * Better to execute in the RAM. Need rather a lot of space on the disk for
dobutokO2.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/ name: dobutokO2-version: 0.35.2.0+version: 0.36.0.0 synopsis: Helps to create experimental music from a file (or its part) and a Ukrainian text. description: It can also generate a timbre for the notes. Uses SoX inside. homepage: https://hackage.haskell.org/package/dobutokO2