dobutokO2 0.7.2.1 → 0.8.0.0
raw patch · 3 files changed
+97/−1 lines, 3 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- CHANGELOG.md +5/−0
- DobutokO/Sound.hs +91/−0
- dobutokO2.cabal +1/−1
CHANGELOG.md view
@@ -67,3 +67,8 @@ ## 0.7.2.1 -- 2020-03-11 * Seventh version revised D. Fixed issue with being not compiled because of the syntactic error.++## 0.8.0.0 -- 2020-03-12++* Eigth version. Added the new functions to the library that allows to produce richer sounds especially 'oberSoXSynth2FDN' one. The user can now specify a+function to be passed as an argument to it and obtain therefore own obertones formula. Added OPTIONS_GHC pragma to the module DobutokO.Sound.
DobutokO/Sound.hs view
@@ -8,6 +8,8 @@ -- A program and a library to create experimental music -- from a mono audio and a Ukrainian text. +{-# OPTIONS_GHC -threaded #-}+ module DobutokO.Sound ( -- * Basic functions for the executable dobutokO2@@ -242,6 +244,95 @@ let paths = sort . filter (isPrefixOf "test") $ paths0 _ <- readProcessWithExitCode (fromJust (showE "sox")) (["--combine", "mix"] ++ paths ++ ["result.wav","vol","0.3"]) "" mapM_ removeFile paths++-- | Similar to 'oberSoXSynth' 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 obertones.+oberSoXSynthDN :: Double -> String -> IO ()+oberSoXSynthDN x zs+ | V.null . convertToProperUkrainian $ zs = oberSoXSynth x+ | otherwise = do+ let note0 = closestNote x+ note1 = dNote (V.unsafeIndex (intervalsFromString zs) 0) note0+ v0 = oberTones note0+ v1 = if isNothing note1 then V.empty+ else oberTones . fromJust $ note1+ oberSoXSynthHelp vec = V.imapM_ (\i (noteN, amplN) -> readProcessWithExitCode (fromJust (showE "sox"))+ ["-r22050", "-n", "test0" ++ show (i + 2) ++ ".wav", "synth", "0.5","sine", showFFloat (Just 4) noteN $ show 0, "vol", showFFloat (Just 4) amplN $ show 0] "") vec+ oberSoXSynthHelp2 vec = V.imapM_ (\i (noteN, amplN) -> readProcessWithExitCode (fromJust (showE "sox"))+ ["-r22050", "-n", "test1" ++ show (i + 2) ++ ".wav", "synth", "0.5","sine", showFFloat (Just 4) noteN $ show 0, "vol", showFFloat (Just 4) amplN $ show 0] "") vec+ _ <- readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "testA.wav", "synth", "0.5","sine", showFFloat (Just 4) note0 $ show 0] ""+ if isNothing note1 then do oberSoXSynthHelp v0+ else do + _ <- readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "testB.wav", "synth", "0.5","sine", showFFloat (Just 4) (fromJust note1) $ show 0] ""+ oberSoXSynthHelp v0+ oberSoXSynthHelp2 v1+ paths0 <- listDirectory "."+ let paths = sort . filter (isPrefixOf "test") $ paths0+ _ <- readProcessWithExitCode (fromJust (showE "sox")) (["--combine", "mix"] ++ paths ++ ["result.wav","vol","0.3"]) ""+ mapM_ removeFile paths++-- | Similar to 'oberSoXSynthDN' except that the resulting duration is specified by the second 'Double' parameter in seconds. For 'oberSoXSynthDN'+-- it is equal to 0.5.+oberSoXSynth2DN :: Double -> Double -> String -> IO ()+oberSoXSynth2DN x y zs+ | V.null . convertToProperUkrainian $ zs = oberSoXSynth x+ | otherwise = do+ let note0 = closestNote x+ note1 = dNote (V.unsafeIndex (intervalsFromString zs) 0) note0+ v0 = oberTones note0+ v1 = if isNothing note1 then V.empty+ else oberTones . fromJust $ note1+ oberSoXSynthHelp vec = V.imapM_ (\i (noteN, amplN) -> readProcessWithExitCode (fromJust (showE "sox"))+ ["-r22050", "-n", "test0" ++ show (i + 2) ++ ".wav", "synth", showFFloat (Just 4) y $ show 0,"sine", showFFloat (Just 4) noteN $ show 0,+ "vol", showFFloat (Just 4) amplN $ show 0] "") vec+ oberSoXSynthHelp2 vec = V.imapM_ (\i (noteN, amplN) -> readProcessWithExitCode (fromJust (showE "sox"))+ ["-r22050", "-n", "test1" ++ show (i + 2) ++ ".wav", "synth", showFFloat (Just 4) y $ show 0,"sine", showFFloat (Just 4) noteN $ show 0,+ "vol", showFFloat (Just 4) amplN $ show 0] "") vec+ _ <- readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "testA.wav", "synth", showFFloat (Just 4) y $ show 0,"sine",+ showFFloat (Just 4) note0 $ show 0] ""+ if isNothing note1 then do oberSoXSynthHelp v0+ else do + _ <- readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "testB.wav", "synth", showFFloat (Just 4) y $ show 0,"sine",+ showFFloat (Just 4) (fromJust note1) $ show 0] ""+ oberSoXSynthHelp v0+ oberSoXSynthHelp2 v1+ paths0 <- listDirectory "."+ let paths = sort . filter (isPrefixOf "test") $ paths0+ _ <- readProcessWithExitCode (fromJust (showE "sox")) (["--combine", "mix"] ++ paths ++ ["result.wav","vol","0.3"]) ""+ mapM_ removeFile paths++-- | Similar to 'oberSoXSynth2DN' but instead of 'oberTones' function, it uses volatile function @f::Double -> V.Vector (Double, Double)@ with+-- somewhat sofisticated mechanism to normalize the resulting 'V.Vector' elements @(Double, Double)@. The last one is experimental feature, so+-- it is your responsibility to provide a function so that it does not lead to clipping.+oberSoXSynth2FDN :: (Double -> V.Vector (Double, Double)) -> Double -> Double -> String -> IO ()+oberSoXSynth2FDN f x y zs+ | V.null . convertToProperUkrainian $ zs = oberSoXSynth x+ | otherwise = do+ let note0 = closestNote x+ note1 = dNote (V.unsafeIndex (intervalsFromString zs) 0) note0+ g = V.map (\(noteX, amplX) -> (closestNote noteX, abs (amplX - (fromIntegral . truncate $ amplX)))) . f+ v0 = g note0+ v1 = if isNothing note1 then V.empty+ else g . fromJust $ note1+ oberSoXSynthHelp vec = V.imapM_ (\i (noteN, amplN) -> readProcessWithExitCode (fromJust (showE "sox"))+ ["-r22050", "-n", "test0" ++ show (i + 2) ++ ".wav", "synth", showFFloat (Just 4) y $ show 0,"sine", showFFloat (Just 4) noteN $ show 0,+ "vol", showFFloat (Just 4) amplN $ show 0] "") vec+ oberSoXSynthHelp2 vec = V.imapM_ (\i (noteN, amplN) -> readProcessWithExitCode (fromJust (showE "sox"))+ ["-r22050", "-n", "test1" ++ show (i + 2) ++ ".wav", "synth", showFFloat (Just 4) y $ show 0,"sine", showFFloat (Just 4) noteN $ show 0,+ "vol", showFFloat (Just 4) amplN $ show 0] "") vec+ _ <- readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "testA.wav", "synth", showFFloat (Just 4) y $ show 0,"sine",+ showFFloat (Just 4) note0 $ show 0] ""+ if isNothing note1 then do oberSoXSynthHelp v0+ else do + _ <- readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "testB.wav", "synth", showFFloat (Just 4) y $ show 0,"sine",+ showFFloat (Just 4) (fromJust note1) $ show 0] ""+ oberSoXSynthHelp v0+ oberSoXSynthHelp2 v1+ paths0 <- listDirectory "."+ let paths = sort . filter (isPrefixOf "test") $ paths0+ _ <- readProcessWithExitCode (fromJust (showE "sox")) (["--combine", "mix"] ++ paths ++ ["result.wav","vol","0.3"]) ""+ mapM_ removeFile paths -- | For the given frequency it generates a musical sound with a timbre. The main component of the sound includes the lower pure quint, -- which can be in the same octave or in the one with the number lower by one. Please, check before executing
dobutokO2.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/ name: dobutokO2-version: 0.7.2.1+version: 0.8.0.0 synopsis: A program and a library to create experimental music from a mono audio and a Ukrainian text description: It can also create a timbre for the notes homepage: https://hackage.haskell.org/package/dobutokO2