All of lore.kernel.org
 help / color / mirror / Atom feed
* (no subject)
@ 2018-01-24 12:00 twischer
  2018-01-24 12:00 ` [PATCH - JACK PCM plugin 4/7] jack: Use ALSA data type for internal hardware pointer twischer
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: twischer @ 2018-01-24 12:00 UTC (permalink / raw)
  To: patch; +Cc: alsa-devel

The following patch set will extend the JACK plugin to detect Xruns
and signal them to the user application.

This patch set is depending on
http://mailman.alsa-project.org/pipermail/alsa-devel/2018-January/130987.html

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH - JACK PCM plugin 4/7] jack: Use ALSA data type for internal hardware pointer
  2018-01-24 12:00 (no subject) twischer
@ 2018-01-24 12:00 ` twischer
  2018-01-24 12:00 ` [PATCH - JACK PCM plugin 5/7] jack: Use internal snd_pcm_state to reduce amount of additional variables twischer
  2018-01-24 12:00 ` [PATCH - JACK PCM plugin 6/7] jack: Report Xruns to user application twischer
  2 siblings, 0 replies; 4+ messages in thread
From: twischer @ 2018-01-24 12:00 UTC (permalink / raw)
  To: patch; +Cc: Timo Wischer, alsa-devel

From: Timo Wischer <twischer@de.adit-jv.com>

to avoid issues with different architetures where
sizeof(unsigned int) != sizeof(snd_pcm_uframes_t)

Additionally the type describes the unit
of the variable, now.

Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>

diff --git a/jack/pcm_jack.c b/jack/pcm_jack.c
index a4f35f4..53192dc 100644
--- a/jack/pcm_jack.c
+++ b/jack/pcm_jack.c
@@ -41,7 +41,7 @@ typedef struct {
 	char **port_names;
 	unsigned int num_ports;
 	snd_pcm_uframes_t boundary;
-	unsigned int hw_ptr;
+	snd_pcm_uframes_t hw_ptr;
 	unsigned int sample_bits;
 	snd_pcm_uframes_t min_avail;
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH - JACK PCM plugin 5/7] jack: Use internal snd_pcm_state to reduce amount of additional variables
  2018-01-24 12:00 (no subject) twischer
  2018-01-24 12:00 ` [PATCH - JACK PCM plugin 4/7] jack: Use ALSA data type for internal hardware pointer twischer
@ 2018-01-24 12:00 ` twischer
  2018-01-24 12:00 ` [PATCH - JACK PCM plugin 6/7] jack: Report Xruns to user application twischer
  2 siblings, 0 replies; 4+ messages in thread
From: twischer @ 2018-01-24 12:00 UTC (permalink / raw)
  To: patch; +Cc: Timo Wischer, alsa-devel

From: Timo Wischer <twischer@de.adit-jv.com>

This variable will be used to exchange the status of the stream between
the ALSA and JACK thread.
In future commits it will also be used
to signal DRAINING state from the ALSA to JACK thread and
to signal XRUN state form the JACK to ALSA thread

Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>

diff --git a/jack/pcm_jack.c b/jack/pcm_jack.c
index 53192dc..a42c8b5 100644
--- a/jack/pcm_jack.c
+++ b/jack/pcm_jack.c
@@ -36,7 +36,11 @@ typedef struct {
 	snd_pcm_ioplug_t io;
 
 	int fd;
-	int activated;		/* jack is activated? */
+
+	/* This variable is not always in sync with io->state
+	 * because it will be accessed by multiple threads.
+	 */
+	snd_pcm_state_t state;
 
 	char **port_names;
 	unsigned int num_ports;
@@ -122,8 +126,8 @@ static int pcm_poll_block_check(snd_pcm_ioplug_t *io)
 	snd_pcm_sframes_t avail;
 	snd_pcm_jack_t *jack = io->private_data;
 
-	if (io->state == SND_PCM_STATE_RUNNING ||
-	    (io->state == SND_PCM_STATE_PREPARED && io->stream == SND_PCM_STREAM_CAPTURE)) {
+	if (jack->state == SND_PCM_STATE_RUNNING ||
+	    (jack->state == SND_PCM_STATE_PREPARED && io->stream == SND_PCM_STREAM_CAPTURE)) {
 		avail = snd_pcm_avail_update(io->pcm);
 		if (avail >= 0 && avail < jack->min_avail) {
 			while (read(io->poll_fd, &buf, sizeof(buf)) == sizeof(buf))
@@ -227,7 +231,7 @@ snd_pcm_jack_process_cb(jack_nframes_t nframes, snd_pcm_ioplug_t *io)
 	}
 
 	hw_ptr = jack->hw_ptr;
-	if (io->state == SND_PCM_STATE_RUNNING) {
+	if (jack->state == SND_PCM_STATE_RUNNING) {
 		const snd_pcm_channel_area_t *areas = snd_pcm_ioplug_mmap_areas(io);
 
 		while (xfer < nframes) {
@@ -307,29 +311,31 @@ static int snd_pcm_jack_prepare(snd_pcm_ioplug_t *io)
 	else
 		pcm_poll_block_check(io); /* block capture pcm if that's XRUN recovery */
 
-	if (jack->ports)
-		return 0;
+	if (!jack->ports) {
+		jack->ports = calloc(io->channels, sizeof(jack_port_t*));
 
-	jack->ports = calloc(io->channels, sizeof(jack_port_t*));
-
-	for (i = 0; i < io->channels; i++) {
-		char port_name[32];
-		if (io->stream == SND_PCM_STREAM_PLAYBACK) {
+		for (i = 0; i < io->channels; i++) {
+			char port_name[32];
+			if (io->stream == SND_PCM_STREAM_PLAYBACK) {
 
-			sprintf(port_name, "out_%03d", i);
-			jack->ports[i] = jack_port_register(jack->client, port_name,
-							    JACK_DEFAULT_AUDIO_TYPE,
-							    JackPortIsOutput, 0);
-		} else {
-			sprintf(port_name, "in_%03d", i);
-			jack->ports[i] = jack_port_register(jack->client, port_name,
-							    JACK_DEFAULT_AUDIO_TYPE,
-							    JackPortIsInput, 0);
+				sprintf(port_name, "out_%03d", i);
+				jack->ports[i] = jack_port_register(jack->client, port_name,
+								    JACK_DEFAULT_AUDIO_TYPE,
+								    JackPortIsOutput, 0);
+			} else {
+				sprintf(port_name, "in_%03d", i);
+				jack->ports[i] = jack_port_register(jack->client, port_name,
+								    JACK_DEFAULT_AUDIO_TYPE,
+								    JackPortIsInput, 0);
+			}
 		}
+
+		jack_set_process_callback(jack->client,
+					  (JackProcessCallback)snd_pcm_jack_process_cb, io);
 	}
 
-	jack_set_process_callback(jack->client,
-				  (JackProcessCallback)snd_pcm_jack_process_cb, io);
+	jack->state = SND_PCM_STATE_PREPARED;
+
 	return 0;
 }
 
@@ -337,12 +343,11 @@ static int snd_pcm_jack_start(snd_pcm_ioplug_t *io)
 {
 	snd_pcm_jack_t *jack = io->private_data;
 	unsigned int i;
+	int err = 0;
 	
 	if (jack_activate (jack->client))
 		return -EIO;
 
-	jack->activated = 1;
-
 	for (i = 0; i < io->channels && i < jack->num_ports; i++) {
 		if (jack->port_names[i]) {
 			const char *src, *dst;
@@ -355,21 +360,27 @@ static int snd_pcm_jack_start(snd_pcm_ioplug_t *io)
 			}
 			if (jack_connect(jack->client, src, dst)) {
 				fprintf(stderr, "cannot connect %s to %s\n", src, dst);
-				return -EIO;
+				err = -EIO;
+				break;
 			}
 		}
 	}
+
+	/* do not start forwarding audio samples before the ports are connected */
+	jack->state = SND_PCM_STATE_RUNNING;
 	
-	return 0;
+	return err;
 }
 
 static int snd_pcm_jack_stop(snd_pcm_ioplug_t *io)
 {
 	snd_pcm_jack_t *jack = io->private_data;
-	
-	if (jack->activated) {
+	const snd_pcm_state_t state = jack->state;
+
+	if (state == SND_PCM_STATE_RUNNING ||
+	    state == SND_PCM_STATE_DRAINING ||
+	    state == SND_PCM_STATE_XRUN) {
 		jack_deactivate(jack->client);
-		jack->activated = 0;
 	}
 #if 0
 	unsigned i;
@@ -380,6 +391,9 @@ static int snd_pcm_jack_stop(snd_pcm_ioplug_t *io)
 		}
 	}
 #endif
+
+	jack->state = SND_PCM_STATE_SETUP;
+
 	return 0;
 }
 
@@ -491,6 +505,7 @@ static int snd_pcm_jack_open(snd_pcm_t **pcmp, const char *name,
 
 	jack->fd = -1;
 	jack->io.poll_fd = -1;
+	jack->state = SND_PCM_STATE_OPEN;
 
 	err = parse_ports(jack, stream == SND_PCM_STREAM_PLAYBACK ?
 			  playback_conf : capture_conf);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH - JACK PCM plugin 6/7] jack: Report Xruns to user application
  2018-01-24 12:00 (no subject) twischer
  2018-01-24 12:00 ` [PATCH - JACK PCM plugin 4/7] jack: Use ALSA data type for internal hardware pointer twischer
  2018-01-24 12:00 ` [PATCH - JACK PCM plugin 5/7] jack: Use internal snd_pcm_state to reduce amount of additional variables twischer
@ 2018-01-24 12:00 ` twischer
  2 siblings, 0 replies; 4+ messages in thread
From: twischer @ 2018-01-24 12:00 UTC (permalink / raw)
  To: patch; +Cc: Timo Wischer, alsa-devel

From: Timo Wischer <twischer@de.adit-jv.com>

Only increasing the hw_ptr is not sufficient
because it will not be evaluated by the ALSA library
to detect an Xrun.

In addition there is a raise where and Xrun detected by the JACK thread
could not be detected in the ALSA thread.
- In playback use case
- The hw_ptr will be increased by the JACK thread (hw_ptr > appl_ptr =>
over run)
- But the ALSA thread increases the appl_ptr before evaluating the
hw_ptr
- Therefore the hw_ptr < appl_ptr again
- ALSA will not detect the over run which was already detected by the
JACK thread

Therefore an additional variable is required to report an Xrun from the
JACK thread to ALSA.

Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>

diff --git a/jack/pcm_jack.c b/jack/pcm_jack.c
index a42c8b5..e75aadc 100644
--- a/jack/pcm_jack.c
+++ b/jack/pcm_jack.c
@@ -198,6 +198,17 @@ static snd_pcm_sframes_t snd_pcm_jack_pointer(snd_pcm_ioplug_t *io)
 {
 	snd_pcm_jack_t *jack = io->private_data;
 
+#ifdef TEST_SIMULATE_XRUNS
+	static int i=0;
+	if (++i > 1000) {
+		i = 0;
+		return -EPIPE;
+	}
+#endif
+
+	if (jack->state == SND_PCM_STATE_XRUN)
+		return -EPIPE;
+
 	/* ALSA library is calulating the delta between the last pointer and
 	 * the current one.
 	 * Normally it is expecting a value between 0 and buffer_size.
@@ -278,6 +289,25 @@ snd_pcm_jack_process_cb(jack_nframes_t nframes, snd_pcm_ioplug_t *io)
 			for (channel = 0; channel < io->channels; channel++)
 				snd_pcm_area_silence(&jack->areas[channel], xfer, samples, io->format);
 		}
+
+		if (io->stream == SND_PCM_STREAM_PLAYBACK &&
+		    jack->state == SND_PCM_STATE_PREPARED) {
+			/* After activating this JACK client with
+			 * jack_activate() this process callback will be called.
+			 * But the processing of snd_pcm_jack_start() would take
+			 * a while longer due to the jack_connect() calls.
+			 * Therefore the device was already started
+			 * but it is not yet in RUNNING state.
+			 * Due to this expected behaviour it is not an under run.
+			 * In Capture use case the buffer should be filled
+			 * and if the application is not fast enough
+			 * to read the data in the buffer
+			 * it is a valid over run.
+			 */
+		} else {
+			/* report Xrun to user application */
+			jack->state = SND_PCM_STATE_XRUN;
+		}
 	}
 
 	pcm_poll_unblock_check(io); /* unblock socket for polling if needed */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2018-01-24 12:00 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-01-24 12:00 (no subject) twischer
2018-01-24 12:00 ` [PATCH - JACK PCM plugin 4/7] jack: Use ALSA data type for internal hardware pointer twischer
2018-01-24 12:00 ` [PATCH - JACK PCM plugin 5/7] jack: Use internal snd_pcm_state to reduce amount of additional variables twischer
2018-01-24 12:00 ` [PATCH - JACK PCM plugin 6/7] jack: Report Xruns to user application twischer

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.