@b3ll, I'll describe in some detail what I'm doing here, and I let you experiment what may work or not.
Considering the paper is not really clear at all times, I've taken a few guesses.
If the works reaches a point of apparent stability, I'll merge it.
For now, I've added 2 commits in the unit-delay branch.
- 971a7a8 for fixing the output filter
Filter couldn't operate according to the structure shown, because the unit delay variable was not kept, meaning either algorithm or structure has been incorrect.
Most probably algorithm, so I reformulated the filter with use of unit delays (as Xout_mem).

- e7f197e BBD's summed output, going to output filter
You have the processing made of 2 loops: (as denoted in the paper)
- the
k loop is the outer loop, runs at the sample rate (being n in code, don't mistake it)
- the
n loop the inner one, operating at BBD clock rate
n-loop implements as:
|
for (unsigned tick = 0; tick < tick_count; ++tick) { |
Further, this n-loop does two different jobs on even/odd ticks:
- even: pushes in a sample into 1 BBD stage
- odd: sums BBD-rate outputs for entry into output filter, which operates at audio-rate
You will observe odd-case will perform this add:
|
Xout[m] += Gout[m] * delta; |
I have found suspicious that BBD's output Xout can be allowed to grow unlimited, as this sum is never reset.
From the paper, I was able to read this information.

If I correctly interpret "over one interval of the k side", it suggest to reset the Xout sum at each frame. Hence I did.
|
for (unsigned m = 0; m < Mout; ++m) |
|
Xout[m] = 0; |
Thinking of it, it means at some frames, accumulation may remain 0 if BBD doesn't tick (the case of a slow clock).
But also intuitively, it makes sense: in analog world, when BBD doesn't tick, the bucket will empty itself (capacitor discharge), and it's the similar idea when zero are fed into the lowpass following.
Hope this little comment makes sense.
I didn't try this action, you can tell me if this has worked or not.
@b3ll, I'll describe in some detail what I'm doing here, and I let you experiment what may work or not.
Considering the paper is not really clear at all times, I've taken a few guesses.
If the works reaches a point of apparent stability, I'll merge it.
For now, I've added 2 commits in the
unit-delaybranch.Filter couldn't operate according to the structure shown, because the unit delay variable was not kept, meaning either algorithm or structure has been incorrect.
Most probably algorithm, so I reformulated the filter with use of unit delays (as
Xout_mem).You have the processing made of 2 loops: (as denoted in the paper)
kloop is the outer loop, runs at the sample rate (beingnin code, don't mistake it)nloop the inner one, operating at BBD clock raten-loop implements as:bbd-delay-experimental/bbd_line.cc
Line 72 in 543cd7e
Further, this
n-loop does two different jobs on even/odd ticks:You will observe odd-case will perform this add:
bbd-delay-experimental/bbd_line.cc
Line 89 in 543cd7e
I have found suspicious that BBD's output
Xoutcan be allowed to grow unlimited, as this sum is never reset.From the paper, I was able to read this information.

If I correctly interpret "over one interval of the
kside", it suggest to reset theXoutsum at each frame. Hence I did.bbd-delay-experimental/bbd_line.cc
Lines 70 to 71 in e7f197e
Thinking of it, it means at some frames, accumulation may remain 0 if BBD doesn't tick (the case of a slow clock).
But also intuitively, it makes sense: in analog world, when BBD doesn't tick, the bucket will empty itself (capacitor discharge), and it's the similar idea when zero are fed into the lowpass following.
Hope this little comment makes sense.
I didn't try this action, you can tell me if this has worked or not.