I still don't understand how it could be, but Poing by the Rotterdam Termination Source topped the charts in the Netherlands in the summer of 1992.
youtu.be/lq6jzgmazk4
I use it to stress test the new debug features :)
Log in to post a comment.
ditty.bpm = 140; const kick = synth.def( (phase, env, tick, options) => Math.sin(phase * 2 * Math.PI * Math.exp(-env.progress)) * env.value, { attack: 0.05, release: 0.3, amp: 1.25, env: adsr2 }); const noise = synth.def( (phase, env, tick, options) => (Math.random() - .5 + 2 * Math.sin(phase)) * (env.value ** 2), { attack: 0.0125, release: 0.45, amp: 1, env: adsr2 }); const poingLine = synth.def( _ => { let x = ditty.tick % 1, base = .8; const i = Math.floor(x = -Math.log(1-x)/Math.log(base)); x = (1-Math.pow(base, i-x)) / (1-1/base); let bounce = -4*x*(x-1) / Math.pow(base*.8, i+1); debug.probe('poing', 2 * bounce - 1, 1, tick_to_second(2)); return 0; }, { env: one }); // My attempt to create the sound of a mouth harp // const poingOsc = synth.def( // class { // constructor(options) { // this.phase = 0; // } // process(note, env, tick, options) { // this.phase += midi_to_hz(note) * ditty.dt * ((env.value + 0.01) ** options.xenv); // const o = .2 * Math.sin(this.phase); // let wave = Math.sin(this.phase * Math.PI * 2 + o); // wave += Math.sin(this.phase * Math.PI * 4.1 + o) / 2; // wave += Math.sin(this.phase * Math.PI * 7.9 + o) / 3; // return wave * (1 - ease01.cubeOut (env.progress)); // } // }, { xenv: -0.4, amp: 1, attack: 0.1, release: 1, env: adsr2 } // ); // Boing sound by srtuss. Much better! // https://dittytoy.net/ditty/4a954c58b5 // // the boing is roughly a sawtooth with a root frequency of 96Hz, through a band-pass filter // the center frequency of the filter sits at 1.2kHz for 90ms, then within 90ms sweeps to 2.9kHz were it stays until the end of the sound const poingOsc = synth.def(class { constructor(opt) { this.p = 0; // crude state variable filter, 12dB per octave this.flt = {lp: 0, bp: 0, hp: 0}; this.t = 0; this.svf = (s, inpt, kf, kq) => { var lp, hp, bp; lp = s.lp + kf * s.bp; hp = inpt - lp - kq * s.bp; bp = s.bp + kf * hp; s.lp = lp; s.hp = hp; s.bp = bp; }; } process(note, env, tick, opt) { // create a sawtooth mixed with a slight square timbre, at a fixed frequency var v = (this.p % 1 + (this.p % 1 < .33 ? .1 : -.1) - .5) * env.value; this.p += 96 * ditty.dt; // add a white noise burst at the beginning v += (Math.random() - .5) * Math.exp(-this.t * 60) * .3; // feed it through the bandpass filter and sweep the filter's cutoff frequency this.svf(this.flt, v, lerp(.169, .41, clamp01((this.t - .09) / .09) ** 2), .08); this.t += ditty.dt; // mix the filter output and saturate it sligthly return Math.sin((this.flt.bp + this.flt.lp * .5 + this.flt.hp * .1) * 4 * env.value); } }, {attack: 0, decay: .4, sustain: .2, release: 0.01, duration: .372, amp: .75}); const delay = filter.def(class { constructor(options) { this.index = 0; this.length = options.interval * ditty.sampleRate * 60 / ditty.bpm | 0; this.left = new Float32Array(this.length); this.right = new Float32Array(this.length); } process(input, options) { if (input) { this.index = (this.index + 1) % this.length; const hist = (this.index + 1) % this.length; const s = options.strength; this.left [this.index] = input[1] + s * this.right[hist]; this.right[this.index] = input[0] + s * this.left [hist]; return [ this.left[this.index], this.right[this.index] ]; } } }, { interval: 1, strength: 0.15 }); loop( (i) => { poingOsc.play(c); kick.play(c); noise.play(c3); sleep(.5); if (i % 8 > 3) noise.play(c3); sleep(.5); } , {sync: 1, amp: .75}).connect( delay.create() ); loop( () => { // bouncing ball ascii art in console const width = 80; const height = 3; const posX = width * 2 * Math.abs(ditty.time * .25 % 1 - .5) | 0; const posY = height * (ditty.tick % 1) ** 2 | 0; const b = posY > 1 ? '0' : 'o'; for (let line=0; line<height; line++) { let str = ''; for (let x=0; x<width; x++) { str += x == posX && line == posY ? b : ' '; } debug.log(line, str); } }, {sync: 1/120}); loop( () => { // bouncing ball osciloscope poingLine.play(c, { duration: 1e5, amp: 0 }); }, { sync: 1e5 } );