{-# LANGUAGE BangPatterns, ExistentialQuantification,
ScopedTypeVariables, FlexibleContexts #-}
module Euterpea.IO.Audio.IO (
outFile, outFileNorm,
maxSample) where
import Control.Arrow.ArrowP
import Control.SF.SF
import Euterpea.IO.Audio.Types hiding (Signal)
import Codec.Wav
import Data.Audio
import Data.Array.Unboxed
import Data.Int
type Signal clk a b = ArrowP SF clk a b
outFile :: forall a p. (AudioSample a, Clock p) =>
String
-> Double
-> Signal p () a
-> IO ()
outFile :: forall a p.
(AudioSample a, Clock p) =>
String -> Double -> Signal p () a -> IO ()
outFile = ([Double] -> [Double])
-> String -> Double -> Signal p () a -> IO ()
forall a p.
(AudioSample a, Clock p) =>
([Double] -> [Double])
-> String -> Double -> Signal p () a -> IO ()
outFileHelp' [Double] -> [Double]
forall a. a -> a
id
normList :: [Double] -> [Double]
normList :: [Double] -> [Double]
normList [Double]
xs = (Double -> Double) -> [Double] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
map (Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
mx) [Double]
xs
where mx :: Double
mx = Double -> Double -> Double
forall a. Ord a => a -> a -> a
max Double
1.0 ([Double] -> Double
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum ((Double -> Double) -> [Double] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
map Double -> Double
forall a. Num a => a -> a
abs [Double]
xs))
outFileNorm :: forall a p. (AudioSample a, Clock p) =>
String
-> Double
-> Signal p () a
-> IO ()
outFileNorm :: forall a p.
(AudioSample a, Clock p) =>
String -> Double -> Signal p () a -> IO ()
outFileNorm = ([Double] -> [Double])
-> String -> Double -> Signal p () a -> IO ()
forall a p.
(AudioSample a, Clock p) =>
([Double] -> [Double])
-> String -> Double -> Signal p () a -> IO ()
outFileHelp' [Double] -> [Double]
normList
outFileHelp :: forall a p. (AudioSample a, Clock p) =>
([Double] -> [Double])
-> String
-> Double
-> Signal p () a
-> IO ()
outFileHelp :: forall a p.
(AudioSample a, Clock p) =>
([Double] -> [Double])
-> String -> Double -> Signal p () a -> IO ()
outFileHelp [Double] -> [Double]
f String
filepath Double
dur Signal p () a
sf =
let sr :: Double
sr = p -> Double
forall p. Clock p => p -> Double
rate (p
forall a. HasCallStack => a
undefined :: p)
numChannels :: Int
numChannels = a -> Int
forall a. AudioSample a => a -> Int
numChans (a
forall a. HasCallStack => a
undefined :: a)
numSamples :: Int
numSamples = Double -> Int
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
truncate (Double
dur Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
sr) Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
numChannels
dat :: [Int32]
dat = (Double -> Int32) -> [Double] -> [Int32]
forall a b. (a -> b) -> [a] -> [b]
map (Double -> Int32
forall a. Audible a => Double -> a
fromSample (Double -> Int32) -> (Double -> Double) -> Double -> Int32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Double -> Double -> Double
forall a. Num a => a -> a -> a
*Double
0.999))
([Double] -> [Double]
f (Double -> Signal p () a -> [Double]
forall a p.
(AudioSample a, Clock p) =>
Double -> Signal p () a -> [Double]
toSamples Double
dur Signal p () a
sf)) :: [Int32]
array :: UArray Int Int32
array = (Int, Int) -> [Int32] -> UArray Int Int32
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
(i, i) -> [e] -> a i e
listArray (Int
0, Int
numSamplesInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) [Int32]
dat
aud :: Audio Int32
aud = Audio { sampleRate :: Int
sampleRate = Double -> Int
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
truncate Double
sr,
channelNumber :: Int
channelNumber = Int
numChannels,
sampleData :: UArray Int Int32
sampleData = UArray Int Int32
array }
in String -> Audio Int32 -> IO ()
forall a.
(IArray UArray a, Audible a, AudibleInWav a) =>
String -> Audio a -> IO ()
exportFile String
filepath Audio Int32
aud
outFileHelp' :: forall a p. (AudioSample a, Clock p) =>
([Double] -> [Double])
-> String
-> Double
-> Signal p () a
-> IO ()
outFileHelp' :: forall a p.
(AudioSample a, Clock p) =>
([Double] -> [Double])
-> String -> Double -> Signal p () a -> IO ()
outFileHelp' [Double] -> [Double]
f String
filepath Double
dur Signal p () a
sf =
let sr :: Double
sr = p -> Double
forall p. Clock p => p -> Double
rate (p
forall a. HasCallStack => a
undefined :: p)
numChannels :: Int
numChannels = a -> Int
forall a. AudioSample a => a -> Int
numChans (a
forall a. HasCallStack => a
undefined :: a)
numSamples :: Int
numSamples = Double -> Int
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
truncate (Double
dur Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
sr) Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
numChannels
dat :: [Int32]
dat = (Double -> Int32) -> [Double] -> [Int32]
forall a b. (a -> b) -> [a] -> [b]
map (Double -> Int32
forall a. Audible a => Double -> a
fromSample (Double -> Int32) -> (Double -> Double) -> Double -> Int32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Double -> Double -> Double
forall a. Num a => a -> a -> a
*Double
0.999) (Double -> Double) -> (Double -> Double) -> Double -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Double
forall {a}. (Ord a, Fractional a) => a -> a
clipFix)
([Double] -> [Double]
f (Double -> Signal p () a -> [Double]
forall a p.
(AudioSample a, Clock p) =>
Double -> Signal p () a -> [Double]
toSamples Double
dur Signal p () a
sf)) :: [Int32]
array :: UArray Int Int32
array = (Int, Int) -> [Int32] -> UArray Int Int32
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
(i, i) -> [e] -> a i e
listArray (Int
0, Int
numSamplesInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) [Int32]
dat
aud :: Audio Int32
aud = Audio { sampleRate :: Int
sampleRate = Double -> Int
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
truncate Double
sr,
channelNumber :: Int
channelNumber = Int
numChannels,
sampleData :: UArray Int Int32
sampleData = UArray Int Int32
array }
in String -> Audio Int32 -> IO ()
forall a.
(IArray UArray a, Audible a, AudibleInWav a) =>
String -> Audio a -> IO ()
exportFile String
filepath Audio Int32
aud where
clipFix :: a -> a
clipFix a
x = if a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
1.0 then a
1.0 else if a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< -a
1.0 then -a
1.0 else a
x
toSamples :: forall a p. (AudioSample a, Clock p) =>
Double -> Signal p () a -> [Double]
toSamples :: forall a p.
(AudioSample a, Clock p) =>
Double -> Signal p () a -> [Double]
toSamples Double
dur Signal p () a
sf =
let sr :: Double
sr = p -> Double
forall p. Clock p => p -> Double
rate (p
forall a. HasCallStack => a
undefined :: p)
numChannels :: Int
numChannels = a -> Int
forall a. AudioSample a => a -> Int
numChans (a
forall a. HasCallStack => a
undefined :: a)
numSamples :: Int
numSamples = Double -> Int
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
truncate (Double
dur Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
sr) Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
numChannels
in Int -> [Double] -> [Double]
forall a. Int -> [a] -> [a]
take Int
numSamples ([Double] -> [Double]) -> [Double] -> [Double]
forall a b. (a -> b) -> a -> b
$ (a -> [Double]) -> [a] -> [Double]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap a -> [Double]
forall a. AudioSample a => a -> [Double]
collapse ([a] -> [Double]) -> [a] -> [Double]
forall a b. (a -> b) -> a -> b
$ SF () a -> [a]
forall a. SF () a -> [a]
unfold (SF () a -> [a]) -> SF () a -> [a]
forall a b. (a -> b) -> a -> b
$ Signal p () a -> SF () a
forall (a :: * -> * -> *) p b c. ArrowP a p b c -> a b c
strip Signal p () a
sf
maxSample :: forall a p. (AudioSample a, Clock p) =>
Double -> Signal p () a -> Double
maxSample :: forall a p.
(AudioSample a, Clock p) =>
Double -> Signal p () a -> Double
maxSample Double
dur Signal p () a
sf = [Double] -> Double
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum ((Double -> Double) -> [Double] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
map Double -> Double
forall a. Num a => a -> a
abs (Double -> Signal p () a -> [Double]
forall a p.
(AudioSample a, Clock p) =>
Double -> Signal p () a -> [Double]
toSamples Double
dur Signal p () a
sf))