packages feed

dobutokO2 0.9.1.0 → 0.10.0.0

raw patch · 3 files changed

+195/−12 lines, 3 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ DobutokO.Sound.Functional: oberSoXSynth2FDN_B :: (Double -> Vector (Double, Double)) -> (Double, Double, Double) -> String -> IO ()
+ DobutokO.Sound.Functional: oberSoXSynth2FDN_S :: (Double -> Vector (Double, Double)) -> (Double, Double) -> String -> IO ()
+ DobutokO.Sound.Functional: oberSoXSynth2FDN_Sf :: (Double -> Vector (Double, Double)) -> (Double, Double) -> String -> IO ()
+ DobutokO.Sound.Functional: oberSoXSynth2FDN_Sf3 :: (Double -> Vector (Double, Double)) -> (Double, Double, Double) -> String -> IO ()
- DobutokO.Sound.Functional: oberSoXSynth2FDN :: (Double -> Vector (Double, Double)) -> Double -> Double -> String -> IO ()
+ DobutokO.Sound.Functional: oberSoXSynth2FDN :: (Double -> Vector (Double, Double)) -> (Double, Double) -> String -> IO ()

Files

CHANGELOG.md view
@@ -95,3 +95,8 @@  * Ninth version revised A. Removed two functions from DobutokO.Sound.Functional module because of their inefficient work that leads to very long (possibly infinitely) computation. ++## 0.10.0.0 -- 2020-03-14++* Tenth version. Added again the possibility to filter possible beats. Added new simple functions that are likely to work with previously prepared+Vector (Double, Double) that satisfies some constraints. Some documentation imrovement. Some performance optimizations.
DobutokO/Sound/Functional.hs view
@@ -8,11 +8,18 @@ -- A program and a library to create experimental music -- from a mono audio and a Ukrainian text. +{-# LANGUAGE BangPatterns #-} {-# OPTIONS_GHC -threaded #-}  module DobutokO.Sound.Functional (   -- * Use additional function as a parameter   oberSoXSynth2FDN+  , oberSoXSynth2FDN_B+  -- ** Just simple function application+  , oberSoXSynth2FDN_S+  -- *** With additional filtering+  , oberSoXSynth2FDN_Sf+  , oberSoXSynth2FDN_Sf3 ) where  import Numeric@@ -32,26 +39,197 @@ -- -- Be aware that the result can be rather unpredictable (the program can even obtain segmentation fault) for not very suitable function. -- But for a lot of functions this works well.-oberSoXSynth2FDN :: (Double -> V.Vector (Double, Double)) -> Double -> Double -> String -> IO ()-oberSoXSynth2FDN f x y zs+-- +-- It is recommended to fully compute the \"f\" function before using it in the 'oberSoXSynth2FDN'.+oberSoXSynth2FDN :: (Double -> V.Vector (Double, Double)) -> (Double, Double) -> String -> IO ()+oberSoXSynth2FDN f (x, y) zs  | V.null . convertToProperUkrainian $ zs = oberSoXSynth x  | otherwise = do     let note0 = closestNote (if x /= 0.0 then abs x else V.unsafeIndex notes 0)         note1 = dNote (V.unsafeIndex (intervalsFromString zs) 0) note0-        g0    = V.fromList . nubBy (\(x1,_) (x2,_) -> x1 == x2) . V.toList . V.map (\(noteX, amplX) ->+        g0    = V.fromList . nubBy (\(!x1,_) (!x2,_) -> x1 == x2) . V.toList . V.map (\(noteX, !amplX) ->            if noteX <= 0.0 then (fromIntegral 2 * note0, abs (amplX - (fromIntegral . truncate $ amplX))) else (closestNote noteX,              abs (amplX - (fromIntegral . truncate $ amplX)))) . f-        g k   = V.takeWhile (\w -> compare (fst w) (V.unsafeIndex notes 107) /= GT && compare (snd w) 0.001 == GT) .-                   V.imap (\i (noteY,z0) -> (fromIntegral (i + 1) * (fst . V.unsafeIndex (g0 k) $ 0), z0)) . g0 $ k +        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    = 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+        ts = showFFloat (Just 4) y $ show 0 +        oberSoXSynthHelp vec =+          let l  = V.length vec in V.imapM_ (\i (noteN, amplN) -> readProcessWithExitCode (fromJust (showE "sox"))+            ["-r22050", "-n", "test0" ++ show (i + 2) ++ ".wav", "synth", ts,"sine", showFFloat (Just 4) noteN $ show 0,+              "vol", showFFloat (Just 4) (amplN / fromIntegral l) $ show 0] "") vec+        oberSoXSynthHelp2 vec =+          let l  = V.length vec in V.imapM_ (\i (noteN, amplN) -> readProcessWithExitCode (fromJust (showE "sox"))+            ["-r22050", "-n", "test1" ++ show (i + 2) ++ ".wav", "synth", ts,"sine", showFFloat (Just 4) noteN $ show 0,+              "vol", showFFloat (Just 4) (amplN / fromIntegral l) $ show 0] "") vec+    _ <- 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 -> Vector (Double, Double)@ with+-- somewhat sophisticated 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. In such a case, the result of application of the+-- 'convertToProperUkrainian' to the 'String' parameter must not be 'V.empty'.+--+-- Be aware that the result can be rather unpredictable (the program can even obtain segmentation fault) for not very suitable function.+-- But for a lot of functions this works well.+-- +-- It is recommended to fully compute the \"f\" function before using it in the 'oberSoXSynth2FDN'.+oberSoXSynth2FDN_B :: (Double -> V.Vector (Double, Double)) -> (Double, Double, Double) -> String -> IO ()+oberSoXSynth2FDN_B f (x, y, limB) zs+ | V.null . convertToProperUkrainian $ zs = oberSoXSynth x+ | otherwise = do+    let limA0 = abs ((limB / fromIntegral 10) - (fromIntegral . truncate $ (limB / fromIntegral 10))) * fromIntegral 10+        limA  = if compare limA0 0.1 == LT then 0.1 else limA0+        note0 = closestNote (if x /= 0.0 then abs x else V.unsafeIndex notes 0)+        note1 = dNote (V.unsafeIndex (intervalsFromString zs) 0) note0+        g0    = V.fromList . nubBy (\(!x1,_) (!x2,_) -> compare (abs (x1 - x2)) limA == LT) . V.toList . V.map (\(noteX, !amplX) ->+           if noteX <= 0.0 then (fromIntegral 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    = if isNothing note1 then V.empty+                else g . fromJust $ note1+        ts = showFFloat (Just 4) y $ show 0 +        oberSoXSynthHelp vec =+          let l  = V.length vec in V.imapM_ (\i (noteN, !amplN) -> readProcessWithExitCode (fromJust (showE "sox"))+            ["-r22050", "-n", "test0" ++ show (i + 2) ++ ".wav", "synth", ts,"sine", showFFloat (Just 4) noteN $ show 0,+              "vol", showFFloat (Just 4) (amplN / fromIntegral l) $ show 0] "") vec+        oberSoXSynthHelp2 vec =+          let l  = V.length vec in V.imapM_ (\i (noteN, !amplN) -> readProcessWithExitCode (fromJust (showE "sox"))+            ["-r22050", "-n", "test1" ++ show (i + 2) ++ ".wav", "synth", ts,"sine", showFFloat (Just 4) noteN $ show 0,+              "vol", showFFloat (Just 4) (amplN / fromIntegral l) $ show 0] "") vec+    _ <- readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "testA.wav", "synth", showFFloat (Just 4) y $ show 0,"sine",+       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 'oberSoXSynth2FDN' but it does not make any normalizing transformations with the 'V.Vector' argument. To be used properly, it is needed+-- that every second element in the tuple in the 'V.Vector' argument must be in the range [-1.0..1.0] and every first element must be in between+-- 16.351597831287414 and 7902.132820097988 (Hz).+--+-- Be aware that the result can be rather unpredictable (the program can even obtain segmentation fault) for not very suitable function.+-- But for a lot of functions this works well.+-- +-- It is recommended to fully compute the \"f\" function before using it in the 'oberSoXSynth2FDN_S'.+oberSoXSynth2FDN_S :: (Double -> V.Vector (Double, Double)) -> (Double, Double) -> String -> IO ()+oberSoXSynth2FDN_S f (x, y) zs+ | V.null . convertToProperUkrainian $ zs = oberSoXSynth x+ | otherwise = do+    let note0 = closestNote (if x /= 0.0 then abs x else V.unsafeIndex notes 0)+        note1 = dNote (V.unsafeIndex (intervalsFromString zs) 0) note0+        v0    = f note0+        v1    = if isNothing note1 then V.empty+                else f . fromJust $ note1+        ts = showFFloat (Just 4) y $ show 0 +        oberSoXSynthHelp vec =+          let l  = V.length vec in V.imapM_ (\i (noteN, !amplN) -> readProcessWithExitCode (fromJust (showE "sox"))+            ["-r22050", "-n", "test0" ++ show (i + 2) ++ ".wav", "synth", ts,"sine", showFFloat (Just 4) noteN $ show 0,+              "vol", showFFloat (Just 4) (amplN / fromIntegral l) $ show 0] "") vec+        oberSoXSynthHelp2 vec =+          let l  = V.length vec in V.imapM_ (\i (noteN, !amplN) -> readProcessWithExitCode (fromJust (showE "sox"))+            ["-r22050", "-n", "test1" ++ show (i + 2) ++ ".wav", "synth", ts,"sine", showFFloat (Just 4) noteN $ show 0,+              "vol", showFFloat (Just 4) (amplN / fromIntegral l) $ show 0] "") vec+    _ <- 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 'oberSoXSynth2FDN_S' but additionally the program filters out from the resulting 'V.Vector' after \"f\" application values that are smaller+-- by absolute value than 0.001.+--+-- Be aware that the result can be rather unpredictable (the program can even obtain segmentation fault) for not very suitable function.+-- But for a lot of functions this works well.+-- +-- It is recommended to fully compute the \"f\" function before using it in the 'oberSoXSynth2FDN_S'.+oberSoXSynth2FDN_Sf :: (Double -> V.Vector (Double, Double)) -> (Double, Double) -> String -> IO ()+oberSoXSynth2FDN_Sf f (x, y) zs+ | V.null . convertToProperUkrainian $ zs = oberSoXSynth x+ | otherwise = do+    let note0 = closestNote (if x /= 0.0 then abs x else V.unsafeIndex notes 0)+        note1 = dNote (V.unsafeIndex (intervalsFromString zs) 0) note0+        v0    = V.filter (\(_,!z) -> compare (abs z) 0.001 == GT) . f $ note0+        v1    = if isNothing note1 then V.empty+                else V.filter (\(_,!z) -> compare z 0.001 == GT) . f . fromJust $ note1+        ts = showFFloat (Just 4) y $ show 0 +        oberSoXSynthHelp vec =+          let l  = V.length vec in V.imapM_ (\i (noteN, !amplN) -> readProcessWithExitCode (fromJust (showE "sox"))+            ["-r22050", "-n", "test0" ++ show (i + 2) ++ ".wav", "synth", ts,"sine", showFFloat (Just 4) noteN $ show 0,+              "vol", showFFloat (Just 4) (amplN / fromIntegral l) $ show 0] "") vec+        oberSoXSynthHelp2 vec =+          let l  = V.length vec in V.imapM_ (\i (noteN, !amplN) -> readProcessWithExitCode (fromJust (showE "sox"))+            ["-r22050", "-n", "test1" ++ show (i + 2) ++ ".wav", "synth", ts,"sine", showFFloat (Just 4) noteN $ show 0,+              "vol", showFFloat (Just 4) (amplN / fromIntegral l) $ show 0] "") vec+    _ <- 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 'oberSoXSynth2FDN_S' but additionally the program filters out from the resulting 'V.Vector' after \"f\" application values that are smaller+-- than the third 'Double' parameter by an absolute value in the triple of @Double@'s. +--+-- Be aware that the result can be rather unpredictable (the program can even obtain segmentation fault) for not very suitable function.+-- But for a lot of functions this works well.+-- +-- It is recommended to fully compute the \"f\" function before using it in the 'oberSoXSynth2FDN_S'.+oberSoXSynth2FDN_Sf3 :: (Double -> V.Vector (Double, Double)) -> (Double, Double, Double) -> String -> IO ()+oberSoXSynth2FDN_Sf3 f (x, y, t0) zs+ | V.null . convertToProperUkrainian $ zs = oberSoXSynth x+ | otherwise = do+    let note0 = closestNote (if x /= 0.0 then abs x else V.unsafeIndex notes 0)+        note1 = dNote (V.unsafeIndex (intervalsFromString zs) 0) note0+        v0    = V.filter (\(_,!z) -> compare (abs z) t0 == GT) . f $ note0+        v1    = if isNothing note1 then V.empty+                else V.filter (\(_,!z) -> compare (abs z) t0 == GT) . f . fromJust $ note1+        ts = showFFloat (Just 4) y $ show 0 +        oberSoXSynthHelp vec =+          let l  = V.length vec in V.imapM_ (\i (noteN, !amplN) -> readProcessWithExitCode (fromJust (showE "sox"))+            ["-r22050", "-n", "test0" ++ show (i + 2) ++ ".wav", "synth", ts,"sine", showFFloat (Just 4) noteN $ show 0,+              "vol", showFFloat (Just 4) (amplN / fromIntegral l) $ show 0] "") vec+        oberSoXSynthHelp2 vec =+          let l  = V.length vec in V.imapM_ (\i (noteN, !amplN) -> readProcessWithExitCode (fromJust (showE "sox"))+            ["-r22050", "-n", "test1" ++ show (i + 2) ++ ".wav", "synth", ts,"sine", showFFloat (Just 4) noteN $ show 0,+              "vol", showFFloat (Just 4) (amplN / fromIntegral l) $ show 0] "") vec     _ <- readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "testA.wav", "synth", showFFloat (Just 4) y $ show 0,"sine",        showFFloat (Just 4) note0 $ show 0] ""     if isNothing note1 then do
dobutokO2.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/  name:                dobutokO2-version:             0.9.1.0+version:             0.10.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