Skip to content

Commit 58ecbaa

Browse files
committed
Add frame dequeue function
1 parent 30ac2cf commit 58ecbaa

File tree

1 file changed

+45
-5
lines changed

1 file changed

+45
-5
lines changed

virtio-snd.c

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,42 @@ static void virtio_snd_read_pcm_release(const virtio_snd_pcm_hdr_t *query,
578578
double omega = 0.0;
579579
int totalframesp = 0;
580580
int 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+
}
581617
static 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

Comments
 (0)