@@ -578,6 +578,42 @@ static void virtio_snd_read_pcm_release(const virtio_snd_pcm_hdr_t *query,
578578double omega = 0.0 ;
579579int totalframesp = 0 ;
580580int totalframesr = 0 ;
581+ static void __virtio_snd_frame_dequeue (void * * out ,
582+ uint32_t n ,
583+ uint32_t stream_id )
584+ {
585+ virtio_snd_prop_t * props = & vsnd_props [stream_id ];
586+ uint32_t cons_head , prod_tail ;
587+ uint32_t cons_next , entries ;
588+ uint32_t mask = props -> pp .buffer_bytes ;
589+
590+ cons_head = props -> ring .cons .head ;
591+ prod_tail = props -> ring .prod .tail ;
592+ /* The subtraction is done between two unsigned 32bits value
593+ * (the result is always modulo 32 bits even if we have
594+ * cons_head > prod_tail). So 'entries' is always between 0
595+ * and size(ring)-1. */
596+ entries = prod_tail - cons_head ;
597+
598+ if (n > entries )
599+ fprintf (stderr , "copy length is larget than entries\n" );
600+
601+ cons_next = cons_head + n ;
602+ props -> ring .cons .head = cons_next ;
603+
604+ /* Copy the frame to output stream */
605+ uint32_t size = props -> pp .buffer_bytes ;
606+ uint32_t idx = cons_head & mask ;
607+ if (idx + n < size ) {
608+ memcpy (* out , props -> ring .buffer + idx , n );
609+ } else {
610+ memcpy (* out , props -> ring .buffer + idx , size - idx );
611+ memcpy (* out + (size - idx ), props -> ring .buffer , n - (size - idx ));
612+ }
613+ asm("" ::: "memory" );
614+
615+ props -> ring .cons .tail = cons_next ;
616+ }
581617static void virtio_snd_cb (struct CNFADriver * dev ,
582618 short * out ,
583619 short * in ,
@@ -610,7 +646,7 @@ static void virtio_snd_cb(struct CNFADriver *dev,
610646 }*/
611647
612648 /* TODO: add single consumer */
613- memcpy ( out , vsnd_props [ id ]. ring . buffer , out_buf_sz );
649+ __virtio_snd_frame_dequeue ( & out , out_buf_sz , id );
614650#if 0
615651 for (int i = 0 ; i < framesp ; i ++ ) {
616652 // Shift phase, so we run at 440 Hz (A4)
@@ -726,9 +762,7 @@ static void __virtio_snd_frame_enqueue(void *payload,
726762{
727763 uint32_t prod_head , cons_tail ;
728764 uint32_t prod_next , free_entries ;
729- virtio_snd_prop_t * props =
730- & vsnd_props [stream_id ]; /* XXX: access the address for the ease of data
731- manipulation */
765+ virtio_snd_prop_t * props = & vsnd_props [stream_id ];
732766 uint32_t mask = props -> pp .buffer_bytes ;
733767
734768 prod_head = props -> ring .prod .head ;
@@ -738,10 +772,16 @@ static void __virtio_snd_frame_enqueue(void *payload,
738772 * prod_head > cons_tail). So 'free_entries' is always between 0
739773 * and size(ring)-1. */
740774 free_entries = mask + cons_tail - prod_head ;
775+ /*fprintf(stderr,
776+ "mask %" PRIu32 " cons_tail %" PRIu32 " prod_head %" PRIu32 "\n",
777+ mask, cons_tail, prod_head);*/
741778
742779 /* Move prod_head. */
743780 if (n > free_entries )
744- fprintf (stderr , "payload length %" PRIu32 " larger than free_entries %" PRIu32 "\n" , n , free_entries );
781+ fprintf (stderr ,
782+ "payload length %" PRIu32 " larger than free_entries %" PRIu32
783+ "\n" ,
784+ n , free_entries );
745785 prod_next = prod_head + n ;
746786 props -> ring .prod .head = prod_next ;
747787
0 commit comments