diff options
author | falkTX <falktx@falktx.com> | 2022-05-04 11:19:06 +0100 |
---|---|---|
committer | falkTX <falktx@falktx.com> | 2022-05-04 11:19:06 +0100 |
commit | 564c710eefc760a5683b88b3ecb8a29100d5274e (patch) | |
tree | 31c6d8b5843eae1943eca80887bf5d68fdbebdf0 | |
parent | 3d5ace462f41e8330e8ffb3acd28ba6ddee54635 (diff) | |
download | jack2-564c710eefc760a5683b88b3ecb8a29100d5274e.tar.gz |
Remove example-clients and tools
Signed-off-by: falkTX <falktx@falktx.com>
54 files changed, 4 insertions, 12960 deletions
diff --git a/example-clients/capture_client.c b/example-clients/capture_client.c deleted file mode 100644 index d3360b40..00000000 --- a/example-clients/capture_client.c +++ /dev/null @@ -1,353 +0,0 @@ -/* - Copyright (C) 2001 Paul Davis - Copyright (C) 2003 Jack O'Quin - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - * 2002/08/23 - modify for libsndfile 1.0.0 <andy@alsaplayer.org> - * 2003/05/26 - use ringbuffers - joq -*/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <sndfile.h> -#include <pthread.h> -#include <signal.h> -#include <getopt.h> -#include <inttypes.h> - -#include <jack/jack.h> -#include <jack/ringbuffer.h> - -typedef struct _thread_info { - pthread_t thread_id; - SNDFILE *sf; - jack_nframes_t duration; - jack_nframes_t rb_size; - jack_client_t *client; - unsigned int channels; - int bitdepth; - char *path; - volatile int can_capture; - volatile int can_process; - volatile int status; -} jack_thread_info_t; - -/* JACK data */ -unsigned int nports; -jack_port_t **ports; -jack_default_audio_sample_t **in; -jack_nframes_t nframes; -const size_t sample_size = sizeof(jack_default_audio_sample_t); - -/* Synchronization between process thread and disk thread. */ -#define DEFAULT_RB_SIZE 16384 /* ringbuffer size in frames */ -jack_ringbuffer_t *rb; -pthread_mutex_t disk_thread_lock = PTHREAD_MUTEX_INITIALIZER; -pthread_cond_t data_ready = PTHREAD_COND_INITIALIZER; -long overruns = 0; -jack_client_t *client; - -static void signal_handler(int sig) -{ - jack_client_close(client); - fprintf(stderr, "signal received, exiting ...\n"); - exit(0); -} - -static void * -disk_thread (void *arg) -{ - jack_thread_info_t *info = (jack_thread_info_t *) arg; - static jack_nframes_t total_captured = 0; - jack_nframes_t samples_per_frame = info->channels; - size_t bytes_per_frame = samples_per_frame * sample_size; - void *framebuf = malloc (bytes_per_frame); - - pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL); - pthread_mutex_lock (&disk_thread_lock); - - info->status = 0; - - while (1) { - - /* Write the data one frame at a time. This is - * inefficient, but makes things simpler. */ - while (info->can_capture && - (jack_ringbuffer_read_space (rb) >= bytes_per_frame)) { - - jack_ringbuffer_read (rb, framebuf, bytes_per_frame); - - if (sf_writef_float (info->sf, framebuf, 1) != 1) { - char errstr[256]; - sf_error_str (0, errstr, sizeof (errstr) - 1); - fprintf (stderr, - "cannot write sndfile (%s)\n", - errstr); - info->status = EIO; /* write failed */ - goto done; - } - - if (++total_captured >= info->duration) { - printf ("disk thread finished\n"); - goto done; - } - } - - /* wait until process() signals more data */ - pthread_cond_wait (&data_ready, &disk_thread_lock); - } - - done: - pthread_mutex_unlock (&disk_thread_lock); - free (framebuf); - return 0; -} - -static int -process (jack_nframes_t nframes, void *arg) -{ - int chn; - size_t i; - jack_thread_info_t *info = (jack_thread_info_t *) arg; - - /* Do nothing until we're ready to begin. */ - if ((!info->can_process) || (!info->can_capture)) - return 0; - - for (chn = 0; chn < nports; chn++) - in[chn] = jack_port_get_buffer (ports[chn], nframes); - - /* Sndfile requires interleaved data. It is simpler here to - * just queue interleaved samples to a single ringbuffer. */ - for (i = 0; i < nframes; i++) { - for (chn = 0; chn < nports; chn++) { - if (jack_ringbuffer_write (rb, (void *) (in[chn]+i), - sample_size) - < sample_size) - overruns++; - } - } - - /* Tell the disk thread there is work to do. If it is already - * running, the lock will not be available. We can't wait - * here in the process() thread, but we don't need to signal - * in that case, because the disk thread will read all the - * data queued before waiting again. */ - if (pthread_mutex_trylock (&disk_thread_lock) == 0) { - pthread_cond_signal (&data_ready); - pthread_mutex_unlock (&disk_thread_lock); - } - - return 0; -} - -static void -jack_shutdown (void *arg) -{ - fprintf(stderr, "JACK shut down, exiting ...\n"); - exit(1); -} - -static void -setup_disk_thread (jack_thread_info_t *info) -{ - SF_INFO sf_info; - int short_mask; - - sf_info.samplerate = jack_get_sample_rate (info->client); - sf_info.channels = info->channels; - - switch (info->bitdepth) { - case 8: short_mask = SF_FORMAT_PCM_U8; - break; - case 16: short_mask = SF_FORMAT_PCM_16; - break; - case 24: short_mask = SF_FORMAT_PCM_24; - break; - case 32: short_mask = SF_FORMAT_PCM_32; - break; - default: short_mask = SF_FORMAT_PCM_16; - break; - } - sf_info.format = SF_FORMAT_WAV|short_mask; - - if ((info->sf = sf_open (info->path, SFM_WRITE, &sf_info)) == NULL) { - char errstr[256]; - sf_error_str (0, errstr, sizeof (errstr) - 1); - fprintf (stderr, "cannot open sndfile \"%s\" for output (%s)\n", info->path, errstr); - jack_client_close (info->client); - exit (1); - } - - info->duration *= sf_info.samplerate; - info->can_capture = 0; - - pthread_create (&info->thread_id, NULL, disk_thread, info); -} - -static void -run_disk_thread (jack_thread_info_t *info) -{ - info->can_capture = 1; - pthread_join (info->thread_id, NULL); - sf_close (info->sf); - if (overruns > 0) { - fprintf (stderr, - "jackrec failed with %ld overruns.\n", overruns); - fprintf (stderr, " try a bigger buffer than -B %" - PRIu32 ".\n", info->rb_size); - info->status = EPIPE; - } -} - -static void -setup_ports (int sources, char *source_names[], jack_thread_info_t *info) -{ - unsigned int i; - size_t in_size; - - /* Allocate data structures that depend on the number of ports. */ - nports = sources; - ports = (jack_port_t **) malloc (sizeof (jack_port_t *) * nports); - in_size = nports * sizeof (jack_default_audio_sample_t *); - in = (jack_default_audio_sample_t **) malloc (in_size); - rb = jack_ringbuffer_create (nports * sample_size * info->rb_size); - - /* When JACK is running realtime, jack_activate() will have - * called mlockall() to lock our pages into memory. But, we - * still need to touch any newly allocated pages before - * process() starts using them. Otherwise, a page fault could - * create a delay that would force JACK to shut us down. */ - memset(in, 0, in_size); - memset(rb->buf, 0, rb->size); - - for (i = 0; i < nports; i++) { - char name[64]; - - sprintf (name, "input%d", i+1); - - if ((ports[i] = jack_port_register (info->client, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0)) == 0) { - fprintf (stderr, "cannot register input port \"%s\"!\n", name); - jack_client_close (info->client); - exit (1); - } - } - - for (i = 0; i < nports; i++) { - if (jack_connect (info->client, source_names[i], jack_port_name (ports[i]))) { - fprintf (stderr, "cannot connect input port %s to %s\n", jack_port_name (ports[i]), source_names[i]); - jack_client_close (info->client); - exit (1); - } - } - - info->can_process = 1; /* process() can start, now */ -} - -int -main (int argc, char *argv[]) -{ - jack_thread_info_t thread_info; - int c; - int longopt_index = 0; - extern int optind, opterr; - int show_usage = 0; - char *optstring = "d:f:b:B:h"; - struct option long_options[] = { - { "help", 0, 0, 'h' }, - { "duration", 1, 0, 'd' }, - { "file", 1, 0, 'f' }, - { "bitdepth", 1, 0, 'b' }, - { "bufsize", 1, 0, 'B' }, - { 0, 0, 0, 0 } - }; - - memset (&thread_info, 0, sizeof (thread_info)); - thread_info.rb_size = DEFAULT_RB_SIZE; - opterr = 0; - - while ((c = getopt_long (argc, argv, optstring, long_options, &longopt_index)) != -1) { - switch (c) { - case 1: - /* getopt signals end of '-' options */ - break; - - case 'h': - show_usage++; - break; - case 'd': - thread_info.duration = atoi (optarg); - break; - case 'f': - thread_info.path = optarg; - break; - case 'b': - thread_info.bitdepth = atoi (optarg); - break; - case 'B': - thread_info.rb_size = atoi (optarg); - break; - default: - fprintf (stderr, "error\n"); - show_usage++; - break; - } - } - - if (show_usage || thread_info.path == NULL || optind == argc) { - fprintf (stderr, "usage: jackrec -f filename [ -d second ] [ -b bitdepth ] [ -B bufsize ] port1 [ port2 ... ]\n"); - exit (1); - } - - if ((client = jack_client_open ("jackrec", JackNullOption, NULL)) == 0) { - fprintf (stderr, "JACK server not running?\n"); - exit (1); - } - - thread_info.client = client; - thread_info.channels = argc - optind; - thread_info.can_process = 0; - - setup_disk_thread (&thread_info); - - jack_set_process_callback (client, process, &thread_info); - jack_on_shutdown (client, jack_shutdown, &thread_info); - - if (jack_activate (client)) { - fprintf (stderr, "cannot activate client"); - } - - setup_ports (argc - optind, &argv[optind], &thread_info); - - /* install a signal handler to properly quits jack client */ -#ifndef WIN32 - signal(SIGQUIT, signal_handler); - signal(SIGHUP, signal_handler); -#endif - signal(SIGTERM, signal_handler); - signal(SIGINT, signal_handler); - - run_disk_thread (&thread_info); - - jack_client_close (client); - - jack_ringbuffer_free (rb); - - exit (0); -} diff --git a/example-clients/control.c b/example-clients/control.c deleted file mode 100644 index 12fb3153..00000000 --- a/example-clients/control.c +++ /dev/null @@ -1,75 +0,0 @@ -/** @file control.c - * - * @brief This simple client demonstrates the basic features of JACK - * as they would be used by many applications. - */ - -#include <stdio.h> -#include <errno.h> -#include <stdlib.h> -#include <string.h> -#include <signal.h> -#include <math.h> -#include <jack/jack.h> - -jack_client_t *client; -static int reorder = 0; - -static int Jack_Graph_Order_Callback(void *arg) -{ - const char **ports; - int i; - - printf("Jack_Graph_Order_Callback count = %d\n", reorder++); - - ports = jack_get_ports(client, NULL, NULL, JackPortIsPhysical|JackPortIsOutput); - if (ports) { - for (i = 0; ports[i]; ++i) { - printf("name: %s\n", ports[i]); - } - jack_free(ports); - } - - ports = jack_get_ports(client, NULL, NULL, JackPortIsPhysical|JackPortIsInput); - if (ports) { - for (i = 0; ports[i]; ++i) { - printf("name: %s\n", ports[i]); - } - jack_free(ports); - } - - return 0; -} - -int -main (int argc, char *argv[]) -{ - jack_options_t options = JackNullOption; - jack_status_t status; - - /* open a client connection to the JACK server */ - - client = jack_client_open("control_client", options, &status); - if (client == NULL) { - printf("jack_client_open() failed \n"); - exit(1); - } - - if (jack_set_graph_order_callback(client, Jack_Graph_Order_Callback, 0) != 0) { - printf("Error when calling jack_set_graph_order_callback() !\n"); - } - - /* Tell the JACK server that we are ready to roll. Our - * process() callback will start running now. */ - - if (jack_activate(client)) { - printf("cannot activate client"); - exit(1); - } - - printf("Type 'q' to quit\n"); - while ((getchar() != 'q')) {} - - jack_client_close(client); - exit (0); -} diff --git a/example-clients/cpu_load.c b/example-clients/cpu_load.c deleted file mode 100644 index 2c7deaa8..00000000 --- a/example-clients/cpu_load.c +++ /dev/null @@ -1,88 +0,0 @@ -/** @file cpu_load.c - * - */ - -#include <stdio.h> -#include <errno.h> -#include <stdlib.h> -#include <string.h> -#include <math.h> -#include <signal.h> -#ifndef WIN32 -#include <unistd.h> -#endif -#include <jack/jack.h> - - -jack_client_t *client; - -static void signal_handler(int sig) -{ - jack_client_close(client); - fprintf(stderr, "signal received, exiting ...\n"); - exit(0); -} - - -/** - * JACK calls this shutdown_callback if the server ever shuts down or - * decides to disconnect the client. - */ -void -jack_shutdown(void *arg) -{ - exit(1); -} - -int -main(int argc, char *argv[]) -{ - jack_options_t options = JackNullOption; - jack_status_t status; - - /* open a client connection to the JACK server */ - - client = jack_client_open ("jack_cpu_load", options, &status); - if (client == NULL) { - fprintf(stderr, "jack_client_open() failed, " - "status = 0x%2.0x\n", status); - if (status & JackServerFailed) { - fprintf(stderr, "Unable to connect to JACK server\n"); - } - exit(1); - } - - jack_on_shutdown(client, jack_shutdown, 0); - - /* Tell the JACK server that we are ready to roll. Our - * process() callback will start running now. */ - - if (jack_activate(client)) { - fprintf(stderr, "cannot activate client"); - exit(1); - } - - /* install a signal handler to properly quits jack client */ -#ifdef WIN32 - signal(SIGINT, signal_handler); - signal(SIGABRT, signal_handler); - signal(SIGTERM, signal_handler); -#else - signal(SIGQUIT, signal_handler); - signal(SIGTERM, signal_handler); - signal(SIGHUP, signal_handler); - signal(SIGINT, signal_handler); -#endif - - while (1) { - printf("jack DSP load %f\n", jack_cpu_load(client)); -#ifdef WIN32 - Sleep(1000); -#else - sleep(1); -#endif - } - - jack_client_close(client); - exit(0 ); -} diff --git a/example-clients/impulse_grabber.c b/example-clients/impulse_grabber.c deleted file mode 100644 index 7084c2e9..00000000 --- a/example-clients/impulse_grabber.c +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright (C) 2001 Steve Harris - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include <stdio.h> -#include <errno.h> -#include <unistd.h> -#include <stdlib.h> -#include <signal.h> -#include <math.h> -#include <getopt.h> - -#include <jack/jack.h> - -jack_port_t *input_port; -jack_port_t *output_port; - -unsigned int impulse_sent = 0; -float *response; -unsigned long response_duration; -unsigned long response_pos; -int grab_finished = 0; -jack_client_t *client; - -static void signal_handler(int sig) -{ - jack_client_close(client); - fprintf(stderr, "signal received, exiting ...\n"); - exit(0); -} - -static int -process (jack_nframes_t nframes, void *arg) - -{ - jack_default_audio_sample_t *out = (jack_default_audio_sample_t *) jack_port_get_buffer (output_port, nframes); - jack_default_audio_sample_t *in = (jack_default_audio_sample_t *) jack_port_get_buffer (input_port, nframes); - unsigned int i; - - if (grab_finished) { - return 0; - } else if (impulse_sent) { - for(i=0; i<nframes && response_pos < response_duration; i++) { - response[response_pos++] = in[i]; - } - if (response_pos >= response_duration) { - grab_finished = 1; - } - for (i=0; i<nframes; i++) { - out[i] = 0.0f;; - } - } else { - out[0] = 1.0f; - for (i=1; i<nframes; i++) { - out[i] = 0.0f; - } - impulse_sent = 1; - } - - return 0; -} - -static void -jack_shutdown (void *arg) -{ - fprintf(stderr, "JACK shut down, exiting ...\n"); - exit (1); -} - -int -main (int argc, char *argv[]) -{ - const char **ports; - float fs; // The sample rate - float peak; - unsigned long peak_sample; - unsigned int i; - float duration = 0.0f; - unsigned int c_format = 0; - int longopt_index = 0; - int c; - extern int optind, opterr; - int show_usage = 0; - char *optstring = "d:f:h"; - struct option long_options[] = { - { "help", 1, 0, 'h' }, - { "duration", 1, 0, 'd' }, - { "format", 1, 0, 'f' }, - { 0, 0, 0, 0 } - }; - - while ((c = getopt_long (argc, argv, optstring, long_options, &longopt_index)) != -1) { - switch (c) { - case 1: - // end of opts, but don't care - break; - case 'h': - show_usage++; - break; - case 'd': - duration = (float)atof(optarg); - break; - case 'f': - if (*optarg == 'c' || *optarg == 'C') { - c_format = 1; - } - break; - default: - show_usage++; - break; - } - } - if (show_usage || duration <= 0.0f) { - fprintf(stderr, "usage: jack_impulse_grab -d duration [-f (C|gnuplot)]\n"); - exit(1); - } - - /* try to become a client of the JACK server */ - - if ((client = jack_client_open("impulse_grabber", JackNullOption, NULL)) == 0) { - fprintf (stderr, "JACK server not running?\n"); - return 1; - } - - /* tell the JACK server to call `process()' whenever - there is work to be done. - */ - - jack_set_process_callback (client, process, 0); - - /* tell the JACK server to call `jack_shutdown()' if - it ever shuts down, either entirely, or if it - just decides to stop calling us. - */ - - jack_on_shutdown (client, jack_shutdown, 0); - - /* display the current sample rate. once the client is activated - (see below), you should rely on your own sample rate - callback (see above) for this value. - */ - - fs = jack_get_sample_rate(client); - response_duration = (unsigned long) (fs * duration); - response = malloc(response_duration * sizeof(float)); - fprintf(stderr, - "Grabbing %f seconds (%lu samples) of impulse response\n", - duration, response_duration); - - /* create two ports */ - - input_port = jack_port_register (client, "input", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); - output_port = jack_port_register (client, "output", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); - - /* tell the JACK server that we are ready to roll */ - - if (jack_activate (client)) { - fprintf (stderr, "cannot activate client"); - return 1; - } - - /* connect the ports. Note: you can't do this before - the client is activated (this may change in the future). - */ - - if ((ports = jack_get_ports (client, NULL, NULL, JackPortIsPhysical|JackPortIsOutput)) == NULL) { - fprintf(stderr, "Cannot find any physical capture ports"); - exit(1); - } - - if (jack_connect (client, ports[0], jack_port_name (input_port))) { - fprintf (stderr, "cannot connect input ports\n"); - } - - free (ports); - - if ((ports = jack_get_ports (client, NULL, NULL, JackPortIsPhysical|JackPortIsInput)) == NULL) { - fprintf(stderr, "Cannot find any physical playback ports"); - exit(1); - } - - if (jack_connect (client, jack_port_name (output_port), ports[0])) { - fprintf (stderr, "cannot connect output ports\n"); - } - - free (ports); - - /* install a signal handler to properly quits jack client */ - signal(SIGQUIT, signal_handler); - signal(SIGTERM, signal_handler); - signal(SIGHUP, signal_handler); - signal(SIGINT, signal_handler); - - /* Wait for grab to finish */ - while (!grab_finished) { - sleep (1); - } - jack_client_close (client); - - peak = response[0]; - peak_sample = 0; - if (c_format) { - printf("impulse[%lu] = {", response_duration); - for (i=0; i<response_duration; i++) { - if (i % 4 != 0) { - printf(" "); - } else { - printf("\n\t"); - } - printf("\"%+1.10f\"", response[i]); - if (i < response_duration - 1) { - printf(","); - } - if (fabs(response[i]) > peak) { - peak = fabs(response[i]); - peak_sample = i; - } - } - printf("\n};\n"); - } else { - for (i=0; i<response_duration; i++) { - printf("%1.12f\n", response[i]); - if (fabs(response[i]) > peak) { - peak = fabs(response[i]); - peak_sample = i; - } - } - } - fprintf(stderr, "Peak value was %f at sample %lu\n", peak, peak_sample); - - exit (0); -} diff --git a/example-clients/inprocess.c b/example-clients/inprocess.c deleted file mode 100644 index 1b855c20..00000000 --- a/example-clients/inprocess.c +++ /dev/null @@ -1,125 +0,0 @@ -/** @file inprocess.c - * - * @brief This demonstrates the basic concepts for writing a client - * that runs within the JACK server process. - * - * For the sake of example, a port_pair_t is allocated in - * jack_initialize(), passed to inprocess() as an argument, then freed - * in jack_finish(). - */ - -#include <stdlib.h> -#include <stdio.h> -#include <memory.h> -#include <jack/jack.h> - -/** - * For the sake of example, an instance of this struct is allocated in - * jack_initialize(), passed to inprocess() as an argument, then freed - * in jack_finish(). - */ -typedef struct { - jack_port_t *input_port; - jack_port_t *output_port; -} port_pair_t; - -/** - * Called in the realtime thread on every process cycle. The entry - * point name was passed to jack_set_process_callback() from - * jack_initialize(). Although this is an internal client, its - * process() interface is identical to @ref simple_client.c. - * - * @return 0 if successful; otherwise jack_finish() will be called and - * the client terminated immediately. - */ -int -inprocess (jack_nframes_t nframes, void *arg) -{ - port_pair_t *pp = arg; - jack_default_audio_sample_t *out = - jack_port_get_buffer (pp->output_port, nframes); - jack_default_audio_sample_t *in = - jack_port_get_buffer (pp->input_port, nframes); - - memcpy (out, in, sizeof (jack_default_audio_sample_t) * nframes); - - return 0; /* continue */ -} - -/** - * This required entry point is called after the client is loaded by - * jack_internal_client_load(). - * - * @param client pointer to JACK client structure. - * @param load_init character string passed to the load operation. - * - * @return 0 if successful; otherwise jack_finish() will be called and - * the client terminated immediately. - */ -JACK_LIB_EXPORT -int -jack_initialize (jack_client_t *client, const char *load_init) -{ - port_pair_t *pp = malloc (sizeof (port_pair_t)); - const char **ports; - - if (pp == NULL) - return 1; /* heap exhausted */ - - jack_set_process_callback (client, inprocess, pp); - - /* create a pair of ports */ - pp->input_port = jack_port_register (client, "input", - JACK_DEFAULT_AUDIO_TYPE, - JackPortIsInput, 0); - pp->output_port = jack_port_register (client, "output", - JACK_DEFAULT_AUDIO_TYPE, - JackPortIsOutput, 0); - - /* join the process() cycle */ - jack_activate (client); - - ports = jack_get_ports (client, NULL, NULL, - JackPortIsPhysical|JackPortIsOutput); - if (ports == NULL) { - fprintf(stderr, "no physical capture ports\n"); - return 1; /* terminate client */ - } - - if (jack_connect (client, ports[0], jack_port_name (pp->input_port))) { - fprintf (stderr, "cannot connect input ports\n"); - } - - jack_free (ports); - - ports = jack_get_ports (client, NULL, NULL, - JackPortIsPhysical|JackPortIsInput); - if (ports == NULL) { - fprintf(stderr, "no physical playback ports\n"); - return 1; /* terminate client */ - } - - if (jack_connect (client, jack_port_name (pp->output_port), ports[0])) { - fprintf (stderr, "cannot connect output ports\n"); - } - - jack_free (ports); - - return 0; /* success */ -} - -/** - * This required entry point is called immediately before the client - * is unloaded, which could happen due to a call to - * jack_internal_client_unload(), or a nonzero return from either - * jack_initialize() or inprocess(). - * - * @param arg the same parameter provided to inprocess(). - */ -JACK_LIB_EXPORT -void -jack_finish (void *arg) -{ - if (arg) - free ((port_pair_t *) arg); -} diff --git a/example-clients/internal_metro.cpp b/example-clients/internal_metro.cpp deleted file mode 100644 index 14747d64..00000000 --- a/example-clients/internal_metro.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/* - Copyright (C) 2002 Anthony Van Groningen - Copyright (C) 2005 Grame - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "internal_metro.h" - -typedef jack_default_audio_sample_t sample_t; - -const double PI = 3.14; - -static int process_audio (jack_nframes_t nframes, void* arg) -{ - InternalMetro* metro = (InternalMetro*)arg; - sample_t *buffer = (sample_t *) jack_port_get_buffer (metro->output_port, nframes); - jack_nframes_t frames_left = nframes; - - while (metro->wave_length - metro->offset < frames_left) { - memcpy (buffer + (nframes - frames_left), metro->wave + metro->offset, sizeof (sample_t) * (metro->wave_length - metro->offset)); - frames_left -= metro->wave_length - metro->offset; - metro->offset = 0; - } - if (frames_left > 0) { - memcpy (buffer + (nframes - frames_left), metro->wave + metro->offset, sizeof (sample_t) * frames_left); - metro->offset += frames_left; - } - - return 0; -} - -InternalMetro::InternalMetro(int freq, double max_amp, int dur_arg, int bpm, char* client_name) -{ - sample_t scale; - int i, attack_length, decay_length; - int attack_percent = 1, decay_percent = 10; - const char *bpm_string = "bpm"; - - offset = 0; - - /* Initial Jack setup, get sample rate */ - if (!client_name) { - client_name = (char *) malloc (9 * sizeof (char)); - strcpy (client_name, "metro"); - } - if ((client = jack_client_open (client_name, JackNullOption, NULL)) == 0) { - fprintf (stderr, "jack server not running?\n"); - return; - } - - jack_set_process_callback (client, process_audio, this); - output_port = jack_port_register (client, bpm_string, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); - input_port = jack_port_register (client, "metro_in", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); - - sr = jack_get_sample_rate (client); - - /* setup wave table parameters */ - wave_length = 60 * sr / bpm; - tone_length = sr * dur_arg / 1000; - attack_length = tone_length * attack_percent / 100; - decay_length = tone_length * decay_percent / 100; - scale = 2 * PI * freq / sr; - - if (tone_length >= wave_length) { - /* - fprintf (stderr, "invalid duration (tone length = %" PRIu32 - ", wave length = %" PRIu32 "\n", tone_length, - wave_length); - */ - return; - } - if (attack_length + decay_length > (int)tone_length) { - fprintf (stderr, "invalid attack/decay\n"); - return; - } - - /* Build the wave table */ - wave = (sample_t *) malloc (wave_length * sizeof(sample_t)); - amp = (double *) malloc (tone_length * sizeof(double)); - - for (i = 0; i < attack_length; i++) { - amp[i] = max_amp * i / ((double) attack_length); - } - for (i = attack_length; i < (int) tone_length - decay_length; i++) { - amp[i] = max_amp; - } - for (i = (int)tone_length - decay_length; i < (int)tone_length; i++) { - amp[i] = - max_amp * (i - (double) tone_length) / ((double) decay_length); - } - for (i = 0; i < (int) tone_length; i++) { - wave[i] = amp[i] * sin (scale * i); - } - for (i = tone_length; i < (int) wave_length; i++) { - wave[i] = 0; - } - - if (jack_activate (client)) { - fprintf(stderr, "cannot activate client"); - } -} - -InternalMetro::~InternalMetro() -{ - jack_deactivate(client); - jack_port_unregister(client, input_port); - jack_port_unregister(client, output_port); - jack_client_close(client); - free(amp); - free(wave); -} diff --git a/example-clients/internal_metro.h b/example-clients/internal_metro.h deleted file mode 100644 index 7febb6dc..00000000 --- a/example-clients/internal_metro.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - Copyright (C) 2001 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#ifndef __internal_metro__ -#define __internal_metro__ - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include <stdlib.h> -#include <stdio.h> -#include <errno.h> -#include <unistd.h> -#include <math.h> -#include <getopt.h> -#include <string.h> - -#include "jack.h" -#include "transport.h" - - - typedef jack_default_audio_sample_t sample_t; - - /*! - \brief A class to test internal clients - */ - - struct InternalMetro { - - jack_client_t *client; - jack_port_t *input_port; - jack_port_t *output_port; - - unsigned long sr; - int freq; - int bpm; - jack_nframes_t tone_length, wave_length; - sample_t *wave; - double *amp; - long offset ; - - InternalMetro(int freq, double max_amp, int dur_arg, int bpm, char* client_name); - virtual ~InternalMetro(); - - }; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/example-clients/latent_client.c b/example-clients/latent_client.c deleted file mode 100644 index 3df147e1..00000000 --- a/example-clients/latent_client.c +++ /dev/null @@ -1,217 +0,0 @@ -/** @file latent_client.c - * - * @brief This simple client demonstrates the most basic features of JACK - * as they would be used by many applications. - */ - -#include <stdio.h> -#include <errno.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <inttypes.h> - -#include <jack/jack.h> - -jack_port_t *input_port; -jack_port_t *output_port; -jack_client_t *client; - -jack_default_audio_sample_t *delay_line; -jack_nframes_t delay_index; -jack_nframes_t latency = 1024; - -#ifdef WIN32 -#define jack_sleep(val) Sleep((val)) -#else -#define jack_sleep(val) usleep((val) * 1000) -#endif - -/** - * The process callback for this JACK application is called in a - * special realtime thread once for each audio cycle. - * - * This client does nothing more than copy data from its input - * port to its output port. It will exit when stopped by - * the user (e.g. using Ctrl-C on a unix-ish operating system) - */ -int -process (jack_nframes_t nframes, void *arg) -{ - jack_default_audio_sample_t *in, *out; - int k; - - in = jack_port_get_buffer (input_port, nframes); - out = jack_port_get_buffer (output_port, nframes); - - for (k=0; k<nframes; k++) { - out[k] = delay_line[delay_index]; - delay_line[delay_index] = in[k]; - delay_index = (delay_index + 1) % latency; - } - - return 0; -} - -void -latency_cb (jack_latency_callback_mode_t mode, void *arg) -{ - jack_latency_range_t range; - if (mode == JackCaptureLatency) { - jack_port_get_latency_range (input_port, mode, &range); - range.min += latency; - range.max += latency; - jack_port_set_latency_range (output_port, mode, &range); - } else { - jack_port_get_latency_range (output_port, mode, &range); - range.min += latency; - range.max += latency; - jack_port_set_latency_range (input_port, mode, &range); - } -} - -/** - * JACK calls this shutdown_callback if the server ever shuts down or - * decides to disconnect the client. - */ -void -jack_shutdown (void *arg) -{ - fprintf(stderr, "JACK shut down, exiting ...\n"); - exit (1); -} - -int -main (int argc, char *argv[]) -{ - const char **ports; - const char *client_name = "latent"; - const char *server_name = NULL; - jack_options_t options = JackNullOption; - jack_status_t status; - - - if (argc == 2) - latency = atoi(argv[1]); - - delay_line = malloc( latency * sizeof(jack_default_audio_sample_t)); - if (delay_line == NULL) { - fprintf (stderr, "no memory"); - exit(1); - } - - memset (delay_line, 0, latency * sizeof(jack_default_audio_sample_t)); - - /* open a client connection to the JACK server */ - - client = jack_client_open (client_name, options, &status, server_name); - if (client == NULL) { - fprintf (stderr, "jack_client_open() failed, " - "status = 0x%2.0x\n", status); - if (status & JackServerFailed) { - fprintf (stderr, "Unable to connect to JACK server\n"); - } - exit (1); - } - if (status & JackServerStarted) { - fprintf (stderr, "JACK server started\n"); - } - if (status & JackNameNotUnique) { - client_name = jack_get_client_name(client); - fprintf (stderr, "unique name `%s' assigned\n", client_name); - } - - /* tell the JACK server to call `process()' whenever - there is work to be done. - */ - - jack_set_process_callback (client, process, 0); - - /* tell the JACK server to call `latency()' whenever - the latency needs to be recalculated. - */ - if (jack_set_latency_callback) - jack_set_latency_callback (client, latency_cb, 0); - - /* tell the JACK server to call `jack_shutdown()' if - it ever shuts down, either entirely, or if it - just decides to stop calling us. - */ - - jack_on_shutdown (client, jack_shutdown, 0); - - /* display the current sample rate. - */ - - printf ("engine sample rate: %" PRIu32 "\n", - jack_get_sample_rate (client)); - - /* create two ports */ - - input_port = jack_port_register (client, "input", - JACK_DEFAULT_AUDIO_TYPE, - JackPortIsInput, 0); - output_port = jack_port_register (client, "output", - JACK_DEFAULT_AUDIO_TYPE, - JackPortIsOutput, 0); - - if ((input_port == NULL) || (output_port == NULL)) { - fprintf(stderr, "no more JACK ports available\n"); - exit (1); - } - - /* Tell the JACK server that we are ready to roll. Our - * process() callback will start running now. */ - - if (jack_activate (client)) { - fprintf (stderr, "cannot activate client"); - exit (1); - } - - /* Connect the ports. You can't do this before the client is - * activated, because we can't make connections to clients - * that aren't running. Note the confusing (but necessary) - * orientation of the driver backend ports: playback ports are - * "input" to the backend, and capture ports are "output" from - * it. - */ - - ports = jack_get_ports (client, NULL, NULL, - JackPortIsPhysical|JackPortIsOutput); - if (ports == NULL) { - fprintf(stderr, "no physical capture ports\n"); - exit (1); - } - - if (jack_connect (client, ports[0], jack_port_name (input_port))) { - fprintf (stderr, "cannot connect input ports\n"); - } - - free (ports); - - ports = jack_get_ports (client, NULL, NULL, - JackPortIsPhysical|JackPortIsInput); - if (ports == NULL) { - fprintf(stderr, "no physical playback ports\n"); - exit (1); - } - - if (jack_connect (client, jack_port_name (output_port), ports[0])) { - fprintf (stderr, "cannot connect output ports\n"); - } - - free (ports); - - /* keep running until stopped by the user */ - - jack_sleep (-1); - - /* this is never reached but if the program - had some other way to exit besides being killed, - they would be important to call. - */ - - jack_client_close (client); - exit (0); -} - diff --git a/example-clients/metro.c b/example-clients/metro.c deleted file mode 100644 index 229eca10..00000000 --- a/example-clients/metro.c +++ /dev/null @@ -1,302 +0,0 @@ -/* - Copyright (C) 2002 Anthony Van Groningen - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include <stdlib.h> -#include <stdio.h> -#include <errno.h> -#ifndef WIN32 -#include <unistd.h> -#endif -#include <math.h> -#include <signal.h> -#include <getopt.h> -#include <string.h> - -#include <jack/jack.h> -#include <jack/transport.h> - -typedef jack_default_audio_sample_t sample_t; - -const double PI = 3.14; - -jack_client_t *client; -jack_port_t *output_port; -unsigned long sr; -int freq = 880; -int bpm; -jack_nframes_t tone_length, wave_length; -sample_t *wave; -long offset = 0; -int transport_aware = 0; -jack_transport_state_t transport_state; - -static void signal_handler(int sig) -{ - jack_client_close(client); - fprintf(stderr, "signal received, exiting ...\n"); - exit(0); -} - -static void -usage () -{ - fprintf (stderr, "\n" -"usage: jack_metro \n" -" [ --frequency OR -f frequency (in Hz) ]\n" -" [ --amplitude OR -A maximum amplitude (between 0 and 1) ]\n" -" [ --duration OR -D duration (in ms) ]\n" -" [ --attack OR -a attack (in percent of duration) ]\n" -" [ --decay OR -d decay (in percent of duration) ]\n" -" [ --name OR -n jack name for metronome client ]\n" -" [ --transport OR -t transport aware ]\n" -" --bpm OR -b beats per minute\n" -); -} - -static void -process_silence (jack_nframes_t nframes) -{ - sample_t *buffer = (sample_t *) jack_port_get_buffer (output_port, nframes); - memset (buffer, 0, sizeof (jack_default_audio_sample_t) * nframes); -} - -jack_nframes_t last_time; -jack_time_t last_micro_time; - -static void -process_audio (jack_nframes_t nframes) -{ - sample_t *buffer = (sample_t *) jack_port_get_buffer (output_port, nframes); - jack_nframes_t frames_left = nframes; - - while (wave_length - offset < frames_left) { - memcpy (buffer + (nframes - frames_left), wave + offset, sizeof (sample_t) * (wave_length - offset)); - frames_left -= wave_length - offset; - offset = 0; - } - if (frames_left > 0) { - memcpy (buffer + (nframes - frames_left), wave + offset, sizeof (sample_t) * frames_left); - offset += frames_left; - } - - /* - jack_nframes_t cur_time = jack_frame_time(client); - jack_time_t cur_micro_time = jack_get_time(); - - printf("jack_frame_time %lld micro %lld delta %d\n", cur_time, (cur_micro_time - last_micro_time), cur_time - last_time); - last_time = cur_time; - last_micro_time = cur_micro_time; - */ -} - -static int -process (jack_nframes_t nframes, void *arg) -{ - if (transport_aware) { - jack_position_t pos; - - if (jack_transport_query (client, &pos) - != JackTransportRolling) { - - process_silence (nframes); - return 0; - } - offset = pos.frame % wave_length; - } - process_audio (nframes); - return 0; -} - -int -main (int argc, char *argv[]) -{ - sample_t scale; - int i, attack_length, decay_length; - double *amp; - double max_amp = 0.5; - int option_index; - int opt; - int got_bpm = 0; - int attack_percent = 1, decay_percent = 10, dur_arg = 100; - char *client_name = 0; - char *bpm_string = "bpm"; - int verbose = 0; - jack_status_t status; - - const char *options = "f:A:D:a:d:b:n:thv"; - struct option long_options[] = - { - {"frequency", 1, 0, 'f'}, - {"amplitude", 1, 0, 'A'}, - {"duration", 1, 0, 'D'}, - {"attack", 1, 0, 'a'}, - {"decay", 1, 0, 'd'}, - {"bpm", 1, 0, 'b'}, - {"name", 1, 0, 'n'}, - {"transport", 0, 0, 't'}, - {"help", 0, 0, 'h'}, - {"verbose", 0, 0, 'v'}, - {0, 0, 0, 0} - }; - - while ((opt = getopt_long (argc, argv, options, long_options, &option_index)) != -1) { - switch (opt) { - case 'f': - if ((freq = atoi (optarg)) <= 0) { - fprintf (stderr, "invalid frequency\n"); - return -1; - } - break; - case 'A': - if (((max_amp = atof (optarg)) <= 0)|| (max_amp > 1)) { - fprintf (stderr, "invalid amplitude\n"); - return -1; - } - break; - case 'D': - dur_arg = atoi (optarg); - fprintf (stderr, "durarg = %u\n", dur_arg); - break; - case 'a': - if (((attack_percent = atoi (optarg)) < 0) || (attack_percent > 100)) { - fprintf (stderr, "invalid attack percent\n"); - return -1; - } - break; - case 'd': - if (((decay_percent = atoi (optarg)) < 0) || (decay_percent > 100)) { - fprintf (stderr, "invalid decay percent\n"); - return -1; - } - break; - case 'b': - got_bpm = 1; - if ((bpm = atoi (optarg)) < 0) { - fprintf (stderr, "invalid bpm\n"); - return -1; - } - bpm_string = (char *) malloc ((strlen (optarg) + 5) * sizeof (char)); - strcpy (bpm_string, optarg); - strcat (bpm_string, "_bpm"); - break; - case 'n': - client_name = (char *) malloc ((strlen (optarg) + 1) * sizeof (char)); - strcpy (client_name, optarg); - break; - case 'v': - verbose = 1; - break; - case 't': - transport_aware = 1; - break; - default: - fprintf (stderr, "unknown option %c\n", opt); - case 'h': - usage (); - return -1; - } - } - if (!got_bpm) { - fprintf (stderr, "bpm not specified\n"); - usage (); - return -1; - } - - /* Initial Jack setup, get sample rate */ - if (!client_name) { - client_name = (char *) malloc (9 * sizeof (char)); - strcpy (client_name, "metro"); - } - if ((client = jack_client_open (client_name, JackNoStartServer, &status)) == 0) { - fprintf (stderr, "JACK server not running?\n"); - return 1; - } - jack_set_process_callback (client, process, 0); - output_port = jack_port_register (client, bpm_string, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); - - sr = jack_get_sample_rate (client); - - /* setup wave table parameters */ - wave_length = 60 * sr / bpm; - tone_length = sr * dur_arg / 1000; - attack_length = tone_length * attack_percent / 100; - decay_length = tone_length * decay_percent / 100; - scale = 2 * PI * freq / sr; - - if (tone_length >= wave_length) { - fprintf (stderr, "invalid duration (tone length = %u, wave length = %u\n", tone_length, wave_length); - return -1; - } - if (attack_length + decay_length > (int)tone_length) { - fprintf (stderr, "invalid attack/decay\n"); - return -1; - } - - /* Build the wave table */ - wave = (sample_t *) malloc (wave_length * sizeof(sample_t)); - amp = (double *) malloc (tone_length * sizeof(double)); - - for (i = 0; i < attack_length; i++) { - amp[i] = max_amp * i / ((double) attack_length); - } - for (i = attack_length; i < (int)tone_length - decay_length; i++) { - amp[i] = max_amp; - } - for (i = (int)tone_length - decay_length; i < (int)tone_length; i++) { - amp[i] = - max_amp * (i - (double) tone_length) / ((double) decay_length); - } - for (i = 0; i < (int)tone_length; i++) { - wave[i] = amp[i] * sin (scale * i); - } - for (i = tone_length; i < (int)wave_length; i++) { - wave[i] = 0; - } - - if (jack_activate (client)) { - fprintf (stderr, "cannot activate client\n"); - goto error; - } - - /* install a signal handler to properly quits jack client */ -#ifdef WIN32 - signal(SIGINT, signal_handler); - signal(SIGABRT, signal_handler); - signal(SIGTERM, signal_handler); -#else - signal(SIGQUIT, signal_handler); - signal(SIGTERM, signal_handler); - signal(SIGHUP, signal_handler); - signal(SIGINT, signal_handler); -#endif - - /* run until interrupted */ - while (1) { -#ifdef WIN32 - Sleep(1000); -#else - sleep(1); -#endif - }; - - jack_client_close(client); - -error: - free(amp); - free(wave); - exit (0); -} diff --git a/example-clients/midi_latency_test.c b/example-clients/midi_latency_test.c deleted file mode 100644 index b70d7243..00000000 --- a/example-clients/midi_latency_test.c +++ /dev/null @@ -1,969 +0,0 @@ -/* -Copyright (C) 2010 Devin Anderson - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation; either version 2.1 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -/* - * This program is used to measure MIDI latency and jitter. It writes MIDI - * messages to one port and calculates how long it takes before it reads the - * same MIDI message over another port. It was written to calculate the - * latency and jitter of hardware and JACK hardware drivers, but might have - * other practical applications. - * - * The latency results of the program include the latency introduced by the - * JACK system. Because JACK has sample accurate MIDI, the same latency - * imposed on audio is also imposed on MIDI going through the system. Make - * sure you take this into account before complaining to me or (*especially*) - * other JACK developers about reported MIDI latency. - * - * The jitter results are a little more interesting. The program attempts to - * calculate 'average jitter' and 'peak jitter', as defined here: - * - * http://openmuse.org/transport/fidelity.html - * - * It also outputs a jitter plot, which gives you a more specific idea about - * the MIDI jitter for the ports you're testing. This is useful for catching - * extreme jitter values, and for analyzing the amount of truth in the - * technical specifications for your MIDI interface(s). :) - * - * This program is loosely based on 'alsa-midi-latency-test' in the ALSA test - * suite. - * - * To port this program to non-POSIX platforms, you'll have to include - * implementations for semaphores and command-line argument handling. - */ - -#include <assert.h> -#include <errno.h> -#include <math.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include <getopt.h> - -#include <jack/jack.h> -#include <jack/midiport.h> - -#ifdef WIN32 -#include <windows.h> -#include <unistd.h> -#else -#include <semaphore.h> -#endif - -#define ABS(x) (((x) >= 0) ? (x) : (-(x))) - -#ifdef WIN32 -typedef HANDLE semaphore_t; -#else -typedef sem_t *semaphore_t; -#endif - -const char *ERROR_MSG_TIMEOUT = "timed out while waiting for MIDI message"; -const char *ERROR_RESERVE = "could not reserve MIDI event on port buffer"; -const char *ERROR_SHUTDOWN = "the JACK server has been shutdown"; - -const char *SOURCE_EVENT_RESERVE = "jack_midi_event_reserve"; -const char *SOURCE_PROCESS = "handle_process"; -const char *SOURCE_SHUTDOWN = "handle_shutdown"; -const char *SOURCE_SIGNAL_SEMAPHORE = "signal_semaphore"; -const char *SOURCE_WAIT_SEMAPHORE = "wait_semaphore"; - -char *alias1; -char *alias2; -jack_client_t *client; -semaphore_t connect_semaphore; -volatile int connections_established; -const char *error_message; -const char *error_source; -jack_nframes_t highest_latency; -jack_time_t highest_latency_time; -jack_latency_range_t in_latency_range; -jack_port_t *in_port; -semaphore_t init_semaphore; -jack_nframes_t last_activity; -jack_time_t last_activity_time; -jack_time_t *latency_time_values; -jack_nframes_t *latency_values; -jack_nframes_t lowest_latency; -jack_time_t lowest_latency_time; -jack_midi_data_t *message_1; -jack_midi_data_t *message_2; -int messages_received; -int messages_sent; -size_t message_size; -jack_latency_range_t out_latency_range; -jack_port_t *out_port; -semaphore_t process_semaphore; -volatile sig_atomic_t process_state; -char *program_name; -jack_port_t *remote_in_port; -jack_port_t *remote_out_port; -size_t samples; -const char *target_in_port_name; -const char *target_out_port_name; -int timeout; -jack_nframes_t total_latency; -jack_time_t total_latency_time; -int unexpected_messages; -int xrun_count; - -#ifdef WIN32 -char semaphore_error_msg[1024]; -#endif - -static void -output_error(const char *source, const char *message); - -static void -output_usage(void); - -static void -set_process_error(const char *source, const char *message); - -static int -signal_semaphore(semaphore_t semaphore); - -static jack_port_t * -update_connection(jack_port_t *remote_port, int connected, - jack_port_t *local_port, jack_port_t *current_port, - const char *target_name); - -static int -wait_semaphore(semaphore_t semaphore, int block); - -static semaphore_t -create_semaphore(int id) -{ - semaphore_t semaphore; - -#ifdef WIN32 - semaphore = CreateSemaphore(NULL, 0, 2, NULL); -#elif defined (__APPLE__) - char name[128]; - sprintf(name, "midi_sem_%d", id); - semaphore = sem_open(name, O_CREAT, 0777, 0); - if (semaphore == (sem_t *) SEM_FAILED) { - semaphore = NULL; - } -#else - semaphore = malloc(sizeof(sem_t)); - if (semaphore != NULL) { - if (sem_init(semaphore, 0, 0)) { - free(semaphore); - semaphore = NULL; - } - } -#endif - - return semaphore; -} - -static void -destroy_semaphore(semaphore_t semaphore, int id) -{ - -#ifdef WIN32 - CloseHandle(semaphore); -#else - sem_destroy(semaphore); -#ifdef __APPLE__ - { - char name[128]; - sprintf(name, "midi_sem_%d", id); - sem_close(semaphore); - sem_unlink(name); - } -#else - free(semaphore); -#endif -#endif - -} - -static void -die(const char *source, const char *error_message) -{ - output_error(source, error_message); - output_usage(); - exit(EXIT_FAILURE); -} - -static const char * -get_semaphore_error(void) -{ - -#ifdef WIN32 - DWORD error = GetLastError(); - if (! FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - semaphore_error_msg, 1024, NULL)) { - snprintf(semaphore_error_msg, 1023, "Unknown OS error code '%ld'", - error); - } - return semaphore_error_msg; -#else - return strerror(errno); -#endif - -} - -static void -handle_info(const char *message) -{ - /* Suppress info */ -} - -static void -handle_port_connection_change(jack_port_id_t port_id_1, - jack_port_id_t port_id_2, int connected, - void *arg) -{ - jack_port_t *port_1; - jack_port_t *port_2; - if ((remote_in_port != NULL) && (remote_out_port != NULL)) { - return; - } - port_1 = jack_port_by_id(client, port_id_1); - port_2 = jack_port_by_id(client, port_id_2); - - /* The 'update_connection' call is not RT-safe. It calls - 'jack_port_get_connections' and 'jack_free'. This might be a problem - with JACK 1, as this callback runs in the process thread in JACK 1. */ - - if (port_1 == in_port) { - remote_in_port = update_connection(port_2, connected, in_port, - remote_in_port, - target_in_port_name); - } else if (port_2 == in_port) { - remote_in_port = update_connection(port_1, connected, in_port, - remote_in_port, - target_in_port_name); - } else if (port_1 == out_port) { - remote_out_port = update_connection(port_2, connected, out_port, - remote_out_port, - target_out_port_name); - } else if (port_2 == out_port) { - remote_out_port = update_connection(port_1, connected, out_port, - remote_out_port, - target_out_port_name); - } - if ((remote_in_port != NULL) && (remote_out_port != NULL)) { - connections_established = 1; - if (! signal_semaphore(connect_semaphore)) { - /* Sigh ... */ - die("post_semaphore", get_semaphore_error()); - } - if (! signal_semaphore(init_semaphore)) { - /* Sigh ... */ - die("post_semaphore", get_semaphore_error()); - } - } -} - -static int -handle_process(jack_nframes_t frames, void *arg) -{ - jack_midi_data_t *buffer; - jack_midi_event_t event; - jack_nframes_t event_count; - jack_nframes_t event_time; - jack_nframes_t frame; - size_t i; - jack_nframes_t last_frame_time; - jack_midi_data_t *message; - jack_time_t microseconds; - void *port_buffer; - jack_time_t time; - jack_midi_clear_buffer(jack_port_get_buffer(out_port, frames)); - switch (process_state) { - - case 0: - /* State: initializing */ - switch (wait_semaphore(init_semaphore, 0)) { - case -1: - set_process_error(SOURCE_WAIT_SEMAPHORE, get_semaphore_error()); - /* Fallthrough on purpose */ - case 0: - return 0; - } - highest_latency = 0; - lowest_latency = 0; - messages_received = 0; - messages_sent = 0; - process_state = 1; - total_latency = 0; - total_latency_time = 0; - unexpected_messages = 0; - xrun_count = 0; - jack_port_get_latency_range(remote_in_port, JackCaptureLatency, - &in_latency_range); - jack_port_get_latency_range(remote_out_port, JackPlaybackLatency, - &out_latency_range); - goto send_message; - - case 1: - /* State: processing */ - port_buffer = jack_port_get_buffer(in_port, frames); - event_count = jack_midi_get_event_count(port_buffer); - last_frame_time = jack_last_frame_time(client); - for (i = 0; i < event_count; i++) { - jack_midi_event_get(&event, port_buffer, i); - message = (messages_received % 2) ? message_2 : message_1; - if ((event.size == message_size) && - (! memcmp(message, event.buffer, - message_size * sizeof(jack_midi_data_t)))) { - goto found_message; - } - unexpected_messages++; - } - microseconds = jack_frames_to_time(client, last_frame_time) - - last_activity_time; - if ((microseconds / 1000000) >= timeout) { - set_process_error(SOURCE_PROCESS, ERROR_MSG_TIMEOUT); - } - break; - found_message: - event_time = last_frame_time + event.time; - frame = event_time - last_activity; - time = jack_frames_to_time(client, event_time) - last_activity_time; - if ((! highest_latency) || (frame > highest_latency)) { - highest_latency = frame; - highest_latency_time = time; - } - if ((! lowest_latency) || (frame < lowest_latency)) { - lowest_latency = frame; - lowest_latency_time = time; - } - latency_time_values[messages_received] = time; - latency_values[messages_received] = frame; - total_latency += frame; - total_latency_time += time; - messages_received++; - if (messages_received == samples) { - process_state = 2; - if (! signal_semaphore(process_semaphore)) { - /* Sigh ... */ - die(SOURCE_SIGNAL_SEMAPHORE, get_semaphore_error()); - } - break; - } - send_message: - frame = (jack_nframes_t) ((((double) rand()) / RAND_MAX) * frames); - if (frame >= frames) { - frame = frames - 1; - } - port_buffer = jack_port_get_buffer(out_port, frames); - buffer = jack_midi_event_reserve(port_buffer, frame, message_size); - if (buffer == NULL) { - set_process_error(SOURCE_EVENT_RESERVE, ERROR_RESERVE); - break; - } - message = (messages_sent % 2) ? message_2 : message_1; - memcpy(buffer, message, message_size * sizeof(jack_midi_data_t)); - last_activity = jack_last_frame_time(client) + frame; - last_activity_time = jack_frames_to_time(client, last_activity); - messages_sent++; - - case 2: - /* State: finished - do nothing */ - case -1: - /* State: error - do nothing */ - case -2: - /* State: signalled - do nothing */ - ; - } - return 0; -} - -static void -handle_shutdown(void *arg) -{ - set_process_error(SOURCE_SHUTDOWN, ERROR_SHUTDOWN); -} - -static void -handle_signal(int sig) -{ - process_state = -2; - if (! signal_semaphore(connect_semaphore)) { - /* Sigh ... */ - die(SOURCE_SIGNAL_SEMAPHORE, get_semaphore_error()); - } - if (! signal_semaphore(process_semaphore)) { - /* Sigh ... */ - die(SOURCE_SIGNAL_SEMAPHORE, get_semaphore_error()); - } -} - -static int -handle_xrun(void *arg) -{ - xrun_count++; - return 0; -} - -static void -output_error(const char *source, const char *message) -{ - fprintf(stderr, "%s: %s: %s\n", program_name, source, message); -} - -static void -output_usage(void) -{ - fprintf(stderr, "Usage: %s [options] [out-port-name in-port-name]\n\n" - "\t-h, --help print program usage\n" - "\t-m, --message-size=size set size of MIDI messages to send " - "(default: 3)\n" - "\t-s, --samples=n number of MIDI messages to send " - "(default: 1024)\n" - "\t-t, --timeout=seconds message timeout (default: 5)\n\n", - program_name); -} - -static unsigned long -parse_positive_number_arg(char *s, char *name) -{ - char *end_ptr; - unsigned long result; - errno = 0; - result = strtoul(s, &end_ptr, 10); - if (errno) { - die(name, strerror(errno)); - } - if (*s == '\0') { - die(name, "argument value cannot be empty"); - } - if (*end_ptr != '\0') { - die(name, "invalid value"); - } - if (! result) { - die(name, "must be a positive number"); - } - return result; -} - -static int -register_signal_handler(void (*func)(int)) -{ - -#ifdef WIN32 - if (signal(SIGABRT, func) == SIG_ERR) { - return 0; - } -#else - if (signal(SIGQUIT, func) == SIG_ERR) { - return 0; - } - if (signal(SIGHUP, func) == SIG_ERR) { - return 0; - } -#endif - - if (signal(SIGINT, func) == SIG_ERR) { - return 0; - } - if (signal(SIGTERM, func) == SIG_ERR) { - return 0; - } - return 1; -} - -static void -set_process_error(const char *source, const char *message) -{ - error_source = source; - error_message = message; - process_state = -1; - if (! signal_semaphore(process_semaphore)) { - /* Sigh ... */ - output_error(source, message); - die(SOURCE_SIGNAL_SEMAPHORE, get_semaphore_error()); - } -} - -static int -signal_semaphore(semaphore_t semaphore) -{ - -#ifdef WIN32 - return ReleaseSemaphore(semaphore, 1, NULL); -#else - return ! sem_post(semaphore); -#endif - -} - -static jack_port_t * -update_connection(jack_port_t *remote_port, int connected, - jack_port_t *local_port, jack_port_t *current_port, - const char *target_name) -{ - if (connected) { - if (current_port) { - return current_port; - } - if (target_name) { - char *aliases[2]; - if (! strcmp(target_name, jack_port_name(remote_port))) { - return remote_port; - } - aliases[0] = alias1; - aliases[1] = alias2; - switch (jack_port_get_aliases(remote_port, aliases)) { - case -1: - /* Sigh ... */ - die("jack_port_get_aliases", "Failed to get port aliases"); - case 2: - if (! strcmp(target_name, alias2)) { - return remote_port; - } - /* Fallthrough on purpose */ - case 1: - if (! strcmp(target_name, alias1)) { - return remote_port; - } - /* Fallthrough on purpose */ - case 0: - return NULL; - } - /* This shouldn't happen. */ - assert(0); - } - return remote_port; - } - if (! strcmp(jack_port_name(remote_port), jack_port_name(current_port))) { - const char **port_names; - if (target_name) { - return NULL; - } - port_names = jack_port_get_connections(local_port); - if (port_names == NULL) { - return NULL; - } - - /* If a connected port is disconnected and other ports are still - connected, then we take the first port name in the array and use it - as our remote port. It's a dumb implementation. */ - current_port = jack_port_by_name(client, port_names[0]); - jack_free(port_names); - if (current_port == NULL) { - /* Sigh */ - die("jack_port_by_name", "failed to get port by name"); - } - } - return current_port; -} - -static int -wait_semaphore(semaphore_t semaphore, int block) -{ - -#ifdef WIN32 - DWORD result = WaitForSingleObject(semaphore, block ? INFINITE : 0); - switch (result) { - case WAIT_OBJECT_0: - return 1; - case WAIT_TIMEOUT: - return 0; - } - return -1; -#else - if (block) { - while (sem_wait(semaphore)) { - if (errno != EINTR) { - return -1; - } - } - } else { - while (sem_trywait(semaphore)) { - switch (errno) { - case EAGAIN: - return 0; - case EINTR: - continue; - default: - return -1; - } - } - } - return 1; -#endif - -} - -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; -} diff --git a/example-clients/midiseq.c b/example-clients/midiseq.c deleted file mode 100644 index 45085e80..00000000 --- a/example-clients/midiseq.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - Copyright (C) 2004 Ian Esten - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include <jack/jack.h> -#include <jack/midiport.h> -#include <stdio.h> -#include <signal.h> -#include <stdlib.h> -#include <unistd.h> - -jack_client_t *client; -jack_port_t *output_port; - -unsigned char* note_frqs; -jack_nframes_t* note_starts; -jack_nframes_t* note_lengths; -jack_nframes_t num_notes; -jack_nframes_t loop_nsamp; -jack_nframes_t loop_index; - -static void signal_handler(int sig) -{ - jack_client_close(client); - fprintf(stderr, "signal received, exiting ...\n"); - exit(0); -} - -static void usage() -{ - fprintf(stderr, "usage: jack_midiseq name nsamp [startindex note nsamp] ...... [startindex note nsamp]\n"); - fprintf(stderr, "eg: jack_midiseq Sequencer 24000 0 60 8000 12000 63 8000\n"); - fprintf(stderr, "will play a 1/2 sec loop (if srate is 48khz) with a c4 note at the start of the loop\n"); - fprintf(stderr, "that lasts for 12000 samples, then a d4# that starts at 1/4 sec that lasts for 800 samples\n"); -} - -static int process(jack_nframes_t nframes, void *arg) -{ - int i,j; - void* port_buf = jack_port_get_buffer(output_port, nframes); - unsigned char* buffer; - jack_midi_clear_buffer(port_buf); - /*memset(buffer, 0, nframes*sizeof(jack_default_audio_sample_t));*/ - - for (i = 0; i < nframes; i++) { - for (j = 0; j < num_notes; j++) { - if (note_starts[j] == loop_index) { - if ((buffer = jack_midi_event_reserve(port_buf, i, 3))) { - /* printf("wrote a note on, port buffer = 0x%x, event buffer = 0x%x\n", port_buf, buffer); */ - buffer[2] = 64; /* velocity */ - buffer[1] = note_frqs[j]; - buffer[0] = 0x90; /* note on */ - } - } else if (note_starts[j] + note_lengths[j] == loop_index) { - if ((buffer = jack_midi_event_reserve(port_buf, i, 3))) { - /* printf("wrote a note off, port buffer = 0x%x, event buffer = 0x%x\n", port_buf, buffer); */ - buffer[2] = 64; /* velocity */ - buffer[1] = note_frqs[j]; - buffer[0] = 0x80; /* note off */ - } - } - } - loop_index = loop_index+1 >= loop_nsamp ? 0 : loop_index+1; - } - return 0; -} - -int main(int narg, char **args) -{ - int i; - jack_nframes_t nframes; - if ((narg<6) || ((narg-3)%3 != 0)) { - usage(); - exit(1); - } - if ((client = jack_client_open (args[1], JackNullOption, NULL)) == 0) { - fprintf (stderr, "JACK server not running?\n"); - return 1; - } - jack_set_process_callback (client, process, 0); - output_port = jack_port_register (client, "out", JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0); - nframes = jack_get_buffer_size(client); - loop_index = 0; - num_notes = (narg - 3)/3; - note_frqs = malloc(num_notes*sizeof(unsigned char)); - note_starts = malloc(num_notes*sizeof(jack_nframes_t)); - note_lengths = malloc(num_notes*sizeof(jack_nframes_t)); - loop_nsamp = atoi(args[2]); - for (i = 0; i < num_notes; i++) { - note_starts[i] = atoi(args[3 + 3*i]); - note_frqs[i] = atoi(args[4 + 3*i]); - note_lengths[i] = atoi(args[5 + 3*i]); - } - - if (jack_activate(client)) { - fprintf (stderr, "cannot activate client"); - return 1; - } - - /* install a signal handler to properly quits jack client */ -#ifndef WIN32 - signal(SIGQUIT, signal_handler); - signal(SIGHUP, signal_handler); -#endif - signal(SIGTERM, signal_handler); - signal(SIGINT, signal_handler); - - /* run until interrupted */ - while (1) { -#ifdef WIN32 - Sleep(1*1000); -#else - sleep(1); -#endif - }; - - jack_client_close(client); - exit (0); -} diff --git a/example-clients/midisine.c b/example-clients/midisine.c deleted file mode 100644 index 4a00c428..00000000 --- a/example-clients/midisine.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - Copyright (C) 2004 Ian Esten - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include <stdio.h> -#include <errno.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <signal.h> -#include <math.h> -#include <inttypes.h> - -#include <jack/jack.h> -#include <jack/midiport.h> - -jack_port_t *input_port; -jack_port_t *output_port; -jack_default_audio_sample_t ramp=0.0; -jack_default_audio_sample_t note_on; -unsigned char note = 0; -jack_default_audio_sample_t note_frqs[128]; - -jack_client_t *client; - -static void signal_handler(int sig) -{ - jack_client_close(client); - fprintf(stderr, "signal received, exiting ...\n"); - exit(0); -} - -static void calc_note_frqs(jack_default_audio_sample_t srate) -{ - int i; - for(i=0; i<128; i++) - { - note_frqs[i] = (2.0 * 440.0 / 32.0) * pow(2, (((jack_default_audio_sample_t)i - 9.0) / 12.0)) / srate; - } -} - -static int process(jack_nframes_t nframes, void *arg) -{ - int i; - void* port_buf = jack_port_get_buffer(input_port, nframes); - jack_default_audio_sample_t *out = (jack_default_audio_sample_t *) jack_port_get_buffer (output_port, nframes); - jack_midi_event_t in_event; - jack_nframes_t event_index = 0; - jack_nframes_t event_count = jack_midi_get_event_count(port_buf); - if(event_count > 1) - { - printf(" midisine: have %d events\n", event_count); - for(i=0; i<event_count; i++) - { - jack_midi_event_get(&in_event, port_buf, i); - printf(" event %d time is %d. 1st byte is 0x%x\n", i, in_event.time, *(in_event.buffer)); - } -/* printf("1st byte of 1st event addr is %p\n", in_events[0].buffer);*/ - } - jack_midi_event_get(&in_event, port_buf, 0); - for(i = 0; i < nframes; i++) - { - if ((in_event.time == i) && (event_index < event_count)) - { - if (((*(in_event.buffer) & 0xf0)) == 0x90) - { - /* note on */ - note = *(in_event.buffer + 1); - if (*(in_event.buffer + 2) == 0) { - note_on = 0.0; - } else { - note_on = (float)(*(in_event.buffer + 2)) / 127.f; - } - } - else if (((*(in_event.buffer)) & 0xf0) == 0x80) - { - /* note off */ - note = *(in_event.buffer + 1); - note_on = 0.0; - } - event_index++; - if(event_index < event_count) - jack_midi_event_get(&in_event, port_buf, event_index); - } - ramp += note_frqs[note]; - ramp = (ramp > 1.0) ? ramp - 2.0 : ramp; - out[i] = note_on*sin(2*M_PI*ramp); - } - return 0; -} - -static int srate(jack_nframes_t nframes, void *arg) -{ - printf("the sample rate is now %" PRIu32 "/sec\n", nframes); - calc_note_frqs((jack_default_audio_sample_t)nframes); - return 0; -} - -static void jack_shutdown(void *arg) -{ - fprintf(stderr, "JACK shut down, exiting ...\n"); - exit(1); -} - -int main(int narg, char **args) -{ - if ((client = jack_client_open("midisine", JackNullOption, NULL)) == 0) - { - fprintf(stderr, "JACK server not running?\n"); - return 1; - } - - calc_note_frqs(jack_get_sample_rate (client)); - - jack_set_process_callback (client, process, 0); - - jack_set_sample_rate_callback (client, srate, 0); - - jack_on_shutdown (client, jack_shutdown, 0); - - input_port = jack_port_register (client, "midi_in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0); - output_port = jack_port_register (client, "audio_out", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); - - if (jack_activate (client)) - { - fprintf(stderr, "cannot activate client"); - return 1; - } - - /* install a signal handler to properly quits jack client */ -#ifndef WIN32 - signal(SIGQUIT, signal_handler); - signal(SIGHUP, signal_handler); -#endif - signal(SIGTERM, signal_handler); - signal(SIGINT, signal_handler); - - /* run until interrupted */ - while(1) { -#ifdef WIN32 - Sleep(1*1000); -#else - sleep(1); -#endif - } - jack_client_close(client); - exit (0); -} - diff --git a/example-clients/netmaster.c b/example-clients/netmaster.c deleted file mode 100644 index 0245fcb6..00000000 --- a/example-clients/netmaster.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - Copyright (C) 2009 Grame - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include <stdlib.h> -#include <stdbool.h> -#include <stdio.h> -#include <errno.h> -#ifndef WIN32 -#include <unistd.h> -#endif -#include <math.h> -#include <signal.h> -#include <getopt.h> -#include <string.h> -#include <assert.h> - -#include <jack/net.h> - -jack_net_master_t* net; - -#define BUFFER_SIZE 512 -#define SAMPLE_RATE 44100 - -static void signal_handler(int sig) -{ - jack_net_master_close(net); - fprintf(stderr, "signal received, exiting ...\n"); - exit(0); -} - -static void -usage () -{ - fprintf (stderr, "\n" - "usage: jack_net_master \n" - " [ -b buffer size (default = %d) ]\n" - " [ -r sample rate (default = %d) ]\n" - " [ -a hostname (default = %s) ]\n" - " [ -p port (default = %d) ]\n", BUFFER_SIZE, SAMPLE_RATE, DEFAULT_MULTICAST_IP, DEFAULT_PORT); -} - -int -main (int argc, char *argv[]) -{ - int buffer_size = BUFFER_SIZE; - int sample_rate = SAMPLE_RATE; - int udp_port = DEFAULT_PORT; - const char* multicast_ip = DEFAULT_MULTICAST_IP; - const char *options = "b:r:a:p:h"; - int option_index; - int opt; - - struct option long_options[] = - { - {"buffer size", 1, 0, 'b'}, - {"sample rate", 1, 0, 'r'}, - {"hostname", 1, 0, 'a'}, - {"port", 1, 0, 'p'}, - {0, 0, 0, 0} - }; - - while ((opt = getopt_long (argc, argv, options, long_options, &option_index)) != -1) { - - switch (opt) { - - case 'b': - buffer_size = atoi(optarg); - break; - - case 'r': - sample_rate = atoi(optarg); - break; - - case 'a': - multicast_ip = strdup(optarg); - break; - - case 'p': - udp_port = atoi(optarg); - break; - - case 'h': - usage(); - return -1; - } - } - - int i; - //jack_master_t request = { 4, 4, -1, -1, buffer_size, sample_rate, "master", -1 }; - jack_master_t request = { -1, -1, -1, -1, buffer_size, sample_rate, "net_master", 6, true }; - jack_slave_t result; - float** audio_input_buffer; - float** audio_output_buffer; - int wait_usec = (int) ((((float)buffer_size) * 1000000) / ((float)sample_rate)); - - printf("Waiting for a slave...\n"); - - if ((net = jack_net_master_open(multicast_ip, udp_port, &request, &result)) == 0) { - fprintf(stderr, "NetJack master can not be opened\n"); - return 1; - } - - printf("Slave is running...\n"); - - /* install a signal handler to properly quits jack client */ -#ifdef WIN32 - signal(SIGINT, signal_handler); - signal(SIGABRT, signal_handler); - signal(SIGTERM, signal_handler); -#else - signal(SIGQUIT, signal_handler); - signal(SIGTERM, signal_handler); - signal(SIGHUP, signal_handler); - signal(SIGINT, signal_handler); -#endif - - // Allocate buffers - - audio_input_buffer = (float**)calloc(result.audio_input, sizeof(float*)); - for (i = 0; i < result.audio_input; i++) { - audio_input_buffer[i] = (float*)calloc(buffer_size, sizeof(float)); - } - - audio_output_buffer = (float**)calloc(result.audio_output, sizeof(float*)); - for (i = 0; i < result.audio_output; i++) { - audio_output_buffer[i] = (float*)calloc(buffer_size, sizeof(float)); - } - - /* - Run until interrupted. - - WARNING !! : this code is given for demonstration purpose. For proper timing bevahiour - it has to be called in a real-time context (which is *not* the case here...) - */ - - //usleep(5*1000000); - printf("Wait...\n"); - //sleep(10); - usleep(1000000); - printf("Wait...OK\n"); - - while (1) { - - // Copy input to output - assert(result.audio_input == result.audio_output); - for (i = 0; i < result.audio_input; i++) { - memcpy(audio_output_buffer[i], audio_input_buffer[i], buffer_size * sizeof(float)); - } - - /* - if (jack_net_master_send(net, result.audio_output, audio_output_buffer, 0, NULL) < 0) { - printf("jack_net_master_send failure, exiting\n"); - break; - } - - usleep(10000); - - if (jack_net_master_recv(net, result.audio_input, audio_input_buffer, 0, NULL) < 0) { - printf("jack_net_master_recv failure, exiting\n"); - break; - } - */ - - if (jack_net_master_send_slice(net, result.audio_output, audio_output_buffer, 0, NULL, BUFFER_SIZE/2) < 0) { - printf("jack_net_master_send failure, exiting\n"); - break; - } - - usleep(10000); - - if (jack_net_master_recv_slice(net, result.audio_input, audio_input_buffer, 0, NULL, BUFFER_SIZE/2) < 0) { - printf("jack_net_master_recv failure, exiting\n"); - break; - } - - usleep(wait_usec); - }; - - // Wait for application end - jack_net_master_close(net); - - for (i = 0; i < result.audio_input; i++) { - free(audio_input_buffer[i]); - } - free(audio_input_buffer); - - for (i = 0; i < result.audio_output; i++) { - free(audio_output_buffer[i]); - } - free(audio_output_buffer); - - exit (0); -} diff --git a/example-clients/netslave.c b/example-clients/netslave.c deleted file mode 100644 index eb923398..00000000 --- a/example-clients/netslave.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - Copyright (C) 2009 Grame - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include <stdlib.h> -#include <stdio.h> -#include <errno.h> -#ifndef WIN32 -#include <unistd.h> -#endif -#include <math.h> -#include <signal.h> -#include <getopt.h> -#include <string.h> - -#include <jack/net.h> - -jack_net_slave_t* net; - -static void signal_handler(int sig) -{ - jack_net_slave_close(net); - fprintf(stderr, "signal received, exiting ...\n"); - exit(0); -} - -static void -usage () -{ - fprintf (stderr, "\n" - "usage: jack_net_slave \n" - " [ -C capture channels (default = 2)]\n" - " [ -P playback channels (default = 2) ]\n" - " [ -a hostname (default = %s) ]\n" - " [ -p port (default = %d)]\n", DEFAULT_MULTICAST_IP, DEFAULT_PORT); -} - -static void net_shutdown(void* data) -{ - printf("Restarting...\n"); -} - -static int net_process(jack_nframes_t buffer_size, - int audio_input, - float** audio_input_buffer, - int midi_input, - void** midi_input_buffer, - int audio_output, - float** audio_output_buffer, - int midi_output, - void** midi_output_buffer, - void* data) -{ - int i; - - // Copy input to output - for (i = 0; i < audio_input; i++) { - memcpy(audio_output_buffer[i], audio_input_buffer[i], buffer_size * sizeof(float)); - } - return 0; -} - -int -main (int argc, char *argv[]) -{ - int audio_input = 2; - int audio_output = 2; - int udp_port = DEFAULT_PORT; - const char* multicast_ip = DEFAULT_MULTICAST_IP; - const char *options = "C:P:a:p:h"; - int option_index; - int opt; - - struct option long_options[] = - { - {"audio input", 1, 0, 'C'}, - {"audio output", 1, 0, 'P'}, - {"hostname", 1, 0, 'a'}, - {"port", 1, 0, 'p'}, - {0, 0, 0, 0} - }; - - while ((opt = getopt_long (argc, argv, options, long_options, &option_index)) != EOF) { - - switch (opt) { - - case 'C': - audio_input = atoi(optarg); - break; - - case 'P': - audio_output = atoi(optarg); - break; - - case 'a': - multicast_ip = strdup(optarg); - break; - - case 'p': - udp_port = atoi(optarg); - break; - - case 'h': - usage(); - return -1; - } - } - - jack_slave_t request = { audio_input, audio_output, 0, 0, DEFAULT_MTU, -1, JackFloatEncoder, 0, 2 }; - jack_master_t result; - - printf("Waiting for a master...\n"); - - if ((net = jack_net_slave_open(multicast_ip, udp_port, "net_slave", &request, &result)) == 0) { - fprintf(stderr, "JACK server not running?\n"); - return 1; - } - - printf("Master is found and running...\n"); - - jack_set_net_slave_process_callback(net, net_process, NULL); - jack_set_net_slave_shutdown_callback(net, net_shutdown, NULL); - - if (jack_net_slave_activate(net) != 0) { - fprintf(stderr, "Cannot activate slave client\n"); - return 1; - } - - /* install a signal handler to properly quits jack client */ -#ifdef WIN32 - signal(SIGINT, signal_handler); - signal(SIGABRT, signal_handler); - signal(SIGTERM, signal_handler); -#else - signal(SIGQUIT, signal_handler); - signal(SIGTERM, signal_handler); - signal(SIGHUP, signal_handler); - signal(SIGINT, signal_handler); -#endif - - /* run until interrupted */ - while (1) { - #ifdef WIN32 - Sleep(1000); - #else - sleep(1); - #endif - }; - - // Wait for application end - jack_net_slave_deactivate(net); - jack_net_slave_close(net); - exit(0); -} diff --git a/example-clients/server_control.cpp b/example-clients/server_control.cpp deleted file mode 100644 index 9be7aea6..00000000 --- a/example-clients/server_control.cpp +++ /dev/null @@ -1,244 +0,0 @@ -/* - Copyright (C) 2008 Grame - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include <stdio.h> -#include <errno.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <getopt.h> -#include <jack/jack.h> -#include <jack/control.h> - -static jackctl_driver_t * jackctl_server_get_driver(jackctl_server_t *server, const char *driver_name) -{ - const JSList * node_ptr = jackctl_server_get_drivers_list(server); - - while (node_ptr) { - if (strcmp(jackctl_driver_get_name((jackctl_driver_t *)node_ptr->data), driver_name) == 0) { - return (jackctl_driver_t *)node_ptr->data; - } - node_ptr = jack_slist_next(node_ptr); - } - - return NULL; -} - -static jackctl_internal_t * jackctl_server_get_internal(jackctl_server_t *server, const char *internal_name) -{ - const JSList * node_ptr = jackctl_server_get_internals_list(server); - - while (node_ptr) { - if (strcmp(jackctl_internal_get_name((jackctl_internal_t *)node_ptr->data), internal_name) == 0) { - return (jackctl_internal_t *)node_ptr->data; - } - node_ptr = jack_slist_next(node_ptr); - } - - return NULL; -} - -#if 0 -static jackctl_parameter_t * -jackctl_get_parameter( - const JSList * parameters_list, - const char * parameter_name) -{ - while (parameters_list) - { - if (strcmp(jackctl_parameter_get_name((jackctl_parameter_t *)parameters_list->data), parameter_name) == 0) - { - return (jackctl_parameter_t *)parameters_list->data; - } - - parameters_list = jack_slist_next(parameters_list); - } - - return NULL; -} -#endif - -static void print_value(union jackctl_parameter_value value, jackctl_param_type_t type) -{ - switch (type) { - - case JackParamInt: - printf("parameter value = %d\n", value.i); - break; - - case JackParamUInt: - printf("parameter value = %u\n", value.ui); - break; - - case JackParamChar: - printf("parameter value = %c\n", value.c); - break; - - case JackParamString: - printf("parameter value = %s\n", value.str); - break; - - case JackParamBool: - printf("parameter value = %d\n", value.b); - break; - } -} - -static void print_parameters(const JSList * node_ptr) -{ - while (node_ptr != NULL) { - jackctl_parameter_t * parameter = (jackctl_parameter_t *)node_ptr->data; - printf("\nparameter name = %s\n", jackctl_parameter_get_name(parameter)); - printf("parameter id = %c\n", jackctl_parameter_get_id(parameter)); - printf("parameter short decs = %s\n", jackctl_parameter_get_short_description(parameter)); - printf("parameter long decs = %s\n", jackctl_parameter_get_long_description(parameter)); - print_value(jackctl_parameter_get_default_value(parameter), jackctl_parameter_get_type(parameter)); - node_ptr = jack_slist_next(node_ptr); - } -} - -static void print_driver(jackctl_driver_t * driver) -{ - printf("\n--------------------------\n"); - printf("driver = %s\n", jackctl_driver_get_name(driver)); - printf("-------------------------- \n"); - print_parameters(jackctl_driver_get_parameters(driver)); -} - -static void print_internal(jackctl_internal_t * internal) -{ - printf("\n-------------------------- \n"); - printf("internal = %s\n", jackctl_internal_get_name(internal)); - printf("-------------------------- \n"); - print_parameters(jackctl_internal_get_parameters(internal)); -} - -static void usage() -{ - fprintf (stderr, "\n" - "usage: jack_server_control \n" - " [ --driver OR -d driver_name ]\n" - " [ --client OR -c client_name ]\n" - ); -} - -int main(int argc, char *argv[]) -{ - jackctl_server_t * server; - const JSList * parameters; - const JSList * drivers; - const JSList * internals; - const JSList * node_ptr; - jackctl_sigmask_t * sigmask; - int opt, option_index; - const char* driver_name = "dummy"; - const char* client_name = "audioadapter"; - - const char *options = "d:c:"; - struct option long_options[] = { - {"driver", 1, 0, 'd'}, - {"client", 1, 0, 'c'}, - {0, 0, 0, 0} - }; - - while ((opt = getopt_long (argc, argv, options, long_options, &option_index)) != -1) { - switch (opt) { - case 'd': - driver_name = optarg; - break; - case 'c': - client_name = optarg; - break; - default: - usage(); - exit(0); - } - } - - server = jackctl_server_create2(NULL, NULL, NULL); - parameters = jackctl_server_get_parameters(server); - - /* - jackctl_parameter_t* param; - union jackctl_parameter_value value; - param = jackctl_get_parameter(parameters, "verbose"); - if (param != NULL) { - value.b = true; - jackctl_parameter_set_value(param, &value); - } - */ - - printf("\n========================== \n"); - printf("List of server parameters \n"); - printf("========================== \n"); - - print_parameters(parameters); - - printf("\n========================== \n"); - printf("List of drivers \n"); - printf("========================== \n"); - - drivers = jackctl_server_get_drivers_list(server); - node_ptr = drivers; - while (node_ptr != NULL) { - print_driver((jackctl_driver_t *)node_ptr->data); - node_ptr = jack_slist_next(node_ptr); - } - - printf("\n========================== \n"); - printf("List of internal clients \n"); - printf("========================== \n"); - - internals = jackctl_server_get_internals_list(server); - node_ptr = internals; - while (node_ptr != NULL) { - print_internal((jackctl_internal_t *)node_ptr->data); - node_ptr = jack_slist_next(node_ptr); - } - - // No error checking in this simple example... - - jackctl_server_open(server, jackctl_server_get_driver(server, driver_name)); - jackctl_server_start(server); - - jackctl_server_load_internal(server, jackctl_server_get_internal(server, client_name)); - - /* - // Switch master test - - jackctl_driver_t* master; - - usleep(5000000); - printf("jackctl_server_load_master\n"); - master = jackctl_server_get_driver(server, "coreaudio"); - jackctl_server_switch_master(server, master); - - usleep(5000000); - printf("jackctl_server_load_master\n"); - master = jackctl_server_get_driver(server, "dummy"); - jackctl_server_switch_master(server, master); - - */ - - sigmask = jackctl_setup_signals(0); - jackctl_wait_signals(sigmask); - jackctl_server_stop(server); - jackctl_server_close(server); - jackctl_server_destroy(server); - return 0; -} diff --git a/example-clients/showtime.c b/example-clients/showtime.c deleted file mode 100644 index 5c352f87..00000000 --- a/example-clients/showtime.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include <stdio.h> -#include <errno.h> -#include <unistd.h> -#include <signal.h> -#include <stdlib.h> -#include <inttypes.h> - -#include <jack/jack.h> -#include <jack/transport.h> - -jack_client_t *client; - -static void -showtime () -{ - jack_position_t current; - jack_transport_state_t transport_state; - jack_nframes_t frame_time; - - transport_state = jack_transport_query (client, ¤t); - frame_time = jack_frame_time (client); - - printf ("frame = %u frame_time = %u usecs = %" PRIu64 "\t", current.frame, frame_time, current.usecs); - - switch (transport_state) { - case JackTransportStopped: - printf ("state: Stopped"); - break; - case JackTransportRolling: - printf ("state: Rolling"); - break; - case JackTransportStarting: - printf ("state: Starting"); - break; - default: - printf ("state: [unknown]"); - } - - if (current.valid & JackPositionBBT) - printf ("\tBBT: %3" PRIi32 "|%" PRIi32 "|%04" - PRIi32, current.bar, current.beat, current.tick); - - if (current.valid & JackPositionTimecode) - printf ("\tTC: (%.6f, %.6f)", - current.frame_time, current.next_time); - printf ("\n"); -} - -static void -jack_shutdown (void *arg) -{ - fprintf(stderr, "JACK shut down, exiting ...\n"); - exit (1); -} - -void -signal_handler (int sig) -{ - jack_client_close (client); - fprintf (stderr, "signal received, exiting ...\n"); - exit (0); -} - -int -main (int argc, char *argv[]) -{ - /* try to become a client of the JACK server */ - - if ((client = jack_client_open ("showtime", JackNullOption, NULL)) == 0) { - fprintf (stderr, "JACK server not running?\n"); - return 1; - } - -#ifndef WIN32 - signal (SIGQUIT, signal_handler); - signal (SIGHUP, signal_handler); -#endif - - signal (SIGTERM, signal_handler); - signal (SIGINT, signal_handler); - - /* tell the JACK server to call `jack_shutdown()' if - it ever shuts down, either entirely, or if it - just decides to stop calling us. - */ - - jack_on_shutdown (client, jack_shutdown, 0); - - /* tell the JACK server that we are ready to roll */ - - if (jack_activate (client)) { - fprintf (stderr, "cannot activate client"); - return 1; - } - - while (1) { - usleep (20); - showtime (); - } - - jack_client_close (client); - exit (0); -} diff --git a/example-clients/simdtests.cpp b/example-clients/simdtests.cpp deleted file mode 100644 index 40b30e90..00000000 --- a/example-clients/simdtests.cpp +++ /dev/null @@ -1,415 +0,0 @@ -/* - * simdtests.c -- test accuracy and performance of simd optimizations - * - * Copyright (C) 2017 Andreas Mueller. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* We must include all headers memops.c includes to avoid trouble with - * out namespace game below. - */ -#include <stdio.h> -#include <string.h> -#include <math.h> -#include <memory.h> -#include <stdlib.h> -#include <stdint.h> -#include <limits.h> -#ifdef __linux__ -#include <endian.h> -#endif -#include "memops.h" - -#if defined (__SSE2__) && !defined (__sun__) -#include <emmintrin.h> -#ifdef __SSE4_1__ -#include <smmintrin.h> -#endif -#endif - -#if defined (__ARM_NEON__) || defined (__ARM_NEON) -#include <arm_neon.h> -#endif - -// our additional headers -#include <time.h> - -/* Dirty: include mempos.c twice the second time with SIMD disabled - * so we can compare aceelerated non accelerated - */ -namespace accelerated { -#include "../common/memops.c" -} - -namespace origerated { -#ifdef __SSE2__ -#undef __SSE2__ -#endif - -#ifdef __ARM_NEON__ -#undef __ARM_NEON__ -#endif - -#ifdef __ARM_NEON -#undef __ARM_NEON -#endif - -#include "../common/memops.c" -} - -// define conversion function types -typedef void (*t_jack_to_integer)( - char *dst, - jack_default_audio_sample_t *src, - unsigned long nsamples, - unsigned long dst_skip, - dither_state_t *state); - -typedef void (*t_integer_to_jack)( - jack_default_audio_sample_t *dst, - char *src, - unsigned long nsamples, - unsigned long src_skip); - -// define/setup test case data -typedef struct test_case_data { - uint32_t frame_size; - uint32_t sample_size; - bool reverse; - t_jack_to_integer jack_to_integer_accel; - t_jack_to_integer jack_to_integer_orig; - t_integer_to_jack integer_to_jack_accel; - t_integer_to_jack integer_to_jack_orig; - dither_state_t *ditherstate; - const char *name; -} test_case_data_t; - -test_case_data_t test_cases[] = { - { - 4, - 3, - true, - accelerated::sample_move_d32u24_sSs, - origerated::sample_move_d32u24_sSs, - accelerated::sample_move_dS_s32u24s, - origerated::sample_move_dS_s32u24s, - NULL, - "32u24s" }, - { - 4, - 3, - false, - accelerated::sample_move_d32u24_sS, - origerated::sample_move_d32u24_sS, - accelerated::sample_move_dS_s32u24, - origerated::sample_move_dS_s32u24, - NULL, - "32u24" }, - { - 4, - 3, - true, - accelerated::sample_move_d32l24_sSs, - origerated::sample_move_d32l24_sSs, - accelerated::sample_move_dS_s32l24s, - origerated::sample_move_dS_s32l24s, - NULL, - "32l24s" }, - { - 4, - 3, - false, - accelerated::sample_move_d32l24_sS, - origerated::sample_move_d32l24_sS, - accelerated::sample_move_dS_s32l24, - origerated::sample_move_dS_s32l24, - NULL, - "32l24" }, - { - 3, - 3, - true, - accelerated::sample_move_d24_sSs, - origerated::sample_move_d24_sSs, - accelerated::sample_move_dS_s24s, - origerated::sample_move_dS_s24s, - NULL, - "24s" }, - { - 3, - 3, - false, - accelerated::sample_move_d24_sS, - origerated::sample_move_d24_sS, - accelerated::sample_move_dS_s24, - origerated::sample_move_dS_s24, - NULL, - "24" }, - { - 2, - 2, - true, - accelerated::sample_move_d16_sSs, - origerated::sample_move_d16_sSs, - accelerated::sample_move_dS_s16s, - origerated::sample_move_dS_s16s, - NULL, - "16s" }, - { - 2, - 2, - false, - accelerated::sample_move_d16_sS, - origerated::sample_move_d16_sS, - accelerated::sample_move_dS_s16, - origerated::sample_move_dS_s16, - NULL, - "16" }, -}; - -// we need to repeat for better accuracy at time measurement -const uint32_t retry_per_case = 1000; - -// setup test buffers -#define TESTBUFF_SIZE 1024 -jack_default_audio_sample_t jackbuffer_source[TESTBUFF_SIZE]; -// integer buffers: max 4 bytes per value / * 2 for stereo -char integerbuffer_accel[TESTBUFF_SIZE*4*2]; -char integerbuffer_orig[TESTBUFF_SIZE*4*2]; -// float buffers -jack_default_audio_sample_t jackfloatbuffer_accel[TESTBUFF_SIZE]; -jack_default_audio_sample_t jackfloatbuffer_orig[TESTBUFF_SIZE]; - -// comparing unsigned makes life easier -uint32_t extract_integer( - char* buff, - uint32_t offset, - uint32_t frame_size, - uint32_t sample_size, - bool big_endian) -{ - uint32_t retval = 0; - unsigned char* curr; - uint32_t mult = 1; - if(big_endian) { - curr = (unsigned char*)buff + offset + sample_size-1; - for(uint32_t i=0; i<sample_size; i++) { - retval += *(curr--) * mult; - mult*=256; - } - } - else { - curr = (unsigned char*)buff + offset + frame_size-sample_size; - for(uint32_t i=0; i<sample_size; i++) { - retval += *(curr++) * mult; - mult*=256; - } - } - return retval; -} - -int main(int argc, char *argv[]) -{ -// parse_arguments(argc, argv); - uint32_t maxerr_displayed = 10; - - // fill jackbuffer - for(int i=0; i<TESTBUFF_SIZE; i++) { - // ramp - jack_default_audio_sample_t value = - ((jack_default_audio_sample_t)((i % TESTBUFF_SIZE) - TESTBUFF_SIZE/2)) / (TESTBUFF_SIZE/2); - // force clipping - value *= 1.02; - jackbuffer_source[i] = value; - } - - for(uint32_t testcase=0; testcase<sizeof(test_cases)/sizeof(test_case_data_t); testcase++) { - // test mono/stereo - for(uint32_t channels=1; channels<=2; channels++) { - ////////////////////////////////////////////////////////////////////////////// - // jackfloat -> integer - - // clean target buffers - memset(integerbuffer_accel, 0, sizeof(integerbuffer_accel)); - memset(integerbuffer_orig, 0, sizeof(integerbuffer_orig)); - // accel - clock_t time_to_integer_accel = clock(); - for(uint32_t repetition=0; repetition<retry_per_case; repetition++) - { - test_cases[testcase].jack_to_integer_accel( - integerbuffer_accel, - jackbuffer_source, - TESTBUFF_SIZE, - test_cases[testcase].frame_size*channels, - test_cases[testcase].ditherstate); - } - float timediff_to_integer_accel = ((float)(clock() - time_to_integer_accel)) / CLOCKS_PER_SEC; - // orig - clock_t time_to_integer_orig = clock(); - for(uint32_t repetition=0; repetition<retry_per_case; repetition++) - { - test_cases[testcase].jack_to_integer_orig( - integerbuffer_orig, - jackbuffer_source, - TESTBUFF_SIZE, - test_cases[testcase].frame_size*channels, - test_cases[testcase].ditherstate); - } - float timediff_to_integer_orig = ((float)(clock() - time_to_integer_orig)) / CLOCKS_PER_SEC; - // output performance results - printf( - "JackFloat->Integer @%7.7s/%u: Orig %7.6f sec / Accel %7.6f sec -> Win: %5.2f %%\n", - test_cases[testcase].name, - channels, - timediff_to_integer_orig, - timediff_to_integer_accel, - (timediff_to_integer_orig/timediff_to_integer_accel-1)*100.0); - uint32_t int_deviation_max = 0; - uint32_t int_error_count = 0; - // output error (avoid spam -> limit error lines per test case) - for(uint32_t sample=0; sample<TESTBUFF_SIZE; sample++) { - uint32_t sample_offset = sample*test_cases[testcase].frame_size*channels; - // compare both results - uint32_t intval_accel=extract_integer( - integerbuffer_accel, - sample_offset, - test_cases[testcase].frame_size, - test_cases[testcase].sample_size, -#if __BYTE_ORDER == __BIG_ENDIAN - !test_cases[testcase].reverse); -#else - test_cases[testcase].reverse); -#endif - uint32_t intval_orig=extract_integer( - integerbuffer_orig, - sample_offset, - test_cases[testcase].frame_size, - test_cases[testcase].sample_size, -#if __BYTE_ORDER == __BIG_ENDIAN - !test_cases[testcase].reverse); -#else - test_cases[testcase].reverse); -#endif - // allow a deviation of 1 - if(intval_accel>intval_orig+1 || intval_orig>intval_accel+1) { - if(int_error_count<maxerr_displayed) { - printf("Value error sample %u:", sample); - printf(" Orig 0x"); - char formatstr[10]; - sprintf(formatstr, "%%0%uX", test_cases[testcase].sample_size*2); - printf(formatstr, intval_orig); - printf(" Accel 0x"); - printf(formatstr, intval_accel); - printf("\n"); - } - int_error_count++; - uint32_t int_deviation; - if(intval_accel > intval_orig) - int_deviation = intval_accel-intval_orig; - else - int_deviation = intval_orig-intval_accel; - if(int_deviation > int_deviation_max) - int_deviation_max = int_deviation; - } - } - printf( - "JackFloat->Integer @%7.7s/%u: Errors: %u Max deviation %u\n", - test_cases[testcase].name, - channels, - int_error_count, - int_deviation_max); - - ////////////////////////////////////////////////////////////////////////////// - // integer -> jackfloat - - // clean target buffers - memset(jackfloatbuffer_accel, 0, sizeof(jackfloatbuffer_accel)); - memset(jackfloatbuffer_orig, 0, sizeof(jackfloatbuffer_orig)); - // accel - clock_t time_to_float_accel = clock(); - for(uint32_t repetition=0; repetition<retry_per_case; repetition++) - { - test_cases[testcase].integer_to_jack_accel( - jackfloatbuffer_accel, - integerbuffer_orig, - TESTBUFF_SIZE, - test_cases[testcase].frame_size*channels); - } - float timediff_to_float_accel = ((float)(clock() - time_to_float_accel)) / CLOCKS_PER_SEC; - // orig - clock_t time_to_float_orig = clock(); - for(uint32_t repetition=0; repetition<retry_per_case; repetition++) - { - test_cases[testcase].integer_to_jack_orig( - jackfloatbuffer_orig, - integerbuffer_orig, - TESTBUFF_SIZE, - test_cases[testcase].frame_size*channels); - } - float timediff_to_float_orig = ((float)(clock() - time_to_float_orig)) / CLOCKS_PER_SEC; - // output performance results - printf( - "Integer->JackFloat @%7.7s/%u: Orig %7.6f sec / Accel %7.6f sec -> Win: %5.2f %%\n", - test_cases[testcase].name, - channels, - timediff_to_float_orig, - timediff_to_float_accel, - (timediff_to_float_orig/timediff_to_float_accel-1)*100.0); - jack_default_audio_sample_t float_deviation_max = 0.0; - uint32_t float_error_count = 0; - // output error (avoid spam -> limit error lines per test case) - for(uint32_t sample=0; sample<TESTBUFF_SIZE; sample++) { - // For easier estimation/readability we scale floats back to integer - jack_default_audio_sample_t sample_scaling; - switch(test_cases[testcase].sample_size) { - case 2: - sample_scaling = SAMPLE_16BIT_SCALING; - break; - default: - sample_scaling = SAMPLE_24BIT_SCALING; - break; - } - jack_default_audio_sample_t floatval_accel = jackfloatbuffer_accel[sample] * sample_scaling; - jack_default_audio_sample_t floatval_orig = jackfloatbuffer_orig[sample] * sample_scaling; - // compare both results - jack_default_audio_sample_t float_deviation; - if(floatval_accel > floatval_orig) - float_deviation = floatval_accel-floatval_orig; - else - float_deviation = floatval_orig-floatval_accel; - if(float_deviation > float_deviation_max) - float_deviation_max = float_deviation; - // deviation > half bit => error - if(float_deviation > 0.5) { - if(float_error_count<maxerr_displayed) { - printf("Value error sample %u:", sample); - printf(" Orig %8.1f Accel %8.1f\n", floatval_orig, floatval_accel); - } - float_error_count++; - } - } - printf( - "Integer->JackFloat @%7.7s/%u: Errors: %u Max deviation %f\n", - test_cases[testcase].name, - channels, - float_error_count, - float_deviation_max); - - printf("\n"); - } - } - return 0; -} diff --git a/example-clients/simple_client.c b/example-clients/simple_client.c deleted file mode 100644 index 18210fbe..00000000 --- a/example-clients/simple_client.c +++ /dev/null @@ -1,220 +0,0 @@ -/** @file simple_client.c - * - * @brief This simple client demonstrates the basic features of JACK - * as they would be used by many applications. - */ - -#include <stdio.h> -#include <errno.h> -#include <stdlib.h> -#include <string.h> -#include <math.h> -#include <signal.h> -#ifndef WIN32 -#include <unistd.h> -#endif -#include <jack/jack.h> - -jack_port_t *output_port1, *output_port2; -jack_client_t *client; - -#ifndef M_PI -#define M_PI (3.14159265) -#endif - -#define TABLE_SIZE (200) -typedef struct -{ - float sine[TABLE_SIZE]; - int left_phase; - int right_phase; -} -paTestData; - -static void signal_handler(int sig) -{ - jack_client_close(client); - fprintf(stderr, "signal received, exiting ...\n"); - exit(0); -} - -/** - * The process callback for this JACK application is called in a - * special realtime thread once for each audio cycle. - * - * This client follows a simple rule: when the JACK transport is - * running, copy the input port to the output. When it stops, exit. - */ - -int -process (jack_nframes_t nframes, void *arg) -{ - jack_default_audio_sample_t *out1, *out2; - paTestData *data = (paTestData*)arg; - int i; - - out1 = (jack_default_audio_sample_t*)jack_port_get_buffer (output_port1, nframes); - out2 = (jack_default_audio_sample_t*)jack_port_get_buffer (output_port2, nframes); - - for( i=0; i<nframes; i++ ) - { - out1[i] = data->sine[data->left_phase]; /* left */ - out2[i] = data->sine[data->right_phase]; /* right */ - data->left_phase += 1; - if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE; - data->right_phase += 3; /* higher pitch so we can distinguish left and right. */ - if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE; - } - - return 0; -} - -/** - * JACK calls this shutdown_callback if the server ever shuts down or - * decides to disconnect the client. - */ -void -jack_shutdown (void *arg) -{ - exit (1); -} - -int -main (int argc, char *argv[]) -{ - const char **ports; - const char *client_name; - const char *server_name = NULL; - jack_options_t options = JackNullOption; - jack_status_t status; - paTestData data; - int i; - - if (argc >= 2) { /* client name specified? */ - client_name = argv[1]; - if (argc >= 3) { /* server name specified? */ - server_name = argv[2]; - int my_option = JackNullOption | JackServerName; - options = (jack_options_t)my_option; - } - } else { /* use basename of argv[0] */ - client_name = strrchr(argv[0], '/'); - if (client_name == 0) { - client_name = argv[0]; - } else { - client_name++; - } - } - - for( i=0; i<TABLE_SIZE; i++ ) - { - data.sine[i] = 0.2 * (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ); - } - data.left_phase = data.right_phase = 0; - - - /* open a client connection to the JACK server */ - - client = jack_client_open (client_name, options, &status, server_name); - if (client == NULL) { - fprintf (stderr, "jack_client_open() failed, " - "status = 0x%2.0x\n", status); - if (status & JackServerFailed) { - fprintf (stderr, "Unable to connect to JACK server\n"); - } - exit (1); - } - if (status & JackServerStarted) { - fprintf (stderr, "JACK server started\n"); - } - if (status & JackNameNotUnique) { - client_name = jack_get_client_name(client); - fprintf (stderr, "unique name `%s' assigned\n", client_name); - } - - /* tell the JACK server to call `process()' whenever - there is work to be done. - */ - - jack_set_process_callback (client, process, &data); - - /* tell the JACK server to call `jack_shutdown()' if - it ever shuts down, either entirely, or if it - just decides to stop calling us. - */ - - jack_on_shutdown (client, jack_shutdown, 0); - - /* create two ports */ - - output_port1 = jack_port_register (client, "output1", - JACK_DEFAULT_AUDIO_TYPE, - JackPortIsOutput, 0); - - output_port2 = jack_port_register (client, "output2", - JACK_DEFAULT_AUDIO_TYPE, - JackPortIsOutput, 0); - - if ((output_port1 == NULL) || (output_port2 == NULL)) { - fprintf(stderr, "no more JACK ports available\n"); - exit (1); - } - - /* Tell the JACK server that we are ready to roll. Our - * process() callback will start running now. */ - - if (jack_activate (client)) { - fprintf (stderr, "cannot activate client"); - exit (1); - } - - /* Connect the ports. You can't do this before the client is - * activated, because we can't make connections to clients - * that aren't running. Note the confusing (but necessary) - * orientation of the driver backend ports: playback ports are - * "input" to the backend, and capture ports are "output" from - * it. - */ - - ports = jack_get_ports (client, NULL, NULL, - JackPortIsPhysical|JackPortIsInput); - if (ports == NULL) { - fprintf(stderr, "no physical playback ports\n"); - exit (1); - } - - if (jack_connect (client, jack_port_name (output_port1), ports[0])) { - fprintf (stderr, "cannot connect output ports\n"); - } - - if (jack_connect (client, jack_port_name (output_port2), ports[1])) { - fprintf (stderr, "cannot connect output ports\n"); - } - - jack_free (ports); - - /* install a signal handler to properly quits jack client */ -#ifdef WIN32 - signal(SIGINT, signal_handler); - signal(SIGABRT, signal_handler); - signal(SIGTERM, signal_handler); -#else - signal(SIGQUIT, signal_handler); - signal(SIGTERM, signal_handler); - signal(SIGHUP, signal_handler); - signal(SIGINT, signal_handler); -#endif - - /* keep running until the Ctrl+C */ - - while (1) { - #ifdef WIN32 - Sleep(1000); - #else - sleep (1); - #endif - } - - jack_client_close (client); - exit (0); -} diff --git a/example-clients/simple_session_client.c b/example-clients/simple_session_client.c deleted file mode 100644 index 67a7cbd2..00000000 --- a/example-clients/simple_session_client.c +++ /dev/null @@ -1,206 +0,0 @@ -/** @file simple_session_client.c - * - * @brief This simple client demonstrates the most basic features of JACK - * as they would be used by many applications. - * this version also adds session manager functionality. - */ - -#include <stdio.h> -#include <errno.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <inttypes.h> - -#include <jack/jack.h> -#include <jack/types.h> -#include <jack/session.h> - -jack_port_t *input_port; -jack_port_t *output_port; -jack_client_t *client; - -int simple_quit = 0; - -/** - * The process callback for this JACK application is called in a - * special realtime thread once for each audio cycle. - * - * This client does nothing more than copy data from its input - * port to its output port. It will exit when stopped by - * the user (e.g. using Ctrl-C on a unix-ish operating system) - */ -int -process (jack_nframes_t nframes, void *arg) -{ - jack_default_audio_sample_t *in, *out; - - in = jack_port_get_buffer (input_port, nframes); - out = jack_port_get_buffer (output_port, nframes); - memcpy (out, in, - sizeof (jack_default_audio_sample_t) * nframes); - - return 0; -} - -void -session_callback (jack_session_event_t *event, void *arg) -{ - char retval[100]; - printf ("session notification\n"); - printf ("path %s, uuid %s, type: %s\n", event->session_dir, event->client_uuid, event->type == JackSessionSave ? "save" : "quit"); - - - snprintf (retval, 100, "jack_simple_session_client %s", event->client_uuid); - event->command_line = strdup (retval); - - jack_session_reply( client, event ); - - if (event->type == JackSessionSaveAndQuit) { - simple_quit = 1; - } - - jack_session_event_free (event); -} - -/** - * JACK calls this shutdown_callback if the server ever shuts down or - * decides to disconnect the client. - */ -void -jack_shutdown (void *arg) -{ - exit (1); -} - -int -main (int argc, char *argv[]) -{ - const char **ports; - const char *client_name = "simple"; - jack_status_t status; - - /* open a client connection to the JACK server */ - - if( argc == 1 ) - client = jack_client_open (client_name, JackNullOption, &status ); - else if( argc == 2 ) - client = jack_client_open (client_name, JackSessionID, &status, argv[1] ); - - if (client == NULL) { - fprintf (stderr, "jack_client_open() failed, " - "status = 0x%2.0x\n", status); - if (status & JackServerFailed) { - fprintf (stderr, "Unable to connect to JACK server\n"); - } - exit (1); - } - if (status & JackServerStarted) { - fprintf (stderr, "JACK server started\n"); - } - if (status & JackNameNotUnique) { - client_name = jack_get_client_name(client); - fprintf (stderr, "unique name `%s' assigned\n", client_name); - } - - /* tell the JACK server to call `process()' whenever - there is work to be done. - */ - - jack_set_process_callback (client, process, 0); - - /* tell the JACK server to call `jack_shutdown()' if - it ever shuts down, either entirely, or if it - just decides to stop calling us. - */ - - jack_on_shutdown (client, jack_shutdown, 0); - - /* tell the JACK server to call `session_callback()' if - the session is saved. - */ - - jack_set_session_callback (client, session_callback, NULL); - - /* display the current sample rate. - */ - - printf ("engine sample rate: %" PRIu32 "\n", - jack_get_sample_rate (client)); - - /* create two ports */ - - input_port = jack_port_register (client, "input", - JACK_DEFAULT_AUDIO_TYPE, - JackPortIsInput, 0); - output_port = jack_port_register (client, "output", - JACK_DEFAULT_AUDIO_TYPE, - JackPortIsOutput, 0); - - if ((input_port == NULL) || (output_port == NULL)) { - fprintf(stderr, "no more JACK ports available\n"); - exit (1); - } - - /* Tell the JACK server that we are ready to roll. Our - * process() callback will start running now. */ - - if (jack_activate (client)) { - fprintf (stderr, "cannot activate client"); - exit (1); - } - - /* Connect the ports. You can't do this before the client is - * activated, because we can't make connections to clients - * that aren't running. Note the confusing (but necessary) - * orientation of the driver backend ports: playback ports are - * "input" to the backend, and capture ports are "output" from - * it. - */ - - - /* only do the autoconnect when not reloading from a session. - * in case of a session reload, the SM will restore our connections - */ - - if (argc==1) { - - ports = jack_get_ports (client, NULL, NULL, - JackPortIsPhysical|JackPortIsOutput); - if (ports == NULL) { - fprintf(stderr, "no physical capture ports\n"); - exit (1); - } - - if (jack_connect (client, ports[0], jack_port_name (input_port))) { - fprintf (stderr, "cannot connect input ports\n"); - } - - free (ports); - - ports = jack_get_ports (client, NULL, NULL, - JackPortIsPhysical|JackPortIsInput); - if (ports == NULL) { - fprintf(stderr, "no physical playback ports\n"); - exit (1); - } - - if (jack_connect (client, jack_port_name (output_port), ports[0])) { - fprintf (stderr, "cannot connect output ports\n"); - } - - free (ports); - } - - /* keep running until until we get a quit event */ - - while (!simple_quit) -#ifdef WIN32 - Sleep(1*1000); -#else - sleep(1); -#endif - - jack_client_close (client); - exit (0); -} diff --git a/example-clients/thru_client.c b/example-clients/thru_client.c deleted file mode 100644 index d47fbe15..00000000 --- a/example-clients/thru_client.c +++ /dev/null @@ -1,217 +0,0 @@ -/** @file thru_client.c - * - * @brief This simple through client demonstrates the basic features of JACK - * as they would be used by many applications. - */ - -#include <stdio.h> -#include <errno.h> -#include <stdlib.h> -#include <string.h> -#include <math.h> -#include <signal.h> -#ifndef WIN32 -#include <unistd.h> -#endif -#include <jack/jack.h> - -jack_port_t **input_ports; -jack_port_t **output_ports; -jack_client_t *client; - -static void signal_handler ( int sig ) -{ - jack_client_close ( client ); - fprintf ( stderr, "signal received, exiting ...\n" ); - exit ( 0 ); -} - -/** - * The process callback for this JACK application is called in a - * special realtime thread once for each audio cycle. - * - * This client follows a simple rule: when the JACK transport is - * running, copy the input port to the output. When it stops, exit. - */ - -int -process ( jack_nframes_t nframes, void *arg ) -{ - int i; - jack_default_audio_sample_t *in, *out; - for ( i = 0; i < 2; i++ ) - { - in = jack_port_get_buffer ( input_ports[i], nframes ); - out = jack_port_get_buffer ( output_ports[i], nframes ); - memcpy ( out, in, nframes * sizeof ( jack_default_audio_sample_t ) ); - } - return 0; -} - -/** - * JACK calls this shutdown_callback if the server ever shuts down or - * decides to disconnect the client. - */ -void -jack_shutdown ( void *arg ) -{ - free ( input_ports ); - free ( output_ports ); - exit ( 1 ); -} - -int -main ( int argc, char *argv[] ) -{ - int i; - const char **ports; - const char *client_name; - const char *server_name = NULL; - jack_options_t options = JackNullOption; - jack_status_t status; - - if ( argc >= 2 ) /* client name specified? */ - { - client_name = argv[1]; - if ( argc >= 3 ) /* server name specified? */ - { - server_name = argv[2]; - options |= JackServerName; - } - } - else /* use basename of argv[0] */ - { - client_name = strrchr ( argv[0], '/' ); - if ( client_name == 0 ) - { - client_name = argv[0]; - } - else - { - client_name++; - } - } - - /* open a client connection to the JACK server */ - - client = jack_client_open ( client_name, options, &status, server_name ); - if ( client == NULL ) - { - fprintf ( stderr, "jack_client_open() failed, " - "status = 0x%2.0x\n", status ); - if ( status & JackServerFailed ) - { - fprintf ( stderr, "Unable to connect to JACK server\n" ); - } - exit ( 1 ); - } - if ( status & JackServerStarted ) - { - fprintf ( stderr, "JACK server started\n" ); - } - if ( status & JackNameNotUnique ) - { - client_name = jack_get_client_name ( client ); - fprintf ( stderr, "unique name `%s' assigned\n", client_name ); - } - - /* tell the JACK server to call `process()' whenever - there is work to be done. - */ - - jack_set_process_callback ( client, process, 0 ); - - /* tell the JACK server to call `jack_shutdown()' if - it ever shuts down, either entirely, or if it - just decides to stop calling us. - */ - - jack_on_shutdown ( client, jack_shutdown, 0 ); - - /* create two ports pairs*/ - input_ports = ( jack_port_t** ) calloc ( 2, sizeof ( jack_port_t* ) ); - output_ports = ( jack_port_t** ) calloc ( 2, sizeof ( jack_port_t* ) ); - - char port_name[16]; - for ( i = 0; i < 2; i++ ) - { - sprintf ( port_name, "input_%d", i + 1 ); - input_ports[i] = jack_port_register ( client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0 ); - sprintf ( port_name, "output_%d", i + 1 ); - output_ports[i] = jack_port_register ( client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0 ); - if ( ( input_ports[i] == NULL ) || ( output_ports[i] == NULL ) ) - { - fprintf ( stderr, "no more JACK ports available\n" ); - exit ( 1 ); - } - } - - /* Tell the JACK server that we are ready to roll. Our - * process() callback will start running now. */ - - if ( jack_activate ( client ) ) - { - fprintf ( stderr, "cannot activate client" ); - exit ( 1 ); - } - - /* Connect the ports. You can't do this before the client is - * activated, because we can't make connections to clients - * that aren't running. Note the confusing (but necessary) - * orientation of the driver backend ports: playback ports are - * "input" to the backend, and capture ports are "output" from - * it. - */ - - ports = jack_get_ports ( client, NULL, NULL, JackPortIsPhysical|JackPortIsOutput ); - if ( ports == NULL ) - { - fprintf ( stderr, "no physical capture ports\n" ); - exit ( 1 ); - } - - for ( i = 0; i < 2; i++ ) - if ( jack_connect ( client, ports[i], jack_port_name ( input_ports[i] ) ) ) - fprintf ( stderr, "cannot connect input ports\n" ); - - free ( ports ); - - ports = jack_get_ports ( client, NULL, NULL, JackPortIsPhysical|JackPortIsInput ); - if ( ports == NULL ) - { - fprintf ( stderr, "no physical playback ports\n" ); - exit ( 1 ); - } - - for ( i = 0; i < 2; i++ ) - if ( jack_connect ( client, jack_port_name ( output_ports[i] ), ports[i] ) ) - fprintf ( stderr, "cannot connect input ports\n" ); - - free ( ports ); - - /* install a signal handler to properly quits jack client */ -#ifdef WIN32 - signal ( SIGINT, signal_handler ); - signal ( SIGABRT, signal_handler ); - signal ( SIGTERM, signal_handler ); -#else - signal ( SIGQUIT, signal_handler ); - signal ( SIGTERM, signal_handler ); - signal ( SIGHUP, signal_handler ); - signal ( SIGINT, signal_handler ); -#endif - - /* keep running until the transport stops */ - - while (1) - { -#ifdef WIN32 - Sleep ( 1000 ); -#else - sleep ( 1 ); -#endif - } - - jack_client_close ( client ); - exit ( 0 ); -} diff --git a/example-clients/wscript b/example-clients/wscript deleted file mode 100644 index f95791ce..00000000 --- a/example-clients/wscript +++ /dev/null @@ -1,110 +0,0 @@ -#! /usr/bin/python3 -# encoding: utf-8 - -example_programs = { - 'jack_cpu_load': 'cpu_load.c', - 'jack_latent_client': 'latent_client.c', - 'jack_metro': 'metro.c', - 'jack_midi_latency_test': 'midi_latency_test.c', - 'jack_midiseq': 'midiseq.c', - 'jack_midisine': 'midisine.c', - 'jack_net_master': 'netmaster.c', - 'jack_net_slave': 'netslave.c', - 'jack_server_control': 'server_control.cpp', - 'jack_showtime': 'showtime.c', - 'jack_simdtests': 'simdtests.cpp', - 'jack_simple_client': 'simple_client.c', - 'jack_simple_session_client': 'simple_session_client.c', - 'jack_thru': 'thru_client.c', - 'jack_zombie': 'zombie.c', - } - -example_libs = { - 'inprocess': 'inprocess.c', -} - - -def configure(conf): - conf.env['BUILD_EXAMPLE_CLIENT_REC'] = conf.env['SNDFILE'] - - -def build(bld): - if bld.env['IS_LINUX']: - os_incdir = ['../linux', '../posix'] - if bld.env['IS_MACOSX']: - os_incdir = ['../macosx', '../posix'] - if bld.env['IS_FREEBSD']: - os_incdir = ['../freebsd', '../posix'] - if bld.env['IS_SUN']: - os_incdir = ['../solaris', '../posix'] - if bld.env['IS_WINDOWS']: - os_incdir = ['../windows'] - for example_program, example_program_source in list(example_programs.items()): - if example_program == 'jack_server_control': - use = ['serverlib', 'STDC++'] - elif example_program == 'jack_net_slave': - if not bld.env['BUILD_NETLIB']: - continue - use = ['netlib'] - elif example_program == 'jack_net_master': - if not bld.env['BUILD_NETLIB']: - continue - use = ['netlib'] - else: - use = ['clientlib'] - - if example_program == 'jack_simdtests': - ftrs = 'cxx cxxprogram' - else: - ftrs = 'c cprogram' - - if bld.env['IS_MACOSX']: - prog = bld(features=ftrs, framework=['Foundation']) - else: - prog = bld(features=ftrs) - prog.includes = os_incdir + ['../common/jack', '../common'] - prog.source = example_program_source - prog.use = use - if bld.env['IS_LINUX']: - prog.use += ['RT', 'M'] - if bld.env['IS_SUN']: - prog.use += ['M'] - if bld.env['IS_FREEBSD']: - prog.use += ['M'] - if bld.env['IS_WINDOWS'] and bld.env['BUILD_STATIC']: - prog.env['LIB_PTHREAD'] = [':libwinpthread.a'] - - prog.target = example_program - - if bld.env['BUILD_EXAMPLE_CLIENT_REC']: - prog = bld(features='c cprogram') - prog.includes = os_incdir + ['../common/jack', '../common'] - prog.source = 'capture_client.c' - prog.use = ['clientlib'] - if bld.env['IS_MACOSX']: - prog.use += ['SNDFILE'] - if bld.env['IS_LINUX']: - prog.use += ['RT', 'SNDFILE'] - if bld.env['IS_FREEBSD']: - prog.use += ['SNDFILE'] - if bld.env['IS_SUN']: - prog.use += ['RT', 'SNDFILE'] - if bld.env['IS_WINDOWS']: - prog.uselib = ['SNDFILE'] - if bld.env['BUILD_STATIC']: - prog.env['LIB_PTHREAD'] = [':libwinpthread.a'] - prog.target = 'jack_rec' - - for example_lib, example_lib_source in list(example_libs.items()): - lib = bld(features='c cshlib') - if not bld.env['IS_WINDOWS']: - lib.env['cshlib_PATTERN'] = '%s.so' - lib.includes = os_incdir + ['../common/jack', '../common'] - lib.target = example_lib - lib.source = example_lib_source - if bld.env['IS_SUN']: - lib.env.append_value('LINKFLAGS', '-lm') - if bld.env['IS_WINDOWS'] and bld.env['BUILD_STATIC']: - prog.env['LIB_PTHREAD'] = [':libwinpthread.a'] - lib.use = 'serverlib' - lib.install_path = '${ADDON_DIR}/' diff --git a/example-clients/zombie.c b/example-clients/zombie.c deleted file mode 100644 index 4ba96925..00000000 --- a/example-clients/zombie.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - Copyright (C) 2002 Jeremy Hall - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id: zombie.c,v 1.1 2005/08/18 11:42:08 letz Exp $ -*/ - -#include <stdio.h> -#include <errno.h> -#include <unistd.h> -#include <string.h> -#include <stdlib.h> -#include <jack/jack.h> - -int running = 1; -int count = 0; -jack_port_t* output_port; - -static int -process(jack_nframes_t nframes, void* arg) -{ - if (count++ == 1000) { - printf("process block\n"); - //while (1) {} -#if WIN32 - Sleep(1*1000); -#else - sleep(1); -#endif - } - - return 0; -} - -static void -shutdown_handler (void *arg) -{ - printf("shutdown \n"); - running = 0; -} - -int -main (int argc, char *argv[]) -{ - jack_client_t* client = NULL; - /* try to become a client of the JACK server */ - if ((client = jack_client_open ("zombie", JackNullOption, NULL)) == 0) { - fprintf (stderr, "JACK server not running?\n"); - goto error; - } - - jack_set_process_callback (client, process, NULL); - jack_on_shutdown(client, shutdown_handler, NULL); - output_port = jack_port_register (client, "port1", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); - - /* tell the JACK server that we are ready to roll */ - if (jack_activate (client)) { - fprintf (stderr, "cannot activate client"); - goto error; - } - - jack_connect(client, jack_port_name(output_port), "coreaudio:Built-in Audio:in2"); - - while (running) { -#if WIN32 - Sleep(1*1000); -#else - sleep(1); -#endif - printf ("run\n"); - } - - jack_deactivate (client); - jack_client_close (client); - return 0; - -error: - if (client) - jack_client_close (client); - return 1; -} - diff --git a/tools/alias.c b/tools/alias.c deleted file mode 100644 index cb2b3f99..00000000 --- a/tools/alias.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <getopt.h> -#include <jack/jack.h> - -char * my_name; - -void -show_version (void) -{ - //fprintf (stderr, "%s: JACK Audio Connection Kit version " VERSION "\n", my_name); -} - -void -show_usage (void) -{ - show_version (); - fprintf (stderr, "\nUsage: %s [options] portname alias\n", my_name); - fprintf (stderr, "List active Jack ports, and optionally display extra information.\n\n"); - fprintf (stderr, "Display options:\n"); - fprintf (stderr, " -u, --unalias remove `alias' as an alias for `port'\n"); - fprintf (stderr, " -h, --help Display this help message\n"); - fprintf (stderr, " --version Output version information and exit\n\n"); - fprintf (stderr, "For more information see http://jackaudio.org/\n"); -} - -int -main (int argc, char *argv[]) -{ - jack_client_t *client; - jack_status_t status; - char* portname; - char* alias; - int unset = 0; - int ret; - int c; - int option_index; - extern int optind; - jack_port_t* port; - - struct option long_options[] = { - { "unalias", 0, 0, 'u' }, - { "help", 0, 0, 'h' }, - { "version", 0, 0, 'v' }, - { 0, 0, 0, 0 } - }; - - if (argc < 3) { - show_usage (); - return 1; - } - - my_name = strrchr(argv[0], '/'); - if (my_name == 0) { - my_name = argv[0]; - } else { - my_name ++; - } - - while ((c = getopt_long (argc, argv, "uhv", long_options, &option_index)) >= 0) { - switch (c) { - case 'u': - unset = 1; - break; - case 'h': - show_usage (); - return 1; - break; - case 'v': - show_version (); - return 1; - break; - default: - show_usage (); - return 1; - break; - } - } - - portname = argv[optind++]; - alias = argv[optind]; - - /* Open a client connection to the JACK server. Starting a - * new server only to list its ports seems pointless, so we - * specify JackNoStartServer. */ - //JOQ: need a new server name option - - client = jack_client_open ("lsp", JackNoStartServer, &status); - - if (client == NULL) { - if (status & JackServerFailed) { - fprintf (stderr, "JACK server not running\n"); - } else { - fprintf (stderr, "jack_client_open() failed, " - "status = 0x%2.0x\n", status); - } - return 1; - } - - if ((port = jack_port_by_name (client, portname)) == 0) { - fprintf (stderr, "No port named \"%s\"\n", portname); - return 1; - } - - if (!unset) { - ret = jack_port_set_alias (port, alias); - } else { - ret = jack_port_unset_alias (port, alias); - } - - jack_client_close (client); - - return ret; - -} diff --git a/tools/alsa_in.c b/tools/alsa_in.c deleted file mode 100644 index a52f06e4..00000000 --- a/tools/alsa_in.c +++ /dev/null @@ -1,846 +0,0 @@ -/** @file simple_client.c - * - * @brief This simple client demonstrates the basic features of JACK - * as they would be used by many applications. - */ - -#include <stdio.h> -#include <errno.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <signal.h> - -#include <math.h> - -#include <jack/jack.h> -#include <jack/jslist.h> -#include "memops.h" - -#include "alsa/asoundlib.h" - -#include <samplerate.h> - -// Here are the lists of the jack ports... - -JSList *capture_ports = NULL; -JSList *capture_srcs = NULL; -JSList *playback_ports = NULL; -JSList *playback_srcs = NULL; -jack_client_t *client; - -snd_pcm_t *alsa_handle; - -int jack_sample_rate; -int jack_buffer_size; - -int quit = 0; -double resample_mean = 1.0; -double static_resample_factor = 1.0; -double resample_lower_limit = 0.25; -double resample_upper_limit = 4.0; - -double *offset_array; -double *window_array; -int offset_differential_index = 0; - -double offset_integral = 0; - -// ------------------------------------------------------ commandline parameters - -int sample_rate = 0; /* stream rate */ -int num_channels = 2; /* count of channels */ -int period_size = 1024; -int num_periods = 2; - -int target_delay = 0; /* the delay which the program should try to approach. */ -int max_diff = 0; /* the diff value, when a hard readpointer skip should occur */ -int catch_factor = 100000; -int catch_factor2 = 10000; -double pclamp = 15.0; -double controlquant = 10000.0; -int smooth_size = 256; -int good_window=0; -int verbose = 0; -int instrument = 0; -int samplerate_quality = 2; - -// Debug stuff: - -volatile float output_resampling_factor = 1.0; -volatile int output_new_delay = 0; -volatile float output_offset = 0.0; -volatile float output_integral = 0.0; -volatile float output_diff = 0.0; -volatile int running_freewheel = 0; - -snd_pcm_uframes_t real_buffer_size; -snd_pcm_uframes_t real_period_size; - -// buffers - -char *tmpbuf; -char *outbuf; -float *resampbuf; - -// format selection, and corresponding functions from memops in a nice set of structs. - -typedef struct alsa_format { - snd_pcm_format_t format_id; - size_t sample_size; - void (*jack_to_soundcard) (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); - void (*soundcard_to_jack) (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); - const char *name; -} alsa_format_t; - -alsa_format_t formats[] = { - { SND_PCM_FORMAT_FLOAT_LE, 4, sample_move_dS_floatLE, sample_move_floatLE_sSs, "float" }, - { SND_PCM_FORMAT_S32, 4, sample_move_d32u24_sS, sample_move_dS_s32u24, "32bit" }, - { SND_PCM_FORMAT_S24_3LE, 3, sample_move_d24_sS, sample_move_dS_s24, "24bit - real" }, - { SND_PCM_FORMAT_S24, 4, sample_move_d32l24_sS, sample_move_dS_s32l24, "24bit" }, - { SND_PCM_FORMAT_S16, 2, sample_move_d16_sS, sample_move_dS_s16, "16bit" } -#ifdef __ANDROID__ - ,{ SND_PCM_FORMAT_S16_LE, 2, sample_move_d16_sS, sample_move_dS_s16, "16bit little-endian" } -#endif -}; -#define NUMFORMATS (sizeof(formats)/sizeof(formats[0])) -int format=0; - -// Alsa stuff... i don't want to touch this bullshit in the next years.... please... - -static int xrun_recovery(snd_pcm_t *handle, int err) { -// printf( "xrun !!!.... %d\n", err ); - if (err == -EPIPE) { /* under-run */ - err = snd_pcm_prepare(handle); - if (err < 0) - printf("Can't recover from underrun, prepare failed: %s\n", snd_strerror(err)); - return 0; - } else if (err == -ESTRPIPE) { - while ((err = snd_pcm_resume(handle)) == -EAGAIN) - usleep(100); /* wait until the suspend flag is released */ - if (err < 0) { - err = snd_pcm_prepare(handle); - if (err < 0) - printf("Can't recover from suspend, prepare failed: %s\n", snd_strerror(err)); - } - return 0; - } - return err; -} - -static int set_hwformat( snd_pcm_t *handle, snd_pcm_hw_params_t *params ) -{ -#ifdef __ANDROID__ - format = 5; - snd_pcm_hw_params_set_format(handle, params, formats[format].format_id); - return 0; -#else - int i; - int err; - - for( i=0; i<NUMFORMATS; i++ ) { - /* set the sample format */ - err = snd_pcm_hw_params_set_format(handle, params, formats[i].format_id); - if (err == 0) { - format = i; - return 0; - } - } - - return err; -#endif -} - -static int set_hwparams(snd_pcm_t *handle, snd_pcm_hw_params_t *params, snd_pcm_access_t access, int rate, int channels, int period, int nperiods ) { - int err, dir=0; - unsigned int buffer_time; - unsigned int period_time; - unsigned int rrate; - unsigned int rchannels; - - /* choose all parameters */ - err = snd_pcm_hw_params_any(handle, params); - if (err < 0) { - printf("Broken configuration for playback: no configurations available: %s\n", snd_strerror(err)); - return err; - } - /* set the interleaved read/write format */ - err = snd_pcm_hw_params_set_access(handle, params, access); - if (err < 0) { - printf("Access type not available for playback: %s\n", snd_strerror(err)); - return err; - } - - /* set the sample format */ - err = set_hwformat(handle, params); - if (err < 0) { - printf("Sample format not available for playback: %s\n", snd_strerror(err)); - return err; - } - /* set the count of channels */ - rchannels = channels; - err = snd_pcm_hw_params_set_channels_near(handle, params, &rchannels); - if (err < 0) { - printf("Channels count (%i) not available for record: %s\n", channels, snd_strerror(err)); - return err; - } - if (rchannels != channels) { - printf("WARNING: channel count does not match (requested %d got %d)\n", channels, rchannels); - num_channels = rchannels; - } - /* set the stream rate */ - rrate = rate; - err = snd_pcm_hw_params_set_rate_near(handle, params, &rrate, 0); - if (err < 0) { - printf("Rate %iHz not available for playback: %s\n", rate, snd_strerror(err)); - return err; - } - if (rrate != rate) { - printf("WARNING: Rate doesn't match (requested %iHz, get %iHz)\n", rate, rrate); - sample_rate = rrate; - } - /* set the buffer time */ - - buffer_time = 1000000*(uint64_t)period*nperiods/rate; - err = snd_pcm_hw_params_set_buffer_time_near(handle, params, &buffer_time, &dir); - if (err < 0) { - printf("Unable to set buffer time %i for playback: %s\n", 1000000*period*nperiods/rate, snd_strerror(err)); - return err; - } - err = snd_pcm_hw_params_get_buffer_size( params, &real_buffer_size ); - if (err < 0) { - printf("Unable to get buffer size back: %s\n", snd_strerror(err)); - return err; - } - if( real_buffer_size != nperiods * period ) { - printf( "WARNING: buffer size does not match: (requested %d, got %d)\n", nperiods * period, (int) real_buffer_size ); - } - /* set the period time */ - period_time = 1000000*(uint64_t)period/rate; - err = snd_pcm_hw_params_set_period_time_near(handle, params, &period_time, &dir); - if (err < 0) { - printf("Unable to set period time %i for playback: %s\n", 1000000*period/rate, snd_strerror(err)); - return err; - } - err = snd_pcm_hw_params_get_period_size(params, &real_period_size, NULL ); - if (err < 0) { - printf("Unable to get period size back: %s\n", snd_strerror(err)); - return err; - } - if( real_period_size != period ) { - printf( "WARNING: period size does not match: (requested %i, got %i)\n", period, (int)real_period_size ); - } - /* write the parameters to device */ - err = snd_pcm_hw_params(handle, params); - if (err < 0) { - printf("Unable to set hw params for playback: %s\n", snd_strerror(err)); - return err; - } - return 0; -} - -static int set_swparams(snd_pcm_t *handle, snd_pcm_sw_params_t *swparams, int period) { - int err; - - /* get the current swparams */ - err = snd_pcm_sw_params_current(handle, swparams); - if (err < 0) { - printf("Unable to determine current swparams for capture: %s\n", snd_strerror(err)); - return err; - } - /* start the transfer when the buffer is full */ - err = snd_pcm_sw_params_set_start_threshold(handle, swparams, period ); - if (err < 0) { - printf("Unable to set start threshold mode for capture: %s\n", snd_strerror(err)); - return err; - } - err = snd_pcm_sw_params_set_stop_threshold(handle, swparams, -1 ); - if (err < 0) { - printf("Unable to set start threshold mode for capture: %s\n", snd_strerror(err)); - return err; - } - /* allow the transfer when at least period_size samples can be processed */ - err = snd_pcm_sw_params_set_avail_min(handle, swparams, 2*period ); - if (err < 0) { - printf("Unable to set avail min for capture: %s\n", snd_strerror(err)); - return err; - } - /* align all transfers to 1 sample */ - err = snd_pcm_sw_params_set_xfer_align(handle, swparams, 1); - if (err < 0) { - printf("Unable to set transfer align for capture: %s\n", snd_strerror(err)); - return err; - } - /* write the parameters to the playback device */ - err = snd_pcm_sw_params(handle, swparams); - if (err < 0) { - printf("Unable to set sw params for capture: %s\n", snd_strerror(err)); - return err; - } - return 0; -} - -// ok... i only need this function to communicate with the alsa bloat api... - -static snd_pcm_t *open_audiofd( char *device_name, int capture, int rate, int channels, int period, int nperiods ) { - int err; - snd_pcm_t *handle; - snd_pcm_hw_params_t *hwparams; - snd_pcm_sw_params_t *swparams; - - snd_pcm_hw_params_alloca(&hwparams); - snd_pcm_sw_params_alloca(&swparams); - - if ((err = snd_pcm_open(&(handle), device_name, capture ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK )) < 0) { - printf("Capture open error: %s\n", snd_strerror(err)); - return NULL; - } - - if ((err = set_hwparams(handle, hwparams,SND_PCM_ACCESS_RW_INTERLEAVED, rate, channels, period, nperiods )) < 0) { - printf("Setting of hwparams failed: %s\n", snd_strerror(err)); - return NULL; - } - if ((err = set_swparams(handle, swparams, period)) < 0) { - printf("Setting of swparams failed: %s\n", snd_strerror(err)); - return NULL; - } - - snd_pcm_start( handle ); - snd_pcm_wait( handle, 200 ); - - return handle; -} - -double hann( double x ) -{ - return 0.5 * (1.0 - cos( 2*M_PI * x ) ); -} - -/** - * The freewheel callback. - */ -void freewheel (int starting, void* arg) { - running_freewheel = starting; -} - -/** - * The process callback for this JACK application. - * It is called by JACK at the appropriate times. - */ -int process (jack_nframes_t nframes, void *arg) { - - if (running_freewheel) { - JSList *node = capture_ports; - - while ( node != NULL) - { - jack_port_t *port = (jack_port_t *) node->data; - float *buf = jack_port_get_buffer (port, nframes); - - memset(buf, 0, sizeof(float)*nframes); - - node = jack_slist_next (node); - } - - return 0; - } - - int rlen; - int err; - snd_pcm_sframes_t delay = target_delay; - int put_back_samples=0; - int i; - - delay = snd_pcm_avail( alsa_handle ); - - delay -= round( jack_frames_since_cycle_start( client ) / static_resample_factor ); - // Do it the hard way. - // this is for compensating xruns etc... - - if( delay > (target_delay+max_diff) ) { - - output_new_delay = (int) delay; - - while ((delay-target_delay) > 0) { - snd_pcm_uframes_t to_read = ((delay-target_delay) > 512) ? 512 : (delay-target_delay); - snd_pcm_readi( alsa_handle, tmpbuf, to_read ); - delay -= to_read; - } - - delay = target_delay; - - // Set the resample_rate... we need to adjust the offset integral, to do this. - // first look at the PI controller, this code is just a special case, which should never execute once - // everything is swung in. - offset_integral = - (resample_mean - static_resample_factor) * catch_factor * catch_factor2; - // Also clear the array. we are beginning a new control cycle. - for( i=0; i<smooth_size; i++ ) - offset_array[i] = 0.0; - } - if( delay < (target_delay-max_diff) ) { - snd_pcm_rewind( alsa_handle, target_delay - delay ); - output_new_delay = (int) delay; - delay = target_delay; - - // Set the resample_rate... we need to adjust the offset integral, to do this. - offset_integral = - (resample_mean - static_resample_factor) * catch_factor * catch_factor2; - // Also clear the array. we are beginning a new control cycle. - for( i=0; i<smooth_size; i++ ) - offset_array[i] = 0.0; - } - /* ok... now we should have target_delay +- max_diff on the alsa side. - * - * calculate the number of frames, we want to get. - */ - - double offset = delay - target_delay; - - // Save offset. - offset_array[(offset_differential_index++)% smooth_size ] = offset; - - // Build the mean of the windowed offset array - // basically fir lowpassing. - double smooth_offset = 0.0; - for( i=0; i<smooth_size; i++ ) - smooth_offset += - offset_array[ (i + offset_differential_index-1) % smooth_size] * window_array[i]; - smooth_offset /= (double) smooth_size; - - // this is the integral of the smoothed_offset - offset_integral += smooth_offset; - - // Clamp offset. - // the smooth offset still contains unwanted noise - // which would go straight onto the resample coeff. - // it only used in the P component and the I component is used for the fine tuning anyways. - if( fabs( smooth_offset ) < pclamp ) - smooth_offset = 0.0; - - // ok. now this is the PI controller. - // u(t) = K * ( e(t) + 1/T \int e(t') dt' ) - // K = 1/catch_factor and T = catch_factor2 - double current_resample_factor = static_resample_factor - smooth_offset / (double) catch_factor - offset_integral / (double) catch_factor / (double)catch_factor2; - - // now quantize this value around resample_mean, so that the noise which is in the integral component doesn't hurt. - current_resample_factor = floor( (current_resample_factor - resample_mean) * controlquant + 0.5 ) / controlquant + resample_mean; - - // Output "instrumentatio" gonna change that to real instrumentation in a few. - output_resampling_factor = (float) current_resample_factor; - output_diff = (float) smooth_offset; - output_integral = (float) offset_integral; - output_offset = (float) offset; - - // Clamp a bit. - if( current_resample_factor < resample_lower_limit ) current_resample_factor = resample_lower_limit; - if( current_resample_factor > resample_upper_limit ) current_resample_factor = resample_upper_limit; - - // Now Calculate how many samples we need. - rlen = ceil( ((double)nframes) / current_resample_factor )+2; - assert( rlen > 2 ); - - // Calculate resample_mean so we can init ourselves to saner values. - resample_mean = 0.9999 * resample_mean + 0.0001 * current_resample_factor; - - // get the data... -again: - err = snd_pcm_readi(alsa_handle, outbuf, rlen); - if( err < 0 ) { - printf( "err = %d\n", err ); - if (xrun_recovery(alsa_handle, err) < 0) { - //printf("Write error: %s\n", snd_strerror(err)); - //exit(EXIT_FAILURE); - } - goto again; - } - if( err != rlen ) { - //printf( "read = %d\n", rlen ); - } - - /* - * render jack ports to the outbuf... - */ - - int chn = 0; - JSList *node = capture_ports; - JSList *src_node = capture_srcs; - SRC_DATA src; - - while ( node != NULL) - { - jack_port_t *port = (jack_port_t *) node->data; - float *buf = jack_port_get_buffer (port, nframes); - - SRC_STATE *src_state = src_node->data; - - formats[format].soundcard_to_jack( resampbuf, outbuf + format[formats].sample_size * chn, rlen, num_channels*format[formats].sample_size ); - - src.data_in = resampbuf; - src.input_frames = rlen; - - src.data_out = buf; - src.output_frames = nframes; - src.end_of_input = 0; - - src.src_ratio = current_resample_factor; - - src_process( src_state, &src ); - - put_back_samples = rlen-src.input_frames_used; - - src_node = jack_slist_next (src_node); - node = jack_slist_next (node); - chn++; - } - - // Put back the samples libsamplerate did not consume. - //printf( "putback = %d\n", put_back_samples ); - snd_pcm_rewind( alsa_handle, put_back_samples ); - - return 0; -} - -/** - * the latency callback. - * sets up the latencies on the ports. - */ - -void -latency_cb (jack_latency_callback_mode_t mode, void *arg) -{ - jack_latency_range_t range; - JSList *node; - - range.min = range.max = round(target_delay * static_resample_factor); - - if (mode == JackCaptureLatency) { - for (node = capture_ports; node; node = jack_slist_next (node)) { - jack_port_t *port = node->data; - jack_port_set_latency_range (port, mode, &range); - } - } else { - for (node = playback_ports; node; node = jack_slist_next (node)) { - jack_port_t *port = node->data; - jack_port_set_latency_range (port, mode, &range); - } - } -} - - -/** - * Allocate the necessary jack ports... - */ - -void alloc_ports( int n_capture, int n_playback ) { - - int port_flags = JackPortIsOutput; - int chn; - jack_port_t *port; - char buf[32]; - - capture_ports = NULL; - for (chn = 0; chn < n_capture; chn++) - { - snprintf (buf, sizeof(buf) - 1, "capture_%u", chn+1); - - port = jack_port_register (client, buf, - JACK_DEFAULT_AUDIO_TYPE, - port_flags, 0); - - if (!port) - { - printf( "jacknet_client: cannot register port for %s", buf); - break; - } - - capture_srcs = jack_slist_append( capture_srcs, src_new( 4-samplerate_quality, 1, NULL ) ); - capture_ports = jack_slist_append (capture_ports, port); - } - - port_flags = JackPortIsInput; - - playback_ports = NULL; - for (chn = 0; chn < n_playback; chn++) - { - snprintf (buf, sizeof(buf) - 1, "playback_%u", chn+1); - - port = jack_port_register (client, buf, - JACK_DEFAULT_AUDIO_TYPE, - port_flags, 0); - - if (!port) - { - printf( "jacknet_client: cannot register port for %s", buf); - break; - } - - playback_srcs = jack_slist_append( playback_srcs, src_new( 4-samplerate_quality, 1, NULL ) ); - playback_ports = jack_slist_append (playback_ports, port); - } -} - -/** - * This is the shutdown callback for this JACK application. - * It is called by JACK if the server ever shuts down or - * decides to disconnect the client. - */ - -void jack_shutdown (void *arg) { - - exit (1); -} - -/** - * be user friendly. - * be user friendly. - * be user friendly. - */ - -void printUsage() { -fprintf(stderr, "usage: alsa_out [options]\n" - "\n" - " -j <jack name> - client name\n" - " -S <server name> - server to connect\n" - " -d <alsa_device> \n" - " -c <channels> \n" - " -p <period_size> \n" - " -n <num_period> \n" - " -r <sample_rate> \n" - " -q <sample_rate quality [0..4]\n" - " -m <max_diff> \n" - " -t <target_delay> \n" - " -i turns on instrumentation\n" - " -v turns on printouts\n" - "\n"); -} - - -/** - * the main function.... - */ - -void -sigterm_handler( int signal ) -{ - quit = 1; -} - - -int main (int argc, char *argv[]) { - char jack_name[30] = "alsa_in"; - char alsa_device[30] = "hw:0"; - char *server_name = NULL; - int jack_opts = 0; - - extern char *optarg; - extern int optind, optopt; - int errflg=0; - int c; - - while ((c = getopt(argc, argv, "ivj:r:c:p:n:d:q:m:t:f:F:C:Q:s:S:")) != -1) { - switch(c) { - case 'j': - strcpy(jack_name,optarg); - break; - case 'r': - sample_rate = atoi(optarg); - break; - case 'c': - num_channels = atoi(optarg); - break; - case 'p': - period_size = atoi(optarg); - break; - case 'n': - num_periods = atoi(optarg); - break; - case 'd': - strcpy(alsa_device,optarg); - break; - case 't': - target_delay = atoi(optarg); - break; - case 'q': - samplerate_quality = atoi(optarg); - break; - case 'm': - max_diff = atoi(optarg); - break; - case 'f': - catch_factor = atoi(optarg); - break; - case 'F': - catch_factor2 = atoi(optarg); - break; - case 'C': - pclamp = (double) atoi(optarg); - break; - case 'Q': - controlquant = (double) atoi(optarg); - break; - case 'v': - verbose = 1; - break; - case 'i': - instrument = 1; - break; - case 's': - smooth_size = atoi(optarg); - break; - case 'S': - server_name = optarg; - jack_opts |= JackServerName; - break; - case ':': - fprintf(stderr, - "Option -%c requires an operand\n", optopt); - errflg++; - break; - case '?': - fprintf(stderr, - "Unrecognized option: -%c\n", optopt); - errflg++; - } - } - if (errflg) { - printUsage(); - exit(2); - } - - if( (samplerate_quality < 0) || (samplerate_quality > 4) ) { - fprintf (stderr, "invalid samplerate quality\n"); - return 1; - } - if ((client = jack_client_open (jack_name, jack_opts, NULL, server_name)) == 0) { - fprintf (stderr, "jack server not running?\n"); - return 1; - } - - /* tell the JACK server to call `process()' whenever - there is work to be done. - */ - - jack_set_process_callback (client, process, 0); - - /* tell the JACK server to call `freewheel()' whenever - freewheel mode changes. - */ - - jack_set_freewheel_callback (client, freewheel, 0); - - /* tell the JACK server to call `jack_shutdown()' if - it ever shuts down, either entirely, or if it - just decides to stop calling us. - */ - - jack_on_shutdown (client, jack_shutdown, 0); - - if (jack_set_latency_callback) - jack_set_latency_callback (client, latency_cb, 0); - - // get jack sample_rate - - jack_sample_rate = jack_get_sample_rate( client ); - - if( !sample_rate ) - sample_rate = jack_sample_rate; - - // now open the alsa fd... - alsa_handle = open_audiofd( alsa_device, 1, sample_rate, num_channels, period_size, num_periods); - if( alsa_handle == 0 ) - exit(20); - - printf( "selected sample format: %s\n", formats[format].name ); - - static_resample_factor = (double) jack_sample_rate / (double) sample_rate; - resample_lower_limit = static_resample_factor * 0.25; - resample_upper_limit = static_resample_factor * 4.0; - resample_mean = static_resample_factor; - - offset_array = malloc( sizeof(double) * smooth_size ); - if( offset_array == NULL ) { - fprintf( stderr, "no memory for offset_array !!!\n" ); - exit(20); - } - window_array = malloc( sizeof(double) * smooth_size ); - if( window_array == NULL ) { - fprintf( stderr, "no memory for window_array !!!\n" ); - exit(20); - } - int i; - for( i=0; i<smooth_size; i++ ) { - offset_array[i] = 0.0; - window_array[i] = hann( (double) i / ((double) smooth_size - 1.0) ); - } - - jack_buffer_size = jack_get_buffer_size( client ); - // Setup target delay and max_diff for the normal user, who does not play with them... - if( !target_delay ) - target_delay = (num_periods*period_size / 2) + jack_buffer_size/2; - - if( !max_diff ) - max_diff = num_periods*period_size - target_delay ; - - if( max_diff > target_delay ) { - fprintf( stderr, "target_delay (%d) can not be smaller than max_diff(%d)\n", target_delay, max_diff ); - exit(20); - } - if( (target_delay+max_diff) > (num_periods*period_size) ) { - fprintf( stderr, "target_delay+max_diff (%d) can not be bigger than buffersize(%d)\n", target_delay+max_diff, num_periods*period_size ); - exit(20); - } - // alloc input ports, which are blasted out to alsa... - alloc_ports( num_channels, 0 ); - - outbuf = malloc( num_periods * period_size * formats[format].sample_size * num_channels ); - resampbuf = malloc( num_periods * period_size * sizeof( float ) ); - tmpbuf = malloc( 512 * formats[format].sample_size * num_channels ); - - if ((outbuf == NULL) || (resampbuf == NULL) || (tmpbuf == NULL)) - { - fprintf( stderr, "no memory for buffers.\n" ); - exit(20); - } - - memset( tmpbuf, 0, 512 * formats[format].sample_size * num_channels); - - /* tell the JACK server that we are ready to roll */ - - if (jack_activate (client)) { - fprintf (stderr, "cannot activate client"); - return 1; - } - - signal( SIGTERM, sigterm_handler ); - signal( SIGINT, sigterm_handler ); - - if( verbose ) { - while(!quit) { - usleep(500000); - if( output_new_delay ) { - printf( "delay = %d\n", output_new_delay ); - output_new_delay = 0; - } - printf( "res: %f, \tdiff = %f, \toffset = %f \n", output_resampling_factor, output_diff, output_offset ); - } - } else if( instrument ) { - printf( "# n\tresamp\tdiff\toffseti\tintegral\n"); - int n=0; - while(!quit) { - usleep(1000); - printf( "%d\t%f\t%f\t%f\t%f\n", n++, output_resampling_factor, output_diff, output_offset, output_integral ); - } - } else { - while(!quit) - { - usleep(500000); - if( output_new_delay ) { - printf( "delay = %d\n", output_new_delay ); - output_new_delay = 0; - } - } - } - - jack_deactivate( client ); - jack_client_close (client); - exit (0); -} diff --git a/tools/alsa_out.c b/tools/alsa_out.c deleted file mode 100644 index 40cdce3c..00000000 --- a/tools/alsa_out.c +++ /dev/null @@ -1,848 +0,0 @@ -/** @file simple_client.c - * - * @brief This simple client demonstrates the basic features of JACK - * as they would be used by many applications. - */ - -#include <alloca.h> -#include <stdio.h> -#include <errno.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <signal.h> - -#include <math.h> - -#include <jack/jack.h> -#include <jack/jslist.h> -#include "memops.h" - -#include "alsa/asoundlib.h" - -#include <samplerate.h> - -// Here are the lists of the jack ports... - -JSList *capture_ports = NULL; -JSList *capture_srcs = NULL; -JSList *playback_ports = NULL; -JSList *playback_srcs = NULL; -jack_client_t *client; - -snd_pcm_t *alsa_handle; - -int jack_sample_rate; -int jack_buffer_size; - -int quit = 0; -double resample_mean = 1.0; -double static_resample_factor = 1.0; -double resample_lower_limit = 0.25; -double resample_upper_limit = 4.0; - -double *offset_array; -double *window_array; -int offset_differential_index = 0; - -double offset_integral = 0; - -// ------------------------------------------------------ commandline parameters - -int sample_rate = 0; /* stream rate */ -int num_channels = 2; /* count of channels */ -int period_size = 1024; -int num_periods = 2; - -int target_delay = 0; /* the delay which the program should try to approach. */ -int max_diff = 0; /* the diff value, when a hard readpointer skip should occur */ -int catch_factor = 100000; -int catch_factor2 = 10000; -double pclamp = 15.0; -double controlquant = 10000.0; -int smooth_size = 256; -int good_window=0; -int verbose = 0; -int instrument = 0; -int samplerate_quality = 2; - -// Debug stuff: - -volatile float output_resampling_factor = 1.0; -volatile int output_new_delay = 0; -volatile float output_offset = 0.0; -volatile float output_integral = 0.0; -volatile float output_diff = 0.0; -volatile int running_freewheel = 0; - -snd_pcm_uframes_t real_buffer_size; -snd_pcm_uframes_t real_period_size; - -// buffers - -char *tmpbuf; -char *outbuf; -float *resampbuf; - -// format selection, and corresponding functions from memops in a nice set of structs. - -typedef struct alsa_format { - snd_pcm_format_t format_id; - size_t sample_size; - void (*jack_to_soundcard) (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); - void (*soundcard_to_jack) (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); - const char *name; -} alsa_format_t; - -alsa_format_t formats[] = { - { SND_PCM_FORMAT_FLOAT_LE, 4, sample_move_dS_floatLE, sample_move_floatLE_sSs, "float" }, - { SND_PCM_FORMAT_S32, 4, sample_move_d32u24_sS, sample_move_dS_s32u24, "32bit" }, - { SND_PCM_FORMAT_S24_3LE, 3, sample_move_d24_sS, sample_move_dS_s24, "24bit - real" }, - { SND_PCM_FORMAT_S24, 4, sample_move_d32l24_sS, sample_move_dS_s32l24, "24bit" }, - { SND_PCM_FORMAT_S16, 2, sample_move_d16_sS, sample_move_dS_s16, "16bit" } -#ifdef __ANDROID__ - ,{ SND_PCM_FORMAT_S16_LE, 2, sample_move_d16_sS, sample_move_dS_s16, "16bit little-endian" } -#endif -}; -#define NUMFORMATS (sizeof(formats)/sizeof(formats[0])) -int format=0; - -// Alsa stuff... i don't want to touch this bullshit in the next years.... please... - -static int xrun_recovery(snd_pcm_t *handle, int err) { -// printf( "xrun !!!.... %d\n", err ); - if (err == -EPIPE) { /* under-run */ - err = snd_pcm_prepare(handle); - if (err < 0) - printf("Can't recovery from underrun, prepare failed: %s\n", snd_strerror(err)); - return 0; - } else if (err == -ESTRPIPE) { - while ((err = snd_pcm_resume(handle)) == -EAGAIN) - usleep(100); /* wait until the suspend flag is released */ - if (err < 0) { - err = snd_pcm_prepare(handle); - if (err < 0) - printf("Can't recovery from suspend, prepare failed: %s\n", snd_strerror(err)); - } - return 0; - } - return err; -} - -static int set_hwformat( snd_pcm_t *handle, snd_pcm_hw_params_t *params ) -{ -#ifdef __ANDROID__ - format = 5; - snd_pcm_hw_params_set_format(handle, params, formats[format].format_id); - return 0; -#else - int i; - int err; - - for( i=0; i<NUMFORMATS; i++ ) { - /* set the sample format */ - err = snd_pcm_hw_params_set_format(handle, params, formats[i].format_id); - if (err == 0) { - format = i; - return 0; - } - } - - return err; -#endif -} - -static int set_hwparams(snd_pcm_t *handle, snd_pcm_hw_params_t *params, snd_pcm_access_t access, int rate, int channels, int period, int nperiods ) { - int err, dir=0; - unsigned int buffer_time; - unsigned int period_time; - unsigned int rrate; - unsigned int rchannels; - - /* choose all parameters */ - err = snd_pcm_hw_params_any(handle, params); - if (err < 0) { - printf("Broken configuration for playback: no configurations available: %s\n", snd_strerror(err)); - return err; - } - /* set the interleaved read/write format */ - err = snd_pcm_hw_params_set_access(handle, params, access); - if (err < 0) { - printf("Access type not available for playback: %s\n", snd_strerror(err)); - return err; - } - - /* set the sample format */ - err = set_hwformat(handle, params); - if (err < 0) { - printf("Sample format not available for playback: %s\n", snd_strerror(err)); - return err; - } - /* set the count of channels */ - rchannels = channels; - err = snd_pcm_hw_params_set_channels_near(handle, params, &rchannels); - if (err < 0) { - printf("Channels count (%i) not available for record: %s\n", channels, snd_strerror(err)); - return err; - } - if (rchannels != channels) { - printf("WARNING: channel count does not match (requested %d got %d)\n", channels, rchannels); - num_channels = rchannels; - } - /* set the stream rate */ - rrate = rate; - err = snd_pcm_hw_params_set_rate_near(handle, params, &rrate, 0); - if (err < 0) { - printf("Rate %iHz not available for playback: %s\n", rate, snd_strerror(err)); - return err; - } - if (rrate != rate) { - printf("Rate doesn't match (requested %iHz, get %iHz)\n", rate, rrate); - return -EINVAL; - } - /* set the buffer time */ - - buffer_time = 1000000*(uint64_t)period*nperiods/rate; - err = snd_pcm_hw_params_set_buffer_time_near(handle, params, &buffer_time, &dir); - if (err < 0) { - printf("Unable to set buffer time %i for playback: %s\n", 1000000*period*nperiods/rate, snd_strerror(err)); - return err; - } - err = snd_pcm_hw_params_get_buffer_size( params, &real_buffer_size ); - if (err < 0) { - printf("Unable to get buffer size back: %s\n", snd_strerror(err)); - return err; - } - if( real_buffer_size != nperiods * period ) { - printf( "WARNING: buffer size does not match: (requested %d, got %d)\n", nperiods * period, (int) real_buffer_size ); - } - /* set the period time */ - period_time = 1000000*(uint64_t)period/rate; - err = snd_pcm_hw_params_set_period_time_near(handle, params, &period_time, &dir); - if (err < 0) { - printf("Unable to set period time %i for playback: %s\n", 1000000*period/rate, snd_strerror(err)); - return err; - } - err = snd_pcm_hw_params_get_period_size(params, &real_period_size, NULL ); - if (err < 0) { - printf("Unable to get period size back: %s\n", snd_strerror(err)); - return err; - } - if( real_period_size != period ) { - printf( "WARNING: period size does not match: (requested %i, got %i)\n", period, (int)real_period_size ); - } - /* write the parameters to device */ - err = snd_pcm_hw_params(handle, params); - if (err < 0) { - printf("Unable to set hw params for playback: %s\n", snd_strerror(err)); - return err; - } - return 0; -} - -static int set_swparams(snd_pcm_t *handle, snd_pcm_sw_params_t *swparams, int period, int nperiods) { - int err; - - /* get the current swparams */ - err = snd_pcm_sw_params_current(handle, swparams); - if (err < 0) { - printf("Unable to determine current swparams for capture: %s\n", snd_strerror(err)); - return err; - } - /* start the transfer when the buffer is full */ - err = snd_pcm_sw_params_set_start_threshold(handle, swparams, period ); - if (err < 0) { - printf("Unable to set start threshold mode for capture: %s\n", snd_strerror(err)); - return err; - } - err = snd_pcm_sw_params_set_stop_threshold(handle, swparams, -1 ); - if (err < 0) { - printf("Unable to set start threshold mode for capture: %s\n", snd_strerror(err)); - return err; - } - /* allow the transfer when at least period_size samples can be processed */ - err = snd_pcm_sw_params_set_avail_min(handle, swparams, 1 ); - if (err < 0) { - printf("Unable to set avail min for capture: %s\n", snd_strerror(err)); - return err; - } - /* align all transfers to 1 sample */ - err = snd_pcm_sw_params_set_xfer_align(handle, swparams, 1); - if (err < 0) { - printf("Unable to set transfer align for capture: %s\n", snd_strerror(err)); - return err; - } - /* write the parameters to the playback device */ - err = snd_pcm_sw_params(handle, swparams); - if (err < 0) { - printf("Unable to set sw params for capture: %s\n", snd_strerror(err)); - return err; - } - return 0; -} - -// ok... i only need this function to communicate with the alsa bloat api... - -static snd_pcm_t *open_audiofd( char *device_name, int capture, int rate, int channels, int period, int nperiods ) { - int err; - snd_pcm_t *handle; - snd_pcm_hw_params_t *hwparams; - snd_pcm_sw_params_t *swparams; - - snd_pcm_hw_params_alloca(&hwparams); - snd_pcm_sw_params_alloca(&swparams); - - if ((err = snd_pcm_open(&(handle), device_name, capture ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK )) < 0) { - printf("Capture open error: %s\n", snd_strerror(err)); - return NULL; - } - - if ((err = set_hwparams(handle, hwparams,SND_PCM_ACCESS_RW_INTERLEAVED, rate, channels, period, nperiods )) < 0) { - printf("Setting of hwparams failed: %s\n", snd_strerror(err)); - return NULL; - } - if ((err = set_swparams(handle, swparams, period, nperiods)) < 0) { - printf("Setting of swparams failed: %s\n", snd_strerror(err)); - return NULL; - } - - //snd_pcm_start( handle ); - //snd_pcm_wait( handle, 200 ); - int num_null_samples = nperiods * period * channels; - char *tmp = alloca( num_null_samples * formats[format].sample_size ); - memset( tmp, 0, num_null_samples * formats[format].sample_size ); - snd_pcm_writei( handle, tmp, num_null_samples ); - - - return handle; -} - -double hann( double x ) -{ - return 0.5 * (1.0 - cos( 2*M_PI * x ) ); -} - -/** - * The freewheel callback. - */ -void freewheel (int starting, void* arg) { - running_freewheel = starting; -} - -/** - * The process callback for this JACK application. - * It is called by JACK at the appropriate times. - */ -int process (jack_nframes_t nframes, void *arg) { - - if (running_freewheel) { - JSList *node = playback_ports; - - while ( node != NULL) - { - jack_port_t *port = (jack_port_t *) node->data; - float *buf = jack_port_get_buffer (port, nframes); - - memset(buf, 0, sizeof(float)*nframes); - - node = jack_slist_next (node); - } - - return 0; - } - - int rlen; - int err; - snd_pcm_sframes_t delay = target_delay; - int i; - - delay = (num_periods*period_size)-snd_pcm_avail( alsa_handle ) ; - - delay -= round( jack_frames_since_cycle_start( client ) * static_resample_factor ); - // Do it the hard way. - // this is for compensating xruns etc... - - if( delay > (target_delay+max_diff) ) { - snd_pcm_rewind( alsa_handle, delay - target_delay ); - output_new_delay = (int) delay; - - delay = target_delay; - - // Set the resample_rate... we need to adjust the offset integral, to do this. - // first look at the PI controller, this code is just a special case, which should never execute once - // everything is swung in. - offset_integral = - (resample_mean - static_resample_factor) * catch_factor * catch_factor2; - // Also clear the array. we are beginning a new control cycle. - for( i=0; i<smooth_size; i++ ) - offset_array[i] = 0.0; - } - if( delay < (target_delay-max_diff) ) { - - output_new_delay = (int) delay; - - while ((target_delay-delay) > 0) { - snd_pcm_uframes_t to_write = ((target_delay-delay) > 512) ? 512 : (target_delay-delay); - snd_pcm_writei( alsa_handle, tmpbuf, to_write ); - delay += to_write; - } - - delay = target_delay; - - // Set the resample_rate... we need to adjust the offset integral, to do this. - offset_integral = - (resample_mean - static_resample_factor) * catch_factor * catch_factor2; - // Also clear the array. we are beginning a new control cycle. - for( i=0; i<smooth_size; i++ ) - offset_array[i] = 0.0; - } - /* ok... now we should have target_delay +- max_diff on the alsa side. - * - * calculate the number of frames, we want to get. - */ - - double offset = delay - target_delay; - - // Save offset. - offset_array[(offset_differential_index++)% smooth_size ] = offset; - - // Build the mean of the windowed offset array - // basically fir lowpassing. - double smooth_offset = 0.0; - for( i=0; i<smooth_size; i++ ) - smooth_offset += - offset_array[ (i + offset_differential_index-1) % smooth_size] * window_array[i]; - smooth_offset /= (double) smooth_size; - - // this is the integral of the smoothed_offset - offset_integral += smooth_offset; - - // Clamp offset. - // the smooth offset still contains unwanted noise - // which would go straight onto the resample coeff. - // it only used in the P component and the I component is used for the fine tuning anyways. - if( fabs( smooth_offset ) < pclamp ) - smooth_offset = 0.0; - - // ok. now this is the PI controller. - // u(t) = K * ( e(t) + 1/T \int e(t') dt' ) - // K = 1/catch_factor and T = catch_factor2 - double current_resample_factor = static_resample_factor - smooth_offset / (double) catch_factor - offset_integral / (double) catch_factor / (double)catch_factor2; - - // now quantize this value around resample_mean, so that the noise which is in the integral component doesn't hurt. - current_resample_factor = floor( (current_resample_factor - resample_mean) * controlquant + 0.5 ) / controlquant + resample_mean; - - // Output "instrumentatio" gonna change that to real instrumentation in a few. - output_resampling_factor = (float) current_resample_factor; - output_diff = (float) smooth_offset; - output_integral = (float) offset_integral; - output_offset = (float) offset; - - // Clamp a bit. - if( current_resample_factor < resample_lower_limit ) current_resample_factor = resample_lower_limit; - if( current_resample_factor > resample_upper_limit ) current_resample_factor = resample_upper_limit; - - // Now Calculate how many samples we need. - rlen = ceil( ((double)nframes) * current_resample_factor )+2; - assert( rlen > 2 ); - - // Calculate resample_mean so we can init ourselves to saner values. - resample_mean = 0.9999 * resample_mean + 0.0001 * current_resample_factor; - /* - * now this should do it... - */ - - outbuf = alloca( rlen * formats[format].sample_size * num_channels ); - - resampbuf = alloca( rlen * sizeof( float ) ); - /* - * render jack ports to the outbuf... - */ - - int chn = 0; - JSList *node = playback_ports; - JSList *src_node = playback_srcs; - SRC_DATA src; - - while ( node != NULL) - { - jack_port_t *port = (jack_port_t *) node->data; - float *buf = jack_port_get_buffer (port, nframes); - - SRC_STATE *src_state = src_node->data; - - src.data_in = buf; - src.input_frames = nframes; - - src.data_out = resampbuf; - src.output_frames = rlen; - src.end_of_input = 0; - - src.src_ratio = current_resample_factor; - - src_process( src_state, &src ); - - formats[format].jack_to_soundcard( outbuf + format[formats].sample_size * chn, resampbuf, src.output_frames_gen, num_channels*format[formats].sample_size, NULL); - - src_node = jack_slist_next (src_node); - node = jack_slist_next (node); - chn++; - } - - // now write the output... -again: - err = snd_pcm_writei(alsa_handle, outbuf, src.output_frames_gen); - //err = snd_pcm_writei(alsa_handle, outbuf, src.output_frames_gen); - if( err < 0 ) { - printf( "err = %d\n", err ); - if (xrun_recovery(alsa_handle, err) < 0) { - printf("Write error: %s\n", snd_strerror(err)); - exit(EXIT_FAILURE); - } - goto again; - } - - return 0; -} - -/** - * the latency callback. - * sets up the latencies on the ports. - */ - -void -latency_cb (jack_latency_callback_mode_t mode, void *arg) -{ - jack_latency_range_t range; - JSList *node; - - range.min = range.max = round(target_delay / static_resample_factor); - - if (mode == JackCaptureLatency) { - for (node = capture_ports; node; node = jack_slist_next (node)) { - jack_port_t *port = node->data; - jack_port_set_latency_range (port, mode, &range); - } - } else { - for (node = playback_ports; node; node = jack_slist_next (node)) { - jack_port_t *port = node->data; - jack_port_set_latency_range (port, mode, &range); - } - } -} - - -/** - * Allocate the necessary jack ports... - */ - -void alloc_ports( int n_capture, int n_playback ) { - - int port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal; - int chn; - jack_port_t *port; - char buf[32]; - - capture_ports = NULL; - for (chn = 0; chn < n_capture; chn++) - { - snprintf (buf, sizeof(buf) - 1, "capture_%u", chn+1); - - port = jack_port_register (client, buf, - JACK_DEFAULT_AUDIO_TYPE, - port_flags, 0); - - if (!port) - { - printf( "jacknet_client: cannot register port for %s", buf); - break; - } - - capture_srcs = jack_slist_append( capture_srcs, src_new( 4-samplerate_quality, 1, NULL ) ); - capture_ports = jack_slist_append (capture_ports, port); - } - - port_flags = JackPortIsInput; - - playback_ports = NULL; - for (chn = 0; chn < n_playback; chn++) - { - snprintf (buf, sizeof(buf) - 1, "playback_%u", chn+1); - - port = jack_port_register (client, buf, - JACK_DEFAULT_AUDIO_TYPE, - port_flags, 0); - - if (!port) - { - printf( "jacknet_client: cannot register port for %s", buf); - break; - } - - playback_srcs = jack_slist_append( playback_srcs, src_new( 4-samplerate_quality, 1, NULL ) ); - playback_ports = jack_slist_append (playback_ports, port); - } -} - -/** - * This is the shutdown callback for this JACK application. - * It is called by JACK if the server ever shuts down or - * decides to disconnect the client. - */ - -void jack_shutdown (void *arg) { - - exit (1); -} - -/** - * be user friendly. - * be user friendly. - * be user friendly. - */ - -void printUsage() { -fprintf(stderr, "usage: alsa_out [options]\n" - "\n" - " -j <jack name> - client name\n" - " -d <alsa_device> \n" - " -c <channels> \n" - " -p <period_size> \n" - " -n <num_period> \n" - " -r <sample_rate> \n" - " -q <sample_rate quality [0..4]\n" - " -m <max_diff> \n" - " -t <target_delay> \n" - " -i turns on instrumentation\n" - " -v turns on printouts\n" - "\n"); -} - - -/** - * the main function.... - */ - -void -sigterm_handler( int signal ) -{ - quit = 1; -} - - -int main (int argc, char *argv[]) { - char jack_name[30] = "alsa_out"; - char alsa_device[30] = "hw:0"; - int jack_opts = 0; - char *server_name = NULL; - - extern char *optarg; - extern int optind, optopt; - int errflg=0; - int c; - - while ((c = getopt(argc, argv, "ivj:r:c:p:n:d:q:m:t:f:F:C:Q:s:S:")) != -1) { - switch(c) { - case 'j': - strcpy(jack_name,optarg); - break; - case 'r': - sample_rate = atoi(optarg); - break; - case 'c': - num_channels = atoi(optarg); - break; - case 'p': - period_size = atoi(optarg); - break; - case 'n': - num_periods = atoi(optarg); - break; - case 'd': - strcpy(alsa_device,optarg); - break; - case 't': - target_delay = atoi(optarg); - break; - case 'q': - samplerate_quality = atoi(optarg); - break; - case 'm': - max_diff = atoi(optarg); - break; - case 'f': - catch_factor = atoi(optarg); - break; - case 'F': - catch_factor2 = atoi(optarg); - break; - case 'C': - pclamp = (double) atoi(optarg); - break; - case 'Q': - controlquant = (double) atoi(optarg); - break; - case 'v': - verbose = 1; - break; - case 'i': - instrument = 1; - break; - case 's': - smooth_size = atoi(optarg); - break; - case 'S': - server_name = optarg; - jack_opts |= JackServerName; - break; - case ':': - fprintf(stderr, - "Option -%c requires an operand\n", optopt); - errflg++; - break; - case '?': - fprintf(stderr, - "Unrecognized option: -%c\n", optopt); - errflg++; - } - } - if (errflg) { - printUsage(); - exit(2); - } - - if( (samplerate_quality < 0) || (samplerate_quality > 4) ) { - fprintf (stderr, "invalid samplerate quality\n"); - return 1; - } - if ((client = jack_client_open (jack_name, jack_opts, NULL, server_name)) == 0) { - fprintf (stderr, "jack server not running?\n"); - return 1; - } - - /* tell the JACK server to call `process()' whenever - there is work to be done. - */ - - jack_set_process_callback (client, process, 0); - - /* tell the JACK server to call `freewheel()' whenever - freewheel mode changes. - */ - - jack_set_freewheel_callback (client, freewheel, 0); - - /* tell the JACK server to call `jack_shutdown()' if - it ever shuts down, either entirely, or if it - just decides to stop calling us. - */ - - jack_on_shutdown (client, jack_shutdown, 0); - - if (jack_set_latency_callback) - jack_set_latency_callback (client, latency_cb, 0); - - // get jack sample_rate - - jack_sample_rate = jack_get_sample_rate( client ); - - if( !sample_rate ) - sample_rate = jack_sample_rate; - - static_resample_factor = (double) sample_rate / (double) jack_sample_rate; - resample_lower_limit = static_resample_factor * 0.25; - resample_upper_limit = static_resample_factor * 4.0; - resample_mean = static_resample_factor; - - offset_array = malloc( sizeof(double) * smooth_size ); - if( offset_array == NULL ) { - fprintf( stderr, "no memory for offset_array !!!\n" ); - exit(20); - } - window_array = malloc( sizeof(double) * smooth_size ); - if( window_array == NULL ) { - fprintf( stderr, "no memory for window_array !!!\n" ); - exit(20); - } - int i; - for( i=0; i<smooth_size; i++ ) { - offset_array[i] = 0.0; - window_array[i] = hann( (double) i / ((double) smooth_size - 1.0) ); - } - - jack_buffer_size = jack_get_buffer_size( client ); - // Setup target delay and max_diff for the normal user, who does not play with them... - if( !target_delay ) - target_delay = (num_periods*period_size / 2) - jack_buffer_size/2; - - if( !max_diff ) - max_diff = target_delay; - - if( max_diff > target_delay ) { - fprintf( stderr, "target_delay (%d) can not be smaller than max_diff(%d)\n", target_delay, max_diff ); - exit(20); - } - if( (target_delay+max_diff) > (num_periods*period_size) ) { - fprintf( stderr, "target_delay+max_diff (%d) can not be bigger than buffersize(%d)\n", target_delay+max_diff, num_periods*period_size ); - exit(20); - } - // now open the alsa fd... - alsa_handle = open_audiofd( alsa_device, 0, sample_rate, num_channels, period_size, num_periods); - if( alsa_handle == 0 ) - exit(20); - - printf( "selected sample format: %s\n", formats[format].name ); - - // alloc input ports, which are blasted out to alsa... - alloc_ports( 0, num_channels ); - - outbuf = malloc( num_periods * period_size * formats[format].sample_size * num_channels ); - resampbuf = malloc( num_periods * period_size * sizeof( float ) ); - tmpbuf = malloc( 512 * formats[format].sample_size * num_channels ); - - if ((outbuf == NULL) || (resampbuf == NULL) || (tmpbuf == NULL)) - { - fprintf( stderr, "no memory for buffers.\n" ); - exit(20); - } - - - /* tell the JACK server that we are ready to roll */ - - if (jack_activate (client)) { - fprintf (stderr, "cannot activate client"); - return 1; - } - - signal( SIGTERM, sigterm_handler ); - signal( SIGINT, sigterm_handler ); - - if( verbose ) { - while(!quit) { - usleep(500000); - if( output_new_delay ) { - printf( "delay = %d\n", output_new_delay ); - output_new_delay = 0; - } - printf( "res: %f, \tdiff = %f, \toffset = %f \n", output_resampling_factor, output_diff, output_offset ); - } - } else if( instrument ) { - printf( "# n\tresamp\tdiff\toffseti\tintegral\n"); - int n=0; - while(!quit) { - usleep(1000); - printf( "%d\t%f\t%f\t%f\t%f\n", n++, output_resampling_factor, output_diff, output_offset, output_integral ); - } - } else { - while(!quit) - { - usleep(500000); - if( output_new_delay ) { - printf( "delay = %d\n", output_new_delay ); - output_new_delay = 0; - } - } - } - - jack_deactivate( client ); - jack_client_close (client); - exit (0); -} diff --git a/tools/bufsize.c b/tools/bufsize.c deleted file mode 100644 index 87683595..00000000 --- a/tools/bufsize.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * bufsize.c -- change JACK buffer size. - * - * Copyright (C) 2003 Jack O'Quin. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <stdio.h> -#include <errno.h> -#include <unistd.h> -#include <signal.h> -#include <stdlib.h> -#include <string.h> -#include <jack/jack.h> -#include <jack/transport.h> - -char *package; /* program name */ -jack_client_t *client; -jack_nframes_t nframes; -int just_print_bufsize=0; - -void jack_shutdown(void *arg) -{ - fprintf(stderr, "JACK shut down, exiting ...\n"); - exit(1); -} - -void signal_handler(int sig) -{ - jack_client_close(client); - fprintf(stderr, "signal received, exiting ...\n"); - exit(0); -} - -void parse_arguments(int argc, char *argv[]) -{ - /* basename $0 */ - package = strrchr(argv[0], '/'); - if (package == 0) - package = argv[0]; - else - package++; - - if (argc==1) { - just_print_bufsize = 1; - return; - } - if (argc < 2) { - fprintf(stderr, "usage: %s <bufsize>\n", package); - exit(9); - } - - if (strspn (argv[1], "0123456789") != strlen (argv[1])) { - fprintf(stderr, "usage: %s <bufsize>\n", package); - exit(8); - } - - nframes = strtoul(argv[1], NULL, 0); - if (errno == ERANGE) { - fprintf(stderr, "%s: invalid buffer size: %s (range is 1-16384)\n", - package, argv[1]); - exit(2); - } - if (nframes < 1 || nframes > 16384) { - fprintf(stderr, "%s: invalid buffer size: %s (range is 1-16384)\n", - package, argv[1]); - exit(3); - } -} - -void silent_function( const char *ignore ) -{ -} - -int main(int argc, char *argv[]) -{ - int rc; - parse_arguments(argc, argv); - - if (just_print_bufsize) - jack_set_info_function( silent_function ); - - /* become a JACK client */ - if ((client = jack_client_open(package, JackNoStartServer, NULL)) == 0) { - fprintf(stderr, "JACK server not running?\n"); - exit(1); - } - -#ifndef WIN32 - signal(SIGQUIT, signal_handler); - signal(SIGHUP, signal_handler); -#endif - signal(SIGTERM, signal_handler); - signal(SIGINT, signal_handler); - - jack_on_shutdown(client, jack_shutdown, 0); - - if (just_print_bufsize) { - fprintf(stdout, "%d\n", jack_get_buffer_size( client ) ); - rc = 0; - } - else - { - rc = jack_set_buffer_size(client, nframes); - if (rc) - fprintf(stderr, "jack_set_buffer_size(): %s\n", strerror(rc)); - } - jack_client_close(client); - - return rc; -} diff --git a/tools/connect.c b/tools/connect.c deleted file mode 100644 index fc43b5e9..00000000 --- a/tools/connect.c +++ /dev/null @@ -1,248 +0,0 @@ -/* - Copyright (C) 2002 Jeremy Hall - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include <stdio.h> -#include <errno.h> -#ifndef WIN32 -#include <unistd.h> -#endif -#include <string.h> -#include <stdlib.h> -#include <getopt.h> - -#include <jack/jack.h> -#include <jack/session.h> - -#define TRUE 1 -#define FALSE 0 - -volatile int done = 0; - -void port_connect_callback(jack_port_id_t a, jack_port_id_t b, int connect, void* arg) -{ - done = 1; -} - -void -show_version (char *my_name) -{ - //fprintf (stderr, "%s: JACK Audio Connection Kit version " VERSION "\n", my_name); -} - -void -show_usage (char *my_name) -{ - show_version (my_name); - fprintf (stderr, "\nusage: %s [options] port1 port2\n", my_name); - fprintf (stderr, "Connects two JACK ports together.\n\n"); - fprintf (stderr, " -s, --server <name> Connect to the jack server named <name>\n"); - fprintf (stderr, " -v, --version Output version information and exit\n"); - fprintf (stderr, " -h, --help Display this help message\n\n"); - fprintf (stderr, "For more information see http://jackaudio.org/\n"); -} - -int -main (int argc, char *argv[]) -{ - jack_client_t *client; - jack_status_t status; - char *server_name = NULL; - int c; - int option_index; - jack_options_t options = JackNoStartServer; - char *my_name = strrchr(argv[0], '/'); - jack_port_t *src_port = 0; - jack_port_t *dst_port = 0; - jack_port_t *port1 = 0; - jack_port_t *port2 = 0; - char portA[300]; - char portB[300]; - int use_uuid=0; - int connecting, disconnecting; - int port1_flags, port2_flags; - int rc = 1; - - struct option long_options[] = { - { "server", 1, 0, 's' }, - { "help", 0, 0, 'h' }, - { "version", 0, 0, 'v' }, - { "uuid", 0, 0, 'u' }, - { 0, 0, 0, 0 } - }; - - while ((c = getopt_long (argc, argv, "s:hvu", long_options, &option_index)) >= 0) { - switch (c) { - case 's': - server_name = (char *) malloc (sizeof (char) * (strlen(optarg) + 1)); - strcpy (server_name, optarg); - options |= JackServerName; - break; - case 'u': - use_uuid = 1; - break; - case 'h': - show_usage (my_name); - return 1; - break; - case 'v': - show_version (my_name); - return 1; - break; - default: - show_usage (my_name); - return 1; - break; - } - } - - connecting = disconnecting = FALSE; - if (my_name == 0) { - my_name = argv[0]; - } else { - my_name ++; - } - - if (strstr(my_name, "disconnect")) { - disconnecting = 1; - } else if (strstr(my_name, "connect")) { - connecting = 1; - } else { - fprintf(stderr, "ERROR! client should be called jack_connect or jack_disconnect. client is called %s\n", my_name); - return 1; - } - - if (argc < 3) { - show_usage(my_name); - return 1; - } - - /* try to become a client of the JACK server */ - - if ((client = jack_client_open (my_name, options, &status, server_name)) == 0) { - fprintf (stderr, "jack server not running?\n"); - return 1; - } - - jack_set_port_connect_callback(client, port_connect_callback, NULL); - - /* find the two ports */ - - if( use_uuid ) { - char *tmpname; - char *clientname; - char *portname; - tmpname = strdup( argv[argc-1] ); - portname = strchr( tmpname, ':' ); - portname[0] = '\0'; - portname+=1; - clientname = jack_get_client_name_by_uuid( client, tmpname ); - if( clientname ) { - - snprintf( portA, sizeof(portA), "%s:%s", clientname, portname ); - jack_free( clientname ); - } else { - snprintf( portA, sizeof(portA), "%s", argv[argc-1] ); - } - free( tmpname ); - - tmpname = strdup( argv[argc-2] ); - portname = strchr( tmpname, ':' ); - portname[0] = '\0'; - portname+=1; - clientname = jack_get_client_name_by_uuid( client, tmpname ); - if( clientname ) { - snprintf( portB, sizeof(portB), "%s:%s", clientname, portname ); - jack_free( clientname ); - } else { - snprintf( portB, sizeof(portB), "%s", argv[argc-2] ); - } - - free( tmpname ); - - } else { - snprintf( portA, sizeof(portA), "%s", argv[argc-1] ); - snprintf( portB, sizeof(portB), "%s", argv[argc-2] ); - } - if ((port1 = jack_port_by_name(client, portA)) == 0) { - fprintf (stderr, "ERROR %s not a valid port\n", portA); - goto exit; - } - if ((port2 = jack_port_by_name(client, portB)) == 0) { - fprintf (stderr, "ERROR %s not a valid port\n", portB); - goto exit; - } - - port1_flags = jack_port_flags (port1); - port2_flags = jack_port_flags (port2); - - if (port1_flags & JackPortIsInput) { - if (port2_flags & JackPortIsOutput) { - src_port = port2; - dst_port = port1; - } - } else { - if (port2_flags & JackPortIsInput) { - src_port = port1; - dst_port = port2; - } - } - - if (!src_port || !dst_port) { - fprintf (stderr, "arguments must include 1 input port and 1 output port\n"); - goto exit; - } - - /* tell the JACK server that we are ready to roll */ - if (jack_activate (client)) { - fprintf (stderr, "cannot activate client"); - goto exit; - } - - /* connect the ports. Note: you can't do this before - the client is activated (this may change in the future). - */ - - if (connecting) { - if (jack_connect(client, jack_port_name(src_port), jack_port_name(dst_port))) { - fprintf (stderr, "cannot connect client, already connected?\n"); - goto exit; - } - } - if (disconnecting) { - if (jack_disconnect(client, jack_port_name(src_port), jack_port_name(dst_port))) { - fprintf (stderr, "cannot disconnect client, already disconnected?\n"); - goto exit; - } - } - - // Wait for connection/disconnection to be effective - while(!done) { -#ifdef WIN32 - Sleep(10); -#else - usleep(10000); -#endif - } - - /* everything was ok, so setting exitcode to 0 */ - rc = 0; - -exit: - jack_client_close (client); - exit (rc); -} diff --git a/tools/evmon.c b/tools/evmon.c deleted file mode 100644 index fdd5b2a0..00000000 --- a/tools/evmon.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - Copyright (C) 2007 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include <stdio.h> -#include <errno.h> -#ifndef WIN32 -#include <unistd.h> -#endif -#include <string.h> -#include <signal.h> -#include <stdlib.h> - -#include <jack/jack.h> -#include <jack/metadata.h> -#include <jack/uuid.h> - -jack_client_t *client; - -static void signal_handler(int sig) -{ - jack_client_close(client); - fprintf(stderr, "signal received, exiting ...\n"); - exit(0); -} - -static void -port_rename_callback (jack_port_id_t port, const char* old_name, const char* new_name, void* arg) -{ - printf ("Port %d renamed from %s to %s\n", port, old_name, new_name); -} - -static void -port_callback (jack_port_id_t port, int yn, void* arg) -{ - printf ("Port %d %s\n", port, (yn ? "registered" : "unregistered")); -} - -static void -connect_callback (jack_port_id_t a, jack_port_id_t b, int yn, void* arg) -{ - printf ("Ports %d and %d %s\n", a, b, (yn ? "connected" : "disconnected")); -} - -static void -client_callback (const char* client, int yn, void* arg) -{ - printf ("Client %s %s\n", client, (yn ? "registered" : "unregistered")); -} - -static int -graph_callback (void* arg) -{ - printf ("Graph reordered\n"); - return 0; -} - -static void -propchange (jack_uuid_t subject, const char* key, jack_property_change_t change, void* arg) -{ - char buf[JACK_UUID_STRING_SIZE]; - const char* action = ""; - - switch (change) { - case PropertyCreated: - action = "created"; - break; - - case PropertyChanged: - action = "changed"; - break; - - case PropertyDeleted: - action = "deleted"; - break; - } - - if (jack_uuid_empty (subject)) { - printf ("All properties changed!\n"); - } else { - jack_uuid_unparse (subject, buf); - - if (key) { - printf ("key [%s] for %s %s\n", key, buf, action); - } else { - printf ("all keys for %s %s\n", buf, action); - } - } -} - -int -main (int argc, char *argv[]) -{ - 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_rename_callback (client, port_rename_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, propchange, NULL)) { - fprintf (stderr, "cannot set property change 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); -} - diff --git a/tools/freewheel.c b/tools/freewheel.c deleted file mode 100644 index 005b3bb8..00000000 --- a/tools/freewheel.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * freewheel - start/stop JACK "freewheeling" mode - * - * Copyright (C) 2003 Paul Davis. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <stdio.h> -#include <errno.h> -#include <unistd.h> -#include <signal.h> -#include <stdlib.h> -#include <string.h> -#include <jack/jack.h> -#include <jack/transport.h> - -char *package; /* program name */ -jack_client_t *client; -int onoff; - -static void jack_shutdown(void *arg) -{ - fprintf(stderr, "JACK shut down, exiting ...\n"); - exit(1); -} - -static void signal_handler(int sig) -{ - jack_client_close(client); - fprintf(stderr, "signal received, exiting ...\n"); - exit(0); -} - -static void parse_arguments(int argc, char *argv[]) -{ - if (argc < 2) { - fprintf(stderr, "usage: %s y|n\n", package); - exit(9); - } - - if (argv[1][0] == 'y' || argv[1][0] == 'Y' || argv[1][0] == '1') { - onoff = 1; - } else { - onoff = 0; - } -} - -int -main (int argc, char *argv[]) -{ - parse_arguments (argc, argv); - - /* become a JACK client */ - if ((client = jack_client_open ("freewheel", JackNullOption, NULL)) == 0) { - fprintf (stderr, "JACK server not running?\n"); - exit(1); - } - -#ifndef WIN32 - signal (SIGQUIT, signal_handler); - signal (SIGHUP, signal_handler); -#endif - signal (SIGTERM, signal_handler); - signal (SIGINT, signal_handler); - - jack_on_shutdown (client, jack_shutdown, 0); - - if (jack_set_freewheel (client, onoff)) { - fprintf (stderr, "failed to reset freewheel mode\n"); - } - - jack_client_close(client); - return 0; -} diff --git a/tools/ipload.c b/tools/ipload.c deleted file mode 100644 index a5a47134..00000000 --- a/tools/ipload.c +++ /dev/null @@ -1,246 +0,0 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <signal.h> -#ifndef WIN32 -#include <unistd.h> -#endif -#include <getopt.h> -#include <jack/jack.h> -#include <jack/intclient.h> - -jack_client_t *client; -jack_intclient_t intclient; -char *client_name; -char *intclient_name; -char *load_name; -char *load_init = ""; -char *server_name = NULL; -int autoclose_opt = 0; -int wait_opt = 0; -volatile int idling = 1; - -static void -signal_handler (int sig) -{ - /* do nothing if internal client closed itself */ - if (idling == 0) - return; - - jack_status_t status; - - fprintf (stderr, "signal received, unloading..."); - status = jack_internal_client_unload (client, intclient); - if (status & JackFailure) - fprintf (stderr, "(failed), status = 0x%2.0x\n", status); - else - fprintf (stderr, "(succeeded)\n"); - if (autoclose_opt) - jack_deactivate(client); - jack_client_close (client); - exit (0); -} - -static void -registration_callback (const char *name, int reg, void *arg) -{ - if (reg || strcmp(intclient_name, name)) - return; - - /* this will stop the wait loop and thus close this application. */ - idling = 0; - return; - - /* unused */ - (void)arg; -} - -static void -show_usage () -{ - fprintf (stderr, "usage: %s [ options ] client-name [ load-name " - "[ init-string]]\n\noptions:\n", client_name); - fprintf (stderr, - "\t-h, --help \t\t print help message\n" - "\t-a, --autoclose\t automatically close when intclient is unloaded\n" - "\t-i, --init string\t initialize string\n" - "\t-s, --server name\t select JACK server\n" - "\t-w, --wait \t\t wait for signal, then unload\n" - "\n" - ); -} - -static int -parse_args (int argc, char *argv[]) -{ - int c; - int option_index = 0; - char *short_options = "hai:s:w"; - struct option long_options[] = { - { "help", 0, 0, 'h' }, - { "autoclose", 0, 0, 'a' }, - { "init", required_argument, 0, 'i' }, - { "server", required_argument, 0, 's' }, - { "wait", 0, 0, 'w' }, - { 0, 0, 0, 0 } - }; - - client_name = strrchr(argv[0], '/'); - if (client_name == NULL) { - client_name = argv[0]; - } else { - client_name++; - } - - while ((c = getopt_long (argc, argv, short_options, long_options, - &option_index)) >= 0) { - switch (c) { - case 'a': - autoclose_opt = 1; - break; - case 'i': - load_init = optarg; - break; - case 's': - server_name = optarg; - break; - case 'w': - wait_opt = 1; - break; - case 'h': - default: - show_usage (); - return 1; - } - } - - /* autoclose makes no sense without wait */ - if (autoclose_opt && ! wait_opt) - autoclose_opt = 0; - - if (optind == argc) { /* no positional args? */ - show_usage (); - return 1; - } - if (optind < argc) - load_name = intclient_name = argv[optind++]; - - if (optind < argc) - load_name = argv[optind++]; - - if (optind < argc) - load_init = argv[optind++]; - - //fprintf (stderr, "client-name = `%s', load-name = `%s', " - // "load-init = `%s', wait = %d\n", - // intclient_name, load_name, load_init, wait_opt); - - return 0; /* args OK */ -} - -int -main (int argc, char *argv[]) -{ - jack_status_t status; - char* name; - - /* parse and validate command arguments */ - if (parse_args (argc, argv)) - exit (1); /* invalid command line */ - - /* first, become a JACK client */ - client = jack_client_open (client_name, JackServerName, - &status, server_name); - if (client == NULL) { - fprintf (stderr, "jack_client_open() failed, " - "status = 0x%2.0x\n", status); - if (status & JackServerFailed) { - fprintf (stderr, "Unable to connect to JACK server\n"); - } - exit (1); - } - if (status & JackServerStarted) { - fprintf (stderr, "JACK server started\n"); - } - if (status & JackNameNotUnique) { - client_name = jack_get_client_name(client); - fprintf (stderr, "unique name `%s' assigned\n", client_name); - } - - /* then, load the internal client */ - intclient = jack_internal_client_load (client, intclient_name, - (JackLoadName|JackLoadInit), - &status, load_name, load_init); - if (status & JackFailure) { - fprintf (stderr, "could not load %s, intclient = %d status = 0x%2.0x\n", - load_name, (int)intclient, status); - return 2; - } - if (status & JackNameNotUnique) { - intclient_name = - jack_get_internal_client_name (client, intclient); - fprintf (stderr, "unique internal client name `%s' assigned\n", - intclient_name); - } - - fprintf (stdout, "%s is running.\n", load_name); - - name = jack_get_internal_client_name(client, intclient); - if (name) { - printf("client name = %s\n", name); - free(name); - } - fflush(stdout); - - if (autoclose_opt) { - jack_set_client_registration_callback(client, registration_callback, NULL); - jack_activate(client); - } - - if (wait_opt) { - /* define a signal handler to unload the client, then - * wait for it to exit */ - #ifdef WIN32 - signal(SIGINT, signal_handler); - signal(SIGABRT, signal_handler); - signal(SIGTERM, signal_handler); - #else - signal(SIGQUIT, signal_handler); - signal(SIGTERM, signal_handler); - signal(SIGHUP, signal_handler); - signal(SIGINT, signal_handler); - #endif - - while (idling) { - #ifdef WIN32 - Sleep(1000); - #else - sleep (1); - #endif - } - } - - if (autoclose_opt) { - jack_deactivate(client); - } - - jack_client_close(client); - return 0; -} - diff --git a/tools/ipunload.c b/tools/ipunload.c deleted file mode 100644 index 2ce3d0c8..00000000 --- a/tools/ipunload.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include <string.h> -#include <stdlib.h> -#include <stdio.h> -#include <jack/jack.h> -#include <jack/intclient.h> - -int -main (int argc, char *argv[]) -{ - char *my_name; - char *client_name; - jack_client_t *client; - jack_status_t status; - jack_intclient_t intclient; - - /* validate args */ - if ((argc < 2) || (argc > 3)) { - fprintf (stderr, "usage: %s client-name [ server-name ]]\n", - argv[0]); - return 1; - } - - /* use `basename $0` for my own client name */ - my_name = strrchr(argv[0], '/'); - if (my_name == 0) { - my_name = argv[0]; - } else { - my_name++; - } - - /* first, become a JACK client */ - if (argc > 2) { - client = jack_client_open (my_name, - (JackServerName|JackNoStartServer), - &status, argv[2]); - } else { - client = jack_client_open (my_name, JackNoStartServer, &status); - } - - if (client == NULL) { - if (status & JackServerFailed) { - fprintf (stderr, "JACK server not running.\n"); - } else { - fprintf (stderr, "JACK open failed, " - "status = 0x%2.0x\n", status); - } - exit (1); - } - - /* then, get the internal client handle */ - client_name = argv[1]; - intclient = jack_internal_client_handle (client, client_name, &status); - if (status & JackFailure) { - fprintf (stderr, "client %s not found.\n", client_name); - exit (2); - } - - /* now, unload the internal client */ - status = jack_internal_client_unload (client, intclient); - if (status & JackFailure) { - if (status & JackNoSuchClient) { - fprintf (stderr, "client %s is gone.\n", - client_name); - } else { - fprintf (stderr, "could not unload %s, " - "returns 0x%2.0x\n", client_name, status); - } - exit (3); - } else { - fprintf (stdout, "%s unloaded.\n", client_name); - } - - jack_client_close(client); - return 0; -} - - diff --git a/tools/lsp.c b/tools/lsp.c deleted file mode 100644 index a1e3f1aa..00000000 --- a/tools/lsp.c +++ /dev/null @@ -1,291 +0,0 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include <stdio.h> -#include <stdlib.h> -#ifndef WIN32 -#include <unistd.h> -#endif -#include <string.h> -#include <getopt.h> -#include <inttypes.h> - -#include <jack/jack.h> -#include <jack/session.h> -#include <jack/uuid.h> - -char * my_name; - -static void -show_version (void) -{ - //fprintf (stderr, "%s: JACK Audio Connection Kit version " VERSION "\n", my_name); -} - -static void -printf_name2uuid (jack_client_t* client, const char* pname) -{ - char *port_component = strchr( pname, ':' ); - size_t csize = port_component - pname + 1; - char client_component[csize]; - snprintf(client_component, csize, "%s", pname); - - char *uuid = jack_get_uuid_for_client_name(client, client_component); - if (uuid) { - printf("%s%s\n", uuid, port_component ); - } else { - printf("%s\n",pname); - } - jack_free(uuid); -} - -static void -show_usage (void) -{ - show_version (); - fprintf (stderr, "\nUsage: %s [options] [filter string]\n", my_name); - fprintf (stderr, "List active Jack ports, and optionally display extra information.\n"); - fprintf (stderr, "Optionally filter ports which match ALL strings provided after any options.\n\n"); - fprintf (stderr, "Display options:\n"); - fprintf (stderr, " -s, --server <name> Connect to the jack server named <name>\n"); - fprintf (stderr, " -A, --aliases List aliases for each port\n"); - fprintf (stderr, " -c, --connections List connections to/from each port\n"); - fprintf (stderr, " -l, --port-latency Display per-port latency in frames at each port\n"); - fprintf (stderr, " -L, --total-latency Display total latency in frames at each port\n"); - fprintf (stderr, " -p, --properties Display port properties. Output may include:\n" - " input|output, can-monitor, physical, terminal\n\n"); - fprintf (stderr, " -t, --type Display port type\n"); - fprintf (stderr, " -u, --uuid Display uuid instead of client name (if available)\n"); - fprintf (stderr, " -U, --port-uuid Display port uuid\n"); - fprintf (stderr, " -h, --help Display this help message\n"); - fprintf (stderr, " --version Output version information and exit\n\n"); - fprintf (stderr, "For more information see http://jackaudio.org/\n"); -} - -int -main (int argc, char *argv[]) -{ - jack_client_t *client; - jack_status_t status; - jack_options_t options = JackNoStartServer; - const char **ports, **connections; - unsigned int i, j, k; - int skip_port; - int show_aliases = 0; - int show_con = 0; - int show_port_latency = 0; - int show_total_latency = 0; - int show_properties = 0; - int show_type = 0; - int show_uuid = 0; - int show_port_uuid = 0; - int c; - int option_index; - char* aliases[2]; - char *server_name = NULL; - - struct option long_options[] = { - { "server", 1, 0, 's' }, - { "aliases", 0, 0, 'A' }, - { "connections", 0, 0, 'c' }, - { "port-latency", 0, 0, 'l' }, - { "total-latency", 0, 0, 'L' }, - { "properties", 0, 0, 'p' }, - { "type", 0, 0, 't' }, - { "uuid", 0, 0, 'u' }, - { "port-uuid", 0, 0, 'U' }, - { "help", 0, 0, 'h' }, - { "version", 0, 0, 'v' }, - { 0, 0, 0, 0 } - }; - - my_name = strrchr(argv[0], '/'); - if (my_name == 0) { - my_name = argv[0]; - } else { - my_name ++; - } - - while ((c = getopt_long (argc, argv, "s:AclLphvtuU", long_options, &option_index)) >= 0) { - switch (c) { - case 's': - server_name = (char *) malloc (sizeof (char) * strlen(optarg)); - strcpy (server_name, optarg); - options |= JackServerName; - break; - case 'A': - aliases[0] = (char *) malloc (jack_port_name_size()); - aliases[1] = (char *) malloc (jack_port_name_size()); - show_aliases = 1; - break; - case 'c': - show_con = 1; - break; - case 'l': - show_port_latency = 1; - break; - case 'L': - show_total_latency = 1; - break; - case 'p': - show_properties = 1; - break; - case 't': - show_type = 1; - break; - case 'u': - show_uuid = 1; - break; - case 'U': - show_port_uuid = 1; - break; - case 'h': - show_usage (); - return 1; - break; - case 'v': - show_version (); - return 1; - break; - default: - show_usage (); - return 1; - break; - } - } - - /* Open a client connection to the JACK server. Starting a - * new server only to list its ports seems pointless, so we - * specify JackNoStartServer. */ - if ((client = jack_client_open ("lsp", options, &status, server_name)) == 0) { - fprintf (stderr, "Error: cannot connect to JACK, "); - if (status & JackServerFailed) { - fprintf (stderr, "server is not running.\n"); - } else { - fprintf (stderr, "jack_client_open() failed, status = 0x%2.0x\n", status); - } - return 1; - } - - ports = jack_get_ports (client, NULL, NULL, 0); - - for (i = 0; ports && ports[i]; ++i) { - // skip over any that don't match ALL of the strings presented at command line - skip_port = 0; - for (k = optind; k < argc; k++){ - if (strstr(ports[i], argv[k]) == NULL ){ - skip_port = 1; - } - } - if (skip_port) continue; - - if (show_uuid) { - printf_name2uuid(client, ports[i]); - } else { - printf ("%s\n", ports[i]); - } - - jack_port_t *port = jack_port_by_name (client, ports[i]); - - if (show_port_uuid) { - char buf[JACK_UUID_STRING_SIZE]; - jack_uuid_t uuid = jack_port_uuid (port); - jack_uuid_unparse (uuid, buf); - printf (" uuid: %s\n", buf); - } - - if (show_aliases) { - int cnt; - int i; - - cnt = jack_port_get_aliases (port, aliases); - for (i = 0; i < cnt; ++i) { - printf (" %s\n", aliases[i]); - } - } - - if (show_con) { - if ((connections = jack_port_get_all_connections (client, jack_port_by_name(client, ports[i]))) != 0) { - for (j = 0; connections[j]; j++) { - printf(" "); - if (show_uuid) { - printf_name2uuid(client, connections[j]); - } else { - printf("%s\n", connections[j]); - } - } - jack_free (connections); - } - } - if (show_port_latency) { - if (port) { - jack_latency_range_t range; - - jack_port_get_latency_range (port, JackPlaybackLatency, &range); - printf (" port playback latency = [ %" PRIu32 " %" PRIu32 " ] frames\n", - range.min, range.max); - - jack_port_get_latency_range (port, JackCaptureLatency, &range); - printf (" port capture latency = [ %" PRIu32 " %" PRIu32 " ] frames\n", - range.min, range.max); - } - } - if (show_total_latency) { - if (port) { - printf (" total latency = %d frames\n", - jack_port_get_total_latency (client, port)); - } - } - if (show_properties) { - if (port) { - int flags = jack_port_flags (port); - printf (" properties: "); - if (flags & JackPortIsInput) { - fputs ("input,", stdout); - } - if (flags & JackPortIsOutput) { - fputs ("output,", stdout); - } - if (flags & JackPortCanMonitor) { - fputs ("can-monitor,", stdout); - } - if (flags & JackPortIsPhysical) { - fputs ("physical,", stdout); - } - if (flags & JackPortIsTerminal) { - fputs ("terminal,", stdout); - } - putc ('\n', stdout); - } - } - if (show_type) { - if (port) { - putc ('\t', stdout); - fputs (jack_port_type (port), stdout); - putc ('\n', stdout); - } - } - } - - if (show_aliases) { - free(aliases[0]); - free(aliases[1]); - } - if (ports) - jack_free (ports); - jack_client_close (client); - exit (0); -} diff --git a/tools/midi_dump.c b/tools/midi_dump.c deleted file mode 100644 index ef9148b3..00000000 --- a/tools/midi_dump.c +++ /dev/null @@ -1,238 +0,0 @@ -// gcc -o jack_midi_dump -Wall midi_dump.c -ljack -pthread - -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <assert.h> -#include <inttypes.h> -#include <jack/jack.h> -#include <jack/midiport.h> -#include <jack/ringbuffer.h> - -#ifdef __MINGW32__ -#include <pthread.h> -#endif - -#ifndef WIN32 -#include <signal.h> -#include <pthread.h> -#include <sys/mman.h> -#endif - -static jack_port_t* port; -static jack_ringbuffer_t *rb = NULL; -static pthread_mutex_t msg_thread_lock = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t data_ready = PTHREAD_COND_INITIALIZER; - -static int keeprunning = 1; -static uint64_t monotonic_cnt = 0; - -#define RBSIZE 100 -#define MSG_BUFFER_SIZE 4096 - -typedef struct { - uint8_t buffer[MSG_BUFFER_SIZE]; - uint32_t size; - uint32_t tme_rel; - uint64_t tme_mon; -} midimsg; - -static void -describe (midimsg* event) -{ - if (event->size == 0) { - return; - } - - uint8_t type = event->buffer[0] & 0xf0; - uint8_t channel = event->buffer[0] & 0xf; - - switch (type) { - case 0x90: - assert (event->size == 3); - printf (" note on (channel %2d): pitch %3d, velocity %3d", channel, event->buffer[1], event->buffer[2]); - break; - case 0x80: - assert (event->size == 3); - printf (" note off (channel %2d): pitch %3d, velocity %3d", channel, event->buffer[1], event->buffer[2]); - break; - case 0xb0: - assert (event->size == 3); - printf (" control change (channel %2d): controller %3d, value %3d", channel, event->buffer[1], event->buffer[2]); - break; - default: - break; - } -} - -int -process (jack_nframes_t frames, void* arg) -{ - void* buffer; - jack_nframes_t N; - jack_nframes_t i; - - buffer = jack_port_get_buffer (port, frames); - assert (buffer); - - N = jack_midi_get_event_count (buffer); - for (i = 0; i < N; ++i) { - jack_midi_event_t event; - int r; - r = jack_midi_event_get (&event, buffer, i); - - if (r != 0) {continue;} - - if (event.size > MSG_BUFFER_SIZE) { - fprintf(stderr, "Error: MIDI message was too large, skipping event. Max. allowed size: %d bytes\n", MSG_BUFFER_SIZE); - } - else if (jack_ringbuffer_write_space (rb) >= sizeof(midimsg)) { - midimsg m; - m.tme_mon = monotonic_cnt; - m.tme_rel = event.time; - m.size = event.size; - memcpy (m.buffer, event.buffer, event.size); - jack_ringbuffer_write (rb, (void *) &m, sizeof(midimsg)); - } - else { - fprintf (stderr, "Error: ringbuffer was full, skipping event.\n"); - } - } - - monotonic_cnt += frames; - - if (pthread_mutex_trylock (&msg_thread_lock) == 0) { - pthread_cond_signal (&data_ready); - pthread_mutex_unlock (&msg_thread_lock); - } - - return 0; -} - -static void wearedone(int sig) { - fprintf(stderr, "Shutting down\n"); - keeprunning = 0; - /* main loop might be blocked by data_ready when jack server dies. */ - if (pthread_mutex_trylock (&msg_thread_lock) == 0) { - pthread_cond_signal (&data_ready); - pthread_mutex_unlock (&msg_thread_lock); - } -} - -static void usage (int status) { - printf ("jack_midi_dump - JACK MIDI Monitor.\n\n"); - printf ("Usage: jack_midi_dump [ OPTIONS ] [CLIENT-NAME]\n\n"); - printf ("Options:\n\ - -a use absolute timestamps relative to application start\n\ - -h display this help and exit\n\ - -r use relative timestamps to previous MIDI event\n\ -\n"); - printf ("\n\ -This tool listens for MIDI events on a JACK MIDI port and prints\n\ -the message to stdout.\n\ -\n\ -If no client name is given it defaults to 'midi-monitor'.\n\ -\n\ -See also: jackd(1)\n\ -\n"); - exit (status); -} - -int -main (int argc, char* argv[]) -{ - jack_client_t* client; - char const default_name[] = "midi-monitor"; - char const * client_name; - int time_format = 0; - int r; - - int cn = 1; - - if (argc > 1) { - if (!strcmp (argv[1], "-a")) { time_format = 1; cn = 2; } - else if (!strcmp (argv[1], "-r")) { time_format = 2; cn = 2; } - else if (!strcmp (argv[1], "-h")) { usage (EXIT_SUCCESS); } - else if (argv[1][0] == '-') { usage (EXIT_FAILURE); } - } - - if (argc > cn) { - client_name = argv[cn]; - } else { - client_name = default_name; - } - - client = jack_client_open (client_name, JackNullOption, NULL); - if (client == NULL) { - fprintf (stderr, "Could not create JACK client.\n"); - exit (EXIT_FAILURE); - } - - rb = jack_ringbuffer_create (RBSIZE * sizeof(midimsg)); - - jack_set_process_callback (client, process, 0); - - port = jack_port_register (client, "input", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0); - if (port == NULL) { - fprintf (stderr, "Could not register port.\n"); - exit (EXIT_FAILURE); - } - -#ifndef WIN32 - if (mlockall (MCL_CURRENT | MCL_FUTURE)) { - fprintf (stderr, "Warning: Can not lock memory.\n"); - } -#endif - - r = jack_activate (client); - if (r != 0) { - fprintf (stderr, "Could not activate client.\n"); - exit (EXIT_FAILURE); - } - -#ifndef WIN32 - signal(SIGHUP, wearedone); - signal(SIGINT, wearedone); -#endif - - pthread_mutex_lock (&msg_thread_lock); - - uint64_t prev_event = 0; - while (keeprunning) { - const int mqlen = jack_ringbuffer_read_space (rb) / sizeof(midimsg); - int i; - for (i=0; i < mqlen; ++i) { - size_t j; - midimsg m; - jack_ringbuffer_read(rb, (char*) &m, sizeof(midimsg)); - - switch(time_format) { - case 1: - printf ("%7"PRId64":", m.tme_rel + m.tme_mon); - break; - case 2: - printf ("%+6"PRId64":", m.tme_rel + m.tme_mon - prev_event); - break; - default: - printf ("%4d:", m.tme_rel); - break; - } - for (j = 0; j < m.size && j < sizeof(m.buffer); ++j) { - printf (" %02x", m.buffer[j]); - } - - describe (&m); - printf("\n"); - prev_event = m.tme_rel + m.tme_mon; - } - fflush (stdout); - pthread_cond_wait (&data_ready, &msg_thread_lock); - } - pthread_mutex_unlock (&msg_thread_lock); - - jack_deactivate (client); - jack_client_close (client); - jack_ringbuffer_free (rb); - - return 0; -} diff --git a/tools/monitor_client.c b/tools/monitor_client.c deleted file mode 100644 index b9a2761a..00000000 --- a/tools/monitor_client.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> - -#include <jack/jack.h> - -#define TRUE 1 -#define FALSE 0 - -int -main (int argc, char *argv[]) -{ - jack_client_t *client; - char *my_name = strrchr(argv[0], '/'); - - if (my_name == 0) { - my_name = argv[0]; - } else { - my_name ++; - } - - if (argc != 2) { - fprintf (stderr, "Usage: %s client\n", my_name); - return 1; - } - - if ((client = jack_client_open ("input monitoring", JackNullOption, NULL)) == 0) { - fprintf (stderr, "JACK server not running?\n"); - return 1; - } - - if (jack_port_request_monitor_by_name (client, argv[1], TRUE)) { - fprintf (stderr, "could not enable monitoring for %s\n", argv[1]); - jack_client_close (client); - return 1; - } - -#ifdef WIN32 - Sleep (30*1000); -#else - sleep (30); -#endif - if (jack_port_request_monitor_by_name (client, argv[1], FALSE)) { - fprintf (stderr, "could not disable monitoring for %s\n", argv[1]); - } - jack_client_close (client); - exit (0); -} - diff --git a/tools/netsource.c b/tools/netsource.c deleted file mode 100644 index 665d73fb..00000000 --- a/tools/netsource.c +++ /dev/null @@ -1,802 +0,0 @@ -/* -NetJack Client - -Copyright (C) 2008 Marc-Olivier Barre <marco@marcochapeau.org> -Copyright (C) 2008 Pieter Palmers <pieterpalmers@users.sourceforge.net> -Copyright (C) 2006 Torben Hohn <torbenh@gmx.de> - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -/** @file netsource.c - * - * @brief This client connects a remote slave JACK to a local JACK server assumed to be the master - */ - - -#include <stdio.h> -#include <errno.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <signal.h> - -#if defined(HAVE_CONFIG_H) -#include "config.h" -#endif - -#ifdef WIN32 -#include <winsock2.h> -#define socklen_t int -#include <malloc.h> -#else -#include <netinet/in.h> -#include <netdb.h> -#include <sys/socket.h> -#endif - -/* These two required by FreeBSD. */ -#include <sys/types.h> - -#include <jack/jack.h> - -#include <netjack_packet.h> -#if HAVE_SAMPLERATE -#include <samplerate.h> -#endif - -#if HAVE_CELT -#include <celt/celt.h> -#endif - -#ifndef CUSTOM_MODES -#define CUSTOM_MODES // for opus_custom_decoder_init -#endif - -#if HAVE_OPUS -#include <opus/opus.h> -#include <opus/opus_custom.h> -#endif - -#include <math.h> - -JSList *capture_ports = NULL; -JSList *capture_srcs = NULL; -int capture_channels = 0; -int capture_channels_audio = 2; -int capture_channels_midi = 1; -JSList *playback_ports = NULL; -JSList *playback_srcs = NULL; -int playback_channels = 0; -int playback_channels_audio = 2; -int playback_channels_midi = 1; -int dont_htonl_floats = 0; - -int latency = 5; -jack_nframes_t factor = 1; -int bitdepth = 0; -int mtu = 1400; -int reply_port = 0; -int bind_port = 0; -int redundancy = 1; -jack_client_t *client; -packet_cache * packcache = 0; - -int state_connected = 0; -int state_latency = 0; -int state_netxruns = 0; -int state_currentframe = 0; -int state_recv_packet_queue_time = 0; - -int quit = 0; - - -int outsockfd; -int insockfd; -#ifdef WIN32 -struct sockaddr_in destaddr; -struct sockaddr_in bindaddr; -#else -struct sockaddr destaddr; -struct sockaddr bindaddr; -#endif - -int sync_state; -jack_transport_state_t last_transport_state; - -int framecnt = 0; - -int cont_miss = 0; - -int freewheeling = 0; - -/** - * This Function allocates all the I/O Ports which are added the lists. - */ -void -alloc_ports (int n_capture_audio, int n_playback_audio, int n_capture_midi, int n_playback_midi) -{ - - int port_flags = JackPortIsOutput; - int chn; - jack_port_t *port; - char buf[32]; - - capture_ports = NULL; - /* Allocate audio capture channels */ - for (chn = 0; chn < n_capture_audio; chn++) { - snprintf (buf, sizeof (buf) - 1, "capture_%u", chn + 1); - port = jack_port_register (client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0); - if (!port) { - printf( "jack_netsource: cannot register %s port\n", buf); - break; - } - if (bitdepth == 1000) { -#if HAVE_CELT -#if HAVE_CELT_API_0_11 - CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate( client ), jack_get_buffer_size(client), NULL ); - capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create_custom( celt_mode, 1, NULL ) ); -#elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 - CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate( client ), jack_get_buffer_size(client), NULL ); - capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create( celt_mode, 1, NULL ) ); -#else - CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate( client ), 1, jack_get_buffer_size(client), NULL ); - capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create( celt_mode ) ); -#endif -#endif - } else if (bitdepth == 999) { -#if HAVE_OPUS - int err; - OpusCustomMode *opus_mode = opus_custom_mode_create(jack_get_sample_rate( client ), jack_get_buffer_size(client), &err); - if (err != OPUS_OK) { printf("OPUS MODE FAILED\n"); } - OpusCustomDecoder *decoder = opus_custom_decoder_create(opus_mode, 1, &err); - if (err != OPUS_OK) { printf("OPUS DECODER FAILED\n"); } - opus_custom_decoder_init(decoder, opus_mode, 1); - capture_srcs = jack_slist_append(capture_srcs, decoder); -#endif - } else { -#if HAVE_SAMPLERATE - capture_srcs = jack_slist_append (capture_srcs, src_new (SRC_LINEAR, 1, NULL)); -#endif - } - capture_ports = jack_slist_append (capture_ports, port); - } - - /* Allocate midi capture channels */ - for (chn = n_capture_audio; chn < n_capture_midi + n_capture_audio; chn++) { - snprintf (buf, sizeof (buf) - 1, "capture_%u", chn + 1); - port = jack_port_register (client, buf, JACK_DEFAULT_MIDI_TYPE, port_flags, 0); - if (!port) { - printf ("jack_netsource: cannot register %s port\n", buf); - break; - } - capture_ports = jack_slist_append(capture_ports, port); - } - - /* Allocate audio playback channels */ - port_flags = JackPortIsInput; - playback_ports = NULL; - for (chn = 0; chn < n_playback_audio; chn++) { - snprintf (buf, sizeof (buf) - 1, "playback_%u", chn + 1); - port = jack_port_register (client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0); - if (!port) { - printf ("jack_netsource: cannot register %s port\n", buf); - break; - } - if( bitdepth == 1000 ) { -#if HAVE_CELT -#if HAVE_CELT_API_0_11 - CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate (client), jack_get_buffer_size(client), NULL ); - playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create_custom( celt_mode, 1, NULL ) ); -#elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 - CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate (client), jack_get_buffer_size(client), NULL ); - playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create( celt_mode, 1, NULL ) ); -#else - CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate (client), 1, jack_get_buffer_size(client), NULL ); - playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create( celt_mode ) ); -#endif -#endif - } else if( bitdepth == 999 ) { -#if HAVE_OPUS - const int kbps = factor; - printf("new opus encoder %d kbps\n", kbps); - int err; - OpusCustomMode *opus_mode = opus_custom_mode_create(jack_get_sample_rate (client), jack_get_buffer_size(client), &err ); // XXX free me - if (err != OPUS_OK) { printf("OPUS MODE FAILED\n"); } - OpusCustomEncoder *oe = opus_custom_encoder_create( opus_mode, 1, &err ); - if (err != OPUS_OK) { printf("OPUS ENCODER FAILED\n"); } - opus_custom_encoder_ctl(oe, OPUS_SET_BITRATE(kbps*1024)); // bits per second - opus_custom_encoder_ctl(oe, OPUS_SET_COMPLEXITY(10)); - opus_custom_encoder_ctl(oe, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC)); - opus_custom_encoder_ctl(oe, OPUS_SET_SIGNAL(OPUS_APPLICATION_RESTRICTED_LOWDELAY)); - opus_custom_encoder_init(oe, opus_mode, 1); - playback_srcs = jack_slist_append(playback_srcs, oe); -#endif - } else { -#if HAVE_SAMPLERATE - playback_srcs = jack_slist_append (playback_srcs, src_new (SRC_LINEAR, 1, NULL)); -#endif - } - playback_ports = jack_slist_append (playback_ports, port); - } - - /* Allocate midi playback channels */ - for (chn = n_playback_audio; chn < n_playback_midi + n_playback_audio; chn++) { - snprintf (buf, sizeof (buf) - 1, "playback_%u", chn + 1); - port = jack_port_register (client, buf, JACK_DEFAULT_MIDI_TYPE, port_flags, 0); - if (!port) { - printf ("jack_netsource: cannot register %s port\n", buf); - break; - } - playback_ports = jack_slist_append (playback_ports, port); - } -} - -/** - * The Sync callback... sync state is set elsewhere... - * we will see if this is working correctly. - * i don't really believe in it yet. - */ -int -sync_cb (jack_transport_state_t state, jack_position_t *pos, void *arg) -{ - static int latency_count = 0; - int retval = sync_state; - - if (! state_connected) { - return 1; - } - if (latency_count) { - latency_count--; - retval = 0; - } - - else if (state == JackTransportStarting && last_transport_state != JackTransportStarting) { - retval = 0; - latency_count = latency - 1; - } - - last_transport_state = state; - return retval; -} - -void -freewheel_cb (int starting, void *arg) -{ - freewheeling = starting; -} - -int deadline_goodness = 0; -/** - * The process callback for this JACK application. - * It is called by JACK at the appropriate times. - */ -int -process (jack_nframes_t nframes, void *arg) -{ - jack_nframes_t net_period; - int rx_bufsize, tx_bufsize; - - jack_default_audio_sample_t *buf; - jack_port_t *port; - JSList *node; - int chn; - int size, i; - const char *porttype; - int input_fd; - - jack_position_t local_trans_pos; - - uint32_t *packet_buf_tx, *packet_bufX; - uint32_t *rx_packet_ptr; - jack_time_t packet_recv_timestamp; - - if( bitdepth == 1000 || bitdepth == 999) - net_period = (factor * jack_get_buffer_size(client) * 1024 / jack_get_sample_rate(client) / 8) & (~1) ; - else - net_period = (float) nframes / (float) factor; - - rx_bufsize = get_sample_size (bitdepth) * capture_channels * net_period + sizeof (jacknet_packet_header); - tx_bufsize = get_sample_size (bitdepth) * playback_channels * net_period + sizeof (jacknet_packet_header); - - /* Allocate a buffer where both In and Out Buffer will fit */ - packet_buf_tx = alloca (tx_bufsize); - - jacknet_packet_header *pkthdr_tx = (jacknet_packet_header *) packet_buf_tx; - - /* - * for latency==0 we need to send out the packet before we wait on the reply. - * but this introduces a cycle of latency, when netsource is connected to itself. - * so we send out before read only in zero latency mode. - * - */ - - if( latency == 0 ) { - /* reset packet_bufX... */ - packet_bufX = packet_buf_tx + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t); - - /* ---------- Send ---------- */ - render_jack_ports_to_payload (bitdepth, playback_ports, playback_srcs, nframes, - packet_bufX, net_period, dont_htonl_floats); - - /* fill in packet hdr */ - pkthdr_tx->transport_state = jack_transport_query (client, &local_trans_pos); - pkthdr_tx->transport_frame = local_trans_pos.frame; - pkthdr_tx->framecnt = framecnt; - pkthdr_tx->latency = latency; - pkthdr_tx->reply_port = reply_port; - pkthdr_tx->sample_rate = jack_get_sample_rate (client); - pkthdr_tx->period_size = nframes; - - /* playback for us is capture on the other side */ - pkthdr_tx->capture_channels_audio = playback_channels_audio; - pkthdr_tx->playback_channels_audio = capture_channels_audio; - pkthdr_tx->capture_channels_midi = playback_channels_midi; - pkthdr_tx->playback_channels_midi = capture_channels_midi; - pkthdr_tx->mtu = mtu; - if( freewheeling != 0 ) - pkthdr_tx->sync_state = (jack_nframes_t)MASTER_FREEWHEELS; - else - pkthdr_tx->sync_state = (jack_nframes_t)deadline_goodness; - //printf("goodness=%d\n", deadline_goodness ); - - packet_header_hton (pkthdr_tx); - if (cont_miss < 3 * latency + 5) { - int r; - for( r = 0; r < redundancy; r++ ) - netjack_sendto (outsockfd, (char *) packet_buf_tx, tx_bufsize, 0, &destaddr, sizeof (destaddr), mtu); - } else if (cont_miss > 50 + 5 * latency) { - state_connected = 0; - packet_cache_reset_master_address( packcache ); - //printf ("Frame %d \tRealy too many packets missed (%d). Let's reset the counter\n", framecnt, cont_miss); - cont_miss = 0; - } - } - - /* - * ok... now the RECEIVE code. - * - */ - - - if( reply_port ) - input_fd = insockfd; - else - input_fd = outsockfd; - - // for latency == 0 we can poll. - if( (latency == 0) || (freewheeling != 0) ) { - jack_time_t deadline = jack_get_time() + 1000000 * jack_get_buffer_size(client) / jack_get_sample_rate(client); - // Now loop until we get the right packet. - while(1) { - jack_nframes_t got_frame; - if ( ! netjack_poll_deadline( input_fd, deadline ) ) - break; - - packet_cache_drain_socket(packcache, input_fd); - - if (packet_cache_get_next_available_framecnt( packcache, framecnt - latency, &got_frame )) - if( got_frame == (framecnt - latency) ) - break; - } - } else { - // normally: - // only drain socket. - packet_cache_drain_socket(packcache, input_fd); - } - - size = packet_cache_retreive_packet_pointer( packcache, framecnt - latency, (char**)&rx_packet_ptr, rx_bufsize, &packet_recv_timestamp ); - /* First alternative : we received what we expected. Render the data - * to the JACK ports so it can be played. */ - if (size == rx_bufsize) { - uint32_t *packet_buf_rx = rx_packet_ptr; - jacknet_packet_header *pkthdr_rx = (jacknet_packet_header *) packet_buf_rx; - packet_bufX = packet_buf_rx + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t); - // calculate how much time there would have been, if this packet was sent at the deadline. - - int recv_time_offset = (int) (jack_get_time() - packet_recv_timestamp); - packet_header_ntoh (pkthdr_rx); - deadline_goodness = recv_time_offset - (int)pkthdr_rx->latency; - //printf( "deadline goodness = %d ---> off: %d\n", deadline_goodness, recv_time_offset ); - - if (cont_miss) { - //printf("Frame %d \tRecovered from dropouts\n", framecnt); - cont_miss = 0; - } - render_payload_to_jack_ports (bitdepth, packet_bufX, net_period, - capture_ports, capture_srcs, nframes, dont_htonl_floats); - - state_currentframe = framecnt; - state_recv_packet_queue_time = recv_time_offset; - state_connected = 1; - sync_state = pkthdr_rx->sync_state; - packet_cache_release_packet( packcache, framecnt - latency ); - } - /* Second alternative : we've received something that's not - * as big as expected or we missed a packet. We render silence - * to the output ports */ - else { - jack_nframes_t latency_estimate; - if( packet_cache_find_latency( packcache, framecnt, &latency_estimate ) ) - //if( (state_latency == 0) || (latency_estimate < state_latency) ) - state_latency = latency_estimate; - - // Set the counters up. - state_currentframe = framecnt; - //state_latency = framecnt - pkthdr->framecnt; - state_netxruns += 1; - - //printf ("Frame %d \tPacket missed or incomplete (expected: %d bytes, got: %d bytes)\n", framecnt, rx_bufsize, size); - //printf ("Frame %d \tPacket missed or incomplete\n", framecnt); - cont_miss += 1; - chn = 0; - node = capture_ports; - while (node != NULL) { - port = (jack_port_t *) node->data; - buf = jack_port_get_buffer (port, nframes); - porttype = jack_port_type (port); - if (strncmp (porttype, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size ()) == 0) - for (i = 0; i < nframes; i++) - buf[i] = 0.0; - else if (strncmp (porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size ()) == 0) - jack_midi_clear_buffer (buf); - node = jack_slist_next (node); - chn++; - } - } - if (latency != 0) { - /* reset packet_bufX... */ - packet_bufX = packet_buf_tx + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t); - - /* ---------- Send ---------- */ - render_jack_ports_to_payload (bitdepth, playback_ports, playback_srcs, nframes, - packet_bufX, net_period, dont_htonl_floats); - - /* fill in packet hdr */ - pkthdr_tx->transport_state = jack_transport_query (client, &local_trans_pos); - pkthdr_tx->transport_frame = local_trans_pos.frame; - pkthdr_tx->framecnt = framecnt; - pkthdr_tx->latency = latency; - pkthdr_tx->reply_port = reply_port; - pkthdr_tx->sample_rate = jack_get_sample_rate (client); - pkthdr_tx->period_size = nframes; - - /* playback for us is capture on the other side */ - pkthdr_tx->capture_channels_audio = playback_channels_audio; - pkthdr_tx->playback_channels_audio = capture_channels_audio; - pkthdr_tx->capture_channels_midi = playback_channels_midi; - pkthdr_tx->playback_channels_midi = capture_channels_midi; - pkthdr_tx->mtu = mtu; - if( freewheeling != 0 ) - pkthdr_tx->sync_state = (jack_nframes_t)MASTER_FREEWHEELS; - else - pkthdr_tx->sync_state = (jack_nframes_t)deadline_goodness; - //printf("goodness=%d\n", deadline_goodness ); - - packet_header_hton (pkthdr_tx); - if (cont_miss < 3 * latency + 5) { - int r; - for( r = 0; r < redundancy; r++ ) - netjack_sendto (outsockfd, (char *) packet_buf_tx, tx_bufsize, 0, &destaddr, sizeof (destaddr), mtu); - } else if (cont_miss > 50 + 5 * latency) { - state_connected = 0; - packet_cache_reset_master_address( packcache ); - //printf ("Frame %d \tRealy too many packets missed (%d). Let's reset the counter\n", framecnt, cont_miss); - cont_miss = 0; - } - } - - framecnt++; - return 0; -} - -/** - * This is the shutdown callback for this JACK application. - * It is called by JACK if the server ever shuts down or - * decides to disconnect the client. - */ - -void -jack_shutdown (void *arg) -{ - fprintf(stderr, "JACK shut down, exiting ...\n"); - exit (1); -} - -void -init_sockaddr_in (struct sockaddr_in *name , const char *hostname , uint16_t port) -{ - name->sin_family = AF_INET ; - name->sin_port = htons (port); - if (hostname) { - struct hostent *hostinfo = gethostbyname (hostname); - if (hostinfo == NULL) { - fprintf (stderr, "init_sockaddr_in: unknown host: %s.\n", hostname); - fflush( stderr ); - } -#ifdef WIN32 - name->sin_addr.s_addr = inet_addr( hostname ); -#else - name->sin_addr = *(struct in_addr *) hostinfo->h_addr ; -#endif - } else - name->sin_addr.s_addr = htonl (INADDR_ANY) ; - -} - -void -printUsage () -{ - fprintf (stderr, "usage: jack_netsource [options]\n" - "\n" - " -h this help text\n" - " -H <slave host> - Host name of the slave JACK\n" - " -o <num channels> - Number of audio playback channels\n" - " -i <num channels> - Number of audio capture channels\n" - " -O <num channels> - Number of midi playback channels\n" - " -I <num channels> - Number of midi capture channels\n" - " -n <periods> - Network latency in JACK periods\n" - " -p <port> - UDP port that the slave is listening on\n" - " -r <reply port> - UDP port that we are listening on\n" - " -B <bind port> - reply port, for use in NAT environments\n" - " -b <bitdepth> - Set transport to use 16bit or 8bit\n" - " -c <kbits> - Use CELT encoding with <kbits> kbits per channel\n" - " -P <kbits> - Use Opus encoding with <kbits> kbits per channel\n" - " -m <mtu> - Assume this mtu for the link\n" - " -R <N> - Redundancy: send out packets N times.\n" - " -e - skip host-to-network endianness conversion\n" - " -N <jack name> - Reports a different name to jack\n" - " -s <server name> - The name of the local jack server\n" - "\n"); -} - -void -sigterm_handler( int signal ) -{ - quit = 1; -} - -int -main (int argc, char *argv[]) -{ - /* Some startup related basics */ - char *client_name, *server_name = NULL, *peer_ip; - int peer_port = 3000; - jack_options_t options = JackNullOption; - jack_status_t status; -#ifdef WIN32 - WSADATA wsa; - int rc = WSAStartup(MAKEWORD(2, 0), &wsa); -#endif - /* Torben's famous state variables, aka "the reporting API" ! */ - /* heh ? these are only the copies of them ;) */ - int statecopy_connected, statecopy_latency, statecopy_netxruns; - jack_nframes_t net_period; - /* Argument parsing stuff */ - extern char *optarg; - extern int optind, optopt; - int errflg = 0, c; - - if (argc < 3) { - printUsage (); - return 1; - } - - client_name = (char *) malloc (sizeof (char) * 10); - peer_ip = (char *) malloc (sizeof (char) * 10); - sprintf(client_name, "netjack"); - sprintf(peer_ip, "localhost"); - - while ((c = getopt (argc, argv, ":h:H:o:i:O:I:n:p:r:B:b:c:m:R:e:N:s:P:")) != -1) { - switch (c) { - case 'h': - printUsage(); - exit (0); - break; - case 'H': - free(peer_ip); - peer_ip = (char *) malloc (sizeof (char) * strlen (optarg) + 1); - strcpy (peer_ip, optarg); - break; - case 'o': - playback_channels_audio = atoi (optarg); - break; - case 'i': - capture_channels_audio = atoi (optarg); - break; - case 'O': - playback_channels_midi = atoi (optarg); - break; - case 'I': - capture_channels_midi = atoi (optarg); - break; - case 'n': - latency = atoi (optarg); - break; - case 'p': - peer_port = atoi (optarg); - break; - case 'r': - reply_port = atoi (optarg); - break; - case 'B': - bind_port = atoi (optarg); - break; - case 'f': - factor = atoi (optarg); - printf("This feature is deprecated and will be removed in future netjack versions. CELT offers a superiour way to conserve bandwidth"); - break; - case 'b': - bitdepth = atoi (optarg); - break; - case 'c': -#if HAVE_CELT - bitdepth = 1000; - factor = atoi (optarg); -#else - printf( "not built with celt support\n" ); - exit(10); -#endif - break; - case 'P': -#if HAVE_OPUS - bitdepth = 999; - factor = atoi (optarg); -#else - printf( "not built with opus support\n" ); - exit(10); -#endif - break; - case 'm': - mtu = atoi (optarg); - break; - case 'R': - redundancy = atoi (optarg); - break; - case 'e': - dont_htonl_floats = 1; - break; - case 'N': - free(client_name); - client_name = (char *) malloc (sizeof (char) * strlen (optarg) + 1); - strcpy (client_name, optarg); - break; - case 's': - server_name = (char *) malloc (sizeof (char) * strlen (optarg) + 1); - strcpy (server_name, optarg); - options |= JackServerName; - break; - case ':': - fprintf (stderr, "Option -%c requires an operand\n", optopt); - errflg++; - break; - case '?': - fprintf (stderr, "Unrecognized option: -%c\n", optopt); - errflg++; - } - } - if (errflg) { - printUsage (); - exit (2); - } - - capture_channels = capture_channels_audio + capture_channels_midi; - playback_channels = playback_channels_audio + playback_channels_midi; - - outsockfd = socket (AF_INET, SOCK_DGRAM, 0); - insockfd = socket (AF_INET, SOCK_DGRAM, 0); - - if ((outsockfd == -1) || (insockfd == -1)) { - fprintf (stderr, "can not open sockets\n" ); - return 1; - } - - init_sockaddr_in ((struct sockaddr_in *) &destaddr, peer_ip, peer_port); - if (bind_port) { - init_sockaddr_in ((struct sockaddr_in *) &bindaddr, NULL, bind_port); - if( bind (outsockfd, &bindaddr, sizeof (bindaddr)) ) { - fprintf (stderr, "bind failure\n" ); - } - } - if (reply_port) { - init_sockaddr_in ((struct sockaddr_in *) &bindaddr, NULL, reply_port); - if( bind (insockfd, &bindaddr, sizeof (bindaddr)) ) { - fprintf (stderr, "bind failure\n" ); - } - } - - /* try to become a client of the JACK server */ - client = jack_client_open (client_name, options, &status, server_name); - if (client == NULL) { - fprintf (stderr, "jack_client_open() failed, status = 0x%2.0x\n" - "Is the JACK server running ?\n", status); - return 1; - } - - /* Set up jack callbacks */ - jack_set_process_callback (client, process, 0); - jack_set_sync_callback (client, sync_cb, 0); - jack_set_freewheel_callback (client, freewheel_cb, 0); - jack_on_shutdown (client, jack_shutdown, 0); - - alloc_ports (capture_channels_audio, playback_channels_audio, capture_channels_midi, playback_channels_midi); - - if( bitdepth == 1000 || bitdepth == 999) - net_period = (factor * jack_get_buffer_size(client) * 1024 / jack_get_sample_rate(client) / 8) & (~1) ; - else - net_period = ceilf((float) jack_get_buffer_size (client) / (float) factor); - - int rx_bufsize = get_sample_size (bitdepth) * capture_channels * net_period + sizeof (jacknet_packet_header); - packcache = packet_cache_new (latency + 50, rx_bufsize, mtu); - - /* tell the JACK server that we are ready to roll */ - if (jack_activate (client)) { - fprintf (stderr, "Cannot activate client"); - return 1; - } - - /* Now sleep forever... and evaluate the state_ vars */ - - signal( SIGTERM, sigterm_handler ); - signal( SIGINT, sigterm_handler ); - - statecopy_connected = 2; // make it report unconnected on start. - statecopy_latency = state_latency; - statecopy_netxruns = state_netxruns; - - while ( !quit ) { -#ifdef WIN32 - Sleep (1000); -#else - sleep(1); -#endif - if (statecopy_connected != state_connected) { - statecopy_connected = state_connected; - if (statecopy_connected) { - state_netxruns = 1; // We want to reset the netxrun count on each new connection - printf ("Connected :-)\n"); - } else - printf ("Not Connected\n"); - - fflush(stdout); - } - - if (statecopy_connected) { - if (statecopy_netxruns != state_netxruns) { - statecopy_netxruns = state_netxruns; - printf ("%s: at frame %06d -> total netxruns %d (%d%%) queue time= %d\n", - client_name, - state_currentframe, - statecopy_netxruns, - 100 * statecopy_netxruns / state_currentframe, - state_recv_packet_queue_time); - - fflush(stdout); - } - } else { - if (statecopy_latency != state_latency) { - statecopy_latency = state_latency; - if (statecopy_latency > 1) - printf ("current latency %d\n", statecopy_latency); - fflush(stdout); - } - } - } - - jack_client_close (client); - packet_cache_free (packcache); - exit (0); -} diff --git a/tools/property.c b/tools/property.c deleted file mode 100644 index 4d5e2a22..00000000 --- a/tools/property.c +++ /dev/null @@ -1,326 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <getopt.h> - -#include <jack/jack.h> -#include <jack/metadata.h> -#include <jack/uuid.h> -#include <jack/session.h> - -static int subject_is_client = 0; -static int subject_is_port = 0; -static jack_uuid_t uuid = JACK_UUID_EMPTY_INITIALIZER; -static char* subject = NULL; - -static void -show_usage (void) -{ - fprintf (stderr, "\nUsage: jack_property [options] UUID [ key [ value [ type ] ] ]\n"); - fprintf (stderr, "Set/Display JACK properties (metadata).\n\n"); - fprintf (stderr, "Set options:\n"); - fprintf (stderr, " -s, --set Set property \"key\" to \"value\" for \"UUID\" with optional MIME type \"type\"\n"); - fprintf (stderr, " -d, --delete Remove/delete property \"key\" for \"UUID\"\n"); - fprintf (stderr, " -d, --delete UUID Remove/delete all properties for \"UUID\"\n"); - fprintf (stderr, " -D, --delete-all Remove/delete all properties\n"); - fprintf (stderr, " --client Interpret UUID as a client name, not a UUID\n"); - fprintf (stderr, " --port \tInterpret UUID as a port name, not a UUID\n"); - fprintf (stderr, "\nDisplay options:\n"); - fprintf (stderr, " -l Show all properties\n"); - fprintf (stderr, " -l, --list UUID \tShow value for all properties of UUID\n"); - fprintf (stderr, " -l, --list UUID key Show value for key of UUID\n"); - fprintf (stderr, "\nFor more information see https://jackaudio.org/\n"); -} - -static int -get_subject (jack_client_t* client, char* argv[], int* optind) -{ - if (subject_is_client) { - char* cstr = argv[(*optind)++]; - char* ustr; - - if ((ustr = jack_get_uuid_for_client_name (client, cstr)) == NULL) { - fprintf (stderr, "cannot get UUID for client named %s\n", cstr); - return -1; - } - - if (jack_uuid_parse (ustr, &uuid)) { - fprintf (stderr, "cannot parse client UUID as UUID '%s' '%s'\n", cstr, ustr); - return -1; - } - - subject = cstr; - - } else if (subject_is_port) { - - char* pstr = argv[(*optind)++]; - jack_port_t* port; - - if ((port = jack_port_by_name (client, pstr)) == NULL) { - fprintf (stderr, "cannot find port name %s\n", pstr); - return -1; - } - - uuid = jack_port_uuid (port); - subject = pstr; - - } else { - char* str = argv[(*optind)++]; - - if (jack_uuid_parse (str, &uuid)) { - fprintf (stderr, "cannot parse subject as UUID\n"); - return -1; - } - - subject = str; - } - - return 0; -} - -int main (int argc, char* argv[]) -{ - jack_client_t* client = NULL; - jack_options_t options = JackNoStartServer; - char* key = NULL; - char* value = NULL; - char* type = NULL; - int set = 1; - int delete = 0; - int delete_all = 0; - int c; - int option_index; - extern int optind; - struct option long_options[] = { - { "set", 0, 0, 's' }, - { "delete", 0, 0, 'd' }, - { "delete-all", 0, 0, 'D' }, - { "list", 0, 0, 'l' }, - { "client", 0, 0, 'c' }, - { "port", 0, 0, 'p' }, - { 0, 0, 0, 0 } - }; - - if (argc < 2) { - show_usage (); - exit (1); - } - - while ((c = getopt_long (argc, argv, "sdDlaApc", long_options, &option_index)) >= 0) { - switch (c) { - case 's': - if (argc < 5) { - show_usage (); - exit (1); - } - set = 1; - break; - case 'd': - if (argc < 3) { - show_usage (); - return 1; - } - set = 0; - delete = 1; - break; - - case 'D': - delete = 0; - set = 0; - delete_all = 1; - break; - - case 'l': - set = 0; - delete = 0; - delete_all = 0; - break; - - case 'p': - subject_is_port = 1; - break; - - case 'c': - subject_is_client = 1; - break; - - case '?': - default: - show_usage (); - exit (1); - } - } - - if ((client = jack_client_open ("jack-property", options, NULL)) == 0) { - fprintf (stderr, "Cannot connect to JACK server\n"); - exit (1); - } - - if (delete_all) { - - if (jack_remove_all_properties (client) == 0) { - printf ("JACK metadata successfully delete\n"); - exit (0); - } - exit (1); - } - - if (delete) { - - int args_left = argc - optind; - - if (args_left < 1) { - show_usage (); - exit (1); - } - - /* argc == 3: delete all properties for a subject - argc == 4: delete value of key for subject - */ - - if (args_left >= 2) { - - if (get_subject (client, argv, &optind)) { - return 1; - } - - key = argv[optind++]; - - if (jack_remove_property (client, uuid, key)) { - fprintf (stderr, "\"%s\" property not removed for %s\n", key, subject); - exit (1); - } - - } else { - - if (get_subject (client, argv, &optind)) { - return 1; - } - - if (jack_remove_properties (client, uuid) < 0) { - fprintf (stderr, "cannot remove properties for UUID %s\n", subject); - exit (1); - } - } - - } else if (set) { - - int args_left = argc - optind; - - if (get_subject (client, argv, &optind)) { - return -1; - } - - key = argv[optind++]; - value = argv[optind++]; - - if (args_left >= 3) { - type = argv[optind++]; - } else { - type = ""; - } - - if (jack_set_property (client, uuid, key, value, type)) { - fprintf (stderr, "cannot set value for key %s of %s\n", key, subject); - exit (1); - } - - } else { - - /* list properties */ - - int args_left = argc - optind; - - if (args_left >= 2) { - - /* list properties for a UUID/key pair */ - - if (get_subject (client, argv, &optind)) { - return -1; - } - - key = argv[optind++]; - - if (jack_get_property (uuid, key, &value, &type) == 0) { - printf ("%s\n", value); - free (value); - if (type) { - free (type); - } - } else { - fprintf (stderr, "Value not found for %s of %s\n", key, subject); - exit (1); - } - - } else if (args_left == 1) { - - /* list all properties for a given UUID */ - - jack_description_t description; - int cnt, n; - - if (get_subject (client, argv, &optind)) { - return -1; - } - - if ((cnt = jack_get_properties (uuid, &description)) < 0) { - fprintf (stderr, "could not retrieve properties for %s\n", subject); - exit (1); - } - - for (n = 0; n < cnt; ++n) { - if (description.properties[n].type) { - printf ("key: %s value: %s type: %s\n", - description.properties[n].key, - description.properties[n].data, - description.properties[n].type); - } else { - printf ("key: %s value: %s\n", - description.properties[n].key, - description.properties[n].data); - } - } - - jack_free_description (&description, 0); - - } else { - - /* list all properties */ - - jack_description_t* description; - int cnt, n; - size_t p; - char buf[JACK_UUID_STRING_SIZE]; - - if ((cnt = jack_get_all_properties (&description)) < 0) { - fprintf (stderr, "could not retrieve all properties\n"); - exit (1); - } - - for (n = 0; n < cnt; ++n) { - jack_uuid_unparse (description[n].subject, buf); - printf ("%s\n", buf); - for (p = 0; p < description[n].property_cnt; ++p) { - if (description[n].properties[p].type) { - printf ("key: %s value: %s type: %s\n", - description[n].properties[p].key, - description[n].properties[p].data, - description[n].properties[p].type); - } else { - printf ("key: %s value: %s\n", - description[n].properties[p].key, - description[n].properties[p].data); - } - } - jack_free_description (&description[n], 0); - } - - free (description); - } - } - - - (void) jack_client_close (client); - return 0; -} diff --git a/tools/samplerate.c b/tools/samplerate.c deleted file mode 100644 index 88b5c31a..00000000 --- a/tools/samplerate.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * smaplerate.c -- get current samplerate - * - * Copyright (C) 2003 Jack O'Quin. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <stdio.h> -#include <errno.h> -#include <unistd.h> -#include <signal.h> -#include <stdlib.h> -#include <string.h> -#include <jack/jack.h> -#include <jack/transport.h> - -char *package; /* program name */ -jack_client_t *client; - -void jack_shutdown(void *arg) -{ - fprintf(stderr, "JACK shut down, exiting ...\n"); - exit(1); -} - -void signal_handler(int sig) -{ - jack_client_close(client); - fprintf(stderr, "signal received, exiting ...\n"); - exit(0); -} - -void parse_arguments(int argc, char *argv[]) -{ - - /* basename $0 */ - package = strrchr(argv[0], '/'); - if (package == 0) - package = argv[0]; - else - package++; - - if (argc==1) { - return; - } - fprintf(stderr, "usage: %s\n", package); - exit(9); -} - -int main(int argc, char *argv[]) -{ - parse_arguments(argc, argv); - - /* become a JACK client */ - if ((client = jack_client_open(package, JackNullOption, NULL)) == 0) { - fprintf(stderr, "JACK server not running?\n"); - exit(1); - } - -#ifndef WIN32 - signal(SIGQUIT, signal_handler); - signal(SIGHUP, signal_handler); -#endif - signal(SIGTERM, signal_handler); - signal(SIGINT, signal_handler); - - jack_on_shutdown(client, jack_shutdown, 0); - - fprintf(stdout, "%d\n", jack_get_sample_rate( client ) ); - - jack_client_close(client); - - return 0; -} diff --git a/tools/session_notify.c b/tools/session_notify.c deleted file mode 100644 index 9f96c261..00000000 --- a/tools/session_notify.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * session_notify.c -- ultra minimal session manager - * - * Copyright (C) 2018 Karl Linden <karl.j.linden@gmail.com> - * Copyright (C) 2010 Torben Hohn. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <alloca.h> -#include <stdio.h> -#include <errno.h> -#include <unistd.h> -#include <signal.h> -#include <stdlib.h> -#include <string.h> -#include <jack/jack.h> -#include <jack/jslist.h> -#include <jack/transport.h> -#include <jack/session.h> - -char *package; /* program name */ -jack_client_t *client; - -jack_session_event_type_t notify_type; -char *save_path = NULL; - -void jack_shutdown(void *arg) -{ - fprintf(stderr, "JACK shut down, exiting ...\n"); - exit(1); -} - -void signal_handler(int sig) -{ - jack_client_close(client); - fprintf(stderr, "signal received, exiting ...\n"); - exit(0); -} - -void parse_arguments(int argc, char *argv[]) -{ - - /* basename $0 */ - package = strrchr(argv[0], '/'); - if (package == 0) - package = argv[0]; - else - package++; - - if (argc==2) { - if( !strcmp( argv[1], "quit" ) ) { - notify_type = JackSessionSaveAndQuit; - return; - } - } - if (argc==3) { - if( !strcmp( argv[1], "save" ) ) { - notify_type = JackSessionSave; - save_path = argv[2]; - return; - } - - } - fprintf(stderr, "usage: %s quit|save [path]\n", package); - exit(9); -} - -typedef struct { - char name[32]; - char uuid[16]; -} uuid_map_t; - -JSList *uuid_map = NULL; - -void add_uuid_mapping( const char *uuid ) { - char *clientname = jack_get_client_name_by_uuid( client, uuid ); - if( !clientname ) { - printf( "error... can not find client for uuid" ); - return; - } - - uuid_map_t *mapping = malloc( sizeof(uuid_map_t) ); - snprintf( mapping->uuid, sizeof(mapping->uuid), "%s", uuid ); - snprintf( mapping->name, sizeof(mapping->name), "%s", clientname ); - uuid_map = jack_slist_append( uuid_map, mapping ); -} - -char *map_port_name_to_uuid_port( const char *port_name ) -{ - JSList *node; - char retval[300]; - char *port_component = strchr( port_name,':' ); - char *client_component = strdup( port_name ); - strchr( client_component, ':' )[0] = '\0'; - - sprintf( retval, "%s", port_name ); - - for( node=uuid_map; node; node=jack_slist_next(node) ) { - uuid_map_t *mapping = node->data; - if( !strcmp( mapping->name, client_component ) ) { - sprintf( retval, "%s%s", mapping->uuid, port_component ); - break; - } - } - - return strdup(retval); -} - -int main(int argc, char *argv[]) -{ - parse_arguments(argc, argv); - jack_session_command_t *retval; - int k,i,j; - - - /* become a JACK client */ - if ((client = jack_client_open(package, JackNullOption, NULL)) == 0) { - fprintf(stderr, "JACK server not running?\n"); - exit(1); - } - -#ifndef WIN32 - signal(SIGQUIT, signal_handler); - signal(SIGHUP, signal_handler); -#endif - - signal(SIGTERM, signal_handler); - signal(SIGINT, signal_handler); - - jack_on_shutdown(client, jack_shutdown, 0); - - jack_activate(client); - - - retval = jack_session_notify( client, NULL, notify_type, save_path ); - for (i = 0; retval[i].uuid; i++) { - printf( "export SESSION_DIR=\"%s%s/\"\n", save_path, retval[i].client_name ); - printf( "%s &\n", retval[i].command ); - add_uuid_mapping(retval[i].uuid); - } - - printf( "sleep 10\n" ); - - for (k = 0; retval[k].uuid; k++) { - - char* port_regexp = alloca( jack_client_name_size()+3 ); - char* client_name = jack_get_client_name_by_uuid( client, retval[k].uuid ); - snprintf( port_regexp, jack_client_name_size()+3, "%s:.*", client_name ); - jack_free(client_name); - const char **ports = jack_get_ports( client, port_regexp, NULL, 0 ); - if( !ports ) { - continue; - } - for (i = 0; ports[i]; ++i) { - const char **connections; - if ((connections = jack_port_get_all_connections (client, jack_port_by_name(client, ports[i]))) != 0) { - for (j = 0; connections[j]; j++) { - char *src = map_port_name_to_uuid_port( ports[i] ); - char *dst = map_port_name_to_uuid_port( connections[j] ); - printf( "jack_connect -u \"%s\" \"%s\"\n", src, dst ); - } - jack_free (connections); - } - } - jack_free(ports); - - } - jack_session_commands_free(retval); - - jack_client_close(client); - - return 0; -} diff --git a/tools/transport.c b/tools/transport.c deleted file mode 100644 index ca5692e0..00000000 --- a/tools/transport.c +++ /dev/null @@ -1,508 +0,0 @@ -/* - * transport.c -- JACK transport master example client. - * - * Copyright (C) 2003 Jack O'Quin. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <stdio.h> -#include <errno.h> -#include <unistd.h> -#include <signal.h> -#include <stdlib.h> -#include <string.h> -#if HAVE_READLINE -#include <readline/readline.h> -#include <readline/history.h> -#endif -#include <jack/jack.h> -#include <jack/transport.h> - -/* Use a copy of the readline macro whitespace if it does not exist. - * Not all readline compatible libraries supply the whitespace macro - * (libedit for example), so pull in the copy in those cases too. */ -#if !HAVE_READLINE || !defined(whitespace) -#define whitespace(c) (((c) == ' ') || ((c) == '\t')) -#endif - -char *package; /* program name */ -int done = 0; -jack_client_t *client; - -/* Time and tempo variables. These are global to the entire, - * transport timeline. There is no attempt to keep a true tempo map. - * The default time signature is: "march time", 4/4, 120bpm - */ -float time_beats_per_bar = 4.0; -float time_beat_type = 4.0; -double time_ticks_per_beat = 1920.0; -double time_beats_per_minute = 120.0; -volatile int time_reset = 1; /* true when time values change */ - -/* JACK timebase callback. - * - * Runs in the process thread. Realtime, must not wait. - */ -static void timebase(jack_transport_state_t state, jack_nframes_t nframes, - jack_position_t *pos, int new_pos, void *arg) -{ - double min; /* minutes since frame 0 */ - long abs_tick; /* ticks since frame 0 */ - long abs_beat; /* beats since frame 0 */ - - if (new_pos || time_reset) { - - pos->valid = JackPositionBBT; - pos->beats_per_bar = time_beats_per_bar; - pos->beat_type = time_beat_type; - pos->ticks_per_beat = time_ticks_per_beat; - pos->beats_per_minute = time_beats_per_minute; - - time_reset = 0; /* time change complete */ - - /* Compute BBT info from frame number. This is relatively - * simple here, but would become complex if we supported tempo - * or time signature changes at specific locations in the - * transport timeline. */ - - min = pos->frame / ((double) pos->frame_rate * 60.0); - abs_tick = min * pos->beats_per_minute * pos->ticks_per_beat; - abs_beat = abs_tick / pos->ticks_per_beat; - - pos->bar = abs_beat / pos->beats_per_bar; - pos->beat = abs_beat - (pos->bar * pos->beats_per_bar) + 1; - pos->tick = abs_tick - (abs_beat * pos->ticks_per_beat); - pos->bar_start_tick = pos->bar * pos->beats_per_bar * - pos->ticks_per_beat; - pos->bar++; /* adjust start to bar 1 */ - -#if 0 - /* some debug code... */ - fprintf(stderr, "\nnew position: %" PRIu32 "\tBBT: %3" - PRIi32 "|%" PRIi32 "|%04" PRIi32 "\n", - pos->frame, pos->bar, pos->beat, pos->tick); -#endif - - } else { - - /* Compute BBT info based on previous period. */ - pos->tick += - nframes * pos->ticks_per_beat * pos->beats_per_minute - / (pos->frame_rate * 60); - - while (pos->tick >= pos->ticks_per_beat) { - pos->tick -= pos->ticks_per_beat; - if (++pos->beat > pos->beats_per_bar) { - pos->beat = 1; - ++pos->bar; - pos->bar_start_tick += - pos->beats_per_bar - * pos->ticks_per_beat; - } - } - } -} - -static void jack_shutdown(void *arg) -{ -#if defined(RL_READLINE_VERSION) && RL_READLINE_VERSION >= 0x0400 - rl_cleanup_after_signal(); -#endif - fprintf(stderr, "JACK shut down, exiting ...\n"); - exit(1); -} - -static void signal_handler(int sig) -{ - jack_client_close(client); - fprintf(stderr, "signal received, exiting ...\n"); - exit(0); -} - -/* Command functions: see commands[] table following. */ - -static void com_activate(char *arg) -{ - if (jack_activate(client)) { - fprintf(stderr, "cannot activate client"); - } -} - -static void com_deactivate(char *arg) -{ - if (jack_deactivate(client)) { - fprintf(stderr, "cannot deactivate client"); - } -} - -static void com_exit(char *arg) -{ - done = 1; -} - -static void com_help(char *); /* forward declaration */ - -static void com_locate(char *arg) -{ - jack_nframes_t frame = 0; - - if (*arg != '\0') - frame = atoi(arg); - - jack_transport_locate(client, frame); -} - -static void com_master(char *arg) -{ - int cond = (*arg != '\0'); - if (jack_set_timebase_callback(client, cond, timebase, NULL) != 0) - fprintf(stderr, "Unable to take over timebase.\n"); -} - -static void com_play(char *arg) -{ - jack_transport_start(client); -} - -static void com_release(char *arg) -{ - jack_release_timebase(client); -} - -static void com_stop(char *arg) -{ - jack_transport_stop(client); -} - -/* Change the tempo for the entire timeline, not just from the current - * location. */ -static void com_tempo(char *arg) -{ - float tempo = 120.0; - - if (*arg != '\0') - tempo = atof(arg); - - time_beats_per_minute = tempo; - time_reset = 1; -} - -/* Set sync timeout in seconds. */ -static void com_timeout(char *arg) -{ - double timeout = 2.0; - - if (*arg != '\0') - timeout = atof(arg); - - jack_set_sync_timeout(client, (jack_time_t) (timeout*1000000)); -} - -/* Toggle between play and stop state */ -static void com_toggle(char *arg) -{ - jack_position_t current; - jack_transport_state_t transport_state; - - transport_state = jack_transport_query (client, ¤t); - - switch (transport_state) { - case JackTransportStopped: - com_play( arg ); - break; - case JackTransportRolling: - com_stop( arg ); - break; - case JackTransportStarting: - fprintf(stderr, "state: Starting - no transport toggling"); - break; - default: - fprintf(stderr, "unexpected state: no transport toggling"); - } -} - - -/* Command parsing based on GNU readline info examples. */ - -typedef void cmd_function_t(char *); /* command function type */ - -/* Transport command table. */ -typedef struct { - char *name; /* user printable name */ - cmd_function_t *func; /* function to call */ - char *doc; /* documentation */ -} command_t; - -/* command table must be in alphabetical order */ -command_t commands[] = { - {"activate", com_activate, "Call jack_activate()"}, - {"exit", com_exit, "Exit transport program"}, - {"deactivate", com_deactivate, "Call jack_deactivate()"}, - {"help", com_help, "Display help text [<command>]"}, - {"locate", com_locate, "Locate to frame <position>"}, - {"master", com_master, "Become timebase master " - "[<conditionally>]"}, - {"play", com_play, "Start transport rolling"}, - {"quit", com_exit, "Synonym for `exit'"}, - {"release", com_release, "Release timebase"}, - {"stop", com_stop, "Stop transport"}, - {"tempo", com_tempo, "Set beat tempo <beats_per_min>"}, - {"timeout", com_timeout, "Set sync timeout in <seconds>"}, - {"toggle", com_toggle, "Toggle transport rolling"}, - {"?", com_help, "Synonym for `help'" }, - {(char *)NULL, (cmd_function_t *)NULL, (char *)NULL } -}; - -static command_t *find_command(char *name) -{ - register int i; - size_t namelen; - - if ((name == NULL) || (*name == '\0')) - return ((command_t *)NULL); - - namelen = strlen(name); - for (i = 0; commands[i].name; i++) - if (strncmp(name, commands[i].name, namelen) == 0) { - - /* make sure the match is unique */ - if ((commands[i+1].name) && - (strncmp(name, commands[i+1].name, namelen) == 0)) - return ((command_t *)NULL); - else - return (&commands[i]); - } - - return ((command_t *)NULL); -} - -static void com_help(char *arg) -{ - register int i; - command_t *cmd; - - if (!*arg) { - /* print help for all commands */ - for (i = 0; commands[i].name; i++) { - printf("%s\t\t%s.\n", commands[i].name, - commands[i].doc); - } - - } else if ((cmd = find_command(arg))) { - printf("%s\t\t%s.\n", cmd->name, cmd->doc); - - } else { - int printed = 0; - - printf("No `%s' command. Valid command names are:\n", arg); - - for (i = 0; commands[i].name; i++) { - /* Print in six columns. */ - if (printed == 6) { - printed = 0; - printf ("\n"); - } - - printf ("%s\t", commands[i].name); - printed++; - } - - printf("\n\nTry `help [command]\' for more information.\n"); - } -} - -static void execute_command(char *line) -{ - register int i; - command_t *command; - char *word; - - /* Isolate the command word. */ - i = 0; - while (line[i] && whitespace(line[i])) - i++; - word = line + i; - - while (line[i] && !whitespace(line[i])) - i++; - - if (line[i]) - line[i++] = '\0'; - - command = find_command(word); - - if (!command) { - fprintf(stderr, "%s: No such command. There is `help\'.\n", - word); - return; - } - - /* Get argument to command, if any. */ - while (whitespace(line[i])) - i++; - - word = line + i; - - /* invoke the command function. */ - (*command->func)(word); -} - - -/* Strip whitespace from the start and end of string. */ -static char *stripwhite(char *string) -{ - register char *s, *t; - - s = string; - while (whitespace(*s)) - s++; - - if (*s == '\0') - return s; - - t = s + strlen (s) - 1; - while (t > s && whitespace(*t)) - t--; - *++t = '\0'; - - return s; -} - -static char *dupstr(char *s) -{ - char *r = malloc(strlen(s) + 1); - strcpy(r, s); - return r; -} - -/* Readline generator function for command completion. */ -static char *command_generator (const char *text, int state) -{ - static int list_index, len; - char *name; - - /* If this is a new word to complete, initialize now. This - includes saving the length of TEXT for efficiency, and - initializing the index variable to 0. */ - if (!state) { - list_index = 0; - len = strlen (text); - } - - /* Return the next name which partially matches from the - command list. */ - while ((name = commands[list_index].name)) { - list_index++; - - if (strncmp(name, text, len) == 0) - return dupstr(name); - } - - return (char *) NULL; /* No names matched. */ -} - -static void command_loop() -{ -#if HAVE_READLINE - char *line, *cmd; - char prompt[32]; - - snprintf(prompt, sizeof(prompt), "%s> ", package); - - /* Allow conditional parsing of the ~/.inputrc file. */ - rl_readline_name = package; - - /* Define a custom completion function. */ - rl_completion_entry_function = command_generator; -#else - char line[64] = {0,}; - char *cmd = NULL; -#endif - - /* Read and execute commands until the user quits. */ - while (!done) { - -#if HAVE_READLINE - line = readline(prompt); - - if (line == NULL) { /* EOF? */ - printf("\n"); /* close out prompt */ - done = 1; - break; - } -#else - printf("%s> ", package); - fgets(line, sizeof(line), stdin); - line[strlen(line)-1] = '\0'; -#endif - - /* Remove leading and trailing whitespace from the line. */ - cmd = stripwhite(line); - - /* If anything left, add to history and execute it. */ - if (*cmd) - { -#if HAVE_READLINE - add_history(cmd); -#endif - execute_command(cmd); - } - -#if HAVE_READLINE - free(line); /* realine() called malloc() */ -#endif - } -} - -int main(int argc, char *argv[]) -{ - jack_status_t status; - - /* basename $0 */ - package = strrchr(argv[0], '/'); - if (package == 0) - package = argv[0]; - else - package++; - - /* open a connection to the JACK server */ - client = jack_client_open (package, JackNullOption, &status); - if (client == NULL) { - fprintf (stderr, "jack_client_open() failed, " - "status = 0x%2.0x\n", status); - return 1; - } - -#if !WIN32 - signal(SIGQUIT, signal_handler); - signal(SIGHUP, signal_handler); -#endif - signal(SIGTERM, signal_handler); - signal(SIGINT, signal_handler); - - jack_on_shutdown(client, jack_shutdown, 0); - - if (jack_activate(client)) { - fprintf(stderr, "cannot activate client"); - return 1; - } - - /* execute commands until done */ - command_loop(); - - jack_client_close(client); - exit(0); -} diff --git a/tools/tw.c b/tools/tw.c deleted file mode 100644 index edc7ef31..00000000 --- a/tools/tw.c +++ /dev/null @@ -1,264 +0,0 @@ -/** @file tw.c - * - * @brief This simple client demonstrates the basic features of JACK - * as they would be used by many applications. - */ - -#include <stdio.h> -#include <errno.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <signal.h> - -#include <jack/jack.h> - -jack_port_t *input_port; -jack_port_t *output_port; -jack_client_t *client; - -/* a simple state machine for this client */ -volatile enum { - Init, - Run, - Exit -} client_state = Init; - -static void signal_handler(int sig) -{ - jack_client_close(client); - fprintf(stderr, "signal received, exiting ...\n"); - exit(0); -} - -/** - * The process callback for this JACK application is called in a - * special realtime thread once for each audio cycle. - * - * This client follows a simple rule: when the JACK transport is - * running, copy the input port to the output. When it stops, exit. - */ -static int -_process (jack_nframes_t nframes) -{ - jack_default_audio_sample_t *in, *out; - jack_transport_state_t ts = jack_transport_query(client, NULL); - - if (ts == JackTransportRolling) { - - if (client_state == Init) - client_state = Run; - - in = jack_port_get_buffer (input_port, nframes); - out = jack_port_get_buffer (output_port, nframes); - memcpy (out, in, - sizeof (jack_default_audio_sample_t) * nframes); - - } else if (ts == JackTransportStopped) { - - if (client_state == Run) { - client_state = Exit; - return -1; // to stop the thread - } - } - - return 0; -} - -static void* jack_thread(void *arg) -{ - jack_client_t* client = (jack_client_t*) arg; - - while (1) { - - jack_nframes_t frames = jack_cycle_wait (client); - int status = _process(frames); - jack_cycle_signal (client, status); - - /* - Possibly do something else after signaling next clients in the graph - */ - - /* End condition */ - if (status != 0) - return 0; - } - - /* not reached*/ - return 0; -} - -/* -static void* jack_thread(void *arg) -{ - jack_client_t* client = (jack_client_t*) arg; - - while (1) { - jack_nframes_t frames; - int status; - // cycle 1 - frames = jack_cycle_wait (client); - status = _process(frames); - jack_cycle_signal (client, status); - // cycle 2 - frames = jack_cycle_wait (client); - status = _process(frames); - jack_cycle_signal (client, status); - // cycle 3 - frames = jack_cycle_wait (client); - status = _process(frames); - jack_cycle_signal (client, status); - // cycle 4 - frames = jack_cycle_wait (client); - status = _process(frames); - jack_cycle_signal (client, status); - } - - return 0; -} -*/ - -/** - * JACK calls this shutdown_callback if the server ever shuts down or - * decides to disconnect the client. - */ -static void -jack_shutdown (void *arg) -{ - fprintf(stderr, "JACK shut down, exiting ...\n"); - exit (1); -} - -int -main (int argc, char *argv[]) -{ - const char **ports; - const char *client_name; - const char *server_name = NULL; - jack_options_t options = JackNullOption; - jack_status_t status; - - if (argc >= 2) { /* client name specified? */ - client_name = argv[1]; - if (argc >= 3) { /* server name specified? */ - server_name = argv[2]; - options |= JackServerName; - } - } else { /* use basename of argv[0] */ - client_name = strrchr(argv[0], '/'); - if (client_name == 0) { - client_name = argv[0]; - } else { - client_name++; - } - } - - /* open a client connection to the JACK server */ - - client = jack_client_open (client_name, options, &status, server_name); - if (client == NULL) { - fprintf (stderr, "jack_client_open() failed, " - "status = 0x%2.0x\n", status); - if (status & JackServerFailed) { - fprintf (stderr, "Unable to connect to JACK server\n"); - } - exit (1); - } - if (status & JackServerStarted) { - fprintf (stderr, "JACK server started\n"); - } - if (status & JackNameNotUnique) { - client_name = jack_get_client_name(client); - fprintf (stderr, "unique name `%s' assigned\n", client_name); - } - - /* tell the JACK server to call `process()' whenever - there is work to be done. - */ - if (jack_set_process_thread(client, jack_thread, client) < 0) - exit(1); - - /* tell the JACK server to call `jack_shutdown()' if - it ever shuts down, either entirely, or if it - just decides to stop calling us. - */ - - jack_on_shutdown (client, jack_shutdown, 0); - - /* display the current sample rate. - */ - - printf ("engine sample rate: %" PRIu32 "\n", - jack_get_sample_rate (client)); - - /* create two ports */ - - input_port = jack_port_register (client, "input", - JACK_DEFAULT_AUDIO_TYPE, - JackPortIsInput, 0); - output_port = jack_port_register (client, "output", - JACK_DEFAULT_AUDIO_TYPE, - JackPortIsOutput, 0); - - if ((input_port == NULL) || (output_port == NULL)) { - fprintf(stderr, "no more JACK ports available\n"); - exit (1); - } - - /* Tell the JACK server that we are ready to roll. Our - * process() callback will start running now. */ - - if (jack_activate (client)) { - fprintf (stderr, "cannot activate client"); - exit (1); - } - - /* Connect the ports. You can't do this before the client is - * activated, because we can't make connections to clients - * that aren't running. Note the confusing (but necessary) - * orientation of the driver backend ports: playback ports are - * "input" to the backend, and capture ports are "output" from - * it. - */ - - ports = jack_get_ports (client, NULL, NULL, - JackPortIsPhysical|JackPortIsOutput); - if (ports == NULL) { - fprintf(stderr, "no physical capture ports\n"); - exit (1); - } - - if (jack_connect (client, ports[0], jack_port_name (input_port))) { - fprintf (stderr, "cannot connect input ports\n"); - } - - jack_free (ports); - - ports = jack_get_ports (client, NULL, NULL, - JackPortIsPhysical|JackPortIsInput); - if (ports == NULL) { - fprintf(stderr, "no physical playback ports\n"); - exit (1); - } - - if (jack_connect (client, jack_port_name (output_port), ports[0])) { - fprintf (stderr, "cannot connect output ports\n"); - } - - jack_free (ports); - - /* install a signal handler to properly quits jack client */ - signal(SIGQUIT, signal_handler); - signal(SIGTERM, signal_handler); - signal(SIGHUP, signal_handler); - signal(SIGINT, signal_handler); - - /* keep running until the transport stops */ - - while (client_state != Exit) { - sleep (1); - } - - jack_client_close (client); - exit (0); -} diff --git a/tools/wait.c b/tools/wait.c deleted file mode 100644 index 6e56cae9..00000000 --- a/tools/wait.c +++ /dev/null @@ -1,152 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <getopt.h> - -#include <time.h> - -#include <jack/jack.h> - -char * my_name; - -void -show_usage(void) -{ - fprintf(stderr, "\nUsage: %s [options]\n", my_name); - fprintf(stderr, "Check for jack existence, or wait, until it either quits, or gets started\n"); - fprintf(stderr, "options:\n"); - fprintf(stderr, " -s, --server <name> Connect to the jack server named <name>\n"); - fprintf(stderr, " -n, --name <name> Set client name to <name>\n"); - fprintf(stderr, " -w, --wait Wait for server to become available\n"); - fprintf(stderr, " -q, --quit Wait until server is quit\n"); - fprintf(stderr, " -c, --check Check whether server is running\n"); - fprintf(stderr, " -t, --timeout Wait timeout in seconds\n"); - fprintf(stderr, " -h, --help Display this help message\n"); - fprintf(stderr, "For more information see http://jackaudio.org/\n"); -} - -int -main(int argc, char *argv[]) -{ - jack_client_t *client; - jack_status_t status; - jack_options_t options = JackNoStartServer; - int c; - int option_index; - char *server_name = NULL; - char *client_name = NULL; - int wait_for_start = 0; - int wait_for_quit = 0; - int just_check = 0; - int wait_timeout = 0; - time_t start_timestamp; - - - struct option long_options[] = { - { "server", 1, 0, 's' }, - { "wait", 0, 0, 'w' }, - { "name", 1, 0, 'n'}, - { "quit", 0, 0, 'q' }, - { "check", 0, 0, 'c' }, - { "timeout", 1, 0, 't' }, - { "help", 0, 0, 'h' }, - { 0, 0, 0, 0 } - }; - - my_name = strrchr(argv[0], '/'); - if (my_name == 0) { - my_name = argv[0]; - } else { - my_name ++; - } - - while ((c = getopt_long (argc, argv, "s:n:wqct:hv", long_options, &option_index)) >= 0) { - switch (c) { - case 's': - server_name = (char *) malloc (sizeof (char) * (strlen(optarg) + 1)); - strcpy (server_name, optarg); - options |= JackServerName; - break; - case 'n': - client_name = (char *) malloc (sizeof (char) * (strlen(optarg) + 1)); - strcpy (client_name, optarg); - break; - case 'w': - wait_for_start = 1; - break; - case 'q': - wait_for_quit = 1; - break; - case 'c': - just_check = 1; - break; - case 't': - wait_timeout = atoi(optarg); - break; - case 'h': - show_usage(); - return 1; - break; - default: - show_usage(); - return 1; - break; - } - } - - /* try to open server in a loop. breaking under certein conditions */ - - start_timestamp = time(NULL); - - while (1) { - if (client_name) { - client = jack_client_open (client_name, options, &status, server_name); - } - else { - client = jack_client_open ("wait", options, &status, server_name); - } - /* check for some real error and bail out */ - if ((client == NULL) && !(status & JackServerFailed)) { - fprintf (stderr, "jack_client_open() failed, " - "status = 0x%2.0x\n", status); - return 1; - } - - if (client == NULL) { - if (wait_for_quit) { - fprintf(stdout, "server is gone\n"); - break; - } - if (just_check) { - fprintf(stdout, "not running\n"); - break; - } - } else { - jack_client_close(client); - if (wait_for_start) { - fprintf(stdout, "server is available\n"); - break; - } - if (just_check) { - fprintf(stdout, "running\n"); - break; - } - } - if (wait_timeout) { - if ((time(NULL) - start_timestamp) > wait_timeout) { - fprintf(stdout, "timeout\n"); - exit(EXIT_FAILURE); - } - } - - // Wait a second, and repeat -#ifdef WIN32 - Sleep(1*1000); -#else - sleep(1); -#endif - } - - exit(0); -} diff --git a/tools/wscript b/tools/wscript deleted file mode 100644 index 00f9aa43..00000000 --- a/tools/wscript +++ /dev/null @@ -1,130 +0,0 @@ -#! /usr/bin/python3 -# encoding: utf-8 - -example_tools = { - 'jack_alias': 'alias.c', - 'jack_bufsize': 'bufsize.c', - 'jack_connect': 'connect.c', - 'jack_evmon': 'evmon.c', - 'jack_freewheel': 'freewheel.c', - 'jack_load': 'ipload.c', - 'jack_lsp': 'lsp.c', - 'jack_midi_dump': 'midi_dump.c', - 'jack_monitor_client': 'monitor_client.c', - 'jack_property': 'property.c', - 'jack_samplerate': 'samplerate.c', - 'jack_session_notify': 'session_notify.c', - 'jack_unload': 'ipunload.c', - 'jack_wait': 'wait.c', - } - - -def configure(conf): - conf.env['BUILD_TOOL_ALSA_IO'] = conf.env['SAMPLERATE'] and conf.env['BUILD_DRIVER_ALSA'] - conf.env['BUILD_TOOL_CLIENT_TRANSPORT'] = conf.env['READLINE'] - conf.env['BUILD_TOOL_CLIENT_NETSOURCE'] = conf.env['CELT'] or conf.env['OPUS'] - conf.env['BUILD_TOOL_ZALSA'] = conf.env['ZALSA'] - - -def build(bld): - if bld.env['IS_LINUX']: - os_incdir = ['../linux', '../posix'] - if bld.env['IS_MACOSX']: - os_incdir = ['../macosx', '../posix'] - if bld.env['IS_FREEBSD']: - os_incdir = ['../freebsd', '../posix'] - if bld.env['IS_SUN']: - os_incdir = ['../solaris', '../posix'] - if bld.env['IS_WINDOWS']: - os_incdir = ['../windows'] - for example_tool, example_tool_source in list(example_tools.items()): - if bld.env['IS_MACOSX']: - prog = bld(features='c cprogram', framework=['Foundation']) - else: - prog = bld(features='c cprogram') - prog.includes = os_incdir + ['../common/jack', '../common'] - prog.source = example_tool_source - prog.use = ['clientlib'] - if bld.env['IS_LINUX']: - prog.use += ['RT', 'M'] - if bld.env['IS_SUN']: - prog.use += ['M'] - if bld.env['IS_WINDOWS'] and bld.env['BUILD_STATIC']: - prog.env['LIB_PTHREAD'] = [':libwinpthread.a'] - # prog.cflags = ['-Wno-deprecated-declarations', '-Wno-misleading-indentation'] - # prog.cxxflags = ['-Wno-deprecated-declarations', '-Wno-misleading-indentation'] - - prog.target = example_tool - - if bld.env['BUILD_TOOL_CLIENT_TRANSPORT']: - prog = bld(features='c cprogram') - prog.includes = os_incdir + ['../common/jack', '../common'] - prog.source = 'transport.c' - prog.use = ['clientlib'] - if bld.env['IS_LINUX']: - prog.use += ['RT', 'READLINE'] - if bld.env['IS_MACOSX']: - prog.use += ['READLINE'] - if bld.env['IS_WINDOWS']: - prog.use += ['READLINE'] - if bld.env['BUILD_STATIC']: - prog.env['LIB_PTHREAD'] = [':libwinpthread.a'] - prog.target = 'jack_transport' - - if bld.env['BUILD_TOOL_CLIENT_NETSOURCE']: - prog = bld(features='c cprogram') - prog.includes = os_incdir + ['.', '..', '../common/jack', '../common'] - prog.source = ['netsource.c', '../common/netjack_packet.c'] - prog.env.append_value('CFLAGS', '-DNO_JACK_ERROR') - prog.use = ['CELT', 'SAMPLERATE', 'OPUS', 'M', 'clientlib'] - prog.target = 'jack_netsource' - prog.defines = ['HAVE_CONFIG_H'] - - if bld.env['IS_LINUX'] and bld.env['BUILD_TOOL_ALSA_IO']: - prog = bld(features='c cprogram') - prog.includes = os_incdir + ['../common/jack', '../common'] - prog.source = ['alsa_in.c', '../common/memops.c'] - prog.env.append_value('CFLAGS', '-DNO_JACK_ERROR') - prog.use = ['clientlib', 'ALSA', 'SAMPLERATE', 'M'] - prog.target = 'alsa_in' - - prog = bld(features='c cprogram') - prog.includes = os_incdir + ['../common/jack', '../common'] - prog.source = ['alsa_out.c', '../common/memops.c'] - prog.env.append_value('CFLAGS', '-DNO_JACK_ERROR') - prog.use = ['clientlib', 'ALSA', 'SAMPLERATE', 'M'] - prog.target = 'alsa_out' - - if bld.env['IS_LINUX'] and bld.env['BUILD_TOOL_ZALSA']: - prog = bld(features=['cxx', 'cxxshlib']) - prog.defines = ['HAVE_CONFIG_H', 'SERVER_SIDE', 'APPNAME="zalsa_in"', 'VERSION="0.4.0"'] - prog.install_path = '${ADDON_DIR}/' - prog.includes = os_incdir + ['../common/jack', '../common', 'zalsa'] - prog.source = [ - 'zalsa/zita-a2j.cc', - 'zalsa/alsathread.cc', - 'zalsa/jackclient.cc', - 'zalsa/pxthread.cc', - 'zalsa/lfqueue.cc', - ] - prog.target = 'zalsa_in' - prog.use = ['ZITA-ALSA-PCMI', 'ZITA-RESAMPLER', 'ALSA', 'M', 'RT', 'serverlib'] - prog.env['cxxshlib_PATTERN'] = '%s.so' - - prog = bld(features=['cxx', 'cxxshlib']) - prog.defines = ['HAVE_CONFIG_H', 'SERVER_SIDE', 'APPNAME="zalsa_out"', 'VERSION="0.4.0"'] - prog.install_path = '${ADDON_DIR}/' - prog.includes = os_incdir + ['../common/jack', '../common', 'zalsa'] - prog.source = [ - 'zalsa/zita-j2a.cc', - 'zalsa/alsathread.cc', - 'zalsa/jackclient.cc', - 'zalsa/pxthread.cc', - 'zalsa/lfqueue.cc', - ] - prog.target = 'zalsa_out' - prog.use = ['ZITA-ALSA-PCMI', 'ZITA-RESAMPLER', 'ALSA', 'M', 'RT', 'serverlib'] - prog.env['cxxshlib_PATTERN'] = '%s.so' - - if not bld.env['IS_WINDOWS']: - bld.symlink_as('${PREFIX}/bin/jack_disconnect', 'jack_connect') diff --git a/tools/zalsa/alsathread.cc b/tools/zalsa/alsathread.cc deleted file mode 100644 index bb5cf75b..00000000 --- a/tools/zalsa/alsathread.cc +++ /dev/null @@ -1,226 +0,0 @@ -// ---------------------------------------------------------------------------- -// -// Copyright (C) 2012-2018 Fons Adriaensen <fons@linuxaudio.org> -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. -// -// ---------------------------------------------------------------------------- - - -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -#include <math.h> -#include "alsathread.h" -#include "timers.h" - - -Alsathread::Alsathread (Alsa_pcmi *alsadev, int mode) : - _alsadev (alsadev ), - _mode (mode), - _state (INIT), - _fsize (alsadev->fsize ()), - _audioq (0), - _commq (0), - _alsaq (0) -{ - // Compute DLL filter coefficients. - _dt = (double) _fsize / _alsadev->fsamp (); - _w1 = 2 * M_PI * 0.1 * _dt; - _w2 = _w1 * _w1; - _w1 *= 1.6; -} - - -Alsathread::~Alsathread (void) -{ - if (_state != INIT) - { - _state = TERM; - thr_wait (); - } - else - { - _alsadev->pcm_stop (); - } -} - - -int Alsathread::start (Lfq_audio *audioq, Lfq_int32 *commq, Lfq_adata *alsaq, int rtprio) -{ - // Start the ALSA thread. - _audioq = audioq; - _commq = commq; - _alsaq = alsaq; - _state = WAIT; - if (thr_start (SCHED_FIFO, rtprio, 0x10000)) return 1; - return 0; -} - - -void Alsathread::send (int k, double t) -{ - Adata *D; - - // Send (state, frame count, timestamp) to Jack thread. - if (_alsaq->wr_avail ()) - { - D = _alsaq->wr_datap (); - D->_state = _state; - D->_nsamp = k; - D->_timer = t; - _alsaq->wr_commit (); - } -} - - -// The following two functions transfer data between the audio queue -// and the ALSA device. Note that we do *not* check the queue's fill -// state, and it may overrun or underrun. It actually will in the first -// few iterations and in error conditions. This is entirely intentional. -// The queue keeps correct read and write counters even in that case, -// and the main control loop and error recovery depend on it working -// and being used in this way. - -int Alsathread::capture (void) -{ - int c, n, k; - float *p; - - // Start reading from ALSA device. - _alsadev->capt_init (_fsize); - if (_state == PROC) - { - // Input frames from the ALSA device to the audio queue. - // The outer loop takes care of wraparound. - for (n = _fsize; n; n -= k) - { - p = _audioq->wr_datap (); // Audio queue write pointer. - k = _audioq->wr_linav (); // Number of frames that can be - if (k > n) k = n; // written without wraparound. - for (c = 0; c < _audioq->nchan (); c++) - { - // Copy and interleave one channel. - _alsadev->capt_chan (c, p + c, k, _audioq->nchan ()); - } - _audioq->wr_commit (k); // Update audio queue state. - } - } - // Finish reading from ALSA device. - _alsadev->capt_done (_fsize); - return _fsize; -} - - -int Alsathread::playback (void) -{ - int c, n, k; - float *p; - - // Start writing to ALSA device. - _alsadev->play_init (_fsize); - c = 0; - if (_state == PROC) - { - // Output frames from the audio queue to the ALSA device. - // The outer loop takes care of wraparound. - for (n = _fsize; n; n -= k) - { - p = _audioq->rd_datap (); // Audio queue read pointer. - k = _audioq->rd_linav (); // Number of frames that can - if (k > n) k = n; // be read without wraparound. - for (c = 0; c < _audioq->nchan (); c++) - { - // De-interleave and copy one channel. - _alsadev->play_chan (c, p + c, k, _audioq->nchan ()); - } - _audioq->rd_commit (k); // Update audio queue state. - } - } - // Clear all or remaining channels. - while (c < _alsadev->nplay ()) _alsadev->clear_chan (c++, _fsize); - // Finish writing to ALSA device. - _alsadev->play_done (_fsize); - return _fsize; -} - - -void Alsathread::thr_main (void) -{ - int na, nu; - double tw, er; - - _alsadev->pcm_start (); - while (_state != TERM) - { - // Wait for next cycle, then take timestamp. - na = _alsadev->pcm_wait (); - - tw = tjack (jack_get_time ()); - // Check for errors - requires restart. - if (_alsadev->state () && (na == 0)) - { - _state = WAIT; - send (0, 0); - usleep (10000); - continue; - } - - // Check for commands from the Jack thread. - if (_commq->rd_avail ()) - { - _state = _commq->rd_int32 (); - if (_state == PROC) _first = true; - if (_state == TERM) send (0, 0); - } - - // We could have more than one period. - nu = 0; - while (na >= _fsize) - { - // Transfer frames. - if (_mode == PLAY) nu += playback (); - else nu += capture (); - // Update loop condition. - na -= _fsize; - // Run the DLL if in PROC state. - if (_state == PROC) - { - if (_first) - { - // Init DLL in first iteration. - _first = false; - _dt = (double) _fsize / _alsadev->fsamp (); - _t0 = tw; - _t1 = tw + _dt; - } - else - { - // Update the DLL. - // If we have more than one period, use - // the time error only for the last one. - if (na >= _fsize) er = 0; - else er = tjack_diff (tw, _t1); - _t0 = _t1; - _t1 = tjack_diff (_t1 + _dt + _w1 * er, 0.0); - _dt += _w2 * er; - } - } - } - - // Send number of frames used and timestamp to Jack thread. - if (_state == PROC) send (nu, _t1); - } - _alsadev->pcm_stop (); -} diff --git a/tools/zalsa/alsathread.h b/tools/zalsa/alsathread.h deleted file mode 100644 index f9cb761c..00000000 --- a/tools/zalsa/alsathread.h +++ /dev/null @@ -1,68 +0,0 @@ -// ---------------------------------------------------------------------------- -// -// Copyright (C) 2012-2018 Fons Adriaensen <fons@linuxaudio.org> -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. -// -// ---------------------------------------------------------------------------- - - -#ifndef __ALSATHREAD_H -#define __ALSATHREAD_H - - -#include <zita-alsa-pcmi.h> -#include "jack/jack.h" -#include "pxthread.h" -#include "lfqueue.h" - - -class Alsathread : public Pxthread -{ -public: - - enum { INIT, WAIT, PROC, TERM }; - enum { PLAY, CAPT }; - - Alsathread (Alsa_pcmi *alsadev, int mode); - virtual ~Alsathread (void); - virtual void thr_main (void); - - int start (Lfq_audio *audioq, Lfq_int32 *commq, Lfq_adata *alsaq, int rtprio); - -private: - - void send (int k, double t); - int capture (void); - int playback (void); - - Alsa_pcmi *_alsadev; - int _mode; - int _state; - int _nfail; - int _fsize; - Lfq_audio *_audioq; - Lfq_int32 *_commq; - Lfq_adata *_alsaq; - bool _first; -// double _jtmod; - double _t0; - double _t1; - double _dt; - double _w1; - double _w2; -}; - - -#endif diff --git a/tools/zalsa/jackclient.cc b/tools/zalsa/jackclient.cc deleted file mode 100644 index 095b2632..00000000 --- a/tools/zalsa/jackclient.cc +++ /dev/null @@ -1,549 +0,0 @@ -// ---------------------------------------------------------------------------- -// -// Copyright (C) 2012-2018 Fons Adriaensen <fons@linuxaudio.org> -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. -// -// ---------------------------------------------------------------------------- - - -#include <stdio.h> -#include <math.h> -#include "jackclient.h" -#include "alsathread.h" -#include "timers.h" - - -Jackclient::Jackclient (jack_client_t* cl, const char *jserv, int mode, int nchan, bool sync, void *arg) : - _client (cl), - _arg (arg), - _mode (mode), - _nchan (nchan), - _state (INIT), - _freew (false), - _resamp (0) -{ - init (jserv); - if (!sync) _resamp = new VResampler (); -} - - -Jackclient::~Jackclient (void) -{ - fini (); -} - - -bool Jackclient::init (const char *jserv) -{ - int i, spol, flags; - char s [64]; - struct sched_param spar; - - if (_client == 0) - { - fprintf (stderr, "Can't connect to Jack, is the server running ?\n"); - return false; - } - jack_set_process_callback (_client, jack_static_process, (void *) this); - jack_set_latency_callback (_client, jack_static_latency, (void *) this); - jack_set_freewheel_callback (_client, jack_static_freewheel, (void *) this); - jack_set_buffer_size_callback (_client, jack_static_buffsize, (void *) this); - jack_on_shutdown (_client, jack_static_shutdown, (void *) this); - - _bsize = 0; - _fsamp = 0; - if (jack_activate (_client)) - { - fprintf(stderr, "Can't activate Jack"); - return false; - } - _jname = jack_get_client_name (_client); - _bsize = jack_get_buffer_size (_client); - _fsamp = jack_get_sample_rate (_client); - - flags = JackPortIsTerminal | JackPortIsPhysical; - for (i = 0; i < _nchan; i++) - { - if (_mode == PLAY) - { - sprintf (s, "playback_%d", i + 1); - _ports [i] = jack_port_register (_client, s, JACK_DEFAULT_AUDIO_TYPE, - flags | JackPortIsInput, 0); - } - else - { - sprintf (s, "capture_%d", i + 1); - _ports [i] = jack_port_register (_client, s, JACK_DEFAULT_AUDIO_TYPE, - flags | JackPortIsOutput, 0); - } - } - pthread_getschedparam (jack_client_thread_id (_client), &spol, &spar); - _rprio = spar.sched_priority - sched_get_priority_max (spol); - _buff = new float [_bsize * _nchan]; - return true; -} - - -void Jackclient::fini (void) -{ - delete[] _buff; - delete _resamp; -} - - -void Jackclient::jack_static_shutdown (void *arg) -{ - ((Jackclient *) arg)->sendinfo (TERM, 0, 0); -} - - -int Jackclient::jack_static_buffsize (jack_nframes_t nframes, void *arg) -{ - Jackclient *J = (Jackclient *) arg; - - if (J->_bsize == 0) J->_bsize = nframes; - else if (J->_bsize != (int) nframes) J->_state = Jackclient::TERM; - return 0; -} - - -void Jackclient::jack_static_freewheel (int state, void *arg) -{ - ((Jackclient *) arg)->jack_freewheel (state); -} - - -void Jackclient::jack_static_latency (jack_latency_callback_mode_t jlcm, void *arg) -{ - ((Jackclient *) arg)->jack_latency (jlcm); -} - - -int Jackclient::jack_static_process (jack_nframes_t nframes, void *arg) -{ - return ((Jackclient *) arg)->jack_process (nframes); -} - - -void Jackclient::start (Lfq_audio *audioq, - Lfq_int32 *commq, - Lfq_adata *alsaq, - Lfq_jdata *infoq, - double ratio, - int delay, - int ltcor, - int rqual) -{ - double d; - - _audioq = audioq; - _commq = commq; - _alsaq = alsaq; - _infoq = infoq; - _ratio = ratio; - _delay = delay; - _rcorr = 1.0; - if (_resamp) - { - _resamp->setup (_ratio, _nchan, rqual); - _resamp->set_rrfilt (100); - d = _resamp->inpsize () / 2.0; - if (_mode == PLAY) d *= _ratio; - _delay += d; - } - _ltcor = ltcor; - _ppsec = (_fsamp + _bsize / 2) / _bsize; - initwait (_ppsec / 2); - jack_recompute_total_latencies (_client); -} - - -void Jackclient::initwait (int nwait) -{ - _count = -nwait; - _commq->wr_int32 (Alsathread::WAIT); - _state = WAIT; - if (nwait > _ppsec) sendinfo (WAIT, 0, 0); -} - - -void Jackclient::initsync (void) -{ - // Reset all lock-free queues. - _commq->reset (); - _alsaq->reset (); - _audioq->reset (); - if (_resamp) - { - // Reset and prefill the resampler. - _resamp->reset (); - _resamp->inp_count = _resamp->inpsize () / 2 - 1; - _resamp->out_count = 99999; - _resamp->process (); - } - // Initialise state variables. - _t_a0 = _t_a1 = 0; - _k_a0 = _k_a1 = 0; - // Initialise loop filter state. - _z1 = _z2 = _z3 = 0; - // Activate the ALSA thread, - _commq->wr_int32 (Alsathread::PROC); - _state = SYNC0; - sendinfo (SYNC0, 0, 0); -} - - -void Jackclient::setloop (double bw) -{ - double w; - - // Set the loop bandwidth to bw Hz. - w = 6.28 * bw * _bsize / _fsamp; - _w0 = 1.0 - exp (-20.0 * w); - _w1 = w * 2 / _bsize; - _w2 = w / 2; - if (_mode == PLAY) _w1 /= _ratio; - else _w1 *= _ratio; -} - - -void Jackclient::playback (int nframes) -{ - int i, j, n; - float *p, *q; - float *inp [MAXCHAN]; - - _bstat = _audioq->rd_avail (); - for (i = 0; i < _nchan; i++) - { - inp [i] = (float *)(jack_port_get_buffer (_ports [i], nframes)); - } - if (_resamp) - { - // Interleave inputs into _buff. - for (i = 0; i < _nchan; i++) - { - p = inp [i]; - q = _buff + i; - for (j = 0; j < _bsize; j++) q [j * _nchan] = p [j]; - } - // Resample _buff and write to audio queue. - // The while loop takes care of wraparound. - _resamp->inp_count = _bsize; - _resamp->inp_data = _buff; - while (_resamp->inp_count) - { - _resamp->out_count = _audioq->wr_linav (); - _resamp->out_data = _audioq->wr_datap (); - n = _resamp->out_count; - _resamp->process (); - n -= _resamp->out_count; - _audioq->wr_commit (n); - } - } - else - { - // Interleave inputs into audio queue. - // The while loop takes care of wraparound. - while (nframes) - { - q = _audioq->wr_datap (); - n = _audioq->wr_linav (); - if (n > nframes) n = nframes; - for (i = 0; i < _nchan; i++) - { - p = inp [i]; - for (j = 0; j < n; j++) q [j * _nchan] = p [j]; - inp [i] += n; - q += 1; - } - _audioq->wr_commit (n); - nframes -= n; - } - } -} - - -void Jackclient::capture (int nframes) -{ - int i, j, n; - float *p, *q; - float *out [MAXCHAN]; - - for (i = 0; i < _nchan; i++) - { - out [i] = (float *)(jack_port_get_buffer (_ports [i], nframes)); - } - if (_resamp) - { - // Read from audio queue and resample. - // The while loop takes care of wraparound. - _resamp->out_count = _bsize; - _resamp->out_data = _buff; - while (_resamp->out_count) - { - _resamp->inp_count = _audioq->rd_linav (); - _resamp->inp_data = _audioq->rd_datap (); - n = _resamp->inp_count; - _resamp->process (); - n -= _resamp->inp_count; - _audioq->rd_commit (n); - } - // Deinterleave _buff to outputs. - for (i = 0; i < _nchan; i++) - { - p = _buff + i; - q = out [i]; - for (j = 0; j < _bsize; j++) q [j] = p [j * _nchan]; - } - } - else - { - // Deinterleave audio queue to outputs. - // The while loop takes care of wraparound. - while (nframes) - { - p = _audioq->rd_datap (); - n = _audioq->rd_linav (); - if (n > nframes) n = nframes; - for (i = 0; i < _nchan; i++) - { - q = out [i]; - for (j = 0; j < n; j++) q [j] = p [j * _nchan]; - out [i] += n; - p += 1; - } - _audioq->rd_commit (n); - nframes -= n; - } - } - _bstat = _audioq->rd_avail (); -} - - -void Jackclient::silence (int nframes) -{ - int i; - float *q; - - // Write silence to all jack ports. - for (i = 0; i < _nchan; i++) - { - q = (float *)(jack_port_get_buffer (_ports [i], nframes)); - memset (q, 0, nframes * sizeof (float)); - } -} - - -void Jackclient::sendinfo (int state, double error, double ratio) -{ - Jdata *J; - - if (_infoq->wr_avail ()) - { - J = _infoq->wr_datap (); - J->_state = state; - J->_error = error; - J->_ratio = ratio; - J->_bstat = _bstat; - _infoq->wr_commit (); - } -} - - -void Jackclient::jack_freewheel (int state) -{ - _freew = state ? true : false; - if (_freew) initwait (_ppsec / 4); -} - - -void Jackclient::jack_latency (jack_latency_callback_mode_t jlcm) -{ - jack_latency_range_t R; - int i; - - if (_state < WAIT) return; - if (_mode == PLAY) - { - if (jlcm != JackPlaybackLatency) return; - R.min = R.max = (int)(_delay / _ratio) + _ltcor; - } - else - { - if (jlcm != JackCaptureLatency) return; - R.min = R.max = (int)(_delay * _ratio) + _ltcor; - } - for (i = 0; i < _nchan; i++) - { - jack_port_set_latency_range (_ports [i], jlcm, &R); - } -} - - -int Jackclient::jack_process (int nframes) -{ - int dk, n; - Adata *D; - jack_time_t t0, t1; - jack_nframes_t ft; - float us; - double tj, err, d1, d2, rd; - - // Buffer size change or other evil. - if (_state == TERM) - { - sendinfo (TERM, 0, 0); - return 0; - } - // Skip cylce if ports may not yet exist. - if (_state < WAIT) return 0; - - // Start synchronisation 1/2 second after entering - // the WAIT state. This delay allows the ALSA thread - // to restart cleanly if necessary. Disabled while - // freewheeling. - if (_state == WAIT) - { - if (_freew) return 0; - if (_mode == CAPT) silence (nframes); - if (++_count == 0) initsync (); - else return 0; - } - - // Get the start time of the current cycle. - jack_get_cycle_times (_client, &ft, &t0, &t1, &us); - tj = tjack (t0); - - // Check for any skipped cycles. - if (_state >= SYNC1) - { - dk = ft - _ft - _bsize; - if (_mode == PLAY) - { - dk = (int)(dk * _ratio + 0.5); - _audioq->wr_commit (dk); - } - else - { - dk = (int)(dk / _ratio + 0.5); - _audioq->rd_commit (dk); - } - } - _ft = ft; - - // Check if we have timing data from the ALSA thread. - n = _alsaq->rd_avail (); - // If the data queue is full restart synchronisation. - // This can happen e.g. on a jack engine timeout, or - // when too many cycles have been skipped. - if (n == _alsaq->size ()) - { - initwait (_ppsec / 2); - return 0; - } - if (n) - { - // Else move interval end to start, and update the - // interval end keeping only the most recent data. - if (_state < SYNC2) _state++; - _t_a0 = _t_a1; - _k_a0 = _k_a1; - while (_alsaq->rd_avail ()) - { - D = _alsaq->rd_datap (); - // Restart synchronisation in case of - // an error in the ALSA interface. - if (D->_state == Alsathread::WAIT) - { - initwait (_ppsec / 2); - return 0; - } - _t_a1 = D->_timer; - _k_a1 += D->_nsamp; - _alsaq->rd_commit (); - } - } - - err = 0; - if (_state >= SYNC2) - { - // Compute the delay error. - d1 = tjack_diff (tj, _t_a0); - d2 = tjack_diff (_t_a1, _t_a0); - rd = _resamp ? _resamp->inpdist () : 0.0; - - if (_mode == PLAY) - { - n = _audioq->nwr () - _k_a0; // Must be done as integer as both terms will overflow. - err = n - (_k_a1 - _k_a0) * d1 / d2 + rd * _ratio - _delay; - } - else - { - n = _k_a0 - _audioq->nrd (); // Must be done as integer as both terms will overflow. - err = n + (_k_a1 - _k_a0) * d1 / d2 + rd - _delay ; - } - n = (int)(floor (err + 0.5)); - if (_state == SYNC2) - { - // We have the first delay error value. Adjust the audio - // queue to obtain the actually wanted delay, and start - // tracking. - if (_mode == PLAY) _audioq->wr_commit (-n); - else _audioq->rd_commit (n); - err -= n; - setloop (1.0); - _state = PROC1; - } - } - - // Switch to lower bandwidth after 4 seconds. - if ((_state == PROC1) && (++_count == 4 * _ppsec)) - { - _state = PROC2; - setloop (0.05); - } - - if (_state >= PROC1) - { - _z1 += _w0 * (_w1 * err - _z1); - _z2 += _w0 * (_z1 - _z2); - _z3 += _w2 * _z2; - // Check error conditions. - if (fabs (_z3) > 0.05) - { - // Something is really wrong, wait 10 seconds then restart. - initwait (10 * _ppsec); - return 0; - } - // Run loop filter and set resample ratio. - if (_resamp) - { - _rcorr = 1 - (_z2 + _z3); - if (_rcorr > 1.05) _rcorr = 1.05; - if (_rcorr < 0.95) _rcorr = 0.95; - _resamp->set_rratio (_rcorr); - } - sendinfo (_state, err, _rcorr); - - // Resample and transfer between audio - // queue and jack ports. - if (_mode == PLAY) playback (nframes); - else capture (nframes); - } - else if (_mode == CAPT) silence (nframes); - - return 0; -} diff --git a/tools/zalsa/jackclient.h b/tools/zalsa/jackclient.h deleted file mode 100644 index 52f3ddfd..00000000 --- a/tools/zalsa/jackclient.h +++ /dev/null @@ -1,120 +0,0 @@ -// ---------------------------------------------------------------------------- -// -// Copyright (C) 2012-2018 Fons Adriaensen <fons@linuxaudio.org> -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. -// -// ---------------------------------------------------------------------------- - - -#ifndef __JACKCLIENT_H -#define __JACKCLIENT_H - - -#include <zita-resampler/vresampler.h> -#include "jack/jack.h" -#include "lfqueue.h" - - -class Jackclient -{ -public: - - Jackclient (jack_client_t*, const char *jserv, int mode, int nchan, bool sync, void *arg); - virtual ~Jackclient (void); - - enum { PLAY, CAPT, MAXCHAN = 64 }; - enum { INIT, TERM, WAIT, SYNC0, SYNC1, SYNC2, PROC1, PROC2 }; - - void start (Lfq_audio *audioq, - Lfq_int32 *commq, - Lfq_adata *alsaq, - Lfq_jdata *infoq, - double ratio, - int delay, - int ltcor, - int rqual); - - const char *jname (void) const { return _jname; } - int fsamp (void) const { return _fsamp; } - int bsize (void) const { return _bsize; } - int rprio (void) const { return _rprio; } - void *getarg(void) const { return _arg; } - -private: - - bool init (const char *jserv); - void fini (void); - void initwait (int nwait); - void initsync (void); - void setloop (double bw); - void silence (int nframes); - void playback (int nframes); - void capture (int nframes); - void sendinfo (int state, double error, double ratio); - - virtual void thr_main (void) {} - - void jack_freewheel (int state); - void jack_latency (jack_latency_callback_mode_t jlcm); - int jack_process (int nframes); - - jack_client_t *_client; - jack_port_t *_ports [MAXCHAN]; - void *_arg; - const char *_jname; - int _mode; - int _nchan; - int _state; - int _count; - int _fsamp; - int _bsize; - int _rprio; - bool _freew; - float *_buff; - - Lfq_audio *_audioq; - Lfq_int32 *_commq; - Lfq_adata *_alsaq; - Lfq_jdata *_infoq; - double _ratio; - int _ppsec; - int _bstat; - - jack_nframes_t _ft; - double _t_a0; - double _t_a1; - int _k_a0; - int _k_a1; - double _delay; - int _ltcor; - - double _w0; - double _w1; - double _w2; - double _z1; - double _z2; - double _z3; - double _rcorr; - VResampler *_resamp; - - static void jack_static_shutdown (void *arg); - static int jack_static_buffsize (jack_nframes_t nframes, void *arg); - static void jack_static_freewheel (int state, void *arg); - static void jack_static_latency (jack_latency_callback_mode_t jlcm, void *arg); - static int jack_static_process (jack_nframes_t nframes, void *arg); -}; - - -#endif diff --git a/tools/zalsa/lfqueue.cc b/tools/zalsa/lfqueue.cc deleted file mode 100644 index f66d07e3..00000000 --- a/tools/zalsa/lfqueue.cc +++ /dev/null @@ -1,89 +0,0 @@ -// ---------------------------------------------------------------------------- -// -// Copyright (C) 2012 Fons Adriaensen <fons@linuxaudio.org> -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. -// -// ---------------------------------------------------------------------------- - - -#include <assert.h> -#include "lfqueue.h" - - -Lfq_adata::Lfq_adata (int size) : - _size (size), - _mask (size - 1), - _nwr (0), - _nrd (0) -{ - assert (!(_size & _mask)); - _data = new Adata [_size]; -} - -Lfq_adata::~Lfq_adata (void) -{ - delete[] _data; -} - - -Lfq_jdata::Lfq_jdata (int size) : - _size (size), - _mask (size - 1), - _nwr (0), - _nrd (0) -{ - assert (!(_size & _mask)); - _data = new Jdata [_size]; -} - -Lfq_jdata::~Lfq_jdata (void) -{ - delete[] _data; -} - - -Lfq_int32::Lfq_int32 (int size) : - _size (size), - _mask (size - 1), - _nwr (0), - _nrd (0) -{ - assert (!(_size & _mask)); - _data = new int32_t [_size]; -} - -Lfq_int32::~Lfq_int32 (void) -{ - delete[] _data; -} - - -Lfq_audio::Lfq_audio (int nsamp, int nchan) : - _size (nsamp), - _mask (nsamp - 1), - _nch (nchan), - _nwr (0), - _nrd (0) -{ - assert (!(_size & _mask)); - _data = new float [_nch * _size]; -} - -Lfq_audio::~Lfq_audio (void) -{ - delete[] _data; -} - - diff --git a/tools/zalsa/lfqueue.h b/tools/zalsa/lfqueue.h deleted file mode 100644 index 3943d401..00000000 --- a/tools/zalsa/lfqueue.h +++ /dev/null @@ -1,182 +0,0 @@ -// ---------------------------------------------------------------------------- -// -// Copyright (C) 2012 Fons Adriaensen <fons@linuxaudio.org> -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. -// -// ---------------------------------------------------------------------------- - - -#ifndef __LFQUEUE_H -#define __LFQUEUE_H - - -#include <stdint.h> -#include <string.h> - - -class Adata -{ -public: - - int32_t _state; - int32_t _nsamp; - double _timer; -}; - - -class Lfq_adata -{ -public: - - Lfq_adata (int size); - ~Lfq_adata (void); - - void reset (void) { _nwr = _nrd = 0; } - int size (void) const { return _size; } - - int wr_avail (void) const { return _size - _nwr + _nrd; } - Adata *wr_datap (void) { return _data + (_nwr & _mask); } - void wr_commit (void) { _nwr++; } - - int rd_avail (void) const { return _nwr - _nrd; } - Adata *rd_datap (void) { return _data + (_nrd & _mask); } - void rd_commit (void) { _nrd++; } - -private: - - Adata *_data; - int _size; - int _mask; - int _nwr; - int _nrd; -}; - - -class Jdata -{ -public: - - int32_t _state; - double _error; - double _ratio; - int _bstat; -}; - - -class Lfq_jdata -{ -public: - - Lfq_jdata (int size); - ~Lfq_jdata (void); - - void reset (void) { _nwr = _nrd = 0; } - int size (void) const { return _size; } - - int wr_avail (void) const { return _size - _nwr + _nrd; } - Jdata *wr_datap (void) { return _data + (_nwr & _mask); } - void wr_commit (void) { _nwr++; } - - int rd_avail (void) const { return _nwr - _nrd; } - Jdata *rd_datap (void) { return _data + (_nrd & _mask); } - void rd_commit (void) { _nrd++; } - -private: - - Jdata *_data; - int _size; - int _mask; - int _nwr; - int _nrd; -}; - - -class Lfq_int32 -{ -public: - - Lfq_int32 (int size); - ~Lfq_int32 (void); - - int size (void) const { return _size; } - void reset (void) { _nwr = _nrd = 0; } - - int wr_avail (void) const { return _size - _nwr + _nrd; } - int32_t *wr_datap (void) { return _data + (_nwr & _mask); } - void wr_commit (void) { _nwr++; } - - int rd_avail (void) const { return _nwr - _nrd; } - int32_t *rd_datap (void) { return _data + (_nrd & _mask); } - void rd_commit (void) { _nrd++; } - - void wr_int32 (int32_t v) { _data [_nwr++ & _mask] = v; } - void wr_uint32 (uint32_t v) { _data [_nwr++ & _mask] = v; } - void wr_float (float v) { *(float *)(_data + (_nwr++ & _mask)) = v; } - - int32_t rd_int32 (void) { return _data [_nrd++ & _mask]; } - int32_t rd_uint32 (void) { return _data [_nrd++ & _mask]; } - float rd_float (void) { return *(float *)(_data + (_nrd++ & _mask)); } - -private: - - int32_t *_data; - int _size; - int _mask; - int _nwr; - int _nrd; -}; - - -class Lfq_audio -{ -public: - - Lfq_audio (int nsamp, int nchan); - ~Lfq_audio (void); - - int size (void) const { return _size; } - void reset (void) - { - _nwr = _nrd = 0; - memset (_data, 0, _size * _nch * sizeof (float)); - } - - int nchan (void) const { return _nch; } - int nwr (void) const { return _nwr; }; - int nrd (void) const { return _nrd; }; - - int wr_avail (void) const { return _size - _nwr + _nrd; } - int wr_linav (void) const { return _size - (_nwr & _mask); } - float *wr_datap (void) { return _data + _nch * (_nwr & _mask); } - void wr_commit (int k) { _nwr += k; } - - int rd_avail (void) const { return _nwr - _nrd; } - int rd_linav (void) const { return _size - (_nrd & _mask); } - float *rd_datap (void) { return _data + _nch * (_nrd & _mask); } - void rd_commit (int k) { _nrd += k; } - -private: - - float *_data; - int _size; - int _mask; - int _nch; - int _nwr; - int _nrd; -}; - - -#endif - diff --git a/tools/zalsa/pxthread.cc b/tools/zalsa/pxthread.cc deleted file mode 100644 index 522827d4..00000000 --- a/tools/zalsa/pxthread.cc +++ /dev/null @@ -1,87 +0,0 @@ -// ---------------------------------------------------------------------------- -// -// Copyright (C) 2012 Fons Adriaensen <fons@linuxaudio.org> -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. -// -// ---------------------------------------------------------------------------- - - -#include "pxthread.h" - - -Pxthread::Pxthread (void) : _thrid (0) -{ -} - - -Pxthread::~Pxthread (void) -{ -} - - -extern "C" void *Pxthread_entry_point (void *arg) -{ - Pxthread *T = (Pxthread *) arg; - T->thr_main (); - return NULL; -} - - -int Pxthread::thr_start (int policy, int priority, size_t stacksize) -{ - int min, max, rc; - pthread_attr_t attr; - struct sched_param parm; - - min = sched_get_priority_min (policy); - max = sched_get_priority_max (policy); - priority += max; - if (priority > max) priority = max; - if (priority < min) priority = min; - parm.sched_priority = priority; - - pthread_attr_init (&attr); - pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); - pthread_attr_setschedpolicy (&attr, policy); - pthread_attr_setschedparam (&attr, &parm); - pthread_attr_setscope (&attr, PTHREAD_SCOPE_SYSTEM); - pthread_attr_setinheritsched (&attr, PTHREAD_EXPLICIT_SCHED); - pthread_attr_setstacksize (&attr, stacksize); - - _thrid = 0; - rc = pthread_create (&_thrid, - &attr, - Pxthread_entry_point, - this); - - pthread_attr_destroy (&attr); - - return rc; -} - - -void Pxthread::thr_main (void) -{ -} - - -void Pxthread::thr_wait (void) -{ - if (_thrid == 0) - return; - pthread_join (_thrid, NULL); - _thrid = 0; -} - diff --git a/tools/zalsa/pxthread.h b/tools/zalsa/pxthread.h deleted file mode 100644 index 542aa6ed..00000000 --- a/tools/zalsa/pxthread.h +++ /dev/null @@ -1,53 +0,0 @@ -// ---------------------------------------------------------------------------- -// -// Copyright (C) 2012 Fons Adriaensen <fons@linuxaudio.org> -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. -// -// ---------------------------------------------------------------------------- - - -#ifndef __PXTHREAD_H -#define __PXTHREAD_H - - -#include <sys/types.h> -#include <stdlib.h> -#include <stdio.h> -#include <stdarg.h> -#include <assert.h> -#include <errno.h> -#include <pthread.h> - - -class Pxthread -{ -public: - - Pxthread (void); - virtual ~Pxthread (void); - Pxthread (const Pxthread&); - Pxthread& operator=(const Pxthread&); - - virtual void thr_main (void) = 0; - virtual int thr_start (int policy, int priority, size_t stacksize = 0); - virtual void thr_wait (void); - -private: - - pthread_t _thrid; -}; - - -#endif diff --git a/tools/zalsa/timers.h b/tools/zalsa/timers.h deleted file mode 100644 index 267afa61..00000000 --- a/tools/zalsa/timers.h +++ /dev/null @@ -1,53 +0,0 @@ -// ---------------------------------------------------------------------------- -// -// Copyright (C) 2012-2018 Fons Adriaensen <fons@linuxaudio.org> -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. -// -// ---------------------------------------------------------------------------- - - -#ifndef __TIMERS_H -#define __TIMERS_H - - -#include <math.h> -#include <sys/time.h> -#include <jack/jack.h> - - -#define tjack_mod ldexp (1e-6f, 32) - - - -inline double tjack_diff (double a, double b) -{ - double d, m; - - d = a - b; - m = tjack_mod; - while (d < -m / 2) d += m; - while (d >= m / 2) d -= m; - return d; -} - - -inline double tjack (jack_time_t t, double dt = 0) -{ - int32_t u = (int32_t)(t & 0xFFFFFFFFLL); - return 1e-6 * u; -} - - -#endif diff --git a/tools/zalsa/zita-a2j.cc b/tools/zalsa/zita-a2j.cc deleted file mode 100644 index 1dbe1144..00000000 --- a/tools/zalsa/zita-a2j.cc +++ /dev/null @@ -1,409 +0,0 @@ -// ---------------------------------------------------------------------------- -// -// Copyright (C) 2012 Fons Adriaensen <fons@linuxaudio.org> -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. -// -// ---------------------------------------------------------------------------- - - -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <stdio.h> -#include <signal.h> -#include "alsathread.h" -#include "jackclient.h" -#include "lfqueue.h" -#include "jack/control.h" - -static const char *clopt = "hvLSwj:d:r:p:n:c:Q:I:"; - -static void help (void) -{ - jack_info ("%s-%s", APPNAME, VERSION); - jack_info ("(C) 2012-2018 Fons Adriaensen <fons@linuxaudio.org>"); - jack_info ("Use ALSA capture device as a Jack client."); - jack_info ("Options:"); - jack_info (" -h Display this text"); - jack_info (" -j <jackname> Name as Jack client [%s]", APPNAME); - jack_info (" -d <device> ALSA capture device [none]"); - jack_info (" -r <rate> Sample rate [48000]"); - jack_info (" -p <period> Period size [256]"); - jack_info (" -n <nfrags> Number of fragments [2]"); - jack_info (" -c <nchannels> Number of channels [2]"); - jack_info (" -S Word clock sync, no resampling"); - jack_info (" -Q <quality> Resampling quality, 16..96 [auto]"); - jack_info (" -I <samples> Latency adjustment [0]"); - jack_info (" -L Force 16-bit and 2 channels [off]"); - jack_info (" -w Wait until soundcard is available [off]"); - jack_info (" -v Print tracing information [off]"); -} - -class zita_a2j -{ - Lfq_int32 *commq; - Lfq_adata *alsaq; - Lfq_jdata *infoq; - Lfq_audio *audioq; - bool stop; - bool v_opt; - bool L_opt; - bool S_opt; - bool w_opt; - char *jname; - char *device; - int fsamp; - int bsize; - int nfrag; - int nchan; - int rqual; - int ltcor; - -public: - - zita_a2j() - { - commq = new Lfq_int32(16); - alsaq = new Lfq_adata(256); - infoq = new Lfq_jdata(256); - audioq = 0; - stop = false; - v_opt = false; - L_opt = false; - S_opt = false; - w_opt = false; - jname = strdup(APPNAME); - device = 0; - fsamp = 48000; - bsize = 128; - nfrag = 2; - nchan = 2; - rqual = 0; - ltcor = 0; - A = 0; - C = 0; - J = 0; - t = 0; - } - -private: - - int procoptions (int ac, const char *av []) - { - int k; - - optind = 1; - opterr = 0; - while ((k = getopt (ac, (char **) av, (char *) clopt)) != -1) - { - if (optarg && (*optarg == '-')) - { - jack_error (APPNAME ": Missing argument for '-%c' option.", k); - jack_error (APPNAME ": Use '-h' to see all options."); - return 1; - } - switch (k) - { - case 'h' : help (); return 1; - case 'v' : v_opt = true; break; - case 'L' : L_opt = true; break; - case 'S' : S_opt = true; break; - case 'w' : w_opt = true; break; - case 'j' : jname = optarg; break; - case 'd' : device = optarg; break; - case 'r' : fsamp = atoi (optarg); break; - case 'p' : bsize = atoi (optarg); break; - case 'n' : nfrag = atoi (optarg); break; - case 'c' : nchan = atoi (optarg); break; - case 'Q' : rqual = atoi (optarg); break; - case 'I' : ltcor = atoi (optarg); break; - case '?': - if (optopt != ':' && strchr (clopt, optopt)) - { - jack_error (APPNAME ": Missing argument for '-%c' option.", optopt); - } - else if (isprint (optopt)) - { - jack_error (APPNAME ": Unknown option '-%c'.", optopt); - } - else - { - jack_error (APPNAME ": Unknown option character '0x%02x'.", optopt & 255); - } - jack_error (APPNAME ": Use '-h' to see all options."); - return 1; - default: - return 1; - } - } - return 0; - } - - int parse_options (const char* load_init) - { - int argsz; - int argc = 0; - const char** argv; - char* args = strdup (load_init); - char* token; - char* ptr = args; - char* savep; - - if (!load_init) { - return 0; - } - - argsz = 8; /* random guess at "maxargs" */ - argv = (const char **) malloc (sizeof (char *) * argsz); - - argv[argc++] = APPNAME; - - while (1) { - - if ((token = strtok_r (ptr, " ", &savep)) == NULL) { - break; - } - - if (argc == argsz) { - argsz *= 2; - argv = (const char **) realloc (argv, sizeof (char *) * argsz); - } - - argv[argc++] = token; - ptr = NULL; - } - - return procoptions (argc, argv); - } - - void printinfo (void) - { - int n, k; - double e, r; - Jdata *J; - - n = 0; - k = 99999; - e = r = 0; - while (infoq->rd_avail ()) - { - J = infoq->rd_datap (); - if (J->_state == Jackclient::TERM) - { - jack_error (APPNAME ": Fatal error condition, terminating."); - stop = true; - return; - } - else if (J->_state == Jackclient::WAIT) - { - jack_info (APPNAME ": Detected excessive timing errors, waiting 10 seconds."); - n = 0; - } - else if (J->_state == Jackclient::SYNC0) - { - jack_info (APPNAME ": Starting synchronisation."); - } - else if (v_opt) - { - n++; - e += J->_error; - r += J->_ratio; - if (J->_bstat < k) k = J->_bstat; - } - infoq->rd_commit (); - } - if (n) jack_info (APPNAME ": %8.3lf %10.6lf %5d", e / n, r / n, k); - } - - - Alsa_pcmi *A; - Alsathread *C; - Jackclient *J; - - pthread_t t; - int topts; - - static void* _retry_alsa_pcmi (void *arg) - { - ((zita_a2j*)arg)->retry_alsa_pcmi (); - return NULL; - } - - void retry_alsa_pcmi () - { - Alsa_pcmi *a; - - while (! stop) - { - sleep(1); - - a = new Alsa_pcmi (0, device, 0, fsamp, bsize, nfrag, topts); - if (a->state ()) - { - delete a; - continue; - } - - A = a; - if (v_opt) A->printinfo (); - C = new Alsathread (A, Alsathread::CAPT); - usleep (100*1000); - jack_initialize_part2 (); - jack_info (APPNAME ": Device is now available and has been activated"); - break; - } - - t = 0; - } - -public: - - int - jack_initialize (jack_client_t* client, const char* load_init) - { - int opts; - - if (parse_options (load_init)) { - jack_error (APPNAME ": parse options failed"); - delete this; - return 1; - } - - if (device == 0) - { - help (); - delete this; - return 1; - } - if (rqual < 16) rqual = 16; - if (rqual > 96) rqual = 96; - if ((fsamp < 8000) || (bsize < 16) || (nfrag < 2) || (nchan < 1)) - { - jack_error (APPNAME ": Illegal parameter value(s)."); - delete this; - return 1; - } - - opts = 0; - if (v_opt) opts |= Alsa_pcmi::DEBUG_ALL; - if (L_opt) opts |= Alsa_pcmi::FORCE_16B | Alsa_pcmi::FORCE_2CH; - if (w_opt) - { - J = new Jackclient (client, 0, Jackclient::CAPT, nchan, S_opt, this); - A = new Alsa_pcmi (0, device, 0, fsamp, bsize, nfrag, opts); - - // if device is not available, spawn thread to keep trying - if (A->state ()) - { - delete A; - A = NULL; - topts = opts; - pthread_create (&t, NULL, _retry_alsa_pcmi, this); - jack_info (APPNAME ": Could not open device, will keep trying in new thread..."); - return 0; - } - - // otherwise continue as normal - if (v_opt) A->printinfo (); - C = new Alsathread (A, Alsathread::CAPT); - } - else - { - A = new Alsa_pcmi (0, device, 0, fsamp, bsize, nfrag, opts); - if (A->state ()) - { - jack_error (APPNAME ": Can't open ALSA capture device '%s'.", device); - delete this; - return 1; - } - if (v_opt) A->printinfo (); - if (nchan > A->ncapt ()) - { - nchan = A->ncapt (); - jack_error (APPNAME ": Warning: only %d channels are available.", nchan); - } - C = new Alsathread (A, Alsathread::CAPT); - J = new Jackclient (client, 0, Jackclient::CAPT, nchan, S_opt, this); - } - - usleep (100*1000); - jack_initialize_part2 (); - return 0; - } - - void jack_initialize_part2 () - { - int k, k_del; - double t_alsa; - double t_jack; - double t_del; - - t_alsa = (double) bsize / fsamp; - if (t_alsa < 1e-3) t_alsa = 1e-3; - t_jack = (double) J->bsize () / J->fsamp (); - t_del = t_alsa + t_jack; - k_del = (int)(t_del * fsamp); - for (k = 256; k < 2 * k_del; k *= 2); - audioq = new Lfq_audio (k, nchan); - - if (rqual == 0) - { - k = (fsamp < J->fsamp ()) ? fsamp : J->fsamp (); - if (k < 44100) k = 44100; - rqual = (int)((6.7 * k) / (k - 38000)); - } - if (rqual < 16) rqual = 16; - if (rqual > 96) rqual = 96; - - C->start (audioq, commq, alsaq, J->rprio () + 10); - J->start (audioq, commq, alsaq, infoq, J->fsamp () / (double) fsamp, k_del, ltcor, rqual); - } - - void jack_finish (void* arg) - { - if (t != 0) - { - stop = true; - pthread_join(t, NULL); - } - - commq->wr_int32 (Alsathread::TERM); - usleep (100000); - delete C; - delete A; - delete J; - delete audioq; - } -}; - -extern "C" { - -int -jack_initialize (jack_client_t* client, const char* load_init) -{ - zita_a2j *c = new zita_a2j(); - return c->jack_initialize(client, load_init); -} - -void jack_finish (void* arg) -{ - if (!arg) return; - Jackclient *J = (Jackclient *)arg; - zita_a2j *c = (zita_a2j *)J->getarg(); - c->jack_finish(arg); - delete c; -} - -} /* extern "C" */ diff --git a/tools/zalsa/zita-j2a.cc b/tools/zalsa/zita-j2a.cc deleted file mode 100644 index a341ab68..00000000 --- a/tools/zalsa/zita-j2a.cc +++ /dev/null @@ -1,408 +0,0 @@ -// ---------------------------------------------------------------------------- -// -// Copyright (C) 2012 Fons Adriaensen <fons@linuxaudio.org> -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. -// -// ---------------------------------------------------------------------------- - - -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <stdio.h> -#include <signal.h> -#include "alsathread.h" -#include "jackclient.h" -#include "lfqueue.h" -#include "jack/control.h" - -static const char *clopt = "hvLSwj:d:r:p:n:c:Q:O:"; - -static void help (void) -{ - jack_info ("%s-%s", APPNAME, VERSION); - jack_info ("(C) 2012-2018 Fons Adriaensen <fons@linuxaudio.org>"); - jack_info ("Use ALSA playback device as a Jack client."); - jack_info ("Options:"); - jack_info (" -h Display this text"); - jack_info (" -j <jackname> Name as Jack client [%s]", APPNAME); - jack_info (" -d <device> ALSA playback device [none]"); - jack_info (" -r <rate> Sample rate [48000]"); - jack_info (" -p <period> Period size [256]"); - jack_info (" -n <nfrags> Number of fragments [2]"); - jack_info (" -c <nchannels> Number of channels [2]"); - jack_info (" -S Word clock sync, no resampling"); - jack_info (" -Q <quality> Resampling quality, 16..96 [auto]"); - jack_info (" -O <samples> Latency adjustment [0]"); - jack_info (" -L Force 16-bit and 2 channels [off]"); - jack_info (" -w Wait until soundcard is available [off]"); - jack_info (" -v Print tracing information [off]"); -} - -class zita_j2a -{ - Lfq_int32 *commq; - Lfq_adata *alsaq; - Lfq_jdata *infoq; - Lfq_audio *audioq; - bool stop; - bool v_opt; - bool L_opt; - bool S_opt; - bool w_opt; - char *jname; - char *device; - int fsamp; - int bsize; - int nfrag; - int nchan; - int rqual; - int ltcor; - -public: - - zita_j2a() - { - commq = new Lfq_int32(16); - alsaq = new Lfq_adata(256); - infoq = new Lfq_jdata(256); - audioq = 0; - stop = false; - v_opt = false; - L_opt = false; - S_opt = false; - w_opt = false; - jname = strdup(APPNAME); - device = 0; - fsamp = 48000; - bsize = 128; - nfrag = 2; - nchan = 2; - rqual = 0; - ltcor = 0; - A = 0; - P = 0; - J = 0; - t = 0; - } - -private: - - int procoptions (int ac, const char *av []) - { - int k; - - optind = 1; - opterr = 0; - while ((k = getopt (ac, (char **) av, (char *) clopt)) != -1) - { - if (optarg && (*optarg == '-')) - { - jack_error (APPNAME ": Missing argument for '-%c' option.", k); - jack_error (APPNAME ": Use '-h' to see all options."); - return 1; - } - switch (k) - { - case 'h' : help (); return 1; - case 'v' : v_opt = true; break; - case 'L' : L_opt = true; break; - case 'S' : S_opt = true; break; - case 'w' : w_opt = true; break; - case 'j' : jname = optarg; break; - case 'd' : device = optarg; break; - case 'r' : fsamp = atoi (optarg); break; - case 'p' : bsize = atoi (optarg); break; - case 'n' : nfrag = atoi (optarg); break; - case 'c' : nchan = atoi (optarg); break; - case 'Q' : rqual = atoi (optarg); break; - case 'O' : ltcor = atoi (optarg); break; - case '?': - if (optopt != ':' && strchr (clopt, optopt)) - { - jack_error (APPNAME ": Missing argument for '-%c' option.", optopt); - } - else if (isprint (optopt)) - { - jack_error (APPNAME ": Unknown option '-%c'.", optopt); - } - else - { - jack_error (APPNAME ": Unknown option character '0x%02x'.", optopt & 255); - } - jack_error (APPNAME ": Use '-h' to see all options."); - return 1; - default: - return 1; - } - } - - return 0; - } - - int parse_options (const char* load_init) - { - int argsz; - int argc = 0; - const char** argv; - char* args = strdup (load_init); - char* token; - char* ptr = args; - char* savep; - - if (!load_init) { - return 0; - } - - argsz = 8; /* random guess at "maxargs" */ - argv = (const char **) malloc (sizeof (char *) * argsz); - - argv[argc++] = APPNAME; - - while (1) { - - if ((token = strtok_r (ptr, " ", &savep)) == NULL) { - break; - } - - if (argc == argsz) { - argsz *= 2; - argv = (const char **) realloc (argv, sizeof (char *) * argsz); - } - - argv[argc++] = token; - ptr = NULL; - } - - return procoptions (argc, argv); - } - - void printinfo (void) - { - int n, k; - double e, r; - Jdata *J; - - n = 0; - k = 99999; - e = r = 0; - while (infoq->rd_avail ()) - { - J = infoq->rd_datap (); - if (J->_state == Jackclient::TERM) - { - jack_info (APPNAME ": Fatal error condition, terminating."); - stop = true; - return; - } - else if (J->_state == Jackclient::WAIT) - { - jack_info (APPNAME ": Detected excessive timing errors, waiting 10 seconds."); - n = 0; - } - else if (J->_state == Jackclient::SYNC0) - { - jack_info (APPNAME ": Starting synchronisation."); - } - else if (v_opt) - { - n++; - e += J->_error; - r += J->_ratio; - if (J->_bstat < k) k = J->_bstat; - } - infoq->rd_commit (); - } - if (n) jack_info ("%8.3lf %10.6lf %5d", e / n, r / n, k); - } - - Alsa_pcmi *A; - Alsathread *P; - Jackclient *J; - - pthread_t t; - int topts; - - static void* _retry_alsa_pcmi (void *arg) - { - ((zita_j2a*)arg)->retry_alsa_pcmi (); - return NULL; - } - - void retry_alsa_pcmi () - { - Alsa_pcmi *a; - - while (! stop) - { - sleep(1); - - a = new Alsa_pcmi (device, 0, 0, fsamp, bsize, nfrag, topts); - if (a->state ()) - { - delete a; - continue; - } - - A = a; - if (v_opt) A->printinfo (); - P = new Alsathread (A, Alsathread::PLAY); - usleep (100*1000); - jack_initialize_part2 (); - jack_info (APPNAME ": Device is now available and has been activated"); - break; - } - - t = 0; - } - -public: - - int jack_initialize (jack_client_t* client, const char* load_init) - { - int opts; - - if (parse_options (load_init)) { - delete this; - return 1; - } - - if (device == 0) - { - help (); - delete this; - return 1; - } - if (rqual < 16) rqual = 16; - if (rqual > 96) rqual = 96; - if ((fsamp < 8000) || (bsize < 16) || (nfrag < 2) || (nchan < 1)) - { - jack_error (APPNAME ": Illegal parameter value(s)."); - delete this; - return 1; - } - - opts = 0; - if (v_opt) opts |= Alsa_pcmi::DEBUG_ALL; - if (L_opt) opts |= Alsa_pcmi::FORCE_16B | Alsa_pcmi::FORCE_2CH; - if (w_opt) - { - J = new Jackclient (client, 0, Jackclient::PLAY, nchan, S_opt, this); - - // if device is not available, spawn thread to keep trying - A = new Alsa_pcmi (device, 0, 0, fsamp, bsize, nfrag, opts); - if (A->state ()) - { - delete A; - A = NULL; - topts = opts; - pthread_create (&t, NULL, _retry_alsa_pcmi, this); - jack_info (APPNAME ": Could not open device, will keep trying in new thread..."); - return 0; - } - - // otherwise continue as normal - if (v_opt) A->printinfo (); - P = new Alsathread (A, Alsathread::PLAY); - } - else - { - A = new Alsa_pcmi (device, 0, 0, fsamp, bsize, nfrag, opts); - if (A->state ()) - { - jack_error (APPNAME ": Can't open ALSA playback device '%s'.", device); - delete this; - return 1; - } - if (v_opt) A->printinfo (); - if (nchan > A->nplay ()) - { - nchan = A->nplay (); - jack_error (APPNAME ": Warning: only %d channels are available.", nchan); - } - P = new Alsathread (A, Alsathread::PLAY); - J = new Jackclient (client, 0, Jackclient::PLAY, nchan, S_opt, this); - } - - usleep (100*1000); - jack_initialize_part2 (); - return 0; - } - - void jack_initialize_part2 () - { - int k, k_del; - double t_jack; - double t_alsa; - double t_del; - - t_alsa = (double) bsize / fsamp; - if (t_alsa < 1e-3) t_alsa = 1e-3; - t_jack = (double) J->bsize () / J->fsamp (); - t_del = t_alsa + t_jack; - k_del = (int)(t_del * fsamp); - for (k = 256; k < 2 * k_del; k *= 2); - audioq = new Lfq_audio (k, nchan); - - if (rqual == 0) - { - k = (fsamp < J->fsamp ()) ? fsamp : J->fsamp (); - if (k < 44100) k = 44100; - rqual = (int)((6.7 * k) / (k - 38000)); - } - if (rqual < 16) rqual = 16; - if (rqual > 96) rqual = 96; - - P->start (audioq, commq, alsaq, J->rprio () + 10); - J->start (audioq, commq, alsaq, infoq, (double) fsamp / J->fsamp (), k_del, ltcor, rqual); - } - - void jack_finish (void* arg) - { - if (t != 0) - { - stop = true; - pthread_join(t, NULL); - t = 0; - } - - commq->wr_int32 (Alsathread::TERM); - usleep (100*1000); - delete P; - delete A; - delete J; - delete audioq; - } -}; - -extern "C" { - -int -jack_initialize (jack_client_t* client, const char* load_init) -{ - zita_j2a *c = new zita_j2a(); - return c->jack_initialize(client, load_init); -} - -void jack_finish (void* arg) -{ - if (!arg) return; - Jackclient *J = (Jackclient *)arg; - zita_j2a *c = (zita_j2a *)J->getarg(); - c->jack_finish(arg); - delete c; -} - -} /* extern "C" */ @@ -169,9 +169,9 @@ def options(opt): help='Build with CELT') celt.add_function(check_for_celt) opt.add_auto_option( - 'example-tools', - help='Build with jack-example-tools', - conf_dest='BUILD_JACK_EXAMPLE_TOOLS', + 'tests', + help='Build tests', + conf_dest='BUILD_TESTS', default=False, ) @@ -337,10 +337,6 @@ def configure(conf): else: conf.env['SYSTEMD_USER_UNIT_DIR'] = None - if conf.env['BUILD_JACK_EXAMPLE_TOOLS']: - conf.recurse('example-clients') - conf.recurse('tools') - # test for the availability of ucontext, and how it should be used for t in ['gp_regs', 'uc_regs', 'mc_gregs', 'gregs']: fragment = '#include <ucontext.h>\n' @@ -853,14 +849,10 @@ def build(bld): build_drivers(bld) - if bld.env['BUILD_JACK_EXAMPLE_TOOLS']: - bld.recurse('example-clients') - bld.recurse('tools') - if bld.env['IS_LINUX'] or bld.env['IS_FREEBSD']: bld.recurse('man') bld.recurse('systemd') - if not bld.env['IS_WINDOWS'] and bld.env['BUILD_JACK_EXAMPLE_TOOLS']: + if not bld.env['IS_WINDOWS'] and bld.env['BUILD_TESTS']: bld.recurse('tests') if bld.env['BUILD_JACKDBUS']: bld.recurse('dbus') |