Unified · Split
| @@ -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 | +} | |
| @@ -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 | +} | |
| @@ -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 | +} | |
| @@ -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 | +} | |
| @@ -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 | +} | |
| @@ -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 | + | |
| @@ -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 | +} | |
| @@ -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 | +} | |
| @@ -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 | +} | |
| @@ -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 | +} | |
| @@ -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 | +*/ | |
| @@ -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 | +} | |
| @@ -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(), "" >>>; | |
| @@ -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 | |
| @@ -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); | |
| @@ -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; | |
| @@ -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 | + | |
| @@ -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 | +} | |
| @@ -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(); | |
| @@ -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; | |
| @@ -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 | +} | |
| @@ -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 | +} | |
| @@ -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 | +} | |
| @@ -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 | + | |
| @@ -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 | +} | |
| @@ -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 | +} | |
| @@ -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 | +} | |
| @@ -4967,8 +4967,9 @@ Modified algorithm code by Gary Scavone, 2005."; · 4966 unmodified lines | ||
| 4967 | 4967 | // end the class import |
| 4968 | 4968 | type_engine_import_class_end( env ); |
| 4969 | 4969 | |
| 4970 | − | |
| 4971 | 4970 | // Mesh2D |
| 4971 | + // 1.5.0.0 (ge) commented out, using the chugin Mesh2D | |
| 4972 | + /* | |
| 4972 | 4973 | if( !type_engine_import_ugen_begin( env, "Mesh2D", "UGen", env->global(), |
| 4973 | 4974 | Mesh2D_ctor, Mesh2D_dtor, |
| 4974 | 4975 | Mesh2D_tick, Mesh2D_pmsg ) ) return FALSE; |
| @@ -5018,6 +5019,7 @@ Modified algorithm code by Gary Scavone, 2005."; · 43 unmodified lines | ||
| 5018 | 5019 | |
| 5019 | 5020 | // end the class import |
| 5020 | 5021 | type_engine_import_class_end( env ); |
| 5022 | + */ | |
| 5021 | 5023 | |
| 5022 | 5024 | // MidiFileIn |
| 5023 | 5025 | 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 | ||
| 27611 | 27613 | if( path != NULL ) |
| 27612 | 27614 | { |
| 27613 | 27615 | // 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 | + // { | |
| 27617 | 27620 | // do nothing here; should have already printed |
| 27618 | 27621 | // const char * s = e.getMessage(); |
| 27619 | 27622 | // CK_FPRINTF_STDERR( "[chuck](via STK): WvIn cannot load file '%s'\n", c ); |
| 27620 | − } | |
| 27623 | + // } | |
| 27621 | 27624 | } |
| 27622 | 27625 | |
| 27623 | 27626 | // return value |
| @@ -27977,7 +27980,7 @@ CK_DLL_CTRL( WvOut_ctrl_matFilename ) · 353 unmodified lines | ||
| 27977 | 27980 | catch( StkError & e ) |
| 27978 | 27981 | { |
| 27979 | 27982 | // 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; | |
| 27981 | 27984 | CK_STDCERR << "[chuck]: WvOut error text '" << e.getMessage() << "'" << CK_STDENDL; |
| 27982 | 27985 | goto done; |
| 27983 | 27986 | } |
| @@ -305,8 +305,13 @@ public: · 304 unmodified lines | ||
| 305 | 305 | { |
| 306 | 306 | m_outputStr += "<a name=\"top\"/>\n"; |
| 307 | 307 | 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> <span style=\"color:black\">/</span> " + 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> <span style=\"color:black\">/</span> " + m_title + "</h1></div>\n"; | |
| 313 | + m_outputStr += "</div>\n"; | |
| 314 | + m_outputStr += "</div>\n"; | |
| 310 | 315 | m_outputStr += "</div>\n"; // #title |
| 311 | 316 | } |
| 312 | 317 | |
| @@ -662,8 +667,12 @@ string CKDocHTMLOutput::renderIndex( const string & title, const vector<CKDocGro · 349 unmodified lines | ||
| 662 | 667 | sout << "</head>\n"; |
| 663 | 668 | sout << "<body>\n"; |
| 664 | 669 | sout << "<div id=\"title\">\n"; |
| 665 | − sout << "<div class=\"titleL\"><h1>" << title << "</h1></div>\n"; | |
| 666 | − sout << "<div class=\"titleR\"><h1> </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"; | |
| 667 | 676 | sout << "</div>\n"; |
| 668 | 677 | sout << "<div id=\"body\">\n"; |
| 669 | 678 | |
| @@ -1705,7 +1714,7 @@ a\n\ · 1035 unmodified lines | ||
| 1705 | 1714 | left: 0;\n\ |
| 1706 | 1715 | right: 0;\n\ |
| 1707 | 1716 | border-bottom: 1px solid black;\n\ |
| 1708 | − padding: 1em 2em;\n\ | |
| 1717 | + padding: 0.5em 2em;\n\ | |
| 1709 | 1718 | margin-bottom: 1.5em;\n\ |
| 1710 | 1719 | background-color: white;\n\ |
| 1711 | 1720 | float: left;\n\ |
| @@ -1716,15 +1725,40 @@ a\n\ · 4 unmodified lines | ||
| 1716 | 1725 | {\n\ |
| 1717 | 1726 | float: left;\n\ |
| 1718 | 1727 | width: auto;\n\ |
| 1719 | − clear: none;\n\ | |
| 1728 | + /* vertically center */\n\ | |
| 1729 | + line-height: 48px;\n\ | |
| 1730 | + height: 48px;\n\ | |
| 1720 | 1731 | }\n\ |
| 1721 | 1732 | \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\ | |
| 1722 | 1744 | .titleR\n\ |
| 1723 | 1745 | {\n\ |
| 1724 | − /* float: right; */\n\ | |
| 1725 | − width: auto;\n\ | |
| 1746 | + float: right;\n\ | |
| 1747 | + width: initial;\n\ | |
| 1726 | 1748 | 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\ | |
| 1728 | 1762 | }\n\ |
| 1729 | 1763 | \n\ |
| 1730 | 1764 | h1\n\ |