From 60b8dd3efcac529368407f29a9f2fbf07ddf5229 Mon Sep 17 00:00:00 2001 From: Cuda-Chen Date: Tue, 29 Oct 2024 21:46:46 +0800 Subject: [PATCH] Introduce new struct to catch the root cause --- virtio-snd.c | 53 +++++++++++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/virtio-snd.c b/virtio-snd.c index 37d7a1f..d5bb63c 100644 --- a/virtio-snd.c +++ b/virtio-snd.c @@ -249,7 +249,13 @@ static int vsnd_dev_cnt = 0; // static struct CNFADriver *audio_host = NULL; -static bool guest_playing = false; +typedef struct { + bool guest_playing; + uint32_t stream_id; +} vsnd_stream_sel_t; +static vsnd_stream_sel_t v = { + .guest_playing = false, +}; /* Forward declaration */ static void virtio_snd_cb(struct CNFADriver *dev, @@ -389,13 +395,16 @@ static void virtio_snd_read_pcm_prepare(struct virtq_desc *vq_desc, virtio_snd_pcm_hdr_t *request = query; uint32_t stream_id = request->stream_id; vsnd_props[stream_id].pp.hdr.hdr.code = VIRTIO_SND_R_PCM_PREPARE; - vsnd_props[stream_id].audio_host = CNFAInit( - NULL, "semu-virtio-snd", virtio_snd_cb, 44100, 0, 1, 0, - vsnd_props[stream_id].pp.buffer_bytes, NULL, NULL, &guest_playing); + vsnd_props[stream_id].audio_host = + CNFAInit(NULL, "semu-virtio-snd", virtio_snd_cb, 44100, 0, 1, 0, + vsnd_props[stream_id].pp.buffer_bytes, NULL, NULL, &v); + size_t sz = vsnd_props[stream_id].pp.buffer_bytes; + vsnd_props[stream_id].buf = malloc(sizeof(vsnd_props[stream_id].buf) * sz); /* Control the callback to prepare the buffer */ /* TODO: add lock to avoid race condition */ - guest_playing = false; + v.guest_playing = false; + v.stream_id = 0; fprintf(stderr, "virtio_snd_read_pcm_prepare\n"); } @@ -407,7 +416,7 @@ static void virtio_snd_read_pcm_start(struct virtq_desc *vq_desc, /* Control the callback to start playing */ /* TODO: add lock to avoid race condition */ - guest_playing = true; + v.guest_playing = true; fprintf(stderr, "virtio_snd_read_pcm_start\n"); } @@ -419,7 +428,7 @@ static void virtio_snd_read_pcm_stop(struct virtq_desc *vq_desc, /* Control the callback to stop playing */ /* TODO: add lock to avoid race condition */ - guest_playing = false; + v.guest_playing = false; fprintf(stderr, "virtio_snd_read_pcm_stop\n"); } @@ -429,7 +438,7 @@ static void virtio_snd_read_pcm_release(struct virtq_desc *vq_desc, { /* Control the callback to stop playing */ /* TODO: add lock to avoid race condition */ - guest_playing = false; + v.guest_playing = false; virtio_snd_pcm_hdr_t *request = query; uint32_t stream_id = request->stream_id; @@ -446,20 +455,19 @@ static void virtio_snd_cb(struct CNFADriver *dev, int framesp, int framesr) { - /* TODO: apply lock on guest_playing and guest_playing_ptr */ - int *guest_playing_ptr = (int *) dev->opaque; + /* TODO: apply lock on guest_playing */ + vsnd_stream_sel_t *v_ptr = (vsnd_stream_sel_t *) dev->opaque; + bool playing = v_ptr->guest_playing; + uint32_t id = v_ptr->stream_id; int output_channels = dev->channelsPlay; int output_buf_sz = framesp * output_channels; - if (framesp > 0) { // playback - if (!(*guest_playing_ptr)) { - memset(out, 0, sizeof(short) * output_buf_sz); - return; - } - } else { - fprintf(stderr, "virtio_snd_cb(%p, %p, %p, %d, %d)\n", dev, out, in, - framesp, framesr); + if (!(playing)) { + memset(out, 0, sizeof(short) * output_buf_sz); + return; } + + memcpy(out, vsnd_props[id].buf, output_buf_sz); } #define VSND_DESC_CNT 3 @@ -595,17 +603,14 @@ static int virtio_snd_tx_desc_handler(virtio_snd_state_t *vsnd, /* Process the data */ fprintf(stderr, "TX process header\n"); - // fprintf(stderr, "stream %d got %ld bytes.\n", stream_id, - // sizeof(payload)); - size_t sz = vsnd_props[stream_id].pp.period_bytes; - vsnd_props[stream_id].buf = malloc(sizeof(vsnd_props[stream_id].buf) * sz); + size_t sz = vsnd_props[stream_id].pp.buffer_bytes; memcpy(vsnd_props[stream_id].buf, payload, sz); /* Return the device status */ fprintf(stderr, "TX return device status\n"); response->status = VIRTIO_SND_S_OK; response->latency_bytes = 0; /* TODO: show the actual latency bytes */ - *plen = vq_desc[1].len; + *plen = sz; return 0; } @@ -791,6 +796,8 @@ static bool virtio_snd_reg_write(virtio_snd_state_t *vsnd, case VSND_QUEUE_TX: virtio_queue_notify_handler(vsnd, value, virtio_snd_tx_desc_handler); + for (int i = 0; i < 10000000; i++) + asm volatile("" ::: "memory"); break; case VSND_QUEUE_EVT: fprintf(stderr, "EVT\n");