@@ -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 */
255261static 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