9. Filters

Filter.dumpClassSubtree

1.RLPF – resonant low pass filter
RHPF – resonant high pass filter
2.BPF – bandpass filter
3.Resonz – a two-pole resonant filter
4.Klank – a bank of resonators.
5.Formlet – FOF-like filter
6.Comb – filter

//———————————-
1. RLPF.ar(in, freq, rq, mul, add)        // q를 사용하는 대신 q의 note reciprocal를 사용한다.
                                     // rq : bandwidth/cutoffFreq
                                     // rq가 작을수록 constant freq를 가진 bw가 작아진다
{RLPF.ar(WhiteNoise.ar,550,0.1)}.scope
{RLPF.ar(WhiteNoise.ar,500,MouseX.kr(0.1,0.9))}.scope
{RLPF.ar(WhiteNoise.ar,MouseX.kr(100,1000),MouseY.kr(0.1,0.9))}.scope

//———————————-
2. 2nd order butterworth bandpass filter
     BPF.ar(in, freq, rq, mul, add)
{BPF.ar(WhiteNoise.ar,550,0.1,0.5)}.scope
{BPF.ar(WhiteNoise.ar,MouseX.kr(200,2000,0,0.5),MouseY.kr(0.001,0.5,1,0.5))}.scope

MouseX:        *kr(minval, maxval, warp, lag),
        warp = 0 : linear, 1:Exponential.
        lag        = lag factor to dezpipper cursor movement
        
//———————————-
3. Resonz – a two-pole resonant filter
        Resonz.ar(in,freq,rq, mul,add)

{Resonz.ar(WhiteNoise.ar,MouseX.kr(100,1000,0,0.05),MouseY.kr(0.001,0.5,1,0.5))}.scope
{Resonz.ar(WhiteNoise.ar(0.5),2000,0.1)}.scope
{BPF.ar(WhiteNoise.ar(0.5),2000,0.1)}.scope  // compare

{Resonz.ar(WhiteNoise.ar(0.5),2000,XLine.kr(1,0.001,8))}.play
//XLine.kr(start, end, dur, mul, add, doneAction):exponential line generator

// add three filters
(
        {Resonz.ar(WhiteNoise.ar(0.3),387,0.1)
        +
        Resonz.ar(WhiteNoise.ar(0.3),1207,0.1)
        +
        Resonz.ar(WhiteNoise.ar(0.3),2000,0.1)}.scope
)// not quite the same
(
        {Mix.ar(
                        Resonz.ar(
                                        WhiteNoise.ar(0.3),[387,1207,2007],0.1)
                                        )
                                        }.scope
)

//———————————-
4. Klank – a bank of resonators.
;어떤 object의 resonant modes를 만든다. (physical model of space or bodies)
Klank.ar(specificationsArrayRef, input, freqscale, freqoffset, decayscale)

specificationsArrayRef – a Ref to an Array of three Arrays :
        frequencies – an Array of filter frequencies.
        amplitudes – an Array of filter amplitudes, or nil. If nil, then amplitudes default to 1.0
        ring times – an Array of 60 dB decay times for the filters.
        
        if only two arrays in the array, that means that ring times (decay times) has been omitted
        
// ` 마크는 multi-channel expansion를 방지시킨다.

(
{
        Klank.ar(`[[100,200,300,400,500,600,700,800,900,1000],
                        [0.05,0.2,0.04,0.06,0.11,0.01,0.15,0.03,0.15,0.02]],
                        PinkNoise.ar(MouseX.kr(0.01,0.1)))
}.scope
)

(freqs and amps taken from Csound formant chart for alto o)
(
{
Klank.ar(
                `[[450,800,2830,3500,4950],
                        [0,-9,-16,-28,-55].dbamp],
                        PinkNoise.ar(0.01))
}.scope
)

//———————————-
5. Formlet FOF-like filter
Formlet.ar(in, freq, attacktime, decaytime, mul, add)
impulse response를 가진 resonant filter로서 exponential decay를 가진 sine wave와 유사하다.

attack과 decay times이 같으면 signal은 cancel된다.
attack > decay이면 , impulse response는 invert된다.

{Formlet.ar(PinkNoise.ar(0.1),1000,0.01,0.1)}.scope
{Formlet.ar(Impulse.ar(20,0.5),1000,0.01,0.1)}.scope// Impulse perhaps more ‘appropriate’ input
//Impulse.ar(freq, phase, mul, add)

band-limited impulse oscillator
Blip.ar(kfreq, knumharmonics,mul,add)
        (in other languages such as Csound, oftem called ‘buzz’)
{Blip.ar(100,100,0.5)}.scope
{Blip.ar(SinOsc.kr(5,0,20,300),1000,0.4)}.scope

modulating formant frequency
        with Blip as signal input
(
{
        var in;
        in = Blip.ar(SinOsc.kr(5,0,20,300), 1000, 0.1);
        Formlet.ar(in, XLine.kr(1500,700,8, doneAction: 2), 0.005, 0.04);
}.scope;
)

//———————————-
6. Comb filter
CombL.ar(in,maxdelaytime, delaytime, decaytime, mul, add);
CombL is with a linear delay
decayTime 은 60dB에 의해 decay되는 echoes시간

{CombL.ar(WhiteNoise.ar(0.1),0.01,0.01,0.2)}.scope
// modulating the delay time:
{CombL.ar(WhiteNoise.ar(0.1),0.01,XLine.kr(0.001,0.01,10,doneAction:2),0.2)}.scope

Karplus-Strong
Comb filter used for Karplus-Strong attempt:

69.midicps                                    // freq (midi to cps)
69.midicps.reciprocal                  // period

(
{
        var burstEnv, att = 0, dec=0.001;
        var delayTime, decayTime = 10;
        var midiPitch = 69;
        delayTime = midiPitch.midicps.reciprocal;//69–>440hz
        burstEnv = EnvGen.kr(Env.perc(att,dec));
        CombL.ar(WhiteNoise.ar(burstEnv), delayTime, delayTime, decayTime);
}.scope;
)

// trigger with Mouse
(
{
        var burstEnv, att = 0, dec = 0.05; //note increase of dec
        var delayTime, decayTime = 10;
        delayTime = MouseX.kr(36,74, lag: 0).midicps.reciprocal;//mouse controls pitch
        burstEnv = EnvGen.kr(Env.perc(att, dec), gate: MouseButton.kr(0,1,0));//mouse down control
        CombL.ar(WhiteNoise.ar(burstEnv), delayTime, delayTime, decayTime);
}.scope
)

//——————————————
http://csound.x-y.net
Ji Youn Kang,
Csound Max Community

8. Noise

8. Noise

{WhiteNoise.ar(0.5)}.scope
{PinkNoise.ar(0.4)}.scope//-3dB per octave
{BrownNoise.ar(0.5)}.scope//-6dB per octave
{GrayNoise.ar(0.4)}.scope//randomly flipping bits

{Dust.ar(MouseX.kr(10,500),mul:0.9)}.scope//마우스가 오른쪽으로 가면 펄스농도가 짙어진다.

Dust as trigger for an envelope:

    EnvGen.ar(envelope, gate, levelScale, levelBias, timeScale, doneAction)
       gate is usually a trigger for the envelope (triggers when <= 0 goes to > 0)
Env.perc(0.001,0.05).plot.test
(
{SinOsc.ar(440, mul:EnvGen.kr(Env.perc(0.001,1.0),
                                                Dust.kr(MouseX.kr(0.5,5))))
}.scope
)
//——————————————
메뉴얼 참조
Dust        : random impulses

Dust.ar(density, mul, add)
Generates random impulses from 0 to +1.
density – average number of impulses per second

MouseX: cursor ugen
superclass: UGen
        *kr(minval, maxval, warp, lag)
        
        minval, maxval        range between left and right end of screen
        warp                        mapping curve. 0 is linear, 1 is exponential (for freq or times e.g)
                                        alternative: ‘linear’, ‘exponential’
        lag                                lag factor to dezpipper cursor movement
//——————————————
http://csound.x-y.net
Ji Youn Kang,
Csound Max Community

7. Env/Variables/RandomSinewaves

1.envelopes – Env, EnvGen

Env을 사용하여 Envelope을 만든다.

-linear envelope (attackTime, sustainTime, releaseTime, level)
Env.linen (1,2,1,0.6).plot//plot:graph를 보여줌
Env.linen (1,2,1,0.6).test

-Env.new([levels],[times],curve)
Env.new([0.001,1,0.3,0.001],[1,0.5,2],’exponential’).plot
Env.new([0.001,1,0.3,0.001],[1,0.5,2],’exponential’).test.plot

Env.new([0.001,1,0.3,0.001],[1,0.5,2],’sine’).test.plot
Env.new([0.001,1,0.3,0.001],[1,0.5,2], ‘welch’).test.plot
Env.new([0.001,1,0.3,0.001],[1,0.5,2], 4).test.plot
Env.new([0.001,1,0.3,0.001],[1,0.5,2], -4).test.plot

-Env.triangle (duration,level)
Env.triangle(1,1).test.plot

-Env.sine(duration,  level)     // has Hanning window shape
Env.sine (1,1).test.plot

-Env.perc(attackTime, releaseTime,peakLevel, curve)//percutive shape
Env.perc(0.05,1,1,-4).test.plot

-cutoff(releaseTime, level, curve)   // has no attack
Env.cutoff(1,1,’sine’).test.plot

-Envelope 을 만들기 위해서 UGen을 사용할 수 있다:
EnvGen        (envelope, gate, levelScale, levelBias, timeScale, doneAction)
        envelope – an instance of Env
        gate – control signal that holds the EnvGen open (except Env.linen)
        
{EnvGen.kr(Env.linen(1,2,1,0.6),doneAction: 2)*SinOsc.ar}.scope

(
{EnvGen.kr(Env.new([0.001,1,0.3,0.001],[1,0.5,2],’exponential’),
        doneAction:2)
* SinOsc.ar}.scope
)        

-Envelope for frequency
(
{SinOsc.ar(EnvGen.kr(Env.new([1000,500,400,800],[5,2,3],’sine’),doneAction:2),mul:0.1)
}.scope
)        

//——————————————
2. Variables.

-Variables는 변수설정으로서 algorithm을 코드의 라인을 분리시켜 표현된다. (세미콜론 사용)

(
        var envelope, freq = 200; //envelope가 변수. 뒤에 값이 없으면 아래에 정의된다. freq는 변수 선언후 바로 값을 준 경우.
        
        envelope = Env.new([0.001,1,0.3,0.001],[1,0.5,2],’exponential’);
        
        {EnvGen.ar(envelope,1,doneAction:2)*SinOsc.ar(freq,0,0.5)}.scope;
)
또는 다음과 같이(세미콜론과 구문 확인)

(
{        var envelope, freq = 200;
        envelope = Env.new([0.001,1,0.3,0.001],[1,0.5,2],’exponential’);
        EnvGen.ar(envelope,1,doneAction:2 ) * SinOsc.ar(freq,0,0.4)
}.scope
)

// statements end with ; unless there is only one line being evaluated
// in the above example, the difference concerned  the beginning of the function

//——————————————
3. Randon Sinewaves.
-random frequencies를 만들기 위해서 Array사용

-Array를 채운다.
Array.fill(10,1.0)//1이 10개인 값
Array.fill(10,1.0.rand)//Array를 같은 값으로 채움.10개의 수를 1,0안쪽의 랜덤숫자로.
Array.fill(10,{1.0.rand})//Array를 다른값으로 채움

-또다른 방법
{1.0.rand}.dup(10)  // dup produces an array by applying a function
{1.00.rand}!10 //! is dup operator (see SymbolicNotations)

thisThread.randSeed = 5;//to seed the random distribution

-값을 normalize하기
[1,0.5,0.3].normalizeSum

(
{
var harmArray, ampArray, fund,n;
//첫번 array: 1~20.0, 두번째:0~1.0, 두번째 array를 normalize, 1.0까지exceed

fund = 100;
n = 20;
harmArray = {rrand(1.0,20)} ! n;//array of n values
ampArray = {1.0.rand}.dup(n).normalizeSum;
Mix.ar(SinOsc.ar(harmArray * fund, 0, ampArray));
}.scope
)

-envelope을 더해보기
(
{
var harmArray,ampArray,fund,n,env;

fund = 100;
n = 20;
harmArray = {rrand(1,20.0)} ! n;
ampArray = {1.0.rand}.dup(n).normalizeSum;
env = Env.linen(1,10,3,0.6);
Mix.ar(SinOsc.ar(harmArray * fund,0,ampArray) * EnvGen.kr(env,1,doneAction:2));
}.scope
)

-additive with a different envelope for each freq

(
// postln writes in post window
{
var harmArray, ampArray, fund,n,env; fund = 100;
n = 20;
harmArray ={rrand(1.0,20)}! n;
ampArray = {1.0.rand}.dup(n).normalizeSum;
env = {EnvGen.kr(Env.linen(rrand(1,10.0).postln,10,3,0.6))} ! n;
Mix.ar(SinOsc.ar(harmArray * fund, 0, ampArray) * env);
}.scope;
)

// yet another way, this time with an array of SinOsc * EnvGens
// sustain time is also random
// ! is the dup operator, returns an array with n object
(
{
var harmArray, ampArray, fund,n; fund = 100;
n = 20;
Mix.ar({SinOsc.ar(rrand(1,20.0) * fund, 0, 0.3.rand) *
        EnvGen.kr(Env.linen(rrand(1.0,10),rrand(5.0,10),3,0.2))} ! n);
}.scope;
)

//——————————————
http://csound.x-y.net
Ji Youn Kang,
Csound Max Community