History

Merge branch 'main' of github.com:ccrma/chuck

Ge Wang committed 3 years ago

Commit c3ccff92 parents 04a71e2 8d42a8b29 files · +1043 −15Browse files

Unified · Split

29 files
  1. examples/analysis/PitchTrack.ck +54 −0
  2. examples/analysis/Sigmund.ck +66 −0
  3. examples/effects/ABSaturator.ck +10 −0
  4. examples/effects/Bitcrusher.ck +15 −0
  5. examples/effects/ExpDelay.ck +34 −0
  6. examples/effects/ExpEnv-modes.ck +25 −0
  7. examples/effects/ExpEnv.ck +15 −0
  8. examples/effects/FoldbackSaturator-index.ck +14 −0
  9. examples/effects/FoldbackSaturator-threshold.ck +12 −0
  10. examples/effects/GVerb.ck +31 −0
  11. examples/effects/KasFilter-demo.ck +105 −0
  12. examples/effects/PowerADSR-feedback-beatings.ck +52 −0
  13. examples/effects/PowerADSR.ck +89 −0
  14. examples/effects/Spectacle.ck +51 −0
  15. examples/effects/WinFuncEnv.ck +103 −0
  16. examples/filter/Elliptic-help.ck +59 −0
  17. examples/filter/FIR-convolve-homer.ck +16 −0
  18. examples/filter/FIR-greyhole-down-up-decimate.ck +50 −0
  19. examples/filter/FIR-sinc-explicit.ck +20 −0
  20. examples/filter/KasFilter.ck +29 −0
  21. examples/filter/Multicomb.ck +25 −0
  22. examples/filter/WPDiodeLadder.ck +16 −0
  23. examples/filter/WPKorg35.ck +15 −0
  24. examples/spatial/AmbPan3-CCRMA.ck +19 −0
  25. examples/spatial/Pan4.ck +11 −0
  26. examples/spatial/Pan8.ck +12 −0
  27. examples/special/Mesh2D.ck +43 −0
  28. src/core/ugen_stk.cpp +9 −6
  29. src/core/ulib_doc.cpp +43 −9
examples/analysis/PitchTrack.ck+54−0
@@ -0,0 +1,54 @@
1+////////////////////////////////////////////////////////////////////
2+// PitchTrack is a monophonic autocorrelation pitch tracker with //
3+// a fast response and extremely high accuracy, even at low //
4+// frequencies. It is adapted from [helmholtz~] for Pd by Katja, //
5+// documented at http://www.katjaas.nl/helmholtz/helmholtz.html //
6+////////////////////////////////////////////////////////////////////
7+
8+// Options
9+// get(): (read only) get calculated frequency
10+//
11+// fidelity: (float) [0-1], default 0.95
12+// This is a threshold for certainty about the result. A highly periodic
13+// signal (ie one that has a strong pitch center) should produce a result
14+// with a high fidelity, which a non-periodic signal (eg noise) will have
15+// a very low fidelity. Setting this parameter close to 1 should reduce
16+// the number of inaccurate reports.
17+//
18+// sensitivity (float) [0-1], default 0.003
19+// This is the minimum RMS value to trigger a pitch calculation. Setting
20+// this parameter low forces PitchTrack to attempt to find the pitch of
21+// even very quiet sounds. Higher values will cause it to trigger only
22+// on louder notes.
23+//
24+// overlap (int) [1-?], default 2
25+// How much to overlap successive analysis frames. Higher values should
26+// produce smoother values, at the cost of an increase of CPU load.
27+//
28+// frame (int) [128-?], default 2048
29+// Size of FFT frame for analysis. Smaller values result in lower latency
30+// and high responsiveness but less accuracy. Higher values result in
31+// considerably greater CPU load. Values that aren't powers of 2 get
32+// rounded up to the next power of 2. Recommend 512, 1024, or 2048.
33+//
34+// bias (float) [0-1], default 0.2
35+// Katja's pitch tracker introduces a small bias to help with the tracking.
36+// (See the link above.) I don't know how this parameter affects the output.
37+
38+// Example
39+SinOsc osc => dac; // create an oscillator
40+// PitchTrack must connect to blackhole to run
41+osc => PitchTrack pitch => blackhole;
42+
43+0.5 => osc.gain;
44+
45+while (true)
46+{
47+ // set the oscillator to a random frequency
48+ Math.random2f(200,1000) => osc.freq;
49+ <<< "Actual oscillator frequency:",osc.freq(),"Hz" >>>;
50+ 250::ms => now; // pass a little time
51+ <<< "PitchTrack thinks it's this:",pitch.get(),"Hz" >>>;
52+ <<< "Difference:",Math.fabs(osc.freq() - pitch.get()),"Hz\n" >>>;
53+ 2::second => now;
54+}
examples/analysis/Sigmund.ck+66−0
@@ -0,0 +1,66 @@
1+///////////////////////////////////////////////////
2+// Sigmund: sinusoidal analysis & pitch tracking //
3+// //
4+// by Miller Puckette //
5+// //
6+///////////////////////////////////////////////////
7+
8+// Options:
9+// npts (int): number of points used in analysis.
10+// Must be a power of 2, at least 128. The
11+// minimum frequency that can be tracked is
12+// about 2 * samplerate / npts
13+// default: 1024
14+//
15+// npeak (int): maximum number of sinusoidal peaks
16+// to look for. The computation time is
17+// quadratic in the number of peaks actually
18+// found (this number only sets an upper
19+// limit). Use it to balance CPU time with
20+// quality of results.
21+//
22+// maxfreq (float): maximum frequency of sinusoidal
23+// peaks to look for. This can be useful in
24+// situations where background nose creates
25+// high-frequency, spurious peaks...
26+//
27+// minpower (float): minimum dB level to
28+// report a pitch. Signals quieter than this
29+// will be assumed to be crosstalk and ignored.
30+// default: 50
31+//
32+// freq() (read-only): get reported frequency of
33+// input signal
34+//
35+// env() (read-only): get reported RMS value (in dB)
36+// of input signal
37+//
38+// peak (int): report freq of nth sinusoundal peak
39+// sorting depends on parameter "dotracks"
40+//
41+// amp (int): report amplitude of nth sinusoundal peak
42+// sorting depends on parameter "dotracks"
43+//
44+// tracks (0/1): toggle whether peak and amp are
45+// sorted in order of amplitude or organized into
46+// tracks
47+//
48+// clear(): clear buffers and reset
49+//
50+// param1, param2, param3 (float): mysterious settings...
51+
52+// must connect to blackhole to perform DSP
53+TriOsc foo => Sigmund siggy => blackhole;
54+
55+4096 => siggy.npts;
56+20 => siggy.npeak;
57+1000 => siggy.maxfreq;
58+25 => siggy.minpower;
59+
60+while (true)
61+{
62+ Math.random2f(5,300) => foo.freq;
63+ Math.random2f(0,1) => foo.gain;
64+ second => now;
65+ <<< "Real frequency:",foo.freq(),"real gain:",foo.gain(),"Sigmund found this:",siggy.freq(), "power:", siggy.env() >>>;
66+}
examples/effects/ABSaturator.ck+10−0
@@ -0,0 +1,10 @@
1+
2+adc => Delay d => ABSaturator sat => dac;
3+
4+20 => sat.drive;
5+4 => sat.dcOffset;
6+
7+while(true)
8+{
9+ 1::second => now;
10+}
examples/effects/Bitcrusher.ck+15−0
@@ -0,0 +1,15 @@
1+
2+adc => Delay d => Bitcrusher bc => dac;
3+
4+0.5::second => d.max => d.delay;
5+
6+0.5 => bc.gain;
7+5 => bc.bits;
8+12 => bc.downsampleFactor;
9+
10+<<< "bits:", bc.bits(), "downsampling:", bc.downsampleFactor() >>>;
11+
12+while(true)
13+{
14+ 1::second => now;
15+}
examples/effects/ExpDelay.ck+34−0
@@ -0,0 +1,34 @@
1+////////////////////////////////////////////////////
2+// ExpDelay - Feedback delay at exponentially //
3+// changing delay times //
4+// //
5+// by Joel Matthys //
6+// (c) 2014, GPL 2.0 //
7+// //
8+////////////////////////////////////////////////////
9+//
10+// Settings:
11+// mix (float): 0-1, dry/wet mix
12+// max (dur): maximum possible delay duration
13+// delay (dur): duration of delay
14+// reps (int): number of repetitions
15+// durcurve (float) [0.0001-inf]: set steepness of delay curve
16+// 1 = steady
17+// <1 = starts fast and slows down
18+// >1 = starts slow and speeds up
19+// ampcurve (float) [0.0001-inf]: set steepness of amplitude decay
20+
21+ModalBar pop => ExpDelay ed => dac;
22+3::second => ed.max;
23+3::second => ed.delay;
24+
25+while (true)
26+{
27+ Math.random2(54,66) => Std.mtof => pop.freq;
28+ 1 => pop.noteOn;
29+ Math.random2f(0.5,2) => ed.durcurve;
30+ Math.random2f(0.5,2) => ed.ampcurve;
31+ Math.random2(5,30) => ed.reps;
32+ <<< "durcurve:",ed.durcurve(), "ampcurve:",ed.ampcurve(), "reps:",ed.reps() >>>;
33+ 4::second => now;
34+}
examples/effects/ExpEnv-modes.ck+25−0
@@ -0,0 +1,25 @@
1+class Mode extends Chubgraph {
2+ SinOsc s => ExpEnv e => outlet;
3+ fun void freq(float freq) { freq => s.freq; }
4+ fun void T60(dur tsixty) { tsixty => e.T60; }
5+ fun void keyOn() { 1 => e.keyOn; }
6+}
7+
8+Mode mod => dac;
9+
10+1000 => mod.freq;
11+second/2 => mod.T60;
12+mod.keyOn();
13+second => now;
14+
15+700 => mod.freq;
16+2*second => mod.T60;
17+mod.keyOn();
18+2*second => now;
19+
20+1200 => mod.freq;
21+3::second => mod.T60;
22+mod.keyOn();
23+3*second => now;
24+
25+
examples/effects/ExpEnv.ck+15−0
@@ -0,0 +1,15 @@
1+SinOsc s => ExpEnv eenv => dac;
2+1000 => s.freq;
3+0.999 => eenv.radius;
4+
5+100*ms => eenv.T60; 1 => eenv.keyOn; second => now;
6+second => eenv.T60; 1 => eenv.keyOn; second => now;
7+3*second => eenv.T60; 1 => eenv.keyOn; 3*second => now;
8+
9+while (1) {
10+ Math.random2f(0.995,0.9995) => eenv.radius;
11+ Math.random2f(0.3,1.0) => eenv.gain;
12+ Std.mtof(Math.random2(0,10)*2+72) => s.freq;
13+ 1 => eenv.keyOn;
14+ 0.1::second => now;
15+}
examples/effects/FoldbackSaturator-index.ck+14−0
@@ -0,0 +1,14 @@
1+SinOsc s => FoldbackSaturator foldy => dac;
2+
3+0.3 => foldy.threshold;
4+
5+0.001 => float delta;
6+
7+while(1::ms => now)
8+{
9+ if((foldy.index() < 1.0) || (foldy.index() > 4.0))
10+ {
11+ -1.0 *=> delta;
12+ }
13+ foldy.index(foldy.index() - delta);
14+}
examples/effects/FoldbackSaturator-threshold.ck+12−0
@@ -0,0 +1,12 @@
1+SinOsc s => FoldbackSaturator foldy => dac;
2+
3+0.001 => float delta;
4+
5+while(10::ms => now)
6+{
7+ if((foldy.threshold() < 0.03) || (foldy.threshold() > 0.8))
8+ {
9+ -1.0 *=> delta;
10+ }
11+ foldy.threshold(foldy.threshold() - delta);
12+}
examples/effects/GVerb.ck+31−0
@@ -0,0 +1,31 @@
1+///////////////////////////////////////////////////////////////////////////////
2+// GVERB is a very smooth reverberator with the ability to produce very long //
3+// reverb times. //
4+// //
5+// GVERB is based on the original "gverb/gigaverb" by Juhana Sadeharju //
6+// (kouhia at nic.funet.fi). The code for this version was adapted from //
7+// RTcmix (http://rtcmix.org), which in turn adapted it from the Max/MSP //
8+// version by Olaf Mtthes (olaf.matthes at gmx.de). //
9+///////////////////////////////////////////////////////////////////////////////
10+
11+// Options
12+// roomsize: (float) [1.0 - 300.0], default 30.0
13+// revtime: (dur), default 5::second
14+// damping: (float), [0.0 - 1.0], default 0.8
15+// spread: (float), default 15.0
16+// inputbandwidth: (float) [0.0 - 1.0], default 0.5
17+// dry (float) [0.0 - 1.0], default 0.6
18+// early (float) [0.0 - 1.0], default 0.4
19+// tail (float) [0.0 - 1.0], default 0.5
20+
21+adc => GVerb gverb => dac;
22+50 => gverb.roomsize;
23+2::second => gverb.revtime;
24+0.3 => gverb.dry;
25+0.2 => gverb.early;
26+0.5 => gverb.tail;
27+
28+while (true)
29+{
30+ second => now;
31+}
examples/effects/KasFilter-demo.ck+105−0
@@ -0,0 +1,105 @@
1+//Under-sampling based resonant Lowpass filter by Kassen
2+//Internal workings are explained in the source, for those who need that.
3+//let's have a look at how to use it in practice here.
4+
5+chout <= "hi there! \n";
6+chout <= "Let's do some filtering! \n";
7+chout <= "Let's start with a simple example: \n";
8+chout <= "... \n";
9+chout.flush();
10+BlitSaw s => KasFilter kf => dac; //we use a BlitSaw because it doesn't alias.
11+
12+220 => s.freq;
13+
14+
15+Envelope ramp => blackhole; //our modulation signal.
16+
17+220 => ramp.value;
18+5::second => ramp.duration;
19+5000 => ramp.target;
20+
21+while (ramp.value() < ramp.target())
22+{
23+ ramp.value() => kf.freq;
24+ samp => now;
25+}
26+0 => s.freq;
27+0 => s.op;
28+
29+chout <= "That sounded a bit like a filter and a bit like under-sampling, right? \n";
30+chout <= "That's because that's exactly what's going on. \n";
31+chout <= "But we can do more, we can add resonance to it, like a normal filter. \n";
32+chout <= "Let's try the same sweep again, but now with some resonance. \n";
33+chout <= "... \n";
34+chout.flush();
35+2::second => now;
36+
37+220 => s.freq;
38+1 => s.op;
39+
40+220 => ramp.value;
41+5::second => ramp.duration;
42+5000 => ramp.target;
43+.85 => kf.resonance;
44+
45+while (ramp.value() < ramp.target())
46+{
47+ ramp.value() => kf.freq;
48+ samp => now;
49+}
50+0 => s.freq;
51+0 => s.op;
52+
53+
54+chout <= "With resonance there is a lot more emphasis on the filter sweep. \n";
55+chout <= "It also brings the artefacts of this technique more to the foreground. \n";
56+chout <= "That might be good or it could be bad, depending on what you want... \n";
57+chout <= "I quite like it, so we can go one step further; \n";
58+chout <= "We can also add a overdrive effect to this resonance, let's try that, \n";
59+chout <= "we'll also turn the frequency of the input way down for the occasion.... \n";
60+chout <= "... \n";
61+chout.flush();
62+2::second => now;
63+
64+8 => s.freq;
65+1 => s.op;
66+
67+75 => ramp.value;
68+5::second => ramp.duration;
69+1000 => ramp.target;
70+.75 => kf.accent;
71+.95 => kf.resonance;
72+
73+while (ramp.value() < ramp.target())
74+{
75+ ramp.value() => kf.freq;
76+ samp => now;
77+}
78+0 => s.freq;
79+0 => s.op;
80+chout <= "That's about it. \n";
81+chout <= "I found it's especially good for lo-fi acid techna, \n";
82+chout <= "it might be good for other things as well, \n";
83+chout <= "Have fun! \n";
84+chout.flush();
85+
86+2::second => now;
87+
88+/*
89+Documentation;
90+kf.freq(float) //sets the cutoff frequency.
91+ This sets both the frequency at which the 2 sample&holds sample the input signal
92+ and the frequency of the sine that crossfades between them.
93+kf.freq() //gets the cutoff frequency
94+kf.resonance(float) //sets the resonance, which is implemented as negative feedback.
95+ accepts values between 0 and 0.95
96+kf.resonance() // gets the resonance.
97+kf.accent(float) //sets the amount of waveshaping on the crossfading sine.
98+ Ranges from 0 to 1, where 1 is close to regular under-sampling
99+ (if no resonance is used).
100+kf.accent() //gets the accent value.
101+
102+Please report bugs, problems or confusing bits to the ChucK mailing list.
103+If that fails or you need me for some other reason try;
104+signal [dot] automatique [at] gmail [another dot] com
105+*/
examples/effects/PowerADSR-feedback-beatings.ck+52−0
@@ -0,0 +1,52 @@
1+// Eric Heep
2+// April 3rd, 2017
3+// poweradsr-feedback-beatings.ck
4+
5+// set number of sines and power envs
6+5 => int num;
7+MagicSine sin[num];
8+PowerADSR env[num];
9+
10+// sound chain
11+for (int i; i < num; i++) {
12+ sin[i] => env[i] => dac;
13+ sin[i].gain(0.25/num);
14+}
15+
16+fun void loopSin(int idx) {
17+ dur env_time;
18+ float curve;
19+ while (true) {
20+ Math.random2(1, 2)::second => env_time;
21+
22+ // curves below 1.0 will be "hill" shaped,
23+ // curves above 1.0 will resemble an exponential curve
24+ Math.random2f(0.5, 4.0) => curve;
25+ sin[idx].freq(Math.random2f(1000, 1100));
26+
27+ // set all envelope durations
28+ env[idx].set(env_time, 1::second, 0.5, env_time);
29+
30+ // set all envelope power curves
31+ env[idx].setCurves(curve, 1.0, 1.0/curve);
32+
33+ // begins attack phase
34+ env[idx].keyOn();
35+ env_time => now;
36+
37+ // begins decay phase
38+ 1::second => now;
39+
40+ // begins release phase
41+ env[idx].keyOff();
42+ env_time => now;
43+ }
44+}
45+
46+for (int i; i < num; i++) {
47+ spork ~ loopSin(i);
48+}
49+
50+while (true) {
51+ 1::second => now;
52+}
examples/effects/PowerADSR.ck+89−0
@@ -0,0 +1,89 @@
1+// PowerADSR is a power based ADSR envelope that
2+// allows separate power curves for each envelope phase.
3+// In general, curves under 1.0 are sharp, while curves over 1.0 are soft.
4+
5+// ~ linearEnvelope^curveValue ~
6+
7+// ~options
8+//
9+// set (duration a, duration d, float s, duration r), default (0.0, 0.0, 1.0, 0.0)
10+// sets duration for attack, decay, and release phase; sets sustain level
11+//
12+// attack or attackTime (duration a), default 1.0::second
13+// sets length for the attack phase
14+//
15+// decay or decayTime (duration d), default 1.0::second
16+// sets length for the decay phase
17+//
18+// release or releasetTime (duration r), default 1:0::second
19+//
20+// sustainLevel (float s), default 0.5
21+// sets level for the sustain phase
22+//
23+// setCurves (float ac, float dc, float rc), default (1.0, 1.0, 1.0) (all linear)
24+// sets power curve for attack, decay, and release phase
25+//
26+// attackCurve (float ac), default 1.0 (linear)
27+// sets power curve for the attack phase
28+//
29+// decayCurve (float dc), default 1.0 (linear)
30+// sets power curve for the decay phase
31+//
32+// releaseCurve(float rc), default 1.0 (linear)
33+// sets power curve for the release phase
34+
35+Noise nois;
36+PowerADSR env;
37+
38+// sound chain
39+nois => env => dac;
40+
41+// you can set the envelope on paramter at a time
42+env.attackTime(1::second);
43+env.releaseTime(1::second);
44+
45+// defaults to a 1.0 curve, you have to set
46+// the curves for the power functionality
47+
48+// curves under 1.0 are sharper
49+env.attackCurve(0.5);
50+
51+// curves over 1.0 are softer
52+env.releaseCurve(2.0);
53+
54+env.keyOn();
55+1::second => now;
56+env.keyOff();
57+1::second => now;
58+
59+// you can also set all the durations and sustain at once
60+env.set(2::second, 1::second, 0.8, 0.5::second);
61+
62+// and all the curves can be set at once, without the sustain
63+env.setCurves(1.75, 1.25, 1.5);
64+
65+env.keyOn();
66+3::second => now;
67+env.keyOff();
68+1.0::second => now;
69+
70+env.set(1::second, 1::second, 0.5, 1::second);
71+
72+// and you can retrieve the state and value of the envelope
73+<<< "Done\t", env.state(), env.value(), "" >>>;
74+
75+env.keyOn();
76+<<< "Attack\t", env.state(), env.value(), "" >>>;
77+1::second => now;
78+
79+<<< "Decay\t", env.state(), env.value(), "" >>>;
80+1::second => now;
81+
82+<<< "Sustain\t", env.state(), env.value(), "" >>>;
83+1::second => now;
84+
85+env.keyOff();
86+<<< "Release\t", env.state(), env.value(), "" >>>;
87+1::second => now;
88+
89+<<< "Done\t", env.state(), env.value(), "" >>>;
examples/effects/Spectacle.ck+51−0
@@ -0,0 +1,51 @@
1+//////////////////////////////////////////////////////
2+// Spectacle - FFT-based spectral delay and EQ //
3+// //
4+// SPECTACLE is an FFT-based delay instrument by //
5+// John Gibson and inspired by the totally awesome //
6+// Spektral Delay plug-in by Native Instruments. //
7+// This version is adapted from RTcmix (rtcmix.org) //
8+// by Joel Matthys //
9+//////////////////////////////////////////////////////
10+
11+// Options
12+//
13+// mix (float) [0-1]: mix of processed and unprocessed signal. default 1.0
14+// clear (void) : reset Spectacle
15+// fftlen (int) : set FFT frame size (power of 2)
16+// overlap (int) : set frame overlap; best between 2 and 6
17+// delayMax (dur) : maximum delay time
18+// delayMin (dur) : minimum delay time
19+// freqMax (float) : maximum frequency processed by Spectacle
20+// freqMin (float) : minimum frequency processed by Spectacle
21+// range (float, float) : set both min and min freqs in one command
22+// bands (int) : set number of frequency bands, 1-512, default 64
23+// delay (dur) : set the same duration for all bands
24+// eq (float) : set the same EQ value for all bands (value is +/- dB)
25+// feedback (float) : set the same feedback value for all bands (-1.0 - 1.0)
26+//
27+// table (string, string) : set delay, eq, or feedback tables to
28+// random, ascending, or descending
29+// example: table ("delay", "random");
30+
31+// warning: use headphones or you'll get feedback!
32+adc => Spectacle spect => dac;
33+0.5 => spect.mix; // mix half processed and unprocessed signal
34+spect.range(100,4100); // limit frequency range
35+20 => spect.bands; // set number of bands to 20
36+// This will divide the spectrum evenly within the frequency range.
37+// Band 1 will cover 100-300 Hz, Band 2 will cover 300-500 Hz, etc.
38+// up to Band 20, which covers 3900-4100 Hz.
39+<<< spect.bands(), "frequency bands with random delay by default" >>>;
40+10::second => now;
41+<<< "switching to ascending delay and descending eq","">>>;
42+spect.table("delay","ascending");
43+spect.table("eq","descending");
44+10::second => now;
45+<<< "switching to ascending eq with feedback","" >>>;
46+0 => spect.eq;
47+0.8 => spect.feedback;
48+20::second => now;
49+adc =< spect; // disconnect input
50+<<< "ringing down","" >>>;
51+minute => now; // let it ring down
examples/effects/WinFuncEnv.ck+103−0
@@ -0,0 +1,103 @@
1+// WinFunEnv is an Attack/Release envelope built around window functions!
2+
3+// ~options
4+//
5+// .set (duration, duration), default (0.0, 0.0)
6+// sets duration for attack and release phase
7+//
8+// .attackTime (duration), default 0.0
9+// sets length for the attack phase
10+//
11+// .releaseTime (duration), default 0.0
12+// sets length for the release phase
13+//
14+// ~ the following window functions are available to use as envelopes
15+// ~ certain functions allow for custom coefficient values (ie setBlackman(0.64) )
16+//
17+// setBlackman()
18+// setBlackman(float a)
19+// setBlackmanHarris()
20+// setBlackmanDerivative (float a0, float a1, float a2, float a3);
21+// setBlackmanNutall()
22+// setExponential()
23+// setExponential(a)
24+// setHann()
25+// setHannPoisson()
26+// setHannPoisson(a)
27+// setNutall()
28+// setParzen()
29+// setPoisson()
30+// setPoisson(float a)
31+// setTukey()
32+// setTukey(float a)
33+// setWelch
34+//
35+// ~ hopefully further updates will see more windows being added (Kaiser, etc)
36+
37+Noise nois => WinFuncEnv win1 => dac;
38+
39+fun void playWindow(WinFuncEnv @ win, dur attack, dur release) {
40+ win.attackTime(attack);
41+ win.releaseTime(release);
42+ win.keyOn();
43+ attack => now;
44+ win.keyOff();
45+ release => now;
46+}
47+
48+// sets Blackman Envelope with a default value of 0.16
49+win1.setBlackman();
50+<<< "Blackman Envelope with default value of 0.16 on white noise", "" >>>;
51+playWindow(win1, 2.5::second, 2.5::second);
52+
53+// sets Blackman Envelope with a custom value
54+win1.setBlackman(Math.random2f(0.05, 0.25));
55+<<< "Blackman Envelope with a random custom value on white noise.", "" >>>;
56+playWindow(win1, 2.5::second, 2.5::second);
57+
58+<<< "Blackman Envelope with a short attack and a long release..", "" >>>;
59+playWindow(win1, 100::ms, 3::second);
60+
61+<<< "Blackman Envelope with a long attack and a short release..", "" >>>;
62+playWindow(win1, 3::second, 100::ms);
63+
64+// sets BlackmanHarris Envelope
65+win1.setBlackmanHarris();
66+<<< "BlackmanHarris Envelope on white noise.", "" >>>;
67+playWindow(win1, 2.5::second, 2.5::second);
68+
69+// replacing noise with a sine wave
70+nois =< win1;
71+SinOsc sin => win1;
72+
73+// sets Parzen Envelope
74+win1.setParzen();
75+<<< "Parzen Window used for amplitude modulation on a sine wave", "" >>>;
76+for (int i; i < 25000; i++) {
77+ playWindow(win1, 0.1::ms, 0.1::ms);
78+}
79+
80+// sets Hann Envelope
81+win1.setHann();
82+<<< "Hann Window used for amplitude modulation on a sine wave", "" >>>;
83+for (int i; i < 25000; i++) {
84+ playWindow(win1, 0.1::ms, 0.1::ms);
85+}
86+
87+// removing sine wave, adding noise and a second envelope to be in series with the first
88+sin =< win1;
89+nois => win1 =< dac;
90+win1 => WinFuncEnv win2 => dac;
91+
92+<<< "Two envelopes, one Parzen and one Welch in series with each other with slightly different envelope times.", "" >>>;
93+win1.setParzen();
94+win2.setWelch();
95+
96+fun void loop(WinFuncEnv @ win, dur envTime) {
97+ repeat(500) {
98+ playWindow(win, envTime, envTime);
99+ }
100+}
101+
102+spork ~ loop(win1, 70::ms);
103+loop(win2, 73::ms);
examples/filter/Elliptic-help.ck+59−0
@@ -0,0 +1,59 @@
1+/////////////////////////////////////////////////////////////
2+// Elliptic //
3+// //
4+// Elliptic implements cascaded IIR filters and a built-in //
5+// elliptical filter design. It is capable of low-pass, //
6+// high-pass, or bandpass filtering with very steep //
7+// slopes. //
8+// //
9+// The atten determines how much of the signal is //
10+// attenuated outside the passband. //
11+// //
12+// Elliptic filters come with a trade-off for their steep //
13+// slopes: they have a certain amount of ripple outside //
14+// the passbands. A very small ripple (0.1 or 0.2 dB) //
15+// produces very little ringing, whereas a large ripple //
16+// (eg. 20 dB) produces a very strong harmonic ring. //
17+// //
18+// The filter design algorithm sometimes can't fulfill the //
19+// design criteria -- a particular combination of cutoff //
20+// frequencies, ripple, and attenuation. If that happens, //
21+// the user is warned that the filter is not initialized, //
22+// and the filter is bypassed. This may happen, for //
23+// instance, if you ask for a very steep attenuation with //
24+// very low ripple. //
25+/////////////////////////////////////////////////////////////
26+
27+// Settings
28+//
29+// atten (float): filter attenuation in dB. Default 90.0
30+// ripple (float): filter ripple in dB. Default 0.2
31+// bypass (int): switch bypass on or off. Default 0
32+//
33+// Before using the filter, you must initialize it as a
34+// low-pass (lpf), high-pass (hpf), or band-pass filter and
35+// designate the passband and stopband frequencies.
36+//
37+// lpf (passband Hz, stopband Hz): create a low-pass filter
38+// hpf (stopband Hz, passband Hz): create a high-pass filter
39+//
40+// bpf (lower passband, upper passband, stopband):
41+// (usually these parameters are ascending values.)
42+//
43+
44+Noise n => Elliptic ell => dac;
45+0.1 => n.gain;
46+
47+80 => ell.atten; // 80 dB attenuation
48+10 => ell.ripple; // 10 dB ripple will cause ringing
49+
50+ell.bpf(500,600,650); // create band-pass filter which
51+ // passes the range 500-600 Hz
52+ // unattenuated, then slopes from
53+ // 600-650 Hz (and 450-500 Hz)
54+
55+true => ell.bypass; // bypass filter
56+2::second => now;
57+
58+false => ell.bypass; // activate filter
59+minute => now;
examples/filter/FIR-convolve-homer.ck+16−0
@@ -0,0 +1,16 @@
1+// FIRConvolveHomer.ck by Perry R. Cook, 10/12
2+// Use FIR to convolve mic input with "dope!"
3+
4+adc => Gain g => FIR imp => dac;
5+SndBuf s => dac;
6+"special:dope" => s.read;
7+
8+s.samples() => imp.order;
9+for (0 => int i; i < imp.order(); i++) {
10+ imp.coeff(i,s.last());
11+ 1.0 :: samp => now;
12+}
13+
14+5.0 :: second => now;
15+
16+
examples/filter/FIR-greyhole-down-up-decimate.ck+50−0
@@ -0,0 +1,50 @@
1+// "Greyhole" demo with decimation/down/upsampling
2+// By Perry R. Cook, October 2012
3+// This demonstrates a couple of things
4+// 1) using FIR Sinc filters for bandlimiting and reconstruction
5+// 2) decimation, for doing signal processing at lower rates
6+// or just for fun
7+
8+int decFactor; // can specify like: chuck TestDownUpSample.ck:8
9+if (me.args() > 0) Std.atoi(me.arg(0)) => decFactor;
10+else 16 => decFactor; // or it will default to what is here
11+
12+Gain decimate; // anything chucked to here will run at lower rate
13+adc => FIR lowpass => blackhole; // initial band limiting if needed
14+Step holdout => FIR lp2 => WvOut w => dac; // hold and reconstruct
15+"test.wav" => w.wavFilename;
16+0.1 => w.fileGain;
17+
18+// lowpass is here to bandlimit before downsampling
19+1.0 => lowpass.gain; 128 => lowpass.order; decFactor => lowpass.sinc;
20+// lp2 is here to get rid of decimation critters after upsampling
21+// but doesn't have to be as high order (driven by a step)
22+1.0 => lp2.gain; 64 => lp2.order; decFactor => lp2.sinc;
23+
24+spork ~ decimateBy(decFactor);
25+
26+1 => int notDone;
27+
28+SinOsc s => decimate; // test to prove decimation works
29+10000.0 => s.freq; // sine freq won't be this, it will
30+0.1 => s.gain; // be thisFreq / decFactor because it
31+ // only runs at the lower rate!!
32+
33+1.0 => lowpass.gain; // this sets/mutes the microphone input
34+
35+while(notDone)
36+{
37+ 0.05 :: second => now; // hang out here and do nothing
38+}
39+
40+fun void decimateBy(int factor) {
41+ while (notDone) { // only take every factor-th
42+ lowpass => decimate; // sample from our input(s)
43+ decimate => blackhole; // hook things up and let
44+ 1 :: samp => now; // one sample through
45+ decimate.last()=> holdout.next; // sample to output
46+ lowpass =< decimate; // now disconnect everybody
47+ decimate =< blackhole; // (probably too enthusiastically)
48+ (factor - 1) :: samp => now; // and hang around between
49+ }
50+}
examples/filter/FIR-sinc-explicit.ck+20−0
@@ -0,0 +1,20 @@
1+// FIR filter demo program, Perry R. Cook, Oct 2012
2+// This shows how to load filter coefficients
3+// explicitly, in this case with a Sinc lowpass filter
4+
5+Noise n => Gain g => FIR f => WvOut w => dac;
6+w.wavFilename("temp.wav");
7+
8+127 => f.order;
9+f.coeff(64,1.0);
10+for (1 => int i; i < 63; i++) {
11+ (i * pi)/4.0 => float temp;
12+ f.coeff(64-i,Math.cos(i*pi/128)*(Math.sin(temp)/temp));
13+ <<< i, f.coeff(64+i,f.coeff(64-i)) >>>;
14+}
15+
16+0.2 => g.gain;
17+
18+5.0 :: second => now;
19+
20+w.closeFile();
examples/filter/KasFilter.ck+29−0
@@ -0,0 +1,29 @@
1+chout <= "creating a KasFilter \n";
2+chout.flush();
3+
4+BlitSaw s => KasFilter kf => dac;
5+
6+110 => s.freq;
7+chout <= "setting variables \n";
8+chout.flush();
9+
10+.9 => kf.gain;
11+.7 => kf.resonance;
12+.3 => kf.accent;
13+chout <= "testing sound using a sweep \n";
14+chout.flush();
15+
16+for (110 => float x; x < 5000; 1.0003 *=>x)
17+{
18+ x => kf.freq;
19+ ms => now;
20+}
21+chout <= "testing get functions \n";
22+chout <= "freq = " <= kf.freq() <= "\n";
23+chout <= "resonance = " <= kf.resonance() <= "\n";
24+chout <= "accent = " <= kf.accent() <= "\n";
25+chout.flush();
26+
27+0 => s.freq;
28+0 => s.op;
29+2::second => now;
examples/filter/Multicomb.ck+25−0
@@ -0,0 +1,25 @@
1+////////////////////////////////////////////////////
2+// Multicomb //
3+// //
4+// Multiple simultaneous comb filters randomly //
5+// chosen within a specified frequency range //
6+// and spread across the stereo field //
7+////////////////////////////////////////////////////
8+//
9+// Settings:
10+//
11+// num (int): set number of comb filters (default 5)
12+// minfreq (float): set low frequency
13+// maxfreq (float): set high frequency
14+// set (float, float): set both low and high freqs
15+// revtime (dur): total ring time (default 1::second)
16+
17+Impulse imp => Multicomb comb => dac;
18+500::ms => comb.revtime;
19+
20+repeat (60)
21+{
22+ comb.set(220,880);
23+ 1 => imp.next;
24+ 500::ms => now;
25+}
examples/filter/WPDiodeLadder.ck+16−0
@@ -0,0 +1,16 @@
1+Noise nse => WPDiodeLadder fltr => dac;
2+
3+SinOsc sin => blackhole;
4+SinOsc sinb => blackhole;
5+0.01 => nse.gain;
6+40 => sin.freq;
7+0.0125 => sinb.freq;
8+17 => fltr.resonance;
9+true => fltr.nonlinear;
10+false => fltr.nlp_type;
11+
12+while(true){
13+ 40 * sinb.last() => sin.freq;
14+ 40 + (Math.pow((sin.last() + 1)/2.0,2) * 17000) => fltr.cutoff;
15+ 1::samp => now;
16+}
examples/filter/WPKorg35.ck+15−0
@@ -0,0 +1,15 @@
1+Noise nse => WPKorg35 fltr => dac;
2+
3+SinOsc sin => blackhole;
4+SinOsc sinb => blackhole;
5+0.01 => nse.gain;
6+40 => sin.freq;
7+0.0125 => sinb.freq;
8+1.99999 => fltr.resonance;
9+true => fltr.nonlinear;
10+
11+while(true){
12+ 40 * sinb.last() => sin.freq;
13+ 40 + (Math.pow((sin.last() + 1)/2.0,2) * 17000) => fltr.cutoff;
14+ 1::samp => now;
15+}
examples/spatial/AmbPan3-CCRMA.ck+19−0
@@ -0,0 +1,19 @@
1+
2+CNoise noise => AmbPan3 pan => dac;
3+
4+0.1 => noise.gain;
5+"pink" => noise.mode;
6+
7+// W X Y Z R S T U V K L M N O P Q
8+ [0, 1, 2, 7, 8, 9, 10, 3, 4,11,12,13, 14, 15, 5, 6] => pan.channelMap;
9+
10+0 => pan.elevation;
11+pi/2 => pan.azimuth;
12+
13+while(true)
14+{
15+ //pan.azimuth()+pi/1024 => pan.azimuth;
16+ pan.elevation() + pi/1024 => pan.elevation;
17+ 5::ms => now;
18+}
19+
examples/spatial/Pan4.ck+11−0
@@ -0,0 +1,11 @@
1+
2+CNoise noise => Pan4 pan => dac;
3+
4+"pink" => noise.mode;
5+0.1 => noise.gain;
6+
7+while(true)
8+{
9+ pan.pan() + 0.01 => pan.pan;
10+ 10::ms => now;
11+}
examples/spatial/Pan8.ck+12−0
@@ -0,0 +1,12 @@
1+
2+CNoise noise => Pan8 pan => dac;
3+
4+"pink" => noise.mode;
5+0.1 => noise.gain;
6+0 => pan.pan;
7+
8+while(true)
9+{
10+ pan.pan() + 0.01 => pan.pan;
11+ 10::ms => now;
12+}
examples/special/Mesh2D.ck+43−0
@@ -0,0 +1,43 @@
1+///////////////////////////////////////////////////////////////////////////////
2+// Mesh2D: Two-dimensional rectilinear waveguide mesh class. //
3+// //
4+// Part of the Synthesis Toolkit in C++ //
5+// https://ccrma.stanford.edu/software/stk/ //
6+// //
7+// This class implements a rectilinear, two-dimensional digital waveguide //
8+// mesh structure. For details, see Van Duyne and Smith, "Physical Modeling //
9+// with the 2-D Digital Waveguide Mesh", Proceedings of the 1993 //
10+// International Computer Music Conference. //
11+// //
12+// This is a digital waveguide model, making its use possibly subject to //
13+// patents held by Stanford University, Yamaha, and others. //
14+///////////////////////////////////////////////////////////////////////////////
15+
16+// Options:
17+//
18+// x: X dimension size in samples. int [2-12], default 5
19+// y: Y dimension size in samples. int [2-12], default 4
20+// xpos: x strike position. float [0-1], default 0.5
21+// ypos: y strike position. float [0-1], default 0.5
22+// decay: decay factor. float [0-1], default 0.999
23+
24+Mesh2D mesh1 => dac.left;
25+Mesh2D mesh2 => dac.right;
26+0.5 => mesh1.gain => mesh2.gain;
27+
28+while (true)
29+{
30+ Math.random2(2,12) => mesh1.x;
31+ Math.random2(2,12) => mesh1.y;
32+ Math.randomf() => mesh1.xpos;
33+ Math.randomf() => mesh1.ypos;
34+ 1 => mesh1.noteOn;
35+ 250::ms => now;
36+ Math.random2(2,12) => mesh2.x;
37+ Math.random2(2,12) => mesh2.y;
38+ Math.randomf() => mesh2.xpos;
39+ Math.randomf() => mesh2.ypos;
40+ 1 => mesh2.noteOn;
41+ 250::ms => now;
42+
43+}
src/core/ugen_stk.cpp+9−6
@@ -4967,8 +4967,9 @@ Modified algorithm code by Gary Scavone, 2005."; · 4966 unmodified lines
49674967 // end the class import
49684968 type_engine_import_class_end( env );
49694969
4970−
49714970 // Mesh2D
4971+ // 1.5.0.0 (ge) commented out, using the chugin Mesh2D
4972+ /*
49724973 if( !type_engine_import_ugen_begin( env, "Mesh2D", "UGen", env->global(),
49734974 Mesh2D_ctor, Mesh2D_dtor,
49744975 Mesh2D_tick, Mesh2D_pmsg ) ) return FALSE;
@@ -5018,6 +5019,7 @@ Modified algorithm code by Gary Scavone, 2005."; · 43 unmodified lines
50185019
50195020 // end the class import
50205021 type_engine_import_class_end( env );
5022+ */
50215023
50225024 // MidiFileIn
50235025 if(!type_engine_import_class_begin( env, "MidiFileIn", "Object", env->global(), MidiFileIn_ctor, MidiFileIn_dtor,
@@ -27611,13 +27613,14 @@ CK_DLL_CTRL( WvIn_ctrl_path ) · 22587 unmodified lines
2761127613 if( path != NULL )
2761227614 {
2761327615 // open
27614− try { w->openFile( path->str().c_str(), FALSE, FALSE ); }
27615− catch( StkError & e )
27616− {
27616+ w->openFile( path->str().c_str(), FALSE, FALSE );
27617+ // try { w->openFile( path->str().c_str(), FALSE, FALSE ); }
27618+ // catch( StkError & e )
27619+ // {
2761727620 // do nothing here; should have already printed
2761827621 // const char * s = e.getMessage();
2761927622 // CK_FPRINTF_STDERR( "[chuck](via STK): WvIn cannot load file '%s'\n", c );
27620− }
27623+ // }
2762127624 }
2762227625
2762327626 // return value
@@ -27977,7 +27980,7 @@ CK_DLL_CTRL( WvOut_ctrl_matFilename ) · 353 unmodified lines
2797727980 catch( StkError & e )
2797827981 {
2797927982 // CK_FPRINTF_STDERR( "%s\n", e.getMessage() );
27980− CK_STDCERR << "[chuck]: WvOut cannot open mat file: " << filename << CK_STDENDL;
27983+ CK_STDCERR << "[chuck]: WvOut cannot open mat file: " << theFilename.c_str() << CK_STDENDL;
2798127984 CK_STDCERR << "[chuck]: WvOut error text '" << e.getMessage() << "'" << CK_STDENDL;
2798227985 goto done;
2798327986 }
src/core/ulib_doc.cpp+43−9
@@ -305,8 +305,13 @@ public: · 304 unmodified lines
305305 {
306306 m_outputStr += "<a name=\"top\"/>\n";
307307 m_outputStr += "<div id=\"title\">\n";
308− m_outputStr += "<div class=\"titleL\"><h1><a href=\"./\">ChucK Class Library Reference</a></h1></div>\n";
309− m_outputStr += "<div class=\"titleR\"><h1>&nbsp;&nbsp;<span style=\"color:black\">/</span>&nbsp;&nbsp;" + m_title + "</h1></div>\n";
308+ m_outputStr += "<div class=\"titleL\">\n";
309+ m_outputStr += "<div style=\"display: flex; align-items: center;\">";
310+ m_outputStr += "<div class=\"inline titlelogo\"><a href=\"https://chuck.stanford.edu/\" target=\"_blank\"><img src=\"https://chuck.stanford.edu/doc/images/chuck-logo2023w.png\" /> </div>";
311+ m_outputStr += "<div class=\"inline\"><h1><a href=\"./\">ChucK Class Library Reference</a></h1></div>\n";
312+ m_outputStr += "<div class=\"inline gray\"><h1>&nbsp;&nbsp;<span style=\"color:black\">/</span>&nbsp;&nbsp;" + m_title + "</h1></div>\n";
313+ m_outputStr += "</div>\n";
314+ m_outputStr += "</div>\n";
310315 m_outputStr += "</div>\n"; // #title
311316 }
312317
@@ -662,8 +667,12 @@ string CKDocHTMLOutput::renderIndex( const string & title, const vector<CKDocGro · 349 unmodified lines
662667 sout << "</head>\n";
663668 sout << "<body>\n";
664669 sout << "<div id=\"title\">\n";
665− sout << "<div class=\"titleL\"><h1>" << title << "</h1></div>\n";
666− sout << "<div class=\"titleR\"><h1>&nbsp;</h1></div>\n";
670+ sout << "<div class=\"titleL\">\n";
671+ sout << "<div style=\"display: flex; align-items: center;\">";
672+ sout << "<div class=\"inline titlelogo\"><a href=\"https://chuck.stanford.edu/\" target=\"_blank\"><img src=\"https://chuck.stanford.edu/doc/images/chuck-logo2023w.png\" /> </div>";
673+ sout << "<div class=\"inline\"><h1>" << title << "</h1></div>\n";
674+ sout << "</div>\n";
675+ sout << "</div>\n";
667676 sout << "</div>\n";
668677 sout << "<div id=\"body\">\n";
669678
@@ -1705,7 +1714,7 @@ a\n\ · 1035 unmodified lines
17051714 left: 0;\n\
17061715 right: 0;\n\
17071716 border-bottom: 1px solid black;\n\
1708− padding: 1em 2em;\n\
1717+ padding: 0.5em 2em;\n\
17091718 margin-bottom: 1.5em;\n\
17101719 background-color: white;\n\
17111720 float: left;\n\
@@ -1716,15 +1725,40 @@ a\n\ · 4 unmodified lines
17161725 {\n\
17171726 float: left;\n\
17181727 width: auto;\n\
1719− clear: none;\n\
1728+ /* vertically center */\n\
1729+ line-height: 48px;\n\
1730+ height: 48px;\n\
17201731 }\n\
17211732 \n\
1733+.gray\n\
1734+{\n\
1735+ color: gray;\n\
1736+}\n\
1737+\n\
1738+.inline\n\
1739+{\n\
1740+ display: inline;\n\
1741+}\n\
1742+\n\
1743+\n\
17221744 .titleR\n\
17231745 {\n\
1724− /* float: right; */\n\
1725− width: auto;\n\
1746+ float: right;\n\
1747+ width: initial;\n\
17261748 clear: none;\n\
1727− color: gray;\n\
1749+}\n\
1750+\n\
1751+.titleLogo\n\
1752+{\n\
1753+ width: 48px;\n\
1754+ height: 48px;\n\
1755+ padding-right: 8px;\n\
1756+}\n\
1757+\n\
1758+.titleLogo img\n\
1759+{\n\
1760+ width: 48px;\n\
1761+ height: 48px;\n\
17281762 }\n\
17291763 \n\
17301764 h1\n\

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t