mirror of https://github.com/xemu-project/xemu.git
audio: bugfixes.
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABAgAGBQJeEy1DAAoJEEy22O7T6HE4IcQQAImPVe33g19T/uW2wH3hgj1W Q4bcRXE7ClrqYue948yc4ygV6UrQoj3YhBDjdj2ngsJTtJI6RRwYF34gLN6kwgN7 Z0it4qLujIw100ay+KBqpKa3M+BlXoKN55w+ylCUYXc/prg0ykuXrG1605ib5vFJ 7NwNNJVxZApt8cstWll5gy9ewbxR1+0Ka9AilCvBiCNoOVpmlJtMV973Gth48E4J l44ROayfCzPBEqldp8yMPkrR/V/+TzBqtMpdV3rItM55c43vVxLnmjEKxxDGHsgG 5xuP0HSnWs9OJ3DJIEOqkmgEH6TzfMqfWxTHDEE6DyUaVOAgMptD9OOjjcK0wbaa MftBSaW0WZc5YSytwj6Hr32l42WVXRFTwVdDzYDglSjgHGxEvh6icz3r5iBPrdsW 5omrwJeo7eyS/MY77tprX8X8jXuxRmemeCE7hR12V0Q5yMLp5TjCwBZqucEXWooc 6F44Pw8wCLENdE0xGjKER9E2n5+vxFo1W0pNjcNIZDsbhnTkgftOvrjv77qpwr0f lyraRvETOcRmE+dBr00ZDHCvq7mPeO6OydPFhLK1ZHEUQvNBRdM80C4yMil/uUnW oiDw7rwcQrwThArof7Bh0c2UoEmpG9CSWKD6+LtCL1PkSJzVgFxnn8d3UdArO75X IPuqYGtqeOkEIH15Vrax =7tsN -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/kraxel/tags/audio-20200106-pull-request' into staging audio: bugfixes. # gpg: Signature made Mon 06 Jan 2020 12:51:15 GMT # gpg: using RSA key 4CB6D8EED3E87138 # gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" [full] # gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" [full] # gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" [full] # Primary key fingerprint: A032 8CFF B93A 17A7 9901 FE7D 4CB6 D8EE D3E8 7138 * remotes/kraxel/tags/audio-20200106-pull-request: audio: fix integer overflow paaudio: wait until the recording stream is ready paaudio: try to drain the recording stream paaudio: drop recording stream in qpa_fini_in hda-codec: fix recording rate control hda-codec: fix playback rate control Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
5d11217645
|
@ -1738,7 +1738,7 @@ static AudioState *audio_init(Audiodev *dev, const char *name)
|
||||||
if (dev->timer_period <= 0) {
|
if (dev->timer_period <= 0) {
|
||||||
s->period_ticks = 1;
|
s->period_ticks = 1;
|
||||||
} else {
|
} else {
|
||||||
s->period_ticks = dev->timer_period * SCALE_US;
|
s->period_ticks = dev->timer_period * (int64_t)SCALE_US;
|
||||||
}
|
}
|
||||||
|
|
||||||
e = qemu_add_vm_change_state_handler (audio_vm_change_state_handler, s);
|
e = qemu_add_vm_change_state_handler (audio_vm_change_state_handler, s);
|
||||||
|
|
|
@ -156,34 +156,48 @@ static size_t qpa_read(HWVoiceIn *hw, void *data, size_t length)
|
||||||
{
|
{
|
||||||
PAVoiceIn *p = (PAVoiceIn *) hw;
|
PAVoiceIn *p = (PAVoiceIn *) hw;
|
||||||
PAConnection *c = p->g->conn;
|
PAConnection *c = p->g->conn;
|
||||||
size_t l;
|
size_t total = 0;
|
||||||
int r;
|
|
||||||
|
|
||||||
pa_threaded_mainloop_lock(c->mainloop);
|
pa_threaded_mainloop_lock(c->mainloop);
|
||||||
|
|
||||||
CHECK_DEAD_GOTO(c, p->stream, unlock_and_fail,
|
CHECK_DEAD_GOTO(c, p->stream, unlock_and_fail,
|
||||||
"pa_threaded_mainloop_lock failed\n");
|
"pa_threaded_mainloop_lock failed\n");
|
||||||
|
if (pa_stream_get_state(p->stream) != PA_STREAM_READY) {
|
||||||
|
/* wait for stream to become ready */
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (total < length) {
|
||||||
|
size_t l;
|
||||||
|
int r;
|
||||||
|
|
||||||
if (!p->read_length) {
|
if (!p->read_length) {
|
||||||
r = pa_stream_peek(p->stream, &p->read_data, &p->read_length);
|
r = pa_stream_peek(p->stream, &p->read_data, &p->read_length);
|
||||||
CHECK_SUCCESS_GOTO(c, r == 0, unlock_and_fail,
|
CHECK_SUCCESS_GOTO(c, r == 0, unlock_and_fail,
|
||||||
"pa_stream_peek failed\n");
|
"pa_stream_peek failed\n");
|
||||||
|
if (!p->read_length) {
|
||||||
|
/* buffer is empty */
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
l = MIN(p->read_length, length);
|
l = MIN(p->read_length, length - total);
|
||||||
memcpy(data, p->read_data, l);
|
memcpy((char *)data + total, p->read_data, l);
|
||||||
|
|
||||||
p->read_data += l;
|
p->read_data += l;
|
||||||
p->read_length -= l;
|
p->read_length -= l;
|
||||||
|
total += l;
|
||||||
|
|
||||||
if (!p->read_length) {
|
if (!p->read_length) {
|
||||||
r = pa_stream_drop(p->stream);
|
r = pa_stream_drop(p->stream);
|
||||||
CHECK_SUCCESS_GOTO(c, r == 0, unlock_and_fail,
|
CHECK_SUCCESS_GOTO(c, r == 0, unlock_and_fail,
|
||||||
"pa_stream_drop failed\n");
|
"pa_stream_drop failed\n");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unlock:
|
||||||
pa_threaded_mainloop_unlock(c->mainloop);
|
pa_threaded_mainloop_unlock(c->mainloop);
|
||||||
return l;
|
return total;
|
||||||
|
|
||||||
unlock_and_fail:
|
unlock_and_fail:
|
||||||
pa_threaded_mainloop_unlock(c->mainloop);
|
pa_threaded_mainloop_unlock(c->mainloop);
|
||||||
|
@ -536,7 +550,6 @@ static void qpa_simple_disconnect(PAConnection *c, pa_stream *stream)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
pa_threaded_mainloop_lock(c->mainloop);
|
|
||||||
/*
|
/*
|
||||||
* wait until actually connects. workaround pa bug #247
|
* wait until actually connects. workaround pa bug #247
|
||||||
* https://gitlab.freedesktop.org/pulseaudio/pulseaudio/issues/247
|
* https://gitlab.freedesktop.org/pulseaudio/pulseaudio/issues/247
|
||||||
|
@ -550,7 +563,6 @@ static void qpa_simple_disconnect(PAConnection *c, pa_stream *stream)
|
||||||
dolog("Failed to disconnect! err=%d\n", err);
|
dolog("Failed to disconnect! err=%d\n", err);
|
||||||
}
|
}
|
||||||
pa_stream_unref(stream);
|
pa_stream_unref(stream);
|
||||||
pa_threaded_mainloop_unlock(c->mainloop);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qpa_fini_out (HWVoiceOut *hw)
|
static void qpa_fini_out (HWVoiceOut *hw)
|
||||||
|
@ -558,8 +570,12 @@ static void qpa_fini_out (HWVoiceOut *hw)
|
||||||
PAVoiceOut *pa = (PAVoiceOut *) hw;
|
PAVoiceOut *pa = (PAVoiceOut *) hw;
|
||||||
|
|
||||||
if (pa->stream) {
|
if (pa->stream) {
|
||||||
qpa_simple_disconnect(pa->g->conn, pa->stream);
|
PAConnection *c = pa->g->conn;
|
||||||
|
|
||||||
|
pa_threaded_mainloop_lock(c->mainloop);
|
||||||
|
qpa_simple_disconnect(c, pa->stream);
|
||||||
pa->stream = NULL;
|
pa->stream = NULL;
|
||||||
|
pa_threaded_mainloop_unlock(c->mainloop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -568,8 +584,20 @@ static void qpa_fini_in (HWVoiceIn *hw)
|
||||||
PAVoiceIn *pa = (PAVoiceIn *) hw;
|
PAVoiceIn *pa = (PAVoiceIn *) hw;
|
||||||
|
|
||||||
if (pa->stream) {
|
if (pa->stream) {
|
||||||
qpa_simple_disconnect(pa->g->conn, pa->stream);
|
PAConnection *c = pa->g->conn;
|
||||||
|
|
||||||
|
pa_threaded_mainloop_lock(c->mainloop);
|
||||||
|
if (pa->read_length) {
|
||||||
|
int r = pa_stream_drop(pa->stream);
|
||||||
|
if (r) {
|
||||||
|
qpa_logerr(pa_context_errno(c->context),
|
||||||
|
"pa_stream_drop failed\n");
|
||||||
|
}
|
||||||
|
pa->read_length = 0;
|
||||||
|
}
|
||||||
|
qpa_simple_disconnect(c, pa->stream);
|
||||||
pa->stream = NULL;
|
pa->stream = NULL;
|
||||||
|
pa_threaded_mainloop_unlock(c->mainloop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -265,8 +265,6 @@ static void hda_audio_input_cb(void *opaque, int avail)
|
||||||
|
|
||||||
int64_t to_transfer = MIN(B_SIZE - (wpos - rpos), avail);
|
int64_t to_transfer = MIN(B_SIZE - (wpos - rpos), avail);
|
||||||
|
|
||||||
hda_timer_sync_adjust(st, -((wpos - rpos) + to_transfer - (B_SIZE >> 1)));
|
|
||||||
|
|
||||||
while (to_transfer) {
|
while (to_transfer) {
|
||||||
uint32_t start = (uint32_t) (wpos & B_MASK);
|
uint32_t start = (uint32_t) (wpos & B_MASK);
|
||||||
uint32_t chunk = (uint32_t) MIN(B_SIZE - start, to_transfer);
|
uint32_t chunk = (uint32_t) MIN(B_SIZE - start, to_transfer);
|
||||||
|
@ -278,6 +276,8 @@ static void hda_audio_input_cb(void *opaque, int avail)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hda_timer_sync_adjust(st, -((wpos - rpos) - (B_SIZE >> 1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hda_audio_output_timer(void *opaque)
|
static void hda_audio_output_timer(void *opaque)
|
||||||
|
@ -338,8 +338,6 @@ static void hda_audio_output_cb(void *opaque, int avail)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
hda_timer_sync_adjust(st, (wpos - rpos) - to_transfer - (B_SIZE >> 1));
|
|
||||||
|
|
||||||
while (to_transfer) {
|
while (to_transfer) {
|
||||||
uint32_t start = (uint32_t) (rpos & B_MASK);
|
uint32_t start = (uint32_t) (rpos & B_MASK);
|
||||||
uint32_t chunk = (uint32_t) MIN(B_SIZE - start, to_transfer);
|
uint32_t chunk = (uint32_t) MIN(B_SIZE - start, to_transfer);
|
||||||
|
@ -351,6 +349,8 @@ static void hda_audio_output_cb(void *opaque, int avail)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hda_timer_sync_adjust(st, (wpos - rpos) - (B_SIZE >> 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hda_audio_compat_input_cb(void *opaque, int avail)
|
static void hda_audio_compat_input_cb(void *opaque, int avail)
|
||||||
|
|
Loading…
Reference in New Issue