BEGIN_JUCE_NAMESPACE

//==============================================================================
LashManager::LashManager (AudioProcessor* filter_)
  : filter (filter_),
    client (0)
{
    int argc = 0;
    char** argv = 0;

    if (filter)
    {
        client = lash_init (lash_extract_args(&argc, &argv),
                            filter->getName(),
                            LASH_Config_File,
                            LASH_PROTOCOL(2, 0));

        if (client)
        {
            lash_event_t* event;

            event = lash_event_new_with_type (LASH_Client_Name);
            lash_event_set_string (event, filter->getName());
            lash_send_event ((lash_client_t*) client, event);

            event = lash_event_new_with_type (LASH_Jack_Client_Name);
            lash_event_set_string (event, filter->getName());
            lash_send_event ((lash_client_t*) client, event);

            startTimer (1000 / 2);
        }
    }
}
Example #2
0
void
lash::handle_event(lash_event_t* ev)
{
    LASH_Event_Type type   = lash_event_get_type(ev);
    const char      *c_str = lash_event_get_string(ev);
    std::string     str    = (c_str == NULL) ? "" : c_str;

    if (type == LASH_Save_File)
    {
        midifile f(str + "/seq32.mid");
        f.write(m_perform, c_no_export_sequence);
        lash_send_event(m_client, lash_event_new_with_type(LASH_Save_File));
    }
    else if (type == LASH_Restore_File)
    {
        midifile f(str + "/seq32.mid");
        f.parse(m_perform, m_mainwnd, 0 );
        lash_send_event(m_client, lash_event_new_with_type(LASH_Restore_File));
    }
    else if (type == LASH_Quit)
    {
        m_client = NULL;
        Gtk::Main::quit();
    }
    else
    {
        fprintf(stderr, "Warning:  Unhandled LASH event.\n");
    }
}
//==============================================================================
void LashManager::timerCallback()
{
    if (! client || ! filter)
        return;

    lash_event_t* event;

    while ((event = lash_get_event ((lash_client_t*) client)) != 0)
    {
        String eventString (lash_event_get_string (event));
        
        switch (lash_event_get_type (event))
        {
        case LASH_Save_File:
            printf ("Asked to save data in %s\n", (const char*) eventString);
            saveState (File (eventString + "/" + filter->getName () + ".lash"));
            lash_send_event ((lash_client_t*) client, lash_event_new_with_type (LASH_Save_File));
            break;

        case LASH_Restore_File:
            printf ("Asked to restore data from %s\n", (const char*) eventString);
            loadState (File (eventString + "/" + filter->getName () + ".lash"));
            lash_send_event ((lash_client_t*) client, lash_event_new_with_type (LASH_Restore_File));
            break;

        case LASH_Quit:
            printf ("Asked to quit !\n");
            stopTimer ();
            break;

        case LASH_Server_Lost:
            printf ("Server lost !\n");
            stopTimer ();
            lash_event_destroy (event);
            return;

        default:
            printf("Got unhandled LADCCA event\n");
            break;
        }
        
        lash_event_destroy (event);
    }

/*
    while ((config = lash_get_config(client)) != 0)
    {
        printf ("Unexpected LASH config: %s\n", lash_config_get_key(config));

        lash_config_free(config);
        free(config);
        config = 0;
    }
*/
}
Example #4
0
/** process any queued events */
void
Lash::process ( void )
{
    lash_event_t *e;

    char *name;

    while ( ( e = lash_get_event( _client ) ) )
    {
        asprintf( &name, "%s/%s", lash_event_get_string( e ), "song.non" );

        const int t = lash_event_get_type ( e );

        switch ( t )
        {
            case LASH_Save_File:
            {
                MESSAGE( "LASH wants us to save \"%s\"", name );

                save_song( name );

                lash_send_event( _client, lash_event_new_with_type( LASH_Save_File ) );

                break;

            }
            case LASH_Restore_File:
            {
                MESSAGE( "LASH wants us to load \"%s\"", name );

                if ( ! load_song( name ) )
                    /* FIXME: should we tell lash that we couldn't load the song? */;

                lash_send_event( _client, lash_event_new_with_type( LASH_Restore_File ) );

                break;
            }
            case LASH_Quit:
                MESSAGE( "LASH wants us to quit" );
                quit();
                break;
            default:
                WARNING( "unhandled LASH event (%d)", t );
        }

        lash_event_destroy( e );
    }
}
Example #5
0
PRIVATE void clock_handler(AClock *clock, AClockReason reason) {

    switch (reason) {
	case CLOCK_DISABLE:
	    jack_deactivate( jack_client );
	    break;

	case CLOCK_ENABLE:
	    jack_set_process_callback( jack_client, (JackProcessCallback) process_callback, NULL ); 
	    jack_on_shutdown (jack_client, jack_shutdown, 0);

	    jack_activate( jack_client );

	    lash_event_t *event;
	    if( lash_enabled( galan_lash_get_client() ) ) {
		event = lash_event_new_with_type(LASH_Jack_Client_Name);
		lash_event_set_string(event, jack_get_client_name( jack_client ) );
		lash_send_event( galan_lash_get_client(), event);
	    }
	    break;

	default:
	    g_message("Unreachable code reached (jack_output)... reason = %d", reason);
	    break;
    }
}
void
init_jack (void)
{
   int err;

#ifdef WITH_LASH
   lash_event_t *event;
#endif

   jack_client = jack_client_open(PROGRAM_NAME, JackNullOption, NULL);

   if (jack_client == NULL)
   {
      g_critical("Could not connect to the JACK server; run jackd first?");
      exit(EX_UNAVAILABLE);
   }

#ifdef WITH_LASH
   event = lash_event_new_with_type(LASH_Client_Name);
// assert(event); /* Documentation does not say anything about return value. */
   lash_event_set_string(event, jack_get_client_name(jack_client));
   lash_send_event(lash_client, event);
   lash_jack_client_name(lash_client, jack_get_client_name(jack_client));
#endif

   err = jack_set_process_callback(jack_client, process_callback, 0);
   if (err)
   {
      g_critical("Could not register JACK process callback.");
      exit(EX_UNAVAILABLE);
   }

   /*
    * The above is pretty close to COMMON CODE.
    */

   input_port = jack_port_register
   (
      jack_client, INPUT_PORT_NAME, JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0
   );
   if (input_port == NULL)
   {
      g_critical("Could not register JACK input port.");
      exit(EX_UNAVAILABLE);
   }

   if (jack_activate(jack_client)) {
      g_critical("Cannot activate JACK client.");
      exit(EX_UNAVAILABLE);
   }
}
Example #7
0
int lash_pollevent()
{
    if (!lash_enabled(lash_client))
        return -1;

    lash_event_t *event;
    char *l_path;
    while (event = lash_get_event(lash_client)) {
        if (lash_event_get_type(event) == LASH_Save_File) {
            lash_buffer = (char *)lash_event_get_string(event);
            l_path = (char *)malloc(strlen(lash_buffer) + 13);
            sprintf(l_path, "%s/phasex.phx", lash_buffer);
            save_patch(l_path, 0);
            sprintf(l_path, "%s/phasex.map", lash_buffer);
            save_midimap(l_path);
            lash_send_event(lash_client, lash_event_new_with_type(LASH_Save_File));
            free(l_path);
            break;
        }
        else if (lash_event_get_type(event) == LASH_Restore_File) {
            lash_buffer = (char *)lash_event_get_string(event);
            l_path = (char *)malloc(strlen(lash_buffer) + 13);
            sprintf(l_path, "%s/phasex.phx", lash_buffer);
            read_patch(l_path, 0);
            sprintf(l_path, "%s/phasex.map", lash_buffer);
            read_midimap(l_path);
            lash_send_event(lash_client, lash_event_new_with_type(LASH_Restore_File));
            free(l_path);
            break;
        }
        else if (lash_event_get_type(event) == LASH_Quit) {
            shutdown = 1;
            break;
        }
        lash_event_destroy(event);
    }
    return 0;
}
Example #8
0
lash::lash(int *argc, char ***argv)
{
#ifdef LASH_SUPPORT
    m_client = lash_init(lash_extract_args(argc, argv), PACKAGE_NAME,
        LASH_Config_File, LASH_PROTOCOL(2, 0));
    if (m_client == NULL) {
        fprintf(stderr, "Failed to connect to LASH.  Session management will not occur.\n");
    } else {
        lash_event_t* event = lash_event_new_with_type(LASH_Client_Name);
        lash_event_set_string(event, "Seq24");
        lash_send_event(m_client, event);
        printf("[Connected to LASH]\n");
    }
#endif // LASH_SUPPORT
}
Example #9
0
int lash_clinit(int argc, char** argv, jack_client_t *jack_client, snd_seq_t *alsa_handle)
{
    lash_jackname = jack_get_client_name(jack_client);
    lash_client = lash_init(lash_extract_args(&argc, &argv), lash_jackname, LASH_Config_File, LASH_PROTOCOL(2, 0));
    if (lash_enabled(lash_client)) 
    {
        lash_jack_client_name(lash_client, lash_jackname);
        lash_event_t *event = lash_event_new_with_type(LASH_Client_Name);
        lash_event_set_string(event, lash_jackname);
        lash_send_event(lash_client, event);
        lash_alsaid = alsa_handle;
        lash_alsa_client_id(lash_client, (unsigned char)snd_seq_client_id(alsa_handle));
        return 0;
    }
    return -1;
}
Example #10
0
bool
Lash::init ( int *argc, char ***argv, const char *jack_name )
{
    MESSAGE( "Initializing LASH" );

    if ( ! ( _client = lash_init( lash_extract_args( argc, argv ), APP_NAME,
                                  LASH_Config_File, LASH_PROTOCOL( 2, 0 ) ) ) )
        return false;

    /* register name */
    lash_jack_client_name( _client, jack_name );

    lash_event_t *e = lash_event_new_with_type( LASH_Client_Name );
    lash_event_set_string( e, APP_TITLE );
    lash_send_event( _client, e );

    return true;
}
Example #11
0
static void *
fluid_lash_run (void * data)
{
  lash_event_t * event;
  lash_config_t * config;
  fluid_synth_t * synth;
  int done = 0;
  int err;
  int pending_restores = 0;

  synth = (fluid_synth_t *) data;

  while (!done)
    {
      while ( (event = lash_get_event (fluid_lash_client)) )
        {
          switch (lash_event_get_type (event))
            {
            case LASH_Save_Data_Set:
              fluid_lash_save (synth);
              lash_send_event (fluid_lash_client, event);
              break;
            case LASH_Restore_Data_Set:
              lash_event_destroy (event);
              break;
            case LASH_Quit:
	      err = kill (getpid(), SIGQUIT);
	      if (err)
		fprintf (stderr, "%s: error sending signal: %s",
			 __FUNCTION__, strerror (errno));
	      lash_event_destroy (event);
	      done = 1;
	      break;
	    case LASH_Server_Lost:
	      lash_event_destroy (event);
	      done = 1;
	      break;
            default:
              fprintf (stderr, "Recieved unknown LASH event of type %d\n", lash_event_get_type (event));
	      lash_event_destroy (event);
	      break;
            }
        }

      while ( (config = lash_get_config (fluid_lash_client)) )
        {
	  if (strcmp (lash_config_get_key (config), "soundfont count") == 0)
	      pending_restores = lash_config_get_value_int (config);
	  else
	    {
              fluid_lash_load (synth, lash_config_get_value_string (config));
	      pending_restores--;
	    }
          lash_config_destroy (config);

	  if (!pending_restores)
	    {
	      event = lash_event_new_with_type (LASH_Restore_Data_Set);
	      lash_send_event (fluid_lash_client, event);
	    }
        }

      usleep (10000);
    }

  return NULL;
}
Example #12
0
int main(int argc, char *argv[])
{
    unsigned int i;
    int opt;
    int help = 0;
    int console = 0;
    char port_name[32];
    pthread_t dt;
#ifdef HAVE_LASH
    lash_args_t *lash_args = lash_extract_args(&argc, &argv);
     lash_event_t *event;
#endif

    auto_begin_threshold = db2lin(DEFAULT_AUTO_BEGIN_THRESHOLD);
    auto_end_threshold = db2lin(DEFAULT_AUTO_END_THRESHOLD);

    while ((opt = getopt(argc, argv, "hic:t:n:p:f:sab:e:T:")) != -1) {
	switch (opt) {
	case 'h':
	    help = 1;
	    break;
	case 'i':
	    console = 1;
	    break;
	case 'c':
	    num_ports = atoi(optarg);
	    DEBUG(1, "ports: %d\n", num_ports);
	    break;
	case 't':
	    buf_length = atoi(optarg);
	    DEBUG(1, "buffer: %ds\n", buf_length);
	    break;
	case 'n':
	    client_name = optarg;
	    DEBUG(1, "client name: %s\n", client_name);
	    break;
	case 'p':
	    prefix = optarg;
	    DEBUG(1, "prefix: %s\n", prefix);
	    break;
	case 'f':
	    format_name = optarg;
	    break;
	case 's':
	    safe_filename = 1;
	    break;
	case 'a':
	    auto_record = 1;
	    break;
	case 'b':
	    auto_begin_threshold = db2lin(atof(optarg));
	    break;
	case 'e':
	    auto_end_threshold = db2lin(atof(optarg));
	    break;
	case 'T':
	    auto_end_time = atoi(optarg);
	    break;
	default:
	    num_ports = 0;
	    break;
	}
    }

    if (optind != argc) {
	num_ports = argc - optind;
    }

    if (num_ports < 1 || num_ports > MAX_PORTS || help) {
	fprintf(stderr, "Usage %s: [-h] [-i] [-c channels] [-n jack-name]\n\t"
			"[-t buffer-length] [-p file prefix] [-f format]\n\t"
			"[-a] [-b begin-threshold] [-e end-threshold] [-T end-time]\n\t"
			"[port-name ...]\n\n", argv[0]);
	fprintf(stderr, "\t-h\tshow this help\n");
	fprintf(stderr, "\t-i\tinteractive mode (console instead of X11) also enabled\n\t\tif DISPLAY is unset\n");
	fprintf(stderr, "\t-c\tspecify number of recording channels\n");
	fprintf(stderr, "\t-n\tspecify the JACK name timemachine will use\n");
	fprintf(stderr, "\t-t\tspecify the pre-recording buffer length\n");
	fprintf(stderr, "\t-p\tspecify the saved file prefix, may include path\n");
	fprintf(stderr, "\t-s\tuse safer characters in filename (windows compatibility)\n");
	fprintf(stderr, "\t-f\tspecify the saved file format\n");
	fprintf(stderr, "\t-a\tenable automatic sound-triggered recording\n");
	fprintf(stderr, "\t-b\tspecify threshold above which automatic recording will begin\n");
	fprintf(stderr, "\t-e\tspecify threshold below which automatic recording will end\n");
	fprintf(stderr, "\t-T\tspecify silence length before automatic recording ends\n");
	fprintf(stderr, "\n");
	fprintf(stderr, "\tchannels must be in the range 1-8, default %d\n",
			DEFAULT_NUM_PORTS);
	fprintf(stderr, "\tjack-name, default \"%s\"\n", DEFAULT_CLIENT_NAME);
	fprintf(stderr, "\tfile-prefix, default \"%s\"\n", DEFAULT_PREFIX);
	fprintf(stderr, "\tbuffer-length, default %d secs\n", DEFAULT_BUF_LENGTH);
	fprintf(stderr, "\tformat, default '%s', options: wav, w64\n", DEFAULT_FORMAT);
	fprintf(stderr, "\tbegin-threshold, default %.1f dB\n", DEFAULT_AUTO_BEGIN_THRESHOLD);
	fprintf(stderr, "\tend-threshold, default %.1f dB\n", DEFAULT_AUTO_END_THRESHOLD);
	fprintf(stderr, "\tend-time, default %d secs\n", DEFAULT_AUTO_END_TIME);
	fprintf(stderr, "\n");
	fprintf(stderr, "specifying port names to connect to on the command line overrides -c\n\n");
	exit(1);
    }

    if (!strcasecmp(format_name, "wav")) {
	format_sf = SF_FORMAT_WAV | SF_FORMAT_FLOAT;
    }
#ifdef HAVE_W64
    if (!strcasecmp(format_name, "w64")) {
	format_sf = SF_FORMAT_W64 | SF_FORMAT_FLOAT;
    }
#endif

    if (format_sf == 0) {
	fprintf(stderr, "Unknown format '%s'\n", format_name);
    }

    /* Register with jack */
    if ((client = jack_client_open(client_name, 0, NULL)) == 0) {
	DEBUG(0, "jack server not running?\n");
	exit(1);
    }
    DEBUG(1, "registering as %s\n", client_name);

    process_init(buf_length);

#ifdef HAVE_LASH
    lash_client = lash_init (lash_args, "TimeMachine",
                     0, /* would be LASH_Config_Data_Set etc. */
                     LASH_PROTOCOL (2,0));
    if (!lash_client) {
	DEBUG(1, "could not initialise LASH\n");
    }
    event = lash_event_new_with_type(LASH_Client_Name);
    lash_event_set_string(event, client_name);
    lash_send_event(lash_client, event);
#endif

    jack_set_process_callback(client, process, 0);

    if (jack_activate(client)) {
	DEBUG(0, "cannot activate JACK client");
	exit(1);
    }
#ifdef HAVE_LASH
    lash_jack_client_name(lash_client, client_name);
#endif

    /* Create the jack ports */
    for (i = 0; i < num_ports; i++) {
	jack_port_t *port;

	snprintf(port_name, 31, "in_%d", i + 1);
	ports[i] = jack_port_register(client, port_name,
				      JACK_DEFAULT_AUDIO_TYPE,
				      JackPortIsInput, 0);
	if (optind != argc) {
	    port = jack_port_by_name(client, argv[optind+i]);
	    if (port == NULL) {
		fprintf(stderr, "Can't find port '%s'\n", port_name);
		continue;
	    }
	    if (jack_connect(client, argv[optind+i], jack_port_name(ports[i]))) {
		fprintf(stderr, "Cannot connect port '%s' to '%s'\n",
			argv[optind+i], jack_port_name(ports[i]));
	    }
	}
    }

    /* Start the disk thread */
    pthread_create(&dt, NULL, (void *)&writer_thread, NULL);

#ifdef HAVE_LIBREADLINE
    if (console || !getenv("DISPLAY") || getenv("DISPLAY")[0] == '\0') {
#ifdef HAVE_LIBLO
      lo_server_thread st = lo_server_thread_new(OSC_PORT, NULL);
      if (st) {
	  lo_server_thread_add_method(st, "/start", "", osc_handler_nox, (void *)1);
	  lo_server_thread_add_method(st, "/stop", "", osc_handler_nox, (void *)0);
	  lo_server_thread_start(st);
	  printf("Listening for OSC requests on osc.udp://localhost:%s\n",
	    OSC_PORT);
      }
#endif

      int done = 0;
      while (!done) {
	char *line = readline("TimeMachine> ");
	if (!line) {
	  printf("EOF\n");
	  break;
	}
	if (line && *line) {
	  add_history(line);
	  if (strncmp(line, "q", 1) == 0) done = 1;
	  else if (strncmp(line, "start", 3) == 0) recording_start();
	  else if (strncmp(line, "stop", 3) == 0) recording_stop();
	  else if (strncmp(line, "help", 3) == 0) {
	    printf("Commands: start stop\n");
	  } else {
	    printf("Unknown command\n");
          }
	}
	free(line);
      }
    } else
#endif
    {
      gtk_init(&argc, &argv);

      add_pixmap_directory(PACKAGE_DATA_DIR "/" PACKAGE "/pixmaps");
      add_pixmap_directory("pixmaps");
      add_pixmap_directory("../pixmaps");

      img_on = create_pixbuf("on.png");
      img_off = create_pixbuf("off.png");
      img_busy = create_pixbuf("busy.png");
      icon_on = create_pixbuf("on-icon.png");
      icon_off = create_pixbuf("off-icon.png");

      main_window = create_window(client_name);
      gtk_window_set_icon(GTK_WINDOW(main_window), icon_off);
      gtk_widget_show(main_window);

      bind_meters();
      g_timeout_add(100, meter_tick, NULL);

#ifdef HAVE_LIBLO
    lo_server_thread st = lo_server_thread_new(OSC_PORT, NULL);
    if (st) {
	lo_server_thread_add_method(st, "/start", "", osc_handler, (void *)1);
	lo_server_thread_add_method(st, "/stop", "", osc_handler, (void *)0);
	lo_server_thread_start(st);
	printf("Listening for OSC requests on osc.udp://localhost:%s\n",
	       OSC_PORT);
    }
#endif

#ifdef HAVE_LASH
      gtk_idle_add(idle_cb, lash_client);
#endif

      gtk_main();
    }

    cleanup();

    /* We can't ever get here, but it keeps gcc quiet */
    return 0;
}
Example #13
0
int main (int argc, char ** argv) {
  unsigned long channels = 2;
  int opt;

  const char * options = "hps:ionc:tD:";

  struct option long_options[] = {
    { "help", 0, NULL, 'h' },
    { "pid-name", 0, NULL, 'p' },
    { "string-name", 1, NULL, 's' },
    { "name", 1, NULL, 'n' },
    { "channels", 1, NULL, 'c' },
    { "input", 1, NULL, 'i' },
    { "output", 1, NULL, 'o' },
    { "no-time", 0, NULL, 't' },
    { "jack-session-uuid", 1, NULL, 'U' },
    { 0, 0, 0, 0 }
  };

#ifdef HAVE_LASH
  lash_args_t * lash_args;
  lash_event_t * lash_event;
#endif  

  gtk_set_locale ();
#ifdef ENABLE_NLS
  bindtextdomain (PACKAGE, LOCALEDIR);
  bind_textdomain_codeset (PACKAGE, "UTF-8");
#endif
  
  /* not using gnome popt */
  for (opt = 1; opt < argc; opt++)
    {
      if (strcmp (argv[opt], "-h") == 0 ||
          strcmp (argv[opt], "--help") == 0)
        {
          print_help ();
          exit (0);
        }
    }


#ifdef HAVE_LASH
  lash_args = lash_extract_args (&argc, &argv);
#endif  

  gtk_init (&argc, &argv);


  /* set the client name */
  client_name = g_string_new ("");
  session_uuid = g_string_new ("");
  g_string_printf (client_name, "%s", CLIENT_NAME_BASE);
  
  while ((opt = getopt_long (argc, argv, options, long_options, NULL)) != -1) {
    switch (opt) {

      case 'h':
        print_help ();
        exit (0);
        break;

      case 's':
        g_string_printf (client_name, "%s (%s)", CLIENT_NAME_BASE, optarg);
        break;

      case 'p':
        g_string_printf (client_name, "%s (%d)", CLIENT_NAME_BASE, getpid());
        break;
      
      case 'n':
        g_string_printf (client_name, CLIENT_NAME_BASE);
        break;

      case 'i':
        connect_inputs = TRUE;
        break;

      case 'o':
        connect_outputs = TRUE;
        break;
      
      case 'c':
        channels = atof (optarg);
        if (channels < 1)
          {
            fprintf (stderr, _("There must be at least one channel\n"));
            exit (EXIT_FAILURE);
          }
        break;
      
      case 't':
        time_runs = FALSE;
        break;

      case 'U':
        g_string_printf (session_uuid, "%s", optarg);
	break;

      case ':':
      case '?':
        print_help ();
        exit (EXIT_FAILURE);
        break;
    }
  }

  if (optind < argc)
  {
    if (argc - optind > 1)
    {
      fprintf (stderr, _("Please specify only one file to open"));
      exit(EXIT_FAILURE);
    }

    initial_filename = g_string_new(argv[optind]);
  }

#ifdef HAVE_LASH
  {
    int flags = LASH_Config_File;
    global_lash_client = lash_init (lash_args, PACKAGE_NAME, flags, LASH_PROTOCOL (2,0));
  }

  if (global_lash_client)
    {
      lash_event = lash_event_new_with_type (LASH_Client_Name);
      lash_event_set_string (lash_event, client_name->str);
      lash_send_event (global_lash_client, lash_event);
    }
#endif /* HAVE_LASH */

  xmlSetCompressMode (XML_COMPRESSION_LEVEL);

  global_ui = ui_new (channels);
  if (!global_ui)
    return 1;
  
  /* ignore the sighup (the jack client thread needs to deal with it) */
  signal (SIGHUP, SIG_IGN);
  
/*  jack_activate (global_ui->procinfo->jack_client); */
  
  gtk_main ();

/*  jack_deactivate (global_ui->procinfo->jack_client); */
  
  ui_destroy (global_ui);
  
  return 0;
}
Example #14
0
static void 
init_jack(void)
{
	int i, err;

#ifdef WITH_LASH
	lash_event_t *event;
#endif

	jack_client = jack_client_open(PROGRAM_NAME, JackNoStartServer, NULL);

	if (jack_client == NULL) {
		g_critical("Could not connect to the JACK server; run jackd first?");
		exit(EX_UNAVAILABLE);
	}

#ifdef WITH_LASH
	event = lash_event_new_with_type(LASH_Client_Name);
	assert (event); /* Documentation does not say anything about return value. */
	lash_event_set_string(event, jack_get_client_name(jack_client));
	lash_send_event(lash_client, event);

	lash_jack_client_name(lash_client, jack_get_client_name(jack_client));
#endif

	err = jack_set_process_callback(jack_client, process_callback, 0);
	if (err) {
		g_critical("Could not register JACK process callback.");
		exit(EX_UNAVAILABLE);
	}

	if (use_transport) {
		err = jack_set_sync_callback(jack_client, sync_callback, 0);
		if (err) {
			g_critical("Could not register JACK sync callback.");
			exit(EX_UNAVAILABLE);
		}
#if 0
		err = jack_set_timebase_callback(jack_client, 1, timebase_callback, 0);
		if (err) {
			g_critical("Could not register JACK timebase callback.");
			exit(EX_UNAVAILABLE);
		}
#endif
	}

	jack_on_shutdown(jack_client, jack_shutdown, 0);

	int number_of_tracks;
	if (remote_control) {
		number_of_tracks = 0; // TODO allow more ports
	}
	else {
		assert(smf->number_of_tracks >= 1);
		number_of_tracks = smf->number_of_tracks;
	}

	/* We are allocating number_of_tracks + 1 output ports. */
	for (i = 0; i <= number_of_tracks; i++) {
		char port_name[32];

		if (i == 0)
			snprintf(port_name, sizeof(port_name), "midi_out");
		else
			snprintf(port_name, sizeof(port_name), "track_%d_midi_out", i);

		output_ports[i] = jack_port_register(jack_client, port_name, JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0);

		if (output_ports[i] == NULL) {
			g_critical("Could not register JACK output port '%s'.", port_name);
			exit(EX_UNAVAILABLE);
		}

		if (just_one_output)
			break;
	}

	if (jack_activate(jack_client)) {
		g_critical("Cannot activate JACK client.");
		exit(EX_UNAVAILABLE);
	}
}