From c87087512f0991820b00355e32215b1a03bc4681 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Thu, 3 Oct 2013 20:40:16 -0400 Subject: update tools submodule --- tools | 1 + tools/.gitignore | 52 --- tools/Makefile.am | 172 -------- tools/alias.c | 121 ------ tools/alsa_in.c | 829 -------------------------------------- tools/alsa_midi/Makefile.am | 13 - tools/alsa_midi/a2j.h | 126 ------ tools/alsa_midi/alsa_midi.c | 878 ---------------------------------------- tools/alsa_midi/list.c | 147 ------- tools/alsa_midi/list.h | 903 ------------------------------------------ tools/alsa_midi/port.c | 217 ---------- tools/alsa_midi/port.h | 29 -- tools/alsa_midi/port_hash.c | 63 --- tools/alsa_midi/port_hash.h | 35 -- tools/alsa_midi/port_thread.c | 235 ----------- tools/alsa_midi/port_thread.h | 49 --- tools/alsa_out.c | 803 ------------------------------------- tools/bufsize.c | 125 ------ tools/connect.c | 225 ----------- tools/evmon.c | 131 ------ tools/freewheel.c | 86 ---- tools/iodelay.c | 269 ------------- tools/ipload.c | 171 -------- tools/ipunload.c | 78 ---- tools/load_test.c | 120 ------ tools/lsp.c | 277 ------------- tools/midi_dump.c | 114 ------ tools/monitor_client.c | 46 --- tools/netsource.c | 783 ------------------------------------ tools/property.c | 331 ---------------- tools/samplerate.c | 85 ---- tools/session_notify.c | 181 --------- tools/transport.c | 481 ---------------------- tools/tw.c | 204 ---------- tools/wait.c | 157 -------- 35 files changed, 1 insertion(+), 8536 deletions(-) create mode 160000 tools delete mode 100644 tools/.gitignore delete mode 100644 tools/Makefile.am delete mode 100644 tools/alias.c delete mode 100644 tools/alsa_in.c delete mode 100644 tools/alsa_midi/Makefile.am delete mode 100644 tools/alsa_midi/a2j.h delete mode 100644 tools/alsa_midi/alsa_midi.c delete mode 100644 tools/alsa_midi/list.c delete mode 100644 tools/alsa_midi/list.h delete mode 100644 tools/alsa_midi/port.c delete mode 100644 tools/alsa_midi/port.h delete mode 100644 tools/alsa_midi/port_hash.c delete mode 100644 tools/alsa_midi/port_hash.h delete mode 100644 tools/alsa_midi/port_thread.c delete mode 100644 tools/alsa_midi/port_thread.h delete mode 100644 tools/alsa_out.c delete mode 100644 tools/bufsize.c delete mode 100644 tools/connect.c delete mode 100644 tools/evmon.c delete mode 100644 tools/freewheel.c delete mode 100644 tools/iodelay.c delete mode 100644 tools/ipload.c delete mode 100644 tools/ipunload.c delete mode 100644 tools/load_test.c delete mode 100644 tools/lsp.c delete mode 100644 tools/midi_dump.c delete mode 100644 tools/monitor_client.c delete mode 100644 tools/netsource.c delete mode 100644 tools/property.c delete mode 100644 tools/samplerate.c delete mode 100644 tools/session_notify.c delete mode 100644 tools/transport.c delete mode 100644 tools/tw.c delete mode 100644 tools/wait.c diff --git a/tools b/tools new file mode 160000 index 0000000..7aebced --- /dev/null +++ b/tools @@ -0,0 +1 @@ +Subproject commit 7aebcedd57ca61d5291b800845d161478f045fb4 diff --git a/tools/.gitignore b/tools/.gitignore deleted file mode 100644 index 5622e73..0000000 --- a/tools/.gitignore +++ /dev/null @@ -1,52 +0,0 @@ -*.lo -*.la -.deps/ -.libs/ -Makefile -Makefile.in -alias.o -bufsize.o -connect.o -evmon.o -freewheel.o -iodelay.o -ipload.o -ipunload.o -property.o -jack_alias -jack_bufsize -jack_connect -jack_disconnect -jack_evmon -jack_freewheel -jack_iodelay -jack_load -jack_load_test -jack_lsp -jack_midi_dump -jack_monitor_client -jack_netsource -jack_netsource-netjack_packet.o -jack_netsource-netsource.o -jack_property -jack_samplerate -jack_session_notify -jack_thread_wait -jack_transport -jack_unload -jack_wait -load_test.o -lsp.o -midi_dump.o -monitor_client.o -samplerate.o -session_notify.o -transport.o -tw.o -wait.o -alsa_in -alsa_out -alsa_in-alsa_in.o -alsa_out-alsa_out.o -alsa_in-memops.o -alsa_out-memops.o diff --git a/tools/Makefile.am b/tools/Makefile.am deleted file mode 100644 index 5fab3ef..0000000 --- a/tools/Makefile.am +++ /dev/null @@ -1,172 +0,0 @@ -MAINTAINERCLEANFILES = Makefile.in - -if HAVE_ALSA_MIDI -ALSA_MIDI_DIR = alsa_midi -else -ALSA_MIDI_DIR = -endif - -if HAVE_READLINE -JACK_TRANSPORT = jack_transport -dist-check-readline: -else -JACK_TRANSPORT = -dist-check-readline: - @echo - @echo ' ******' You need readline installed to make dist.' ******' - @echo - @false -endif - -NETJACK_TOOLS = jack_netsource - -if HAVE_SAMPLERATE -if HAVE_ALSA -NETJACK_TOOLS += alsa_in alsa_out -endif -dist-check-samplerate: -else -dist-check-samplerate: - @echo - @echo ' ******' You need libsamplerate installed to make dist.' ******' - @echo - @false -endif - -bin_PROGRAMS = jack_load \ - jack_unload \ - jack_monitor_client \ - jack_connect \ - jack_disconnect \ - jack_lsp \ - jack_freewheel \ - jack_evmon \ - jack_alias \ - jack_bufsize \ - jack_samplerate \ - jack_session_notify \ - jack_wait \ - jack_midi_dump \ - jack_iodelay \ - jack_load_test \ - jack_property \ - $(JACK_TRANSPORT) \ - $(NETJACK_TOOLS) - -noinst_PROGRAMS = jack_thread_wait - -if HAVE_SNDFILE -# note! jackrec_CFLAGS syntax not supported by automake-1.4 -sndfile_cflags = @SNDFILE_CFLAGS@ -endif - -AM_CFLAGS = -I.. $(JACK_CFLAGS) $(sndfile_cflags) -AM_CXXFLAGS = -I.. $(JACK_CFLAGS) $(sndfile_cflags) - -jack_property_SOURCES = property.c -jack_property_LDFLAGS = @OS_LDFLAGS@ -jack_property_LDADD = $(top_builddir)/libjack/libjack.la - -jack_connect_SOURCES = connect.c -jack_connect_LDFLAGS = @OS_LDFLAGS@ -jack_connect_LDADD = $(top_builddir)/libjack/libjack.la - -jack_disconnect_SOURCES = connect.c -jack_disconnect_LDFLAGS = @OS_LDFLAGS@ -jack_disconnect_LDADD = $(top_builddir)/libjack/libjack.la - -jack_monitor_client_SOURCES = monitor_client.c -jack_monitor_client_LDFLAGS = @OS_LDFLAGS@ -jack_monitor_client_LDADD = $(top_builddir)/libjack/libjack.la - -jack_thread_wait_SOURCES = tw.c -jack_thread_wait_LDFLAGS = @OS_LDFLAGS@ -jack_thread_wait_LDADD = $(top_builddir)/libjack/libjack.la - -jack_wait_SOURCES = wait.c -jack_wait_LDFLAGS = @OS_LDFLAGS@ -jack_wait_LDADD = $(top_builddir)/libjack/libjack.la - -jack_evmon_SOURCES = evmon.c -jack_evmon_LDFLAGS = @OS_LDFLAGS@ -jack_evmon_LDADD = $(top_builddir)/libjack/libjack.la - -jack_alias_SOURCES = alias.c -jack_alias_LDFLAGS = @OS_LDFLAGS@ -jack_alias_LDADD = $(top_builddir)/libjack/libjack.la - -jack_lsp_SOURCES = lsp.c -jack_lsp_LDFLAGS = @OS_LDFLAGS@ -jack_lsp_LDADD = $(top_builddir)/libjack/libjack.la - -jack_freewheel_SOURCES = freewheel.c -jack_freewheel_LDFLAGS = @OS_LDFLAGS@ -jack_freewheel_LDADD = $(top_builddir)/libjack/libjack.la - -jack_bufsize_SOURCES = bufsize.c -jack_bufsize_LDFLAGS = @OS_LDFLAGS@ -jack_bufsize_LDADD = $(top_builddir)/libjack/libjack.la - -jack_samplerate_SOURCES = samplerate.c -jack_samplerate_LDFLAGS = @OS_LDFLAGS@ -jack_samplerate_LDADD = $(top_builddir)/libjack/libjack.la - -jack_session_notify_SOURCES = session_notify.c -jack_session_notify_LDFLAGS = @OS_LDFLAGS@ -jack_session_notify_LDADD = $(top_builddir)/libjack/libjack.la - -jack_midi_dump_SOURCES = midi_dump.c -jack_midi_dump_LDFLAGS = @OS_LDFLAGS@ -jack_midi_dump_LDADD = $(top_builddir)/libjack/libjack.la - -jack_iodelay_SOURCES = iodelay.c -jack_iodelay_LDFLAGS = @OS_LDFLAGS@ -jack_iodelay_LDADD = $(top_builddir)/libjack/libjack.la - -if HAVE_READLINE -jack_transport_SOURCES = transport.c -jack_transport_LDFLAGS = -lreadline @READLINE_DEPS@ @OS_LDFLAGS@ -jack_transport_LDADD = $(top_builddir)/libjack/libjack.la -endif - -jack_load_test_SOURCES = load_test.c -jack_load_test_LDFLAGS = @OS_LDFLAGS@ -jack_load_test_LDADD = $(top_builddir)/libjack/libjack.la -# -# General purpose in-process loader/unloader -# - -jack_load_SOURCES = ipload.c -jack_load_LDFLAGS = @OS_LDFLAGS@ -jack_load_LDADD = $(top_builddir)/libjack/libjack.la - -jack_unload_SOURCES = ipunload.c -jack_unload_LDFLAGS = @OS_LDFLAGS@ -jack_unload_LDADD = $(top_builddir)/libjack/libjack.la - -# -# Netjack slave tools -# -jack_netsource_SOURCES = netsource.c $(top_builddir)/drivers/netjack/netjack_packet.c -jack_netsource_CFLAGS = @NETJACK_CFLAGS@ -I$(top_srcdir)/drivers/netjack -jack_netsource_LDFLAGS = @NETJACK_LIBS@ @OS_LDFLAGS@ -jack_netsource_LDADD = $(top_builddir)/libjack/libjack.la - -if HAVE_SAMPLERATE -if HAVE_ALSA -alsa_in_SOURCES = alsa_in.c $(top_builddir)/drivers/alsa/memops.c -alsa_in_CFLAGS = @NETJACK_CFLAGS@ -I$(top_builddir)/drivers/alsa -alsa_in_LDFLAGS = -lasound -lsamplerate @OS_LDFLAGS@ -alsa_in_LDADD = $(top_builddir)/libjack/libjack.la - -alsa_out_SOURCES = alsa_out.c $(top_builddir)/drivers/alsa/memops.c -alsa_out_CFLAGS = @NETJACK_CFLAGS@ -I$(top_builddir)/drivers/alsa -alsa_out_LDFLAGS = -lasound -lsamplerate @OS_LDFLAGS@ -alsa_out_LDADD = $(top_builddir)/libjack/libjack.la -endif #HAVE_ALSA -endif #HAVE_SAMPLERATE - -SUBDIRS = $(ALSA_MIDI_DIR) -DIST_SUBDIRS = alsa_midi - -# XXX ? dist-hook: dist-check-sndfile dist-check-samplerate diff --git a/tools/alias.c b/tools/alias.c deleted file mode 100644 index 5a5d523..0000000 --- a/tools/alias.c +++ /dev/null @@ -1,121 +0,0 @@ -#include -#include -#include -#include -#include - -#include - -#include - -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 8df3969..0000000 --- a/tools/alsa_in.c +++ /dev/null @@ -1,829 +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 -#include -#include -#include -#include -#include - -#include - -#include -#include -#include "memops.h" - -#include "alsa/asoundlib.h" - -#include - -// 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 - -const char* alsa_device = "hw:0"; -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; - -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_d24_sS, sample_move_dS_s24, "24bit" }, - { SND_PCM_FORMAT_S16, 2, sample_move_d16_sS, sample_move_dS_s16, "16bit" } -}; -#define NUMFORMATS (sizeof(formats)/sizeof(formats[0])) -int format=0; - -// Alsa stuff... i dont 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 == -EAGAIN) { - 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 ) -{ - int i; - int err; - - for( i=0; i (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 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 = target_delay; - - 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 - client name\n" - " -d \n" - " -c \n" - " -p \n" - " -n \n" - " -r \n" - " -q \n" - " -t \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"; - - 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:")) != -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': - alsa_device = strdup (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 ':': - 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, 0, 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); - - /* handle freewheeling */ - - 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 target_delay ) { - fprintf( stderr, "target_delay (%d) cant 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) cant 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_midi/Makefile.am b/tools/alsa_midi/Makefile.am deleted file mode 100644 index 55950f4..0000000 --- a/tools/alsa_midi/Makefile.am +++ /dev/null @@ -1,13 +0,0 @@ -MAINTAINERCLEANFILES = Makefile.in - -# -# in-process ALSA/JACK MIDI bridge client -# - -alsa_mididir = $(ADDON_DIR) - -alsa_midi_LTLIBRARIES = alsa_midi.la -alsa_midi_la_LDFLAGS = -module -avoid-version @OS_LDFLAGS@ -alsa_midi_la_SOURCES = alsa_midi.c port.c port_hash.c port_thread.c list.c - -noinst_HEADERS = a2j.h list.h port.h port_hash.h port_thread.h diff --git a/tools/alsa_midi/a2j.h b/tools/alsa_midi/a2j.h deleted file mode 100644 index 87453ae..0000000 --- a/tools/alsa_midi/a2j.h +++ /dev/null @@ -1,126 +0,0 @@ -/* -*- Mode: C ; c-basic-offset: 2 -*- */ -/* - * ALSA SEQ < - > JACK MIDI bridge - * - * Copyright (c) 2006,2007 Dmitry S. Baikov - * Copyright (c) 2007,2008,2009 Nedko Arnaudov - * - * 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; version 2 of the License. - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef STRUCTS_H__FD2CC895_411F_4ADE_9200_50FE395EDB72__INCLUDED -#define STRUCTS_H__FD2CC895_411F_4ADE_9200_50FE395EDB72__INCLUDED - -#include -#include -#include - -#define JACK_INVALID_PORT NULL - -#define MAX_PORTS 2048 -#define MAX_EVENT_SIZE 1024 - -#define PORT_HASH_BITS 4 -#define PORT_HASH_SIZE (1 << PORT_HASH_BITS) - -/* Beside enum use, these are indeces for (struct a2j).stream array */ -#define A2J_PORT_CAPTURE 0 // ALSA playback port -> JACK capture port -#define A2J_PORT_PLAYBACK 1 // JACK playback port -> ALSA capture port - -typedef struct a2j_port * a2j_port_hash_t[PORT_HASH_SIZE]; - -struct a2j; - -struct a2j_port -{ - struct a2j_port * next; /* hash - jack */ - struct list_head siblings; /* list - main loop */ - struct a2j * a2j_ptr; - bool is_dead; - char name[64]; - snd_seq_addr_t remote; - jack_port_t * jack_port; - - jack_ringbuffer_t * inbound_events; // alsa_midi_event_t + data - int64_t last_out_time; - - void * jack_buf; -}; - -struct a2j_stream -{ - snd_midi_event_t *codec; - - jack_ringbuffer_t *new_ports; - - a2j_port_hash_t port_hash; - struct list_head list; -}; - -struct a2j -{ - jack_client_t * jack_client; - - snd_seq_t *seq; - pthread_t alsa_input_thread; - pthread_t alsa_output_thread; - int client_id; - int port_id; - int queue; - bool freewheeling; - bool running; - bool finishing; - - jack_ringbuffer_t* port_add; // snd_seq_addr_t - jack_ringbuffer_t* port_del; // struct a2j_port* - jack_ringbuffer_t* outbound_events; // struct a2j_delivery_event - jack_nframes_t cycle_start; - - sem_t output_semaphore; - - struct a2j_stream stream[2]; -}; - -#define NSEC_PER_SEC ((int64_t)1000*1000*1000) - -struct a2j_alsa_midi_event -{ - int64_t time; - int size; -}; - -#define MAX_JACKMIDI_EV_SIZE 16 - -struct a2j_delivery_event -{ - struct list_head siblings; - - /* a jack MIDI event, plus the port its destined for: everything - the ALSA output thread needs to deliver the event. time is - part of the jack_event. - */ - jack_midi_event_t jack_event; - jack_nframes_t time; /* realtime, not offset time */ - struct a2j_port* port; - char midistring[MAX_JACKMIDI_EV_SIZE]; -}; - -void a2j_info (const char* fmt, ...); -void a2j_error (const char* fmt, ...); -void a2j_debug (const char* fmt, ...); -void a2j_warning (const char* fmt, ...); - - - -#endif /* #ifndef STRUCTS_H__FD2CC895_411F_4ADE_9200_50FE395EDB72__INCLUDED */ diff --git a/tools/alsa_midi/alsa_midi.c b/tools/alsa_midi/alsa_midi.c deleted file mode 100644 index ad06b1a..0000000 --- a/tools/alsa_midi/alsa_midi.c +++ /dev/null @@ -1,878 +0,0 @@ -/* -*- Mode: C ; c-basic-offset: 2 -*- */ -/* - * ALSA SEQ < - > JACK MIDI bridge - * - * Copyright (c) 2006,2007 Dmitry S. Baikov - * Copyright (c) 2007,2008,2009 Nedko Arnaudov - * Copyright (c) 2009,2010 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; version 2 of the License. - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "list.h" -#include "a2j.h" -#include "port_hash.h" -#include "port.h" -#include "port_thread.h" - -bool g_stop_request = false; - -void -a2j_info (const char* fmt, ...) -{ - va_list ap; - va_start (ap, fmt); - vfprintf (stdout, fmt, ap); - fputc ('\n', stdout); -} - -void -a2j_error (const char* fmt, ...) -{ - va_list ap; - va_start (ap, fmt); - vfprintf (stdout, fmt, ap); - fputc ('\n', stdout); -} - - -void -a2j_debug (const char* fmt, ...) -{ - va_list ap; - va_start (ap, fmt); - vfprintf (stderr, fmt, ap); - fputc ('\n', stdout); -} - -void -a2j_warning (const char* fmt, ...) -{ - va_list ap; - va_start (ap, fmt); - vfprintf (stdout, fmt, ap); - fputc ('\n', stdout); -} - -static bool -a2j_stream_init(struct a2j * self, int which) -{ - struct a2j_stream *str = &self->stream[which]; - - str->new_ports = jack_ringbuffer_create (MAX_PORTS * sizeof(struct a2j_port *)); - if (str->new_ports == NULL) { - return false; - } - - snd_midi_event_new (MAX_EVENT_SIZE, &str->codec); - INIT_LIST_HEAD (&str->list); - - return true; -} - -static void -a2j_stream_detach (struct a2j_stream * stream_ptr) -{ - struct a2j_port * port_ptr; - struct list_head * node_ptr; - - while (!list_empty (&stream_ptr->list)) { - node_ptr = stream_ptr->list.next; - list_del (node_ptr); - port_ptr = list_entry (node_ptr, struct a2j_port, siblings); - a2j_info ("port deleted: %s", port_ptr->name); - a2j_port_free (port_ptr); - } -} - -static -void -a2j_stream_close (struct a2j * self, int which) -{ - struct a2j_stream *str = &self->stream[which]; - - if (str->codec) - snd_midi_event_free (str->codec); - if (str->new_ports) - jack_ringbuffer_free (str->new_ports); -} - -static void -stop_threads (struct a2j* self) -{ - if (self->running) { - void* thread_status; - - self->running = false; /* tell alsa io thread to stop, whenever they wake up */ - /* do something that we need to do anyway and will wake the io thread, then join */ - snd_seq_disconnect_from (self->seq, self->port_id, SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_ANNOUNCE); - a2j_debug ("wait for ALSA input thread\n"); - pthread_join (self->alsa_input_thread, &thread_status); - a2j_debug ("input thread done\n"); - - /* wake output thread and join */ - sem_post(&self->output_semaphore); - pthread_join(self->alsa_output_thread, &thread_status); - a2j_debug ("output thread done\n"); - } -} - -/* - * =================== Input/output port handling ========================= - */ - -void a2j_add_ports (struct a2j_stream * str) -{ - struct a2j_port * port_ptr; - while (jack_ringbuffer_read (str->new_ports, (char *)&port_ptr, sizeof(port_ptr))) { - a2j_debug("jack: inserted port %s", port_ptr->name); - a2j_port_insert (str->port_hash, port_ptr); - } -} - -static -void -a2j_port_event (struct a2j * self, snd_seq_event_t * ev) -{ - const snd_seq_addr_t addr = ev->data.addr; - - if (addr.client == self->client_id) - return; - - if (ev->type == SND_SEQ_EVENT_PORT_START || ev->type == SND_SEQ_EVENT_PORT_CHANGE) { - if (jack_ringbuffer_write_space(self->port_add) >= sizeof(addr)) { - a2j_debug("port_event: add/change %d:%d", addr.client, addr.port); - jack_ringbuffer_write(self->port_add, (char*)&addr, sizeof(addr)); - } else { - a2j_error("dropping port_event: add/change %d:%d", addr.client, addr.port); - } - } else if (ev->type == SND_SEQ_EVENT_PORT_EXIT) { - a2j_debug("port_event: del %d:%d", addr.client, addr.port); - a2j_port_setdead(self->stream[A2J_PORT_CAPTURE].port_hash, addr); - a2j_port_setdead(self->stream[A2J_PORT_PLAYBACK].port_hash, addr); - } -} - -/* --- INBOUND FROM ALSA TO JACK ---- */ - -static void -a2j_input_event (struct a2j * self, snd_seq_event_t * alsa_event) -{ - jack_midi_data_t data[MAX_EVENT_SIZE]; - struct a2j_stream *str = &self->stream[A2J_PORT_CAPTURE]; - long size; - struct a2j_port *port; - jack_nframes_t now; - - now = jack_frame_time (self->jack_client); - - if ((port = a2j_port_get(str->port_hash, alsa_event->source)) == NULL) { - return; - } - - /* - * RPNs, NRPNs, Bank Change, etc. need special handling - * but seems, ALSA does it for us already. - */ - snd_midi_event_reset_decode(str->codec); - if ((size = snd_midi_event_decode(str->codec, data, sizeof(data), alsa_event))<0) { - return; - } - - // fixup NoteOn with vel 0 - if ((data[0] & 0xF0) == 0x90 && data[2] == 0x00) { - data[0] = 0x80 + (data[0] & 0x0F); - data[2] = 0x40; - } - - a2j_debug("input: %d bytes at event_frame=%u", (int)size, now); - - if (jack_ringbuffer_write_space(port->inbound_events) >= (sizeof(struct a2j_alsa_midi_event) + size)) { - struct a2j_alsa_midi_event ev; - char *ev_charp = (char*) &ev; - size_t limit; - size_t to_write = sizeof(ev); - - jack_ringbuffer_data_t vec[2]; - jack_ringbuffer_get_write_vector( port->inbound_events, vec ); - ev.time = now; - ev.size = size; - - - limit = (to_write > vec[0].len ? vec[0].len : to_write); - if (limit) { - memcpy( vec[0].buf, ev_charp, limit ); - to_write -= limit; - ev_charp += limit; - vec[0].buf += limit; - vec[0].len -= limit; - } - if (to_write) { - memcpy( vec[1].buf, ev_charp, to_write ); - vec[1].buf += to_write; - vec[1].len -= to_write; - } - - to_write = size; - ev_charp = (char *)data; - limit = (to_write > vec[0].len ? vec[0].len : to_write); - if (limit) { - memcpy (vec[0].buf, ev_charp, limit); - } - to_write -= limit; - ev_charp += limit; - if (to_write) { - memcpy (vec[1].buf, ev_charp, to_write); - } - - jack_ringbuffer_write_advance( port->inbound_events, sizeof(ev) + size ); - } else { - a2j_error ("MIDI data lost (incoming event buffer full): %ld bytes lost", size); - } - -} - -static int -a2j_process_incoming (struct a2j* self, struct a2j_port* port, jack_nframes_t nframes) -{ - jack_nframes_t one_period; - struct a2j_alsa_midi_event ev; - char *ev_buf; - - /* grab data queued by the ALSA input thread and write it into the JACK - port buffer. it will delivered during the JACK period that this - function is called from. - */ - - /* first clear the JACK port buffer in preparation for new data - */ - - // a2j_debug ("PORT: %s process input", jack_port_name (port->jack_port)); - - jack_midi_clear_buffer (port->jack_buf); - - one_period = jack_get_buffer_size (self->jack_client); - - while (jack_ringbuffer_peek (port->inbound_events, (char*)&ev, sizeof(ev) ) == sizeof(ev) ) { - - jack_midi_data_t* buf; - jack_nframes_t offset; - - if (ev.time >= self->cycle_start) { - break; - } - - //jack_ringbuffer_read_advance (port->inbound_events, sizeof (ev)); - ev_buf = (char *) alloca( sizeof(ev) + ev.size ); - - if (jack_ringbuffer_peek (port->inbound_events, ev_buf, sizeof(ev) + ev.size ) != sizeof(ev) + ev.size) - break; - - offset = self->cycle_start - ev.time; - if (offset > one_period) { - /* from a previous cycle, somehow. cram it in at the front */ - offset = 0; - } else { - /* offset from start of the current cycle */ - offset = one_period - offset; - } - - a2j_debug ("event at %d offset %d", ev.time, offset); - - /* make sure there is space for it */ - - buf = jack_midi_event_reserve (port->jack_buf, offset, ev.size); - - if (buf) { - /* grab the event */ - memcpy( buf, ev_buf + sizeof(ev), ev.size ); - } else { - /* throw it away (no space) */ - a2j_error ("threw away MIDI event - not reserved at time %d", ev.time); - } - jack_ringbuffer_read_advance (port->inbound_events, sizeof(ev) + ev.size); - - a2j_debug("input on %s: sucked %d bytes from inbound at %d", jack_port_name (port->jack_port), ev.size, ev.time); - } - - return 0; -} - -void* -alsa_input_thread (void* arg) -{ - struct a2j * self = arg; - int npfd; - struct pollfd * pfd; - snd_seq_addr_t addr; - snd_seq_client_info_t * client_info; - snd_seq_port_info_t * port_info; - bool initial; - snd_seq_event_t * event; - int ret; - - npfd = snd_seq_poll_descriptors_count(self->seq, POLLIN); - pfd = (struct pollfd *)alloca(npfd * sizeof(struct pollfd)); - snd_seq_poll_descriptors(self->seq, pfd, npfd, POLLIN); - - initial = true; - - while (self->running) { - if ((ret = poll(pfd, npfd, 1000)) > 0) { - - while (snd_seq_event_input (self->seq, &event) > 0) { - if (initial) { - snd_seq_client_info_alloca(&client_info); - snd_seq_port_info_alloca(&port_info); - snd_seq_client_info_set_client(client_info, -1); - while (snd_seq_query_next_client(self->seq, client_info) >= 0) { - addr.client = snd_seq_client_info_get_client(client_info); - if (addr.client == SND_SEQ_CLIENT_SYSTEM || addr.client == self->client_id) { - continue; - } - snd_seq_port_info_set_client(port_info, addr.client); - snd_seq_port_info_set_port(port_info, -1); - while (snd_seq_query_next_port(self->seq, port_info) >= 0) { - addr.port = snd_seq_port_info_get_port(port_info); - a2j_update_port(self, addr, port_info); - } - } - - initial = false; - } - - if (event->source.client == SND_SEQ_CLIENT_SYSTEM) { - a2j_port_event(self, event); - } else { - a2j_input_event(self, event); - } - - snd_seq_free_event (event); - } - } - } - - return (void*) 0; -} - -/* --- OUTBOUND FROM JACK TO ALSA ---- */ - -int -a2j_process_outgoing ( - struct a2j * self, - struct a2j_port * port) -{ - /* collect data from JACK port buffer and queue it for delivery by ALSA output thread */ - - int nevents; - jack_ringbuffer_data_t vec[2]; - int i; - int written = 0; - size_t limit; - struct a2j_delivery_event* dev; - size_t gap = 0; - - jack_ringbuffer_get_write_vector (self->outbound_events, vec); - - dev = (struct a2j_delivery_event*) vec[0].buf; - limit = vec[0].len / sizeof (struct a2j_delivery_event); - nevents = jack_midi_get_event_count (port->jack_buf); - - for (i = 0; (i < nevents) && (written < limit); ++i) { - - jack_midi_event_get (&dev->jack_event, port->jack_buf, i); - if (dev->jack_event.size <= MAX_JACKMIDI_EV_SIZE) - { - dev->time = dev->jack_event.time; - dev->port = port; - memcpy( dev->midistring, dev->jack_event.buffer, dev->jack_event.size ); - written++; - ++dev; - } - } - - /* anything left? use the second part of the vector, as much as possible */ - - if (i < nevents) - { - if (vec[0].len) - { - gap = vec[0].len - written * sizeof(struct a2j_delivery_event); - } - - dev = (struct a2j_delivery_event*) vec[1].buf; - - limit += (vec[1].len / sizeof (struct a2j_delivery_event)); - - while ((i < nevents) && (written < limit)) - { - jack_midi_event_get(&dev->jack_event, port->jack_buf, i); - if (dev->jack_event.size <= MAX_JACKMIDI_EV_SIZE) - { - dev->time = dev->jack_event.time; - dev->port = port; - memcpy(dev->midistring, dev->jack_event.buffer, dev->jack_event.size); - written++; - ++dev; - } - ++i; - } - } - - // a2j_debug( "done pushing events: %d ... gap: %d ", (int)written, (int)gap ); - /* clear JACK port buffer; advance ring buffer ptr */ - - jack_ringbuffer_write_advance (self->outbound_events, written * sizeof (struct a2j_delivery_event) + gap); - - return nevents; -} - -static int -time_sorter (struct a2j_delivery_event * a, struct a2j_delivery_event * b) -{ - if (a->time < b->time) { - return -1; - } else if (a->time > b->time) { - return 1; - } - return 0; -} - -static void* -alsa_output_thread(void * arg) -{ - struct a2j * self = (struct a2j*) arg; - struct a2j_stream *str = &self->stream[A2J_PORT_PLAYBACK]; - int i; - struct list_head evlist; - struct list_head * node_ptr; - jack_ringbuffer_data_t vec[2]; - snd_seq_event_t alsa_event; - struct a2j_delivery_event* ev; - float sr; - jack_nframes_t now; - int err; - int limit; - - while (self->running) { - /* first, make a list of all events in the outbound_events FIFO */ - - INIT_LIST_HEAD(&evlist); - - jack_ringbuffer_get_read_vector (self->outbound_events, vec); - - a2j_debug ("output thread: got %d+%d events", - (vec[0].len / sizeof (struct a2j_delivery_event)), - (vec[1].len / sizeof (struct a2j_delivery_event))); - - ev = (struct a2j_delivery_event*) vec[0].buf; - limit = vec[0].len / sizeof (struct a2j_delivery_event); - for (i = 0; i < limit; ++i) { - list_add_tail(&ev->siblings, &evlist); - ev++; - } - - ev = (struct a2j_delivery_event*) vec[1].buf; - limit = vec[1].len / sizeof (struct a2j_delivery_event); - for (i = 0; i < limit; ++i) { - list_add_tail(&ev->siblings, &evlist); - ev++; - } - - if (vec[0].len < sizeof(struct a2j_delivery_event) && (vec[1].len == 0)) { - /* no events: wait for some */ - a2j_debug ("output thread: wait for events"); - sem_wait (&self->output_semaphore); - a2j_debug ("output thread: AWAKE ... loop back for events"); - continue; - } - - /* now sort this list by time */ - - list_sort(&evlist, struct a2j_delivery_event, siblings, time_sorter); - - /* now deliver */ - - sr = jack_get_sample_rate (self->jack_client); - - list_for_each(node_ptr, &evlist) - { - ev = list_entry(node_ptr, struct a2j_delivery_event, siblings); - - snd_seq_ev_clear(&alsa_event); - snd_midi_event_reset_encode(str->codec); - if (!snd_midi_event_encode(str->codec, (const unsigned char *)ev->midistring, ev->jack_event.size, &alsa_event)) - { - continue; // invalid event - } - - snd_seq_ev_set_source(&alsa_event, self->port_id); - snd_seq_ev_set_dest(&alsa_event, ev->port->remote.client, ev->port->remote.port); - snd_seq_ev_set_direct (&alsa_event); - - now = jack_frame_time (self->jack_client); - - ev->time += self->cycle_start; - - a2j_debug ("@ %d, next event @ %d", now, ev->time); - - /* do we need to wait a while before delivering? */ - - if (ev->time > now) { - struct timespec nanoseconds; - jack_nframes_t sleep_frames = ev->time - now; - float seconds = sleep_frames / sr; - - /* if the gap is long enough, sleep */ - - if (seconds > 0.001) { - nanoseconds.tv_sec = (time_t) seconds; - nanoseconds.tv_nsec = (long) NSEC_PER_SEC * (seconds - nanoseconds.tv_sec); - - a2j_debug ("output thread sleeps for %.2f msec", ((double) nanoseconds.tv_nsec / NSEC_PER_SEC) * 1000.0); - - if (nanosleep (&nanoseconds, NULL) < 0) { - fprintf (stderr, "BAD SLEEP\n"); - /* do something ? */ - } - } - } - - /* its time to deliver */ - err = snd_seq_event_output(self->seq, &alsa_event); - snd_seq_drain_output (self->seq); - now = jack_frame_time (self->jack_client); - a2j_debug("alsa_out: written %d bytes to %s at %d, DELTA = %d", ev->jack_event.size, ev->port->name, now, - (int32_t) (now - ev->time)); - } - - /* free up space in the FIFO */ - - jack_ringbuffer_read_advance (self->outbound_events, vec[0].len + vec[1].len); - - /* and head back for more */ - } - - return (void*) 0; -} - -/** CORE JACK PROCESSING */ - - -/* ALSA */ - -static void -a2j_jack_process_internal (struct a2j * self, int dir, jack_nframes_t nframes) -{ - struct a2j_stream * stream_ptr; - int i; - struct a2j_port ** port_ptr_ptr; - struct a2j_port * port_ptr; - int nevents = 0; - - stream_ptr = &self->stream[dir]; - a2j_add_ports(stream_ptr); - - // process ports - for (i = 0 ; i < PORT_HASH_SIZE ; i++) - { - port_ptr_ptr = &stream_ptr->port_hash[i]; - while (*port_ptr_ptr != NULL) - { - port_ptr = *port_ptr_ptr; - - if (!port_ptr->is_dead) { - port_ptr->jack_buf = jack_port_get_buffer(port_ptr->jack_port, nframes); - - if (dir == A2J_PORT_CAPTURE) { - a2j_process_incoming (self, port_ptr, nframes); - } else { - nevents += a2j_process_outgoing (self, port_ptr); - } - - } else if (jack_ringbuffer_write_space (self->port_del) >= sizeof(port_ptr)) { - - a2j_debug("jack: removed port %s", port_ptr->name); - *port_ptr_ptr = port_ptr->next; - jack_ringbuffer_write(self->port_del, (char*)&port_ptr, sizeof(port_ptr)); - continue; - - } - - port_ptr_ptr = &port_ptr->next; - } - } - - if (dir == A2J_PORT_PLAYBACK && nevents > 0) { - int sv; - - /* if we queued up anything for output, tell the output thread in - case its waiting for us. - */ - - sem_getvalue (&self->output_semaphore, &sv); - sem_post (&self->output_semaphore); - } -} - -static int -a2j_process(jack_nframes_t nframes, void * arg) -{ - struct a2j* self = (struct a2j *) arg; - - if (self->freewheeling) { - return 0; - } - - self->cycle_start = jack_last_frame_time (self->jack_client); - - a2j_jack_process_internal (self, A2J_PORT_CAPTURE, nframes); - a2j_jack_process_internal (self, A2J_PORT_PLAYBACK, nframes); - - return 0; -} - -/* --- */ - -static -void -a2j_freewheel(int starting, void * arg) -{ - struct a2j* self = (struct a2j*) arg; - self->freewheeling = starting; -} - -static -void -a2j_shutdown (void * arg) -{ - struct a2j* self = (struct a2j*) self; - a2j_warning ("JACK server shutdown notification received."); - stop_threads (self); -} - -int -connect_to_alsa (struct a2j* self) -{ - int error; - void* thread_status; - - self->port_add = jack_ringbuffer_create (2 * MAX_PORTS * sizeof(snd_seq_addr_t)); - - if (self->port_add == NULL) { - goto free_self; - } - - self->port_del = jack_ringbuffer_create(2 * MAX_PORTS * sizeof(struct a2j_port *)); - if (self->port_del == NULL) { - goto free_ringbuffer_add; - } - - self->outbound_events = jack_ringbuffer_create (MAX_EVENT_SIZE * 16 * sizeof(struct a2j_delivery_event)); - if (self->outbound_events == NULL) { - goto free_ringbuffer_del; - } - - if (!a2j_stream_init (self, A2J_PORT_CAPTURE)) { - goto free_ringbuffer_outbound; - } - - if (!a2j_stream_init (self, A2J_PORT_PLAYBACK)) { - goto close_capture_stream; - } - - if ((error = snd_seq_open(&self->seq, "hw", SND_SEQ_OPEN_DUPLEX, 0)) < 0) { - a2j_error("failed to open alsa seq"); - goto close_playback_stream; - } - - if ((error = snd_seq_set_client_name(self->seq, "jackmidi")) < 0) { - a2j_error("snd_seq_set_client_name() failed"); - goto close_seq_client; - } - - if ((self->port_id = snd_seq_create_simple_port( - self->seq, - "port", - SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_WRITE -#ifndef DEBUG - |SND_SEQ_PORT_CAP_NO_EXPORT -#endif - ,SND_SEQ_PORT_TYPE_APPLICATION)) < 0) { - - a2j_error("snd_seq_create_simple_port() failed"); - goto close_seq_client; - } - - if ((self->client_id = snd_seq_client_id(self->seq)) < 0) { - a2j_error("snd_seq_client_id() failed"); - goto close_seq_client; - } - - if ((self->queue = snd_seq_alloc_queue(self->seq)) < 0) { - a2j_error("snd_seq_alloc_queue() failed"); - goto close_seq_client; - } - - snd_seq_start_queue (self->seq, self->queue, 0); - - if ((error = snd_seq_nonblock(self->seq, 1)) < 0) { - a2j_error("snd_seq_nonblock() failed"); - goto close_seq_client; - } - - snd_seq_drop_input (self->seq); - - a2j_add_ports(&self->stream[A2J_PORT_CAPTURE]); - a2j_add_ports(&self->stream[A2J_PORT_PLAYBACK]); - - if (sem_init(&self->output_semaphore, 0, 0) < 0) { - a2j_error("can't create IO semaphore"); - goto close_jack_client; - } - - self->running = true; - - if (pthread_create(&self->alsa_input_thread, NULL, alsa_input_thread, self) < 0) { - a2j_error("cannot start ALSA input thread"); - goto sem_destroy; - } - - /* wake the poll loop in the alsa input thread so initial ports are fetched */ - if ((error = snd_seq_connect_from (self->seq, self->port_id, SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_ANNOUNCE)) < 0) { - a2j_error("snd_seq_connect_from() failed"); - goto join_input_thread; - } - - if (pthread_create(&self->alsa_output_thread, NULL, alsa_output_thread, self) < 0) { - a2j_error("cannot start ALSA input thread"); - goto sem_destroy; - } - - return 0; - - /* error handling */ - - self->running = false; /* tell alsa threads to stop */ - self->finishing = false; - - snd_seq_disconnect_from(self->seq, self->port_id, SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_ANNOUNCE); - join_input_thread: - pthread_join (self->alsa_input_thread, &thread_status); - sem_destroy: - sem_destroy (&self->output_semaphore); - close_jack_client: - if ((error = jack_client_close(self->jack_client)) < 0) { - a2j_error("Cannot close jack client"); - } - close_seq_client: - snd_seq_close(self->seq); - close_playback_stream: - a2j_stream_close(self, A2J_PORT_PLAYBACK); - close_capture_stream: - a2j_stream_close(self, A2J_PORT_CAPTURE); - free_ringbuffer_outbound: - jack_ringbuffer_free(self->outbound_events); - free_ringbuffer_del: - jack_ringbuffer_free(self->port_del); - free_ringbuffer_add: - jack_ringbuffer_free(self->port_add); - free_self: - free(self); - return -1; -} - -/* JACK internal client API: 2 entry points - */ - -int -jack_initialize (jack_client_t *client, const char* load_init) -{ - struct a2j* self = calloc(1, sizeof(struct a2j)); - - if (!self) { - return -1; - } - - self->jack_client = client; - - if (load_init) { - char* args = strdup (load_init); - char* token; - char* ptr = args; - char* savep; - - while (1) { - if ((token = strtok_r (ptr, ", ", &savep)) == NULL) { - break; - } -#if 0 - /* example of how to use tokens */ - - if (strncasecmp (token, "in", 2) == 0) { - self->input = 1; - } -#endif - - ptr = NULL; - } - - free (args); - } - - if (connect_to_alsa (self)) { - free (self); - return -1; - } - - jack_set_process_callback (client, a2j_process, self); - jack_set_freewheel_callback (client, a2j_freewheel, self); - jack_on_shutdown (client, a2j_shutdown, self); - - jack_activate (client); - - return 0; -} - -void -jack_finish (void *arg) -{ - struct a2j* self = (struct a2j*) arg; - - self->finishing = true; - - stop_threads (self); - sem_destroy(&self->output_semaphore); - jack_ringbuffer_reset (self->port_add); - a2j_stream_detach (&self->stream[A2J_PORT_CAPTURE]); - a2j_stream_detach (&self->stream[A2J_PORT_PLAYBACK]); - snd_seq_close(self->seq); - self->seq = NULL; - a2j_stream_close (self, A2J_PORT_CAPTURE); - a2j_stream_close (self, A2J_PORT_PLAYBACK); - jack_ringbuffer_free(self->outbound_events); - jack_ringbuffer_free(self->port_add); - jack_ringbuffer_free(self->port_del); - - free (self); -} diff --git a/tools/alsa_midi/list.c b/tools/alsa_midi/list.c deleted file mode 100644 index 438066c..0000000 --- a/tools/alsa_midi/list.c +++ /dev/null @@ -1,147 +0,0 @@ -/* -*- Mode: C ; c-basic-offset: 2 -*- */ -/***************************************************************************** - * - * list_sort() adapted from linux kernel. - * - * 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; version 2 of the License - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - *****************************************************************************/ - -#include - -#include "list.h" - -/* list sort from Mark J Roberts (mjr@znex.org) */ -void -__list_sort( - struct list_head *head, - int member_offset, - int (*cmp)(void * a, void * b)) -{ - struct list_head *p, *q, *e, *list, *tail, *oldhead; - int insize, nmerges, psize, qsize, i; - - list = head->next; - list_del(head); - insize = 1; - for (;;) { - p = oldhead = list; - list = tail = NULL; - nmerges = 0; - - while (p) { - nmerges++; - q = p; - psize = 0; - for (i = 0; i < insize; i++) { - psize++; - q = q->next == oldhead ? NULL : q->next; - if (!q) - break; - } - - qsize = insize; - while (psize > 0 || (qsize > 0 && q)) { - if (!psize) { - e = q; - q = q->next; - qsize--; - if (q == oldhead) - q = NULL; - } else if (!qsize || !q) { - e = p; - p = p->next; - psize--; - if (p == oldhead) - p = NULL; - } else if (cmp((void *)p - member_offset, (void *)q - member_offset) <= 0) { - e = p; - p = p->next; - psize--; - if (p == oldhead) - p = NULL; - } else { - e = q; - q = q->next; - qsize--; - if (q == oldhead) - q = NULL; - } - if (tail) - tail->next = e; - else - list = e; - e->prev = tail; - tail = e; - } - p = q; - } - - tail->next = list; - list->prev = tail; - - if (nmerges <= 1) - break; - - insize *= 2; - } - - head->next = list; - head->prev = list->prev; - list->prev->next = head; - list->prev = head; -} - -struct test_list_el { - int value; - struct list_head test_list_node; -}; - -int test_list_sort_comparator(struct test_list_el * e1, struct test_list_el * e2) -{ - return e1->value - e2->value; -} - -void test_list_sort(void) -{ - struct list_head test_list; - struct test_list_el *el, *next; - struct test_list_el te1 = {.value = 1}; - struct test_list_el te2 = {.value = 2}; - struct test_list_el te3 = {.value = 3}; - struct test_list_el te4 = {.value = 4}; - struct test_list_el te5 = {.value = 5}; - struct test_list_el te6 = {.value = 6}; - struct test_list_el te7 = {.value = 7}; - - const int expected[] = {1, 2, 3, 4, 5, 6, 7}; - int i; - - INIT_LIST_HEAD(&test_list); - list_add_tail(&te2.test_list_node, &test_list); - list_add_tail(&te6.test_list_node, &test_list); - list_add_tail(&te4.test_list_node, &test_list); - list_add_tail(&te5.test_list_node, &test_list); - list_add_tail(&te7.test_list_node, &test_list); - list_add_tail(&te1.test_list_node, &test_list); - list_add_tail(&te3.test_list_node, &test_list); - - list_sort(&test_list, struct test_list_el, test_list_node, test_list_sort_comparator); - - i = 0; - list_for_each_entry_safe(el, next, &test_list, test_list_node) { - assert(el->value == expected[i]); - i++; - } -} diff --git a/tools/alsa_midi/list.h b/tools/alsa_midi/list.h deleted file mode 100644 index 5b7f4d4..0000000 --- a/tools/alsa_midi/list.h +++ /dev/null @@ -1,903 +0,0 @@ -/* -*- Mode: C ; c-basic-offset: 2 -*- */ -/***************************************************************************** - * - * Linux kernel header adapted for user-mode - * The 2.6.17-rt1 version was used. - * - * Original copyright holders of this code are unknown, they were not - * mentioned in the original file. - * - * 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; version 2 of the License - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - *****************************************************************************/ - -#ifndef _LINUX_LIST_H -#define _LINUX_LIST_H - -#include - -#if !defined(offsetof) -#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) -#endif - -/** - * container_of - cast a member of a structure out to the containing structure - * @ptr: the pointer to the member. - * @type: the type of the container struct this is embedded in. - * @member: the name of the member within the struct. - * - */ -#define container_of(ptr, type, member) ({ \ - const typeof( ((type *)0)->member ) *__mptr = (ptr); \ - (type *)( (char *)__mptr - offsetof(type,member) );}) - -#define prefetch(x) (x = x) - -/* - * These are non-NULL pointers that will result in page faults - * under normal circumstances, used to verify that nobody uses - * non-initialized list entries. - */ -#define LIST_POISON1 ((void *) 0x00100100) -#define LIST_POISON2 ((void *) 0x00200200) - -/* - * Simple doubly linked list implementation. - * - * Some of the internal functions ("__xxx") are useful when - * manipulating whole lists rather than single entries, as - * sometimes we already know the next/prev entries and we can - * generate better code by using them directly rather than - * using the generic single-entry routines. - */ - -struct list_head { - struct list_head *next, *prev; -}; - -#define LIST_HEAD_INIT(name) { &(name), &(name) } - -#define LIST_HEAD(name) \ - struct list_head name = LIST_HEAD_INIT(name) - -static inline void INIT_LIST_HEAD(struct list_head *list) -{ - list->next = list; - list->prev = list; -} - -/* - * Insert a new entry between two known consecutive entries. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -static inline void __list_add(struct list_head *new, - struct list_head *prev, - struct list_head *next) -{ - next->prev = new; - new->next = next; - new->prev = prev; - prev->next = new; -} - -/** - * list_add - add a new entry - * @new: new entry to be added - * @head: list head to add it after - * - * Insert a new entry after the specified head. - * This is good for implementing stacks. - */ -static inline void list_add(struct list_head *new, struct list_head *head) -{ - __list_add(new, head, head->next); -} - -/** - * list_add_tail - add a new entry - * @new: new entry to be added - * @head: list head to add it before - * - * Insert a new entry before the specified head. - * This is useful for implementing queues. - */ -static inline void list_add_tail(struct list_head *new, struct list_head *head) -{ - __list_add(new, head->prev, head); -} - -/* - * Insert a new entry between two known consecutive entries. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -static inline void __list_add_rcu(struct list_head * new, - struct list_head * prev, struct list_head * next) -{ - new->next = next; - new->prev = prev; -// smp_wmb(); - next->prev = new; - prev->next = new; -} - -/** - * list_add_rcu - add a new entry to rcu-protected list - * @new: new entry to be added - * @head: list head to add it after - * - * Insert a new entry after the specified head. - * This is good for implementing stacks. - * - * The caller must take whatever precautions are necessary - * (such as holding appropriate locks) to avoid racing - * with another list-mutation primitive, such as list_add_rcu() - * or list_del_rcu(), running on this same list. - * However, it is perfectly legal to run concurrently with - * the _rcu list-traversal primitives, such as - * list_for_each_entry_rcu(). - */ -static inline void list_add_rcu(struct list_head *new, struct list_head *head) -{ - __list_add_rcu(new, head, head->next); -} - -/** - * list_add_tail_rcu - add a new entry to rcu-protected list - * @new: new entry to be added - * @head: list head to add it before - * - * Insert a new entry before the specified head. - * This is useful for implementing queues. - * - * The caller must take whatever precautions are necessary - * (such as holding appropriate locks) to avoid racing - * with another list-mutation primitive, such as list_add_tail_rcu() - * or list_del_rcu(), running on this same list. - * However, it is perfectly legal to run concurrently with - * the _rcu list-traversal primitives, such as - * list_for_each_entry_rcu(). - */ -static inline void list_add_tail_rcu(struct list_head *new, - struct list_head *head) -{ - __list_add_rcu(new, head->prev, head); -} - -/* - * Delete a list entry by making the prev/next entries - * point to each other. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -static inline void __list_del(struct list_head * prev, struct list_head * next) -{ - next->prev = prev; - prev->next = next; -} - -/** - * list_del - deletes entry from list. - * @entry: the element to delete from the list. - * Note: list_empty on entry does not return true after this, the entry is - * in an undefined state. - */ -static inline void list_del(struct list_head *entry) -{ - __list_del(entry->prev, entry->next); - entry->next = LIST_POISON1; - entry->prev = LIST_POISON2; -} - -/** - * list_del_rcu - deletes entry from list without re-initialization - * @entry: the element to delete from the list. - * - * Note: list_empty on entry does not return true after this, - * the entry is in an undefined state. It is useful for RCU based - * lockfree traversal. - * - * In particular, it means that we can not poison the forward - * pointers that may still be used for walking the list. - * - * The caller must take whatever precautions are necessary - * (such as holding appropriate locks) to avoid racing - * with another list-mutation primitive, such as list_del_rcu() - * or list_add_rcu(), running on this same list. - * However, it is perfectly legal to run concurrently with - * the _rcu list-traversal primitives, such as - * list_for_each_entry_rcu(). - * - * Note that the caller is not permitted to immediately free - * the newly deleted entry. Instead, either synchronize_rcu() - * or call_rcu() must be used to defer freeing until an RCU - * grace period has elapsed. - */ -static inline void list_del_rcu(struct list_head *entry) -{ - __list_del(entry->prev, entry->next); - entry->prev = LIST_POISON2; -} - -/* - * list_replace_rcu - replace old entry by new one - * @old : the element to be replaced - * @new : the new element to insert - * - * The old entry will be replaced with the new entry atomically. - */ -static inline void list_replace_rcu(struct list_head *old, - struct list_head *new) -{ - new->next = old->next; - new->prev = old->prev; -// smp_wmb(); - new->next->prev = new; - new->prev->next = new; - old->prev = LIST_POISON2; -} - -/** - * list_del_init - deletes entry from list and reinitialize it. - * @entry: the element to delete from the list. - */ -static inline void list_del_init(struct list_head *entry) -{ - __list_del(entry->prev, entry->next); - INIT_LIST_HEAD(entry); -} - -/** - * list_move - delete from one list and add as another's head - * @list: the entry to move - * @head: the head that will precede our entry - */ -static inline void list_move(struct list_head *list, struct list_head *head) -{ - __list_del(list->prev, list->next); - list_add(list, head); -} - -/** - * list_move_tail - delete from one list and add as another's tail - * @list: the entry to move - * @head: the head that will follow our entry - */ -static inline void list_move_tail(struct list_head *list, - struct list_head *head) -{ - __list_del(list->prev, list->next); - list_add_tail(list, head); -} - -/** - * list_empty - tests whether a list is empty - * @head: the list to test. - */ -static inline int list_empty(const struct list_head *head) -{ - return head->next == head; -} - -/** - * list_empty_careful - tests whether a list is - * empty _and_ checks that no other CPU might be - * in the process of still modifying either member - * - * NOTE: using list_empty_careful() without synchronization - * can only be safe if the only activity that can happen - * to the list entry is list_del_init(). Eg. it cannot be used - * if another CPU could re-list_add() it. - * - * @head: the list to test. - */ -static inline int list_empty_careful(const struct list_head *head) -{ - struct list_head *next = head->next; - return (next == head) && (next == head->prev); -} - -static inline void __list_splice(struct list_head *list, - struct list_head *head) -{ - struct list_head *first = list->next; - struct list_head *last = list->prev; - struct list_head *at = head->next; - - first->prev = head; - head->next = first; - - last->next = at; - at->prev = last; -} - -/** - * list_splice - join two lists - * @list: the new list to add. - * @head: the place to add it in the first list. - */ -static inline void list_splice(struct list_head *list, struct list_head *head) -{ - if (!list_empty(list)) - __list_splice(list, head); -} - -/** - * list_splice_init - join two lists and reinitialise the emptied list. - * @list: the new list to add. - * @head: the place to add it in the first list. - * - * The list at @list is reinitialised - */ -static inline void list_splice_init(struct list_head *list, - struct list_head *head) -{ - if (!list_empty(list)) { - __list_splice(list, head); - INIT_LIST_HEAD(list); - } -} - -/** - * list_entry - get the struct for this entry - * @ptr: the &struct list_head pointer. - * @type: the type of the struct this is embedded in. - * @member: the name of the list_struct within the struct. - */ -#define list_entry(ptr, type, member) \ - container_of(ptr, type, member) - -/** - * list_for_each - iterate over a list - * @pos: the &struct list_head to use as a loop counter. - * @head: the head for your list. - */ -#define list_for_each(pos, head) \ - for (pos = (head)->next; prefetch(pos->next), pos != (head); \ - pos = pos->next) - -/** - * __list_for_each - iterate over a list - * @pos: the &struct list_head to use as a loop counter. - * @head: the head for your list. - * - * This variant differs from list_for_each() in that it's the - * simplest possible list iteration code, no prefetching is done. - * Use this for code that knows the list to be very short (empty - * or 1 entry) most of the time. - */ -#define __list_for_each(pos, head) \ - for (pos = (head)->next; pos != (head); pos = pos->next) - -/** - * list_for_each_prev - iterate over a list backwards - * @pos: the &struct list_head to use as a loop counter. - * @head: the head for your list. - */ -#define list_for_each_prev(pos, head) \ - for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \ - pos = pos->prev) - -/** - * list_for_each_safe - iterate over a list safe against removal of list entry - * @pos: the &struct list_head to use as a loop counter. - * @n: another &struct list_head to use as temporary storage - * @head: the head for your list. - */ -#define list_for_each_safe(pos, n, head) \ - for (pos = (head)->next, n = pos->next; pos != (head); \ - pos = n, n = pos->next) - -/** - * list_for_each_entry - iterate over list of given type - * @pos: the type * to use as a loop counter. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry(pos, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member); \ - prefetch(pos->member.next), &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) - -/** - * list_for_each_entry_reverse - iterate backwards over list of given type. - * @pos: the type * to use as a loop counter. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry_reverse(pos, head, member) \ - for (pos = list_entry((head)->prev, typeof(*pos), member); \ - prefetch(pos->member.prev), &pos->member != (head); \ - pos = list_entry(pos->member.prev, typeof(*pos), member)) - -/** - * list_prepare_entry - prepare a pos entry for use as a start point in - * list_for_each_entry_continue - * @pos: the type * to use as a start point - * @head: the head of the list - * @member: the name of the list_struct within the struct. - */ -#define list_prepare_entry(pos, head, member) \ - ((pos) ? : list_entry(head, typeof(*pos), member)) - -/** - * list_for_each_entry_continue - iterate over list of given type - * continuing after existing point - * @pos: the type * to use as a loop counter. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry_continue(pos, head, member) \ - for (pos = list_entry(pos->member.next, typeof(*pos), member); \ - prefetch(pos->member.next), &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) - -/** - * list_for_each_entry_from - iterate over list of given type - * continuing from existing point - * @pos: the type * to use as a loop counter. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry_from(pos, head, member) \ - for (; prefetch(pos->member.next), &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) - -/** - * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry - * @pos: the type * to use as a loop counter. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry_safe(pos, n, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member), \ - n = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.next, typeof(*n), member)) - -/** - * list_for_each_entry_safe_continue - iterate over list of given type - * continuing after existing point safe against removal of list entry - * @pos: the type * to use as a loop counter. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry_safe_continue(pos, n, head, member) \ - for (pos = list_entry(pos->member.next, typeof(*pos), member), \ - n = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.next, typeof(*n), member)) - -/** - * list_for_each_entry_safe_from - iterate over list of given type - * from existing point safe against removal of list entry - * @pos: the type * to use as a loop counter. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry_safe_from(pos, n, head, member) \ - for (n = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.next, typeof(*n), member)) - -/** - * list_for_each_entry_safe_reverse - iterate backwards over list of given type safe against - * removal of list entry - * @pos: the type * to use as a loop counter. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry_safe_reverse(pos, n, head, member) \ - for (pos = list_entry((head)->prev, typeof(*pos), member), \ - n = list_entry(pos->member.prev, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.prev, typeof(*n), member)) - -/** - * list_for_each_rcu - iterate over an rcu-protected list - * @pos: the &struct list_head to use as a loop counter. - * @head: the head for your list. - * - * This list-traversal primitive may safely run concurrently with - * the _rcu list-mutation primitives such as list_add_rcu() - * as long as the traversal is guarded by rcu_read_lock(). - */ -#define list_for_each_rcu(pos, head) \ - for (pos = (head)->next; \ - prefetch(rcu_dereference(pos)->next), pos != (head); \ - pos = pos->next) - -#define __list_for_each_rcu(pos, head) \ - for (pos = (head)->next; \ - rcu_dereference(pos) != (head); \ - pos = pos->next) - -/** - * list_for_each_safe_rcu - iterate over an rcu-protected list safe - * against removal of list entry - * @pos: the &struct list_head to use as a loop counter. - * @n: another &struct list_head to use as temporary storage - * @head: the head for your list. - * - * This list-traversal primitive may safely run concurrently with - * the _rcu list-mutation primitives such as list_add_rcu() - * as long as the traversal is guarded by rcu_read_lock(). - */ -#define list_for_each_safe_rcu(pos, n, head) \ - for (pos = (head)->next; \ - n = rcu_dereference(pos)->next, pos != (head); \ - pos = n) - -/** - * list_for_each_entry_rcu - iterate over rcu list of given type - * @pos: the type * to use as a loop counter. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - * - * This list-traversal primitive may safely run concurrently with - * the _rcu list-mutation primitives such as list_add_rcu() - * as long as the traversal is guarded by rcu_read_lock(). - */ -#define list_for_each_entry_rcu(pos, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member); \ - prefetch(rcu_dereference(pos)->member.next), \ - &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) - - -/** - * list_for_each_continue_rcu - iterate over an rcu-protected list - * continuing after existing point. - * @pos: the &struct list_head to use as a loop counter. - * @head: the head for your list. - * - * This list-traversal primitive may safely run concurrently with - * the _rcu list-mutation primitives such as list_add_rcu() - * as long as the traversal is guarded by rcu_read_lock(). - */ -#define list_for_each_continue_rcu(pos, head) \ - for ((pos) = (pos)->next; \ - prefetch(rcu_dereference((pos))->next), (pos) != (head); \ - (pos) = (pos)->next) - -/* - * Double linked lists with a single pointer list head. - * Mostly useful for hash tables where the two pointer list head is - * too wasteful. - * You lose the ability to access the tail in O(1). - */ - -struct hlist_head { - struct hlist_node *first; -}; - -struct hlist_node { - struct hlist_node *next, **pprev; -}; - -#define HLIST_HEAD_INIT { .first = NULL } -#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL } -#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL) -static inline void INIT_HLIST_NODE(struct hlist_node *h) -{ - h->next = NULL; - h->pprev = NULL; -} - -static inline int hlist_unhashed(const struct hlist_node *h) -{ - return !h->pprev; -} - -static inline int hlist_empty(const struct hlist_head *h) -{ - return !h->first; -} - -static inline void __hlist_del(struct hlist_node *n) -{ - struct hlist_node *next = n->next; - struct hlist_node **pprev = n->pprev; - *pprev = next; - if (next) - next->pprev = pprev; -} - -static inline void hlist_del(struct hlist_node *n) -{ - __hlist_del(n); - n->next = LIST_POISON1; - n->pprev = LIST_POISON2; -} - -/** - * hlist_del_rcu - deletes entry from hash list without re-initialization - * @n: the element to delete from the hash list. - * - * Note: list_unhashed() on entry does not return true after this, - * the entry is in an undefined state. It is useful for RCU based - * lockfree traversal. - * - * In particular, it means that we can not poison the forward - * pointers that may still be used for walking the hash list. - * - * The caller must take whatever precautions are necessary - * (such as holding appropriate locks) to avoid racing - * with another list-mutation primitive, such as hlist_add_head_rcu() - * or hlist_del_rcu(), running on this same list. - * However, it is perfectly legal to run concurrently with - * the _rcu list-traversal primitives, such as - * hlist_for_each_entry(). - */ -static inline void hlist_del_rcu(struct hlist_node *n) -{ - __hlist_del(n); - n->pprev = LIST_POISON2; -} - -static inline void hlist_del_init(struct hlist_node *n) -{ - if (!hlist_unhashed(n)) { - __hlist_del(n); - INIT_HLIST_NODE(n); - } -} - -/* - * hlist_replace_rcu - replace old entry by new one - * @old : the element to be replaced - * @new : the new element to insert - * - * The old entry will be replaced with the new entry atomically. - */ -static inline void hlist_replace_rcu(struct hlist_node *old, - struct hlist_node *new) -{ - struct hlist_node *next = old->next; - - new->next = next; - new->pprev = old->pprev; -// smp_wmb(); - if (next) - new->next->pprev = &new->next; - *new->pprev = new; - old->pprev = LIST_POISON2; -} - -static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) -{ - struct hlist_node *first = h->first; - n->next = first; - if (first) - first->pprev = &n->next; - h->first = n; - n->pprev = &h->first; -} - - -/** - * hlist_add_head_rcu - adds the specified element to the specified hlist, - * while permitting racing traversals. - * @n: the element to add to the hash list. - * @h: the list to add to. - * - * The caller must take whatever precautions are necessary - * (such as holding appropriate locks) to avoid racing - * with another list-mutation primitive, such as hlist_add_head_rcu() - * or hlist_del_rcu(), running on this same list. - * However, it is perfectly legal to run concurrently with - * the _rcu list-traversal primitives, such as - * hlist_for_each_entry_rcu(), used to prevent memory-consistency - * problems on Alpha CPUs. Regardless of the type of CPU, the - * list-traversal primitive must be guarded by rcu_read_lock(). - */ -static inline void hlist_add_head_rcu(struct hlist_node *n, - struct hlist_head *h) -{ - struct hlist_node *first = h->first; - n->next = first; - n->pprev = &h->first; -// smp_wmb(); - if (first) - first->pprev = &n->next; - h->first = n; -} - -/* next must be != NULL */ -static inline void hlist_add_before(struct hlist_node *n, - struct hlist_node *next) -{ - n->pprev = next->pprev; - n->next = next; - next->pprev = &n->next; - *(n->pprev) = n; -} - -static inline void hlist_add_after(struct hlist_node *n, - struct hlist_node *next) -{ - next->next = n->next; - n->next = next; - next->pprev = &n->next; - - if(next->next) - next->next->pprev = &next->next; -} - -/** - * hlist_add_before_rcu - adds the specified element to the specified hlist - * before the specified node while permitting racing traversals. - * @n: the new element to add to the hash list. - * @next: the existing element to add the new element before. - * - * The caller must take whatever precautions are necessary - * (such as holding appropriate locks) to avoid racing - * with another list-mutation primitive, such as hlist_add_head_rcu() - * or hlist_del_rcu(), running on this same list. - * However, it is perfectly legal to run concurrently with - * the _rcu list-traversal primitives, such as - * hlist_for_each_entry_rcu(), used to prevent memory-consistency - * problems on Alpha CPUs. - */ -static inline void hlist_add_before_rcu(struct hlist_node *n, - struct hlist_node *next) -{ - n->pprev = next->pprev; - n->next = next; -// smp_wmb(); - next->pprev = &n->next; - *(n->pprev) = n; -} - -/** - * hlist_add_after_rcu - adds the specified element to the specified hlist - * after the specified node while permitting racing traversals. - * @prev: the existing element to add the new element after. - * @n: the new element to add to the hash list. - * - * The caller must take whatever precautions are necessary - * (such as holding appropriate locks) to avoid racing - * with another list-mutation primitive, such as hlist_add_head_rcu() - * or hlist_del_rcu(), running on this same list. - * However, it is perfectly legal to run concurrently with - * the _rcu list-traversal primitives, such as - * hlist_for_each_entry_rcu(), used to prevent memory-consistency - * problems on Alpha CPUs. - */ -static inline void hlist_add_after_rcu(struct hlist_node *prev, - struct hlist_node *n) -{ - n->next = prev->next; - n->pprev = &prev->next; -// smp_wmb(); - prev->next = n; - if (n->next) - n->next->pprev = &n->next; -} - -#define hlist_entry(ptr, type, member) container_of(ptr,type,member) - -#define hlist_for_each(pos, head) \ - for (pos = (head)->first; pos && ({ prefetch(pos->next); 1; }); \ - pos = pos->next) - -#define hlist_for_each_safe(pos, n, head) \ - for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \ - pos = n) - -/** - * hlist_for_each_entry - iterate over list of given type - * @tpos: the type * to use as a loop counter. - * @pos: the &struct hlist_node to use as a loop counter. - * @head: the head for your list. - * @member: the name of the hlist_node within the struct. - */ -#define hlist_for_each_entry(tpos, pos, head, member) \ - for (pos = (head)->first; \ - pos && ({ prefetch(pos->next); 1;}) && \ - ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ - pos = pos->next) - -/** - * hlist_for_each_entry_continue - iterate over a hlist continuing after existing point - * @tpos: the type * to use as a loop counter. - * @pos: the &struct hlist_node to use as a loop counter. - * @member: the name of the hlist_node within the struct. - */ -#define hlist_for_each_entry_continue(tpos, pos, member) \ - for (pos = (pos)->next; \ - pos && ({ prefetch(pos->next); 1;}) && \ - ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ - pos = pos->next) - -/** - * hlist_for_each_entry_from - iterate over a hlist continuing from existing point - * @tpos: the type * to use as a loop counter. - * @pos: the &struct hlist_node to use as a loop counter. - * @member: the name of the hlist_node within the struct. - */ -#define hlist_for_each_entry_from(tpos, pos, member) \ - for (; pos && ({ prefetch(pos->next); 1;}) && \ - ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ - pos = pos->next) - -/** - * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry - * @tpos: the type * to use as a loop counter. - * @pos: the &struct hlist_node to use as a loop counter. - * @n: another &struct hlist_node to use as temporary storage - * @head: the head for your list. - * @member: the name of the hlist_node within the struct. - */ -#define hlist_for_each_entry_safe(tpos, pos, n, head, member) \ - for (pos = (head)->first; \ - pos && ({ n = pos->next; 1; }) && \ - ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ - pos = n) - -/** - * hlist_for_each_entry_rcu - iterate over rcu list of given type - * @tpos: the type * to use as a loop counter. - * @pos: the &struct hlist_node to use as a loop counter. - * @head: the head for your list. - * @member: the name of the hlist_node within the struct. - * - * This list-traversal primitive may safely run concurrently with - * the _rcu list-mutation primitives such as hlist_add_head_rcu() - * as long as the traversal is guarded by rcu_read_lock(). - */ -#define hlist_for_each_entry_rcu(tpos, pos, head, member) \ - for (pos = (head)->first; \ - rcu_dereference(pos) && ({ prefetch(pos->next); 1;}) && \ - ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ - pos = pos->next) - -#endif - -/** - * __list_sort - sort the list using given comparator with merge-sort algorithm - * @head: is a head of the list to be sorted - * @member_offset: is machine offset inside the list entry structure to the - * field of type struct list_head which links that entry with - * the list. - */ -extern void __list_sort(struct list_head * head, - int member_offset, - int (*comparator)(void*,void*)); - -/** - * list_sort - wrapper for __list_sort - * @head: is a head of the list to be sorted - * @type: is the type of list entry - * @member: is the name of the field inside entry that links that entry with - * other entries in the list. - * @comaprator: function comparing two entries, should return value lesser - * than 0 when the first argument is lesser than the second one. - */ -#define list_sort(head,type,member,comparator) \ - ({ \ - __list_sort(head, \ - offsetof(type, member), \ - (int (*)(void*, void*)) comparator); \ - }) - -void test_list_sort(void); diff --git a/tools/alsa_midi/port.c b/tools/alsa_midi/port.c deleted file mode 100644 index fd35864..0000000 --- a/tools/alsa_midi/port.c +++ /dev/null @@ -1,217 +0,0 @@ -/* - * ALSA SEQ < - > JACK MIDI bridge - * - * Copyright (c) 2006,2007 Dmitry S. Baikov - * Copyright (c) 2007,2008,2009 Nedko Arnaudov - * Copyright (c) 2009,2010 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; version 2 of the License. - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include - -#include "list.h" -#include "a2j.h" -#include "port_hash.h" -#include "port.h" - -/* This should be part of JACK API */ -#define JACK_IS_VALID_PORT_NAME_CHAR(c) \ - (isalnum(c) || \ - (c) == '/' || \ - (c) == '_' || \ - (c) == '(' || \ - (c) == ')' || \ - (c) == '-' || \ - (c) == '[' || \ - (c) == ']') - -static -int -a2j_alsa_connect_from (struct a2j * self, int client, int port) -{ - snd_seq_port_subscribe_t* sub; - snd_seq_addr_t seq_addr; - int err; - - snd_seq_port_subscribe_alloca (&sub); - seq_addr.client = client; - seq_addr.port = port; - snd_seq_port_subscribe_set_sender (sub, &seq_addr); - seq_addr.client = self->client_id; - seq_addr.port = self->port_id; - snd_seq_port_subscribe_set_dest (sub, &seq_addr); - - snd_seq_port_subscribe_set_time_update (sub, 1); - snd_seq_port_subscribe_set_queue (sub, self->queue); - snd_seq_port_subscribe_set_time_real (sub, 1); - - if ((err = snd_seq_subscribe_port (self->seq, sub))) { - a2j_error ("can't subscribe to %d:%d - %s", client, port, snd_strerror(err)); - } - - return err; -} - -void -a2j_port_setdead (a2j_port_hash_t hash, snd_seq_addr_t addr) -{ - struct a2j_port *port = a2j_port_get(hash, addr); - - if (port) { - port->is_dead = true; // see jack_process_internal - } else { - a2j_debug("port_setdead: not found (%d:%d)", addr.client, addr.port); - } -} - -void -a2j_port_free (struct a2j_port * port) -{ - // snd_seq_disconnect_from (self->seq, self->port_id, port->remote.client, port->remote.port); - // snd_seq_disconnect_to (self->seq, self->port_id, port->remote.client, port->remote.port); - - if (port->inbound_events) { - jack_ringbuffer_free (port->inbound_events); - } - - if (port->jack_port != JACK_INVALID_PORT && !port->a2j_ptr->finishing) { - jack_port_unregister (port->a2j_ptr->jack_client, port->jack_port); - } - - free (port); -} - -void -a2j_port_fill_name (struct a2j_port * port_ptr, int dir, snd_seq_client_info_t * client_info_ptr, - const snd_seq_port_info_t * port_info_ptr, bool make_unique) -{ - char *c; - - if (make_unique) { - snprintf (port_ptr->name, - sizeof(port_ptr->name), - "%s [%d] %s %s", - snd_seq_client_info_get_name(client_info_ptr), - snd_seq_client_info_get_client(client_info_ptr), - snd_seq_port_info_get_name(port_info_ptr), - (dir == A2J_PORT_CAPTURE ? "in" : "out")); - } else { - snprintf (port_ptr->name, - sizeof(port_ptr->name), - "%s %s %s", - snd_seq_client_info_get_name(client_info_ptr), - snd_seq_port_info_get_name(port_info_ptr), - (dir == A2J_PORT_CAPTURE ? "in" : "out")); - } - - // replace all offending characters with ' ' - for (c = port_ptr->name; *c; ++c) { - if (!JACK_IS_VALID_PORT_NAME_CHAR(*c)) { - *c = ' '; - } - } -} - -struct a2j_port * -a2j_port_create (struct a2j * self, int dir, snd_seq_addr_t addr, const snd_seq_port_info_t * info) -{ - struct a2j_port *port; - int err; - int client; - snd_seq_client_info_t * client_info_ptr; - int jack_caps; - struct a2j_stream * stream_ptr; - - stream_ptr = &self->stream[dir]; - - if ((err = snd_seq_client_info_malloc (&client_info_ptr)) != 0) { - a2j_error("Failed to allocate client info"); - goto fail; - } - - client = snd_seq_port_info_get_client (info); - - err = snd_seq_get_any_client_info (self->seq, client, client_info_ptr); - if (err != 0) { - a2j_error("Failed to get client info"); - goto fail_free_client_info; - } - - a2j_debug ("client name: '%s'", snd_seq_client_info_get_name(client_info_ptr)); - a2j_debug ("port name: '%s'", snd_seq_port_info_get_name(info)); - - port = calloc (1, sizeof(struct a2j_port)); - if (!port) { - goto fail_free_client_info; - } - - port->a2j_ptr = self; - port->jack_port = JACK_INVALID_PORT; - port->remote = addr; - - a2j_port_fill_name (port, dir, client_info_ptr, info, false); - - /* Add port to list early, before registering to JACK, so map functionality is guaranteed to work during port registration */ - list_add_tail (&port->siblings, &stream_ptr->list); - - if (dir == A2J_PORT_CAPTURE) { - jack_caps = JackPortIsOutput; - } else { - jack_caps = JackPortIsInput; - } - - /* mark anything that looks like a hardware port as physical&terminal */ - if (snd_seq_port_info_get_type (info) & (SND_SEQ_PORT_TYPE_HARDWARE|SND_SEQ_PORT_TYPE_PORT|SND_SEQ_PORT_TYPE_SPECIFIC)) { - jack_caps |= JackPortIsPhysical|JackPortIsTerminal; - } - - port->jack_port = jack_port_register (self->jack_client, port->name, JACK_DEFAULT_MIDI_TYPE, jack_caps, 0); - if (port->jack_port == JACK_INVALID_PORT) { - a2j_error("jack_port_register() failed for '%s'", port->name); - goto fail_free_port; - } - - if (dir == A2J_PORT_CAPTURE) { - err = a2j_alsa_connect_from (self, port->remote.client, port->remote.port); - } else { - err = snd_seq_connect_to (self->seq, self->port_id, port->remote.client, port->remote.port); - } - - if (err) { - a2j_info("port skipped: %s", port->name); - goto fail_free_port; - } - - port->inbound_events = jack_ringbuffer_create(MAX_EVENT_SIZE*16); - - a2j_info("port created: %s", port->name); - return port; - - fail_free_port: - list_del (&port->siblings); - - a2j_port_free (port); - - fail_free_client_info: - snd_seq_client_info_free (client_info_ptr); - - fail: - return NULL; -} diff --git a/tools/alsa_midi/port.h b/tools/alsa_midi/port.h deleted file mode 100644 index 07169a3..0000000 --- a/tools/alsa_midi/port.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -*- Mode: C ; c-basic-offset: 2 -*- */ -/* - * ALSA SEQ < - > JACK MIDI bridge - * - * Copyright (c) 2006,2007 Dmitry S. Baikov - * Copyright (c) 2007,2008,2009 Nedko Arnaudov - * - * 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; version 2 of the License. - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef PORT_H__757ADD0F_5E53_41F7_8B7F_8119C5E8A9F1__INCLUDED -#define PORT_H__757ADD0F_5E53_41F7_8B7F_8119C5E8A9F1__INCLUDED - -struct a2j_port* a2j_port_create (struct a2j * self, int dir, snd_seq_addr_t addr, const snd_seq_port_info_t * info); -void a2j_port_setdead (a2j_port_hash_t hash, snd_seq_addr_t addr); -void a2j_port_free (struct a2j_port * port); - -#endif /* #ifndef PORT_H__757ADD0F_5E53_41F7_8B7F_8119C5E8A9F1__INCLUDED */ diff --git a/tools/alsa_midi/port_hash.c b/tools/alsa_midi/port_hash.c deleted file mode 100644 index cc9c5c6..0000000 --- a/tools/alsa_midi/port_hash.c +++ /dev/null @@ -1,63 +0,0 @@ -/* -*- Mode: C ; c-basic-offset: 2 -*- */ -/* - * ALSA SEQ < - > JACK MIDI bridge - * - * Copyright (c) 2006,2007 Dmitry S. Baikov - * Copyright (c) 2007,2008,2009 Nedko Arnaudov - * - * 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; version 2 of the License. - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include - -#include "list.h" -#include "a2j.h" -#include "port_hash.h" - -static inline -int -a2j_port_hash( - snd_seq_addr_t addr) -{ - return (addr.client + addr.port) % PORT_HASH_SIZE; -} - -struct a2j_port * -a2j_port_get( - a2j_port_hash_t hash, - snd_seq_addr_t addr) -{ - struct a2j_port **pport = &hash[a2j_port_hash(addr)]; - while (*pport) { - struct a2j_port *port = *pport; - if (port->remote.client == addr.client && port->remote.port == addr.port) - return port; - pport = &port->next; - } - return NULL; -} - -void -a2j_port_insert( - a2j_port_hash_t hash, - struct a2j_port * port) -{ - struct a2j_port **pport = &hash[a2j_port_hash(port->remote)]; - port->next = *pport; - *pport = port; -} diff --git a/tools/alsa_midi/port_hash.h b/tools/alsa_midi/port_hash.h deleted file mode 100644 index ec21f11..0000000 --- a/tools/alsa_midi/port_hash.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -*- Mode: C ; c-basic-offset: 2 -*- */ -/* - * ALSA SEQ < - > JACK MIDI bridge - * - * Copyright (c) 2006,2007 Dmitry S. Baikov - * Copyright (c) 2007,2008,2009 Nedko Arnaudov - * - * 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; version 2 of the License. - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef PORT_HASH_H__A44CBCD6_E075_49CB_8F73_DF9772511D55__INCLUDED -#define PORT_HASH_H__A44CBCD6_E075_49CB_8F73_DF9772511D55__INCLUDED - -void -a2j_port_insert( - a2j_port_hash_t hash, - struct a2j_port * port); - -struct a2j_port * -a2j_port_get( - a2j_port_hash_t hash, - snd_seq_addr_t addr); - -#endif /* #ifndef PORT_HASH_H__A44CBCD6_E075_49CB_8F73_DF9772511D55__INCLUDED */ diff --git a/tools/alsa_midi/port_thread.c b/tools/alsa_midi/port_thread.c deleted file mode 100644 index 98df0e2..0000000 --- a/tools/alsa_midi/port_thread.c +++ /dev/null @@ -1,235 +0,0 @@ -/* -*- Mode: C ; c-basic-offset: 2 -*- */ -/* - * ALSA SEQ < - > JACK MIDI bridge - * - * Copyright (c) 2006,2007 Dmitry S. Baikov - * Copyright (c) 2007,2008,2009 Nedko Arnaudov - * - * 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; version 2 of the License. - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include - -#include "list.h" -#include "a2j.h" -#include "port.h" -#include "port_hash.h" -#include "port_thread.h" - -struct a2j_port * -a2j_find_port_by_addr( - struct a2j_stream * stream_ptr, - snd_seq_addr_t addr) -{ - struct list_head * node_ptr; - struct a2j_port * port_ptr; - - list_for_each(node_ptr, &stream_ptr->list) - { - port_ptr = list_entry(node_ptr, struct a2j_port, siblings); - if (port_ptr->remote.client == addr.client && port_ptr->remote.port == addr.port) - { - return port_ptr; - } - } - - return NULL; -} - -struct a2j_port * -a2j_find_port_by_jack_port_name( - struct a2j_stream * stream_ptr, - const char * jack_port) -{ - struct list_head * node_ptr; - struct a2j_port * port_ptr; - - list_for_each(node_ptr, &stream_ptr->list) - { - port_ptr = list_entry(node_ptr, struct a2j_port, siblings); - if (strcmp(port_ptr->name, jack_port) == 0) - { - return port_ptr; - } - } - - return NULL; -} - -/* - * ==================== Port add/del handling thread ============================== - */ - -static -void -a2j_update_port_type (struct a2j * self, int dir, snd_seq_addr_t addr, int caps, const snd_seq_port_info_t * info) -{ - struct a2j_stream * stream_ptr; - int alsa_mask; - struct a2j_port * port_ptr; - - a2j_debug("update_port_type(%d:%d)", addr.client, addr.port); - - stream_ptr = &self->stream[dir]; - port_ptr = a2j_find_port_by_addr(stream_ptr, addr); - - if (dir == A2J_PORT_CAPTURE) { - alsa_mask = SND_SEQ_PORT_CAP_SUBS_READ; - } else { - alsa_mask = SND_SEQ_PORT_CAP_SUBS_WRITE; - } - - if (port_ptr != NULL && (caps & alsa_mask) != alsa_mask) { - a2j_debug("setdead: %s", port_ptr->name); - port_ptr->is_dead = true; - } - - if (port_ptr == NULL && (caps & alsa_mask) == alsa_mask) { - if(jack_ringbuffer_write_space(stream_ptr->new_ports) >= sizeof(port_ptr)) { - port_ptr = a2j_port_create (self, dir, addr, info); - if (port_ptr != NULL) { - jack_ringbuffer_write(stream_ptr->new_ports, (char *)&port_ptr, sizeof(port_ptr)); - } - } else { - a2j_error( "dropping new port event... increase MAX_PORTS" ); - } - } -} - -void -a2j_update_port (struct a2j * self, snd_seq_addr_t addr, const snd_seq_port_info_t * info) -{ - unsigned int port_caps = snd_seq_port_info_get_capability(info); - unsigned int port_type = snd_seq_port_info_get_type(info); - - a2j_debug("port %u:%u", addr.client, addr.port); - a2j_debug("port type: 0x%08X", port_type); - a2j_debug("port caps: 0x%08X", port_caps); - - if (port_type & SND_SEQ_PORT_TYPE_SPECIFIC) { - a2j_debug("SPECIFIC"); - } - - if (port_type & SND_SEQ_PORT_TYPE_MIDI_GENERIC) { - a2j_debug("MIDI_GENERIC"); - } - - if (port_type & SND_SEQ_PORT_TYPE_MIDI_GM) { - a2j_debug("MIDI_GM"); - } - - if (port_type & SND_SEQ_PORT_TYPE_MIDI_GS) { - a2j_debug("MIDI_GS"); - } - - if (port_type & SND_SEQ_PORT_TYPE_MIDI_XG) { - a2j_debug("MIDI_XG"); - } - - if (port_type & SND_SEQ_PORT_TYPE_MIDI_MT32) { - a2j_debug("MIDI_MT32"); - } - - if (port_type & SND_SEQ_PORT_TYPE_MIDI_GM2) { - a2j_debug("MIDI_GM2"); - } - - if (port_type & SND_SEQ_PORT_TYPE_SYNTH) { - a2j_debug("SYNTH"); - } - - if (port_type & SND_SEQ_PORT_TYPE_DIRECT_SAMPLE) { - a2j_debug("DIRECT_SAMPLE"); - } - - if (port_type & SND_SEQ_PORT_TYPE_SAMPLE) { - a2j_debug("SAMPLE"); - } - - if (port_type & SND_SEQ_PORT_TYPE_HARDWARE) { - a2j_debug("HARDWARE"); - } - - if (port_type & SND_SEQ_PORT_TYPE_SOFTWARE) { - a2j_debug("SOFTWARE"); - } - - if (port_type & SND_SEQ_PORT_TYPE_SYNTHESIZER) { - a2j_debug("SYNTHESIZER"); - } - - if (port_type & SND_SEQ_PORT_TYPE_PORT) { - a2j_debug("PORT"); - } - - if (port_type & SND_SEQ_PORT_TYPE_APPLICATION) { - a2j_debug("APPLICATION"); - } - - if (port_type == 0) { - a2j_debug("Ignoring port of type 0"); - return; - } - - if (port_caps & SND_SEQ_PORT_CAP_NO_EXPORT) { - a2j_debug("Ignoring no-export port"); - return; - } - - a2j_update_port_type (self, A2J_PORT_CAPTURE, addr, port_caps, info); - a2j_update_port_type (self, A2J_PORT_PLAYBACK, addr, port_caps, info); -} - -void -a2j_free_ports (jack_ringbuffer_t * ports) -{ - struct a2j_port *port; - int sz; - - while ((sz = jack_ringbuffer_read (ports, (char*)&port, sizeof(port)))) { - assert (sz == sizeof(port)); - a2j_info("port deleted: %s", port->name); - list_del (&port->siblings); - a2j_port_free(port); - } -} - -void -a2j_update_ports (struct a2j * self) -{ - snd_seq_addr_t addr; - int size; - - while ((size = jack_ringbuffer_read(self->port_add, (char *)&addr, sizeof(addr))) != 0) { - - snd_seq_port_info_t * info; - int err; - - snd_seq_port_info_alloca(&info); - - assert (size == sizeof(addr)); - assert (addr.client != self->client_id); - - if ((err = snd_seq_get_any_port_info(self->seq, addr.client, addr.port, info)) >= 0) { - a2j_update_port(self, addr, info); - } else { - a2j_port_setdead(self->stream[A2J_PORT_CAPTURE].port_hash, addr); - a2j_port_setdead(self->stream[A2J_PORT_PLAYBACK].port_hash, addr); - } - } -} diff --git a/tools/alsa_midi/port_thread.h b/tools/alsa_midi/port_thread.h deleted file mode 100644 index e69af7f..0000000 --- a/tools/alsa_midi/port_thread.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -*- Mode: C ; c-basic-offset: 2 -*- */ -/* - * ALSA SEQ < - > JACK MIDI bridge - * - * Copyright (c) 2006,2007 Dmitry S. Baikov - * Copyright (c) 2007,2008,2009 Nedko Arnaudov - * - * 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; version 2 of the License. - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef PORT_THREAD_H__1C6B5065_5556_4AC6_AA9F_44C32A9648C6__INCLUDED -#define PORT_THREAD_H__1C6B5065_5556_4AC6_AA9F_44C32A9648C6__INCLUDED - -void -a2j_update_port( - struct a2j * self, - snd_seq_addr_t addr, - const snd_seq_port_info_t * info); - -void -a2j_update_ports( - struct a2j * self); - -void -a2j_free_ports( - jack_ringbuffer_t * ports); - -struct a2j_port * -a2j_find_port_by_addr( - struct a2j_stream * stream_ptr, - snd_seq_addr_t addr); - -struct a2j_port * -a2j_find_port_by_jack_port_name( - struct a2j_stream * stream_ptr, - const char * jack_port); - -#endif /* #ifndef PORT_THREAD_H__1C6B5065_5556_4AC6_AA9F_44C32A9648C6__INCLUDED */ diff --git a/tools/alsa_out.c b/tools/alsa_out.c deleted file mode 100644 index be25e40..0000000 --- a/tools/alsa_out.c +++ /dev/null @@ -1,803 +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 -#include -#include -#include -#include -#include - -#include - -#include -#include -#include "memops.h" - -#include "alsa/asoundlib.h" - -#include - -// 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; - -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_d24_sS, sample_move_dS_s24, "24bit" }, - { SND_PCM_FORMAT_S16, 2, sample_move_d16_sS, sample_move_dS_s16, "16bit" } -}; -#define NUMFORMATS (sizeof(formats)/sizeof(formats[0])) -int format=0; - -// Alsa stuff... i dont 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 == -EAGAIN) { - 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 ) -{ - int i; - int err; - - for( i=0; i (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 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 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 = target_delay; - - 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 - client name\n" - " -d \n" - " -c \n" - " -p \n" - " -n \n" - " -r \n" - " -q \n" - " -t \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"; - - 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:")) != -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 ':': - 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, 0, 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); - - 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 target_delay ) { - fprintf( stderr, "target_delay (%d) cant 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) cant 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 3fb7e7b..0000000 --- a/tools/bufsize.c +++ /dev/null @@ -1,125 +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 -#include -#include -#include -#include -#include -#include -#include - -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 \n", package); - exit(9); - } - - if (strspn (argv[1], "0123456789") != strlen (argv[1])) { - fprintf(stderr, "usage: %s \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, JackNullOption, NULL)) == 0) { - fprintf(stderr, "JACK server not running?\n"); - exit(1); - } - - signal(SIGQUIT, signal_handler); - signal(SIGTERM, signal_handler); - signal(SIGHUP, 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 327a91c..0000000 --- a/tools/connect.c +++ /dev/null @@ -1,225 +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 -#include -#include -#include -#include -#include - -#include - -#include -#include - -#define TRUE 1 -#define FALSE 0 - -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 Connect to the jack server named \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)); - 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; - } - - /* 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; - } - - /* 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))) { - goto exit; - } - } - if (disconnecting) { - if (jack_disconnect(client, jack_port_name(src_port), jack_port_name(dst_port))) { - goto exit; - } - } - - /* 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 82b583f..0000000 --- a/tools/evmon.c +++ /dev/null @@ -1,131 +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 -#include -#include -#include -#include - -#include -#include -#include - -void -port_callback (jack_port_id_t port, int yn, void* arg) -{ - printf ("Port %d %s\n", port, (yn ? "registered" : "unregistered")); -} - -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")); -} - -void -client_callback (const char* client, int yn, void* arg) -{ - printf ("Client %s %s\n", client, (yn ? "registered" : "unregistered")); -} - -int -graph_callback (void* arg) -{ - printf ("Graph reordered\n"); - return 0; -} - -void -propchange (jack_uuid_t subject, const char* key, jack_property_change_t change) -{ - 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_client_t *client; - jack_options_t options = JackNullOption; - jack_status_t status; - - if ((client = jack_client_open ("event-monitor", options, &status, NULL)) == 0) { - fprintf (stderr, "jack_client_open() failed, " - "status = 0x%2.0x\n", status); - if (status & JackServerFailed) { - fprintf (stderr, "Unable to connect to JACK server\n"); - } - return 1; - } - - if (jack_set_port_registration_callback (client, port_callback, NULL)) { - fprintf (stderr, "cannot set port registration callback\n"); - return 1; - } - if (jack_set_port_connect_callback (client, connect_callback, NULL)) { - fprintf (stderr, "cannot set port connect callback\n"); - return 1; - } - if (jack_set_client_registration_callback (client, client_callback, NULL)) { - fprintf (stderr, "cannot set client registration callback\n"); - return 1; - } - if (jack_set_graph_order_callback (client, graph_callback, NULL)) { - fprintf (stderr, "cannot set graph order registration callback\n"); - return 1; - } - if (jack_set_property_change_callback (client, (JackPropertyChangeCallback) propchange, 0)) { - fprintf (stderr, "cannot set property change callback\n"); - return 1; - } - if (jack_activate (client)) { - fprintf (stderr, "cannot activate client"); - return 1; - } - - sleep (-1); - exit (0); -} - diff --git a/tools/freewheel.c b/tools/freewheel.c deleted file mode 100644 index f8a38fe..0000000 --- a/tools/freewheel.c +++ /dev/null @@ -1,86 +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 -#include -#include -#include -#include -#include -#include -#include - -char *package; /* program name */ -jack_client_t *client; -int onoff; - -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[]) -{ - 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); - } - - signal (SIGQUIT, signal_handler); - signal (SIGTERM, signal_handler); - signal (SIGHUP, 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/iodelay.c b/tools/iodelay.c deleted file mode 100644 index 1384e52..0000000 --- a/tools/iodelay.c +++ /dev/null @@ -1,269 +0,0 @@ -/* - Copyright (C) 2003-2008 Fons Adriaensen - - 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 -#include -#include -#include -#include - -struct Freq -{ - int p; - int f; - float xa; - float ya; - float x1; - float y1; - float x2; - float y2; -}; - - -struct MTDM -{ - double _del; - double _err; - float _wlp; - int _cnt; - int _inv; - - struct Freq _freq [13]; -}; - - -struct MTDM * mtdm_new (double fsamp) -{ - int i; - struct Freq *F; - - struct MTDM *retval = malloc( sizeof(struct MTDM) ); - - if (retval==NULL) - return NULL; - - retval->_cnt = 0; - retval->_inv = 0; - - retval->_freq [0].f = 4096; - retval->_freq [1].f = 2048; - retval->_freq [2].f = 3072; - retval->_freq [3].f = 2560; - retval->_freq [4].f = 2304; - retval->_freq [5].f = 2176; - retval->_freq [6].f = 1088; - retval->_freq [7].f = 1312; - retval->_freq [8].f = 1552; - retval->_freq [9].f = 1800; - retval->_freq [10].f = 3332; - retval->_freq [11].f = 3586; - retval->_freq [12].f = 3841; - retval->_wlp = 200.0f / fsamp; - for (i = 0, F = retval->_freq; i < 13; i++, F++) { - F->p = 128; - F->xa = F->ya = 0.0f; - F->x1 = F->y1 = 0.0f; - F->x2 = F->y2 = 0.0f; - } - - return retval; -} - -int mtdm_process (struct MTDM *self, size_t len, float *ip, float *op) -{ - int i; - float vip, vop, a, c, s; - struct Freq *F; - - while (len--) - { - vop = 0.0f; - vip = *ip++; - for (i = 0, F = self->_freq; i < 13; i++, F++) - { - a = 2 * (float) M_PI * (F->p & 65535) / 65536.0; - F->p += F->f; - c = cosf (a); - s = -sinf (a); - vop += (i ? 0.01f : 0.20f) * s; - F->xa += s * vip; - F->ya += c * vip; - } - *op++ = vop; - if (++self->_cnt == 16) - { - for (i = 0, F = self->_freq; i < 13; i++, F++) - { - F->x1 += self->_wlp * (F->xa - F->x1 + 1e-20); - F->y1 += self->_wlp * (F->ya - F->y1 + 1e-20); - F->x2 += self->_wlp * (F->x1 - F->x2 + 1e-20); - F->y2 += self->_wlp * (F->y1 - F->y2 + 1e-20); - F->xa = F->ya = 0.0f; - } - self->_cnt = 0; - } - } - - return 0; -} - -int mtdm_resolve (struct MTDM *self) -{ - int i, k, m; - double d, e, f0, p; - struct Freq *F = self->_freq; - - if (hypot (F->x2, F->y2) < 0.001) return -1; - d = atan2 (F->y2, F->x2) / (2 * M_PI); - if (self->_inv) d += 0.5; - if (d > 0.5) d -= 1.0; - f0 = self->_freq [0].f; - m = 1; - self->_err = 0.0; - for (i = 0; i < 12; i++) - { - F++; - p = atan2 (F->y2, F->x2) / (2 * M_PI) - d * F->f / f0; - if (self->_inv) p += 0.5; - p -= floor (p); - p *= 2; - k = (int)(floor (p + 0.5)); - e = fabs (p - k); - if (e > self->_err) self->_err = e; - if (e > 0.4) return 1; - d += m * (k & 1); - m *= 2; - } - self->_del = 16 * d; - - return 0; -} - -void mtdm_invert (struct MTDM *self) -{ - self->_inv ^= 1; -} -// -------------------------------------------------------------------------------- - -static struct MTDM *mtdm; -static jack_client_t *jack_handle; -static jack_port_t *jack_capt; -static jack_port_t *jack_play; - -jack_latency_range_t capture_latency = {-1, -1}; -jack_latency_range_t playback_latency = {-1, -1}; - -void -latency_cb (jack_latency_callback_mode_t mode, void *arg) -{ - jack_latency_range_t range; - - range.min = range.max = 0; - - if (mode == JackCaptureLatency) { - jack_port_set_latency_range (jack_play, mode, &range); - jack_port_get_latency_range (jack_capt, mode, &range); - if ((range.min != capture_latency.min) || (range.max != capture_latency.max)) { - capture_latency = range; - printf ("new capture latency: [%d, %d]\n", range.min, range.max); - } - } else { - jack_port_set_latency_range (jack_capt, mode, &range); - jack_port_get_latency_range (jack_play, mode, &range); - if ((range.min != playback_latency.min) || (range.max != playback_latency.max)) { - playback_latency = range; - printf ("new playback latency: [%d, %d]\n", range.min, range.max); - } - } - -} - -int jack_callback (jack_nframes_t nframes, void *arg) -{ - float *ip, *op; - - ip = (float *)(jack_port_get_buffer (jack_capt, nframes)); - op = (float *)(jack_port_get_buffer (jack_play, nframes)); - mtdm_process (mtdm, nframes, ip, op); - return 0; -} - -int main (int ac, char *av []) -{ - float t; - jack_status_t s; - - jack_handle = jack_client_open ("jack_delay", JackNoStartServer, &s); - if (jack_handle == 0) - { - fprintf (stderr, "Can't connect to Jack, is the server running ?\n"); - exit (1); - } - - mtdm = mtdm_new(jack_get_sample_rate(jack_handle)); - - jack_set_process_callback (jack_handle, jack_callback, 0); - - if (jack_set_latency_callback) - jack_set_latency_callback (jack_handle, latency_cb, 0); - - jack_capt = jack_port_register (jack_handle, "in", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); - jack_play = jack_port_register (jack_handle, "out", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); - - t = 1000.0f / jack_get_sample_rate (jack_handle); - - if (jack_activate (jack_handle)) - { - fprintf(stderr, "Can't activate Jack"); - return 1; - } - - while (1) - { - - #ifdef WIN32 - Sleep (250); - #else - usleep (250000); - #endif - if (mtdm_resolve (mtdm) < 0) printf ("Signal below threshold...\n"); - else - { - jack_nframes_t systemic_latency; - - if (mtdm->_err > 0.3) - { - mtdm_invert ( mtdm ); - mtdm_resolve ( mtdm ); - } - systemic_latency = (jack_nframes_t) floor (mtdm->_del - (capture_latency.max + playback_latency.max)); - - printf ("%10.3lf frames %10.3lf ms total roundtrip latency\n\textra loopback latency: %u frames\n\tuse %u for the backend arguments -I and -O", mtdm->_del, mtdm->_del * t, - systemic_latency, systemic_latency/2); - if (mtdm->_err > 0.2) printf (" ??"); - if (mtdm->_inv) printf (" Inv"); - printf ("\n"); - } - } - - return 0; -} - -// -------------------------------------------------------------------------------- diff --git a/tools/ipload.c b/tools/ipload.c deleted file mode 100644 index 5d8ad7e..0000000 --- a/tools/ipload.c +++ /dev/null @@ -1,171 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -jack_client_t *client; -jack_intclient_t intclient; -char *client_name; -char *intclient_name; -char *load_name; -char *load_init = NULL; -char *server_name = NULL; -int wait_opt = 0; - -void -signal_handler (int sig) -{ - 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"); - jack_client_close (client); - exit (0); -} - -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-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" - ); -} - -int -parse_args (int argc, char *argv[]) -{ - int c; - int option_index = 0; - char *short_options = "hi:s:w"; - struct option long_options[] = { - { "help", 0, 0, 'h' }, - { "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 'i': - load_init = optarg; - break; - case 's': - server_name = optarg; - break; - case 'w': - wait_opt = 1; - break; - case 'h': - default: - show_usage (); - return 1; - } - } - - 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; - - /* 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 */ - jack_internal_client_load (client, intclient_name, - (JackLoadName|JackLoadInit), - &status, intclient, load_name, load_init); - - if (status & JackFailure) { - fprintf (stderr, "could not load %s, status = 0x%2.0x\n", - load_name, 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); - - if (wait_opt) { - /* define a signal handler to unload the client, then - * wait for it to exit */ - signal (SIGQUIT, signal_handler); - signal (SIGTERM, signal_handler); - signal (SIGHUP, signal_handler); - signal (SIGINT, signal_handler); - - while (1) { - sleep (1); - } - } - - return 0; -} - - diff --git a/tools/ipunload.c b/tools/ipunload.c deleted file mode 100644 index 395904b..0000000 --- a/tools/ipunload.c +++ /dev/null @@ -1,78 +0,0 @@ -#include -#include -#include -#include -#include - -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]; - - if (jack_internal_client_handle (client, client_name, &status, intclient) != 0) { - 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); - } - - return 0; -} - - diff --git a/tools/load_test.c b/tools/load_test.c deleted file mode 100644 index 76d6d08..0000000 --- a/tools/load_test.c +++ /dev/null @@ -1,120 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include - -char * my_name; -jack_client_t *client; -unsigned int wait_timeout = 1000; - -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]\n", my_name); - fprintf (stderr, "this is a test client, which just sleeps in its process_cb to simulate cpu load\n"); - fprintf (stderr, "options:\n"); - fprintf (stderr, " -t, --timeout Wait timeout in seconds\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"); -} - -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 -process_cb (jack_nframes_t nframes, void *arg) -{ - jack_time_t now = jack_get_time(); - jack_time_t wait = now + wait_timeout; - - while (jack_get_time() < wait) ; - - return 0; -} - -int -main (int argc, char *argv[]) -{ - int c; - int option_index; - - struct option long_options[] = { - { "timeout", 1, 0, 't' }, - { "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, "t:hv", long_options, &option_index)) >= 0) { - switch (c) { - case 't': - wait_timeout = atoi(optarg); - break; - case 'h': - show_usage (); - return 1; - break; - case 'v': - show_version (); - return 1; - break; - default: - show_usage (); - return 1; - break; - } - } - - /* try to open server in a loop. breaking under certein conditions */ - - client = jack_client_open( "load_test", JackNullOption, NULL ); - - signal(SIGQUIT, signal_handler); - signal(SIGTERM, signal_handler); - signal(SIGHUP, signal_handler); - signal(SIGINT, signal_handler); - - jack_on_shutdown(client, jack_shutdown, 0); - - jack_set_process_callback( client, process_cb, NULL ); - - jack_activate (client); - - sleep( -1 ); - - exit (0); -} diff --git a/tools/lsp.c b/tools/lsp.c deleted file mode 100644 index f39af53..0000000 --- a/tools/lsp.c +++ /dev/null @@ -1,277 +0,0 @@ -#include -#include -#include -#include -#include - -#include - -#include -#include - -char * my_name; - -void -show_version (void) -{ - fprintf (stderr, "%s: JACK Audio Connection Kit version " VERSION "\n", - my_name); -} - -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 && strcmp(uuid, "-1") != 0) { - printf("%s%s\n", uuid, port_component ); - } else { - printf("%s\n",pname); - } - jack_free(uuid); -} - -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 Connect to the jack server named \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, --latency Display per-port latency in frames at each port\n"); - fprintf (stderr, " -L, --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. */ - client = jack_client_open ("lsp", options, &status, server_name); - 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; - } - - 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[64]; - jack_uuid_t uuid; - jack_port_uuid (port, uuid); - 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; - printf (" port latency = %" PRIu32 " frames\n", - jack_port_get_latency (port)); - - 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 = %" PRIu32 " 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 (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 8192628..0000000 --- a/tools/midi_dump.c +++ /dev/null @@ -1,114 +0,0 @@ -#include -#include -#include -#include -#include - -static jack_port_t* port; - -static void -describe (jack_midi_event_t* event, char* buffer, size_t buflen) -{ - assert (buflen > 0); - - buffer[0] = '\0'; - - if (event->size == 0) { - return; - } - - int type = event->buffer[0] & 0xf0; - int channel = event->buffer[0] & 0xf; - - switch (type) { - case 0x90: - assert (event->size == 3); - snprintf (buffer, buflen, "note on (channel %d): pitch %d, velocity %d", channel, event->buffer[1], event->buffer[2]); - break; - case 0x80: - assert (event->size == 3); - snprintf (buffer, buflen, "note off (channel %d): pitch %d, velocity %d", channel, event->buffer[1], event->buffer[2]); - break; - case 0xb0: - assert (event->size == 3); - snprintf (buffer, buflen, "control change (channel %d): controller %d, value %d", 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; - char description[256]; - - 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) { - size_t j; - - printf ("%d:", event.time); - for (j = 0; j < event.size; ++j) { - printf (" %x", event.buffer[j]); - } - - describe (&event, description, sizeof (description)); - printf (" %s", description); - - printf ("\n"); - } - } - - return 0; -} - - -int -main (int argc, char* argv[]) -{ - jack_client_t* client; - char const default_name[] = "midi-monitor"; - char const * client_name; - int r; - - if (argc == 2) { - client_name = argv[1]; - } 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); - } - - 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); - } - - r = jack_activate (client); - if (r != 0) { - fprintf (stderr, "Could not activate client.\n"); - exit (EXIT_FAILURE); - } - - sleep (-1); - - return 0; -} diff --git a/tools/monitor_client.c b/tools/monitor_client.c deleted file mode 100644 index d4a2e4d..0000000 --- a/tools/monitor_client.c +++ /dev/null @@ -1,46 +0,0 @@ -#include -#include -#include -#include - -#include - -#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; - } - sleep (30); - 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 9850550..0000000 --- a/tools/netsource.c +++ /dev/null @@ -1,783 +0,0 @@ -/* -NetJack Client - -Copyright (C) 2008 Marc-Olivier Barre -Copyright (C) 2008 Pieter Palmers -Copyright (C) 2006 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. - -*/ - -/** @file netsource.c - * - * @brief This client connects a remote slave JACK to a local JACK server assumed to be the master - */ - -#include "config.h" - -#include -#include -#include -#include -#include -#include - -#ifdef WIN32 -#include -#include -#else -#include -#include -#include -#endif - -/* These two required by FreeBSD. */ -#include - - -#include - -//#include -#include -#if HAVE_SAMPLERATE -#include -#endif - -#if HAVE_CELT -#include -#endif - -#include - -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_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 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_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 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 dont 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 ) - 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 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, jack_get_time ) ) - break; - - packet_cache_drain_socket(packcache, input_fd, jack_get_time); - - 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, jack_get_time); - } - - 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 ouput 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 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) -{ - 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 - Host name of the slave JACK\n" - " -o - Number of audio playback channels\n" - " -i - Number of audio capture channels\n" - " -O - Number of midi playback channels\n" - " -I - Number of midi capture channels\n" - " -n - Network latency in JACK periods\n" - " -p - UDP port that the slave is listening on\n" - " -r - UDP port that we are listening on\n" - " -B - reply port, for use in NAT environments\n" - " -b - Set transport to use 16bit or 8bit\n" - " -c - Use CELT encoding with kbits per channel\n" - " -m - Assume this mtu for the link\n" - " -R - Redundancy: send out packets N times.\n" - " -e - skip host-to-network endianness conversion\n" - " -N - Reports a different name to jack\n" - " -s - 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:")) != -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 supprt\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, "cant 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 ) - 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 42c7536..0000000 --- a/tools/property.c +++ /dev/null @@ -1,331 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -static int subject_is_client = 0; -static int subject_is_port = 0; -static jack_uuid_t uuid; -static char* subject; - -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 Interpret UUID as a port name, not a UUID\n"); - fprintf (stderr, "Display options:\n"); - fprintf (stderr, " -l Show all properties\n"); - fprintf (stderr, " -l, --list UUID Show value all properties of UUID\n"); - fprintf (stderr, " -l, --list UUID key Show value for key of UUID\n"); - fprintf (stderr, "For more information see http://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); - - } - - if (jack_uuid_parse (ustr, uuid)) { - fprintf (stderr, "cannot parse client UUID as UUID\n"); - 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; - } - - jack_port_uuid (port, uuid); - 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 = JackNullOption; - char* key = NULL; - char* value = NULL; - char* type = NULL; - int set = 1; - int delete = 0; - int delete_all = 0; - int list_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' }, - { "all", 0, 0, 'a' }, - { "client", 0, 0, 'c' }, - { "port", 0, 0, 'p' }, - { 0, 0, 0, 0 } - }; - - 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 'a': - list_all = 1; - 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", value, 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; - size_t 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; - size_t cnt; - size_t p; - size_t n; - char buf[JACK_UUID_STRING_SIZE]; - - if ((cnt = jack_get_all_properties (&description)) < 0) { - fprintf (stderr, "could not retrieve properties for %s\n", subject); - 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[n].key, - description[n].properties[n].data, - description[n].properties[n].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 fd258a0..0000000 --- a/tools/samplerate.c +++ /dev/null @@ -1,85 +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 -#include -#include -#include -#include -#include -#include -#include - -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); - } - - signal(SIGQUIT, signal_handler); - signal(SIGTERM, signal_handler); - signal(SIGHUP, 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 9cb3f89..0000000 --- a/tools/session_notify.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * session_notify.c -- ultra minimal session manager - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -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... cant 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); - } - - signal(SIGQUIT, signal_handler); - signal(SIGTERM, signal_handler); - signal(SIGHUP, 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 a1b0ab7..0000000 --- a/tools/transport.c +++ /dev/null @@ -1,481 +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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -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 */ -volatile int avr_set = 0; -float audio_frames_per_video_frame; - -/* JACK timebase callback. - * - * Runs in the process thread. Realtime, must not wait. - */ -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; - } - } - } - - if (avr_set) { - pos->valid |= JackAudioVideoRatio; - pos->audio_frames_per_video_frame = audio_frames_per_video_frame; - } -} - -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); -} - -void signal_handler(int sig) -{ - jack_client_close(client); - fprintf(stderr, "signal received, exiting ...\n"); - exit(0); -} - - -/* Command functions: see commands[] table following. */ - -void com_activate(char *arg) -{ - if (jack_activate(client)) { - fprintf(stderr, "cannot activate client"); - } -} - -void com_deactivate(char *arg) -{ - if (jack_deactivate(client)) { - fprintf(stderr, "cannot deactivate client"); - } -} - -void com_exit(char *arg) -{ - done = 1; -} - -void com_help(char *); /* forward declaration */ - -void com_locate(char *arg) -{ - jack_nframes_t frame = 0; - - if (*arg != '\0') - frame = atoi(arg); - - jack_transport_locate(client, frame); -} - -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"); -} - -void com_play(char *arg) -{ - jack_transport_start(client); -} - -void com_release(char *arg) -{ - jack_release_timebase(client); -} - -void com_stop(char *arg) -{ - jack_transport_stop(client); -} - -/* Change the tempo for the entire timeline, not just from the current - * location. */ -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. */ -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)); -} - - -/* Change the tempo for the entire timeline, not just from the current - * location. */ -void com_av_ratio(char *arg) -{ - float avr = 0; - - if (*arg != '\0') - avr = atof(arg); - - audio_frames_per_video_frame = avr; - avr_set = 1; -} - -/* 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()"}, - {"avr", com_av_ratio, "Set audio/video frame ratio