Skip to content

Commit eebc78a

Browse files
committed
Play Front_Center with repeating artifact
1 parent fbf2f19 commit eebc78a

File tree

1 file changed

+39
-7
lines changed

1 file changed

+39
-7
lines changed

virtio-snd.c

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,9 @@ typedef struct {
272272
#define VSND_RING_SZ_MASK 0x0FFFFFFFULL /* ring size mask */
273273
typedef struct {
274274
void *buffer;
275+
pthread_cond_t readable, writable;
276+
int buf_ev_notity;
277+
pthread_mutex_t lock;
275278
struct prod {
276279
volatile uint32_t head; /* producer head */
277280
volatile uint32_t tail; /* producer tail */
@@ -298,9 +301,9 @@ typedef struct {
298301
// PCM frame ring buffer
299302
virtio_snd_ring_buffer_t ring;
300303
} virtio_snd_prop_t;
301-
#define VSND_COMPILER_BARRIER \
302-
do { \
303-
asm("" ::: "memory"); \
304+
#define VSND_COMPILER_BARRIER \
305+
do { \
306+
asm("mfence" ::: "memory"); \
304307
} while (0)
305308

306309
static virtio_snd_config_t vsnd_configs[VSND_DEV_CNT_MAX];
@@ -518,6 +521,9 @@ static void virtio_snd_read_pcm_prepare(const virtio_snd_pcm_hdr_t *query,
518521
vsnd_props[stream_id].ring.cons.size = sz;
519522
vsnd_props[stream_id].ring.prod.mask = sz - 1;
520523
vsnd_props[stream_id].ring.cons.mask = sz - 1;
524+
pthread_mutex_init(&vsnd_props[stream_id].ring.lock, NULL);
525+
pthread_cond_init(&vsnd_props[stream_id].ring.readable, NULL);
526+
pthread_cond_init(&vsnd_props[stream_id].ring.writable, NULL);
521527

522528
*plen = 0;
523529
fprintf(stderr, "virtio_snd_read_pcm_prepare\n");
@@ -588,11 +594,15 @@ static void virtio_snd_read_pcm_release(const virtio_snd_pcm_hdr_t *query,
588594
}
589595

590596
vsnd_props[stream_id].pp.hdr.hdr.code = VIRTIO_SND_R_PCM_RELEASE;
591-
CNFAClose(vsnd_props[stream_id].audio_host);
592-
fprintf(stderr, "pass CNFAclose\n");
593597

594598
/* Tear down the PCM frames. */
595599
free(vsnd_props[stream_id].ring.buffer);
600+
pthread_mutex_destroy(&vsnd_props[stream_id].ring.lock);
601+
pthread_cond_destroy(&vsnd_props[stream_id].ring.readable);
602+
pthread_cond_destroy(&vsnd_props[stream_id].ring.writable);
603+
604+
CNFAClose(vsnd_props[stream_id].audio_host);
605+
fprintf(stderr, "pass CNFAclose\n");
596606

597607
*plen = 0;
598608
fprintf(stderr, "virtio_snd_read_pcm_release\n");
@@ -610,6 +620,12 @@ static void __virtio_snd_frame_dequeue(short *out,
610620
uint32_t cons_next, entries;
611621
uint32_t mask = props->ring.cons.mask;
612622

623+
pthread_mutex_lock(&props->ring.lock);
624+
while (props->ring.buf_ev_notity < 1) {
625+
fprintf(stderr, "---wair in deque---\n");
626+
pthread_cond_wait(&props->ring.readable, &props->ring.lock);
627+
}
628+
613629
cons_head = props->ring.cons.head;
614630
prod_tail = props->ring.prod.tail;
615631
/* The subtraction is done between two unsigned 32bits value
@@ -639,10 +655,16 @@ static void __virtio_snd_frame_dequeue(short *out,
639655
} else {
640656
memcpy(out, props->ring.buffer + idx, size - idx);
641657
memcpy(out + (size - idx), props->ring.buffer, n - (size - idx));
658+
fprintf(stderr, "=== start %" PRIu32 " end %" PRIu32 "\n", size - idx,
659+
n - (size - idx));
642660
}
643661
VSND_COMPILER_BARRIER;
644662

645663
props->ring.cons.tail = cons_next;
664+
665+
props->ring.buf_ev_notity--;
666+
pthread_cond_signal(&props->ring.writable);
667+
pthread_mutex_unlock(&props->ring.lock);
646668
}
647669
static void virtio_snd_cb(struct CNFADriver *dev,
648670
short *out,
@@ -656,7 +678,6 @@ static void virtio_snd_cb(struct CNFADriver *dev,
656678
uint32_t out_buf_sz = framesp * channels;
657679

658680
pthread_mutex_lock(&virtio_snd_ctrl_mutex);
659-
660681
while (v_ptr->guest_playing == 0) {
661682
fprintf(stderr, "wait ctrl cond\n");
662683
memset(out, 0, sizeof(*out) * out_buf_sz);
@@ -667,7 +688,8 @@ static void virtio_snd_cb(struct CNFADriver *dev,
667688
totalframesp += framesp;
668689

669690
uint32_t id = v_ptr->stream_id;
670-
fprintf(stderr, "start to play with out_buf_sz %" PRIu32 "\n", out_buf_sz);
691+
// fprintf(stderr, "start to play with out_buf_sz %" PRIu32 "\n",
692+
// out_buf_sz);
671693

672694
/* TODO: add single consumer */
673695
#if 1
@@ -791,6 +813,12 @@ static void __virtio_snd_frame_enqueue(void *payload,
791813
virtio_snd_prop_t *props = &vsnd_props[stream_id];
792814
uint32_t mask = props->ring.prod.mask;
793815

816+
pthread_mutex_lock(&props->ring.lock);
817+
while (props->ring.buf_ev_notity > 0) {
818+
fprintf(stderr, "---wait for enque---\n");
819+
pthread_cond_wait(&props->ring.writable, &props->ring.lock);
820+
}
821+
794822
prod_head = props->ring.prod.head;
795823
cons_tail = props->ring.cons.tail;
796824
/* The subtraction is done between two unsigned 32bits value
@@ -828,6 +856,10 @@ static void __virtio_snd_frame_enqueue(void *payload,
828856

829857
/* Update prod_tail */
830858
props->ring.prod.tail = prod_next;
859+
860+
props->ring.buf_ev_notity++;
861+
pthread_cond_signal(&props->ring.readable);
862+
pthread_mutex_unlock(&props->ring.lock);
831863
}
832864

833865
typedef struct {

0 commit comments

Comments
 (0)