{-# OPTIONS_GHC -threaded #-}
module DobutokO.Sound.IntermediateF (
getFileRSizes
, getFileRSizesS
, getFileRSizesS2
, getFileRTuples
, listVDirectory
, isHighQ
, shouldBeReplaced
, indexesFromMrk
, playAndMark
, playAMrk
, pAnR1
, pAnR2
, pAnR_
, playAMrk2G
, pAnR12G
, pAnR22G
, pAnR_2G
, infoFromV
, internalConv
, ixFromRes
, ixInterv
, ixInterv2G
, thisOne
, playSeqAR
, playSeqARV
, playSeqARV2
, playCollect1Dec
, playCollectDec
, replaceWithHQs
, isOddAsElem
, maxLinV
, minLinV
, doubleLtoV
, filterToBnds
, getFileRSizes2G
, getFileRSizesS2G
, getFileRTuples2G
, listVDirectory2G
, listVDirectory3G
, playSeqAR2G
, playSeqARV2G
, playSeqARV22G
, playCollectDec2G
, replaceWithHQs2G
, soxBasicParams
, reverbE
, reverbWE
, reverb1E
, reverbW1E
, reverbE2C
, reverbWE2C
, reverb1E2C
, reverb1WE2C
, soxE1
, getSilenceF
, fadeAllE
, fadeAllEMilN
, soxE2C
, soxE12C
, recE
, rec1E
, playE
, f2w
, w2f
, cfw2wf
, efw2
, efw2vv
, wOrf
, wavToFlac
, flacToWav
, soxREw1
, soxRE1
, soxREA1
) where
import Numeric (showFFloat)
import CaseBi (getBFst')
import Control.Monad (void)
import Control.Concurrent (myThreadId,forkIO,threadDelay,killThread)
import qualified Data.List as L (sort)
import Control.Exception (onException)
import Control.Exception.FinalException (FinalException (NotRecorded,ExecutableNotProperlyInstalled),catchEnd)
import Data.List (isPrefixOf,isSuffixOf,(\\),maximum,minimum)
import Data.Char (isDigit,isSpace)
import qualified Data.Vector as V
import System.Directory
import SoXBasics (playA,durationA,recA)
import MMSyn7l
import EndOfExe (showE)
import System.Process (readProcessWithExitCode)
import Data.Maybe (fromJust,isJust)
import System.Exit (ExitCode (ExitSuccess))
import System.Info (os)
import DobutokO.Sound.ParseList (parseStoLInts)
getFileRSizes :: IO (V.Vector Integer)
getFileRSizes = getFileRSizes2G "221w"
getFileRSizes2G :: String -> IO (V.Vector Integer)
getFileRSizes2G ys = do
dirN <- listDirectory "."
let dirN1 = V.fromList . L.sort . filter (\s -> isPrefixOf "result" s && isSuffixOf (if drop 3 ys == "f" then ".flac" else ".wav") s) $ dirN
V.mapM getFileSize dirN1
getFileRSizesS :: IO (V.Vector Int)
getFileRSizesS = getFileRSizesS2G "221w"
getFileRSizesS2G :: String -> IO (V.Vector Int)
getFileRSizesS2G ys = do
dirN0 <- listDirectory "."
let dirN2 = V.fromList . L.sort . filter (\s -> isPrefixOf "result" s && isSuffixOf (if drop 3 ys == "f" then ".flac" else ".wav") s) $ dirN0
sizes1 <- V.mapM getFileSize dirN2
return . V.map fromIntegral $ sizes1
getFileRSizesS2 :: IO (V.Vector Int)
getFileRSizesS2 = getFileRSizes >>= \s -> return . V.map fromIntegral $ s
getFileRTuples :: IO (V.Vector (FilePath,Integer))
getFileRTuples = getFileRTuples2G "221w"
getFileRTuples2G :: String -> IO (V.Vector (FilePath,Integer))
getFileRTuples2G ys = do
dirN <- listDirectory "."
let dirN0 = L.sort . filter (\s -> isPrefixOf "result" s && isSuffixOf (if drop 3 ys == "f" then ".flac" else ".wav") s) $ dirN
sizes0 <- mapM getFileSize dirN0
let tpls = V.fromList . zip dirN0 $ sizes0
return tpls
listVDirectory :: IO (V.Vector FilePath)
listVDirectory = listVDirectory2G "221w"
listVDirectory2G :: String -> IO (V.Vector FilePath)
listVDirectory2G ys = do
dir0N <- listDirectory "."
let diNN = V.fromList . L.sort . filter (\s -> isPrefixOf "result" s && isSuffixOf (if drop 3 ys == "f" then ".flac" else ".wav") s) $ dir0N
return diNN
listVDirectory3G :: String -> String -> IO (V.Vector FilePath)
listVDirectory3G ys zs = do
dir0N <- listDirectory "."
let diNN = V.fromList . L.sort . filter (\s -> isPrefixOf zs s && isSuffixOf (if drop 3 ys == "f" then ".flac" else ".wav") s) $ dir0N
return diNN
playAndMark :: V.Vector FilePath -> IO (V.Vector String)
playAndMark vec
| V.null vec = return V.empty
| otherwise = V.imapM (\i xs -> do
duration <- durationA $ V.unsafeIndex vec i
putStrLn "Listen to the next sound, please. Please, do not enter anything while sound plays. "
forkIO $ do
myThread <- myThreadId
playA xs
killThread myThread
threadDelay (read (show $ truncate (duration * 1000000))::Int)
putStr "How do you mark the file that has just been played now -- if of high quality, print \"1\", if of low quality, print \"0\", "
putStrLn "if it is just accepted, press \'Enter\'. "
mark0 <- getLine
putStrLn "-----------------------------------------------------------------------------------------"
let mark = take 1 mark0
case mark of
"1" -> return $ show i ++ "*" ++ xs
"0" -> return $ show i ++ "**" ++ xs
_ -> return []) vec >>= V.filterM (return . not . null)
playAMrk :: IO (V.Vector String)
playAMrk = playAMrk2G "221w"
playAMrk2G :: String -> IO (V.Vector String)
playAMrk2G ys = listVDirectory2G ys >>= playAndMark
shouldBeReplaced :: String -> Bool
shouldBeReplaced (x:y:xs)
| x == '*' && y == '*' = True
| otherwise = shouldBeReplaced (y:xs)
shouldBeReplaced _ = False
isHighQ :: String -> Bool
isHighQ xs = (length . filter (== '*') $ xs) == 1
indexesFromMrk :: String -> Int
indexesFromMrk xs = read (takeWhile (/= '*') xs)::Int
internalConv :: ([String],[String]) -> (V.Vector Int, V.Vector String)
internalConv (xss,yss) = (V.fromList . map indexesFromMrk $ xss,V.fromList . map (dropWhile (== '*')) $ yss)
ixFromRes :: String -> String
ixFromRes xs = (takeWhile (/= '.') xs) \\ "result"
ixInterv :: Int -> IO (Int, Int)
ixInterv = ixInterv2G "221w"
ixInterv2G :: String -> Int -> IO (Int, Int)
ixInterv2G ys index0
| compare index0 0 == LT = do
dirV <- listVDirectory2G ys
let l1 = V.length dirV
case compare l1 13 of
LT -> return (0,l1 - 1)
_ -> return (0,11)
| compare index0 7 == LT = do
dirV <- listVDirectory2G ys
let l1 = V.length dirV
case compare index0 (l1 - 5) of
GT -> return (0, l1 - 1)
_ -> return (0, index0 + 4)
| otherwise = do
dirV <- listVDirectory2G ys
let l1 = V.length dirV
case compare l1 13 of
LT -> return (0,l1 - 1)
_ ->
case compare index0 (l1 - 5) of
GT -> return (index0 - 7, l1 - 1)
_ -> return (index0 - 7, index0 + 4)
infoFromV :: V.Vector String -> [(V.Vector Int, V.Vector String)]
infoFromV vec = map (internalConv . unzip . V.toList . V.map (break (== '*'))) [v1, v2]
where (v1, v2) = V.partition shouldBeReplaced vec
playSeqAR :: Int -> IO ()
playSeqAR = playSeqAR2G "221w"
playSeqAR2G :: String -> Int -> IO ()
playSeqAR2G ys index0 = do
(minBnd,maxBnd) <- ixInterv2G ys index0
dirV2 <- listVDirectory2G ys
mapM_ (playA . V.unsafeIndex dirV2) [minBnd..maxBnd]
playSeqARV :: V.Vector Int -> IO ()
playSeqARV = playSeqARV2G "221w"
playSeqARV2G :: String -> V.Vector Int -> IO ()
playSeqARV2G ys vec = do
dirV2 <- listVDirectory2G ys
V.mapM_ (playA . V.unsafeIndex dirV2) vec
playSeqARV2 :: V.Vector String -> IO ()
playSeqARV2 = playSeqARV22G "221w"
playSeqARV22G :: String -> V.Vector String -> IO ()
playSeqARV22G ys vec = do
let indexesHQs = fst . last . infoFromV $ vec
playSeqARV2G ys indexesHQs
playCollectDec :: V.Vector String -> IO (V.Vector Bool)
playCollectDec = playCollectDec2G "221w"
playCollectDec2G :: String -> V.Vector String -> IO (V.Vector Bool)
playCollectDec2G ys vec = do
dirV3 <- listVDirectory2G ys
let indexesHQs = fst . last . infoFromV $ vec
V.mapM (playCollect1Dec dirV3) indexesHQs
replaceWithHQs :: FilePath -> V.Vector Bool -> V.Vector FilePath -> IO ()
replaceWithHQs = replaceWithHQs2G "221w"
replaceWithHQs2G :: String -> FilePath -> V.Vector Bool -> V.Vector FilePath -> IO ()
replaceWithHQs2G ys file0 vecBools stringHQs
| V.length vecBools == V.length stringHQs =
case V.length stringHQs of
0 -> putStrLn "That's all!"
1 | V.unsafeIndex vecBools 0 -> do
copyFile (head . V.toList $ stringHQs) ("resultI." ++ if drop 3 ys == "f" then "flac" else "wav")
renameFile ("resultI." ++ if drop 3 ys == "f" then "flac" else "wav") file0
| otherwise -> putStrLn "Nothing has changed. "
_ -> do
let yss = V.toList . V.ifilter (\i _ -> V.unsafeIndex vecBools i) $ stringHQs
case length yss of
0 -> putStrLn "That's all!"
1 -> copyFile (head yss) file0
_ -> do
(_,_,herr) <- readProcessWithExitCode (fromJust (showE "sox")) (yss ++ soxBasicParams ys ["",file0]) ""
putStrLn herr
| otherwise =
let stringHQ2s = V.take (min (V.length vecBools) (V.length stringHQs)) stringHQs
vecBool2s = V.take (min (V.length vecBools) (V.length stringHQs)) vecBools in replaceWithHQs2G ys file0 vecBool2s stringHQ2s
thisOne :: IO Bool
thisOne = do
putStrLn "Would you like to add this sound played just now to the sequence of sounds that will replace the needed one? "
yes <- getLine
putStrLn "-----------------------------------------------------------------------"
return $ take 1 yes == "1"
playCollect1Dec :: V.Vector String -> Int -> IO Bool
playCollect1Dec dirV2 i
| compare i 0 /= LT && compare i (V.length dirV2) /= GT = do
playA $ V.unsafeIndex dirV2 i
thisOne
| otherwise = error "DobutokO.Sound.IntermediateF.playCollect1Dec: wrong Int parameter! "
pAnR1 :: V.Vector String -> IO (V.Vector String)
pAnR1 = pAnR12G "221w"
pAnR12G :: String -> V.Vector String -> IO (V.Vector String)
pAnR12G ys vec
| V.null vec = putStrLn "You have processed all the marked files! " >> return V.empty
| otherwise = do
let [(indexes0,strings),(indexesHQ,stringHQs)] = infoFromV vec
putStrLn "Please, listen to the melody and remember what sound you would like to replace and the surrounding sounds. "
playSeqAR2G ys $ V.unsafeIndex indexes0 0
putStrLn "---------------------------------------------------------------"
putStrLn "Now, please, listen to a collection of sounds considered of higher quality which you can use to replace the needed one. "
vecBools <- playCollectDec2G ys vec
replaceWithHQs2G ys (V.unsafeIndex strings 0) vecBools stringHQs
return $ V.map (\(ix,xs) -> show ix ++ "**" ++ xs) . V.zip (V.unsafeDrop 1 indexes0) $ (V.unsafeDrop 1 strings)
pAnR2 :: V.Vector String -> IO ()
pAnR2 = pAnR22G "221w"
pAnR22G :: String -> V.Vector String -> IO ()
pAnR22G ys vec
| V.null vec = putStrLn "You have processed all the marked files! "
| otherwise = onException (pAnR12G ys vec >>= pAnR22G ys) (return ())
pAnR_ :: IO ()
pAnR_ = pAnR_2G "221w"
pAnR_2G :: String -> IO ()
pAnR_2G ys = do
vec <- playAMrk2G ys
pAnR22G ys vec
reverbE :: FilePath -> [String] -> IO ()
reverbE file arggs = do
(code,_,_) <- readProcessWithExitCode (fromJust (showE "sox")) ([file,file ++ "reverb" ++ efw2 file,"reverb"] ++ arggs) ""
case code of
ExitSuccess -> renameFile (file ++ "reverb" ++ efw2 file) file
_ -> do
removeFile $ file ++ "reverb" ++ efw2 file
putStrLn $ "DobutokO.Sound.IntermediateF.reverbE \"" ++ file ++ "\" has not been successful. The file has not been changed at all. "
reverbE2C :: FilePath -> [String] -> IO ()
reverbE2C file arggs = do
(code,_,_) <- readProcessWithExitCode (fromJust (showE "sox")) ([file,file ++ "reverb" ++ efw2vv file,"reverb"] ++ arggs) ""
case code of
ExitSuccess -> do { renameFile (file ++ "reverb" ++ efw2vv file) (cfw2wf file) ; removeFile file }
_ -> do { removeFile $ file ++ "reverb" ++ efw2vv file
; putStrLn $ "DobutokO.Sound.IntermediateF.reverbE2C \"" ++ file ++ "\" has not been successful. The file has not been changed at all. " }
reverb1E :: FilePath -> [String] -> IO ()
reverb1E file arggs = do
(code,_,_) <- readProcessWithExitCode (fromJust (showE "sox")) ([file,file ++ "reverb1" ++ efw2 file,"reverb"] ++ arggs ++ ["channels","1"]) ""
case code of
ExitSuccess -> renameFile (file ++ "reverb1" ++ efw2 file) file
_ -> do
removeFile $ file ++ "reverb1" ++ efw2 file
putStrLn $ "DobutokO.Sound.IntermediateF.reverb1E \"" ++ file ++ "\" has not been successful. The file has not been changed at all. "
reverb1E2C :: FilePath -> [String] -> IO ()
reverb1E2C file arggs = do
(code,_,_) <- readProcessWithExitCode (fromJust (showE "sox")) ([file,file ++ "reverb1" ++ efw2vv file,"reverb"] ++ arggs ++ ["channels","1"]) ""
case code of
ExitSuccess -> do { renameFile (file ++ "reverb1" ++ efw2vv file) (cfw2wf file) ; removeFile file }
_ -> do
removeFile $ file ++ "reverb1" ++ efw2vv file
putStrLn $ "DobutokO.Sound.IntermediateF.reverb1E2C \"" ++ file ++ "\" has not been successful. The file has not been changed at all. "
reverbWE :: FilePath -> [String] -> IO ()
reverbWE file arggs = do
(code,_,_) <- readProcessWithExitCode (fromJust (showE "sox")) ([file,file ++ "reverbW" ++ efw2 file,"reverb","-w"] ++ arggs) ""
case code of
ExitSuccess -> renameFile (file ++ "reverbW" ++ efw2 file) file
_ -> do
removeFile $ file ++ "reverbW" ++ efw2 file
putStrLn $ "DobutokO.Sound.IntermediateF.reverbWE \"" ++ file ++ "\" has not been successful. The file has not been changed at all. "
reverbWE2C :: FilePath -> [String] -> IO ()
reverbWE2C file arggs = do
(code,_,_) <- readProcessWithExitCode (fromJust (showE "sox")) ([file,file ++ "reverbW" ++ efw2vv file,"reverb","-w"] ++ arggs) ""
case code of
ExitSuccess -> do { renameFile (file ++ "reverbW" ++ efw2vv file) (cfw2wf file) ; removeFile file }
_ -> do { removeFile $ file ++ "reverbW" ++ efw2vv file
; putStrLn $ "DobutokO.Sound.IntermediateF.reverbWE2C \"" ++ file ++ "\" has not been successful. The file has not been changed at all. " }
reverbW1E :: FilePath -> [String] -> IO ()
reverbW1E file arggs = do
(code,_,_) <- readProcessWithExitCode (fromJust (showE "sox")) ([file,file ++ "reverbW1" ++ efw2 file,"reverb","-w"] ++ arggs ++ ["channels","1"]) ""
case code of
ExitSuccess -> renameFile (file ++ "reverbW1" ++ efw2 file) file
_ -> do
removeFile $ file ++ "reverbW1" ++ efw2 file
putStrLn $ "DobutokO.Sound.IntermediateF.reverbW1E \"" ++ file ++ "\" has not been successful. The file has not been changed at all. "
reverb1WE2C :: FilePath -> [String] -> IO ()
reverb1WE2C file arggs = do
(code,_,_) <- readProcessWithExitCode (fromJust (showE "sox")) ([file,file ++ "reverbW1" ++ efw2vv file,"reverb","-w"] ++ arggs ++ ["channels","1"]) ""
case code of
ExitSuccess -> do { renameFile (file ++ "reverbW1" ++ efw2vv file) (cfw2wf file) ; removeFile file }
_ -> do
removeFile $ file ++ "reverbW1" ++ efw2vv file
putStrLn $ "DobutokO.Sound.IntermediateF.reverb1WE2C \"" ++ file ++ "\" has not been successful. The file has not been changed at all. "
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)
soxE2C :: FilePath -> [String] -> IO ()
soxE2C file arggs = do
(code,_,_) <- readProcessWithExitCode (fromJust (showE "sox")) ([file,file ++ "effects" ++ efw2vv file] ++ arggs) ""
case code of
ExitSuccess -> do { renameFile (file ++ "effects" ++ efw2vv file) (cfw2wf file) ; removeFile file }
_ -> do
removeFile $ file ++ "effects" ++ efw2vv file
putStrLn $ "DobutokO.Sound.IntermediateF.soxE2C \"" ++ file ++ "\" has not been successful. The file has not been changed at all. "
soxE1 :: FilePath -> [String] -> IO ()
soxE1 file arggs = do
(code,_,_) <- readProcessWithExitCode (fromJust (showE "sox")) ([file,file ++ "effects" ++ efw2 file] ++ arggs ++ ["channels","1"]) ""
case code of
ExitSuccess -> renameFile (file ++ "effects" ++ efw2 file) file
_ -> do
removeFile $ file ++ "effects" ++ efw2 file
putStrLn $ "DobutokO.Sound.IntermediateF.soxE1 \"" ++ file ++ "\" has not been successful. The file has not been changed at all. "
soxE12C :: FilePath -> [String] -> IO ()
soxE12C file arggs = do
(code,_,_) <- readProcessWithExitCode (fromJust (showE "sox")) ([file,file ++ "effects" ++ efw2vv file] ++ arggs ++ ["channels","1"]) ""
case code of
ExitSuccess -> do { renameFile (file ++ "effects" ++ efw2vv file) (cfw2wf file) ; removeFile file }
_ -> do
removeFile $ file ++ "effects" ++ efw2vv file
putStrLn $ "DobutokO.Sound.IntermediateF.soxE12C \"" ++ file ++ "\" has not been successful. The file has not been changed at all. "
recE :: FilePath -> [String] -> IO ()
recE file arggs | isJust (showE "sox") && take 5 os == "mingw" = do
(code, _, _) <- readProcessWithExitCode (fromJust (showE "sox")) (["-t","waveaudio","-d", file] ++ arggs)""
if code /= ExitSuccess
then do
e0 <- doesFileExist file
if e0
then do
removeFile file
catchEnd (NotRecorded file)
else catchEnd (NotRecorded file)
else do
e1 <- doesFileExist file
if e1
then return ()
else catchEnd (NotRecorded file)
| isJust (showE "rec") = do
(code, _, _) <- readProcessWithExitCode (fromJust (showE "rec")) (file:arggs) ""
if code /= ExitSuccess
then do
e0 <- doesFileExist file
if e0
then do
removeFile file
catchEnd (NotRecorded file)
else catchEnd (NotRecorded file)
else do
e1 <- doesFileExist file
if e1
then return ()
else catchEnd (NotRecorded file)
| otherwise = catchEnd ExecutableNotProperlyInstalled
rec1E :: FilePath -> [String] -> IO ()
rec1E file arggs | isJust (showE "sox") && take 5 os == "mingw" = do
(code, _, _) <- readProcessWithExitCode (fromJust (showE "sox")) (["-t","waveaudio","-d", file] ++ arggs ++ ["channels","1"])""
if code /= ExitSuccess
then do
e0 <- doesFileExist file
if e0
then do
removeFile file
catchEnd (NotRecorded file)
else catchEnd (NotRecorded file)
else do
e1 <- doesFileExist file
if e1
then return ()
else catchEnd (NotRecorded file)
| isJust (showE "rec") = do
(code, _, _) <- readProcessWithExitCode (fromJust (showE "rec")) ([file] ++ arggs ++ ["channels","1"]) ""
if code /= ExitSuccess
then do
e0 <- doesFileExist file
if e0
then do
removeFile file
catchEnd (NotRecorded file)
else catchEnd (NotRecorded file)
else do
e1 <- doesFileExist file
if e1
then return ()
else catchEnd (NotRecorded file)
| otherwise = catchEnd ExecutableNotProperlyInstalled
playE :: FilePath -> [String] -> IO ()
playE file arggs | take 5 os == "mingw" =
if isJust (showE "sox")
then void (readProcessWithExitCode (fromJust (showE "sox")) ([file, "-t", "waveaudio", "-d"] ++ arggs) "")
else catchEnd ExecutableNotProperlyInstalled
| otherwise = if isJust (showE "play")
then void (readProcessWithExitCode (fromJust (showE "play")) ([file] ++ arggs) "")
else catchEnd ExecutableNotProperlyInstalled
getSilenceF :: FilePath -> IO ()
getSilenceF file = soxE file ["vol","0"]
fadeAllE :: String -> String -> IO ()
fadeAllE ys zs = listVDirectory3G ys zs >>= V.mapM_ fadeEnds
fadeAllEMilN :: Int -> String -> String -> IO ()
fadeAllEMilN n ys zs = listVDirectory3G ys zs >>= V.mapM_ (fadeEndsMilN n)
isOddAsElem :: Eq a => a -> V.Vector [a] -> Bool
isOddAsElem x v
| V.null v = False
| otherwise = (V.length . V.findIndices (elem x) $ v) `rem` 2 == 1
maxLinV :: Ord a => V.Vector [a] -> Maybe a
maxLinV v
| V.all null v || V.null v = Nothing
| otherwise = Just (V.maximum . V.map maximum . V.filter (not . null) $ v)
minLinV :: Ord a => V.Vector [a] -> Maybe a
minLinV v
| V.all null v || V.null v = Nothing
| otherwise = Just (V.minimum . V.map minimum . V.filter (not . null) $ v)
doubleLtoV :: Ord a => [[a]] -> V.Vector a
doubleLtoV = V.fromList . shortenL . L.sort . concat
where shortenL z1@(z:_)
| length (takeWhile (== z) z1) `rem` 2 == 1 = z:shortenL (dropWhile (== z) z1)
| otherwise = shortenL (dropWhile (== z) z1)
shortenL _ = []
filterToBnds :: Int -> Int -> [Int] -> [Int]
filterToBnds lbnd hbnd = filter (\x -> compare x lbnd /= LT && compare x hbnd /= GT)
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"]])
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"]])
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