aboutsummaryrefslogtreecommitdiff
path: root/audio/spiceaudio.c
diff options
context:
space:
mode:
authorKővágó, Zoltán <dirty.ice.hu@gmail.com>2019-09-19 23:24:21 +0200
committerGerd Hoffmann <kraxel@redhat.com>2019-09-23 12:28:47 +0200
commit857271a29c2c0e5deb05deb540a2580d1d408b34 (patch)
tree4fc6973c058119db43306e2fbedecc007396aa12 /audio/spiceaudio.c
parentdc88e38fa7f7480becf34712eae41380b62aacc6 (diff)
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>
Diffstat (limited to 'audio/spiceaudio.c')
-rw-r--r--audio/spiceaudio.c51
1 files changed, 8 insertions, 43 deletions
diff --git a/audio/spiceaudio.c b/audio/spiceaudio.c
index ff4e4dcbb0..4ce4f94c6d 100644
--- a/audio/spiceaudio.c
+++ b/audio/spiceaudio.c
@@ -40,15 +40,10 @@
#define LINE_IN_SAMPLES (256 * 4)
#endif
-typedef struct SpiceRateCtl {
- int64_t start_ticks;
- int64_t bytes_sent;
-} SpiceRateCtl;
-
typedef struct SpiceVoiceOut {
HWVoiceOut hw;
SpicePlaybackInstance sin;
- SpiceRateCtl rate;
+ RateCtl rate;
int active;
uint32_t *frame;
uint32_t fpos;
@@ -58,7 +53,7 @@ typedef struct SpiceVoiceOut {
typedef struct SpiceVoiceIn {
HWVoiceIn hw;
SpiceRecordInstance sin;
- SpiceRateCtl rate;
+ RateCtl rate;
int active;
} SpiceVoiceIn;
@@ -89,32 +84,6 @@ static void spice_audio_fini (void *opaque)
/* nothing */
}
-static void rate_start (SpiceRateCtl *rate)
-{
- memset (rate, 0, sizeof (*rate));
- rate->start_ticks = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
-}
-
-static int rate_get_samples (struct audio_pcm_info *info, SpiceRateCtl *rate)
-{
- int64_t now;
- int64_t ticks;
- int64_t bytes;
- int64_t samples;
-
- now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
- ticks = now - rate->start_ticks;
- bytes = muldiv64(ticks, info->bytes_per_second, NANOSECONDS_PER_SECOND);
- samples = (bytes - rate->bytes_sent) >> info->shift;
- if (samples < 0 || samples > 65536) {
- error_report("Resetting rate control (%" PRId64 " samples)", samples);
- rate_start(rate);
- samples = 0;
- }
- rate->bytes_sent += samples << info->shift;
- return samples;
-}
-
/* playback */
static int line_out_init(HWVoiceOut *hw, struct audsettings *as,
@@ -154,7 +123,6 @@ static void line_out_fini (HWVoiceOut *hw)
static void *line_out_get_buffer(HWVoiceOut *hw, size_t *size)
{
SpiceVoiceOut *out = container_of(hw, SpiceVoiceOut, hw);
- size_t decr;
if (!out->frame) {
spice_server_playback_get_buffer(&out->sin, &out->frame, &out->fsize);
@@ -162,12 +130,10 @@ static void *line_out_get_buffer(HWVoiceOut *hw, size_t *size)
}
if (out->frame) {
- decr = rate_get_samples(&hw->info, &out->rate);
- decr = MIN(out->fsize - out->fpos, decr);
-
- *size = decr << hw->info.shift;
+ *size = audio_rate_get_bytes(
+ &hw->info, &out->rate, (out->fsize - out->fpos) << hw->info.shift);
} else {
- rate_start(&out->rate);
+ audio_rate_start(&out->rate);
}
return out->frame + out->fpos;
}
@@ -197,7 +163,7 @@ static int line_out_ctl (HWVoiceOut *hw, int cmd, ...)
break;
}
out->active = 1;
- rate_start (&out->rate);
+ audio_rate_start(&out->rate);
spice_server_playback_start (&out->sin);
break;
case VOICE_DISABLE:
@@ -273,8 +239,7 @@ static void line_in_fini (HWVoiceIn *hw)
static size_t line_in_read(HWVoiceIn *hw, void *buf, size_t len)
{
SpiceVoiceIn *in = container_of (hw, SpiceVoiceIn, hw);
- uint64_t delta_samp = rate_get_samples(&hw->info, &in->rate);
- uint64_t to_read = MIN(len >> 2, delta_samp);
+ uint64_t to_read = audio_rate_get_bytes(&hw->info, &in->rate, len) >> 2;
size_t ready = spice_server_record_get_samples(&in->sin, buf, to_read);
/* XXX: do we need this? */
@@ -296,7 +261,7 @@ static int line_in_ctl (HWVoiceIn *hw, int cmd, ...)
break;
}
in->active = 1;
- rate_start (&in->rate);
+ audio_rate_start(&in->rate);
spice_server_record_start (&in->sin);
break;
case VOICE_DISABLE: