audio: common rate control code for timer based outputs
This commit removes the ad-hoc rate-limiting code from noaudio and
wavaudio, and replaces them with a (slightly modified) code from
spiceaudio. This way multiple write calls (for example when the
circular buffer wraps around) do not cause problems.
Signed-off-by: Kővágó, Zoltán <DirtY.iCE.hu@gmail.com>
Message-id: fd0fe5b95b13fa26d09ae77a72f99d0ea411de14.1568927990.git.DirtY.iCE.hu@gmail.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
diff --git a/audio/wavaudio.c b/audio/wavaudio.c
index 78af2f1..85f5ff9 100644
--- a/audio/wavaudio.c
+++ b/audio/wavaudio.c
@@ -35,21 +35,15 @@
typedef struct WAVVoiceOut {
HWVoiceOut hw;
FILE *f;
- int64_t old_ticks;
+ RateCtl rate;
int total_samples;
} WAVVoiceOut;
static size_t wav_write_out(HWVoiceOut *hw, void *buf, size_t len)
{
WAVVoiceOut *wav = (WAVVoiceOut *) hw;
- int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
- int64_t ticks = now - wav->old_ticks;
- int64_t bytes =
- muldiv64(ticks, hw->info.bytes_per_second, NANOSECONDS_PER_SECOND);
-
- bytes = MIN(bytes, len);
- bytes = bytes >> hw->info.shift << hw->info.shift;
- wav->old_ticks = now;
+ int64_t bytes = audio_rate_get_bytes(&hw->info, &wav->rate, len);
+ assert(bytes >> hw->info.shift << hw->info.shift == bytes);
if (bytes && fwrite(buf, bytes, 1, wav->f) != 1) {
dolog("wav_write_out: fwrite of %" PRId64 " bytes failed\nReason: %s\n",
@@ -130,6 +124,8 @@
strerror(errno));
return -1;
}
+
+ audio_rate_start(&wav->rate);
return 0;
}
@@ -179,8 +175,11 @@
static int wav_ctl_out (HWVoiceOut *hw, int cmd, ...)
{
- (void) hw;
- (void) cmd;
+ WAVVoiceOut *wav = (WAVVoiceOut *) hw;
+
+ if (cmd == VOICE_ENABLE) {
+ audio_rate_start(&wav->rate);
+ }
return 0;
}