Freeq Delay is based around a 'fixed buffer delay', that is the delay length is always a fixed length in samples. To achieve different delay lengths you play the buffer faster or slower. This also mean's that if there's data in the buffer and you change the speed the data get played back at the new speed, as it would in a tape delay say..
There's a few extra effects to spice things up a bit: an LFO, EQ and waveshaper.
It's quite cpu hungry at the moment, but I reckon the main code can be optimised loads, I'm just checking it's working proper first..
There's a few modules in there perhaps worth ripping: the LFO has a tempo sync/pulse width and uses non-bandlimited waveforms for faster cpu, also the fixed buffer delay may come in useful..
Thanks to Angstrom for the preset manager and rl for the pertty backdrop
Have fun
Sam
Shifrin ·
Wow, this thing looks and sounds very cool 🙂
As always, thanks for posting this up Sam!
Shif.
infuzion ·
Does seem neat! Very fun 🙂 I think this has alot of potential to be kick-arce!
A few things:
1) I'm not sure what the waveshaper does? Control the sample buffer's amp, EQ, freq? Plus I think the GUI doesn't make it clear that the EQ is before it in the audio chain.
2) Feedback is often way loud past 50%, to the point of clipping. Might be worth putting the the GUI that it is - % on the left, + % on the right.
3) Having a graphic spline EQ (looking like the waveshaper) would be really neat to simulate damping inside the delay.
rl ·
very nice!
the waveshaper is a neat trick to simulate type saturation (or doing other wild things...)
lalo ·
great stuff sambean 🙂
skOre ·
yummy 😀
Tom7777 ·
Thanks sambean 🙂
oddson ·
This is extremely cool but I can't make heads nor tails out of the delay code... 😕
Any chance you might add some comments to it sometime?
Also, I think 'ratio' is a bit misleading as a label for what I take to be a playback speed variable (on the tape delay analogy).
More great work as always Sam..! 😀
sambean ·
Thanks peeps!
infuzion wrote: Does seem neat! Very fun 🙂 I think this has alot of potential to be kick-arce!
A few things:
1) I'm not sure what the waveshaper does? Control the sample buffer's amp, EQ, freq? Plus I think the GUI doesn't make it clear that the EQ is before it in the audio chain.
2) Feedback is often way loud past 50%, to the point of clipping. Might be worth putting the the GUI that it is - % on the left, + % on the right.
3) Having a graphic spline EQ (looking like the waveshaper) would be really neat to simulate damping inside the delay.
Cheers for the feedback:
1) The waveshaper modifies the signals amp passing through it . You read the input sample along the x axis, and the corresponding y value is the output sample. So a straight diagonal line from bottom-left to top-right will do nothing to the sample (output = input). Different shapes will distort the signal in different ways: the default is set to mimic a sort of tape saturation, as rl suggests..
2) The max feedback is 100%, however if any of the waveshaper graph is above the diagonal line it will amplify as well, so you may get clipping because of that..
3) Good idea.. I may use the parametric EQ instead to allow more complex damping..
oddson wrote: This is extremely cool but I can't make heads nor tails out of the delay code... Confused
Any chance you might add some comments to it sometime?
Also, I think 'ratio' is a bit misleading as a label for what I take to be a playback speed variable (on the tape delay analogy).
Thanks! I'll post some commented code.. I was just making sure it was working, and yup, labelling it 'speed' would be a bit more sensible.. 🙂
With a standard delay you read a sample from an array, write a new sample to the array then increase the array pointer by 1 sample. This creates a simple delay of the length of the array..
With this delay, the array size is fixed, but the size of the step that the pointer makes is defined by the ratio, this has implications for reading and writing to the array.
ratio = min(ratio,10);
ratio = max(ratio,0.1);
/* This is to limit the range of the ratio values..*/
rp = rp + ratio;
rp = rp - (rp>=SIZEDEL)&SIZEDEL;
/*advance the pointer by the ratio, and if it exceeds the delay size, start back again at zero..*/
rpi = rp - 0.5;
rpi = rndint(rpi);
frac = rp - rpi;
/*extract the integer and fractional part of the pointer*/
When reading, it's now possible to have fractional pointers eg 23.45, so we need to interpolate the data, as you would with a wav file
out = (1 - frac) * dubdelay[rpi1] + frac * dubdelay[rpi2];
/*The output is standard linear interpolation between the values rpi1 and rpi2 (pointer +1 and pointer +2) we read from +1 so we don't read the sample we've just written(which can happen with ratios<1)..*/
When writing to the array, we only want to write to integer sample values that the pointer passes:
for example if the old sample position 23.45 and the ratio is 0.3, the new sample position will be 23.75, in this case we havn't crossed a sample, so we we shouldnt write any data..
If on the other hand the old position is 23.45 and th ratio in 2.7, the new sample position will be 26.15, in this case we've crossed 3 sample's 24, 25 and 26 so we should write to these samples using linear interpolation..
The number of samples crossed is calculated with the countback variable, if it's less than zero no samples are crossed, 0-1 1 sample crossed, 1-2 2 samples crossed.. etc
I'll go over the writing code in a bit.. I've got some chores to do now 😉
Cheers
Sam
Shifrin ·
Thanks for that excellent walkthrough of the delay code Sam 🙂
Much appreciated!
Shif.
infuzion ·
Thanks for the feedback on my feedback 🙂
drumma ·
Amazing stuff, thanks ! 🙂
Wrote something here? To have a post removed or your name hidden, write to [email protected].