Created
February 1, 2012 13:42
-
-
Save abailly/1716994 to your computer and use it in GitHub Desktop.
sound module
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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