General > General Technical Chat

How correct is this video about the future of silicon

<< < (3/3)

T3sl4co1l:

--- Quote from: pcprogrammer on February 27, 2023, 10:30:16 am ---For sure. I used to be good at math taught in school, but have a hard time with understanding some of the more advanced equations now. Things like Pythagoras or trigonometry are still ok, but differential equations and such take digging very deep.

Would like to learn more about calculating coefficients for filters in DSP, but there are so many other things I also like to know or do too. Hard to choose and I often dose of half way through when reading stuff.

--- End quote ---

Well now that's an easier one, at least!  Well, depending on what aspect you're looking for, heh.

First you need the basics: IIR or FIR type.  For analysis, the Z-transform is analogous to the Fourier transform; despite Z being simply a time shift (z^-1 means taking the previous sample x[n-1] while evaluating an equation at sample n), it works out the same, and indeed there exists an isomorphism, mapping the unit circle (poles within = stable, poles without = unstable) to the Fourier half-plane (left poles = stable, right poles = unstable).  So you can perfectly transform a given continuous-time (RLC) filter to a discrete-time (sampled) filter, within restrictions of sample rate and all that of course.

Of IIR, there are a few methods to use, of which the most popular / easy / stable / general is probably the biquad.  Five coefficients which can be tuned for any 2nd-order filter -- bandpass/stop, LP/HP... uhh and maybe all-pass, not sure?  In short, a rational 2nd order i.e. two poles and two zeroes, so, take your pick.  Solutions are straightforward enough:
https://www.earlevel.com/main/2013/10/13/biquad-calculator-v2/
View source to see the expressions in the JS, should be easy enough to understand even if you don't know JS exactly.

The derivation of these formulas, in turn, will be along the same lines as traditional analytical filters: position the poles/zeroes for a given desired response, or approximations to a straight-line (passband within x dB, stopband beyond y dB, etc.) response.

And a single biquad stage is 2nd order, what to do with higher orders?  Same thing we do with op-amps of course: each stage is two poles and cascade them as needed for a desired higher-order overall response.  So the first has close-in poles, and the next are higher Q, and etc. until you have the total response for whatever, Butterworth or Cheb. or etc. type you wanted.

Repeated 2nd-order blocks are preferred over a single higher-order block, because of sensitivity: while it's possible to implement an IIR filter that way, accumulator bits / coefficient precision becomes much more critical.  Kind of like -- I suppose by analogy, consider the Sallen-Key filter, which is said to be more sensitive to component values/tolerances than others like the MFB topology; well, suppose you go further, using a nth order Sallen-Key (yes, higher order active filters, around a single op-amp, are possible!), which you can imagine will be that much more sensitive to component values still; and then consider that the poles are positioned within the unit circle rather than on the plane and a small numerical error can easily push them outside the circle (poles/zeroes of a polynomial expression are highly sensitive to the coefficient values, it's an "ill conditioned" problem in general), and that error can arise from both rounding of the coefficients and truncation in the accumulator.

I suppose if you just use for example floating point (at float or double precision as the case may be), a higher-order filter might be tolerable, and maybe you can save a few cycles on the computation by making it a little more compact, or using fewer memory ops or whatever.  For most purposes, with say 16-bit fixed point, or 32-bit (or below) floats (standard or non-), 2nd order is probably preferred.

As for FIR, they're quite trivial: the coefficients are the impulse response, done and done.  You're literally cranking the convolution of the input with the filter's response, for each and every sample of the output.  So, you want a Gaussian response?  Plot a Gaussian hump and away you go!  Want something sharper?  Add some ringing, using whatever exponential or sinc shaped waveforms you might like; or choose any of the various well-known window functions for their respective spectral properties; it's all very easy to do, perfectly stable, and the only downside is, if you need a low frequency cutoff, well, you're going to need to convolve a heck of a lot of samples...

So IIR tends to be better for low cutoffs, but depending on how much CPU power / memory bandwidth you have available, either is often suitable.

So, hardest part, is as hard as any other filter -- polynomial solutions, of arbitrary order, approximating some frequency response.  Easiest part is, I'd say easier than analog filters, it's literally just the mechanical process of adding samples multiplied by coefficients (MAC operation).  In a FIR, no coefficients interact with each other, it's unconditionally stable; in IIR, it's equivalent to an active (analog) filter.

And sometimes (often, even?!) we don't even bother with that, because the shitty frequency response of a "boxcar" filter (rect[n] window, sliding average) is a suitable sacrifice for its simplicity: just toss each sample into a circular buffer, add the latest (nth) sample to the accumulator and subtract the last (n-Nth) sample -- the one that just fell out of the buffer.  Absolutely zero multiplication required (well, aside from normalizing the output gain), and all it needs is memory -- of which only two accesses are needed per sample.  Which is a kind of example (I think?) of a CIC ("cascaded integrator comb") filter, notice the summation per sample (the output/accumulator value) is taking the previous value plus the difference between nth and n-Nth samples -- it's the integral of a derivative.  Which does mean the value could become offset accidentally (integral of a derivative equals the function "plus a constant", which is to say, the DC offset is undefined in general), but in a deterministic computer, that "accident" by definition will never happen and the "plus a constant" equals the initialized offset (which in turn makes it a definite integral starting from zero, "plus a constant" accounted for).

As for diff eq, I'm not too into it, but I never really needed more than linear equations anyway (with, again, polynomial solutions -- filters, control loops, etc.).  And anything worse I'd gladly just plug into a numerical (or CAS) solver; particular, analytical solutions are likely to be more curiosity than practical (e.g. Bessel functions that aren't any easier to manipulate).

There is one interesting problem I've played with: the temperature distribution on a flat sheet, for a circular isothermal heat source.  Assuming convection proportional to temp rise, we have heat loss at any given point on the sheet depending on its temperature, while also spreading out (through the sheet) to a larger radius, where there's more (differential) area to dissipate heat into, etc.  Obviously the sheet won't be uniformly heated -- at a basic guess, it should be reciprocal or logarithmic with distance, because of the available area at a given radius -- but because the loss depends on temp as well, it must be something just different from that.  Okay well, set up the equations, push things around a bit and, fair enough, there's an equation I can't solve.  Let me see what Wolfram Alpha thinks of it. ;D  Turns out it's a Bessel function, with the first zero I think at the edge of the sheet (for some circular outer edge; which we can take to infinity if we like).  I forget the exact proportions that go into and around the function, but yeah, it's hottest in the center, dropping as radius goes up, and not quite as 1/r or ln(r/r_0) or anything, it's a little bit different.  So that was a cool problem.

Suppose I should go set that up again and see what the exact ratios were...

I recall plugging in the heat spreading rate of PCB stock (approximately anyway; it's mostly due to the copper anyway, so take the total thickness across however many layers you've poured/planed) and getting about an inch or two radius -- which is just as we expect for the hot spot on a 2oz 2-layer PCB, and for say a D(2)PAK or so, the total power dissipation (for reasonable max temp rise) is around... 5W or so, I think it was?  So, even as poor an estimate as proportional convection loss is (it's actually steeper than proportional, and depends on orientation, and bits above the hot-part have a lower coefficient than below because, well, the rising air is already warmed!...etc...), it's not too bad overall.

Other examples I've applied diff. eq. to, include uniform heat dissipation along a heat spreader sunk at one end (temp goes quadratically with distance, vertex at the uncooled end -- makes sense), or the hold-up time of an SMPS (also a quadratic).  Quadratics and exponentials are nice as you need no tricks to solve them (or just one simple trick for exponentials), just integrate and go.

Or the uh... what are some other recent workings-out, *thumbs through notes*, oh yeah:
- A couple, just, simple proofs reminding of certain integral solutions (half charge/energy point of an exponential decay; RMS of a wave)
- Simplifying complex arithmetic (for JS implementation)
- Transfer functions for certain RLC networks
- Or uh, going back a couple years, I derived a "tuning" equation for the series-resonant induction heater circuit.  Despite being 3 elements in a 2nd-order system, this involves a 4th order polynomial solution (basically because the solution isn't precisely symmetrical for ±ω i.e. can be reduced in terms of ω^2 --> ω, which is to say, of the form a ω^4 + b ω^2 + c = 0), but the solution is very close to the nearest quadratic* so a numerical solution converges rapidly.

*Hm, I wonder in what sense polynomials can be projected into each other; in the sense of projective spaces, mapping a higher-dimension space to a lower one.  I suppose you have your choice of projections though, both in the linear algebraic sense (take whatever [linear] map you like), and any kind of polynomial (or even more complicated) function you might apply.  (Compare 3D perspective projection, where P:[x, y, z] --> [x/z, y/z], a rational relation.)

Well, I digress...

Tim

pcprogrammer:

--- Quote from: T3sl4co1l on February 27, 2023, 06:00:54 pm ---Well now that's an easier one, at least!  Well, depending on what aspect you're looking for, heh.

--- End quote ---

Might be for you, but for me most of it is in the dark.  :o

I have played with simple IIR filters and can do calculations on them but they not always bring what I want. I'm talking audio synthesizer stuff here. With some trickery it is even possible to have them oscillate just like filters used in actual analog synths. Calculations can be similar to simple analog RC filters for what I understand from it.

It is the I think FIR filters where you have a set of coefficients for the multiply add on the different delayed samples that puzzle me. But based on what you wrote the biquad is IIR, so now I'm confused.

Have to reread the book on DSP I have. That is the problem for me with a lot of this stuff, it does not stick at the first read anymore. Here too, taking it into practice and repeat it over and over is key.

I do grasp the principles a bit, but the calculations for the coefficients for a specific -3db point elude me. I will take a look at the website and the code you linked. JS is at least something I know well.

This filter stuff was what I was playing with before I started to reverse engineer the FNIRSI 1013D scope. I bought that scope to have a smaller device on my desk to look at the signals coming from my Siel Opera 6 emulation module I made. Yet another project that is lying around waiting for the software to be finished  :palm:

It is based on six STM32F103 and one STM32F303 modules. One of the F103's is the master module that controls the other six modules. Each of these is to generate a single voice based on the architecture of the Siel Opera 6. The F303 module is used for the DAC in it. It outputs the mix of the 6 voices. It still needs a lot of work.

Cheers,
Peter


T3sl4co1l:

--- Quote from: pcprogrammer on February 27, 2023, 07:23:08 pm ---I have played with simple IIR filters and can do calculations on them but they not always bring what I want. I'm talking audio synthesizer stuff here. With some trickery it is even possible to have them oscillate just like filters used in actual analog synths. Calculations can be similar to simple analog RC filters for what I understand from it.
--- End quote ---

Ah, neat.  And yep, of course you'll get more accurate tones with a DDS (and total freedom of waveform at that!), but there might be reasons to still want a coarsely tunable feedback sort of thing.



--- Quote ---It is the I think FIR filters where you have a set of coefficients for the multiply add on the different delayed samples that puzzle me. But based on what you wrote the biquad is IIR, so now I'm confused.
--- End quote ---

Yes, exactly.  Biquad is a feedback (IIR) type.  Or at least... the kind that's what I'm thinking of.  Here's the implementation I used last time I played around,
https://github.com/T3sl4co1l/Reverb/blob/master/dsp.c#L292
well... not the clearest thing, it's got some optimization cluttering things up there.

In general, a DSP filter is the convolution of instant and previous input and output samples:
$$ y[n] = x[n] a_0 + x[n-1] a_1 + ... + y[n-1] b_1 + y[n-2] b_2 + ... $$

\$x[n]\$ is the latest input sample, \$y[n]\$ is the new output sample, and \$[n-1]\$ etc. are past samples of input or output.  The coefficients a and b have finite span of course (above some n, their values are zero).

FIR simply has all \$b_n = 0\$.  IIR has any combination, but usually restricted to \$a_0\$, \$a_1\$, \$a_2\$, \$b_1\$ and \$b_2\$ as in the biquad case.

Also I might be using the symbols backwards here, but anyway it's just multiply-accumulate, a convolution over previous input samples, and optionally outputs.

The... I forget if the biquad precisely uses coefficients in this form or what; in any case the code above works on a ~trivial transformation of the values from the calculator linked earlier.  Which, let me see here; I wrote a bookmarklet (remember those?) to do that.  You load up the calculator and set up the values as needed, then run this:


--- Code: ---(function() {
    var count = 0, ret = ["", ""], n;
    document.getElementById('biquad_coefsList').innerHTML.split(" ").forEach(function(x) {
        n = Math.round(16384 * Number.parseFloat(x));
        if (n) {
            if (count >= 3) {
                n = -n;
            }
            ret[0] += ", " + n;
            ret[1] += " " + ("0000" + (n + 0x10000).toString(16)).slice(-4);
            count++;
        }
    } );
    ret = "a0, a1, a2, b1, b2:\n" +"Dec: " + ret[0].slice(2) + '\n' +"Hex: " + ret[1].slice(1);
    console.log(ret);
    alert(ret);
} )();

--- End code ---

Oh yeah, the later coefficients are negated, just to keep the flow straightforward -- the data are arranged in memory for one fell swoop of MAC-ing, which leads to some shuffling around of them.  Whether that's actually optimal on AVR or other, whatever; it works well enough though.

...Which, is indeed as commented.  That T3sl4co1l guy seems like he was on top of things after all!...

The 16384 constant of course gives 14 bits fractional, 1 bit integer, and 1 bit sign.  This limits some values I think?  But for most values it seems alright.



--- Quote ---Have to reread the book on DSP I have. That is the problem for me with a lot of this stuff, it does not stick at the first read anymore. Here too, taking it into practice and repeat it over and over is key.

I do grasp the principles a bit, but the calculations for the coefficients for a specific -3db point elude me. I will take a look at the website and the code you linked. JS is at least something I know well.
--- End quote ---

When the change per sample is small, you can approximate it just as you'd solve an RC circuit, taking the differential equation form and changing \$d\$'s to \$\Delta\$'s.  Think that was where I derived the DC offset filter (dspHighpass()).  You need reasonable precision of course, otherwise it just locks up in place (hence the 32-bit accumulator there).

As cutoff gets closer to Fs/2, everything warps, and you start needing more... uh, tans or tanhs or something I think? I already forget much of the formulas myself.  Which, if you've never done it, deriving those a few times might be a good exercise I suppose?  I should maybe do that again myself, but at least for the time being, I'm happy enough having a general sense about it -- basic order-of-magnitude confidence checking and that -- and just run a calculator to get the exact values when needed.

As for the nature of those formulas, the derivations -- like I said, at the heart is a transform, and you're basically solving polynomials in that transformed space as an auxiliary equation to the differential difference equation, and the poles/zeroes drop out along the way which happen to tell you something about the frequency response.  Worse comes to worse, you can do a 0-order hold and Fourier transform the signals -- but working in Z domain straightaway is easier of course.

And yeah, DSP filters kinda suck, in general.  Especially as you approach Fs/2.  That's more or less your price of doing everything step by step -- having to do a lot of steps to accomplish the same thing.  The asymptotic response is still the order of the filter (or less), but the sharpness is different, and you tend to need more stages for a given response.  So maybe you just needed to lean into things a bit deeper.

It's all kinda trivial when you can toss more CPU power at it -- maybe it's less fun this way, but you could always consider tossing it on an rPi or whatever and run everything, well you could run parallel processes even if you wanted, but just chucking everything into a sample loop one after the next and chaining them all together will easily be done on a platform like that.  Networking STM32s sounds perhaps a little nightmarish in contrast...(says the guy who made a DSP effect on a poor unsuspecting XMEGA, though :-DD ).

Also, you should at least be able to do a couple voices, or a lot of filtering and whatnot effects, on the '303, no? *shrug*

Anyway, I'm sure there are reasons (even if it's just "having fun" ... or having "fun" as the case sometimes may be). :)

Tim

pcprogrammer:

--- Quote from: T3sl4co1l on February 27, 2023, 10:26:44 pm ---Yes, exactly.  Biquad is a feedback (IIR) type.  Or at least... the kind that's what I'm thinking of. 

--- End quote ---

After looking at the website with the calculator and following a link on it to info about the biquad, I came to that realization. The diagrams show feedback, which is the cause of the "infinite" behavior. That still stucked from reading the DSP book  :)


--- Quote from: T3sl4co1l on February 27, 2023, 10:26:44 pm ---As cutoff gets closer to Fs/2, everything warps, and you start needing more...

--- End quote ---

This I experienced in several tests I did with the simple IIR filters. Best to stay well below it.


--- Quote from: T3sl4co1l on February 27, 2023, 10:26:44 pm ---Networking STM32s sounds perhaps a little nightmarish in contrast...

Also, you should at least be able to do a couple voices, or a lot of filtering and whatnot effects, on the '303, no? *shrug*

Anyway, I'm sure there are reasons (even if it's just "having fun" ... or having "fun" as the case sometimes may be). :)

--- End quote ---

That was indeed part of the challenge, to device some system to have a lot of data passing through the modules. I'm using SPI for the signals and UART for the parameters. This in combination with DMA takes no processor time and works well. The master module generates common LFO signals and sends these to every module via one of the SPI links. The voice modules inject their voice output into the buffer that is repeatedly send to the F303 module.

And sure multiple voices could probably be done on the F303. An AVR can do multiple voices of simple synthesis, but the "fun" is in the whole setup being a replica of the original.

I wrote an emulator for it in 2014 under windows XP with functioning synthesis and it would be easy to make something on a raspberry pi, but I wanted to do something with the bunch of bluepills I bought.  :-DD

Peter

Navigation

[0] Message Index

[*] Previous page

There was an error while thanking
Thanking...
Go to full version
Powered by SMFPacks Advanced Attachments Uploader Mod