Safe Haskell | Safe |
---|---|

Language | Haskell98 |

Common math functions.

## Synopsis

- half_pi :: Floating a => a
- two_pi :: Floating n => n
- mul_add_hs :: Num a => a -> a -> a -> a
- sc3_truncate :: RealFrac a => a -> a
- sc3_round :: RealFrac a => a -> a
- sc3_ceiling :: RealFrac a => a -> a
- sc3_floor :: RealFrac a => a -> a
- sc3_round_to :: RealFrac n => n -> n -> n
- sc3_idiv :: RealFrac n => n -> n -> n
- sc3_mod :: RealFrac n => n -> n -> n
- fmod_f32 :: Float -> Float -> Float
- fmod_f64 :: Double -> Double -> Double
- sc3_clip :: Ord a => a -> a -> a -> a
- clip_hs :: Ord a => (a, a) -> a -> a
- sc3_mod_alt :: RealFrac a => a -> a -> a
- sc3_wrap_ni :: RealFrac a => a -> a -> a -> a
- wrap_hs :: RealFrac n => (n, n) -> n -> n
- sc3_wrap :: RealFrac n => n -> n -> n -> n
- generic_wrap :: (Ord a, Num a) => (a, a) -> a -> a
- bin_to_freq :: (Fractional n, Integral i) => n -> i -> i -> n
- midi_to_cps :: Floating a => a -> a
- cps_to_midi :: Floating a => a -> a
- cps_to_oct :: Floating a => a -> a
- oct_to_cps :: Floating a => a -> a
- degree_to_key :: RealFrac a => [a] -> a -> a -> a
- amp_to_db :: Floating a => a -> a
- db_to_amp :: Floating a => a -> a
- midi_to_ratio :: Floating a => a -> a
- ratio_to_midi :: Floating a => a -> a
- cps_to_incr :: Fractional a => a -> a -> a -> a
- incr_to_cps :: Fractional a => a -> a -> a -> a
- pan2_f :: Fractional t => (t -> t) -> t -> t -> (t, t)
- lin_pan2 :: Fractional t => t -> t -> (t, t)
- eq_pan2 :: Floating t => t -> t -> (t, t)
- sc3_properFraction :: RealFrac t => t -> (t, t)
- sc3_dif_sqr :: Num a => a -> a -> a
- sc3_hypot :: Floating a => a -> a -> a
- sc3_hypotx :: (Ord a, Floating a) => a -> a -> a
- foldToRange :: (Ord a, Num a) => a -> a -> a -> a
- sc3_fold :: (Ord a, Num a) => a -> a -> a -> a
- sc3_distort :: Fractional n => n -> n
- sc3_softclip :: (Ord n, Fractional n) => n -> n
- sc3_true :: Num n => n
- sc3_false :: Num n => n
- sc3_not :: (Ord n, Num n) => n -> n
- sc3_bool :: Num n => Bool -> n
- sc3_comparison :: Num n => (n -> n -> Bool) -> n -> n -> n
- sc3_eq :: (Num n, Eq n) => n -> n -> n
- sc3_neq :: (Num n, Eq n) => n -> n -> n
- sc3_lt :: (Num n, Ord n) => n -> n -> n
- sc3_lte :: (Num n, Ord n) => n -> n -> n
- sc3_gt :: (Num n, Ord n) => n -> n -> n
- sc3_gte :: (Num n, Ord n) => n -> n -> n
- data Clip_Rule
- apply_clip_rule :: Ord n => Clip_Rule -> n -> n -> n -> n -> n -> Maybe n
- urange :: Fractional a => a -> a -> a -> a
- range_muladd :: Fractional t => t -> t -> (t, t)
- range :: Fractional a => a -> a -> a -> a
- range_hs :: Fractional a => (a, a) -> a -> a
- linlin_muladd :: Fractional t => t -> t -> t -> t -> (t, t)
- linlin_hs :: Fractional a => (a, a) -> (a, a) -> a -> a
- sc3_linlin :: Fractional a => a -> a -> a -> a -> a -> a
- linlin_enum_plain :: (Enum t, Enum u) => t -> u -> t -> u
- linlin_enum :: (Enum t, Enum u) => (t, t) -> (u, u) -> t -> Maybe u
- linlin_enum_err :: (Enum t, Enum u) => (t, t) -> (u, u) -> t -> u
- linlin_eq :: (Eq a, Num a) => (a, a) -> (a, a) -> a -> Maybe a
- linlin_eq_err :: (Eq a, Num a) => (a, a) -> (a, a) -> a -> a
- linexp_hs :: Floating a => (a, a) -> (a, a) -> a -> a
- lin_exp :: Floating a => a -> a -> a -> a -> a -> a
- sc3_linexp :: (Ord a, Floating a) => a -> a -> a -> a -> a -> a
- sc3_explin :: (Ord a, Floating a) => a -> a -> a -> a -> a -> a
- sc3_expexp :: (Ord a, Floating a) => a -> a -> a -> a -> a -> a
- sc3_lincurve :: (Ord a, Floating a) => a -> a -> a -> a -> a -> a -> a
- sc3_curvelin :: (Ord a, Floating a) => a -> a -> a -> a -> a -> a -> a
- double_pp :: Int -> Double -> String
- real_pp :: Double -> String
- parse_double :: String -> Maybe Double

# Documentation

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

Multiply and add, ordinary haskell argument order.
See also `mul_add`

of the `MulAdd`

class.

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

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

`fromInteger`

of `truncate`

.

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

`fromInteger`

of `ceiling`

.

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

Variant of `SC3`

`roundTo`

function.

sc3_round_to (2/3) 0.25 == 0.75

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

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]

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

`SC3`

clip function. Clip *n* to within range *(i,j)*. `clip`

is a `UGen`

.

map (\n -> sc3_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 `sc3_clip`

with haskell argument structure.

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

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

Fractional modulo, alternate implementation.

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

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

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

map (sc3_wrap_ni 0 5) [4,5,6] == [4,0,1] map (sc3_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]

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

Variant of `wrap_hs`

with `SC3`

argument ordering.

map (\n -> sc3_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 #

Given sample-rate *sr* and bin-count *n* calculate frequency of *i*th bin.

bin_to_freq 44100 2048 32 == 689.0625

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 fractional 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 #

Cycles per second to linear octave (4.75 = A4 = 440).

map (cps_to_oct . midi_to_cps) [60,63,69] == [4.0,4.25,4.75]

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

Linear octave to cycles per second.

map (cps_to_midi . oct_to_cps) [4.0,4.25,4.75] == [60,63,69]

degree_to_key :: RealFrac a => [a] -> a -> a -> a Source #

Degree, scale and steps per octave to key.

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]

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

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

Pan2 function, identity is linear, sqrt is equal power.

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

Linear pan.

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

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

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

a^2 - b^2.

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

Euclidean distance function (`sqrt`

of sum of squares).

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

SC3 hypotenuse approximation function.

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]

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

Variant of `foldToRange`

with `SC3`

argument ordering.

sc3_distort :: Fractional n => n -> n Source #

SC3 distort operator.

sc3_softclip :: (Ord n, Fractional n) => n -> n Source #

SC3 softclip operator.

# Bool

sc3_not :: (Ord n, Num n) => n -> n Source #

Lifted `not`

.

sc3_not sc3_true == sc3_false sc3_not sc3_false == sc3_true

sc3_comparison :: Num n => (n -> n -> Bool) -> n -> n -> n Source #

Lift comparison function.

# Eq

# Ord

# Clip Rule

Enumeration of clipping rules.

## Instances

Bounded Clip_Rule Source # | |

Enum Clip_Rule Source # | |

Defined in Sound.SC3.Common.Math succ :: Clip_Rule -> Clip_Rule # pred :: Clip_Rule -> Clip_Rule # fromEnum :: Clip_Rule -> Int # enumFrom :: Clip_Rule -> [Clip_Rule] # enumFromThen :: Clip_Rule -> Clip_Rule -> [Clip_Rule] # enumFromTo :: Clip_Rule -> Clip_Rule -> [Clip_Rule] # enumFromThenTo :: Clip_Rule -> Clip_Rule -> Clip_Rule -> [Clip_Rule] # |

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

Clip a value that is expected to be within an input range to an output range, according to a rule.

let f r = map (\x -> apply_clip_rule r 0 1 (-1) 1 x) [-1,0,0.5,1,2] in map f [minBound .. maxBound]

# LinLin

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 #

Tuple variant of `range`

.

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_hs :: Fractional a => (a, a) -> (a, a) -> a -> a Source #

`sc3_linlin`

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

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

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

Map from one linear range to another linear range.

r = [0,0.125,0.25,0.375,0.5,0.625,0.75,0.875,1] map (\i -> sc3_linlin i (-1) 1 0 1) [-1,-0.75 .. 1] == r

linlin_enum_plain :: (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_plain 'a' 'A' 'e' == 'E' linlin_enum_plain 0 (-50) 16 == -34 linlin_enum_plain 0 (-50) (-1) == -51

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

Variant of `linlin_enum_plain`

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.

# LinExp

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

Linear to exponential range conversion. Rule is as at linExp UGen, haskell manner argument ordering. Destination values must be nonzero and have the same sign.

map (floor . linexp_hs (1,2) (10,100)) [0,1,1.5,2,3] == [1,10,31,100,1000] map (floor . linexp_hs (-2,2) (1,100)) [-3,-2,-1,0,1,2,3] == [0,1,3,10,31,100,316]

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

Variant of `linexp_hs`

with argument ordering as at `linExp`

UGen.

map (\i -> lin_exp i 1 2 1 3) [1,1.1 .. 2] map (\i -> floor (lin_exp i 1 2 10 100)) [0,1,1.5,2,3]

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

`SimpleNumber.linexp`

shifts from linear to exponential ranges.

map (sc3_linexp 1 2 1 3) [1,1.1 .. 2]

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

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

`SimpleNumber.explin`

is the inverse of linexp.

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

# ExpExp

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

Translate from one exponential range to another.

map (sc3_expexp 0.1 10 4.3 100) [1.. 10]

# LinCurve

sc3_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 . sc3_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 (sc3_lincurve c 0 1 (-1) 1) [0,0.01 .. 1]) [-6,-4 .. 6])

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

Inverse of `sc3_lincurve`

.

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

# PP

double_pp :: Int -> Double -> String Source #

The default show is odd, 0.05 shows as 5.0e-2.

unwords (map (double_pp 4) [0.0001,0.001,0.01,0.1,1.0]) == "0.0001 0.001 0.01 0.1 1.0"

real_pp :: Double -> String Source #

Print as integer if integral, else as real.

unwords (map real_pp [0.0001,0.001,0.01,0.1,1.0]) == "0.0001 0.001 0.01 0.1 1"