jack1 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

149 lines
3.1KB

  1. #include <stdio.h>
  2. #include <errno.h>
  3. #include <unistd.h>
  4. #include <signal.h>
  5. #include <stdlib.h>
  6. #include <jack/jack.h>
  7. #include <jack/transport.h>
  8. typedef struct {
  9. volatile jack_nframes_t guard1;
  10. volatile jack_transport_info_t info;
  11. volatile jack_nframes_t guard2;
  12. } guarded_transport_info_t;
  13. guarded_transport_info_t now;
  14. jack_client_t *client;
  15. void
  16. showtime ()
  17. {
  18. guarded_transport_info_t current;
  19. int tries = 0;
  20. /* Since "now" is updated from the process() thread every
  21. * buffer period, we must copy it carefully to avoid getting
  22. * an incoherent hash of multiple versions. */
  23. do {
  24. /* Throttle the busy wait if we don't get the a clean
  25. * copy very quickly. */
  26. if (tries > 10) {
  27. usleep (20);
  28. tries = 0;
  29. }
  30. current = now;
  31. tries++;
  32. } while (current.guard1 != current.guard2);
  33. if (current.info.valid & JackTransportPosition)
  34. printf ("frame: %7lu\t", current.info.frame);
  35. else
  36. printf ("frame: [-]\t");
  37. if (current.info.valid & JackTransportState) {
  38. switch (current.info.transport_state) {
  39. case JackTransportStopped:
  40. printf ("state: Stopped\t");
  41. break;
  42. case JackTransportRolling:
  43. printf ("state: Rolling\t");
  44. break;
  45. case JackTransportLooping:
  46. printf ("state: Looping\t");
  47. break;
  48. default:
  49. printf ("state: [unknown]\t");
  50. }
  51. }
  52. else
  53. printf ("state: [-]\t");
  54. if (current.info.valid & JackTransportLoop)
  55. printf ("loop: %lu-%lu\t", current.info.loop_start,
  56. current.info.loop_end);
  57. else
  58. printf ("loop: [-]\t");
  59. if (current.info.valid & JackTransportBBT)
  60. printf ("BBT: %3d|%d|%04d\n", current.info.bar,
  61. current.info.beat, current.info.tick);
  62. else
  63. printf ("BBT: [-]\n");
  64. }
  65. int
  66. process (jack_nframes_t nframes, void *arg)
  67. {
  68. /* The guard flags contain a running counter of sufficiently
  69. * high resolution, that showtime() can detect whether the
  70. * last update is complete. */
  71. now.guard1 = jack_frame_time(client);
  72. jack_get_transport_info (client, (jack_transport_info_t *) &now.info);
  73. now.guard2 = now.guard1;
  74. return 0;
  75. }
  76. void
  77. jack_shutdown (void *arg)
  78. {
  79. exit (1);
  80. }
  81. void
  82. signal_handler (int sig)
  83. {
  84. jack_client_close (client);
  85. fprintf (stderr, "signal received, exiting ...\n");
  86. exit (0);
  87. }
  88. int
  89. main (int argc, char *argv[])
  90. {
  91. /* try to become a client of the JACK server */
  92. if ((client = jack_client_new ("showtime")) == 0) {
  93. fprintf (stderr, "jack server not running?\n");
  94. return 1;
  95. }
  96. signal (SIGQUIT, signal_handler);
  97. signal (SIGTERM, signal_handler);
  98. signal (SIGHUP, signal_handler);
  99. signal (SIGINT, signal_handler);
  100. /* tell the JACK server to call `process()' whenever
  101. there is work to be done.
  102. */
  103. jack_set_process_callback (client, process, 0);
  104. /* tell the JACK server to call `jack_shutdown()' if
  105. it ever shuts down, either entirely, or if it
  106. just decides to stop calling us.
  107. */
  108. jack_on_shutdown (client, jack_shutdown, 0);
  109. /* tell the JACK server that we are ready to roll */
  110. if (jack_activate (client)) {
  111. fprintf (stderr, "cannot activate client");
  112. return 1;
  113. }
  114. while (1) {
  115. usleep (100000);
  116. showtime ();
  117. }
  118. jack_client_close (client);
  119. exit (0);
  120. }