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; }
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; }
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; } }
// 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; }
// 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; }
// 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); }
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; }