66 lines
1.7 KiB
Haskell
66 lines
1.7 KiB
Haskell
-- https://hackage.haskell.org/package/bytestring-0.12.1.0/docs/Data-ByteString-Lazy.html#t:LazyByteString
|
|
import qualified Data.ByteString.Lazy as BL
|
|
|
|
-- https://hackage.haskell.org/package/bytestring-0.12.1.0/docs/Data-ByteString-Builder.html
|
|
import qualified Data.ByteString.Builder as B
|
|
|
|
import qualified Data.Foldable
|
|
import qualified System.Process
|
|
import qualified Text.Printf
|
|
|
|
type Hz = Float
|
|
type Seconds = Float
|
|
type Signal = [Float]
|
|
|
|
-- Byte strings with Little Endian 32 bit float
|
|
|
|
-- B.floatLE n :: B.Builder
|
|
|
|
outFile :: FilePath
|
|
outFile = "out.bin"
|
|
|
|
-- volume :: Float
|
|
-- volume = 0.2
|
|
|
|
-- Number of samples per second
|
|
-- ie, number of float values per second
|
|
sampleRate :: Hz
|
|
sampleRate = 48000
|
|
|
|
-- step :: Float
|
|
-- step = 0.01
|
|
|
|
|
|
duration :: Float
|
|
duration = 2.0
|
|
|
|
wave :: Float -> Hz -> Seconds -> Signal
|
|
wave volume freq duration
|
|
= map (* volume) -- adjust volume
|
|
$ map sin -- generate wave
|
|
$ map (* step) [0.0 .. sampleRate * duration]
|
|
where
|
|
step = (freq * 2 * pi) / sampleRate
|
|
|
|
sound :: Signal
|
|
sound = concat $ map (++)
|
|
[wave 0.2 440 duration
|
|
wave 0.2 frq secs
|
|
|
|
toBS :: [Float] -> B.Builder
|
|
toBS wav = Data.Foldable.fold $ map B.floatLE wav
|
|
|
|
|
|
-- LazyByteString: Serializable-friendly form of ByteString
|
|
-- https://hackage.haskell.org/package/bytestring-0.12.1.0/docs/Data-ByteString-Lazy.html#t:LazyByteString
|
|
save :: FilePath -> IO ()
|
|
save outfile = BL.writeFile outfile $ B.toLazyByteString $ toBS sound
|
|
|
|
play :: IO ()
|
|
play = do
|
|
save outFile
|
|
_ <- System.Process.runCommand
|
|
$ Text.Printf.printf "ffplay -showmode 1 -f f32le -ar %f %s" sampleRate outFile
|
|
return ()
|
|
|