pouët.net

Go to bottom

303 if you please

category: general [glöplog]
Here's a tb-303 emulator:

Basically you call tb303_lump periodically and it fills a float buffer with 44100hz samples. You also call tb303_event when you want to modify parameters. So that I may improve upon this I'm wondering if anyone knows how the accent control works with the 303? What does this knob do?


tb303.c
Code: #include <stdio.h> #include <stdlib.h> #include <math.h> #include "tb303.h" void init_tb303(tb303_t *s) { s->vco_inc = 0.0f; s->vco_k = 0.0f; s->vcf_cutoff = s->vcf_envmod = s->vcf_reso = s->vcf_envdecay = s->vcf_a = s->vcf_b = s->vcf_d1 = s->vcf_d2 = s->vcf_c0 = s->vcf_e0 = s->vcf_e1 = s->vcf_a = 0.0f; s->vca_mode = 2; s->vca_attack = 1.0f - 0.94406088f; s->vca_decay = 0.99897516; s->vca_a0 = 0.5f; } void tb303_event(tb303_t *s, tb303_event_t *e) { int dirty = 0; float d; if( (e->mask & CUT) == CUT) { s->vcf_cutoff = e->cut; dirty = 1; } if( (e->mask & RES) == RES) { s->vcf_reso = e->res; s->vcf_rescoeff = exp(-1.20 + 3.455*s->vcf_reso); dirty = 1; } if( (e->mask & ENV) == ENV) { s->vcf_envmod = e->env; dirty = 1; } if( (e->mask & DEC) == DEC) { d = e->dec; d = 0.2 + (2.3*d); d*=44100; s->vcf_envdecay = pow(0.1, 1.0/d * ENVINC); } if(dirty == 1) { s->vcf_e1 = exp(6.109 + 1.5876* s->vcf_envmod + 2.1553*s->vcf_cutoff - 1.2*(1.0-s->vcf_reso)); s->vcf_e0 = exp(5.613 - 0.8*s->vcf_envmod + 2.1553*s->vcf_cutoff - 0.7696*(1.0-s->vcf_reso)); s->vcf_e0*=M_PI/44100.0f; s->vcf_e1*=M_PI/44100.0f; s->vcf_e1 -= s->vcf_e0; s->vcf_envpos = ENVINC; } if( (e->mask & NOTE) == NOTE) { s->vco_inc = (440.0/44100.0)*pow(2, (e->note-57)*(1.0/12.0)); s->vca_mode = 0; s->vcf_c0 = s->vcf_e1; s->vcf_envpos = ENVINC; } else s->vca_mode = 1; } void tb303_lump(float *buf, int len, tb303_t *s) { int i; float w,k; for(i=0;i<len;i++) { if(s->vcf_envpos >= ENVINC) { w = s->vcf_e0 + s->vcf_c0; k = exp(-w/s->vcf_rescoeff); s->vcf_c0 *= s->vcf_envdecay; s->vcf_a = 2.0*cos(2.0*w) * k; s->vcf_b = -k*k; s->vcf_c = 1.0 - s->vcf_a - s->vcf_b; s->vcf_envpos = 0; } buf[i]=s->vcf_a*s->vcf_d1 + s->vcf_b*s->vcf_d2 + s->vcf_c*s->vco_k*s->vca_a; s->vcf_d2=s->vcf_d1; s->vcf_envpos++; s->vcf_d1=buf[i]; s->vco_k += s->vco_inc; if(s->vco_k > 0.5) s->vco_k -= 1.0; if(i==len/2) s->vca_mode = 2; if(!s->vca_mode) s->vca_a+=(s->vca_a0-s->vca_a)*s->vca_attack; else if(s->vca_mode == 1) { s->vca_a *= s->vca_decay; if(s->vca_a < (1/65536.0)) { s->vca_a = 0; s->vca_mode = 2; } } } }



tb303.h

Code: #define ENVINC 64 typedef struct { float vco_inc, vco_k; float vcf_cutoff, vcf_envmod, vcf_envdecay, vcf_reso, vcf_rescoeff; float vcf_e0, vcf_e1; float vcf_c0; float vcf_d1, vcf_d2; float vcf_a, vcf_b, vcf_c; int vcf_envpos; float vca_attack, vca_decay, vca_a0, vca_a; int vca_mode; } tb303_t; #define NOTE (1) #define A (1<<1) #define S (1<<2) #define CUT (1<<3) #define RES (1<<4) #define ENV (1<<5) #define DEC (1<<6) #define ACC (1<<7) typedef struct { int note, a, s; float cut, res, env, dec, acc; int mask; } tb303_event_t; void init_tb303(tb303_t *s); void tb303_lump(float *buf, int len, tb303_t *s); void tb303_event(tb303_t *s, tb303_event_t *e);
added on the 2009-12-28 04:34:20 by sigflup sigflup
At each note you can define the ACCENT value to ON/OFF - consider it as a bool value. When the 303 finds a note with ACCENT ON, it amplifies that note with the value set with the accent knob. There you can have those typical loud-and-wobbly acid sounds.
added on the 2009-12-28 04:53:20 by -SP- -SP-
Ahh.... I see, thanks! I've also heard rumors that it ramps up the decay of a note as well, do you know if that's true?
added on the 2009-12-28 05:02:19 by sigflup sigflup
Good question... It sounds like it has a longer decay, but that's just cause of the amplification I think. Since there is a dedicated decay knob, I'd find it useless to tamper with it from the accent.
added on the 2009-12-28 07:10:28 by -SP- -SP-
I've always wondered what the accent knob was. And 44.1Khz is so oldschool. 192KHz or die.
added on the 2009-12-28 07:28:23 by xernobyl xernobyl
if you dont have a real 303 at home download Rebirth from Propellerheads as it give a decent emulation of how a real 303 sounds
added on the 2009-12-28 12:57:07 by Tigrou Tigrou
well, rebirth is ok, but nowhere near the real thing. :D
ABL2 is much closer to the real thing than Rebirth ever was (Rebirth 1.5's distortion was kind of OK though for distorted 303 sounds..).
added on the 2009-12-28 14:03:27 by booster booster
On the original, with high volume accent notes the ladder-filter goes into deep saturation (tanh-style). That gives a Together with the distortion this gives a compression effect, so the decay sounds longer...
added on the 2009-12-28 14:23:56 by torus torus
ABL2 is great for when using it in your daw, but i can use MY REAL 303 FUCK YEAH!
soo.. people are complaining that software simulators fail to perfectly simulate hardware which completely failed to simulate the hardware it was designed to simulate?
added on the 2009-12-28 15:04:17 by sol_hsa sol_hsa
sol_hsa: yeah but it's like when you invent a new cough sirup and accidentally make coca cola, en then people start to complain that pepsy isn't coca.
xernobyl: I don't think I can hear anything (clearly) above 16KHz, maybe 18KHz, and I'm a healthy 22 year old. It is only going to get worse as I get older. I don't think I can tell the difference between triangle and sine at 16KHz. The rumored peak frequency anyone can hear is ~22KHz. The typical highest frequency produced by AC97 style hardware in a typical computer is 24KHz (sampling at 48KHz).

Nyquist–Shannon: Obey
added on the 2009-12-28 20:11:34 by QUINTIX QUINTIX
QUINTIX: i think you misunderstood the nyquist frequency.
if you have 44kHz sampling freq, the highest freq you can produce is 22kHz, but that's allways a square wave, anything else results in distortion.
and even worse, if you want to make a waveform close to the nyquist freq (e.g. 21kHz) it gets distorted.
so to get those right you need an even higher sampling rate.
and if your hearing is perfect (like mine, for now at least) you will notice the difference.

ofcource when we're talking about output this is really just audiofilic. you'll notice the difference, but none of the two sounds better or something like that. but when you need to process it later, a higher sampling rate is allways better.
Quote:
yeah but it's like when you invent a new cough sirup and accidentally make coca cola, en then people start to complain that pepsy isn't coca.

that might very well be the best analogy of this year :)
added on the 2009-12-28 20:45:58 by Gargaj Gargaj
whynot2000: you probably misunderstand nyquist, too :)

your onboard 48khz soundcard can produce a pretty nice 23.5khz sine wave if you feed it with the right input. Similarly, it can produce sums of sine waves. But music changes in time, and the higher sampling rate will be useful were it comes to transients. Also, higher sampling rate for the simulation / sound processing can be useful even if the result is downsampled to, say 44khz.
added on the 2009-12-28 22:05:57 by blala blala
your statement does not defy my statement. it's an addittion at most.
let's talk 48kHz sampling rate here.
if you want a sinewave of 23.5kHz you just can't do that, you'll get a 24kHz squarewave with subharmonics (and the usual harmonics a sqrwave has). and those harmonics will change periodicaly with 0.5kHz.
same goes for when you'd have a 24kHz sinewave, if that wave is 25% or 75% out of phase with the output, you should have a flat line, just do the math.
the latter might not be so true in reality, cause i assumed the outputrate is exactly and constant 48kHz
that is not how dsp works
added on the 2009-12-28 22:30:22 by _-_-__ _-_-__
in that, a 23.5khz sine wave is perfectly represented at the 48khz sampling rate, and will be reconstructed as a sinewave by a DAC.
added on the 2009-12-28 22:31:28 by _-_-__ _-_-__
no, you won't get a square wave. you will get something which is almost a sine wave, with slightly oscillating amplitude.

exactly 24khz does not play. of course closer you go to 24khz, more problems you will have, but i think 23khz is pretty ok. Anyway, the way the sound cards work, there is a lowpass filter at 24khz, and since it's analogue, of course it's not a brickwall filter, so exactly 24khz is pretty much meaningless both physically and mathematically.

let me tell you how the nyquist theorem works: If you have a sum (i think integral is ok, too) of sine waves, the frequency of each is strictly smaller than the nyquist frequency, and you sample it with the given sample rate but with infinite precision, and for an infinitely long period, then you can reconstruct the original wave *exactly*. The problem with this is of course that 1) you don't have infinite time; 2) music changes in time; 3) the precision isn't infinite either, but 16/24 bits.

If you don't believe me, just sample a 23khz sine wave at 48khz (or 21khz and 44khz, depending on your soundcard), and connect the output to an oscilloscope. Then be in awe, and read the mathematics :)
added on the 2009-12-28 22:37:30 by blala blala
i can't understand that, or you are wrong
let's simplify it.
let's say we have a 20hz sampling rate, so nyquist 10hz.
you can make a 10hz wave, but there is no way of telling what form it was, the output will allways be something like [5,-5,5,-5,...,-5]. that's a square wave. and you might build your hardware so that it comes out as a sinewave (so, interpolating the values) but then everything would be interpolated, an intende squarewave would become a sinewave.
and the other problem; try making a 9hz wave (whatever the form is) in this way. i think that's impossible.
sigflup: on a side-note, this might come in handy.
added on the 2009-12-28 22:58:53 by bdk bdk
whynot2000, a square wave at 10hz in your example does *not* exist. Because the upper harmonics of the square wave, or if you think in terms of fourier series, the sine waves above 10hz that form the square wave, cannot be represented in the 20hz sampling rate.

The signal [5,-5,5...] in your example can *only* be a sinewave, by construction. And for this reason, the interpolation/reconstruction performed by the DAC is by design supposed to recreate a sine wave.
added on the 2009-12-28 23:00:35 by _-_-__ _-_-__
sigflup > it would be nice to turn it into a portaudio sample!
short answer: Nyquist interpolation works very differently than you think.

Plot a 9hz sine wave sampled at 10hz (or whatever is your favourite frequency). What you see is something alternating, with an envelope which looks like a double sine, approx. 1hz freq (except i probably miscalculated this frequency). It seems strange to expect that this will somehow give back your original sine wave; but in fact, if you sample it for an infinite time, from the big bang to the end of the times, then the mathematics says that you can reconstruct it exactly. There is even a formula for the reconstruction, namely, the convolution with a sinc function (iirc). Now, the soundcard does not have an infinite sample, but we can approximate with a finite sample, too. Because the soundcard needs a balance between reconstruction accuracy and the dynamics (*), it will "remember" (via the lowpass filter) only the last few samples anyway; this will cause the slight oscillation of the amplitude of the reconstructed sine, which will be stronger as you go closer to the nyquist frequency.

(*) There is a uncertainty principle here, exactly the same as in quantum mechanics, between time resolution and frequency resolution.

You can read the details on the wikipedia:
http://en.wikipedia.org/wiki/Nyquist-Shannon_sampling_theorem
http://en.wikipedia.org/wiki/Whittaker–Shannon_interpolation_formula
added on the 2009-12-28 23:15:53 by blala blala

login

Go to top