Beispiel #1
0
static
void rotter_termination_handler (int signum)
{
  switch(signum) {
    case SIGHUP:  rotter_info("Got hangup signal."); break;
    case SIGTERM: rotter_info("Got termination signal."); break;
    case SIGINT:  rotter_info("Got interupt signal."); break;
  }

  // Signal the main thead to stop
  rotter_run_state = ROTTER_STATE_QUITING;
}
Beispiel #2
0
static int rotter_close_file(rotter_ringbuffer_t *ringbuffer)
{
  rotter_info( "Closing file for ringbuffer %c.", ringbuffer->label);
  encoder->close(ringbuffer->file_handle, &ringbuffer->file_start);
  ringbuffer->close_file = 0;
  ringbuffer->file_handle = NULL;
  return 0;
}
Beispiel #3
0
static int rotter_open_file(rotter_ringbuffer_t *ringbuffer)
{
  char filepath[MAX_FILEPATH_LEN];
  int err = -1;
  struct tm tm;

  if (utc) {
    gmtime_r( &ringbuffer->file_start.tv_sec, &tm );
  } else {
    localtime_r( &ringbuffer->file_start.tv_sec, &tm );
  }

  if (!strcasecmp(file_layout, "hierarchy")) {
    err = time_to_filepath_hierarchy( &tm, encoder->file_suffix, filepath );
  } else if (!strcasecmp(file_layout, "flat")) {
    err = time_to_filepath_flat( &tm, encoder->file_suffix, filepath );
  } else if (!strcasecmp(file_layout, "combo")) {
    err = time_to_filepath_combo( &tm, encoder->file_suffix, filepath );
  } else if (!strcasecmp(file_layout, "dailydir")) {
    err = time_to_filepath_dailydir( &tm, encoder->file_suffix, filepath );
  } else if (!strcasecmp(file_layout, "accurate")) {
    err = time_to_filepath_accurate( &tm, ringbuffer->file_start.tv_usec, encoder->file_suffix, filepath );
  } else {
    err = time_to_filepath_custom( &tm, file_layout, filepath );
  }

  if (err) {
    rotter_fatal( "Failed to build file path for layout: %s", file_layout );
    return -1;
  }

  // Make sure the parent directory exists
  if (rotter_mkdir_for_file(filepath)) {
    rotter_fatal( "Failed to create parent directories for filepath: %s (%s)",
                  filepath, strerror(errno) );
    return -1;
  }

  // Open the new file
  rotter_info( "Opening new archive file for ringbuffer %c: %s", ringbuffer->label, filepath );
  ringbuffer->file_handle = encoder->open(filepath, &ringbuffer->file_start);

  if (ringbuffer->file_handle) {
    // Success
    return 0;
  } else {
    return 1;
  }
}
Beispiel #4
0
// Connect one Jack port to another
int connect_jack_port( const char* out, jack_port_t *port )
{
  const char* in = jack_port_name( port );
  int err;

  rotter_info("Connecting '%s' to '%s'", out, in);

  if ((err = jack_connect(client, out, in)) != 0) {
    rotter_fatal("connect_jack_port(): failed to jack_connect() ports: %d", err);
    return err;
  }

  // Success
  return 0;
}
Beispiel #5
0
// Initialise Jack related stuff
int init_jack( const char* client_name, jack_options_t jack_opt )
{
  jack_status_t status;

  // Register with Jack
  if ((client = jack_client_open(client_name, jack_opt, &status)) == 0) {
    rotter_fatal("Failed to start jack client: 0x%x", status);
    return -1;
  }
  rotter_info( "JACK client registered as '%s'.", jack_get_client_name( client ) );


  // Create our input port(s)
  if (channels==1) {
    if (!(inport[0] = jack_port_register(client, "mono", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0))) {
      rotter_fatal("Cannot register mono input port.");
      return -1;
    }
  } else {
    if (!(inport[0] = jack_port_register(client, "left", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0))) {
      rotter_fatal("Cannot register left input port.");
      return -1;
    }

    if (!(inport[1] = jack_port_register(client, "right", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0))) {
      rotter_fatal( "Cannot register left input port.");
      return -1;
    }
  }

  // Register xrun callback
  jack_set_xrun_callback(client, xrun_callback_jack, client);

  // Register shutdown callback
  jack_on_shutdown(client, shutdown_callback_jack, NULL);

  // Register callback
  if (jack_set_process_callback(client, callback_jack, NULL)) {
    rotter_fatal( "Failed to set Jack process callback.");
    return -1;
  }

  // Success
  return 0;
}
Beispiel #6
0
// Delete files older than 'hours'
int deletefiles( const char* dirpath, int hours )
{
  int old_niceness, new_niceness = 15;
  time_t now = time(NULL);
  dev_t device = get_file_device( dirpath );

  if (hours<=0)
    return 0;

  if (delete_child_pid) {
    rotter_error( "Not deleting files: the last deletion process has not finished." );
    return delete_child_pid;
  }

  rotter_info( "Deleting files older than %d hours in %s.", hours, dirpath );

  // Fork a new process
  delete_child_pid = fork();
  if (delete_child_pid>0) {
    // Parent is here
    rotter_debug( "Forked new proccess to delete files (pid=%d).", delete_child_pid );
    return delete_child_pid;
  } else if (delete_child_pid<0) {
    rotter_error( "Warning: fork failed: %s", strerror(errno) );
    return 0;
  }

  // Make this process nicer
  // (deleting files is pretty unimportant)
  old_niceness = nice( new_niceness );
  rotter_debug( "Changed child proccess niceless from %d to %d.", old_niceness, new_niceness );

  // Recursively process directories
  deletefiles_in_dir( dirpath, device, now-(hours*3600) );

  // End of child process
  exit(0);
}
Beispiel #7
0
encoder_funcs_t* init_lame( output_format_t* format, int channels, int bitrate )
{
  encoder_funcs_t* funcs = NULL;

  lame_opts = lame_init();
  if (lame_opts==NULL) {
    rotter_error("lame error: failed to initialise.");
    return NULL;
  }

  if ( 0 > lame_set_num_channels( lame_opts, channels ) ) {
    rotter_error("lame error: failed to set number of channels.");
    return NULL;
  }

  if ( 0 > lame_set_in_samplerate( lame_opts, jack_get_sample_rate( client ) )) {
    rotter_error("lame error: failed to set input samplerate.");
    return NULL;
  }

  if ( 0 > lame_set_out_samplerate( lame_opts, jack_get_sample_rate( client ) )) {
    rotter_error("lame error: failed to set output samplerate.");
    return NULL;
  }

  if ( 0 > lame_set_brate( lame_opts, bitrate) ) {
    rotter_error("lame error: failed to set bitrate.");
    return NULL;
  }

  if ( 0 > lame_init_params( lame_opts ) ) {
    rotter_error("lame error: failed to initialize parameters.");
    return NULL;
  }


  rotter_info( "Encoding using liblame version %s.", get_lame_version() );
  rotter_debug( "  Input: %d Hz, %d channels",
            lame_get_in_samplerate(lame_opts),
            lame_get_num_channels(lame_opts));
  rotter_debug( "  Output: %s Layer 3, %d kbps, %s",
            lame_get_version_name(lame_opts),
            lame_get_brate(lame_opts),
            lame_get_mode_name(lame_opts));

  // Allocate memory for encoded audio
  mpeg_buffer = malloc( 1.25*SAMPLES_PER_FRAME + 7200 );
  if ( mpeg_buffer==NULL ) {
    rotter_error( "Failed to allocate memery for encoded audio." );
    return NULL;
  }

  // Allocate memory for callback functions
  funcs = calloc( 1, sizeof(encoder_funcs_t) );
  if ( funcs==NULL ) {
    rotter_error( "Failed to allocate memery for encoder callback functions structure." );
    return NULL;
  }


  funcs->file_suffix = "mp3";
  funcs->open = open_mpegaudio_file;
  funcs->close = close_mpegaudio_file;
  funcs->write = write_lame;
  funcs->deinit = deinit_lame;


  return funcs;
}