Open303 - open source 303 emulation project - collaborators wanted

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

Post

I will re-post the only useful part of what I'd previously posted.

To calculate your glide, just use a plain lossy integrator:

Code: Select all

memory += (input - memory) * coefficient
The coefficient can be calculated using a time constant and percentage as follows:

Code: Select all

coefficient = 1.0 - pow(0.1, 1.0 / (seconds * sample_rate))
Rather than a percentage, you use the inverse of the fraction. So for 90%, we use 10/100 = 0.10.

So, say we want to reach within 90% in 1000 steps.

Code: Select all

coefficient = 1.0 - pow(1.0 - 90.0/100.0, 1.0 / 1000.0)
coefficient = 0.0022999361774466828055780571462377
Starting from 1.0 with input of 0.0 (an exponential decay), after 1000 steps we want to see what our state will be.

Code: Select all

state = pow(1.0 - coefficient, steps)
state = pow(1.0 - 0.0022999361774466828055780571462377, 1000.0)
state = 0.10
Free plug-ins for Windows, MacOS and Linux. Xhip Synthesizer v8.0 and Xhip Effects Bundle v6.7.
The coder's credo: We believe our work is neither clever nor difficult; it is done because we thought it would be easy.
Work less; get more done.

Post

antto wrote:i've actually done this recently, i hooked up one of my x0xes to send midi notes to xhip (some version i downloaded long ago) and matched the slide time accurately no idea if the glide parameter uses "90%" in the formula (you'll know) but the value that got there was 105ms
http://www.muffwiggler.com/forum/viewto ... 54#1568254
Xhip uses 99%. This is because I calculate the number of steps required to reach that far and accept that on the last step + 1 a jump of 1% occurs.

This is an optimization of course. The glide only needs to actually run and therefore the pitch be recomputed while changing. Once 99% has been reached the entire computation can be skipped.

Code: Select all

Using a 'virtual sample rate' of 1000hz, 
105ms at 99%:
coefficient = 1.0 - pow(1.0 - 99.0/100.0, 1.0 / (1000.0 * 0.105))
coefficient = 0.042910876322872116118630930394149

Now to calculate the number of steps required to reach 90% and compute the time in ms from that:
steps = log(1.0 - 90.0/100.0) / log(1.0 - coefficient)
steps = log(1.0 - 90.0/100.0) / log(1.0 - 0.042910876322872116118630930394149)
steps = 52.5
steps are already in ms as our "virtual rate" is 1000.
52.5ms.
You were off by about 2ms :)
Free plug-ins for Windows, MacOS and Linux. Xhip Synthesizer v8.0 and Xhip Effects Bundle v6.7.
The coder's credo: We believe our work is neither clever nor difficult; it is done because we thought it would be easy.
Work less; get more done.

Post

Regarding "access to RC to hz formula";

http://en.wikipedia.org/wiki/Rise_time# ... RC_network

It's a simple matter of rescaling the coefficient to get 0% to 90% rather than 10% to 90%.
Free plug-ins for Windows, MacOS and Linux. Xhip Synthesizer v8.0 and Xhip Effects Bundle v6.7.
The coder's credo: We believe our work is neither clever nor difficult; it is done because we thought it would be easy.
Work less; get more done.

Post

my brain hurts from the math formulas/symbols in wikipedia

good to know, but i still think "7.23Hz" is simpler, given that the slide time is fixed
i guess one could use the coefficient from the "7.23Hz" calculation to figure out the equivalent "tau" value for the formula you posted, i've thought of that, but just didn't do it (or i tried and failed)
surely i use the tau formula for the RC envelopes, just not for the slide LPF and also the C13 LPF (iirc) because in both cases, at least in my model, those two LPFs switch between fixed time constants, and it wasn't a problem to adjust them in Hz scale
plus, it works consistently under different sampling rates so - it was good enough for me
It doesn't matter how it sounds..
..as long as it has BASS and it's LOUD!

irc.libera.chat >>> #kvr

Post

andrea993 wrote:The GUI is developed in Qt (so it's multi-platform) and make a porting a Qt gui to VST is easy.
Not quite. It is a pain. Real hard pain.

Post

Hi; let me do a post on this long dormant thread to see if there's a way to reach Robin. I've started making Open303 into a VCVRack module after Andrew posted it on a list of "interesting open source dsp libraries". Have it working as a module on my mac in my dev area now. Also: the library sounds really good and built with almost no changes.

It's MIT licensed so I am assuming this is OK but I wanted to just see if there was a way to reach original author to ask if they have any concerns.

Thanks

Post

baconpaul wrote: Tue Jun 18, 2019 10:11 pm Hi; let me do a post on this long dormant thread to see if there's a way to reach Robin.
Click his signature block and go to his website; his contact info is shown on his Company page. (And if someone doesn't supply a link, you can always click their icon to go to their profile page, where you can either PM them or their might have supply a web link.)
My audio DSP blog: earlevel.com

Post

haaa! 10 years ago! i'm happy to see that there's still interest in this code. i didn't even remember which type of licensing i applied. so....it's mit...so sure - you may use it. i'd appreciate to get mentioned with a link to my website somewhere (like in the creative commons license) but there's no requirement for that. analyzing the behavior and trying to emulate it was really a crowdsourcing effort and the techniques, we used are probably not exactly "state-of-art". there's no circuit modeling or anything like that going on - but who cares, if it sounds good?. it was more like: take straightforward dsp algos and tweak them until they sound right. i still love the sound of the 303 and hope, my code can be a little contribution to its immortalization ...so, yeah - go ahead and do something cool with it! <3
My website: rs-met.com, My presences on: YouTube, GitHub, Facebook

Post

Awesome! Yes was going to credit you of course! I will add a link to your website in the credits and prominently in the documentation for the module also.

It really sounds great and built super easily. Here's my alpha in rack running if you want to see: https://www.youtube.com/watch?v=RT3RNOo ... e=youtu.be (Obviously I want to write a less terrible face plate before I release it into the plugin manager)

Post

nice! thank you and good luck with your project. i just checked out vcv rack - seems to be an interesting project with a lot potential indeed. maybe i'll contribute some modules myself in the future. we'll see....
My website: rs-met.com, My presences on: YouTube, GitHub, Facebook

Post

Here's a reference for the tb-303 oscillator. You'll need to download ltspice to run this netlist which can output the waveforms scaled/filtered to approximate reference levels that you can then match to any oscillator code.

I can't reach pastebin ATM (weird?) so here it is in an annoying code tag block:

Code: Select all

* tb-303 oscillator + exponential current source + pulse waveshaper

* 0v CV Hz = 440 * (2^(1/12))^(3 - 12*5) = 16.35 Hz
* fit two cycles + third edge = 2 * 1000 (ms) / 16.35 = 122.32 ms
.tran 0 123m 0 20u

* ideally this would be made to run with .step to render the output in various semitones or octaves.
* unfortunately i'm not aware of any function to generate parameterized filenames for the .wave function.
* you'll need to manually adjust the parameter and filenames for output (0v = pulse0, 1v = pulse1, 2v = pulse2, ...)
;.step param CV 0 5 1
.wave z:\pulse0.wav 16 48.0K V(o_p)
.wave z:\ramp0.wav 16 48.0K V(o_r)

V1 vp 0 DC 12
V2 vh 0 DC 5.333

* cv input
.param CV 0
* middle c = 440 * (2^(1/12))^3 = ~523.25113 Hz
* -4.7xxx trimmed for ~523 Hz at 5v CV input
V4 cvb 0 DC {-4.7062 + CV}

* exponential current source
* this is a cheap pnp-buffered single npn transistor which is totally inaccurate
* the real circuit uses stabilization via a matched NPN and an opamp for feedback
* as far as accuracy of the oscillator core however it should have no notable effect
R77 cvb ii 220k
R7 cv ii 220k
* scale adjustment (1v/octave)
R8 ii 0 4040
R9 vp ib 100k
Q6 0 ii ib 2N3906
Q7 ir ib 0 2N3904
R88 cp ir 4.7k

* scr
Q4 4  12 vp 2N3906
D1 4  5     1N4148
Q5 5  5  10 2N3904
Q3 12 5  cp 2N3904
R6 10 vh    10k

* capacitor
.ic V(cp) 5.1
C3 vp cp 10n

* buffer
* MPF104 is the wrong NJFET for the buffer,
* the FET Vto and other properties affect offset and clipping (top of ramp)
* which in turn affect pulsewidth for the pulse waveshaper
JQ1 vp cp bf MPF104
R1 bf 0 10k

* shaper input filter
R2 bf sh_in 100k
C1 bf 17 10n
R3 17 sh_in 10k

* pulse shaper
* R5 & R4 will adjust pulse width, C2 tone/"curve" for low notes
* you can find lots of discussion about trimming the width
* in various places online (for 303 based clones)
R5 vp psi 22k
C2 psi 0 1u
Q2 pl sh_in psi 2N3906
R4 vh pl 10k

* highpass and 1/5 scaling for the outputs
* ramp
R90 bf d_r 1000k
C90 d_r o_r 100n
R91 o_r 0 220k
* pulse
R80 pl d_p 1000k
C80 d_p o_p 100n
R81 o_p 0 220k

* models
.MODEL 1N4148 D (IS=14.2P RS=4.2 N=1.7 BV=75 IBV=5U CJO=1.74P VJ=0.75 M=0.333 TT=4.32N)
.MODEL 2N3904 NPN(IS=6.73E-15 BF=416.4 VAF=74.03 IKF=0.06678 ISE=6.73E-15 NE=1.259 BR=0.7374 RB=10 RC=1 CJE=4.5E-12 TF=3.012E-10 XTF=2 VTF=4 ITF=0.4 CJC=3.638E-12 MJC=0.3085 TR=2.395E-7 XTB=1.5 KF=9E-16 )
.MODEL 2N3906 PNP(IS=4E-14 BF=400 VAF=50 IKF=0.02 ISE=7E-15 NE=1.16 BR=7.5 RC=2.4 CJE=6.3E-12 VJE=0.75 TF=5E-10 CJC=5.8E-12 VJC=0.75 TR=2.3E-8 VJS=0.75 XTB=1.5 KF=6E-16 )
* the MPF104 model has been trimmed with Vto=-1.45 to get what "looks reasonable"
* A better JFET model would probably be the best solution here
.MODEL MPF104 NJF(Beta=488.9u Betatce=-.5 Rd=1 Rs=1 Lambda=3.83m Vto=-1.45 Vtotc=-2.5m Is=181.3f Isr=1.747p N=1 Nr=2 Xti=3 Alpha=2.543u Vk=152.2 Cgd=4p M=.3114 Pb=.5 Fc=.5 Cgs=4.627p Kf=4.284E-18 Af=1)
.END
To run the simulation with an input CV to simulate a pattern, you can use the following modification to the netlist:

Code: Select all

* adjust the simulation time to match the input pattern
.tran 0 7 0 20u

* cv input
* the input "VIN1" is generated from channel zero of the .wav file
VIN1 cvin 0 wavefile=z:/dont_mess_up_bassline.wav chan=0
* behavioral voltage source allows mathematical equations on voltage
B1 cvb 0 V=V(cvin)*(128/12) - 4.7062 - 1
;.param CV 0
* middle c = 440 * (2^(1/12))^3 = ~523.25113 Hz
* -4.7xxx trimmed for ~523 Hz at 5v CV input
;V4 cvb 0 DC {-4.7062 + CV}
Which produces this:
http://xhip.net/temp/dont_mess_up_bassline_pulse.mp3
( http://xhip.net/temp/dont_mess_up_bassline_pulse.flac )

Here's the input "notes" as a CV scaled to note/128, at a low sample rate (8000 Hz) to make it load quickly into ltspice. Make sure you don't use input waveforms that are dramatically oversampled as it'll take forever to convert them before the simulation can start running. Notes and envelopes could probably be at something like 1000 Hz and maintain 100% accuracy including glides and everything.

You'll need to convert from flac to 16-bit RIFF wav to get ltspice to load it (to my knowledge):
http://xhip.net/temp/dont_mess_up_bassline.flac
Free plug-ins for Windows, MacOS and Linux. Xhip Synthesizer v8.0 and Xhip Effects Bundle v6.7.
The coder's credo: We believe our work is neither clever nor difficult; it is done because we thought it would be easy.
Work less; get more done.

Post

thanks aciddose! i'll try this soon. i never did any circuit modeling before - this spice stuff is all new to me - but probably worth to learn
My website: rs-met.com, My presences on: YouTube, GitHub, Facebook

Post

I was going to look at building something maybe from the open303 source to generate the CV patterns including gate/envelope/glide/accent and so on but that's a bit much effort and more than I'm really interested in atm.

I had this spice netlist around though because the 303 oscillator is based upon a simple (although poor quality, in my opinion) SCR circuit which is the very best and lowest part-count oscillator that is possible. Since the 303's pulse waveshaper has its pulse width determined by input amplitude and offset, it should be possible to replace the nJFET buffer transistor with an opamp and then get full PWM control. So in that respect it's quite an interesting circuit from the perspective of modular synthesizers.

(Note: the generic SCR oscillator core supports sync in/out too! A full SCR is a four-pin device made from two transistors: NPN + PNP with the PN overlapped. So NPNP gives four pins total. The middle "PN" are the trigger pins, one positive, one negative.)

The 303 filter is a bit more difficult (mostly due to matched pairs) but it can also be adequately reproduced using generic transistors. The envelopes, accent, glide and other portions of the circuit are trivial. So yes, it's a bit of a headache to get past some of the hurdles of using a simulator like ltspice... but once you do you can model things with so much accuracy that you have a nearly perfect reference to use for something like the 303 pulse shaper or even given enough effort any part of any analog device.

It is all fairly complicated stuff though. Hurdles just like with anything... very similar to learning C++.

Anyone with experience in DSP should find analog electronics quite fun... you might even find yourself inhaling vast amounts of lead fumes at some point. Don't say I didn't warn you!
Free plug-ins for Windows, MacOS and Linux. Xhip Synthesizer v8.0 and Xhip Effects Bundle v6.7.
The coder's credo: We believe our work is neither clever nor difficult; it is done because we thought it would be easy.
Work less; get more done.

Post

The annoying thing about the 303 pulse-shaper is that it seems basically impossible to accurately reproduce using band-limited techniques, but then if you use circuit simulation you'll need a very small time-step (ie. high oversampling) to avoid crazy aliasing.

I would argue that it's by far the worst part of the whole thing if you want to build a good sounding plugin out of the thing.

Post

That's less true that it seems based upon intuition. The amplification is only about 20x and the non-linearity can be approximated reasonably well with a variety of methods. It's a bit difficult to create a real-time model to reproduce 100% perfect results during glides and so on... but I have doubts as to whether there are any significant audible effects there.

Ultimately the most important factor at play is the smooth vs. hard edge. The ramp reset edge is sharp but the other edge of the pulse is smooth and frequency dependent. The sh-09 for example uses a pulse shaper with 20x (680k/33k = 20.60606~) gain to achieve the same effect. Since the majority of the spectra is a single easy-to-produce "sharp" edge it means we don't need to worry so much about bandwidth for the other "soft" edge.

"Crazy aliasing" isn't going to happen in a realistic model as the highest oscillator frequencies are generally only around 1000 Hz anyway. Above that point we can just start running a generic oscillator where the difference becomes inaudible.
Free plug-ins for Windows, MacOS and Linux. Xhip Synthesizer v8.0 and Xhip Effects Bundle v6.7.
The coder's credo: We believe our work is neither clever nor difficult; it is done because we thought it would be easy.
Work less; get more done.

Post Reply

Return to “DSP and Plugin Development”