From 6e253b59bd7314531b4a700b0bab5781ff50fccb Mon Sep 17 00:00:00 2001 From: joq Date: Sun, 1 Jun 2003 17:46:07 +0000 Subject: [PATCH] jack_showtime fixes; transport doc clarifications git-svn-id: svn+ssh://jackaudio.org/trunk/jack@407 0c269be4-1314-0410-8aa9-9f06e86f4224 --- configure.in | 2 +- example-clients/showtime.c | 66 +++++++++++++++++++++++++++++++------- jack/transport.h | 5 +-- 3 files changed, 59 insertions(+), 14 deletions(-) diff --git a/configure.in b/configure.in index f7f8938..e623f03 100644 --- a/configure.in +++ b/configure.in @@ -14,7 +14,7 @@ dnl changes are made dnl --- JACK_MAJOR_VERSION=0 JACK_MINOR_VERSION=71 -JACK_MICRO_VERSION=5 +JACK_MICRO_VERSION=6 dnl --- dnl HOWTO: updating the jack protocal version diff --git a/example-clients/showtime.c b/example-clients/showtime.c index c6bb93c..5f43378 100644 --- a/example-clients/showtime.c +++ b/example-clients/showtime.c @@ -7,26 +7,70 @@ #include #include +typedef struct { + volatile jack_nframes_t guard1; + volatile jack_transport_info_t info; + volatile jack_nframes_t guard2; +} guarded_transport_info_t; + +guarded_transport_info_t now; jack_client_t *client; -jack_transport_info_t now; + void showtime () { - jack_transport_info_t current = now; - printf ("frame: %lu state: %d loop: %lu-%lu " - "BBT: %d|%d|%d\n", - current.frame, current.transport_state, current.loop_start, current.loop_end, - current.bar, - current.beat, - current.tick); + guarded_transport_info_t current; + int tries = 0; + + /* Since "now" is updated from the process() thread every + * buffer period, we must copy it carefully to avoid getting + * an incoherent hash of multiple versions. */ + do { + /* Throttle the busy wait if we don't get the a clean + * copy very quickly. */ + if (tries > 10) { + usleep (20); + tries = 0; + } + current = now; + tries++; + + } while (current.guard1 != current.guard2); + + if (current.info.valid & JackTransportPosition) + printf ("frame: %lu ", current.info.frame); + else + printf ("frame: [-] "); + + if (current.info.valid & JackTransportState) + printf ("state: %d ", current.info.transport_state); + else + printf ("state: [-] "); + + if (current.info.valid & JackTransportLoop) + printf ("loop: %lu-%lu ", current.info.loop_start, + current.info.loop_end); + else + printf ("loop: [-] "); + + if (current.info.valid & JackTransportBBT) + printf ("BBT: %d|%d|%d\n", current.info.bar, + current.info.beat, current.info.tick); + else + printf ("BBT: [-]\n"); } int process (jack_nframes_t nframes, void *arg) { - now.valid = JackTransportState|JackTransportPosition|JackTransportLoop; - jack_get_transport_info (client, &now); + /* The guard flags contain a running counter of sufficiently + * high resolution, that showtime() can detect whether the + * last update is complete. */ + now.guard1 = jack_frame_time(client); + jack_get_transport_info (client, &now.info); + now.guard2 = now.guard1; + return 0; } @@ -39,8 +83,8 @@ jack_shutdown (void *arg) void signal_handler (int sig) { - fprintf (stderr, "signal received, exiting ...\n"); jack_client_close (client); + fprintf (stderr, "signal received, exiting ...\n"); exit (0); } diff --git a/jack/transport.h b/jack/transport.h index 10904ca..4a7efb6 100644 --- a/jack/transport.h +++ b/jack/transport.h @@ -95,8 +95,8 @@ typedef struct { * a bitmask of all transport info fields that are set * in tinfo. * - * @pre Caller must be the current timebase master. - * + * @pre Caller must be the current timebase master. Must be called + * from the process() thread. */ void jack_set_transport_info (jack_client_t *client, jack_transport_info_t *tinfo); @@ -108,6 +108,7 @@ void jack_set_transport_info (jack_client_t *client, * a bitmask of all transport info fields that are legal to * use. * + * @pre Must be called from the process() thread. */ void jack_get_transport_info (jack_client_t *client, jack_transport_info_t *tinfo);