예제 #1
0
파일: jack.c 프로젝트: doctaweeks/rotter
// Crude way of automatically connecting up jack ports
int autoconnect_jack_ports( jack_client_t* client )
{
  const char **all_ports;
  unsigned int ch=0;
  int i;

  // Get a list of all the jack ports
  all_ports = jack_get_ports(client, NULL, NULL, JackPortIsOutput);
  if (!all_ports) {
    rotter_fatal("autoconnect_jack_ports(): jack_get_ports() returned NULL.");
    return -1;
  }

  // Step through each port name
  for (i = 0; all_ports[i]; ++i) {
    // Connect the port
    if (connect_jack_port( all_ports[i], inport[ch] )) {
      return -1;
    }

    // Found enough ports ?
    if (++ch >= channels) break;
  }

  free( all_ports );

  return 0;
}
예제 #2
0
파일: silentjack.c 프로젝트: l1n/silentjack
static
jack_client_t* init_jack( const char * client_name, const char* connect_port ) 
{
	jack_status_t status;
	jack_options_t options = JackNoStartServer;
	jack_client_t *client = NULL;

	// Register with Jack
	if ((client = jack_client_open(client_name, options, &status)) == 0) {
		fprintf(stderr, "Failed to start jack client: %d\n", status);
		exit(1);
	}
	if (!quiet) printf("JACK client registered as '%s'.\n", jack_get_client_name( client ) );

	// Create our pair of output ports
	if (!(input_port = jack_port_register(client, "in", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0))) {
		fprintf(stderr, "Cannot register input port 'in'.\n");
		exit(1);
	}
	
	// Register shutdown callback
	jack_on_shutdown (client, shutdown_callback_jack, NULL );

	// Register the peak audio callback
	jack_set_process_callback(client, process_peak, 0);

	// Activate the client
	if (jack_activate(client)) {
		fprintf(stderr, "Cannot activate client.\n");
		exit(1);
	}
	
	// Connect up our input port ?
	if (connect_port) {
		connect_jack_port( client, input_port, connect_port );
	}
	
	return client;
}
예제 #3
0
int main(int argc, char *argv[])
{
  int autoconnect = 0;
  jack_options_t jack_opt = JackNullOption;
  char *client_name = DEFAULT_CLIENT_NAME;
  char *connect_left = NULL;
  char *connect_right = NULL;
  const char *format_name = NULL;
  int bitrate = DEFAULT_BITRATE;
  int sync_period = DEFAULT_SYNC_PERIOD;
  float sleep_time = 0;
  time_t next_sync = 0;
  int i,opt;

  // Make STDOUT unbuffered
  setbuf(stdout, NULL);

  // Parse Switches
  while ((opt = getopt(argc, argv, "al:r:n:N:O:p:jf:b:Q:d:c:R:L:s:uvqh")) != -1) {
    switch (opt) {
      case 'a':  autoconnect = 1; break;
      case 'l':  connect_left = optarg; break;
      case 'r':  connect_right = optarg; break;
      case 'n':  client_name = optarg; break;
      case 'N':  archive_name = optarg; break;
      case 'O':  originator = strdup(optarg); break;
      case 'p':  archive_period_seconds = atol(optarg); break;
      case 'j':  jack_opt |= JackNoStartServer; break;
      case 'f':  format_name = rotter_str_tolower(optarg); break;
      case 'b':  bitrate = atoi(optarg); break;
      case 'Q':  vbr_quality = atof(optarg); break;
      case 'd':  delete_hours = atoi(optarg); break;
      case 'c':  channels = atoi(optarg); break;
      case 'R':  rb_duration = atof(optarg); break;
      case 'L':  file_layout = optarg; break;
      case 's':  sync_period = atoi(optarg); break;
      case 'u':  utc = 1; break;
      case 'v':  verbose = 1; break;
      case 'q':  quiet = 1; break;
      default:  usage(); break;
    }
  }

  // Validate parameters
  if (quiet && verbose) {
    rotter_error("Can't be quiet and verbose at the same time.");
    usage();
  }

  // Check the number of channels
  if (channels!=1 && channels!=2) {
    rotter_error("Number of channels should be either 1 or 2.");
    usage();
  }

  // Check remaining arguments
    argc -= optind;
    argv += optind;
    if (argc!=1) {
      rotter_error("%s requires a root directory argument.", PACKAGE_NAME);
      usage();
  } else {
    root_directory = argv[0];
    if (root_directory[strlen(root_directory)-1] == '/')
      root_directory[strlen(root_directory)-1] = 0;

    if (rotter_directory_exists(root_directory)) {
      rotter_debug("Root directory: %s", root_directory);
    } else {
      rotter_fatal("Root directory does not exist: %s", root_directory);
      goto cleanup;
    }
  }

  // Search for the selected output format
  if (format_name) {
    for(i=0; format_list[i].name; i++) {
      if (strcmp( format_list[i].name, format_name ) == 0) {
        // Found desired format
        output_format = &format_list[i];
        rotter_debug("User selected [%s] '%s'.",  output_format->name,  output_format->desc);
        break;
      }
    }
    if (output_format==NULL) {
      rotter_fatal("Failed to find format [%s], please check the supported format list.", format_name);
      goto cleanup;
    }
  } else {
    output_format = &format_list[0];
  }

  // No originator defined?
  if (!originator) {
    originator = rotter_get_hostname();
  }

  // Initialise JACK
  if (init_jack( client_name, jack_opt )) {
    rotter_debug("Failed to initialise Jack client.");
    goto cleanup;
  }

  // Create ring buffers
  if (init_ringbuffers()) {
    rotter_debug("Failed to initialise ring buffers.");
    goto cleanup;
  }

  // Create temporary buffer for reading samples into
  if (init_tmpbuffers(output_format->samples_per_frame)) {
    rotter_debug("Failed to initialise temporary buffers.");
    goto cleanup;
  }

  // Initialise encoder
  encoder = output_format->initfunc(output_format, channels, bitrate);
  if (encoder==NULL) {
    rotter_debug("Failed to initialise encoder.");
    goto cleanup;
  }

  // Activate JACK
  if (jack_activate(client)) {
    rotter_fatal("Cannot activate JACK client.");
    goto cleanup;
  }

  // Setup signal handlers
  signal(SIGTERM, rotter_termination_handler);
  signal(SIGINT, rotter_termination_handler);
  signal(SIGHUP, rotter_termination_handler);

  // Auto-connect our input ports ?
  if (autoconnect) autoconnect_jack_ports( client );
  if (connect_left) connect_jack_port( connect_left, inport[0] );
  if (connect_right && channels == 2) connect_jack_port( connect_right, inport[1] );

  // Calculate period to wait when there is no audio to process
  sleep_time = (2.0f * output_format->samples_per_frame / jack_get_sample_rate( client ));
  rotter_debug("Sleep period is %dms.", (int)(sleep_time * 1000));

  while( rotter_run_state == ROTTER_STATE_RUNNING ) {
    time_t now = time(NULL);
    int samples_processed = rotter_process_audio();
    if (samples_processed <= 0) {
      usleep(sleep_time * 1000000);
    }

    // Is it time to sync the encoded audio to disk?
    if (next_sync < now) {
      rotter_sync_to_disk();
      next_sync = now + sync_period;
    }

    deletefiles_cleanup_child();
  }


cleanup:

  // Clean up JACK
  deinit_jack();

  // Free buffers and close files
  deinit_tmpbuffers();
  deinit_ringbuffers();

  // Shut down encoder
  if (encoder)
    encoder->deinit();

  // Free the originator string
  if (originator)
    free(originator);

  // Did something go wrong?
  if (rotter_run_state == ROTTER_STATE_QUITING) {
    return EXIT_SUCCESS;
  } else {
    return EXIT_FAILURE;
  }
}