I made a quick hack change over lunch as a test,
which has eliminated the glitch. I'm basing it on the original code from the repo, unpatched. However this does not represent a 'fix' for the problem, it just indicates where the problem is coming from.
Originally zeroes were pushed into the dac.readPosition (ring tail) as soon as data was fetched by it. However if the readPosition does not move on (e.g. if the fractional step is < 1.0) then the next (duplicated) sample would have been zapped with a zero - which is incorrect.
I made this mod which writes the zero only if the integer part of the readPosition advances.
/* Upgrade dac's buffer read pointer */
dac.readPosition_float += crossbar.frequence_ratio;
n = dac.readPosition_float >> 32; /* number of samples to skip */
if (n)
{
// becomes safe to zero old data if tail has moved
dac.buffer_left[dac.readPosition] = 0;
dac.buffer_right[dac.readPosition] = 0;
}
dac.readPosition = (dac.readPosition + n) % DACBUFFER_SIZE;
dac.readPosition_float &= 0xffffffff; /* only keep the fractional part */
The captured sample does not have any of the unwanted zeroes present - which I think is indicative.
However it also doesn't have random data in its place. That suggests the previous patch was incorrect, and creating more glitches. I am working with the original (unpatched) code, making only the change above.
I'm still not happy with the change above, because the ring tail should not modify the data at all. However it might help somebody else formulate a fix. I don't understand the reason zeroes are written so I'm not the best person to make that choice.
For now I'll stick with this temporary hack until something better surfaces.
I am left with another problem though. It looks different - perhaps related but can't be sure. I can't blame this next problem on Hatari because I'll have to start all over again, following it through from my own code to the output. That won't happen soon, so you might or might not hear from me again at some point :)
D