mmsyn7ukr-0.8.0.0: SoXBasics1.hs
-- |
-- Module : SoXBasics1
-- Copyright : (c) OleksandrZhabenko 2020
-- License : MIT
--
-- Maintainer : olexandr543@yahoo.com
--
-- A program and a library that can be used as a simple
-- basic interface to some SoX functionality or for producing
-- the approximately Ukrainian speech with your own recorded
-- voice (actually it produces the needed sound representations).
-- This module differs from a SoXBasics that the resulting files
-- in it have possibly just the same name as the input ones. The functions
-- try to replace the initial file with the processed one.
--
module SoXBasics1 (
-- * Produce sound
-- ** Amplitude modification
norm
, normL
, gainL
, quarterSinFade
-- ** Adding silence
, silenceBoth
-- ** Changing sample rate
, resampleA
-- ** Working with noise
, noiseReduceB
, noiseReduceE
-- ** Filtering
, sincA
-- ** Volume amplification
, volS
, volS2
) where
import System.Directory
import Data.Maybe (isJust, fromJust)
import Numeric
import System.Process
import EndOfExe
import System.Exit
import qualified SoXBasics as SX (extremeS1,upperBnd,selMA,maxAbs,norm)
-- | Function 'norm' applies a SoX normalization effect on the audio file.
-- The function must be used with the @FilePath@ parameter containing no directories in its name (that means the file of the @FilePath@ parameter must be
-- in the same directory where the function is called from). While being
-- executed the function tries to replace the initial file with the resulting processed one and to clean the temporary files. If it is not
-- successful the function exits with error and leaves the initial file without modification.
norm :: FilePath -> IO ()
norm file = if isJust (showE "sox")
then do
_ <- readProcessWithExitCode (fromJust (showE "sox")) [file, "8" ++ file, "norm"] ""
exist0 <- doesFileExist $ "8" ++ file
if exist0
then do
removeFile file
renameFile ("8" ++ file) file
else error "The initial file was not changed!"
else error "SoX is not properly installed in your system. Please, install it properly and then call the function again."
-- | Function 'normL' applies a SoX gain effect on the audio file with the maximum absolute dB value given by the @Int@ argument.
-- The function must be used with the @FilePath@ parameter containing no directories in its name (that means the file of the @FilePath@ parameter must be
-- in the same directory where the function is called from). While being
-- executed the function tries to replace the initial file with the resulting processed one and to clean the temporary files. If it is not
-- successful the function exits with error and leaves the initial file without modification.
normL :: FilePath -> Int -> IO ()
normL file level = if isJust (showE "sox")
then do
_ <- readProcessWithExitCode (fromJust (showE "sox")) [file, "9" ++ file, "gain", "-n", show level] ""
exist0 <- doesFileExist $ "9" ++ file
if exist0
then do
removeFile file
renameFile ("9" ++ file) file
else error "The initial file was not changed!"
else error "SoX is not properly installed in your system. Please, install it properly and then call the function again."
-- | Function 'normL' applies a SoX \"gain -b [db-Value]\" effect on the audio file with dB value given by the @Double@ argument.
-- The function must be used with the @FilePath@ parameter containing no directories in its name (that means the file of the @FilePath@ parameter must be
-- in the same directory where the function is called from). While being
-- executed the function tries to replace the initial file with the resulting processed one and to clean the temporary files. If it is not
-- successful the function exits with error and leaves the initial file without modification.
gainL :: FilePath -> Double -> IO ()
gainL file level = if isJust (showE "sox")
then do
_ <- readProcessWithExitCode (fromJust (showE "sox")) [file, "9" ++ file, "gain", "-b", showFFloat (Just 6) level $ show 0] ""
exist0 <- doesFileExist $ "9" ++ file
if exist0
then do
removeFile file
renameFile ("9" ++ file) file
else error "The initial file was not changed!"
else error "SoX is not properly installed in your system. Please, install it properly and then call the function again."
-- | Function 'quarterSinFade' applies a fade effect by SoX to the audio file with \"q\" type.
-- The function must be used with the @FilePath@ parameter containing no directories in its name (that means the file of the @FilePath@ parameter must be
-- in the same directory where the function is called from). While being
-- executed the function tries to replace the initial file with the resulting processed one and to clean the temporary files. If it is not
-- successful the function exits with error and leaves the initial file without modification.
quarterSinFade :: FilePath -> IO ()
quarterSinFade file = if isJust (showE "sox")
then do
pos <- SX.extremeS1 file
upp <- SX.upperBnd file
_ <- readProcessWithExitCode (fromJust (showE "sox")) [file, "4" ++ file, "fade", "q", show pos ++ "s", "=" ++ show upp ++ "s", show (upp - pos) ++ "s"] ""
exist0 <- doesFileExist $ "4" ++ file
if exist0
then do
removeFile file
renameFile ("4" ++ file) file
else error "The initial file was not changed!"
else error "SoX is not properly installed in your system. Please, install it properly and then call the function again."
-- | Function 'silenceBoth' adds some silence to both ends of the audio.
-- The function must be used with the @FilePath@ parameter containing no directories in its name (that means the file of the @FilePath@ parameter must be
-- in the same directory where the function is called from). While being
-- executed the function tries to replace the initial file with the resulting processed one and to clean the temporary files. If it is not
-- successful the function exits with error and leaves the initial file without modification.
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"] ""
exist0 <- doesFileExist $ "3" ++ file
exist1 <- doesFileExist $ "2" ++ file
if exist0
then if exist1
then do
removeFile $ "3" ++ file
removeFile file
renameFile ("2" ++ file) file
else do
removeFile $ "3" ++ file
error "The resulting file was not created!"
else error "The initial file was not changed!"
else error "SoX is not properly installed in your system. Please, install it properly and then call the function again."
-- | Function 'resampleA' changes the sample rate for the recorded audio for further processing.
-- The function must be used with the @FilePath@ parameter containing no directories in its name (that means the file of the @FilePath@ parameter must be
-- in the same directory where the function is called from). While being
-- executed the function tries to replace the initial file with the resulting processed one and to clean the temporary files. If it is not
-- successful the function exits with error and leaves the initial file without modification.
resampleA :: FilePath -> Int -> IO ()
resampleA file frequency = if isJust (showE "sox")
then do
_ <- readProcessWithExitCode (fromJust (showE "sox")) [file, "3" ++ file, "rate", "-s", "-I", show frequency] ""
exist0 <- doesFileExist $ "3" ++ file
if exist0
then do
removeFile file
renameFile ("3" ++ file) file
else error "The initial file was not changed!"
else error "SoX is not properly installed in your system. Please, install it properly and then call the function again."
-- | Function 'noiseReduceB' reduces with SoX a noise in the file given with the corresponding noise profile created with 'noiseProfB' function.
-- The function must be used with the @FilePath@ parameter containing no directories in its name (that means the file of the @FilePath@ parameter must be
-- in the same directory where the function is called from). While being
-- executed the function tries to replace the initial file with the resulting processed one and to clean the temporary files. If it is not
-- successful the function exits with error and leaves the initial file without modification.
noiseReduceB :: FilePath -> IO ()
noiseReduceB file = if isJust (showE "sox")
then do
_ <- readProcessWithExitCode (fromJust (showE "sox")) [file, "_" ++ file, "noisered", file ++ ".b.prof"] ""
exist0 <- doesFileExist $ "_" ++ file
if exist0
then do
removeFile file
renameFile ("_" ++ file) file
else error "The initial file was not changed!"
else error "SoX is not properly installed in your system. Please, install it properly and then call the function again."
-- | Function 'noiseReduceE' reduces with SoX a noise in the file given with the corresponding noise profile created with 'noiseProfE' function.
-- The function must be used with the @FilePath@ parameter containing no directories in its name (that means the file of the @FilePath@ parameter must be
-- in the same directory where the function is called from). While being
-- executed the function tries to replace the initial file with the resulting processed one and to clean the temporary files. If it is not
-- successful the function exits with error and leaves the initial file without modification.
noiseReduceE :: FilePath -> IO ()
noiseReduceE file = if isJust (showE "sox")
then do
_ <- readProcessWithExitCode (fromJust (showE "sox")) [file, "_." ++ file, "noisered", file ++ ".e.prof"] ""
exist0 <- doesFileExist $ "_." ++ file
if exist0
then do
removeFile file
renameFile ("_." ++ file) file
else error "The initial file was not changed!"
else error "SoX is not properly installed in your system. Please, install it properly and then call the function again."
-- | Function 'volS' changes the given audio with the linear ratio for the amplitude so that the resulting amlitude is equal to the given @Double@ parameter.
-- The function must be used with the @FilePath@ parameter containing no directories in its name (that means the file of the @FilePath@ parameter must be
-- in the same directory where the function is called from). While being
-- executed the function tries to replace the initial file with the resulting processed one and to clean the temporary files. If it is not
-- successful the function exits with error and leaves the initial file without modification.
volS :: FilePath -> Double -> IO ()
volS file amplitude = if isJust (showE "sox")
then do
SX.norm file
exist0 <- doesFileExist $ "8" ++ file
if exist0
then do
_ <- readProcessWithExitCode (fromJust (showE "sox")) ["8" ++ file, "8." ++ file, "vol", showFFloat Nothing amplitude $ show 0, "amplitude"] ""
exist1 <- doesFileExist $ "8." ++ file
if exist1
then do
removeFile file
removeFile $ "8" ++ file
renameFile ("8." ++ file) file
else do
removeFile $ "8" ++ file
error "The initial file was not changed!"
else error "The initial file was not changed at all!"
else error "SoX is not properly installed in your system. Please, install it properly and then call the function again."
-- | Function 'volS2' changes the given audio (the first @FilePath@ parameter, which must be normalized e. g. by the 'norm' function before) with
-- the linear ratio for the amplitude so that the resulting amlitude is equal to the maximum by absolute value amplitude for the file given
-- by the second @FilePath@ parameter. The function must be used with the first @FilePath@ parameter containing no directories in its name
-- (that means the file of the first @FilePath@ parameter must be in the same directory where the function is called from). While being
-- executed the function tries to replace the initial file with the resulting processed one and to clean the temporary files. If it is not
-- successful the function exits with error and leaves the initial file without modification.
volS2 :: FilePath -> FilePath -> IO ()
volS2 fileA fileB = if isJust (showE "sox")
then do
upp <- SX.upperBnd fileB
amplMax <- SX.selMA fileB (0, upp) True
amplMin <- SX.selMA fileB (0, upp) False
let ampl = read (fst . SX.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 do
removeFile fileA
renameFile ("8." ++ tail fileA) fileA
else error "The initial file was not changed!"
else error "SoX is not properly installed in your system. Please, install it properly and then call the function again."
-- | Function 'sincA' uses a \"sinc\" effect with @-a 50 -I 0.07k-11k@ band-pass filter for the audio file given. While being
-- executed the function tries to replace the initial file with the resulting processed one and to clean the temporary files. If it is not
-- successful the function exits with error and leaves the initial file without modification.
sincA :: FilePath -> IO ()
sincA file = if isJust (showE "sox")
then do
_ <- readProcessWithExitCode (fromJust (showE "sox")) [file, "4." ++ file, "sinc", "-a", "50", "-I", "0.07k-11k"] ""
exist0 <- doesFileExist $ "4." ++ file
if exist0
then do
removeFile file
renameFile ("4." ++ file) file
else error "The initial file was not changed!"
else error "SoX is not properly installed in your system. Please, install it properly and then call the function again."