Safe Haskell | None |
---|

Data flow node functions, or unit generators.

- split :: a -> (a, a)
- swap :: a -> b -> (b, a)
- two_pi :: Floating a => a
- midi_cps :: Floating a => a -> a
- mul_add :: Num a => a -> a -> a -> a
- calc_fb :: Floating a => a -> a -> a
- lin_lin :: Fractional a => a -> a -> a -> a -> a -> a
- lin_exp :: Floating a => a -> a -> a -> a -> a -> a
- clip2 :: (Num a, Ord a) => a -> a -> a
- hz_to_incr :: Fractional a => a -> a -> a -> a
- incr_to_hz :: Fractional a => a -> a -> a -> a
- lin_pan2 :: Fractional t => t -> t -> (t, t)
- k_sample_rate :: Fractional n => n
- w_radians_per_sample :: DF Float
- tbl_guard :: [a] -> [a]
- tbl_sin :: Floating n => Int -> [n]
- clipr :: K_Num a => DF a -> DF a -> DF a
- df_clip2 :: K_Num a => DF a -> DF a -> DF a
- iir1 :: K' a => a -> Binary_Op (DF a) -> DF a -> DF a
- phasor :: K_Num a => DF a -> a -> DF a -> DF a
- a_alloc_sec :: V_Id -> Float -> DF (Vec Float)
- a_delay_ph :: DF (Vec Float) -> DF Float -> DF Int32 -> DF Int32 -> DF Float
- a_delay :: DF (Vec Float) -> DF Float -> DF Int32 -> DF Float
- a_tbl_sin :: V_Id -> Int -> DF (Vec Float)
- a_lerp :: DF (Vec Float) -> DF Float -> DF Float
- tbl_phasor :: Int -> Float -> DF Float -> DF Float
- a_osc :: DF (Vec Float) -> DF Float -> Float -> DF Float
- unit_delay :: K' a => a -> DF a -> DF a
- iir2 :: K_Num a => Ternary_Op (DF a) -> DF a -> DF a
- fir1 :: K' a => a -> (DF a -> DF a -> DF b) -> DF a -> DF b
- fir2 :: Ternary_Op (DF Float) -> DF Float -> DF Float
- biquad :: Quinary_Op (DF Float) -> DF Float -> DF Float
- counter :: K_Num a => a -> DF a -> DF a
- buf_delay :: DF Int32 -> DF Float -> DF Int32 -> DF Float
- buf_comb_n :: DF Int32 -> DF Float -> DF Float -> DF Float -> DF Float
- comb_n :: V_Id -> Float -> DF Float -> DF Float -> DF Float -> DF Float
- lcg_i32 :: Int32 -> Int32 -> Int32 -> DF Int32
- lcg_glibc :: Int32 -> DF Int32
- randi :: Int32 -> DF Int32
- randf :: Int32 -> DF Float
- white_noise :: Int32 -> DF Float
- brown_noise_f :: Binary_Op (DF Float)
- brown_noise :: Int32 -> DF Float
- sin_osc :: DF Float -> Float -> DF Float
- impulse :: DF Float -> Float -> DF Float
- lf_saw :: DF Float -> Float -> DF Float
- lf_pulse :: DF Float -> Float -> DF Float -> DF Float
- bpz2 :: DF Float -> DF Float
- brz2 :: DF Float -> DF Float
- lpz1 :: DF Float -> DF Float
- lpz2 :: DF Float -> DF Float
- one_pole_f :: Fractional a => a -> Binary_Op a
- one_pole :: DF Float -> DF Float -> DF Float
- one_zero_f :: Fractional a => a -> Binary_Op a
- one_zero :: DF Float -> DF Float -> DF Float
- sos_f :: Num a => a -> a -> a -> a -> a -> Quinary_Op a
- sos :: DF Float -> DF Float -> DF Float -> DF Float -> DF Float -> DF Float -> DF Float
- resonz_f :: DF Float -> DF Float -> Ternary_Op (DF Float)
- resonz :: DF Float -> DF Float -> DF Float -> DF Float
- rlpf_f :: DF Float -> DF Float -> Ternary_Op (DF Float)
- rlpf :: DF Float -> DF Float -> DF Float -> DF Float
- type T5 t = (t, t, t, t, t)
- hpf_c :: Floating t => t -> t -> T5 t
- hpf :: DF Float -> DF Float -> DF Float
- positive :: K_Num a => DF a -> DF Bool
- non_positive :: K_Num a => DF a -> DF Bool
- trigger_f :: K_Num a => DF a -> DF a -> DF Bool
- trigger :: K_Num a => DF a -> DF Bool
- count_true :: K_Num a => DF Bool -> DF a
- pulse_divider :: DF Bool -> DF Int32 -> DF Int32 -> DF Bool
- pulse_divider' :: K_Num a => DF a -> DF Int32 -> DF Int32 -> DF a
- latch :: K_Num a => DF a -> DF Bool -> DF a
- decay_f :: DF Float -> Binary_Op (DF Float)
- decay :: DF Float -> DF Float -> DF Float
- decay2 :: DF Float -> DF Float -> DF Float -> DF Float
- delay1 :: K_Num a => DF a -> DF a
- delay2 :: K_Num a => DF a -> DF a
- lag_f :: DF Float -> Binary_Op (DF Float)
- lag :: DF Float -> DF Float -> DF Float
- lag2 :: DF Float -> DF Float -> DF Float
- lag3 :: DF Float -> DF Float -> DF Float

# Tuples

# Math

mul_add :: Num a => a -> a -> a -> aSource

Multiply and add.

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

calc_fb :: Floating a => a -> a -> aSource

Calculate feedback multipler in comb filter circuit given *delay*
and *decay* times.

calc_fb 0.2 3.0 == 0.6309573444801932

lin_lin :: Fractional a => a -> a -> a -> a -> a -> aSource

Linear range conversion.

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

do {s <- lf_saw 1.0 0.0 ;o <- sin_osc (lin_lin s (-1.0) 1.0 220.0 440.0) 0.0 ;audition [] (out1 (o * 0.1))}

lin_exp :: Floating a => a -> a -> a -> a -> a -> aSource

Exponential range conversion.

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

do {s <- lf_saw 0.25 0.0 ;o <- sin_osc (lin_exp (s + 1.0) 0.0 2.0 220.0 440.0) 0.0 ;audition [] (out1 (o * 0.1))}

clip2 :: (Num a, Ord a) => a -> a -> aSource

Constrain p in (-q,q).

let r = -10 : -10 : [-10,-9 .. 10] in map (flip clip2 10) [-12,-11 .. 12] == r

hz_to_incr :: Fractional a => a -> a -> a -> aSource

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

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

incr_to_hz :: Fractional a => a -> a -> a -> aSource

Inverse of `hz_to_incr`

.

incr_to_hz 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)]

do {o <- sin_osc 440.0 0.0 ;l <- sin_osc 0.5 0.0 ;let (p,q) = lin_pan2 (o * 0.1) l in audition [] (out2 p q)}

# Environment

k_sample_rate :: Fractional n => nSource

Compile time sample rate constant.

w_radians_per_sample :: DF FloatSource

Environment value, equal to

.
`two_pi`

/ `w_sample_rate`

# Tbl

tbl_sin :: Floating n => Int -> [n]Source

Generate guarded sin table.

map (round . (* 100)) (tbl_sin 12) == [0,50,87,100,87,50,0,-50,-87,-100,-87,-50,0]

# Phasor

df_clip2 :: K_Num a => DF a -> DF a -> DF aSource

`clip2`

variant.

do {o <- sin_osc 440 0 ;audition [] (out1 (df_clip2 (o * 2) 0.1))}

iir1 :: K' a => a -> Binary_Op (DF a) -> DF a -> DF aSource

Single place infinite impulse response filter with indicated initial value.

import Data.Int import Sound.DF.Uniform.GADT import Sound.DF.Uniform.LL.K

draw (iir1 (0::Int32) (+) 1) draw (iir1 (0::Float) (+) 1)

phasor :: K_Num a => DF a -> a -> DF a -> DF aSource

*r* = right hand edge, *ip* = initial phase, *x* = increment

draw (phasor 9.0 (4.5::Float) 0.5) draw (phasor 9 (0::Int32) 1)

# Array

a_delay_ph :: DF (Vec Float) -> DF Float -> DF Int32 -> DF Int32 -> DF FloatSource

Array delay with *phasor* argument for write index.

a_delay :: DF (Vec Float) -> DF Float -> DF Int32 -> DF FloatSource

Array delay.

do {a <- df_vec_m [0,1,2] ;draw (a_delay a 0.0 0)}

let {f = sin_osc 0.1 0.0 ;o = sin_osc (f * 200.0 + 600.0) 0.0 ;a = df_vec (V_Id 0) (replicate 48000 0) ;d = a_delay a o 24000} in audition [] (out2 (o * 0.1) (d * 0.05))

a_tbl_sin :: V_Id -> Int -> DF (Vec Float)Source

Array fill function (sin).

do {i <- phasor 64 0 1 ;a = a_tbl_sin (V_Id 0) 64 ;let s = a_read a i in audition [] (out1 (s * 0.2))}

a_lerp :: DF (Vec Float) -> DF Float -> DF FloatSource

Linear interpolating variant of `a_read`

.

let {i = phasor 64.0 0 (hz_to_incr k_sample_rate 64.0 330.0) ;a = a_tbl_sin (V_Id 0) 64 ;s = a_lerp a i} in audition [] (out1 (s * 0.2))

# Osc

tbl_phasor :: Int -> Float -> DF Float -> DF FloatSource

`phasor`

for table of *z* places. *ip* is in (0,1).

draw (phasor 64.0 (0.0::Float) (hz_to_incr k_sample_rate 64.0 330.0)) draw (tbl_phasor 64 0.0 330.0)

a_osc :: DF (Vec Float) -> DF Float -> Float -> DF FloatSource

Table lookup oscillator. *ip* is in (0,1).

let {a = a_tbl_sin (V_Id 0) 256 ;f = a_osc a 4.0 0.0 ;o = a_osc a (f * 200.0 + 400.0) 0.0} in audition [] (out1 (o * 0.1))

Cancellation:

let {a = a_tbl_sin (V_Id 0) 256 ;o1 = a_osc a 440.0 0.0 ;o2 = a_osc a 440.0 0.5} in audition [] (out1 (o1 + o2))

# Filter constructors.

unit_delay :: K' a => a -> DF a -> DF aSource

Single sample delay with indicated initial value.

draw (unit_delay (0::Int32) 1) draw (unit_delay (0.0::Float) 1.0)

let {c = counter 0.0 1.0 ;d = unit_delay 0.0 c} in audition_text 12 (out2 c d)

iir2 :: K_Num a => Ternary_Op (DF a) -> DF a -> DF aSource

Two place infinite impulse response filter. Inputs are: *f*=
function `(x0 y1 y2 -> y0)`

, *i* = input signal.

let {c1 = iir2 (\x y1 _ -> x + y1) 0.001 ;o1 = sin_osc (c1 + 220.0) 0 ;c2 = iir2 (\x _ y2 -> x + y2) 0.001 ;o2 = sin_osc (c2 + 220.0) 0} in audition [] (out2 (o1 * 0.1) (o2 * 0.1))

fir1 :: K' a => a -> (DF a -> DF a -> DF b) -> DF a -> DF bSource

Single place finite impulse response filter.

fir2 :: Ternary_Op (DF Float) -> DF Float -> DF FloatSource

Two place finite impulse response filter.

# Counter

counter :: K_Num a => a -> DF a -> DF aSource

Counter from indicated initial value.

draw (counter (0::Int32) 1) draw (counter (0.0::Float) 1.0)

audition_text 10 (out1 (counter 0.0 1.0))

# Buffer

buf_delay :: DF Int32 -> DF Float -> DF Int32 -> DF FloatSource

Buffer delay.

draw (buf_delay 0 0.0 0)

buf_comb_n :: DF Int32 -> DF Float -> DF Float -> DF Float -> DF FloatSource

Non-interpolating comb filter. Inputs are: *b* = buffer index,
*i* = input signal, *dl* = delay time, *dc* = decay time.

All times are in seconds. The decay time is the time for the
echoes to decay by `60`

decibels. If this time is negative then the
feedback coefficient will be negative, thus emphasizing only odd
harmonics at an octave lower.

draw (out1 (buf_comb_n 0 0.0 0.0 0.0))

Comb used as a resonator. The resonant fundamental is equal to reciprocal of the delay time.

import qualified Sound.SC3 as S

let {n = white_noise 0 ;dt = let f x = lin_exp (x + 2.0) 1.0 2.0 0.0001 0.01 in f (lf_saw 0.1 0.0) ;c = buf_comb_n 0 (n * 0.1) dt 0.2} in audition [S.b_alloc 0 48000 1] (out1 c)

Comb used as an echo.

let {i = impulse 0.5 0.0 ;n = white_noise 0 ;e = decay (i * 0.5) 0.2 ;c = buf_comb_n 0 (e * n) 0.2 3.0} in audition [S.b_alloc 0 48000 1] (out1 c)

# Comb

comb_n :: V_Id -> Float -> DF Float -> DF Float -> DF Float -> DF FloatSource

Array variant of `buf_comb_n`

. Max delay time is in seconds.

let {n = white_noise 0 ;dt = let f x = lin_exp (x + 2.0) 1.0 2.0 0.0001 0.01 in f (lf_saw 0.1 0.0) ;c = comb_n (V_Id 0) 0.1 (n * 0.1) dt 0.2} in audition [] (out1 c)

let {i = impulse 0.5 0.0 ;n = white_noise 0 ;e = decay (i * 0.5) 0.2 ;c = comb_n (V_Id 0) 0.2 (e * n) 0.2 3.0} in audition [] (out1 c)

# Noise

lcg_i32 :: Int32 -> Int32 -> Int32 -> DF Int32Source

`Int32`

linear congruential generator, hence signed modulo of
`2^32`

. Note that the state and all internal math is 32bit.

See http://en.wikipedia.org/wiki/Linear_congruential_generator for possible parameters.

randf :: Int32 -> DF FloatSource

`i32_to_normal_f32`

of `randi`

, so in (0,1).

audition_text 24 (out1 (randf 0))

white_noise :: Int32 -> DF FloatSource

White noise (-1,1). Generates noise whose spectrum has equal power at all frequencies.

audition_text 24 (out1 (white_noise 0))

let n = white_noise 0 * 0.1 in draw (out1 (n - n))

let {n = white_noise 0 * 0.1 ;m = white_noise 5 * 0.1} in audition [] (out1 (n - m))

brown_noise :: Int32 -> DF FloatSource

Brown noise (-1,1). Generates noise whose spectrum falls off in power by 6 dB per octave.

let n = brown_noise 0 in audition [] (out1 (n * 0.1))

let {n = brown_noise 0 ;f = lin_exp n (-1.0) 1.0 64.0 9600.0 ;o = sin_osc f 0} in audition [] (out1 (o * 0.1))

# Osc

sin_osc :: DF Float -> Float -> DF FloatSource

Sine oscillator. Inputs are: *f* = frequency (in hz), *ip* =
initial phase.

let o = sin_osc 440.0 0.0 in audition [] (out1 (o * 0.1))

Used as both Oscillator and LFO.

let {f = sin_osc 4.0 0.0 ;o = sin_osc (f * 200.0 + 400.0) 0.0} in audition [] (out1 (o * 0.1))

Cancellation.

let {o1 = sin_osc 440.0 0.0 ;o2 = sin_osc 440.0 pi} in audition [] (out1 (o1 + o2))

impulse :: DF Float -> Float -> DF FloatSource

Impulse oscillator (non band limited).
Outputs non band limited single sample impulses.
Inputs are: *f* = frequency (in hertz), *ip* = phase offset (0..1)

let o = impulse 800.0 0.0 in audition [] (out1 (o * 0.1))

let {f = sin_osc 0.25 0.0 * 2500.0 + 2505.0 ;o = impulse f 0.0} in audition [] (out1 (o * 0.1))

# LF Osc.

lf_saw :: DF Float -> Float -> DF FloatSource

Non-band limited sawtooth oscillator. Output ranges from -1 to +1.
Inputs are: *f* = frequency (in hertz), *ip* = initial phase (0,2).

let o = lf_saw 500.0 1.0 in audition [] (out1 (o * 0.1))

Used as both Oscillator and LFO.

let {f = lf_saw 4.0 0.0 ;o = lf_saw (f * 400.0 + 400.0) 0.0} in audition [] (out1 (o * 0.1))

lf_pulse :: DF Float -> Float -> DF Float -> DF FloatSource

Non-band-limited pulse oscillator. Outputs a high value of one
and a low value of zero. Inputs are: *f* = frequency (in hertz),
*ip* = initial phase (0,1), *w* = pulse width duty cycle (0,1).

let {o1 = lf_pulse 3.0 0.0 0.3 * 200.0 + 200.0 ;o2 = lf_pulse o1 0.0 0.2 * 0.1} in audition [] (out1 o2)

# Filters

one_pole_f :: Fractional a => a -> Binary_Op aSource

Given *cf* construct `iir1`

one-pole function.

one_pole :: DF Float -> DF Float -> DF FloatSource

One pole filter.

let {n = white_noise 0 ;f = one_pole (n * 0.5) 0.95} in audition [] (out1 f)

one_zero_f :: Fractional a => a -> Binary_Op aSource

Given *cf* construct `fir1`

one-zero function.

one_zero :: DF Float -> DF Float -> DF FloatSource

One zero filter.

let {n = white_noise 0 ;f = one_zero (n * 0.5) 0.5} in audition [] (out1 f)

sos_f :: Num a => a -> a -> a -> a -> a -> Quinary_Op aSource

sos :: DF Float -> DF Float -> DF Float -> DF Float -> DF Float -> DF Float -> DF FloatSource

Second order filter section.

resonz :: DF Float -> DF Float -> DF Float -> DF FloatSource

A two pole resonant filter with zeroes at z = +/- 1. Based on
K. Steiglitz, "A Note on Constant-Gain Digital Resonators",
*Computer Music Journal*, vol 18, no. 4, pp. 8-10, Winter 1994.
The reciprocal of Q is used rather than Q because it saves a divide
operation inside the unit generator.

Inputs are: *i* = input signal, *f* = resonant frequency (in
hertz), *rq* = bandwidth ratio (reciprocal of Q);where *rq* =
bandwidth / centerFreq.

let {n = white_noise 0 ;r = resonz (n * 0.5) 440.0 0.1} in audition [] (out1 r)

Modulate frequency

let {n = white_noise 0 ;f = lf_saw 0.1 0.0 * 3500.0 + 4500.0 ;r = resonz (n * 0.5) f 0.05} in audition [] (out1 r)

rlpf :: DF Float -> DF Float -> DF Float -> DF FloatSource

Resonant low pass filter. Inputs are: *i* = input signal, *f* =
frequency (hertz), *rq* = reciprocal of Q (resonance).

let {n = white_noise 0 ;f = sin_osc 0.5 0.0 * 40.0 + 220.0 ;r = rlpf n f 0.1} in audition [] (out1 r)

hpf_c :: Floating t => t -> t -> T5 tSource

2nd order Butterworth high-pass filter coefficients.

hpf_c 48000.0 (440.0 :: DF Float)

# Triggers

count_true :: K_Num a => DF Bool -> DF aSource

Count `True`

values at input.

let n = white_noise 0 in audition_text 12 (out2 n (count_true (trigger n)))

pulse_divider' :: K_Num a => DF a -> DF Int32 -> DF Int32 -> DF aSource

SC3 `PulseDivider`

.

let n = white_noise 0 in audition_text 12 (out2 n (pulse_divider' n 2 1))

latch :: K_Num a => DF a -> DF Bool -> DF aSource

Sample and hold. Holds input signal value when triggered. Inputs
are: *i* = input signal, *t* = trigger.

let {n = white_noise 0 ;i = impulse 9.0 0.0 ;l = latch n (trigger i) ;o = sin_osc (l * 400.0 + 500.0) 0.0} in audition [] (out1 (o * 0.2))

# Decays

decay :: DF Float -> DF Float -> DF FloatSource

Exponential decay. Inputs are: *i* = input signal, *t* = decay
time. This is essentially the same as Integrator except that
instead of supplying the coefficient directly, it is caculated from
a 60 dB decay time. This is the time required for the integrator to
lose 99.9 % of its value or -60dB. This is useful for exponential
decaying envelopes triggered by impulses.

Used as an envelope.

let {n = brown_noise 0 ;f = lf_saw 0.1 0.0 ;i = impulse (lin_lin f (-1.0) 1.0 2.0 5.0) 0.25 ;e = decay i 0.2} in audition [] (out1 (e * n))

decay2 :: DF Float -> DF Float -> DF Float -> DF FloatSource

Exponential decay (equivalent to `decay dcy - decay atk`

).