Skip to content

Instantly share code, notes, and snippets.

@abailly
Created February 1, 2012 13:42
Show Gist options
  • Save abailly/1716994 to your computer and use it in GitHub Desktop.
Save abailly/1716994 to your computer and use it in GitHub Desktop.
sound module
import System.Environment (getArgs)
import qualified Data.ByteString.Lazy as B
import Sound
outputSound = B.putStr.B.pack.map fromIntegral.scale (0,255)
main = do
[frequency,volume,duration] <- getArgs
let f = read frequency :: Int
let d = read duration :: Int
let a = read volume :: Double
outputSound $ computeSound f d a
module Sound where
-- this a CAF: Constant Applicative Form
samplingRate = 44000 :: Int
-- a sinusoidal wave between -1 and +1
wave frequency =
let n = samplingRate `div` frequency
in map (sin . (* (2 * pi))) [ fromIntegral i / fromIntegral n | i <- [0 .. n]]
amplitude ratio | ratio > 0 && ratio < 1 = map (*ratio)
| otherwise = id
slice seconds wave =
take (samplingRate * seconds) repeatWave
where
repeatWave = wave ++ repeatWave
scale :: (Int,Int) -> [Double] -> [Int]
scale (min,max) (x:xs) = truncate (((x + 1) / 2) * fromIntegral (max - min)) + min : scale (min,max) xs
scale _ [] = []
computeSound frequency duration volume =
slice duration $ amplitude volume $ wave frequency
import Test.HUnit
import Test.QuickCheck
import Sound
amplitude_multiply_wave_samples d =
amplitude d wave' == map (*d) wave'
where
wave' = wave 440
-- first test on sound
convert_a_frequency_to_a_wave =
take 3 (wave frequency) ~?= [0.0,6.279051952931337e-2,0.12533323356430426]
where
frequency = 440
slice_a_wave_for_a_given_number_of_seconds =
length (slice seconds aWave) ~?= 88000
where
seconds = 2
aWave = wave 440
scale_wave_to_a_single_byte_value =
take 3 (scale (0,255) aWave) ~?= [0,16,31]
where
aWave = wave 440
tests = [ convert_a_frequency_to_a_wave,
slice_a_wave_for_a_given_number_of_seconds,
scale_wave_to_a_single_byte_value]
runAllTests = runTestTT $ TestList tests
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment