diff --git a/configure.in b/configure.in index b9e5265..707c070 100644 --- a/configure.in +++ b/configure.in @@ -13,7 +13,7 @@ dnl micro version = incremented when implementation-only dnl changes are made dnl --- JACK_MAJOR_VERSION=0 -JACK_MINOR_VERSION=77 +JACK_MINOR_VERSION=78 JACK_MICRO_VERSION=0 @@ -296,6 +296,7 @@ libjack/Makefile drivers/Makefile drivers/alsa/Makefile drivers/solaris/Makefile +drivers/dummy/Makefile example-clients/Makefile doc/Makefile doc/reference.doxygen diff --git a/doc/.cvsignore b/doc/.cvsignore index c2f9a20..d4a0b58 100644 --- a/doc/.cvsignore +++ b/doc/.cvsignore @@ -1,5 +1,6 @@ Makefile Makefile.in doxygen-build.stamp -reference reference.doxygen +html +latex diff --git a/doc/Makefile.am b/doc/Makefile.am index 44e8f26..274c6a2 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -6,7 +6,7 @@ DOX=reference.doxygen EXTRA_DIST= -INSTIMAGES=reference/html/doxygen.png reference/html/fsm.png +INSTIMAGES=html/doxygen.png /html/fsm.png DOC_STAMPS=html-build.stamp @@ -25,36 +25,36 @@ clean-local: distclean-local: clean rm -f *.stamp || true - if test -d reference; then rm -rf reference; fi + if test -d html; then rm -rf html; fi + if test -d latex; then rm -rf latex; fi install-data-local: - $(mkinstalldirs) $(DESTDIR)$(DOC_DIR)/reference/html - (installfiles=`echo reference/html/*.html`; \ - if test "$$installfiles" = 'reference/html/*.html'; \ + $(mkinstalldirs) $(DESTDIR)$(DOC_DIR)/html + (installfiles=`echo html/*.html`; \ + if test "$$installfiles" = 'html/*.html'; \ then echo '-- Nothing to install' ; \ else \ - for i in $$installfiles $(INSTIMAGES) reference/html/doxygen.css; do \ + for i in $$installfiles $(INSTIMAGES) html/doxygen.css; do \ echo '-- Installing '$$i ; \ - $(INSTALL_DATA) $$i $(DESTDIR)$(DOC_DIR)/reference/html; \ + $(INSTALL_DATA) $$i $(DESTDIR)$(DOC_DIR)/html; \ done; \ fi) # we need doxygen stuff built so we can know what to uninstall uninstall-local: doxygen-build.stamp - (installfiles=`echo reference/html/*.html`; \ - if test "$$installfiles" = 'reference/html/*.html'; \ + (installfiles=`echo html/*.html`; \ + if test "$$installfiles" = 'html/*.html'; \ then echo '-- Nothing to uninstall' ; \ else \ - for i in $$installfiles $(INSTIMAGES) reference/html/doxygen.css; do \ + for i in $$installfiles $(INSTIMAGES) html/doxygen.css; do \ echo '-- Unstalling '$$i ; \ rm $(DESTDIR)$(DOC_DIR)/$$i; \ done; \ fi) dist-hook: dist-hook-local - mkdir $(distdir)/reference - mkdir $(distdir)/reference/html - -cp reference/html/*.html reference/html/*.css \ - reference/html/*.png $(distdir)/reference/html + mkdir $(distdir)/html + -cp html/*.html html/*.css \ + html/*.png $(distdir)/html .PHONY : dist-hook-local diff --git a/doc/reference.doxygen.in b/doc/reference.doxygen.in index c8e4a3f..eabb10b 100644 --- a/doc/reference.doxygen.in +++ b/doc/reference.doxygen.in @@ -30,7 +30,7 @@ PROJECT_NUMBER = @JACK_VERSION@ # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. -OUTPUT_DIRECTORY = reference +OUTPUT_DIRECTORY = # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this diff --git a/drivers/Makefile.am b/drivers/Makefile.am index 806566a..62ab096 100644 --- a/drivers/Makefile.am +++ b/drivers/Makefile.am @@ -12,6 +12,7 @@ else SOLARIS_DIR = endif -SUBDIRS = $(ALSA_DIR) $(SOLARIS_DIR) +SUBDIRS = dummy $(ALSA_DIR) $(SOLARIS_DIR) + +DIST_SUBDIRS = dummy alsa solaris -DIST_SUBDIRS = alsa solaris \ No newline at end of file diff --git a/drivers/alsa/alsa_driver.c b/drivers/alsa/alsa_driver.c index a7628fe..5bd126c 100644 --- a/drivers/alsa/alsa_driver.c +++ b/drivers/alsa/alsa_driver.c @@ -191,9 +191,9 @@ static void alsa_driver_setup_io_function_pointers (alsa_driver_t *driver) { - switch (driver->sample_bytes) { + switch (driver->playback_sample_bytes) { case 2: - if (driver->interleaved) { + if (driver->playback_interleaved) { driver->channel_copy = memcpy_interleave_d16_s16; } else { driver->channel_copy = memcpy_fake; @@ -219,12 +219,10 @@ alsa_driver_setup_io_function_pointers (alsa_driver_t *driver) driver->write_via_copy = sample_move_d16_sS; break; } - - driver->read_via_copy = sample_move_dS_s16; break; case 4: - if (driver->interleaved) { + if (driver->playback_interleaved) { driver->channel_copy = memcpy_interleave_d32_s32; } else { driver->channel_copy = memcpy_fake; @@ -250,9 +248,15 @@ alsa_driver_setup_io_function_pointers (alsa_driver_t *driver) driver->write_via_copy = sample_move_d32u24_sS; break; } + break; + } + switch (driver->capture_sample_bytes) { + case 2: + driver->read_via_copy = sample_move_dS_s16; + break; + case 4: driver->read_via_copy = sample_move_dS_s32u24; - break; } } @@ -389,10 +393,6 @@ static int alsa_driver_set_parameters (alsa_driver_t *driver, jack_nframes_t frames_per_cycle, jack_nframes_t user_nperiods, jack_nframes_t rate) { - int p_noninterleaved = 0; - int c_noninterleaved = 0; - snd_pcm_format_t c_format = 0; - snd_pcm_format_t p_format = 0; int dir; unsigned int p_period_size = 0; unsigned int c_period_size = 0; @@ -431,8 +431,8 @@ alsa_driver_set_parameters (alsa_driver_t *driver, jack_nframes_t frames_per_cyc if (driver->playback_handle) { p_period_size = snd_pcm_hw_params_get_period_size (driver->playback_hw_params, &dir); p_nfragments = snd_pcm_hw_params_get_periods (driver->playback_hw_params, &dir); - p_format = (snd_pcm_format_t) snd_pcm_hw_params_get_format (driver->playback_hw_params); - p_noninterleaved = (snd_pcm_hw_params_get_access (driver->playback_hw_params) == SND_PCM_ACCESS_MMAP_NONINTERLEAVED); + driver->playback_sample_format = (snd_pcm_format_t) snd_pcm_hw_params_get_format (driver->playback_hw_params); + driver->playback_interleaved = (snd_pcm_hw_params_get_access (driver->playback_hw_params) == SND_PCM_ACCESS_MMAP_INTERLEAVED); if (p_period_size != driver->frames_per_cycle) { jack_error ("alsa_pcm: requested an interrupt every %u frames but got %uc frames for playback", @@ -444,8 +444,8 @@ alsa_driver_set_parameters (alsa_driver_t *driver, jack_nframes_t frames_per_cyc if (driver->capture_handle) { c_period_size = snd_pcm_hw_params_get_period_size (driver->capture_hw_params, &dir); c_nfragments = snd_pcm_hw_params_get_periods (driver->capture_hw_params, &dir); - c_format = (snd_pcm_format_t) snd_pcm_hw_params_get_format (driver->capture_hw_params); - c_noninterleaved = (snd_pcm_hw_params_get_access (driver->capture_hw_params) == SND_PCM_ACCESS_MMAP_NONINTERLEAVED); + driver->capture_sample_format = (snd_pcm_format_t) snd_pcm_hw_params_get_format (driver->capture_hw_params); + driver->capture_interleaved = (snd_pcm_hw_params_get_access (driver->capture_hw_params) == SND_PCM_ACCESS_MMAP_INTERLEAVED); if (c_period_size != driver->frames_per_cycle) { jack_error ("alsa_pcm: requested an interrupt every %u frames but got %uc frames for capture", @@ -460,44 +460,35 @@ alsa_driver_set_parameters (alsa_driver_t *driver, jack_nframes_t frames_per_cyc return -1; } - /* Check that we are using the same sample format on both streams */ - - if (p_format != c_format) { - jack_error ("Sorry. The PCM device \"%s\" and \"%s\"" - "don't support the same sample format for capture and playback." - "We cannot use this PCM device.", driver->alsa_name_playback, driver->alsa_name_capture ); - return -1; - } - - /* check interleave setup */ - - if (c_noninterleaved != p_noninterleaved) { - jack_error ("ALSA: the playback and capture components for this PCM device differ " - "in their use of channel interleaving. We cannot use this PCM device."); - return -1; - } - driver->nfragments = c_nfragments; - driver->interleaved = !c_noninterleaved; - driver->sample_format = c_format; } else if (driver->capture_handle) { driver->nfragments = c_nfragments; - driver->interleaved = !c_noninterleaved; - driver->sample_format = c_format; } else { driver->nfragments = p_nfragments; - driver->interleaved = !p_noninterleaved; - driver->sample_format = p_format; + } driver->buffer_frames = driver->frames_per_cycle * driver->nfragments; - driver->sample_bytes = snd_pcm_format_physical_width (driver->sample_format) / 8; + driver->playback_sample_bytes = snd_pcm_format_physical_width (driver->playback_sample_format) / 8; + driver->capture_sample_bytes = snd_pcm_format_physical_width (driver->capture_sample_format) / 8; + + switch (driver->playback_sample_format) { + case SND_PCM_FORMAT_S32_LE: + case SND_PCM_FORMAT_S16_LE: + case SND_PCM_FORMAT_S32_BE: + case SND_PCM_FORMAT_S16_BE: + break; + + default: + jack_error ("programming error: unhandled format type for playback"); + exit (1); + } - switch (driver->sample_format) { + switch (driver->capture_sample_format) { case SND_PCM_FORMAT_S32_LE: case SND_PCM_FORMAT_S16_LE: case SND_PCM_FORMAT_S32_BE: @@ -505,11 +496,11 @@ alsa_driver_set_parameters (alsa_driver_t *driver, jack_nframes_t frames_per_cyc break; default: - jack_error ("programming error: unhandled format type"); + jack_error ("programming error: unhandled format type for capture"); exit (1); } - if (driver->interleaved) { + if (driver->playback_interleaved) { const snd_pcm_channel_area_t *my_areas; snd_pcm_uframes_t offset, frames; if (snd_pcm_mmap_begin(driver->playback_handle, &my_areas, &offset, &frames) < 0) { @@ -517,16 +508,22 @@ alsa_driver_set_parameters (alsa_driver_t *driver, jack_nframes_t frames_per_cyc return -1; } driver->playback_interleave_skip = my_areas[0].step / 8; + driver->interleave_unit = snd_pcm_format_physical_width (driver->playback_sample_format) / 8; + } else { + driver->interleave_unit = 0; /* NOT USED */ + driver->playback_interleave_skip = snd_pcm_format_physical_width (driver->playback_sample_format) / 8; + } + + if (driver->capture_interleaved) { + const snd_pcm_channel_area_t *my_areas; + snd_pcm_uframes_t offset, frames; if (snd_pcm_mmap_begin(driver->capture_handle, &my_areas, &offset, &frames) < 0) { - jack_error ("ALSA: %s: mmap areas info error", driver->alsa_name_playback); + jack_error ("ALSA: %s: mmap areas info error", driver->alsa_name_capture); return -1; } driver->capture_interleave_skip = my_areas[0].step / 8; - driver->interleave_unit = snd_pcm_format_physical_width (driver->sample_format) / 8; } else { - driver->interleave_unit = 0; /* NOT USED */ - driver->playback_interleave_skip = snd_pcm_format_physical_width (driver->sample_format) / 8; - driver->capture_interleave_skip = driver->playback_interleave_skip; + driver->capture_interleave_skip = snd_pcm_format_physical_width (driver->capture_sample_format) / 8; } if (driver->playback_nchannels > driver->capture_nchannels) { @@ -576,8 +573,7 @@ alsa_driver_set_parameters (alsa_driver_t *driver, jack_nframes_t frames_per_cyc } driver->clock_sync_data = (ClockSyncStatus *) malloc (sizeof (ClockSyncStatus) * - (driver->capture_nchannels > driver->playback_nchannels ? - driver->capture_nchannels : driver->playback_nchannels)); + driver->max_nchannels); driver->period_usecs = (jack_time_t) floor ((((float) driver->frames_per_cycle) / driver->frame_rate) * 1000000.0f); driver->poll_timeout = (int) floor (1.5f * driver->period_usecs); @@ -1170,6 +1166,7 @@ alsa_driver_write (alsa_driver_t* driver, jack_nframes_t nframes) snd_pcm_sframes_t contiguous; snd_pcm_sframes_t offset; jack_port_t *port; + int err; driver->process_count++; @@ -1224,9 +1221,10 @@ alsa_driver_write (alsa_driver_t* driver, jack_nframes_t nframes) alsa_driver_silence_untouched_channels (driver, contiguous); } - if (snd_pcm_mmap_commit (driver->playback_handle, offset, contiguous) < 0) { - jack_error ("could not complete playback of %lu frames", contiguous); - return -1; + if ((err = snd_pcm_mmap_commit (driver->playback_handle, offset, contiguous)) < 0) { + jack_error ("could not complete playback of %lu frames: error = %d", contiguous, err); + if (err != -EPIPE && err != -ESTRPIPE) + return -1; } nframes -= contiguous; diff --git a/drivers/dummy/.cvsignore b/drivers/dummy/.cvsignore new file mode 100644 index 0000000..6e5ca7e --- /dev/null +++ b/drivers/dummy/.cvsignore @@ -0,0 +1,6 @@ +Makefile +Makefile.in +.deps +.libs +*.lo +*.la diff --git a/drivers/dummy/Makefile.am b/drivers/dummy/Makefile.am new file mode 100644 index 0000000..8fc2bc0 --- /dev/null +++ b/drivers/dummy/Makefile.am @@ -0,0 +1,12 @@ +MAINTAINERCLEANFILES=Makefile.in + +AM_CFLAGS = $(JACK_CFLAGS) + +plugindir = $(ADDON_DIR) + +plugin_LTLIBRARIES = jack_dummy.la + +jack_dummy_la_LDFLAGS = -module -avoid-version +jack_dummy_la_SOURCES = dummy_driver.c dummy_driver.h + +# jack_alsa_la_LIBADD = diff --git a/drivers/dummy/dummy_driver.c b/drivers/dummy/dummy_driver.c new file mode 100644 index 0000000..9524bdd --- /dev/null +++ b/drivers/dummy/dummy_driver.c @@ -0,0 +1,323 @@ +/* + Copyright (C) 2003 Robert Ham + Copyright (C) 2001 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. + + $Id$ +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "dummy_driver.h" + +#undef DEBUG_WAKEUP + + +static int +dummy_driver_audio_start (dummy_driver_t *driver) +{ + return 0; +} + +static int +dummy_driver_audio_stop (dummy_driver_t *driver) +{ + return 0; +} + +static jack_nframes_t +dummy_driver_wait (dummy_driver_t *driver, int extra_fd, int *status, float *delayed_usecs) +{ + usleep (driver->wait_time); + + driver->last_wait_ust = jack_get_microseconds (); + + *status = 0; + *delayed_usecs = 0.0; + + return driver->period_size; +} + +static int +dummy_driver_null_cycle (dummy_driver_t* driver, jack_nframes_t nframes) +{ + return 0; +} + +static int +dummy_driver_read (dummy_driver_t *driver, jack_nframes_t nframes) +{ + return 0; +} + +static int +dummy_driver_write (dummy_driver_t* driver, jack_nframes_t nframes) +{ + return 0; +} + + +static int +dummy_driver_attach (dummy_driver_t *driver, jack_engine_t *engine) +{ + jack_port_t * port; + char buf[32]; + unsigned int chn; + int port_flags; + + driver->engine = engine; + + driver->engine->set_buffer_size (engine, driver->period_size); + driver->engine->set_sample_rate (engine, driver->sample_rate); + + port_flags = JackPortIsOutput|JackPortIsPhysical|JackPortIsTerminal; + + for (chn = 0; chn < driver->capture_channels; chn++) + { + snprintf (buf, sizeof(buf) - 1, "capture_%u", chn+1); + + port = jack_port_register (driver->client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0); + if (!port) + { + jack_error ("DUMMY: cannot register port for %s", buf); + break; + } + + driver->capture_ports = jack_slist_append (driver->capture_ports, port); + } + + port_flags = JackPortIsInput|JackPortIsPhysical|JackPortIsTerminal; + + for (chn = 0; chn < driver->playback_channels; chn++) + { + snprintf (buf, sizeof(buf) - 1, "playback_%u", chn+1); + + port = jack_port_register (driver->client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0); + + if (!port) + { + jack_error ("DUMMY: cannot register port for %s", buf); + break; + } + + driver->playback_ports = jack_slist_append (driver->playback_ports, port); + } + + jack_activate (driver->client); + + return 0; +} + +static void +dummy_driver_detach (dummy_driver_t *driver, jack_engine_t *engine) +{ + JSList * node; + + if (driver->engine == 0) + return; + + for (node = driver->capture_ports; node; node = jack_slist_next (node)) + jack_port_unregister (driver->client, ((jack_port_t *) node->data)); + + jack_slist_free (driver->capture_ports); + driver->capture_ports = NULL; + + + for (node = driver->playback_ports; node; node = jack_slist_next (node)) + jack_port_unregister (driver->client, ((jack_port_t *) node->data)); + + jack_slist_free (driver->playback_ports); + driver->playback_ports = NULL; + + driver->engine = NULL; +} + +static void +dummy_driver_delete (dummy_driver_t *driver) +{ + free (driver); +} + +static jack_driver_t * +dummy_driver_new (jack_client_t * client, + char *name, + unsigned int capture_ports, + unsigned int playback_ports, + jack_nframes_t sample_rate, + jack_nframes_t period_size, + unsigned long wait_time) +{ + dummy_driver_t * driver; + + printf ("creating dummy driver ... %s|%lu|%lu|%lu|%u|%u\n", + name, sample_rate, period_size, wait_time, + capture_ports, playback_ports); + + driver = (dummy_driver_t *) calloc (1, sizeof (dummy_driver_t)); + + jack_driver_init ((jack_driver_t *) driver); + + driver->attach = (JackDriverAttachFunction) dummy_driver_attach; + driver->detach = (JackDriverDetachFunction) dummy_driver_detach; + driver->wait = (JackDriverWaitFunction) dummy_driver_wait; + driver->read = (JackDriverReadFunction) dummy_driver_read; + driver->write = (JackDriverReadFunction) dummy_driver_write; + driver->null_cycle = (JackDriverNullCycleFunction) dummy_driver_null_cycle; + driver->start = (JackDriverStartFunction) dummy_driver_audio_start; + driver->stop = (JackDriverStopFunction) dummy_driver_audio_stop; + + driver->period_usecs = (((float)period_size) / ((float)sample_rate)) / 1000000.0; + + driver->sample_rate = sample_rate; + driver->period_size = period_size; + driver->wait_time = wait_time; + + driver->capture_channels = capture_ports; + driver->capture_ports = NULL; + driver->playback_channels = playback_ports; + driver->playback_ports = NULL; + + driver->client = client; + driver->engine = NULL; + + return (jack_driver_t *) driver; +} + +static void +dummy_usage () +{ + fprintf (stderr, "\n" +"dummy driver arguments:\n" +" -h,--help \tprint this message\n" +" -r,--rate \tsample rate (default: 48000)\n" +" -p,--period \tframes per period (default: 1024)\n" +" -C,--capture \tnumber of capture ports (default: 2)\n" +" -P,--playback \tnumber of playback ports (default: 2)\n" +" -w,--wait \tnumber of usecs to wait between engine processes (default: 21333)\n" +"\n"); +} + +static void +dummy_error (char *type, char *value) +{ + fprintf (stderr, "dummy driver: unknown %s: `%s'\n", type, value); + dummy_usage(); +} + + + +/* DRIVER "PLUGIN" INTERFACE */ + +const char driver_client_name[] = "dummy_pcm"; + +jack_driver_t * +driver_initialize (jack_client_t *client, int argc, char **argv) +{ + jack_nframes_t sample_rate = 48000; + jack_nframes_t period_size = 1024; + unsigned int capture_ports = 2; + unsigned int playback_ports = 2; + int wait_time_set = 0; + unsigned long wait_time; + + int opt; + char optstring[2]; /* string made from opt char */ + struct option long_options[] = + { + { "help", no_argument, NULL, 'h' }, + { "rate", required_argument, NULL, 'r' }, + { "period", required_argument, NULL, 'p' }, + { "capture", required_argument, NULL, 'C' }, + { "playback", required_argument, NULL, 'P' }, + { "wait", required_argument, NULL, 'w' }, + { 0, 0, 0, 0 } + }; + + + /* + * Setting optind back to zero is a hack to reinitialize a new + * getopts() loop. See declaration in . + */ + + optind = 0; + opterr = 0; + + while ((opt = getopt_long(argc, argv, "C::P::p:r:w:h", + long_options, NULL)) + != EOF) { + switch (opt) { + + case 'C': + capture_ports = atoi (optarg); + break; + + case 'P': + playback_ports = atoi (optarg); + break; + + case 'p': + period_size = atoi(optarg); + break; + + case 'r': + sample_rate = atoi(optarg); + break; + + case 'w': + wait_time = strtoul(optarg, NULL, 10); + wait_time_set = 1; + break; + + case 'h': + dummy_usage(); + return NULL; + + /* the rest is error handling: */ + case 1: /* not an option */ + dummy_error("parameter", optarg); + return NULL; + + default: /* unrecognized option */ + optstring[0] = (char) optopt; + optstring[1] = '\0'; + dummy_error("option", optstring); + return NULL; + } + } + + if (!wait_time_set) + wait_time = (((float)period_size) / ((float)sample_rate)) * 1000000.0; + + return dummy_driver_new (client, "dummy_pcm", capture_ports, playback_ports, + sample_rate, period_size, wait_time); +} + +void +driver_finish (jack_driver_t *driver) +{ + dummy_driver_delete ((dummy_driver_t *) driver); +} diff --git a/drivers/dummy/dummy_driver.h b/drivers/dummy/dummy_driver.h new file mode 100644 index 0000000..827a233 --- /dev/null +++ b/drivers/dummy/dummy_driver.h @@ -0,0 +1,52 @@ +/* + Copyright (C) 2003 Robert Ham + + 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. +*/ + + +#ifndef __JACK_DUMMY_DRIVER_H__ +#define __JACK_DUMMY_DRIVER_H__ + +#include + +#include +#include +#include +#include + +typedef struct _dummy_driver dummy_driver_t; + +struct _dummy_driver +{ + + JACK_DRIVER_DECL + + jack_nframes_t sample_rate; + jack_nframes_t period_size; + unsigned long wait_time; + + unsigned int capture_channels; + unsigned int playback_channels; + + JSList * capture_ports; + JSList * playback_ports; + + struct _jack_engine * engine; + + jack_client_t * client; +}; + +#endif /* __JACK_DUMMY_DRIVER_H__ */ diff --git a/jack/alsa_driver.h b/jack/alsa_driver.h index bfc4118..cddf424 100644 --- a/jack/alsa_driver.h +++ b/jack/alsa_driver.h @@ -62,7 +62,8 @@ typedef struct { channel_t user_nchannels; channel_t playback_nchannels; channel_t capture_nchannels; - unsigned long sample_bytes; + unsigned long playback_sample_bytes; + unsigned long capture_sample_bytes; jack_nframes_t frame_rate; jack_nframes_t frames_per_cycle; @@ -76,7 +77,8 @@ typedef struct { snd_pcm_uframes_t buffer_frames; unsigned long channels_not_done; unsigned long channel_done_bits; - snd_pcm_format_t sample_format; + snd_pcm_format_t playback_sample_format; + snd_pcm_format_t capture_sample_format; float max_sample_val; unsigned long user_nperiods; unsigned long nfragments; @@ -102,7 +104,8 @@ typedef struct { char hw_metering : 1; char all_monitor_in : 1; char capture_and_playback_not_synced : 1; - char interleaved : 1; + char playback_interleaved : 1; + char capture_interleaved : 1; char with_monitor_ports : 1; ReadCopyFunction read_via_copy; @@ -130,27 +133,27 @@ static __inline__ void alsa_driver_mark_channel_done (alsa_driver_t *driver, cha } static __inline__ void alsa_driver_silence_on_channel (alsa_driver_t *driver, channel_t chn, jack_nframes_t nframes) { - if (driver->interleaved) { + if (driver->playback_interleaved) { memset_interleave (driver->playback_addr[chn], - 0, nframes * driver->sample_bytes, + 0, nframes * driver->playback_sample_bytes, driver->interleave_unit, driver->playback_interleave_skip); } else { - memset (driver->playback_addr[chn], 0, nframes * driver->sample_bytes); + memset (driver->playback_addr[chn], 0, nframes * driver->playback_sample_bytes); } alsa_driver_mark_channel_done (driver,chn); } static __inline__ void alsa_driver_silence_on_channel_no_mark (alsa_driver_t *driver, channel_t chn, jack_nframes_t nframes) { - if (driver->interleaved) { + if (driver->playback_interleaved) { memset_interleave (driver->playback_addr[chn], - 0, nframes * driver->sample_bytes, + 0, nframes * driver->playback_sample_bytes, driver->interleave_unit, driver->playback_interleave_skip); } else { - memset (driver->playback_addr[chn], 0, nframes * driver->sample_bytes); + memset (driver->playback_addr[chn], 0, nframes * driver->playback_sample_bytes); } } @@ -184,7 +187,7 @@ static __inline__ void alsa_driver_copy_channel (alsa_driver_t *driver, driver->channel_copy (driver->playback_addr[output_channel], driver->capture_addr[input_channel], - nsamples * driver->sample_bytes, + nsamples * driver->playback_sample_bytes, driver->playback_interleave_skip, driver->capture_interleave_skip); alsa_driver_mark_channel_done (driver, output_channel); diff --git a/jack/internal.h b/jack/internal.h index 8fedfea..31424bf 100644 --- a/jack/internal.h +++ b/jack/internal.h @@ -336,7 +336,7 @@ typedef struct _jack_client_internal { struct _jack_client_internal *next_client; /* not a linked list! */ dlhandle handle; int (*initialize)(jack_client_t*, const char*); /* for internal clients only */ - void (*finish)(void); /* for internal clients only */ + void (*finish)(void *); /* for internal clients only */ int error; #if defined(__APPLE__) && defined(__POWERPC__) diff --git a/jackd/engine.c b/jackd/engine.c index 8bb9cea..20e2785 100644 --- a/jackd/engine.c +++ b/jackd/engine.c @@ -779,7 +779,7 @@ jack_client_unload (jack_client_internal_t *client) { if (client->handle) { if (client->finish) { - client->finish (); + client->finish (client->control->process_arg); } dlclose (client->handle); } diff --git a/jackd/transengine.c b/jackd/transengine.c index 0ce9d9b..b05b9a7 100644 --- a/jackd/transengine.c +++ b/jackd/transengine.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include