module Melodics.Executable (
circle
, workWithInput
, rawToSoundFile
, printInfoF
, recFileName
)
where
import Data.Char (isSpace, isControl)
import Data.Maybe (isJust,fromJust,fromMaybe)
import System.IO
import System.IO.Unsafe (unsafePerformIO)
import System.Process (callProcess)
import System.Directory (removeFile,findExecutable)
import Control.Exception (onException)
import EndOfExe (showE)
import Melodics.Ukrainian (appendS16LEFile, convertToProperUkrainian)
import UkrainianLControl
circle :: String -> IO ()
circle :: String -> IO ()
circle String
zs = IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO a
onException ((Int -> IO ()) -> [Int] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (String -> Int -> IO ()
workWithInput String
zs) [Int
1..]) (do
String -> IO ()
putStr String
"Notice, there was (may be) CmdLineArgument exception. To avoid it, please, specify the command line argument (if needed) in the form \"ABC\""
String -> IO ()
putStr String
" where A is either a letter \'f\', \'o\', \'w\' or a digit and B and C are both digits! The exception (may be) arose from "
String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"the command line arguments " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. Show a => a -> String
show String
zs String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
". Please, check also whether the SoX was installed with the support for needed codec.")
workWithInput :: String -> Int -> IO ()
workWithInput :: String -> Int -> IO ()
workWithInput String
zs Int
j = do
[String
nameSF,String
ys] <- String -> [Int] -> IO [String]
nameAndControl String
zs [Int
1,Int
2]
String -> IOMode -> (Handle -> IO ()) -> IO ()
forall r. String -> IOMode -> (Handle -> IO r) -> IO r
withBinaryFile (String
nameSF String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
".raw") IOMode
AppendMode (Vector String -> Handle -> IO ()
appendS16LEFile (String -> Vector String
convertToProperUkrainian String
ys))
String -> IO ()
putStrLn String
"The .raw file was created by the program. If there is SoX installed then it will run further. "
let ts :: Maybe String
ts = String -> Maybe String
showE String
"sox"
if Maybe String -> Bool
forall a. Maybe a -> Bool
isJust Maybe String
ts
then String -> String -> String -> IO ()
rawToSoundFile String
zs String
nameSF (Maybe String -> String
forall a. HasCallStack => Maybe a -> a
fromJust Maybe String
ts)
else IO ()
printInfoF
recFileName :: IO String
recFileName :: IO String
recFileName = do
String -> IO ()
putStrLn String
"Please, specify the name of the resulting sound file. Please, do NOT use '}' character and space or control characters!"
String
nameOfSoundFile <- IO String
getLine
let nameSF :: String
nameSF = (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
filter (\Char
x -> Bool -> Bool
not (Char -> Bool
isSpace Char
x) Bool -> Bool -> Bool
&& Bool -> Bool
not (Char -> Bool
isControl Char
x) Bool -> Bool -> Bool
&& Char
x Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'}') String
nameOfSoundFile
String -> IO String
forall (m :: * -> *) a. Monad m => a -> m a
return String
nameSF
getCtrl :: String -> IO String
getCtrl :: String -> IO String
getCtrl String
zs = do
String
xs <- IO String
getLine
let ys :: String
ys = Int -> String -> String
forall a. Int -> [a] -> [a]
take (String -> Int
nSymbols (String -> Int) -> (String -> String) -> String -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String, (String, String)) -> String
forall a b. (a, b) -> a
fst ((String, (String, String)) -> String)
-> (String -> (String, (String, String))) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> (String, (String, String))
genControl (String -> Int) -> String -> Int
forall a b. (a -> b) -> a -> b
$ String
zs) String
xs
String -> IO String
forall (m :: * -> *) a. Monad m => a -> m a
return String
ys
recFNAndCtrl :: String -> Int -> IO String
recFNAndCtrl :: String -> Int -> IO String
recFNAndCtrl String
zs Int
n
| Int -> Bool
forall a. Integral a => a -> Bool
odd Int
n = IO String
recFileName
| Bool
otherwise = String -> IO String
getCtrl String
zs
nameAndControl :: String -> [Int] -> IO [String]
nameAndControl :: String -> [Int] -> IO [String]
nameAndControl String
zs = (Int -> IO String) -> [Int] -> IO [String]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (String -> Int -> IO String
recFNAndCtrl String
zs)
rawToSoundFile :: String -> String -> FilePath -> IO ()
rawToSoundFile :: String -> String -> String -> IO ()
rawToSoundFile String
zs String
nameSF String
executablePath
| String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
zs = do
String -> [String] -> IO ()
callProcess String
executablePath [String
"-r22050",String
"-c1",String
"-L",String
"-esigned-integer",String
"-b16", String
nameSF String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
".raw", String
nameSF String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
".wav"]
String -> IO ()
removeFile (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
nameSF String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
".raw"
| Bool
otherwise = do
let ws :: (String, String)
ws = (String, (String, String)) -> (String, String)
forall a b. (a, b) -> b
snd ((String, (String, String)) -> (String, String))
-> (String -> (String, (String, String)))
-> String
-> (String, String)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> (String, (String, String))
genControl (String -> (String, String)) -> String -> (String, String)
forall a b. (a -> b) -> a -> b
$ String
zs
String -> [String] -> IO ()
callProcess String
executablePath [String
"-r22050",String
"-c1",String
"-L",String
"-esigned-integer",String
"-b16", String
nameSF String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
".raw", (String, String) -> String
forall a b. (a, b) -> a
fst (String, String)
ws, String
nameSF String -> String -> String
forall a. [a] -> [a] -> [a]
++ (String, String) -> String
forall a b. (a, b) -> b
snd (String, String)
ws]
String -> IO ()
removeFile (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
nameSF String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
".raw"
printInfoF :: IO ()
printInfoF :: IO ()
printInfoF = do
String -> IO ()
putStr String
"You have a resulting file in a raw PCM format with bitrate 22050 Hz and 1 channel (mono) in the .raw format. "
String -> IO ()
putStr String
"You can further process it by yourself manually, otherwise, please, install FFMpeg or LibAV executables in the directory mentioned in the variable PATH"
String -> IO ()
putStrLn String
" and then run: "
String -> IO ()
putStrLn String
"\"name_of_FFMpeg_or_LibAV_executable\" -f s16le -acodec pcm_s16le -ac 1 -ar 22050 -i \"name_Of_the_sound_file\" \"the_same_name_without_.raw_ending_and_with_.wav_ending\""
String -> IO ()
putStrLn String
""
String -> IO ()
putStrLn String
"OR you can install SoX executable in the directory mentioned in the variable PATH and then run: "
String -> IO ()
putStrLn String
"\"Path_to_the_SoX_executable\" -b16 -r22050 -c1 -e signed-integer -L \"name_of_the_file_in_raw_format_with_new._prefix\" \"name_of_the_file_in_raw_format_with_new._prefix\" in the terminal."