40 lines
1.2 KiB
Haskell
40 lines
1.2 KiB
Haskell
module MorsePlaySox (play) where
|
|
|
|
import Sound.Sox.Play
|
|
import Sound.Sox.Option.Format
|
|
import Sound.Sox.Signal.List
|
|
import Data.Int
|
|
import System.Exit
|
|
import MorseCode
|
|
|
|
samps = 15 -- samples/cycle
|
|
freq = 700 -- cycles/second (frequency)
|
|
rate = samps * freq -- samples/second (sampling rate)
|
|
|
|
type Samples = [Int16]
|
|
|
|
-- One cycle of silence and a sine wave.
|
|
mute, sine :: Samples
|
|
mute = replicate samps 0
|
|
sine = let n = fromIntegral samps
|
|
f k = 8000.0 * sin (2*pi*k/n)
|
|
in map (round . f . fromIntegral) [0..samps-1]
|
|
|
|
-- Repeat samples until we have the specified duration in seconds.
|
|
rep :: Float -> Samples -> Samples
|
|
rep dur = take n . cycle
|
|
where n = round (dur * fromIntegral rate)
|
|
|
|
-- Convert Morse symbols to samples. Durations are in seconds, based on
|
|
-- http://en.wikipedia.org/wiki/Morse_code#Representation.2C_timing_and_speeds.
|
|
toSamples :: MSym -> Samples
|
|
toSamples Dot = rep 0.1 sine
|
|
toSamples Dash = rep 0.3 sine
|
|
toSamples SGap = rep 0.1 mute
|
|
toSamples CGap = rep 0.3 mute
|
|
toSamples WGap = rep 0.7 mute
|
|
|
|
-- Interpret the stream of Morse symbols as sound.
|
|
play :: Morse -> IO ExitCode
|
|
play = simple put none rate . concatMap toSamples
|