Sound.SC3.Common.Math

Synopsis

# Documentation

half_pi :: Floating a => a Source #

Half pi.

half_pi == 1.5707963267948966

two_pi :: Floating n => n Source #

Two pi.

two_pi == 6.283185307179586

mul_add_hs :: Num a => a -> a -> a -> a Source #

Multiply and add, ordinary haskell argument order. mul_add is a method of the MulAdd class.

map (mul_add_hs 2 3) [1,2] == [5,7] && map (mul_add_hs 3 4) [1,2] == [7,10]

sc_truncate :: RealFrac a => a -> a Source #

sc_round :: RealFrac a => a -> a Source #

sc_ceiling :: RealFrac a => a -> a Source #

sc_floor :: RealFrac a => a -> a Source #

sc3_round_to :: RealFrac n => n -> n -> n Source #

Variant of SC3 roundTo function.

let r = [0,0,0.25,0.25,0.5,0.5,0.5,0.75,0.75,1,1]
in map (sc3_round_to 0.25) [0,0.1 .. 1] == r

sc3_idiv :: RealFrac n => n -> n -> n Source #

sc3_mod :: RealFrac n => n -> n -> n Source #

The SC3 % UGen operator is the mod' function.

> 1.5 % 1.2 // ~= 0.3
> -1.5 % 1.2 // ~= 0.9
> 1.5 % -1.2 // ~= -0.9
> -1.5 % -1.2 // ~= -0.3
let (%) = sc3_mod
1.5 % 1.2 ~= 0.3
(-1.5) % 1.2 ~= 0.9
1.5 % (-1.2) ~= -0.9
(-1.5) % (-1.2) ~= -0.3
> 1.2 % 1.5 // ~= 1.2
> -1.2 % 1.5 // ~= 0.3
> 1.2 % -1.5 // ~= -0.3
> -1.2 % -1.5 // ~= -1.2
1.2 % 1.5 ~= 1.2
(-1.2) % 1.5 ~= 0.3
1.2 % (-1.5) ~= -0.3
(-1.2) % (-1.5) ~= -1.2
map (\n -> sc3_mod n 12.0) [-1.0,12.25,15.0] == [11.0,0.25,3.0]

Type specialised sc3_mod.

Type specialised sc3_mod.

sc_clip :: Ord a => a -> a -> a -> a Source #

SC3 clip function. Clip n to within range (i,j). clip is a UGen.

map (\n -> sc_clip n 5 10) [3..12] == [5,5,5,6,7,8,9,10,10,10]

clip_hs :: Ord a => (a, a) -> a -> a Source #

Variant of sc_clip with haskell argument structure.

map (clip_hs (5,10)) [3..12] == [5,5,5,6,7,8,9,10,10,10]

sc_mod :: RealFrac a => a -> a -> a Source #

Fractional modulo.

map (\n -> sc_mod n 12.0) [-1.0,12.25,15.0] == [11.0,0.25,3.0]

sc_wrap_ni :: RealFrac a => a -> a -> a -> a Source #

Wrap function that is non-inclusive at right edge, ie. the Wrap UGen rule.

map (sc_wrap_ni 0 5) [4,5,6] == [4,0,1]
map (sc_wrap_ni 5 10) [3..12] == [8,9,5,6,7,8,9,5,6,7]

wrap_hs :: RealFrac n => (n, n) -> n -> n Source #

Wrap n to within range (i,j), ie. AbstractFunction.wrap, ie. inclusive at right edge. wrap is a UGen, hence prime.

> [5,6].wrap(0,5) == [5,0]
map (wrap_hs (0,5)) [5,6] == [5,0]
> [9,10,5,6,7,8,9,10,5,6].wrap(5,10) == [9,10,5,6,7,8,9,10,5,6]
map (wrap_hs (5,10)) [3..12] == [9,10,5,6,7,8,9,10,5,6]

sc_wrap :: RealFrac n => n -> n -> n -> n Source #

Variant of wrap' with SC3 argument ordering.

map (\n -> sc_wrap n 5 10) [3..12] == map (wrap_hs (5,10)) [3..12]

generic_wrap :: (Ord a, Num a) => (a, a) -> a -> a Source #

Generic variant of wrap'.

> [5,6].wrap(0,5) == [5,0]
map (generic_wrap (0,5)) [5,6] == [5,0]
> [9,10,5,6,7,8,9,10,5,6].wrap(5,10) == [9,10,5,6,7,8,9,10,5,6]
map (generic_wrap (5::Integer,10)) [3..12] == [9,10,5,6,7,8,9,10,5,6]

bin_to_freq :: (Fractional n, Integral i) => n -> i -> i -> n Source #

midi_to_cps :: Floating a => a -> a Source #

Midi note number to cycles per second.

map (floor . midi_to_cps) [0,24,69,120,127] == [8,32,440,8372,12543]
map (floor . midi_to_cps) [-36,138] == [1,23679]

cps_to_midi :: Floating a => a -> a Source #

Cycles per second to midi note number.

map (round . cps_to_midi) [8,32,440,8372,12543] == [0,24,69,120,127]
map (round . cps_to_midi) [1,24000] == [-36,138]

cps_to_oct :: Floating a => a -> a Source #

oct_to_cps :: Floating a => a -> a Source #

amp_to_db :: Floating a => a -> a Source #

Linear amplitude to decibels.

map (round . amp_to_db) [0.01,0.05,0.0625,0.125,0.25,0.5] == [-40,-26,-24,-18,-12,-6]

db_to_amp :: Floating a => a -> a Source #

Decibels to linear amplitude.

map (floor . (* 100). db_to_amp) [-40,-26,-24,-18,-12,-6] == [01,05,06,12,25,50]

midi_to_ratio :: Floating a => a -> a Source #

Fractional midi note interval to frequency multiplier.

map midi_to_ratio [0,7,12] == [1,1.4983070768766815,2]

ratio_to_midi :: Floating a => a -> a Source #

Inverse of midi_to_ratio.

map ratio_to_midi [3/2,2] == [7.019550008653875,12]

urange :: Fractional a => a -> a -> a -> a Source #

Scale uni-polar (0,1) input to linear (l,r) range

map (urange 3 4) [0,0.5,1] == [3,3.5,4]

range_muladd :: Fractional t => t -> t -> (t, t) Source #

Calculate multiplier and add values for range transform.

range_muladd 3 4 == (0.5,3.5)

range :: Fractional a => a -> a -> a -> a Source #

Scale bi-polar (-1,1) input to linear (l,r) range. Note that the argument order is not the same as linlin.

map (range 3 4) [-1,0,1] == [3,3.5,4]
map (\x -> let (m,a) = linlin_muladd (-1) 1 3 4 in x * m + a) [-1,0,1] == [3,3.5,4]

range_hs :: Fractional a => (a, a) -> a -> a Source #

data Clip_Rule Source #

Constructors

 Clip_None Clip_Left Clip_Right Clip_Both

Instances

 Source # Methods Source # MethodsenumFrom :: Clip_Rule -> [Clip_Rule] #

apply_clip_rule :: Ord n => Clip_Rule -> n -> n -> n -> n -> n -> Maybe n Source #

linlin_muladd :: Fractional t => t -> t -> t -> t -> (t, t) Source #

Calculate multiplier and add values for linlin transform.

range_muladd 3 4 == (0.5,3.5)
linlin_muladd (-1) 1 3 4 == (0.5,3.5)
linlin_muladd 0 1 3 4 == (1,3)
linlin_muladd (-1) 1 0 1 == (0.5,0.5)
linlin_muladd (-0.3) 1 (-1) 1

linlin :: Fractional a => a -> a -> a -> a -> a -> a Source #

Map from one linear range to another linear range.

map (\i -> linlin i (-1) 1 0 1) [-1,-0.9 .. 1.0]

linlin_hs :: Fractional a => (a, a) -> (a, a) -> a -> a Source #

Variant with a more typical argument structure, ranges as pairs and input last.

map (linlin_hs (0,127) (-0.5,0.5)) [0,63.5,127]

linlin_enum' :: (Enum t, Enum u) => t -> u -> t -> u Source #

Given enumeration from dst that is in the same relation as n is from src.

linlin _enum' 'a' 'A' 'e' == 'E'
linlin_enum' 0 (-50) 16 == -34
linlin_enum' 0 (-50) (-1) == -51

linlin_enum :: (Enum t, Enum u) => (t, t) -> (u, u) -> t -> Maybe u Source #

Variant of linlin_enum' that requires src and dst ranges to be of equal size, and for n to lie in src.

linlin_enum (0,100) (-50,50) 0x10 == Just (-34)
linlin_enum (-50,50) (0,100) (-34) == Just 0x10
linlin_enum (0,100) (-50,50) (-1) == Nothing

linlin_enum_err :: (Enum t, Enum u) => (t, t) -> (u, u) -> t -> u Source #

Erroring variant.

linlin_eq :: (Eq a, Num a) => (a, a) -> (a, a) -> a -> Maybe a Source #

Variant of linlin that requires src and dst ranges to be of equal size, thus with constraint of Num and Eq instead of Fractional.

linlin_eq (0,100) (-50,50) 0x10 == Just (-34)
linlin_eq (-50,50) (0,100) (-34) == Just 0x10

linlin_eq_err :: (Eq a, Num a) => (a, a) -> (a, a) -> a -> a Source #

Erroring variant.

sc_linexp :: (Ord a, Floating a) => a -> a -> a -> a -> a -> a Source #

SimpleNumber.linexp shifts from linear to exponential ranges.

> [1,1.5,2].collect({|i| i.linexp(1,2,10,100).floor}) == [10,31,100]
map (floor . sc_linexp 1 2 10 100) [0,1,1.5,2,3] == [10,10,31,100,100]

sc_explin :: (Ord a, Floating a) => a -> a -> a -> a -> a -> a Source #

SimpleNumber.explin is the inverse of linexp.

map (sc_explin 10 100 1 2) [10,10,31,100,100]

sc_expexp :: (Ord a, Floating a) => a -> a -> a -> a -> a -> a Source #

sc_lincurve :: (Ord a, Floating a) => a -> a -> a -> a -> a -> a -> a Source #

Map x from an assumed linear input range (src_l,src_r) to an exponential curve output range (dst_l,dst_r). curve is like the parameter in Env. Unlike with linexp, the output range may include zero.

> (0..10).lincurve(0,10,-4.3,100,-3).round == [-4,24,45,61,72,81,87,92,96,98,100]
let f = round . sc_lincurve (-3) 0 10 (-4.3) 100
in map f [0 .. 10] == [-4,24,45,61,72,81,87,92,96,98,100]
import Sound.SC3.Plot
plotTable (map (\c-> map (sc_lincurve c 0 1 (-1) 1) [0,0.01 .. 1]) [-6,-4 .. 6])

sc_curvelin :: (Ord a, Floating a) => a -> a -> a -> a -> a -> a -> a Source #

Inverse of sc_lincurve.

let f = round . sc_curvelin (-3) (-4.3) 100 0 10
in map f [-4,24,45,61,72,81,87,92,96,98,100] == [0..10]

linexp_hs :: Floating a => (a, a) -> (a, a) -> a -> a Source #

lin_exp :: Floating a => a -> a -> a -> a -> a -> a Source #

Exponential range conversion.

map (\i -> lin_exp i 1 2 1 3) [1,1.1 .. 2]

cps_to_incr :: Fractional a => a -> a -> a -> a Source #

sr = sample rate, r = cycle (two-pi), cps = frequency

cps_to_incr 48000 128 375 == 1
cps_to_incr 48000 two_pi 458.3662361046586 == 6e-2

incr_to_cps :: Fractional a => a -> a -> a -> a Source #

Inverse of cps_to_incr.

incr_to_cps 48000 128 1 == 375

lin_pan2 :: Fractional t => t -> t -> (t, t) Source #

Linear pan.

map (lin_pan2 1) [-1,0,1] == [(1,0),(0.5,0.5),(0,1)]

sc3_properFraction :: RealFrac t => t -> (t, t) Source #

sc_dif_sqr :: Num a => a -> a -> a Source #

sc_hypot :: Floating a => a -> a -> a Source #

sc_hypotx :: (Ord a, Floating a) => a -> a -> a Source #

foldToRange :: (Ord a, Num a) => a -> a -> a -> a Source #

Fold k to within range (i,j), ie. AbstractFunction.fold

map (foldToRange 5 10) [3..12] == [7,6,5,6,7,8,9,10,9,8]

fold_ :: (Ord a, Num a) => a -> a -> a -> a Source #

Variant of foldToRange with SC3 argument ordering.