Bouncing ball delay

would someone know how to implement a bouncing ball delay?

cool, but this is slowing down, and bouncing balls ascelerate :slight_smile:

You can use a multi-tap delay:

// amended example from DelTapWr help
// a Buffer for the UGens to use, one second at the current sample rate
b = Buffer.alloc(s, s.sampleRate * 1, 1);

(
// write a signal into a delay, tap it at multiple times
SynthDef(\test, { |out, buffer|
    var src, tapPhase, taps, times, muls;
    src = WhiteNoise.ar(0.2) * Decay.kr(Dust.kr(1.5), 0.2);
    tapPhase = DelTapWr.ar(buffer, src);
	times = 8.collect({arg i; 1 - (0.8 ** (i + 1));});
	muls = 8.collect({arg i; 0.8 ** i});
    taps = DelTapRd.ar(buffer, tapPhase,
        times,   // tap times
        1,       // no interp
        muls     // muls for each tap
    );
    Out.ar(out, [src, taps.sum])
}).add;
)

x = Synth(\test, [\buffer, b]);
x.free;
b.free;

Best,
Paul

1 Like

Hi @porres ,
some time ago I’ve written something making use of the TBall Ugen.

I wanted something that would play a sample repeatedly, at increasingly closer intervals.

To do this I used the granulation technique (in particular I had used the Ugen GrainBufJ (a Joshua-modified version of GrainBuf that I had found inside the SCplugins > JoshUgens ).

Here’s the code for the synth:

(
SynthDef(\grainbufj_ball_mul_env, {
	|out=0, amp=1.0, pan=0.0,
	// buffer stuff
	buf, rate=1.0,
	// ball stuff
	g=0.125, damp=0.1, friction=0.001
	// grain stuff
	gdur=1, envbuf, pos=0.0
	// env stuff
	atk=0.0, rel=5, cA=(-4), cB=(-2)
	|
	var sig, trigger, env;

	env = EnvGen.ar(Env.perc(atk, rel, curve:[cA, cB]),1,doneAction:2);
	//triggers generation
	trigger = Impulse.ar(0);
	trigger = TBall.ar(trigger, g, damp, friction);

	sig = GrainBufJ.ar(2, // num channels
		trigger,
		gdur, // size of the grain in seconds
		buf,
		BufRateScale.ir(buf)*rate,
		pos, //position
		grainAmp: Latch.ar(env, trigger),
		//pan: pan,
		// use the pan below for a ping-ping effect
		//pan: Demand.ar(trigger, 0, Dseq([-1, 1], inf)),
		// use line below for a degradint to the center ping-pong
		pan: Demand.ar(trigger, 0, Dseq([-1, 1], inf))* Line.ar(1.0, 0.0, atk+rel),
		envbufnum:envbuf,
		maxGrains: 256
	);

	sig = sig * amp;

	Out.ar(out, Pan2.ar(sig, pan));
}).add;
)

interesting things can happen if you play with the parameters of TBall physics!
let me know :slight_smile:

@bgola where did your code go?

if its just about accelerating rhythms you could curve the phase of a ramp, here perfectly bpm synced.

(
var rampFromBPM = { |bpm, beatsPerMeasure|
	var beatsPerSec = bpm / 60;
	var measureRate = beatsPerSec / beatsPerMeasure;
	(Phasor.ar(DC.ar(0), measureRate * SampleDur.ir) - SampleDur.ir).wrap(0, 1);
};

var rampToTrig = { |phase|
	var history = Delay1.ar(phase);
	var delta = (phase - history);
	var sum = (phase + history);
	var trig = (delta / sum).abs > 0.5;
	Trig1.ar(trig, SampleDur.ir);
};

SynthDef(\test, {
	var measurePhase = rampFromBPM.(\bpm.kr(120), \beatsPerMeasure.kr(4)).lincurve(0, 1, 0, 1, \curve.kr(2));
	var measureTrigger = rampToTrig.(measurePhase);
	var stepsPerMeasure = \stepsPerMeasure.kr(20);
	var stepPhase = (measurePhase * stepsPerMeasure).wrap(0, 1);
	var stepTrigger = rampToTrig.(stepPhase);
	Out.ar(0, stepTrigger * 0.5);
	Out.ar(1, measureTrigger * 0.5);
}).add;
)

x = Synth(\test, [\stepsPerMeasure, 20, \curve, 2]);
x.free;

x = Synth(\test, [\stepsPerMeasure, 100, \curve, 4]);
x.free;