jack2 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.

164 lines
3.2KB

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <unistd.h>
  4. #include <assert.h>
  5. #include <jack/jack.h>
  6. #include <jack/midiport.h>
  7. #ifndef WIN32
  8. #include <signal.h>
  9. #endif
  10. static jack_port_t* port;
  11. static int keeprunning = 1;
  12. static int time_format = 0;
  13. static uint64_t monotonic_cnt = 0;
  14. static uint64_t prev_event = 0;
  15. static void
  16. describe (jack_midi_event_t* event, char* buffer, size_t buflen)
  17. {
  18. assert (buflen > 0);
  19. buffer[0] = '\0';
  20. if (event->size == 0) {
  21. return;
  22. }
  23. int type = event->buffer[0] & 0xf0;
  24. int channel = event->buffer[0] & 0xf;
  25. switch (type) {
  26. case 0x90:
  27. assert (event->size == 3);
  28. snprintf (buffer, buflen, "note on (channel %d): pitch %d, velocity %d", channel, event->buffer[1], event->buffer[2]);
  29. break;
  30. case 0x80:
  31. assert (event->size == 3);
  32. snprintf (buffer, buflen, "note off (channel %d): pitch %d, velocity %d", channel, event->buffer[1], event->buffer[2]);
  33. break;
  34. case 0xb0:
  35. assert (event->size == 3);
  36. snprintf (buffer, buflen, "control change (channel %d): controller %d, value %d", channel, event->buffer[1], event->buffer[2]);
  37. break;
  38. default:
  39. break;
  40. }
  41. }
  42. int
  43. process (jack_nframes_t frames, void* arg)
  44. {
  45. void* buffer;
  46. jack_nframes_t N;
  47. jack_nframes_t i;
  48. char description[256];
  49. buffer = jack_port_get_buffer (port, frames);
  50. assert (buffer);
  51. N = jack_midi_get_event_count (buffer);
  52. for (i = 0; i < N; ++i) {
  53. jack_midi_event_t event;
  54. int r;
  55. r = jack_midi_event_get (&event, buffer, i);
  56. if (r == 0) {
  57. size_t j;
  58. switch(time_format) {
  59. case 1:
  60. printf ("%7"PRId64":", event.time + monotonic_cnt);
  61. break;
  62. case 2:
  63. printf ("%+6"PRId64":", event.time + monotonic_cnt - prev_event);
  64. break;
  65. default:
  66. printf ("%4d:", event.time);
  67. break;
  68. }
  69. for (j = 0; j < event.size; ++j) {
  70. printf (" %x", event.buffer[j]);
  71. }
  72. describe (&event, description, sizeof (description));
  73. printf (" %s", description);
  74. printf ("\n");
  75. prev_event = event.time + monotonic_cnt;
  76. }
  77. }
  78. monotonic_cnt += frames;
  79. return 0;
  80. }
  81. static void wearedone(int sig) {
  82. keeprunning = 0;
  83. }
  84. int
  85. main (int argc, char* argv[])
  86. {
  87. jack_client_t* client;
  88. char const default_name[] = "midi-monitor";
  89. char const * client_name;
  90. int r;
  91. int cn = 1;
  92. if (argc > 1) {
  93. if (!strcmp(argv[1], "-a")) { time_format = 1; cn = 2; }
  94. if (!strcmp(argv[1], "-r")) { time_format = 2; cn = 2; }
  95. }
  96. if (argc > cn) {
  97. client_name = argv[cn];
  98. } else {
  99. client_name = default_name;
  100. }
  101. client = jack_client_open (client_name, JackNullOption, NULL);
  102. if (client == NULL) {
  103. fprintf (stderr, "Could not create JACK client.\n");
  104. exit (EXIT_FAILURE);
  105. }
  106. jack_set_process_callback (client, process, 0);
  107. port = jack_port_register (client, "input", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
  108. if (port == NULL) {
  109. fprintf (stderr, "Could not register port.\n");
  110. exit (EXIT_FAILURE);
  111. }
  112. r = jack_activate (client);
  113. if (r != 0) {
  114. fprintf (stderr, "Could not activate client.\n");
  115. exit (EXIT_FAILURE);
  116. }
  117. #ifndef WIN32
  118. signal(SIGHUP, wearedone);
  119. signal(SIGINT, wearedone);
  120. #endif
  121. /* run until interrupted */
  122. while (keeprunning) {
  123. #ifdef WIN32
  124. Sleep(1000);
  125. #else
  126. sleep(1);
  127. #endif
  128. };
  129. jack_deactivate (client);
  130. jack_client_close (client);
  131. return 0;
  132. }