[hatari-devel] Higher precision when generating samples
Nicolas Pomarède
npomarede at corp.free.fr
Mon Jan 24 00:44:11 CET 2011
Hello
before applying David's patch, I wanted to improve a few things in
sound.c regarding rounding errors.
Actually the number of samples per frame could be wrong, depending on
the sound output and the VBL rate.
For example, at 44100 kHz and 50 Hz VBL, you get 882 samples per frame
(not rounding), but at 11025 @ 50 Hz, you get 220.5.
In the latter case, Hatari was rounding this to 221. This means that
during 1 VBL, you could get 25 extra samples generated. After a number
of VBL, these samples would accumulate and create a growing difference
between the rate of the sound card and the rate of the sound emulated by
Hatari ; here we get 11025 for the sound card, but 11050 Hz for Hatari.
The difference is not really hearable, but it matters when dealing with
sound buffers.
So, Hatari generated up to 49 extra samples per VBL (worst case)
But on the contrary Sound_SetSamplesPassed() could also generate one
less sample than expected. Due to rounding errors, calling for example
882 times Sound_SetSamplesPassed() would not always give the same result
that calling Sound_SetSamplesPassed() to generate 882 samples in one go.
For most programs that change sound register only once during the VBL,
this was not noticeable, but when changing registers several times per
VBL the rounding error could occur.
So, all in all, both rounding errors were quite rare and they happen to
compensate each other (more or less, but with an output freq of 44.1 kHz
there was nearly no such errors).
But still, this was not correct, so I modified the code to :
- simulate a high precision SamplesPerFrame value, that will adjust
the number of generated samples per frame to really match the desired
sound output freq. So even freq such as 12517 kHz @ 60 Hz should give
correct results (that is 12517 samples are generated each second)
- ensure we always have SamplesPerFrame samples during each VBL,
regardless of the rounding precision in SetSamplesPassed(). This is made
by completing each audio frame up to SamplesPerFrame (see FillFrame
paramater added in Sound_Update). FillFrame is true only when called
from Sound_Update_VBL.
So, we really have a correct number of samples each frame now,
especially when recording sound as a wav file or recording as an avi
file (previously saved audio frames could also have a wrong size).
David's patch has another approach : it changes the delay between 2 VBL
to match the generated number of samples, so this corrects the
audio/video sync when running Hatari, but it doesn't correct
SamplesPerFrame, which is really necessary if we want to have precise
wav/avi files recording.
David and Eero, as you reported delays in sound at 60 Hz and low freq,
could you tell me if these modifications improve the situation ?
Nicolas
More information about the hatari-devel
mailing list