String open (const BigInteger& inputChannels, const BigInteger& outputChannels, double /* sampleRate */, int /* bufferSizeSamples */) { jack_Log ("opening client"); lastError = client.open (KV_JACK_NAME, 0); if (lastError.isNotEmpty()) { jack_Log (lastError); return lastError; } DBG("num inputs: " << inputChannels.getHighestBit()); DBG("num outputs: " << outputChannels.getHighestBit()); jack_on_shutdown (client, JackDevice::shutdownCallback, this); jack_set_error_function (JackDevice::errorCallback); jack_set_port_connect_callback (client, JackDevice::portConnectCallback, this); jack_set_process_callback (client, JackDevice::processCallback, this); jack_set_thread_init_callback (client, JackDevice::threadInitCallback, this); jack_set_port_registration_callback (client, JackDevice::_portRegistration, this); client.registerPort ("audio_1", Jack::audioPort, JackPortIsOutput); client.registerPort ("audio_2", Jack::audioPort, JackPortIsOutput); return lastError; }
bool JackClient::setup(volatile bool* p_runFlag, uint32_t nrOfFramesInRingBuffer) { m_p_runFlag = p_runFlag; const char *server_name = NULL; jack_options_t options = JackNoStartServer; jack_status_t status; // create a jack client m_p_jackClient = jack_client_open(s_jackClientName.c_str(), options, &status, server_name); if (m_p_jackClient == NULL) { DEBUG_PRINT("jack_client_open() failed, status = 0x%2.0x", status); if (status & JackServerFailed) { DEBUG_PRINT("unable to connect to JACK server"); } return false; } if (status & JackServerStarted) { DEBUG_PRINT("jack server up and running"); } if (status & JackNameNotUnique) { char* client_name = jack_get_client_name(m_p_jackClient); DEBUG_PRINT("unique name `%s' assigned", client_name); } // create ringbuffer m_p_ringBuffer = jack_ringbuffer_create(sizeof(jack_default_audio_sample_t) * jack_get_buffer_size(m_p_jackClient) * nrOfFramesInRingBuffer); if (m_p_ringBuffer == NULL) { DEBUG_PRINT("failed to create ringbuffer"); return false; } // setup callbacks int check; if ((check = jack_set_process_callback(m_p_jackClient, JackClient::processJackCallback, this))) { return false; } jack_on_shutdown(m_p_jackClient, JackClient::shutdownJackCallback, this); if ((check = jack_set_port_connect_callback(m_p_jackClient, JackClient::connectionJackCallback, this))) { return false; } if (!registerPorts()) { return false; } return true; }
void gojack_generic_callback_sync_destroy(struct gojack_generic_callback_sync *sync) { jack_set_freewheel_callback(sync->client, NULL, NULL); jack_set_buffer_size_callback(sync->client, NULL, NULL); jack_set_sample_rate_callback(sync->client, NULL, NULL); jack_set_client_registration_callback(sync->client, NULL, NULL); jack_set_port_registration_callback(sync->client, NULL, NULL); jack_set_port_connect_callback(sync->client, NULL, NULL); jack_set_port_rename_callback(sync->client, NULL, NULL); jack_set_graph_order_callback(sync->client, NULL, NULL); jack_set_xrun_callback(sync->client, NULL, NULL); jack_set_latency_callback(sync->client, NULL, NULL); cgo_callback_sync_destroy(sync->base); pthread_mutex_destroy(&sync->lock); free(sync); }
int main (int argc, char *argv[]) { jack_client_t *client; jack_options_t options = JackNullOption; jack_status_t status; if ((client = jack_client_open ("event-monitor", options, &status, NULL)) == 0) { fprintf (stderr, "jack_client_open() failed, " "status = 0x%2.0x\n", status); if (status & JackServerFailed) { fprintf (stderr, "Unable to connect to JACK server\n"); } return 1; } if (jack_set_port_registration_callback (client, port_callback, NULL)) { fprintf (stderr, "cannot set port registration callback\n"); return 1; } if (jack_set_port_connect_callback (client, connect_callback, NULL)) { fprintf (stderr, "cannot set port connect callback\n"); return 1; } if (jack_set_client_registration_callback (client, client_callback, NULL)) { fprintf (stderr, "cannot set client registration callback\n"); return 1; } if (jack_set_graph_order_callback (client, graph_callback, NULL)) { fprintf (stderr, "cannot set graph order registration callback\n"); return 1; } if (jack_set_property_change_callback (client, (JackPropertyChangeCallback) propchange, 0)) { fprintf (stderr, "cannot set property change callback\n"); return 1; } if (jack_activate (client)) { fprintf (stderr, "cannot activate client"); return 1; } sleep (-1); exit (0); }
struct gojack_generic_callback_sync * gojack_generic_callback_sync_create(jack_client_t *client) { struct gojack_generic_callback_sync *sync = (struct gojack_generic_callback_sync *) malloc(sizeof(struct gojack_generic_callback_sync)); void *arg = (void *) sync; sync->base = cgo_callback_sync_create(); cgo_callback_sync_set_log_callback(sync->base, &handle_log, NULL); pthread_mutex_init(&sync->lock, NULL); sync->client = client; jack_set_freewheel_callback(client, &handle_freewheel, arg); jack_set_buffer_size_callback(client, &handle_buffer_size, arg); //jack_set_sample_rate_callback(client, &handle_sample_rate, arg); jack_set_client_registration_callback(client, &handle_client_registration, arg); jack_set_port_registration_callback(client, &handle_port_registration, arg); jack_set_port_connect_callback(client, &handle_port_connect, arg); jack_set_port_rename_callback(client, &handle_port_rename, arg); jack_set_graph_order_callback(client, &handle_graph_order, arg); jack_set_xrun_callback(client, &handle_xrun, arg); //jack_set_latency_callback(client, &handle_latency, arg); return sync; }
int main (int argc, char *argv[]) { // Make output unbuffered setbuf(stdout, NULL); setbuf(stderr, NULL); if (argc >= 2 && ( strcmp(argv[1],"-h")==0 || strcmp(argv[1],"--help")==0)) { printf("send jack events as OSC message\n\n"); printf("syntax: jack_oscev <osc local port> <osc remote host> <osc remote port>\n\n"); printf("all params are optional. order matters.\n"); printf("default values: 6677 127.0.0.1 6678\n"); printf("example: jack_oscev 9988 10.10.10.42\n"); printf("test on .42: oscdump 6678\n\n"); printf("messages sent by jack_oscev (example content):\n"); printf(" /oscev/started\n"); printf(" /oscev/client/registered s \"meter\"\n"); printf(" /oscev/port/registered i 24\n"); printf(" /oscev/port/connected ii 2 24\n"); printf(" /oscev/port/disconnected ii 2 24\n"); printf(" /oscev/port/unregistered i 24\n"); printf(" /oscev/client/unregistered s \"meter\"\n\n"); //printf(""); printf("jack_oscev source at https://github.com/7890/jack_tools\n\n"); return(0); } //remote port if (argc >= 4) { osc_send_to_port=argv[3]; } if (argc >= 3) { osc_send_to_host=argv[2]; } //local port if (argc >= 2) { osc_my_server_port=argv[1]; } //init osc st = lo_server_thread_new(osc_my_server_port, error); loa = lo_address_new(osc_send_to_host, osc_send_to_port); lo_server_thread_start(st); lo_message reply=lo_message_new(); lo_send_message (loa, "/oscev/started", reply); lo_message_free (reply); jack_options_t options = JackNullOption; jack_status_t status; if ((client = jack_client_open ("oscev", options, &status, NULL)) == 0) { fprintf (stderr, "jack_client_open() failed, " "status = 0x%2.0x\n", status); if (status & JackServerFailed) { fprintf (stderr, "Unable to connect to JACK server\n"); } return 1; } if (jack_set_port_registration_callback (client, port_callback, NULL)) { fprintf (stderr, "cannot set port registration callback\n"); return 1; } if (jack_set_port_connect_callback (client, connect_callback, NULL)) { fprintf (stderr, "cannot set port connect callback\n"); return 1; } if (jack_set_client_registration_callback (client, client_callback, NULL)) { fprintf (stderr, "cannot set client registration callback\n"); return 1; } /* //don't register for now if (jack_set_graph_order_callback (client, graph_callback, NULL)) { fprintf (stderr, "cannot set graph order registration callback\n"); return 1; } */ if (jack_activate (client)) { fprintf (stderr, "cannot activate client"); return 1; } #ifndef WIN32 signal(SIGINT, signal_handler); signal(SIGQUIT, signal_handler); signal(SIGHUP, signal_handler); #endif signal(SIGABRT, signal_handler); signal(SIGTERM, signal_handler); #ifdef WIN32 Sleep(INFINITE); #else sleep (-1); #endif exit (0); }
void JACKInput::Init() { m_message_queue.Reset(RING_BUFFER_SIZE * m_channels * sizeof(float)); m_jack_client = jack_client_open("SimpleScreenRecorder", JackNoStartServer, NULL); if(m_jack_client == NULL) { Logger::LogError("[JACKInput::Init] " + Logger::tr("Error: Could not connect to JACK!")); throw JACKException(); } m_jack_ports.resize(m_channels, NULL); for(unsigned int i = 0; i < m_channels; ++i) { std::string port_name = "in_" + NumToString(i + 1); m_jack_ports[i] = jack_port_register(m_jack_client, port_name.c_str(), JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); if(m_jack_ports[i] == NULL) { Logger::LogError("[JACKInput::Init] " + Logger::tr("Error: Could not create JACK port!")); throw JACKException(); } } if(jack_set_process_callback(m_jack_client, ProcessCallback, this) != 0) { Logger::LogError("[JACKInput::Init] " + Logger::tr("Error: Could not set JACK process callback!")); throw JACKException(); } if(jack_set_sample_rate_callback(m_jack_client, SampleRateCallback, this) != 0) { Logger::LogError("[JACKInput::Init] " + Logger::tr("Error: Could not set JACK sample rate callback!")); throw JACKException(); } if(jack_set_xrun_callback(m_jack_client, XRunCallback, this) != 0) { Logger::LogError("[JACKInput::Init] " + Logger::tr("Error: Could not set JACK xrun callback!")); throw JACKException(); } if(jack_set_port_connect_callback(m_jack_client, PortConnectCallback, this) != 0) { Logger::LogError("[JACKInput::Init] " + Logger::tr("Error: Could not set JACK port connect callback!")); throw JACKException(); } if(jack_activate(m_jack_client) != 0) { Logger::LogError("[JACKInput::Init] " + Logger::tr("Error: Could not activate JACK client!")); throw JACKException(); } for(unsigned int i = 0; i < m_channels; ++i) { std::string port_name_full = std::string(jack_get_client_name(m_jack_client)) + ":in_" + NumToString(i + 1); if(m_connect_system_capture) { std::string capture_name = "system:capture_" + NumToString(i + 1); Logger::LogInfo("[JACKInput::Init] " + Logger::tr("Connecting port %1 to %2.") .arg(QString::fromStdString(capture_name)).arg(QString::fromStdString(port_name_full))); jack_connect(m_jack_client, capture_name.c_str(), port_name_full.c_str()); } if(m_connect_system_playback) { std::string playback_name = "system:playback_" + NumToString(i + 1); jack_port_t *port = jack_port_by_name(m_jack_client, playback_name.c_str()); if(port != NULL) { const char **connected_ports = jack_port_get_all_connections(m_jack_client, port); if(connected_ports != NULL) { for(const char **p = connected_ports; *p != NULL; ++p) { Logger::LogInfo("[JACKInput::Init] " + Logger::tr("Connecting port %1 to %2.") .arg(*p).arg(QString::fromStdString(port_name_full))); jack_connect(m_jack_client, *p, port_name_full.c_str()); } jack_free(connected_ports); } } } } // start input thread m_should_stop = false; m_error_occurred = false; m_thread = std::thread(&JACKInput::InputThread, this); }
/* JackProxyDriver is wrapped in a JackWaitCallbackDriver decorator that behaves as a "dummy driver, until Initialize method returns. */ bool JackProxyDriver::Initialize() { jack_log("JackProxyDriver::Initialize"); // save existing local connections if needed if (fAutoSave) { SaveConnections(0); } // new loading, but existing client, restart the driver if (fClient) { jack_info("JackProxyDriver restarting..."); jack_client_close(fClient); } FreePorts(); // display some additional infos jack_info("JackProxyDriver started in %s mode.", (fEngineControl->fSyncMode) ? "sync" : "async"); do { jack_status_t status; char *old = NULL; if (fPromiscuous) { // as we are fiddling with the environment variable content, save it const char* tmp = getenv("JACK_PROMISCUOUS_SERVER"); if (tmp) { old = strdup(tmp); } // temporary enable promiscuous mode if (setenv("JACK_PROMISCUOUS_SERVER", fPromiscuous, 1) < 0) { free(old); jack_error("Error allocating memory."); return false; } } jack_info("JackProxyDriver connecting to %s", fUpstream); fClient = jack_client_open(fClientName, static_cast<jack_options_t>(JackNoStartServer|JackServerName), &status, fUpstream); if (fPromiscuous) { // restore previous environment variable content if (old) { if (setenv("JACK_PROMISCUOUS_SERVER", old, 1) < 0) { free(old); jack_error("Error allocating memory."); return false; } free(old); } else { unsetenv("JACK_PROMISCUOUS_SERVER"); } } // the connection failed, try again later if (!fClient) { JackSleep(1000000); } } while (!fClient); jack_info("JackProxyDriver connected to %s", fUpstream); // we are connected, let's register some callbacks jack_on_shutdown(fClient, shutdown_callback, this); if (jack_set_process_callback(fClient, process_callback, this) != 0) { jack_error("Cannot set process callback."); return false; } if (jack_set_buffer_size_callback(fClient, bufsize_callback, this) != 0) { jack_error("Cannot set buffer size callback."); return false; } if (jack_set_sample_rate_callback(fClient, srate_callback, this) != 0) { jack_error("Cannot set sample rate callback."); return false; } if (jack_set_port_connect_callback(fClient, connect_callback, this) != 0) { jack_error("Cannot set port connect callback."); return false; } // detect upstream physical playback ports if needed if (fDetectPlaybackChannels) { fPlaybackChannels = CountIO(JACK_DEFAULT_AUDIO_TYPE, JackPortIsPhysical | JackPortIsOutput); } // detect upstream physical capture ports if needed if (fDetectCaptureChannels) { fCaptureChannels = CountIO(JACK_DEFAULT_AUDIO_TYPE, JackPortIsPhysical | JackPortIsInput); } if (AllocPorts() != 0) { jack_error("Can't allocate ports."); return false; } bufsize_callback(jack_get_buffer_size(fClient)); srate_callback(jack_get_sample_rate(fClient)); // restore local connections if needed if (fAutoSave) { LoadConnections(0); } // everything is ready, start upstream processing if (jack_activate(fClient) != 0) { jack_error("Cannot activate jack client."); return false; } // connect upstream ports if needed if (fAutoConnect) { ConnectPorts(); } return true; }
int main(int argc, char **argv) { int jitter_plot[101]; int latency_plot[101]; int long_index = 0; struct option long_options[] = { {"help", 0, NULL, 'h'}, {"message-size", 1, NULL, 'm'}, {"samples", 1, NULL, 's'}, {"timeout", 1, NULL, 't'} }; size_t name_arg_count; size_t name_size; char *option_string = "hm:s:t:"; int show_usage = 0; connections_established = 0; error_message = NULL; message_size = 3; program_name = argv[0]; remote_in_port = 0; remote_out_port = 0; samples = 1024; timeout = 5; for (;;) { signed char c = getopt_long(argc, argv, option_string, long_options, &long_index); switch (c) { case 'h': show_usage = 1; break; case 'm': message_size = parse_positive_number_arg(optarg, "message-size"); break; case 's': samples = parse_positive_number_arg(optarg, "samples"); break; case 't': timeout = parse_positive_number_arg(optarg, "timeout"); break; default: { char *s = "'- '"; s[2] = c; die(s, "invalid switch"); } case -1: if (show_usage) { output_usage(); exit(EXIT_SUCCESS); } goto parse_port_names; case 1: /* end of switch :) */ ; } } parse_port_names: name_arg_count = argc - optind; switch (name_arg_count) { case 2: target_in_port_name = argv[optind + 1]; target_out_port_name = argv[optind]; break; case 0: target_in_port_name = 0; target_out_port_name = 0; break; default: output_usage(); return EXIT_FAILURE; } name_size = jack_port_name_size(); alias1 = malloc(name_size * sizeof(char)); if (alias1 == NULL) { error_message = strerror(errno); error_source = "malloc"; goto show_error; } alias2 = malloc(name_size * sizeof(char)); if (alias2 == NULL) { error_message = strerror(errno); error_source = "malloc"; goto free_alias1; } latency_values = malloc(sizeof(jack_nframes_t) * samples); if (latency_values == NULL) { error_message = strerror(errno); error_source = "malloc"; goto free_alias2; } latency_time_values = malloc(sizeof(jack_time_t) * samples); if (latency_time_values == NULL) { error_message = strerror(errno); error_source = "malloc"; goto free_latency_values; } message_1 = malloc(message_size * sizeof(jack_midi_data_t)); if (message_1 == NULL) { error_message = strerror(errno); error_source = "malloc"; goto free_latency_time_values; } message_2 = malloc(message_size * sizeof(jack_midi_data_t)); if (message_2 == NULL) { error_message = strerror(errno); error_source = "malloc"; goto free_message_1; } switch (message_size) { case 1: message_1[0] = 0xf6; message_2[0] = 0xfe; break; case 2: message_1[0] = 0xc0; message_1[1] = 0x00; message_2[0] = 0xd0; message_2[1] = 0x7f; break; case 3: message_1[0] = 0x80; message_1[1] = 0x00; message_1[2] = 0x00; message_2[0] = 0x90; message_2[1] = 0x7f; message_2[2] = 0x7f; break; default: message_1[0] = 0xf0; memset(message_1 + 1, 0, (message_size - 2) * sizeof(jack_midi_data_t)); message_1[message_size - 1] = 0xf7; message_2[0] = 0xf0; memset(message_2 + 1, 0x7f, (message_size - 2) * sizeof(jack_midi_data_t)); message_2[message_size - 1] = 0xf7; } client = jack_client_open(program_name, JackNullOption, NULL); if (client == NULL) { error_message = "failed to open JACK client"; error_source = "jack_client_open"; goto free_message_2; } in_port = jack_port_register(client, "in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0); if (in_port == NULL) { error_message = "failed to register MIDI-in port"; error_source = "jack_port_register"; goto close_client; } out_port = jack_port_register(client, "out", JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0); if (out_port == NULL) { error_message = "failed to register MIDI-out port"; error_source = "jack_port_register"; goto unregister_in_port; } if (jack_set_process_callback(client, handle_process, NULL)) { error_message = "failed to set process callback"; error_source = "jack_set_process_callback"; goto unregister_out_port; } if (jack_set_xrun_callback(client, handle_xrun, NULL)) { error_message = "failed to set xrun callback"; error_source = "jack_set_xrun_callback"; goto unregister_out_port; } if (jack_set_port_connect_callback(client, handle_port_connection_change, NULL)) { error_message = "failed to set port connection callback"; error_source = "jack_set_port_connect_callback"; goto unregister_out_port; } jack_on_shutdown(client, handle_shutdown, NULL); jack_set_info_function(handle_info); process_state = 0; connect_semaphore = create_semaphore(0); if (connect_semaphore == NULL) { error_message = get_semaphore_error(); error_source = "create_semaphore"; goto unregister_out_port; } init_semaphore = create_semaphore(1); if (init_semaphore == NULL) { error_message = get_semaphore_error(); error_source = "create_semaphore"; goto destroy_connect_semaphore;; } process_semaphore = create_semaphore(2); if (process_semaphore == NULL) { error_message = get_semaphore_error(); error_source = "create_semaphore"; goto destroy_init_semaphore; } if (jack_activate(client)) { error_message = "could not activate client"; error_source = "jack_activate"; goto destroy_process_semaphore; } if (name_arg_count) { if (jack_connect(client, jack_port_name(out_port), target_out_port_name)) { error_message = "could not connect MIDI out port"; error_source = "jack_connect"; goto deactivate_client; } if (jack_connect(client, target_in_port_name, jack_port_name(in_port))) { error_message = "could not connect MIDI in port"; error_source = "jack_connect"; goto deactivate_client; } } if (! register_signal_handler(handle_signal)) { error_message = strerror(errno); error_source = "register_signal_handler"; goto deactivate_client; } printf("Waiting for connections ...\n"); if (wait_semaphore(connect_semaphore, 1) == -1) { error_message = get_semaphore_error(); error_source = "wait_semaphore"; goto deactivate_client; } if (connections_established) { printf("Waiting for test completion ...\n\n"); if (wait_semaphore(process_semaphore, 1) == -1) { error_message = get_semaphore_error(); error_source = "wait_semaphore"; goto deactivate_client; } } if (! register_signal_handler(SIG_DFL)) { error_message = strerror(errno); error_source = "register_signal_handler"; goto deactivate_client; } if (process_state == 2) { double average_latency = ((double) total_latency) / samples; double average_latency_time = total_latency_time / samples; size_t i; double latency_plot_offset = floor(((double) lowest_latency_time) / 100.0) / 10.0; double sample_rate = (double) jack_get_sample_rate(client); jack_nframes_t total_jitter = 0; jack_time_t total_jitter_time = 0; for (i = 0; i <= 100; i++) { jitter_plot[i] = 0; latency_plot[i] = 0; } for (i = 0; i < samples; i++) { double latency_time_value = (double) latency_time_values[i]; double latency_plot_time = (latency_time_value / 1000.0) - latency_plot_offset; double jitter_time = ABS(average_latency_time - latency_time_value); if (latency_plot_time >= 10.0) { (latency_plot[100])++; } else { (latency_plot[(int) (latency_plot_time * 10.0)])++; } if (jitter_time >= 10000.0) { (jitter_plot[100])++; } else { (jitter_plot[(int) (jitter_time / 100.0)])++; } total_jitter += ABS(average_latency - ((double) latency_values[i])); total_jitter_time += jitter_time; } printf("Reported out-port latency: %.2f-%.2f ms (%u-%u frames)\n" "Reported in-port latency: %.2f-%.2f ms (%u-%u frames)\n" "Average latency: %.2f ms (%.2f frames)\n" "Lowest latency: %.2f ms (%u frames)\n" "Highest latency: %.2f ms (%u frames)\n" "Peak MIDI jitter: %.2f ms (%u frames)\n" "Average MIDI jitter: %.2f ms (%.2f frames)\n", (out_latency_range.min / sample_rate) * 1000.0, (out_latency_range.max / sample_rate) * 1000.0, out_latency_range.min, out_latency_range.max, (in_latency_range.min / sample_rate) * 1000.0, (in_latency_range.max / sample_rate) * 1000.0, in_latency_range.min, in_latency_range.max, average_latency_time / 1000.0, average_latency, lowest_latency_time / 1000.0, lowest_latency, highest_latency_time / 1000.0, highest_latency, (highest_latency_time - lowest_latency_time) / 1000.0, highest_latency - lowest_latency, (total_jitter_time / 1000.0) / samples, ((double) total_jitter) / samples); printf("\nJitter Plot:\n"); for (i = 0; i < 100; i++) { if (jitter_plot[i]) { printf("%.1f - %.1f ms: %d\n", ((float) i) / 10.0, ((float) (i + 1)) / 10.0, jitter_plot[i]); } } if (jitter_plot[100]) { printf(" > 10 ms: %d\n", jitter_plot[100]); } printf("\nLatency Plot:\n"); for (i = 0; i < 100; i++) { if (latency_plot[i]) { printf("%.1f - %.1f ms: %d\n", latency_plot_offset + (((float) i) / 10.0), latency_plot_offset + (((float) (i + 1)) / 10.0), latency_plot[i]); } } if (latency_plot[100]) { printf(" > %.1f ms: %d\n", latency_plot_offset + 10.0, latency_plot[100]); } } deactivate_client: jack_deactivate(client); printf("\nMessages sent: %d\nMessages received: %d\n", messages_sent, messages_received); if (unexpected_messages) { printf("Unexpected messages received: %d\n", unexpected_messages); } if (xrun_count) { printf("Xruns: %d\n", xrun_count); } destroy_process_semaphore: destroy_semaphore(process_semaphore, 2); destroy_init_semaphore: destroy_semaphore(init_semaphore, 1); destroy_connect_semaphore: destroy_semaphore(connect_semaphore, 0); unregister_out_port: jack_port_unregister(client, out_port); unregister_in_port: jack_port_unregister(client, in_port); close_client: jack_client_close(client); free_message_2: free(message_2); free_message_1: free(message_1); free_latency_time_values: free(latency_time_values); free_latency_values: free(latency_values); free_alias2: free(alias2); free_alias1: free(alias1); if (error_message != NULL) { show_error: output_error(error_source, error_message); exit(EXIT_FAILURE); } return EXIT_SUCCESS; }