|
@@ -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:
|