Skip to content

Commit 60b8dd3

Browse files
committed
Introduce new struct to catch the root cause
1 parent 0dd37d0 commit 60b8dd3

File tree

1 file changed

+30
-23
lines changed

1 file changed

+30
-23
lines changed

virtio-snd.c

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,13 @@ static int vsnd_dev_cnt = 0;
249249

250250
// static struct CNFADriver *audio_host = NULL;
251251

252-
static bool guest_playing = false;
252+
typedef struct {
253+
bool guest_playing;
254+
uint32_t stream_id;
255+
} vsnd_stream_sel_t;
256+
static vsnd_stream_sel_t v = {
257+
.guest_playing = false,
258+
};
253259

254260
/* Forward declaration */
255261
static void virtio_snd_cb(struct CNFADriver *dev,
@@ -389,13 +395,16 @@ static void virtio_snd_read_pcm_prepare(struct virtq_desc *vq_desc,
389395
virtio_snd_pcm_hdr_t *request = query;
390396
uint32_t stream_id = request->stream_id;
391397
vsnd_props[stream_id].pp.hdr.hdr.code = VIRTIO_SND_R_PCM_PREPARE;
392-
vsnd_props[stream_id].audio_host = CNFAInit(
393-
NULL, "semu-virtio-snd", virtio_snd_cb, 44100, 0, 1, 0,
394-
vsnd_props[stream_id].pp.buffer_bytes, NULL, NULL, &guest_playing);
398+
vsnd_props[stream_id].audio_host =
399+
CNFAInit(NULL, "semu-virtio-snd", virtio_snd_cb, 44100, 0, 1, 0,
400+
vsnd_props[stream_id].pp.buffer_bytes, NULL, NULL, &v);
401+
size_t sz = vsnd_props[stream_id].pp.buffer_bytes;
402+
vsnd_props[stream_id].buf = malloc(sizeof(vsnd_props[stream_id].buf) * sz);
395403

396404
/* Control the callback to prepare the buffer */
397405
/* TODO: add lock to avoid race condition */
398-
guest_playing = false;
406+
v.guest_playing = false;
407+
v.stream_id = 0;
399408

400409
fprintf(stderr, "virtio_snd_read_pcm_prepare\n");
401410
}
@@ -407,7 +416,7 @@ static void virtio_snd_read_pcm_start(struct virtq_desc *vq_desc,
407416

408417
/* Control the callback to start playing */
409418
/* TODO: add lock to avoid race condition */
410-
guest_playing = true;
419+
v.guest_playing = true;
411420

412421
fprintf(stderr, "virtio_snd_read_pcm_start\n");
413422
}
@@ -419,7 +428,7 @@ static void virtio_snd_read_pcm_stop(struct virtq_desc *vq_desc,
419428

420429
/* Control the callback to stop playing */
421430
/* TODO: add lock to avoid race condition */
422-
guest_playing = false;
431+
v.guest_playing = false;
423432

424433
fprintf(stderr, "virtio_snd_read_pcm_stop\n");
425434
}
@@ -429,7 +438,7 @@ static void virtio_snd_read_pcm_release(struct virtq_desc *vq_desc,
429438
{
430439
/* Control the callback to stop playing */
431440
/* TODO: add lock to avoid race condition */
432-
guest_playing = false;
441+
v.guest_playing = false;
433442

434443
virtio_snd_pcm_hdr_t *request = query;
435444
uint32_t stream_id = request->stream_id;
@@ -446,20 +455,19 @@ static void virtio_snd_cb(struct CNFADriver *dev,
446455
int framesp,
447456
int framesr)
448457
{
449-
/* TODO: apply lock on guest_playing and guest_playing_ptr */
450-
int *guest_playing_ptr = (int *) dev->opaque;
458+
/* TODO: apply lock on guest_playing */
459+
vsnd_stream_sel_t *v_ptr = (vsnd_stream_sel_t *) dev->opaque;
460+
bool playing = v_ptr->guest_playing;
461+
uint32_t id = v_ptr->stream_id;
451462
int output_channels = dev->channelsPlay;
452463
int output_buf_sz = framesp * output_channels;
453464

454-
if (framesp > 0) { // playback
455-
if (!(*guest_playing_ptr)) {
456-
memset(out, 0, sizeof(short) * output_buf_sz);
457-
return;
458-
}
459-
} else {
460-
fprintf(stderr, "virtio_snd_cb(%p, %p, %p, %d, %d)\n", dev, out, in,
461-
framesp, framesr);
465+
if (!(playing)) {
466+
memset(out, 0, sizeof(short) * output_buf_sz);
467+
return;
462468
}
469+
470+
memcpy(out, vsnd_props[id].buf, output_buf_sz);
463471
}
464472

465473
#define VSND_DESC_CNT 3
@@ -595,17 +603,14 @@ static int virtio_snd_tx_desc_handler(virtio_snd_state_t *vsnd,
595603

596604
/* Process the data */
597605
fprintf(stderr, "TX process header\n");
598-
// fprintf(stderr, "stream %d got %ld bytes.\n", stream_id,
599-
// sizeof(payload));
600-
size_t sz = vsnd_props[stream_id].pp.period_bytes;
601-
vsnd_props[stream_id].buf = malloc(sizeof(vsnd_props[stream_id].buf) * sz);
606+
size_t sz = vsnd_props[stream_id].pp.buffer_bytes;
602607
memcpy(vsnd_props[stream_id].buf, payload, sz);
603608

604609
/* Return the device status */
605610
fprintf(stderr, "TX return device status\n");
606611
response->status = VIRTIO_SND_S_OK;
607612
response->latency_bytes = 0; /* TODO: show the actual latency bytes */
608-
*plen = vq_desc[1].len;
613+
*plen = sz;
609614

610615
return 0;
611616
}
@@ -791,6 +796,8 @@ static bool virtio_snd_reg_write(virtio_snd_state_t *vsnd,
791796
case VSND_QUEUE_TX:
792797
virtio_queue_notify_handler(vsnd, value,
793798
virtio_snd_tx_desc_handler);
799+
for (int i = 0; i < 10000000; i++)
800+
asm volatile("" ::: "memory");
794801
break;
795802
case VSND_QUEUE_EVT:
796803
fprintf(stderr, "EVT\n");

0 commit comments

Comments
 (0)