module SoXBasics where
import System.Directory
import Data.Maybe (isJust, fromJust)
import Numeric
import Data.Char
import System.Process
import System.IO
import EndOfExe
import System.Exit
import Control.Concurrent (threadDelay)
maxAbs :: (String, String) -> (String, Bool)
maxAbs (xs, ys) | null xs || null ys = ([], False)
| head xs == '-' && head ys == '-' = if compare xs ys /= LT then (xs, False) else (ys, False)
| head xs /= '-' && head ys /= '-' = if compare xs ys == GT then (xs, True) else (ys, True)
| head xs == '-' && head ys /= '-' = if compare (tail xs) ys /= LT then (xs, False) else (ys, True)
| otherwise = if compare xs (tail ys) == GT then (xs, True) else (ys, False)
getMaxA :: FilePath -> (Int, Int) -> IO String
getMaxA file (lowerbound, upperbound) = if isJust (showE "sox")
then do
(_, _, herr) <- readProcessWithExitCode (fromJust (showE "sox")) [file, "-n", "trim", show lowerbound ++ "s", "=" ++ show upperbound ++ "s", "stat"] ""
let zs = lines herr in return (let u = (words $ zs !! 3) !! 2 in if head u == '-' then take 9 u else take 8 u)
else error "SoX is not properly installed in your system. Please, install it properly and then call the function again."
getMinA :: FilePath -> (Int, Int) -> IO String
getMinA file (lowerbound, upperbound) = if isJust (showE "sox")
then do
(_, _, herr1) <- readProcessWithExitCode (fromJust (showE "sox")) [file, "-n", "trim", show lowerbound ++ "s", "=" ++ show upperbound ++ "s", "stat"] ""
let zs = lines herr1 in return (let u = (words $ zs !! 4) !! 2 in if head u == '-' then take 9 u else take 8 u)
else error "SoX is not properly installed in your system. Please, install it properly and then call the function again."
selMaxAbs :: FilePath -> (Int, Int) -> IO (String, Bool)
selMaxAbs file (lowerbnd, upperbnd) = do
tX <- getMaxA file (lowerbnd, upperbnd)
tN <- getMinA file (lowerbnd, upperbnd)
return (maxAbs (tX, tN))
selMA :: FilePath -> (Int, Int) -> Bool -> IO String
selMA file (lowerbnd, upperbnd) x = if x then getMaxA file (lowerbnd, upperbnd) else getMinA file (lowerbnd, upperbnd)
extremeS :: FilePath -> (Int, Int) -> Int -> IO (String, Bool) -> IO Int
extremeS file (lowerbnd, upperbnd) eps x = if compare (upperbnd - lowerbnd) (eps + 33) == LT
then return $ (upperbnd + lowerbnd) `quot` 2
else do
(ys, z) <- x
let t = (lowerbnd + upperbnd) `quot` 2
rs <- selMA file (lowerbnd, t) z
if (ys == rs)
then extremeS file (lowerbnd, t) eps x
else extremeS file (t, upperbnd) eps x
alterVadB :: FilePath -> Double -> Int -> Double -> IO ()
alterVadB file lim noiseMax exit | compare lim exit /= GT = putStrLn $ "File " ++ file ++ " is ready for further processing."
| otherwise =
if isJust (showE "sox")
then do
lim1 <- durationA file
alterVadHelp file lim1 lim noiseMax exit
else error "SoX is not properly installed in your system. Please, install it properly and then call the function again."
alterVadHelp :: FilePath -> Double -> Double -> Int -> Double -> IO ()
alterVadHelp file lim1 lim noiseMax exit | compare lim1 lim == LT = alterVadB file lim1 noiseMax exit
| compare lim1 lim == EQ =
let noiseM = (case noiseMax of
0 -> "0.01"
1 -> "0.02"
2 -> "0.04"
3 -> "0.08"
_ -> "0.04") in do
(_, _, herr) <- readProcessWithExitCode (fromJust (showE "sox")) [file, "-n", "trim", "0", showFFloat Nothing (lim1 / 2.0) $ show 0, "stat"] ""
let zs = lines herr in let z = concatMap (dropWhile (not . isDigit)) . take 1 . drop 3 $ zs in if z < noiseM
then do
_ <- readProcessWithExitCode (fromJust (showE "sox")) [file, "7" ++ file, "trim", showFFloat Nothing (lim1 / 2.0) $ show 0, "-0.000000"] ""
threadDelay 100000
opFile file exit noiseMax
else alterVadB file (lim1 / 4.0) noiseMax exit
| otherwise =
let noiseM = (case noiseMax of
0 -> "0.01"
1 -> "0.02"
2 -> "0.04"
3 -> "0.08"
_ -> "0.04") in do
(_, _, herr) <- readProcessWithExitCode (fromJust (showE "sox")) [file, "-n", "trim", "0", showFFloat Nothing (lim / 2.0) $ show 0, "stat"] ""
let zs = lines herr in let z = concatMap (dropWhile (not . isDigit)) . take 1 . drop 3 $ zs in if z < noiseM
then do
_ <- readProcessWithExitCode (fromJust (showE "sox")) [file, "7" ++ file, "trim", showFFloat Nothing (lim / 2.0) $ show 0, "-0.000000"] ""
threadDelay 100000
opFile file exit noiseMax
else alterVadB file (lim / 4.0) noiseMax exit
opFile :: FilePath -> Double -> Int -> IO ()
opFile file exit noiseMax = do
removeFile file
exist0 <- doesFileExist file
if not exist0
then do
renameFile ("7" ++ file) file
lim2 <- durationA file
alterVadB file lim2 noiseMax exit
else opFile file exit noiseMax
norm :: FilePath -> IO ()
norm file = if isJust (showE "sox")
then readProcessWithExitCode (fromJust (showE "sox")) [file, "8" ++ file, "norm"] "" >> return ()
else error "SoX is not properly installed in your system. Please, install it properly and then call the function again."
normL :: FilePath -> Int -> IO ()
normL file level = if isJust (showE "sox")
then readProcessWithExitCode (fromJust (showE "sox")) [file, "9" ++ file, "gain", "-n", show level] "" >> return ()
else error "SoX is not properly installed in your system. Please, install it properly and then call the function again."
soxStat :: FilePath -> IO ()
soxStat file = if isJust (showE "sox")
then do
(_, _, herr) <- readProcessWithExitCode (fromJust (showE "sox")) [file, "-n", "stat"] ""
putStrLn herr
else error "SoX is not properly installed in your system. Please, install it properly and then call the function again."
alterVadE :: FilePath -> Double -> Int -> Double -> IO ()
alterVadE file lim noiseMax exit | compare lim exit /= GT = putStrLn $ "File " ++ file ++ " is ready for further processing"
| otherwise =
if isJust (showE "sox")
then do
_ <- readProcessWithExitCode (fromJust (showE "sox")) [file, "6" ++ file, "reverse"] ""
alterVadB ("6" ++ file) lim noiseMax exit
_ <- readProcessWithExitCode (fromJust (showE "sox")) ["6" ++ file, "76" ++ file, "reverse"] ""
removeFile $ "6" ++ file
renameFile ("76" ++ file) file
else error "SoX is not properly installed in your system. Please, install it properly and then call the function again."
upperBnd :: FilePath -> IO Int
upperBnd file = if isJust (showE "soxi")
then do
(_, Just hout, _, _) <- createProcess (proc (fromJust (showE "soxi")) ["-s",file]){ std_out = CreatePipe }
x0 <- hGetContents hout
let z = read x0::Int in return z
else error "SoX is not properly installed in your system. Please, install it properly and then call the function again."
extremeS1 :: FilePath -> IO Int
extremeS1 file = do
upp <- upperBnd file
extremeS file (0::Int, upp) (if upp `quot` 32 > 2 then upp `quot` 32 else 2::Int) (selMaxAbs file (0::Int, upp))
quarterSinFade :: FilePath -> IO ()
quarterSinFade file = if isJust (showE "sox")
then do
pos <- extremeS1 file
upp <- upperBnd file
_ <- readProcessWithExitCode (fromJust (showE "sox")) [file, "4" ++ file, "fade", "q", show pos ++ "s", "=" ++ show upp ++ "s", show (upp - pos) ++ "s"] ""
return ()
else error "SoX is not properly installed in your system. Please, install it properly and then call the function again."
silenceBoth :: FilePath -> Int -> Int -> IO ()
silenceBoth file beginning end = if isJust (showE "sox")
then do
_ <- readProcessWithExitCode (fromJust (showE "sox")) [file, "3" ++ file, "delay", show beginning ++ "s", "reverse"] ""
_ <- readProcessWithExitCode (fromJust (showE "sox")) ["3" ++ file, "2" ++ file, "delay", show end ++ "s", "reverse"] ""
removeFile $ "3" ++ file
else error "SoX is not properly installed in your system. Please, install it properly and then call the function again."
recA :: FilePath -> Double -> IO ()
recA file x = if isJust (showE "rec")
then readProcessWithExitCode (fromJust (showE "rec")) ["-b16", "-c1", "-e", "signed-integer", "-L", file, "trim", "0.5", showFFloat Nothing x $ show 0] "" >> return ()
else error "SoX is not properly installed in your system. Please, install it properly and then call the function again."
resampleA :: FilePath -> Int -> IO ()
resampleA file frequency = if isJust (showE "sox")
then readProcessWithExitCode (fromJust (showE "sox")) [file, "3" ++ file, "rate", "-s", "-I", show frequency] "" >> return ()
else error "SoX is not properly installed in your system. Please, install it properly and then call the function again."
durationA :: FilePath -> IO Double
durationA file = if isJust (showE "soxi")
then do
(_, Just hout, _, _) <- createProcess (proc (fromJust (showE "soxi")) ["-D",file]){ std_out = CreatePipe }
x0 <- hGetContents hout
let z = read x0::Double in return z
else error "SoX is not properly installed in your system. Please, install it properly and then call the function again."
playA :: FilePath -> IO ()
playA file = if isJust (showE "play")
then readProcessWithExitCode (fromJust (showE "play")) [file] "" >> return ()
else error "SoX is not properly installed in your system. Please, install it properly and then call the function again."
noiseProfB :: FilePath -> IO ()
noiseProfB file = if isJust (showE "sox")
then readProcessWithExitCode (fromJust (showE "sox")) [file, "-n", "trim", "0", "0.05", "noiseprof",file ++ ".b.prof"] "" >> return ()
else error "SoX is not properly installed in your system. Please, install it properly and then call the function again."
noiseProfE :: FilePath -> IO ()
noiseProfE file = if isJust (showE "sox")
then readProcessWithExitCode (fromJust (showE "sox")) [file, "-n", "trim", "-0.05", "0.05", "noiseprof",file ++ ".e.prof"] "" >> return ()
else error "SoX is not properly installed in your system. Please, install it properly and then call the function again."
noiseReduceB :: FilePath -> IO ()
noiseReduceB file = if isJust (showE "sox")
then readProcessWithExitCode (fromJust (showE "sox")) [file, "_" ++ file, "noisered", file ++ ".b.prof"] "" >> return ()
else error "SoX is not properly installed in your system. Please, install it properly and then call the function again."
noiseReduceE :: FilePath -> IO ()
noiseReduceE file = if isJust (showE "sox")
then readProcessWithExitCode (fromJust (showE "sox")) [file, "_." ++ file, "noisered", file ++ ".e.prof"] "" >> return ()
else error "SoX is not properly installed in your system. Please, install it properly and then call the function again."
volS :: FilePath -> Double -> IO ()
volS file amplitude = if isJust (showE "sox")
then do
norm file
_ <- readProcessWithExitCode (fromJust (showE "sox")) ["8" ++ file, "8." ++ file, "vol", showFFloat Nothing amplitude $ show 0, "amplitude", "0.01"] ""
removeFile $ "8" ++ file
else error "SoX is not properly installed in your system. Please, install it properly and then call the function again."
volS2 :: FilePath -> FilePath -> IO ()
volS2 fileA fileB = if isJust (showE "sox")
then do
upp <- upperBnd fileB
amplMax <- selMA fileB (0, upp) True
amplMin <- selMA fileB (0, upp) False
let ampl = read (fst . maxAbs $ (amplMax, amplMin))::Double
(code, _, _) <- readProcessWithExitCode (fromJust (showE "sox")) [fileA, "8." ++ tail fileA, "vol", showFFloat Nothing ampl $ show 0, "amplitude"] ""
if code /= ExitSuccess
then error "File was not created with \"vol\" effect!"
else do
file8e <- doesFileExist $ "8." ++ tail fileA
if file8e
then removeFile fileA
else error "Second error!"
else error "SoX is not properly installed in your system. Please, install it properly and then call the function again."
sincA :: FilePath -> IO ()
sincA file = if isJust (showE "sox")
then readProcessWithExitCode (fromJust (showE "sox")) [file, "4." ++ file, "sinc", "-a", "50", "-I", "0.1k-11k"] "" >> return ()
else error "SoX is not properly installed in your system. Please, install it properly and then call the function again."