Skip to content

Commit bd59033

Browse files
committed
Get the frames only after pcm_start state
1 parent a1818c0 commit bd59033

File tree

1 file changed

+33
-9
lines changed

1 file changed

+33
-9
lines changed

virtio-snd.c

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,8 @@ typedef struct {
321321
// PCM frame doubly-ended queue
322322
vsnd_buf_queue_node_t buf;
323323
struct list_head buf_queue_head;
324+
// PCM frame immediate buffer;
325+
void *immediate;
324326

325327
// playback control
326328
vsnd_stream_sel_t v;
@@ -552,7 +554,7 @@ static void virtio_snd_read_pcm_prepare(const virtio_snd_pcm_hdr_t *query,
552554
/* CNFA only accept frame with signed 16-bit data in little-endian. */
553555
props->audio_host =
554556
CNFAInit(NULL, "semu-virtio-snd", virtio_snd_cb, rate, 0, channels, 0,
555-
period_bytes / VSND_CNFA_FRAME_SZ, NULL, NULL, &props->v);
557+
cnfa_period_frames, NULL, NULL, &props->v);
556558
uint32_t sz = props->pp.buffer_bytes;
557559
props->ring.buffer = (void *) malloc(sizeof(void) * sz);
558560
props->ring.prod.head = 0;
@@ -567,6 +569,7 @@ static void virtio_snd_read_pcm_prepare(const virtio_snd_pcm_hdr_t *query,
567569
pthread_cond_init(&props->ring.readable, NULL);
568570
pthread_cond_init(&props->ring.writable, NULL);
569571
INIT_LIST_HEAD(&props->buf_queue_head);
572+
props->immediate = (void *)malloc(sizeof(void) * cnfa_period_bytes);
570573
#if WRITEOUT
571574
outfile = fopen("out_enque.bin", "wb");
572575
#endif
@@ -648,6 +651,7 @@ static void virtio_snd_read_pcm_release(const virtio_snd_pcm_hdr_t *query,
648651
#endif
649652
/* Tear down the PCM ring buffer. */
650653
free(props->ring.buffer);
654+
free(props->immediate);
651655
pthread_mutex_destroy(&props->ring.lock);
652656
pthread_cond_destroy(&props->ring.readable);
653657
pthread_cond_destroy(&props->ring.writable);
@@ -710,26 +714,46 @@ static void __virtio_snd_frame_dequeue(short *out,
710714
"cons_head %" PRIu32 " cons_next %" PRIu32 " prod_tail %" PRIu32
711715
" mask %" PRIu32 " idx %" PRIu32 "\n",
712716
cons_head, cons_next, prod_tail, mask, idx);
713-
if (idx + n < size) {
717+
/*if (idx + n < size) {
714718
memcpy(out, props->ring.buffer + idx, n);
715719
} else {
716720
memcpy(out, props->ring.buffer + idx, size - idx);
717721
memcpy(out + (size - idx), props->ring.buffer, n - (size - idx));
718722
fprintf(stderr, "=== start %" PRIu32 " end %" PRIu32 "\n", size - idx,
719723
n - (size - idx));
720-
}
724+
}*/
721725
VSND_COMPILER_BARRIER;
722726

723727
props->ring.cons.tail = cons_next;
724728

725-
/*uint32_t len = 0;
726-
while (!list_empty(&props->buf_queue_head) && len < n) {
729+
uint32_t written_bytes = 0;
730+
memset(props->immediate, 0, sizeof(void) * n);
731+
while (!list_empty(&props->buf_queue_head) && written_bytes < n) {
727732
vsnd_buf_queue_node_t *node =
728733
list_first_entry(&props->buf_queue_head, vsnd_buf_queue_node_t, q);
729-
list_del(&node->q);
730-
memcpy(out, node->addr, node->len);
731-
len += node->len;
732-
}*/
734+
uint32_t left = n - written_bytes;
735+
uint32_t actual = node->len - node->pos;
736+
uint32_t len = left < actual ? left : actual; /* Naive min implementation */
737+
738+
fprintf(stderr,
739+
"--- left %" PRIu32 " actual %" PRIu32 " len %" PRIu32 " written %" PRIu32 "\n",
740+
left,
741+
actual,
742+
len,
743+
written_bytes);
744+
745+
memcpy(
746+
props->immediate + written_bytes,
747+
node->addr,
748+
len);
749+
750+
written_bytes += len;
751+
node->pos += len;
752+
if(node->pos >= node->len)
753+
list_del(&node->q);
754+
}
755+
fprintf(stderr, "*** written %" PRIu32 " out n %" PRIu32 "\n", written_bytes, n);
756+
memcpy(out, props->immediate, n);
733757

734758
props->ring.buf_ev_notity--;
735759
pthread_cond_signal(&props->ring.writable);

0 commit comments

Comments
 (0)