dobutokO2 0.38.1.0 → 0.39.0.0
raw patch · 6 files changed
+422/−217 lines, 6 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- DobutokO.Sound.Executable: h1 :: (Double -> OvertonesO) -> (Double, Double) -> Int -> IO ()
- DobutokO.Sound.Executable: h2 :: OvertonesO -> (Double, Double) -> Int -> Int -> Double -> IO ()
- DobutokO.Sound.Executable: soundGen3G :: FilePath -> (Double -> OvertonesO) -> Double -> String -> ((Double, Double) -> Double -> (Double -> OvertonesO) -> OvertonesO) -> ((Double, Double) -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (Double -> OvertonesO) -> IO ()
- DobutokO.Sound.Executable: soundGen3GMN :: Int64 -> Int64 -> FilePath -> (Double -> OvertonesO) -> Double -> String -> ((Double, Double) -> Double -> (Double -> OvertonesO) -> OvertonesO) -> ((Double, Double) -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (Double -> OvertonesO) -> IO ()
- DobutokO.Sound.Executable: soundGen3G_O :: Int -> Int -> Double -> FilePath -> (Double -> OvertonesO) -> Double -> String -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (Int -> OvertonesO) -> (OvertonesO -> OvertonesO) -> (Double -> OvertonesO) -> IO ()
- DobutokO.Sound.Executable: soundGen3G_O2 :: ((Double -> OvertonesO, Int -> Double -> OvertonesO, Int -> Double -> OvertonesO) -> Vector (Int, Int) -> Vector (Double, Double -> OvertonesO)) -> Int -> Int -> Double -> FilePath -> (Double -> OvertonesO) -> Double -> String -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (Int -> OvertonesO) -> (OvertonesO -> OvertonesO) -> (Double -> OvertonesO) -> IO ()
- DobutokO.Sound.Executable: soundGen3G_O2G :: ((Vector (Double -> OvertonesO), Vector (Int -> Double -> OvertonesO), Vector (Int -> Double -> OvertonesO)) -> Vector (Int, Int) -> Vector (Double, Double -> OvertonesO)) -> Vector (Double -> OvertonesO) -> Vector (Int -> Double -> OvertonesO) -> Vector (Int -> Double -> OvertonesO) -> Int -> Int -> Double -> FilePath -> (Double -> OvertonesO) -> Double -> String -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (Int -> OvertonesO) -> (Double -> OvertonesO) -> IO ()
- DobutokO.Sound.Executable: soundGen3G_O2GMN :: Int64 -> Int64 -> ((Vector (Double -> OvertonesO), Vector (Int -> Double -> OvertonesO), Vector (Int -> Double -> OvertonesO)) -> Vector (Int, Int) -> Vector (Double, Double -> OvertonesO)) -> Vector (Double -> OvertonesO) -> Vector (Int -> Double -> OvertonesO) -> Vector (Int -> Double -> OvertonesO) -> Int -> Int -> Double -> FilePath -> (Double -> OvertonesO) -> Double -> String -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (Int -> OvertonesO) -> (Double -> OvertonesO) -> IO ()
- DobutokO.Sound.Executable: soundGen3G_O2MN :: Int64 -> Int64 -> ((Double -> OvertonesO, Int -> Double -> OvertonesO, Int -> Double -> OvertonesO) -> Vector (Int, Int) -> Vector (Double, Double -> OvertonesO)) -> Int -> Int -> Double -> FilePath -> (Double -> OvertonesO) -> Double -> String -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (Int -> OvertonesO) -> (OvertonesO -> OvertonesO) -> (Double -> OvertonesO) -> IO ()
- DobutokO.Sound.Executable: soundGen3G_OMN :: Int64 -> Int64 -> Int -> Int -> Double -> FilePath -> (Double -> OvertonesO) -> Double -> String -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (Int -> OvertonesO) -> (OvertonesO -> OvertonesO) -> (Double -> OvertonesO) -> IO ()
- DobutokO.Sound.Executable: testSoundGen2G :: FilePath -> (Double -> OvertonesO) -> Double -> String -> IO ()
- DobutokO.Sound.Executable: testSoundGen2GMN :: Int64 -> Int64 -> FilePath -> (Double -> OvertonesO) -> Double -> String -> IO ()
+ DobutokO.Sound.Functional: h1 :: (Double -> OvertonesO) -> (Double, Double) -> Int -> IO ()
+ DobutokO.Sound.Functional: h2 :: OvertonesO -> (Double, Double) -> Int -> Int -> Double -> IO ()
+ DobutokO.Sound.Functional: h2Params :: OvertonesO -> (Double, Double) -> Params -> Double -> IO ()
+ DobutokO.Sound.Functional: overMeloPar :: (Double -> OvertonesO) -> (Double -> Double) -> Params -> Double -> Double -> Double -> IO ()
+ DobutokO.Sound.Functional: soundGen3G :: FilePath -> (Double -> OvertonesO) -> Double -> String -> ((Double, Double) -> Double -> (Double -> OvertonesO) -> OvertonesO) -> ((Double, Double) -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (Double -> OvertonesO) -> IO ()
+ DobutokO.Sound.Functional: soundGen3GMN :: Int64 -> Int64 -> FilePath -> (Double -> OvertonesO) -> Double -> String -> ((Double, Double) -> Double -> (Double -> OvertonesO) -> OvertonesO) -> ((Double, Double) -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (Double -> OvertonesO) -> IO ()
+ DobutokO.Sound.Functional: soundGen3G_O :: Int -> Int -> Double -> FilePath -> (Double -> OvertonesO) -> Double -> String -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (Int -> OvertonesO) -> (OvertonesO -> OvertonesO) -> (Double -> OvertonesO) -> IO ()
+ DobutokO.Sound.Functional: soundGen3G_O2 :: ((Double -> OvertonesO, Int -> Double -> OvertonesO, Int -> Double -> OvertonesO) -> Vector (Int, Int) -> Vector (Double, Double -> OvertonesO)) -> Int -> Int -> Double -> FilePath -> (Double -> OvertonesO) -> Double -> String -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (Int -> OvertonesO) -> (OvertonesO -> OvertonesO) -> (Double -> OvertonesO) -> IO ()
+ DobutokO.Sound.Functional: soundGen3G_O2G :: ((Vector (Double -> OvertonesO), Vector (Int -> Double -> OvertonesO), Vector (Int -> Double -> OvertonesO)) -> Vector (Int, Int) -> Vector (Double, Double -> OvertonesO)) -> Vector (Double -> OvertonesO) -> Vector (Int -> Double -> OvertonesO) -> Vector (Int -> Double -> OvertonesO) -> Int -> Int -> Double -> FilePath -> (Double -> OvertonesO) -> Double -> String -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (Int -> OvertonesO) -> (Double -> OvertonesO) -> IO ()
+ DobutokO.Sound.Functional: soundGen3G_O2GMN :: Int64 -> Int64 -> ((Vector (Double -> OvertonesO), Vector (Int -> Double -> OvertonesO), Vector (Int -> Double -> OvertonesO)) -> Vector (Int, Int) -> Vector (Double, Double -> OvertonesO)) -> Vector (Double -> OvertonesO) -> Vector (Int -> Double -> OvertonesO) -> Vector (Int -> Double -> OvertonesO) -> Int -> Int -> Double -> FilePath -> (Double -> OvertonesO) -> Double -> String -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (Int -> OvertonesO) -> (Double -> OvertonesO) -> IO ()
+ DobutokO.Sound.Functional: soundGen3G_O2GMNPar :: Int64 -> Int64 -> ((Vector (Double -> OvertonesO), Vector (Int -> Double -> OvertonesO), Vector (Int -> Double -> OvertonesO)) -> Vector (Int, Int) -> Vector (Double, Double -> OvertonesO)) -> Vector (Double -> OvertonesO) -> Vector (Int -> Double -> OvertonesO) -> Vector (Int -> Double -> OvertonesO) -> Params -> Double -> FilePath -> (Double -> OvertonesO) -> Double -> String -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (Int -> OvertonesO) -> (Double -> OvertonesO) -> IO ()
+ DobutokO.Sound.Functional: soundGen3G_O2GPar :: ((Vector (Double -> OvertonesO), Vector (Int -> Double -> OvertonesO), Vector (Int -> Double -> OvertonesO)) -> Vector (Int, Int) -> Vector (Double, Double -> OvertonesO)) -> Vector (Double -> OvertonesO) -> Vector (Int -> Double -> OvertonesO) -> Vector (Int -> Double -> OvertonesO) -> Params -> Double -> FilePath -> (Double -> OvertonesO) -> Double -> String -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (Int -> OvertonesO) -> (Double -> OvertonesO) -> IO ()
+ DobutokO.Sound.Functional: soundGen3G_O2MN :: Int64 -> Int64 -> ((Double -> OvertonesO, Int -> Double -> OvertonesO, Int -> Double -> OvertonesO) -> Vector (Int, Int) -> Vector (Double, Double -> OvertonesO)) -> Int -> Int -> Double -> FilePath -> (Double -> OvertonesO) -> Double -> String -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (Int -> OvertonesO) -> (OvertonesO -> OvertonesO) -> (Double -> OvertonesO) -> IO ()
+ DobutokO.Sound.Functional: soundGen3G_O2MNPar :: Int64 -> Int64 -> ((Double -> OvertonesO, Int -> Double -> OvertonesO, Int -> Double -> OvertonesO) -> Vector (Int, Int) -> Vector (Double, Double -> OvertonesO)) -> Params -> Double -> FilePath -> (Double -> OvertonesO) -> Double -> String -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (Int -> OvertonesO) -> (OvertonesO -> OvertonesO) -> (Double -> OvertonesO) -> IO ()
+ DobutokO.Sound.Functional: soundGen3G_O2Par :: ((Double -> OvertonesO, Int -> Double -> OvertonesO, Int -> Double -> OvertonesO) -> Vector (Int, Int) -> Vector (Double, Double -> OvertonesO)) -> Params -> Double -> FilePath -> (Double -> OvertonesO) -> Double -> String -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (Int -> OvertonesO) -> (OvertonesO -> OvertonesO) -> (Double -> OvertonesO) -> IO ()
+ DobutokO.Sound.Functional: soundGen3G_OMN :: Int64 -> Int64 -> Int -> Int -> Double -> FilePath -> (Double -> OvertonesO) -> Double -> String -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (Int -> OvertonesO) -> (OvertonesO -> OvertonesO) -> (Double -> OvertonesO) -> IO ()
+ DobutokO.Sound.Functional: soundGen3G_OMNPar :: Int64 -> Int64 -> Params -> Double -> FilePath -> (Double -> OvertonesO) -> Double -> String -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (Int -> OvertonesO) -> (OvertonesO -> OvertonesO) -> (Double -> OvertonesO) -> IO ()
+ DobutokO.Sound.Functional: soundGen3G_OPar :: Params -> Double -> FilePath -> (Double -> OvertonesO) -> Double -> String -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (Int -> OvertonesO) -> (OvertonesO -> OvertonesO) -> (Double -> OvertonesO) -> IO ()
+ DobutokO.Sound.Functional: testSoundGen2G :: FilePath -> (Double -> OvertonesO) -> Double -> String -> IO ()
+ DobutokO.Sound.Functional: testSoundGen2GMN :: Int64 -> Int64 -> FilePath -> (Double -> OvertonesO) -> Double -> String -> IO ()
+ DobutokO.Sound.IntermediateF: soxRE1 :: Int -> Int -> Int -> Int -> Int -> Int -> FilePath -> IO ()
+ DobutokO.Sound.IntermediateF: soxREA1 :: Int -> Int -> Int -> Int -> Int -> Int -> Int -> String -> String -> FilePath -> IO ()
+ DobutokO.Sound.IntermediateF: soxREw1 :: Int -> Int -> Int -> Int -> Int -> Int -> FilePath -> IO ()
Files
- CHANGELOG.md +6/−0
- DobutokO/Sound/Executable.hs +0/−215
- DobutokO/Sound/Functional.hs +374/−0
- DobutokO/Sound/IntermediateF.hs +35/−1
- README.markdown +6/−0
- dobutokO2.cabal +1/−1
CHANGELOG.md view
@@ -357,3 +357,9 @@ ## 0.38.1.0 -- 2020-05-04 * Thirty-eigth version revised A. Fixed issue with being not exported constructors in a Params datatype. ++## 0.39.0.0 -- 2020-05-07++* Thirty-ninth version. Added new functions with Params to DobutokO.Sound.Executable module. Changed the structure of the modules DobutokO.Sound.Functional +and DobutokO.Sound.Executable into more logical one. Added three new functions for special SoX effects to the DobutokO.Sound.IntermediateF module. +Some minor documentation improvements.
DobutokO/Sound/Executable.hs view
@@ -17,20 +17,6 @@ , recAndProcess , dobutokO2H7 , dobutokO2H9- -- * Library functions- , testSoundGen2G- , soundGen3G- , soundGen3G_O- , soundGen3G_O2- , soundGen3G_O2G- -- ** With MN control- , testSoundGen2GMN- , soundGen3GMN- , soundGen3G_OMN- , soundGen3G_O2MN- , soundGen3G_O2GMN- , h1- , h2 ) where import Control.Monad (void)@@ -53,8 +39,6 @@ import DobutokO.Sound.IntermediateF import DobutokO.Sound.ParseList (parseStoLInts) import DobutokO.Sound.Functional-import DobutokO.Sound.Keyboard-import GHC.Int (Int64) -- | Function that actually makes processing in the @dobutokO2@ executable. Please, check before executing -- whether there is no \"x.wav\", \"test*\", \"result*\" and \"end*\" files in the current directory, because they can be overwritten.@@ -642,202 +626,3 @@ ---------------------------------------------------------------------------------------------- --- | Tesing variant of the 'soundGen3G' with predefined three last functional arguments.-testSoundGen2G :: FilePath -> (Double -> OvertonesO) -> Double -> String -> IO ()- ---------------------- - -- f-testSoundGen2G = testSoundGen2GMN (-1) (-1)---- | Tesing variant of the 'soundGen3GMN' with predefined three last functional arguments.-testSoundGen2GMN :: Int64 -> Int64 -> FilePath -> (Double -> OvertonesO) -> Double -> String -> IO ()- ---------------------- - -- f-testSoundGen2GMN m n1 file f y zs = do- vecA0 <- fmap (V.map (`quotRem` 108)) ((if m == (-1) && n1 == (-1) then readFileDoubles else readFileDoublesMN m n1) file) -- >>= print- let n = V.length vecA0- freq0 j = V.unsafeIndex notes (snd . V.unsafeIndex vecA0 $ j `rem` n)- f0 t = V.fromList [(0.05763181818181818 * t, 0.3598),(1.112159090909091 * t, 0.4588962),(2 * t, 0.6853),(3 * t, 0.268),(4 * t, 0.6823),(5 * t, 0.53)]- fA1 j = fAddFElem (freq0 (j + 1),0.5) f0 gAdd04 - fR1 j = fRemoveFElem (freq0 (j + 1),0.5) f0 gRem03- vecB = V.imap (\j r -> (V.unsafeIndex notes (snd r),- case fst r of- 0 -> f0- 1 -> fA1 j- 2 -> fA1 j- 3 -> fA1 j- 4 -> fA1 j- _ -> fR1 j)) vecA0- 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---- | Generates a sequence of sounds with changing timbre. Uses several functions as parameters. -soundGen3G :: FilePath -> (Double -> OvertonesO) -> Double -> String -> ((Double,Double) -> Double -> (Double -> OvertonesO) -> OvertonesO) - -> ((Double,Double) -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (Double -> OvertonesO) -> IO ()-soundGen3G = soundGen3GMN (-1) (-1)---- | Generates a sequence of sounds with changing timbre. Uses several functions as parameters. To specify how many sounds the resulting files --- will provide, you use first two 'Int64' arguments, the first of which is a number of dropped elements for 'readFileDoubles' and the second one --- is a number of produced sounds (and, respectively, number of taken elements).-soundGen3GMN :: Int64 -> Int64 -> FilePath -> (Double -> OvertonesO) -> Double -> String -> ((Double,Double) -> Double -> (Double -> OvertonesO) -> OvertonesO) - -> ((Double,Double) -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (Double -> OvertonesO) -> IO ()-soundGen3GMN m n1 file f y zs gAdd gRem f0 = do- vecA0 <- fmap (V.map (`quotRem` 108)) ((if m == (-1) && n1 == (-1) then readFileDoubles else readFileDoublesMN m n1) file) -- >>= print- let n = V.length vecA0- freq0 j = V.unsafeIndex notes (snd . V.unsafeIndex vecA0 $ j `rem` n)- fA1 j = fAddFElem (freq0 (j + 1),0.5) f0 gAdd- fR1 j = fRemoveFElem (freq0 (j + 1),0.5) f0 gRem- vecB = V.imap (\j r -> (V.unsafeIndex notes (snd r),- case fst r of- 0 -> f0- 1 -> fA1 j- 2 -> fA1 j- 3 -> fA1 j- 4 -> fA1 j- _ -> fR1 j)) vecA0- zeroN = numVZeroesPre vecB- 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---- | Generates a sequence of sounds with changing timbre. Uses several functions as parameters. Unlike the 'soundGen3G', the last two --- functions as arguments for their first argument have not ('Double','Double'), but 'V.Vector' of them so are applied to 'OvertonesO'. To --- provide a generalized functionality, it uses two additional functions @freq0 :: Int -> OvertonesO@ and @proj :: OvertonesO -> OvertonesO@ --- to define the first element to which are applied @gAdds@ and @gRems@ and the way to obtain a internal 'OvertonesO'.--- Besides, it lifts notes into specified with the first two 'Int' arguments enku (see 'liftInEnku'). --- The 'Double' argument is a average duration of the sounds.-soundGen3G_O :: Int -> Int -> Double -> FilePath -> (Double -> OvertonesO) -> Double -> String -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) - -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (Int -> OvertonesO) -> (OvertonesO -> OvertonesO) -> - (Double -> OvertonesO) -> IO ()-soundGen3G_O = soundGen3G_OMN (-1) (-1)---- | Generates a sequence of sounds with changing timbre. Uses several functions as parameters. To specify how many sounds the resulting files --- will provide, you use first two 'Int64' arguments, the first of which is a number of dropped elements for 'readFileDoubles' and the second one --- is a number of produced sounds (and, respectively, number of taken elements).-soundGen3G_OMN :: Int64 -> Int64 -> Int -> Int -> Double -> FilePath -> (Double -> OvertonesO) -> Double -> String -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) - -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (Int -> OvertonesO) -> (OvertonesO -> OvertonesO) -> - (Double -> OvertonesO) -> IO ()-soundGen3G_OMN m1 n1 m ku freq1 file f y zs gAdds gRems freq0 proj f0 = do- vecA0 <- fmap (V.map (`quotRem` 108)) ((if m1 == (-1) && n1 == (-1) then readFileDoubles else readFileDoublesMN m1 n1) file) -- >>= print- let n = V.length vecA0- fA1 j = fAddFElems (proj . freq0 $ j) f0 gAdds- fR1 j = fRemoveFElems (proj . freq0 $ j) f0 gRems- vecB = V.imap (\j r -> (V.unsafeIndex notes (snd r),- case fst r of- 0 -> f0- 1 -> fA1 j- 2 -> fA1 j- 3 -> fA1 j- 4 -> fA1 j- _ -> fR1 j)) vecA0- zeroN = numVZeroesPre vecB- 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 ---- | Generates a sequence of sounds with changing timbre. Is a generalized version of the 'soundGen3G_O', instead of predefined conversion function --- inside, it uses a user-defined one. --- --- > soundGen3G_O = soundGen3G_O2 --- with the first argument --- --- > conversionFII (f0,fA1,fR1) = imap (\j r -> (unsafeIndex notes (snd r),--- --- > case fst r of--- --- > 0 -> f0--- --- > 1 -> fA1 j--- --- > 2 -> fA1 j--- --- > 3 -> fA1 j--- --- > 4 -> fA1 j--- --- > _ -> fR1 j))--- --- -soundGen3G_O2 :: ((Double -> OvertonesO,Int -> Double -> OvertonesO,Int -> Double -> OvertonesO) -> V.Vector (Int,Int) -> - V.Vector (Double,Double -> OvertonesO)) -> Int -> Int -> Double -> FilePath -> (Double -> OvertonesO) -> Double -> String -> - (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> - (Int -> OvertonesO) -> (OvertonesO -> OvertonesO) -> (Double -> OvertonesO) -> IO ()-soundGen3G_O2 = soundGen3G_O2MN (-1) (-1)---- | Generates a sequence of sounds with changing timbre. Is a generalized version of the 'soundGen3G_O2'. To specify how many sounds the resulting files --- will provide, you use first two 'Int64' arguments, the first of which is a number of dropped elements for 'readFileDoubles' and the second one --- is a number of produced sounds (and, respectively, number of taken elements).-soundGen3G_O2MN :: Int64 -> Int64 -> ((Double -> OvertonesO,Int -> Double -> OvertonesO,Int -> Double -> OvertonesO) -> V.Vector (Int,Int) -> - V.Vector (Double,Double -> OvertonesO)) -> Int -> Int -> Double -> FilePath -> (Double -> OvertonesO) -> Double -> String -> - (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> - (Int -> OvertonesO) -> (OvertonesO -> OvertonesO) -> (Double -> OvertonesO) -> IO ()-soundGen3G_O2MN m1 n1 conversionFII m ku freq1 file f y zs gAdds gRems freq0 proj f0 = do- vecA0 <- fmap (V.map (`quotRem` 108)) ((if m1 == (-1) && n1 == (-1) then readFileDoubles else readFileDoublesMN m1 n1) file) -- >>= print- let n = V.length vecA0- fA1 j = fAddFElems (proj . freq0 $ j) f0 gAdds- fR1 j = fRemoveFElems (proj . freq0 $ j) f0 gRems- vecB = conversionFII (f0,fA1,fR1) vecA0- zeroN = numVZeroesPre vecB- 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 ---- | Generates a sequence of sounds with changing timbre. Is a generalized version of the 'soundGen3G_O2', but for the conversion function conversionFII as its --- tuple first argument uses not the tuple of the three functions, but a tuple of three 'V.Vector' of functions of the respective types, that allows to --- specify more comlex behaviour and different variants inside the function itself, not its inner function parts. 'V.Vector' as a data type is used --- instead of more common list because it has similar functionality and besides provides easier and quicker access to its elements. So these are the --- following vectors of functions: @vf :: Vector (Double -> OvertonesO)@ (no changing a function for timbre generation), --- @vfA :: Vector (Int -> Double -> OvertonesO)@ (for \"adding\" overtones to the function for timbre generation), --- and @vfR :: Vector (Int -> Double -> OvertonesO@ (for \"removing\" overtones from the function for timbre generation).--- -soundGen3G_O2G :: ((V.Vector (Double -> OvertonesO),V.Vector (Int -> Double -> OvertonesO),V.Vector (Int -> Double -> OvertonesO)) -> V.Vector (Int,Int) -> - V.Vector (Double,Double -> OvertonesO)) -> V.Vector (Double -> OvertonesO) -> V.Vector (Int -> Double -> OvertonesO) -> V.Vector (Int -> Double -> OvertonesO) -> - Int -> Int -> Double -> FilePath -> (Double -> OvertonesO) -> Double -> String -> - (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> - (Int -> OvertonesO) -> (Double -> OvertonesO) -> IO ()-soundGen3G_O2G = soundGen3G_O2GMN (-1) (-1)---- | Generates a sequence of sounds with changing timbre. Is a generalized version of the 'soundGen3G_O2G'. To specify how many sounds the resulting files --- will provide, you use first two 'Int64' arguments, the first of which is a number of dropped elements for 'readFileDoubles' and the second one --- is a number of produced sounds (and, respectively, number of taken elements).-soundGen3G_O2GMN :: Int64 -> Int64 -> ((V.Vector (Double -> OvertonesO),V.Vector (Int -> Double -> OvertonesO),V.Vector (Int -> Double -> OvertonesO)) -> V.Vector (Int,Int) -> - V.Vector (Double,Double -> OvertonesO)) -> V.Vector (Double -> OvertonesO) -> V.Vector (Int -> Double -> OvertonesO) -> V.Vector (Int -> Double -> OvertonesO) -> - Int -> Int -> Double -> FilePath -> (Double -> OvertonesO) -> Double -> String -> - (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> - (Int -> OvertonesO) -> (Double -> OvertonesO) -> IO ()-soundGen3G_O2GMN m1 n1 conversionFII vf vfA vfR m ku freq1 file f y zs gAdds gRems freq0 f0 = do- 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- zeroN = numVZeroesPre vecB- 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 ---- | For the given parameters generates a single sound with overtones.-h1 :: (Double -> OvertonesO) -> (Double, Double) -> Int -> IO ()-h1 f (x, y) j = do- let note0 = closestNote (if x /= 0.0 then abs x else V.unsafeIndex notes 0)- v0 = f note0- ts = showFFloat (Just 4) (abs y) ""- (code,_,herr) <- readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "testA.wav", "synth", ts,"sine",showFFloat Nothing note0 ""] ""- print herr- partialTest_k v0 0 ts- mixTest---- | For the given parameters generates a single sound with overtones. Unlike the 'h1' function, it lifts into specified by 'Int' arguments enku --- (see 'liftInEnku') the frequency.-h2 :: OvertonesO -> (Double, Double) -> Int -> Int -> Double -> IO ()-h2 v (x, y) m ku freq1 = do- let note0 = fromMaybe freq1 . liftInEnku m ku . closestNote $ (if x /= 0.0 then abs x else V.unsafeIndex notes 0)- ts = showFFloat (Just 4) (abs y) ""- (code,_,herr) <- readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "testA.wav", "synth", ts,"sine",showFFloat Nothing note0 ""] ""- print herr- partialTest_k v 0 ts- mixTest
DobutokO/Sound/Functional.hs view
@@ -213,6 +213,30 @@ , overSoXSynthGen2FDN_SfPar , overSoXSynthGen2FDN_Sf3GPar , overSoXSynthGen2FDN_Sf3G2GPar + -- * Another way to generalize the simple functions+ , testSoundGen2G+ , soundGen3G+ , soundGen3G_O+ , soundGen3G_O2+ , soundGen3G_O2G+ -- ** With MN control+ , testSoundGen2GMN+ , soundGen3GMN+ , soundGen3G_OMN+ , soundGen3G_O2MN+ , soundGen3G_O2GMN+ , h1+ , h2+ -- ** New with Params control+ , soundGen3G_OPar+ , soundGen3G_O2Par+ , soundGen3G_O2GPar+ , soundGen3G_OMNPar+ , soundGen3G_O2MNPar+ , soundGen3G_O2GMNPar+ , h2Params+ -- * Creating melody from overtones+ , overMeloPar ) where import Text.Read (readMaybe)@@ -230,7 +254,10 @@ import SoXBasics (durationA,upperBnd,selMaxAbs) import MMSyn7.Syllable import DobutokO.Sound.IntermediateF+import GHC.Int (Int64)+import DobutokO.Sound.Keyboard + -- | Representation of the scales and modes for the notes. Can be extended further, but for a lot of situations the following realization is sufficient. -- See, for example, 'filterInParams' and so on. 'String' is (are) used as a general classification name, for some of them there are provided two -- 'String' to classify. Lists are used to specify remainders in some meaning. See also, 'liftInParams' and 'toneE' ('toneD') functions, 'elemP' and @@ -2045,4 +2072,351 @@ -- | A way to show not the (somewhat algebraic) structure of the 'Params' (as the usual 'show' does), but the contained frequencies in it. showD :: Params -> String showD = show . filterInParams ++------------------------------------------------------------------------------------------------++-- | Tesing variant of the 'soundGen3G' with predefined three last functional arguments.+testSoundGen2G :: FilePath -> (Double -> OvertonesO) -> Double -> String -> IO ()+ ---------------------- + -- f+testSoundGen2G = testSoundGen2GMN (-1) (-1)++-- | Tesing variant of the 'soundGen3GMN' with predefined three last functional arguments.+testSoundGen2GMN :: Int64 -> Int64 -> FilePath -> (Double -> OvertonesO) -> Double -> String -> IO ()+ ---------------------- + -- f+testSoundGen2GMN m n1 file f y zs = do+ vecA0 <- fmap (V.map (`quotRem` 108)) ((if m == (-1) && n1 == (-1) then readFileDoubles else readFileDoublesMN m n1) file) -- >>= print+ let n = V.length vecA0+ freq0 j = V.unsafeIndex notes (snd . V.unsafeIndex vecA0 $ j `rem` n)+ f0 t = V.fromList [(0.05763181818181818 * t, 0.3598),(1.112159090909091 * t, 0.4588962),(2 * t, 0.6853),(3 * t, 0.268),(4 * t, 0.6823),(5 * t, 0.53)]+ fA1 j = fAddFElem (freq0 (j + 1),0.5) f0 gAdd04 + fR1 j = fRemoveFElem (freq0 (j + 1),0.5) f0 gRem03+ vecB = V.imap (\j r -> (V.unsafeIndex notes (snd r),+ case fst r of+ 0 -> f0+ 1 -> fA1 j+ 2 -> fA1 j+ 3 -> fA1 j+ 4 -> fA1 j+ _ -> fR1 j)) vecA0+ 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++-- | Generates a sequence of sounds with changing timbre. Uses several functions as parameters. +soundGen3G :: FilePath -> (Double -> OvertonesO) -> Double -> String -> ((Double,Double) -> Double -> (Double -> OvertonesO) -> OvertonesO) + -> ((Double,Double) -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (Double -> OvertonesO) -> IO ()+soundGen3G = soundGen3GMN (-1) (-1)++-- | Generates a sequence of sounds with changing timbre. Uses several functions as parameters. To specify how many sounds the resulting files +-- will provide, you use first two 'Int64' arguments, the first of which is a number of dropped elements for 'readFileDoubles' and the second one +-- is a number of produced sounds (and, respectively, number of taken elements).+soundGen3GMN :: Int64 -> Int64 -> FilePath -> (Double -> OvertonesO) -> Double -> String -> ((Double,Double) -> Double -> (Double -> OvertonesO) -> OvertonesO) + -> ((Double,Double) -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (Double -> OvertonesO) -> IO ()+soundGen3GMN m n1 file f y zs gAdd gRem f0 = do+ vecA0 <- fmap (V.map (`quotRem` 108)) ((if m == (-1) && n1 == (-1) then readFileDoubles else readFileDoublesMN m n1) file) -- >>= print+ let n = V.length vecA0+ freq0 j = V.unsafeIndex notes (snd . V.unsafeIndex vecA0 $ j `rem` n)+ fA1 j = fAddFElem (freq0 (j + 1),0.5) f0 gAdd+ fR1 j = fRemoveFElem (freq0 (j + 1),0.5) f0 gRem+ vecB = V.imap (\j r -> (V.unsafeIndex notes (snd r),+ case fst r of+ 0 -> f0+ 1 -> fA1 j+ 2 -> fA1 j+ 3 -> fA1 j+ 4 -> fA1 j+ _ -> fR1 j)) vecA0+ zeroN = numVZeroesPre vecB+ 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++-- | Generates a sequence of sounds with changing timbre. Uses several functions as parameters. Unlike the 'soundGen3G', the last two +-- functions as arguments for their first argument have not ('Double','Double'), but 'V.Vector' of them so are applied to 'OvertonesO'. To +-- provide a generalized functionality, it uses two additional functions @freq0 :: Int -> OvertonesO@ and @proj :: OvertonesO -> OvertonesO@ +-- to define the first element to which are applied @gAdds@ and @gRems@ and the way to obtain a internal 'OvertonesO'.+-- Besides, it lifts notes into specified with the first two 'Int' arguments enku (see 'liftInEnku'). +-- The 'Double' argument is a average duration of the sounds.+soundGen3G_O :: Int -> Int -> Double -> FilePath -> (Double -> OvertonesO) -> Double -> String -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) + -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (Int -> OvertonesO) -> (OvertonesO -> OvertonesO) -> + (Double -> OvertonesO) -> IO ()+soundGen3G_O = soundGen3G_OMN (-1) (-1)++-- | Generalized version of the 'soundGen3G_O' where instead of lifting with 'liftInEnku' 'liftInParams' is used. It allows e. g. to +-- use some tonality. For more information, please, refer to 'filterInParams'.+soundGen3G_OPar :: Params -> Double -> FilePath -> (Double -> OvertonesO) -> Double -> String -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) + -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (Int -> OvertonesO) -> (OvertonesO -> OvertonesO) -> + (Double -> OvertonesO) -> IO ()+soundGen3G_OPar = soundGen3G_OMNPar (-1) (-1)++-- | Generates a sequence of sounds with changing timbre. Uses several functions as parameters. To specify how many sounds the resulting files +-- will provide, you use first two 'Int64' arguments, the first of which is a number of dropped elements for 'readFileDoubles' and the second one +-- is a number of produced sounds (and, respectively, number of taken elements).+soundGen3G_OMN :: Int64 -> Int64 -> Int -> Int -> Double -> FilePath -> (Double -> OvertonesO) -> Double -> String -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) + -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (Int -> OvertonesO) -> (OvertonesO -> OvertonesO) -> + (Double -> OvertonesO) -> IO ()+soundGen3G_OMN m1 n1 m ku freq1 file f y zs gAdds gRems freq0 proj f0 = do+ vecA0 <- fmap (V.map (`quotRem` 108)) ((if m1 == (-1) && n1 == (-1) then readFileDoubles else readFileDoublesMN m1 n1) file) -- >>= print+ let n = V.length vecA0+ fA1 j = fAddFElems (proj . freq0 $ j) f0 gAdds+ fR1 j = fRemoveFElems (proj . freq0 $ j) f0 gRems+ vecB = V.imap (\j r -> (V.unsafeIndex notes (snd r),+ case fst r of+ 0 -> f0+ 1 -> fA1 j+ 2 -> fA1 j+ 3 -> fA1 j+ 4 -> fA1 j+ _ -> fR1 j)) vecA0+ zeroN = numVZeroesPre vecB+ 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 ++-- | Generalized version of the 'soundGen3G_OMN' where instead of lifting with 'liftInEnku' 'liftInParams' is used. It allows e. g. to +-- use some tonality. For more information, please, refer to 'filterInParams'.+soundGen3G_OMNPar :: Int64 -> Int64 -> Params -> Double -> FilePath -> (Double -> OvertonesO) -> Double -> String -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) + -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (Int -> OvertonesO) -> (OvertonesO -> OvertonesO) -> + (Double -> OvertonesO) -> IO ()+soundGen3G_OMNPar m1 n1 params freq1 file f y zs gAdds gRems freq0 proj f0 = do+ vecA0 <- fmap (V.map (`quotRem` 108)) ((if m1 == (-1) && n1 == (-1) then readFileDoubles else readFileDoublesMN m1 n1) file) -- >>= print+ let n = V.length vecA0+ fA1 j = fAddFElems (proj . freq0 $ j) f0 gAdds+ fR1 j = fRemoveFElems (proj . freq0 $ j) f0 gRems+ vecB = V.imap (\j r -> (V.unsafeIndex notes (snd r),+ case fst r of+ 0 -> f0+ 1 -> fA1 j+ 2 -> fA1 j+ 3 -> fA1 j+ 4 -> fA1 j+ _ -> fR1 j)) vecA0+ zeroN = numVZeroesPre vecB+ v2 = str2DurationsDef n zs y in V.imapM_ (\j (x,k) -> do+ h2Params (k x) (x, (V.unsafeIndex v2 (j `rem` (V.length v2)))) params freq1+ renameFile ("result.wav") $ "result0" ++ prependZeroes zeroN (show (j + 1)) ++ ".wav") vecB+ endFromResult ++-- | Generates a sequence of sounds with changing timbre. Is a generalized version of the 'soundGen3G_O', instead of predefined conversion function +-- inside, it uses a user-defined one. +-- +-- > soundGen3G_O = soundGen3G_O2 +-- with the first argument +-- +-- > conversionFII (f0,fA1,fR1) = imap (\j r -> (unsafeIndex notes (snd r),+-- +-- > case fst r of+-- +-- > 0 -> f0+-- +-- > 1 -> fA1 j+-- +-- > 2 -> fA1 j+-- +-- > 3 -> fA1 j+-- +-- > 4 -> fA1 j+-- +-- > _ -> fR1 j))+-- +-- +soundGen3G_O2 :: ((Double -> OvertonesO,Int -> Double -> OvertonesO,Int -> Double -> OvertonesO) -> V.Vector (Int,Int) -> + V.Vector (Double,Double -> OvertonesO)) -> Int -> Int -> Double -> FilePath -> (Double -> OvertonesO) -> Double -> String -> + (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> + (Int -> OvertonesO) -> (OvertonesO -> OvertonesO) -> (Double -> OvertonesO) -> IO ()+soundGen3G_O2 = soundGen3G_O2MN (-1) (-1)++-- | Generalized version of the 'soundGen3G_O2' where instead of lifting with 'liftInEnku' 'liftInParams' is used. It allows e. g. to +-- use some tonality. For more information, please, refer to 'filterInParams'.+soundGen3G_O2Par :: ((Double -> OvertonesO,Int -> Double -> OvertonesO,Int -> Double -> OvertonesO) -> V.Vector (Int,Int) -> + V.Vector (Double,Double -> OvertonesO)) -> Params -> Double -> FilePath -> (Double -> OvertonesO) -> Double -> String -> + (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> + (Int -> OvertonesO) -> (OvertonesO -> OvertonesO) -> (Double -> OvertonesO) -> IO ()+soundGen3G_O2Par = soundGen3G_O2MNPar (-1) (-1)++-- | Generates a sequence of sounds with changing timbre. Is a generalized version of the 'soundGen3G_O2'. To specify how many sounds the resulting files +-- will provide, you use first two 'Int64' arguments, the first of which is a number of dropped elements for 'readFileDoubles' and the second one +-- is a number of produced sounds (and, respectively, number of taken elements).+soundGen3G_O2MN :: Int64 -> Int64 -> ((Double -> OvertonesO,Int -> Double -> OvertonesO,Int -> Double -> OvertonesO) -> V.Vector (Int,Int) -> + V.Vector (Double,Double -> OvertonesO)) -> Int -> Int -> Double -> FilePath -> (Double -> OvertonesO) -> Double -> String -> + (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> + (Int -> OvertonesO) -> (OvertonesO -> OvertonesO) -> (Double -> OvertonesO) -> IO ()+soundGen3G_O2MN m1 n1 conversionFII m ku freq1 file f y zs gAdds gRems freq0 proj f0 = do+ vecA0 <- fmap (V.map (`quotRem` 108)) ((if m1 == (-1) && n1 == (-1) then readFileDoubles else readFileDoublesMN m1 n1) file) -- >>= print+ let n = V.length vecA0+ fA1 j = fAddFElems (proj . freq0 $ j) f0 gAdds+ fR1 j = fRemoveFElems (proj . freq0 $ j) f0 gRems+ vecB = conversionFII (f0,fA1,fR1) vecA0+ zeroN = numVZeroesPre vecB+ 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++-- | Generalized version of the 'soundGen3G_O2MN' where instead of lifting with 'liftInEnku' 'liftInParams' is used. It allows e. g. to +-- use some tonality. For more information, please, refer to 'filterInParams'.+soundGen3G_O2MNPar :: Int64 -> Int64 -> ((Double -> OvertonesO,Int -> Double -> OvertonesO,Int -> Double -> OvertonesO) -> V.Vector (Int,Int) -> + V.Vector (Double,Double -> OvertonesO)) -> Params -> Double -> FilePath -> (Double -> OvertonesO) -> Double -> String -> + (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> + (Int -> OvertonesO) -> (OvertonesO -> OvertonesO) -> (Double -> OvertonesO) -> IO ()+soundGen3G_O2MNPar m1 n1 conversionFII params freq1 file f y zs gAdds gRems freq0 proj f0 = do+ vecA0 <- fmap (V.map (`quotRem` 108)) ((if m1 == (-1) && n1 == (-1) then readFileDoubles else readFileDoublesMN m1 n1) file) -- >>= print+ let n = V.length vecA0+ fA1 j = fAddFElems (proj . freq0 $ j) f0 gAdds+ fR1 j = fRemoveFElems (proj . freq0 $ j) f0 gRems+ vecB = conversionFII (f0,fA1,fR1) vecA0+ zeroN = numVZeroesPre vecB+ v2 = str2DurationsDef n zs y in V.imapM_ (\j (x,k) -> do+ h2Params (k x) (x, (V.unsafeIndex v2 (j `rem` (V.length v2)))) params freq1+ renameFile ("result.wav") $ "result0" ++ prependZeroes zeroN (show (j + 1)) ++ ".wav") vecB+ endFromResult ++-- | Generates a sequence of sounds with changing timbre. Is a generalized version of the 'soundGen3G_O2', but for the conversion function conversionFII as its +-- tuple first argument uses not the tuple of the three functions, but a tuple of three 'V.Vector' of functions of the respective types, that allows to +-- specify more comlex behaviour and different variants inside the function itself, not its inner function parts. 'V.Vector' as a data type is used +-- instead of more common list because it has similar functionality and besides provides easier and quicker access to its elements. So these are the +-- following vectors of functions: @vf :: Vector (Double -> OvertonesO)@ (no changing a function for timbre generation), +-- @vfA :: Vector (Int -> Double -> OvertonesO)@ (for \"adding\" overtones to the function for timbre generation), +-- and @vfR :: Vector (Int -> Double -> OvertonesO@ (for \"removing\" overtones from the function for timbre generation).+-- +soundGen3G_O2G :: ((V.Vector (Double -> OvertonesO),V.Vector (Int -> Double -> OvertonesO),V.Vector (Int -> Double -> OvertonesO)) -> V.Vector (Int,Int) -> + V.Vector (Double,Double -> OvertonesO)) -> V.Vector (Double -> OvertonesO) -> V.Vector (Int -> Double -> OvertonesO) -> V.Vector (Int -> Double -> OvertonesO) -> + Int -> Int -> Double -> FilePath -> (Double -> OvertonesO) -> Double -> String -> + (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> + (Int -> OvertonesO) -> (Double -> OvertonesO) -> IO ()+soundGen3G_O2G = soundGen3G_O2GMN (-1) (-1)++-- | Generalized version of the 'soundGen3G_O2G' where instead of lifting with 'liftInEnku' 'liftInParams' is used. It allows e. g. to +-- use some tonality. For more information, please, refer to 'filterInParams'.+soundGen3G_O2GPar :: ((V.Vector (Double -> OvertonesO),V.Vector (Int -> Double -> OvertonesO),V.Vector (Int -> Double -> OvertonesO)) -> V.Vector (Int,Int) -> + V.Vector (Double,Double -> OvertonesO)) -> V.Vector (Double -> OvertonesO) -> V.Vector (Int -> Double -> OvertonesO) -> V.Vector (Int -> Double -> OvertonesO) -> + Params -> Double -> FilePath -> (Double -> OvertonesO) -> Double -> String -> + (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> + (Int -> OvertonesO) -> (Double -> OvertonesO) -> IO ()+soundGen3G_O2GPar = soundGen3G_O2GMNPar (-1) (-1)++-- | Generates a sequence of sounds with changing timbre. Is a generalized version of the 'soundGen3G_O2G'. To specify how many sounds the resulting files +-- will provide, you use first two 'Int64' arguments, the first of which is a number of dropped elements for 'readFileDoubles' and the second one +-- is a number of produced sounds (and, respectively, number of taken elements).+soundGen3G_O2GMN :: Int64 -> Int64 -> ((V.Vector (Double -> OvertonesO),V.Vector (Int -> Double -> OvertonesO),V.Vector (Int -> Double -> OvertonesO)) -> V.Vector (Int,Int) -> + V.Vector (Double,Double -> OvertonesO)) -> V.Vector (Double -> OvertonesO) -> V.Vector (Int -> Double -> OvertonesO) -> V.Vector (Int -> Double -> OvertonesO) -> + Int -> Int -> Double -> FilePath -> (Double -> OvertonesO) -> Double -> String -> + (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> + (Int -> OvertonesO) -> (Double -> OvertonesO) -> IO ()+soundGen3G_O2GMN m1 n1 conversionFII vf vfA vfR m ku freq1 file f y zs gAdds gRems freq0 f0 = do+ 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+ zeroN = numVZeroesPre vecB+ 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++-- | Generalized version of the 'soundGen3G_O2GMN' where instead of lifting with 'liftInEnku' 'liftInParams' is used. It allows e. g. to +-- use some tonality. For more information, please, refer to 'filterInParams'.+soundGen3G_O2GMNPar :: Int64 -> Int64 -> ((V.Vector (Double -> OvertonesO),V.Vector (Int -> Double -> OvertonesO),V.Vector (Int -> Double -> OvertonesO)) -> V.Vector (Int,Int) -> + V.Vector (Double,Double -> OvertonesO)) -> V.Vector (Double -> OvertonesO) -> V.Vector (Int -> Double -> OvertonesO) -> V.Vector (Int -> Double -> OvertonesO) -> + Params -> Double -> FilePath -> (Double -> OvertonesO) -> Double -> String -> + (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> (OvertonesO -> Double -> (Double -> OvertonesO) -> OvertonesO) -> + (Int -> OvertonesO) -> (Double -> OvertonesO) -> IO ()+soundGen3G_O2GMNPar m1 n1 conversionFII vf vfA vfR params freq1 file f y zs gAdds gRems freq0 f0 = do+ 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+ zeroN = numVZeroesPre vecB+ v2 = str2DurationsDef n zs y in V.imapM_ (\j (x,k) -> do+ h2Params (k x) (x, (V.unsafeIndex v2 (j `rem` (V.length v2)))) params freq1+ renameFile ("result.wav") $ "result0" ++ prependZeroes zeroN (show (j + 1)) ++ ".wav") vecB+ endFromResult ++-- | For the given parameters generates a single sound with overtones or pause depending on the sign of the second element in a tuple of 'Double': +-- if it is greater than zero then the sound is generated, if less -- the silence (pause), if it is equal to zero then it prints informational message +-- about not standard situation. +h1 :: (Double -> OvertonesO) -> (Double, Double) -> Int -> IO ()+h1 f (x, y) j = do+ let note0 = closestNote (if x /= 0.0 then abs x else V.unsafeIndex notes 0)+ v0 = f note0+ ts = showFFloat (Just 4) (abs y) ""+ case compare y 0.0 of+ GT -> do + (_,_,herr) <- readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "testA.wav", "synth", ts,"sine",showFFloat Nothing note0 ""] ""+ print herr+ partialTest_k v0 0 ts+ mixTest+ LT -> readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "result.wav", "synth", ts,"sine",showFFloat Nothing note0 "","vol","0"] "" >>= + \(_,_,herr) -> putStr herr+ _ -> putStrLn "Zero length of the sound! " ++-- | For the given parameters generates a single sound with overtones or pause depending on the sign of the second element in a tuple of 'Double': +-- if it is greater than zero then the sound is generated, if less -- the silence (pause), if it is equal to zero then it prints informational message +-- about not standard situation. Unlike the 'h1' function, it lifts into specified by 'Int' arguments enku (see 'liftInEnku') the frequency.+h2 :: OvertonesO -> (Double, Double) -> Int -> Int -> Double -> IO ()+h2 v (x, y) m ku freq1 = do+ let note0 = fromMaybe freq1 . liftInEnku m ku . closestNote $ (if x /= 0.0 then abs x else V.unsafeIndex notes 0)+ ts = showFFloat (Just 4) (abs y) ""+ case compare y 0.0 of+ GT -> do + (_,_,herr) <- readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "testA.wav", "synth", ts,"sine",showFFloat Nothing note0 ""] ""+ print herr+ partialTest_k v 0 ts+ mixTest+ LT -> readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "result.wav", "synth", ts,"sine",showFFloat Nothing note0 "","vol","0"] "" >>= + \(_,_,herr) -> putStr herr+ _ -> putStrLn "Zero length of the sound! " ++-- | For the given parameters generates a single sound with overtones or pause depending on the sign of the second element in a tuple of 'Double': +-- if it is greater than zero then the sound is generated, if less -- the silence (pause), if it is equal to zero then it prints informational message +-- about not standard situation. Unlike the 'h1' function, it lifts into specified by 'Params' argument frequency.+h2Params :: OvertonesO -> (Double, Double) -> Params -> Double -> IO ()+h2Params v (x, y) params freq1 = do+ let note01 = flip liftInParams params (if x /= 0.0 then abs x else V.unsafeIndex notes 0)+ ts = showFFloat (Just 4) (abs y) ""+ note0 = if note01 == 11440.0 then freq1 else note01+ case compare y 0.0 of+ GT -> do + (_,_,herr) <- readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "testA.wav", "synth", ts,"sine",showFFloat Nothing note0 ""] ""+ print herr+ partialTest_k v 0 ts+ mixTest+ LT -> readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "result.wav", "synth", ts,"sine",showFFloat Nothing note0 "","vol","0"] "" >>= + \(_,_,herr) -> putStr herr+ _ -> putStrLn "Zero length of the sound! " ++-- | Generates melody for the given parameters. The idea is that every application of the function @f :: Double -> OvertonesO@ to its argument +-- possibly can produce multiple overtones being represented as 'V.Vector' of tuples of pairs of 'Double'. We can use the first element in the +-- tuple to obtain a new sound parameters and the second one -- to obtain its new duration in the melody. Additional function @g :: Double -> Double@ +-- is used to avoid the effect of becoming less and less -- closer to the zero for the higher overtones so the durations will become also less. +-- Besides it allows to rescale the durations in a much more convenient way. +-- +-- The first 'Double' parameter is a multiplication coefficient to increase or to decrease the durations (positive values correspond to increasing inside +-- the @g@. function applied afterwards with function composition. +-- The second 'Double' parameter is a usual frequency which is used instead of the 11440.0 (Hz) value. +-- The third 'Double' parameter is a main argument -- the frequency for which the 'OvertonesO' are generated as a first step of the computation. +overMeloPar :: (Double -> OvertonesO) -> (Double -> Double) -> Params -> Double -> Double -> Double -> IO ()+overMeloPar f g params coeff freq0 freq = do + let v = f freq+ vFreqs = V.map ((\z -> if z == 11440.0 then freq0 else z) . flip liftInParams params . fst) v+ vD = V.map (g . (* coeff) . snd) v+ v2 = V.map f vFreqs+ vS = V.map (\z -> showFFloat (Just 4) (abs z) "") vD+ h42 j (x,v3,y,ts) + | compare y 0.0 == GT = do + (_,_,herr) <- readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "testA.wav", "synth", ts,"sine",showFFloat Nothing (fst x) ""] ""+ print herr+ partialTest_k v3 0 ts+ mixTest+ renameFile "result.wav" $ "result" ++ prependZeroes (numVZeroesPre v) (show j) ++ ".wav"+ | compare y 0.0 == LT = do + (_,_,herr) <- readProcessWithExitCode (fromJust (showE "sox")) ["-r22050", "-n", "result.wav", "synth", ts,"sine",showFFloat Nothing (fst x) "","vol","0"] "" + putStr herr+ renameFile "result.wav" $ "result" ++ prependZeroes (numVZeroesPre v) (show j) ++ ".wav"+ | otherwise = putStrLn "Zero length of the sound! " + V.imapM_ (\j zz -> h42 j zz) . V.zip4 v v2 vD $ vS
DobutokO/Sound/IntermediateF.hs view
@@ -104,6 +104,10 @@ , wOrf , wavToFlac , flacToWav+ -- * Special SoX effects+ , soxREw1+ , soxRE1+ , soxREA1 ) where import Numeric (showFFloat)@@ -192,7 +196,7 @@ return diNN -- | During function evaluation you can listen to the sound files and mark them with \"1\" and \"0\". The first one means that the sound is considered--- of higher quality and is intended to be used as a replacement for the worse sounds markd by \"0\". The function returns a 'V.Vector' of specially formatted+-- of higher quality and is intended to be used as a replacement for the worse sounds marked by \"0\". The function returns a 'V.Vector' of specially formatted -- 'String' that represents only those files that are connected with the replacement procedure. playAndMark :: V.Vector FilePath -> IO (V.Vector String) playAndMark vec@@ -808,3 +812,33 @@ filterToBnds :: Int -> Int -> [Int] -> [Int] filterToBnds lbnd hbnd = filter (\x -> compare x lbnd /= LT && compare x hbnd /= GT) +-- | Applies a special chain of the SoX effects to a file to obtain a somewhat similar to some instruments sound for some values of the 'Int' parameters. +-- These last ones are used (after some normalizing transformation) as a arguments for the SoX \"reverb -w\" effect. For more information about their +-- meaning, please, refer to the SoX and reverberation documentation, besides you can give them a try. +soxREw1 :: Int -> Int -> Int -> Int -> Int -> Int -> FilePath -> IO ()+soxREw1 reverberance damping roomscale stereodepth predelay wetgain file = do + durat <- durationA file+ soxE file (concat [["channels", "2", "rate", "44100", "reverb", "-w"], map (\n -> show (abs n `rem` 101)) [reverberance, damping, roomscale, stereodepth], + [show (abs predelay `rem` 501), show (abs wetgain `rem` 7), "trim", "0", showFFloat (Just 5) durat "", "reverse", "fade", "q", "0.002", "-0.0", "earwax"]])++-- | Applies a special chain of the SoX effects to a file to obtain a somewhat other its sounding. Similar to 'soxREw1' in realization, but can give +-- rather another sounding. +soxRE1 :: Int -> Int -> Int -> Int -> Int -> Int -> FilePath -> IO ()+soxRE1 reverberance damping roomscale stereodepth predelay wetgain file = do + durat <- durationA file+ soxE file (concat [["channels", "2", "rate", "44100", "reverb"], map (\n -> show (abs n `rem` 101)) [reverberance, damping, roomscale, stereodepth], + [show (abs predelay `rem` 501), show (abs wetgain `rem` 7), "trim", "0", showFFloat (Just 5) durat "", "reverse", "fade", "q", "0.002", "-0.0", "earwax"]])++-- | Applies a special chain of the SoX effects to the files which are obtained as a result of the 'listVDirectory3G' to the current directory. +-- For some values of the first six 'Int' parameters you obtain a somewhat similar to some instruments sounds. +-- These parameters are used (after some normalizing transformation) as a arguments for the SoX \"reverb -w\" effect. For more information about their +-- meaning, please, refer to the SoX and reverberation documentation, besides you can give them a try. The last 'Int' parameter is the first argument +-- for the afterwards general SoX "reverb" effect. 'String' arguments are that ones for the 'listVDirectory3G'. The 'FilePath' argument is a name +-- for the resulting file (in the supported by the SoX format). +soxREA1 :: Int -> Int -> Int -> Int -> Int -> Int -> Int -> String -> String -> FilePath -> IO ()+soxREA1 reverberance damping roomscale stereodepth predelay wetgain reverb2 ys zs file = do + dir0V <- listVDirectory3G ys zs+ V.mapM_ (soxREw1 reverberance damping roomscale stereodepth predelay wetgain) dir0V+ (_,_,herr) <- readProcessWithExitCode (fromJust (showE "sox")) (concat [V.toList dir0V, [file, "reverb", show (abs reverb2 `rem` 101)]]) ""+ print herr+
README.markdown view
@@ -250,6 +250,12 @@ allows to use tonalities or something close to them. For more information, please, refer to DobutokO.Sound.Functional and DobutokO.Sound modules. +Since the 0.39.0.0 version there are some additional effects and opportunities +in the DobutokO.Sound.Functional and DobutokO.Sound.IntermediateF modules. Some +functions in the library were moved from the DobutokO.Sound.Executable module +to the DobutokO.Sound.Functional module because of logics of the module structure +and semantics.+ ** 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.38.1.0+version: 0.39.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