the simplest jack client

Here’s the simplest jack client ever. It is selfdocumented. It is also so simple, it’s almost maddening. Maybe that’s why people like jack. The client registers with jack, creates an output port and writes zeros to it :)

First the code without any comments. See below this one for the commented version.

  1. #include <signal .h>
  2. #include <unistd .h>
  3. #include <stdio .h>
  4.  
  5. jack_client_t *client;
  6. jack_port_t   *port;
  7.  
  8. int process(jack_nframes_t nframes, void *arg) {
  9.         int index;
  10.        
  11.         float *buffer = jack_port_get_buffer(port, nframes);
  12.  
  13.         for (index = 0; index < nframes; ++index) {
  14.                 buffer[index] = 0;
  15.         }
  16.        
  17.         return 1;
  18. }
  19.  
  20. int quit = 0;
  21.  
  22. void signalled(int signal) {
  23.         quit = 1;
  24. }
  25.  
  26. int main() {
  27.         signal(SIGINT, signalled);
  28.  
  29.         client = jack_client_new(“foobar”);
  30.         if (!client) {
  31.                 printf(“couldn’t connect to jack server. Either it’s not running or the client name is already taken\n);
  32.                 exit(1);
  33.         }
  34.  
  35.         port = jack_port_register(client, “output”, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput|JackPortIsTerminal, 0);
  36.  
  37.         jack_set_process_callback(client, process, 0);
  38.  
  39.         jack_activate(client);
  40.        
  41.         while(!quit)
  42.                 sleep(1);
  43.        
  44.         jack_deactivate(client);
  45.  
  46.         jack_client_close(client);
  47.  
  48.         return 0;
  49. }

The same code with some comments:

  1. #include <signal .h>
  2. #include <unistd .h>
  3. #include <stdio .h>
  4.  
  5. jack_client_t *client;
  6. jack_port_t   *port;
  7.  
  8. /* this is the heart of the client. the process callback.
  9. * this will be called by jack every process cycle.
  10. * jack provides us with a buffer for out output port,
  11. * which we can happily write into. inthis case we just
  12. * fill it with 0’s to produce…. silence! not to bad, eh? */
  13. int process(jack_nframes_t nframes, void *arg) {
  14.         int index;
  15.        
  16.         /* this function returns a pointer to the buffer where
  17.      * we can write our frames samples */
  18.         float *buffer = jack_port_get_buffer(port, nframes);
  19.  
  20.         /* so we do it :) */
  21.         for (index = 0; index < nframes; ++index) {
  22.                 buffer[index] = 0;
  23.         }
  24.        
  25.         return 1;
  26. }
  27.  
  28. /* a flag which will be set by our signal handler when
  29. * it’s time to exit */
  30. int quit = 0;
  31.  
  32. /* the signal handler */
  33. void signalled(int signal) {
  34.         quit = 1;
  35. }
  36.  
  37. int main() {
  38.         /* setup our signal handler signalled() above, so
  39.          * we can exit cleanly (see end of main()) */
  40.         signal(SIGINT, signalled);
  41.  
  42.  
  43.         /* naturally we need to become a jack client :) */
  44.         client = jack_client_new(“foobar”);
  45.         if (!client) {
  46.                 printf(“couldn’t connect to jack server. Either it’s not running or the client name is already taken\n);
  47.                 exit(1);
  48.         }
  49.  
  50.         /* we register an output port and tell jack it’s a
  51.          * terminal port which means we don’t
  52.          * have any input ports from which we could somhow
  53.          * feed our output */
  54.         port = jack_port_register(client, “output”, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput|JackPortIsTerminal, 0);
  55.  
  56.         /* jack is callback based. That means we register
  57.          * a callback function (see process() above)
  58.          * which will then get called by jack once per process cycle */
  59.         jack_set_process_callback(client, process, 0);
  60.  
  61.         /* tell jack that we are ready to do our thing */
  62.         jack_activate(client);
  63.        
  64.         /* wait until this app receives a SIGINT (i.e. press
  65.          * ctrl-c in the terminal) see signalled() above */
  66.         while(!quit)
  67.                 /* let’s not waste cycles by busy waiting */
  68.                 sleep(1);
  69.        
  70.         /* so we shall quit, eh? ok, cleanup time. otherwise
  71.          * jack would probably produce an xrun
  72.          * on shutdown */
  73.         jack_deactivate(client);
  74.  
  75.         /* shutdown cont. */
  76.         jack_client_close(client);
  77.  
  78.         /* done !! */
  79.         return 0;
  80. }

Leave a Reply