module Sox.File where
import qualified BinarySample as BinSmp
import qualified Sox as Sox
import System.Cmd(rawSystem)
import System.Exit(ExitCode)
import Data.List(isSuffixOf)
import qualified Algebra.RealField as RealField
import qualified Algebra.Field as Field
import PreludeBase
import NumericPrelude
render :: (RealField.C a, BinSmp.C v) =>
FilePath -> a -> (a -> [v]) -> IO ExitCode
render fileName sampleRate renderer =
write fileName sampleRate (renderer sampleRate)
renderMono :: (RealField.C a) =>
FilePath -> a -> (a -> [a]) -> IO ExitCode
renderMono fileName sampleRate renderer =
writeMono fileName sampleRate (renderer sampleRate)
renderStereo :: (RealField.C a) =>
FilePath -> a -> (a -> [(a,a)]) -> IO ExitCode
renderStereo fileName sampleRate renderer =
writeStereo fileName sampleRate (renderer sampleRate)
write :: (RealField.C a, BinSmp.C v) =>
FilePath -> a -> [v] -> IO ExitCode
write fileName sampleRate signal =
writeSignalRaw fileName [] sampleRate
(BinSmp.numChannels (head signal))
(BinSmp.signalToBinary signal)
writeMono :: (RealField.C a) =>
FilePath -> a -> [a] -> IO ExitCode
writeMono fileName sampleRate signal =
writeSignalRaw fileName []
sampleRate 1 (BinSmp.signalToBinaryMono signal)
writeStereo :: (RealField.C a) =>
FilePath -> a -> [(a,a)] -> IO ExitCode
writeStereo fileName sampleRate signal =
writeSignalRaw fileName []
sampleRate 2 (BinSmp.signalToBinaryStereo signal)
writeSignalRaw :: (RealField.C a) =>
FilePath -> [String] -> a -> Int -> [Int] -> IO ExitCode
writeSignalRaw fileName soxOptions sampleRate numChannels stream =
let fileNameRaw = fileName ++ ".sw"
in do BinSmp.writeInt16Stream fileNameRaw stream
rawToAIFF fileName soxOptions sampleRate numChannels
encode fileName
rawToAIFF :: (RealField.C a) =>
FilePath -> [String] -> a -> Int -> IO ExitCode
rawToAIFF fileName soxOptions sampleRate numChannels =
let fileNameRaw = fileName ++ ".sw"
fileNameAIFF = fileName ++ ".aiff"
in rawSystem "sox"
(soxOptions ++
Sox.sampleRateOption sampleRate ++
Sox.channelOption numChannels ++
[fileNameRaw, fileNameAIFF])
encode :: FilePath -> IO ExitCode
encode fileName =
let fileNameAIFF = fileName ++ ".aiff"
fileNameMP3 = fileName ++ ".mp3"
in do rawSystem "oggenc" ["--quality", "5", fileNameAIFF]
rawSystem "lame" ["-h", fileNameAIFF, fileNameMP3]
readAIFFMono :: (Field.C a) => FilePath -> IO [a]
readAIFFMono file =
let stem = if isSuffixOf ".aiff" file
then take (length file 5) file
else file
tmp = stem ++ ".sw"
in do
rawSystem "sox" [file, tmp]
fmap (map BinSmp.int16ToNum) (BinSmp.readInt16Stream tmp)