repa-sndfile-3.2.3.2: exec/gensine.hs
{-# LANGUAGE TypeOperators #-}
{-|
Module : $Header$
CopyRight : (c) 8c6794b6
License : BSD3
Maintainer : 8c6794b6@gmail.com
Stability : experimental
Portability : non-portable
Generates sine wave.
-}
module Main where
import Control.Monad (void)
import Data.Array.Repa (Array, DIM2, computeP)
import Data.Array.Repa.Repr.ForeignPtr (F)
import qualified Sound.File.Sndfile as S
import Sound.File.Sndfile.Buffer.Vector
import System.Environment (getArgs)
import Data.Array.Repa.IO.Sndfile
import Data.Array.Repa.IO.Sndfile.Examples (genSine, genSineV)
main :: IO ()
main = do
args <- getArgs
case args of
dur:frq:path:mode:_ ->
let dur' = read dur
frq' = read frq
fmt = wav16 {frames = 48000 * dur'}
in case mode of
"buf" -> do
arr <- computeP (genSine dur' frq') :: IO (Array F DIM2 Double)
writeSF path fmt arr
"vec" -> void $ S.writeFile fmt path (toBuffer $ genSineV dur' frq')
_ -> usage
_ -> usage
usage :: IO ()
usage = error "Usage: duration freq path [buf|vec]"
{- ---------------------------------------------------------------------------
- Write stereo sound, using different frequency for each channel.
- Modify header format to 'channels = 2' and run.
genSine :: Int -> Double -> Array DIM2 Double
genSine dur frq =
let sh = Z :. 2 :. (dur * 48000) :: DIM2
in fromFunction sh $ \(_ :. i :. j) ->
sin (frq * (fromIntegral i + 1) * fromIntegral j * pi * 2 / 48000)
Generating 30 seconds of 440 hz sine wav took about 0.2 sec with repa, in 8 core
machine, using 8 threads. It uses 4x more memory of the size of result file.
For just reading and writing sound files as haskell data, storable vector took
almost same execution time. It took about 0.25sec in same machine, memory usage
was less.
-}