Created
October 16, 2025 13:52
-
-
Save juliusdeblaaij/e75436680845efe011b8470be3f589ba to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //-------------------------------------------------------------------- | |
| // name: shepard-wav-func.ck | |
| // desc: Shepard–Risset illusion from a WAV sample, ascending or descending | |
| //-------------------------------------------------------------------- | |
| // Shepard-tone generator as a sporkable function | |
| fun void shepardTone(string samplePath, float direction) | |
| { | |
| // direction: positive = ascending, negative = descending | |
| .004 / 16.0 * direction => float INC; | |
| 1::ms => dur T; | |
| // Gaussian parameters | |
| 66 => float MU; | |
| 42 => float SIGMA; | |
| 1 / Math.gauss(MU, MU, SIGMA) => float SCALE; | |
| // MIDI pitch values across several octaves | |
| [ 12.0, 24, 36, 48, 60, 72, 84, 96, 108 ] @=> float pitches[]; | |
| pitches.size() => int N; | |
| // output gain | |
| Gain gain => dac; | |
| (1.0/N)*(0.5*N) => gain.gain; | |
| // sample players | |
| SndBuf bufs[N]; | |
| // load and connect | |
| for (int i; i < N; i++) | |
| { | |
| samplePath => bufs[i].read; | |
| bufs[i] => gain; | |
| bufs[i].loop(1); | |
| 0 => bufs[i].pos; | |
| } | |
| // reference frequency for rate calculation | |
| 440.0 => float baseFreq; | |
| // continuous illusion loop | |
| while (true) | |
| { | |
| for (int i; i < N; i++) | |
| { | |
| pitches[i] => Std.mtof => float freq; | |
| freq / baseFreq => bufs[i].rate; | |
| Math.gauss(pitches[i], MU, SIGMA) * SCALE => float intensity; | |
| intensity * 96 => Math.dbtorms => bufs[i].gain; | |
| INC +=> pitches[i]; | |
| if (pitches[i] > 120) 108 -=> pitches[i]; | |
| else if (pitches[i] < 12) 108 +=> pitches[i]; | |
| } | |
| T => now; | |
| } | |
| } | |
| //-------------------------------------------------------------------- | |
| // Example usage | |
| //-------------------------------------------------------------------- | |
| // ascending illusion | |
| spork ~ shepardTone("C:/Users/juliu/Downloads/VCR noise no click.wav", 1.0); | |
| // descending illusion (starts a second later) | |
| 1::second => now; | |
| //spork ~ shepardTone("C:/Users/juliu/Downloads/VCR noise no click.wav", -1.0); | |
| // run forever | |
| while (true) 1::second => now; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment