| |
Hermit
Registered: May 2008 Posts: 208 |
Software filter ('capacitor')
I want to share my 'invention' what I worked out 1..2 years ago. Don't know if there were examples for it on c64 or not.
While I was writing my hmtsynth (which you can find on d64 of my 3SID tracker or http://hermitsoft.uw.hu/c64prog/hmtsynth.prg ), I was developing a Potmeter control into it (through paddle pins in Joy port).
The potmeter ohmic 'signal' goes to the SID on the mainboard, and the SID measures it with its ADC (Analog to Digital Converter) which takes the help of a capacitor for the AD-conversion.
And the big problem was the strongly noticeable jitter in the value read from $D419 potmeter register, especially at higher impedance values of potmeters (up to 470kohm..)
That caused hearable frequent jumps in SID Pulsewidth & filter settings which were adjusted by & recorded from potmeter.
To solve this we can't use external filter on the potmeter as it will be the part of the ADC circuit which already uses a capacitor.. The jitter in $d419 seemed to come from the SID itself, so not any hardware solution could solve it..
So I decided to filt down the jitter by software, and build an algorythm to imitate the behavior of a capacitor (used as low-pass filter).
On my picture you can see the principle: First we store the $d419 input value to a memory byte, this byte will be the output of the filter. In every frame we read the $d419 input, and calculate the difference to the stored (output) value. Our capacitor should follow jumps slow, therefore we divide the calculated difference (delta) by a number (which so represents the value of the capacitor). In Hmtsynth, I divide the difference by 4.
Now we add the divided difference to the actual output byte
, and we are ready for waiting next frame, where all the process is repeated again (except init). In hmtsynth you can see the white bar moving a bit slower than adjusting the potmeter, but this way we eliminate the jitter in 1byte value-range of the $d418 register..
The White line on diagram is the jittering input, the purple is the 2x filtered output, the blue used 4x filtering (divided the delta by 4) and highly decreased the jitter but kept the average (low frequency) value..
I hope you can use the method in your software, whenever you need to reduce the undesired higher frequency component of a signal..
Have a nice experiment
Hermit Software Hungary |
|
| |
Adam
Registered: Jul 2009 Posts: 323 |
That is a really good invention! Is it possible to hook up a system to control muliple effects where one pot could control a filter while the other controls the resonance or ect, using the aX and aY input of JOY0 (pin 5 + 9?) |
| |
enthusi
Registered: May 2004 Posts: 677 |
err...
this how some mouse drivers work for some time now (?)... |
| |
linde
Registered: Jul 2006 Posts: 47 |
In applications where I've wanted to get rid of jitter from potentiometers and accelerometers I usually just stored the x latest read values in a buffer (x depending on amount of jitter and need for immediate response) and calculated the mean of them. That usually gets rid of all the noise, and is not unthinkable on a C64 with x=16 or x=32.
I haven't tried your method though. It seems faster and maybe even more responsive. I wish people would start cracking paddle games to include a filter like this! |
| |
j0x
Registered: Mar 2004 Posts: 215 |
Hermit's idea has some undesirable properties, given that it has "infinite memory". Because of the limited resolution, this may not be a problem, however, and it is brilliantly simple and intuitive.
Using a circular buffer, Lindes idea can be made almost free for any (reasonable) buffer length. Just keep a sum of all the values in your buffer, and for each step you just need to:
subtract the oldest element from the sum
add the newest element to the sum
get the output value by dividing the sum by the buffer length
If your buffer length is a power of two, the division isn't expensive.
The phase delay of such an unweighted averaging filter may be undesirable, but adding a single multiplication could turn it into an exponentially weighted filter, reducing the phase delay. This may introduce precision issues if you're not careful, though...
|
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
btw "ohmic signal" -> resistance :)
and what enthusi said. for more info google for software low pass filters =P |
| |
yonx Account closed
Registered: Dec 2003 Posts: 31 |
I think "Hermits algorithm" is pretty much standard for doing stuff like this, atleast I use it all the time for smoothing out controller-values when VJ:ing and for doing easing and stuff like that in animations :)
j0x: i don't see what undesirable features the algorithm would have, could you please develop that a bit?
i havent tried lindes method but i have a strong feeling that it's less responsive and also requires more polling of input-data / second to be accurate.. |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
"lindes method" is pretty much exactly the same thing, except with a different cutoff frequency :) (and more latency, which is related to that) |
| |
j0x
Registered: Mar 2004 Posts: 215 |
yonx: The infinite memory of the method would mean that it would never forget an extreme value. A contrived example: Say your input values are typically between -1 and 1. Then, due to a measurement error, you get a value of eleven squillion. This peak will influence the filter output forever, whereas if you have a finite window (as in Linde's example), the peak will stop having any influence once it passes out of the window.
|
| |
yonx Account closed
Registered: Dec 2003 Posts: 31 |
j0x: okay, now i get what you're pointing at :) as you already stated this shouldn't be a problem if the input is limited to a sane range before smoothed out..
groepaz: they might be similar filterwise, but considering the very low samplerate (1 sample / frame, max?) i still believe that Lindes buffer will introduce noticable latency to the user (atleast when the buffersize>16).. |