Open303 - open source 303 emulation project - collaborators wanted

DSP, Plugin and Host development discussion.
Post Reply New Topic
RELATED
PRODUCTS
JC-303

Post

Robin from www.rs-met.com wrote:this must really be it! i could closely fit a 303 filter-sweep via passing an RC-generated envelope through this function, as can be seen here:

Image
So to get this slope, you used

pow( 2, ( env - 0.3846 ) * envAmt )

where envAmt is the 303's 'decay rate' and env is a linear (or exponential?) function of time?

:?:

Post

as far as i understand - no, decay knob controls the time of the envelope (the signal in the "env" variable)
envAmt should be what EnvMod knob controls..

btw, i have doubts about this (tho it sounds promising..)

if we say that the cutoff knob only adds DC to the filter cutoff, and the "bipolar" envelope is all that is left to make the envelopes (i ain't talking about accent or anything, just cutoff and envmod)
then look at my image TB-303_FEnv_anlz_01.jpg (assuming it's correct, and i believe that..) and tell me, would that work?

just looking roughly at it, without messing with the calculator, i got a gut feeling that it won't work
either the cutoff must add to the envmod, or the DC at the envelope (which makes the bipolarity) <or> the envmod changes the cutoff DC

or some wierd filter frequency response (that is not linear like xVolts/KHz)
^^ i don't want to believe that
It doesn't matter how it sounds..
..as long as it has BASS and it's LOUD!

irc.libera.chat >>> #kvr

Post

ok, i'm so dumb, it seems exp(-2 * pi * omega) does the trick ;]
It doesn't matter how it sounds..
..as long as it has BASS and it's LOUD!

irc.libera.chat >>> #kvr

Post

antto wrote:just need to think of the formula (based on sampling rate, or omega, or somethin..)
difference equation:
y[n] = c*y[n-1]

coefficient:
c = exp(-1/(tau*fs))

where: fs: samplerate, tau: decay time constant (time for drop to a level of 1/e = 0.36someting)
My website: rs-met.com, My presences on: YouTube, GitHub, Facebook

Post

brambos wrote: So to get this slope, you used

pow( 2, ( env - 0.3846 ) * envAmt )

where envAmt is the 303's 'decay rate' and env is a linear (or exponential?) function of time?

:?:
yes. and env is the exponential decay from the RC filter. ...and i had to scale the whole curve according to some (assumed) nominal cutoff frequency, of course.

errmm but no, envAmt is not the decay-rate but the 'envelope amount'
My website: rs-met.com, My presences on: YouTube, GitHub, Facebook

Post

ok, no matter what i do, i can't get the RC output to match my curve (you know which one) whatever i do with that 2^((env-x) * y) shaper
it's just not right
and that DC (the X value there) doesn't change the "shape" of the curve in any way, it only makes things difficult
It doesn't matter how it sounds..
..as long as it has BASS and it's LOUD!

irc.libera.chat >>> #kvr

Post

antto wrote:ok, no matter what i do, i can't get the RC output to match my curve (you know which one) whatever i do with that 2^((env-x) * y) shaper
it's just not right
and that DC (the X value there) doesn't change the "shape" of the curve in any way, it only makes things difficult

Antto,

is this what you've been using thus far (need to look up one of your old posts... hang on...)
curve: -0.2938485 / (1.0 + -608.94871 * exp(-6.1539216 * x))
x is your linear envelope.. 1 to 0.. (decaying)

min decay: 0.341
max decay: 4.310
Because that looks a lot simpler.. and your synth sounds (and looks) already incredibly close to the real thing!

If this works, then why not stick with it? Or is there something inherently wrong with the code above?

Post

antto wrote:i can't get the RC output to match my curve (you know which one)
i know which one ....mmm...well, not exactly. i remember you describing some procedure of extracting data-points graphically from a spectrogram with some image viewing program...but that's about all i know. could you post the data? and maybe the concrete sample from which the data was drawn?

i'll do with mine, too...
My website: rs-met.com, My presences on: YouTube, GitHub, Facebook

Post

yeah, the curve that you commented is exactly what i use since then
and it is an approximitation of the curve i mesured out from a sample from rv0 (actually, it matches perfectly all other samples i got at any decay time!)

damn, i don't remember which sample i was analyzing (tho, it doesn't matter, as long as the cutoff, envmod, and decay are not changed during the note
if i change to RC Envelopes, i won't be able to use that approximitation, but i'll have to compare the RC envelope with this curve (because it is Teh Curve..)

EDIT: well, i was comparing the RC thing with my approximitation of the curve
that's what i meant

i can give you the datapoints i measured, and used to make the approximitation (tho, that's the best one i selected out of CurveExpert, and it is close enough that i don't really find any difference when i do 1:1 comparisons)
It doesn't matter how it sounds..
..as long as it has BASS and it's LOUD!

irc.libera.chat >>> #kvr

Post

antto wrote:yeah, the curve that you commented is exactly what i use since then
and it is an approximitation of the curve i mesured out from a sample from rv0 (actually, it matches perfectly all other samples i got at any decay time!)
Looks good. So do you use the same curve for the amp decay? Or just for the filter env decay?

I quickly tried this curve by fitting it in one of my old synth's code, and it sounds about right for the shortest decay time, but the long one (4 seconds!) sounds really looooong to my ears.. so I must have implemented something wrong I guess because in your synth it sounds really accurate.
(because it is Teh Curve..)
:D

Post

Robin from www.rs-met.com wrote:thanks for that clarification. unfortunately, i don't have enough EE background to read such things from circuit diagrams. is this also the case for the amplitude envelope?
there's a simplified schematic in service notes that shows this. the antilog amp is there mainly for cutoff and the envelope also goes thru it. seems not to be the case with amp env, but could be implemented in VCA block.

Post

brambos: nah, just for the Filter Envelope..

i think the VCA envelope is just a normal RC (in other words - exponential decay) with the same old time (that you can't change, and it doesn't change)
it's something like ~5 seconds
It doesn't matter how it sounds..
..as long as it has BASS and it's LOUD!

irc.libera.chat >>> #kvr

Post

antto wrote:i can give you the datapoints i measured, and used to make the approximitation
that would be interesting indeed - since, if you cant fit it with the exp-of-exp, then it probably differs from my data

i used the following sample:

http://www.box.net/shared/z37u29dhim

which was extracted from the file, you posted somewhere (i think originally from rv0). and this is the octave script to process the sample (extracts the data and fits the curve):

Code: Select all

clear all;

[x fs] = wavread('Samples/ResoSweep.wav');

% obtain the data-set from the sample:
x          = filter([1 -1], 1, x);
fftSize    = 512;
hopSize    = fftSize/4;
N          = length(x);
numFrames  = floor(N/hopSize)-3;
frameStart = 1;
window     = hanningWindow(fftSize);
freqs      = zeros(numFrames, 1);
for i=1:numFrames
 frame               = window.*x(frameStart:frameStart+fftSize-1);
 spectrum            = fft(frame);
 spectrum            = abs(spectrum(1:fftSize/2));
 [maxValue maxIndex] = max(spectrum);
 freqs(i)            = maxIndex;
 frameStart          = frameStart+hopSize;
end
times = (0:numFrames-1)*hopSize/fs;
freqs = binIndexToFrequency(freqs, fftSize, fs);

% generate the curve:
c = 0.9937;
a = 5.4;
o = 1/2.60;
y = 1;
f = 3000; % nominal cutoff frequency
numFrames = length(times);
env = zeros(numFrames,1);
for n=1:numFrames
 env(n) = y;
 y      = c*y; 
end
env = 2.^((env-o)*a);
env = f*env;

% plot data and generated curve:
plot(times, freqs, times, env);
grid on;
My website: rs-met.com, My presences on: YouTube, GitHub, Facebook

Post

i haven't read all the posts in between. so here goes the whole envelope generation.

first the simple 1-pole LP for env:

env[n] = env[n-1] + g(T)*(tresh - env[n-1])

where tresh is the threshold where the filter needs to go (0 in this case, sustain in ADSR when decaing or also 0 when released).

g(T) = 1 - exp(1/(Fs*T))

where Fs is sampling rate and T is the time it takes to decay 63% from current level to treshold.

finally for current cutoff in tb303:

fc[n] = Fc*pow(2, (env[n] - 0.3846)*envAmt)

where Fc is the cutoff that the user sets and evnAmt is envelope amount.

Post

i'm thinking i should implement it in my synth also.

Post Reply

Return to “DSP and Plugin Development”