<div dir="ltr">How about using a CIC filter then?<div><br><div><a href="https://www.embedded.com/design/configurable-systems/4006446/Understanding-cascaded-integrator-comb-filters">https://www.embedded.com/design/configurable-systems/4006446/Understanding-cascaded-integrator-comb-filters</a><br></div><div><br></div><div>They are basically moving average filters with decimation built-in. They don't need multiplication at all, and I love how they work by design with modular arithmetic (wraparound is a feature, not a bug).</div></div><div><br></div><div>Here's a C++ implementation that works (optimized with templates):</div><div><div><br></div><div><<<<</div><div><div>constexpr int ipow(int a, int b) {</div><div>  return b==0 ? 1 : a * ipow(a, b-1);</div><div>}</div></div><div><br></div><div>// N number of stages, R decimation rate</div><div>// careful: gain must be <= 2^16</div><div>template<int N, int R></div><div>class CicDecimator {</div><div>  int32_t hi[N] = {0};</div><div>  int32_t hc[N] = {0};</div><div>  static constexpr int gain = ipow(R, N);</div><div>public:</div><div>  // reads [R*size] input samples, writes [size] output samples:</div><div>  void Process(int16_t *input, int16_t *output, size_t size) {</div><div>    while(size--) {</div><div>      // N integrators</div><div>      for (int i=0; i<R; i++) {</div><div>        hi[0] += *input++;</div><div>        for(int n=1; n<N; n++) {</div><div>          hi[n] += hi[n-1];</div><div>        }</div><div>      }</div><div>      // N combs</div><div>      int32_t v = hi[N-1];</div><div>      for (int n=0; n<N; n++) {</div><div>        int32_t in = v;</div><div>        v -= hc[n];</div><div>        hc[n] = in;</div><div>      }</div><div>      *output++ = static_cast<int16_t>(v / gain);</div><div>    }</div><div>  }</div><div>};</div></div><div>>>>></div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr">On Sun, May 27, 2018 at 12:20 AM Gordonjcp <<a href="mailto:gordonjcp@gjcp.net">gordonjcp@gjcp.net</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Thu, May 17, 2018 at 03:45:51PM +0100, <a href="mailto:rburnett@richieburnett.co.uk" target="_blank">rburnett@richieburnett.co.uk</a> wrote:<br>
> Is this just a thought exercise or is it required for a particular<br>
> application?<br>
> <br>
> This isn't how *I* personally would make a half-band filter.  They<br>
> are usually done with FIR filters if the ultimate aim of the game is<br>
> to drop the sample rate down (decimation.)<br>
> <br>
> FIR has a number of advantages here over IIR here:  It is inherently<br>
> stable (even with coefficient rounding on your low-end micro,) it<br>
> has linear phase response, and you don't need to calculate the<br>
> output samples that you will be throwing away later in the<br>
> decimating process.<br>
<br>
Right, but for FIR you'd need a multiplier and a whole bunch of<br>
registers for the taps, which I'm keen to avoid.<br>
<br>
-- <br>
Gordonjcp<br>
<br>
_______________________________________________<br>
Synth-diy mailing list<br>
<a href="mailto:Synth-diy@synth-diy.org" target="_blank">Synth-diy@synth-diy.org</a><br>
<a href="http://synth-diy.org/mailman/listinfo/synth-diy" rel="noreferrer" target="_blank">http://synth-diy.org/mailman/listinfo/synth-diy</a><br>
</blockquote></div>