aboutsummaryrefslogtreecommitdiff
path: root/audio/jack/files/patch-aa
diff options
context:
space:
mode:
Diffstat (limited to 'audio/jack/files/patch-aa')
-rw-r--r--audio/jack/files/patch-aa1318
1 files changed, 1318 insertions, 0 deletions
diff --git a/audio/jack/files/patch-aa b/audio/jack/files/patch-aa
new file mode 100644
index 000000000000..3067e0553d46
--- /dev/null
+++ b/audio/jack/files/patch-aa
@@ -0,0 +1,1318 @@
+diff -urN jack-audio-connection-kit-0.94.0/configure.in configure.in
+--- jack-audio-connection-kit-0.94.0/configure.in 2004-01-13 04:43:12.000000000 +0200
++++ configure.in 2004-02-14 16:21:26.000000000 +0200
+@@ -116,7 +116,7 @@
+
+ JACK_CORE_CFLAGS="-I\$(top_srcdir) -I\$(top_builddir) -D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS -Wall"
+
+-JACK_CFLAGS="$JACK_CORE_CFLAGS -g"
++JACK_CFLAGS="$JACK_CORE_CFLAGS -g $CFLAGS"
+ dnl
+ dnl figure out how best to optimize
+ dnl
+@@ -162,6 +162,8 @@
+ fi
+ fi
+
++JACK_OPT_CFLAGS="$JACK_CORE_CFLAGS -march=pentium2 -mcpu=pentium4 -mmmx -O3 -ffast-math -funroll-loops -fprefetch-loop-arrays"
++
+ AC_ARG_ENABLE(optimize,
+ [ --enable-optimize ask the compiler for its best optimizations],
+ [ if test "x$enable_optimize" != "xno" ; then JACK_CFLAGS="$JACK_OPT_CFLAGS" ; fi ])
+@@ -416,6 +418,7 @@
+ drivers/dummy/Makefile
+ drivers/portaudio/Makefile
+ drivers/iec61883/Makefile
++drivers/oss/Makefile
+ example-clients/Makefile
+ doc/Makefile
+ doc/reference.doxygen
+diff -urN jack-audio-connection-kit-0.94.0/drivers/oss/Makefile.am drivers/oss/Makefile.am
+--- jack-audio-connection-kit-0.94.0/drivers/oss/Makefile.am 1970-01-01 02:00:00.000000000 +0200
++++ drivers/oss/Makefile.am 2004-02-14 16:21:26.000000000 +0200
+@@ -0,0 +1,14 @@
++MAINTAINCLEANFILES = Makefile.in
++
++AM_CFLAGS = $(JACK_CFLAGS) -I/opt/oss/include -D_XOPEN_SOURCE=600 -DUSE_BARRIER
++#AM_CFLAGS = $(JACK_CFLAGS) -I/opt/oss/include
++AM_LDFLAGS = $(JACK_LDFLAGS) -lpthread -lrt
++
++plugindir = $(ADDON_DIR)
++
++plugin_LTLIBRARIES = jack_oss.la
++
++jack_oss_la_LDFLAGS = -module -avoid-version
++jack_oss_la_SOURCES = oss_driver.c oss_driver.h
++
++noinst_HEADERS = oss_driver.h
+diff -urN jack-audio-connection-kit-0.94.0/drivers/oss/oss_driver.c drivers/oss/oss_driver.c
+--- jack-audio-connection-kit-0.94.0/drivers/oss/oss_driver.c 1970-01-01 02:00:00.000000000 +0200
++++ drivers/oss/oss_driver.c 2004-02-14 17:22:53.000000000 +0200
+@@ -0,0 +1,1171 @@
++/*
++
++ OSS driver for Jack
++ Copyright (C) 2003-2004 Jussi Laako <jussi@sonarnerd.net>
++
++ 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., 59 Temple Place, Suite 330, Boston,
++ MA 02111-1307 USA
++
++*/
++
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++#include <fcntl.h>
++#include <errno.h>
++#include <math.h>
++#include <float.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <sys/ioctl.h>
++#include <sys/soundcard.h>
++#include <stdarg.h>
++#include <getopt.h>
++#ifndef USE_BARRIER
++#include <pthread.h>
++#else
++#include <pthread.h>
++#include <semaphore.h>
++#endif
++
++#include <jack/types.h>
++#include <jack/internal.h>
++#include <jack/engine.h>
++#include <jack/time.h>
++
++#include "oss_driver.h"
++
++
++#define OSS_DRIVER_N_PARAMS 9
++const static jack_driver_param_desc_t oss_params[OSS_DRIVER_N_PARAMS] = {
++ { "samplerate",
++ 's',
++ JackDriverParamUInt,
++ { .ui = OSS_DRIVER_DEF_FS },
++ "sample rate",
++ "sample rate"
++ },
++ { "periodsize",
++ 'b',
++ JackDriverParamUInt,
++ { .ui = OSS_DRIVER_DEF_BLKSIZE },
++ "period size",
++ "period size"
++ },
++ { "wordlength",
++ 'w',
++ JackDriverParamInt,
++ { .i = OSS_DRIVER_DEF_BITS },
++ "word length",
++ "word length"
++ },
++ { "capturech",
++ 'c',
++ JackDriverParamUInt,
++ { .ui = OSS_DRIVER_DEF_INS },
++ "capture channels",
++ "capture channels"
++ },
++ { "playbackch",
++ 'p',
++ JackDriverParamUInt,
++ { .ui = OSS_DRIVER_DEF_OUTS },
++ "playback channels",
++ "playback channels"
++ },
++ { "inputdev",
++ 'i',
++ JackDriverParamString,
++ { .str = '\0' },
++ "input device",
++ "input device"
++ },
++ { "outputdev",
++ 'o',
++ JackDriverParamString,
++ { .str = '\0' },
++ "output device",
++ "output device"
++ },
++ { "ignorehwbuf",
++ 'd',
++ JackDriverParamBool,
++ { },
++ "ignore hardware period size",
++ "ignore hardware period size"
++ },
++ { "help",
++ 'h',
++ JackDriverParamBool,
++ { },
++ "help",
++ "help"
++ }
++};
++
++
++
++/* internal functions */
++
++
++static void copy_and_convert_in (jack_sample_t *dst, void *src,
++ size_t nframes, int channel, int chcount, int bits)
++{
++ int srcidx;
++ int dstidx;
++ signed short *s16src = (signed short *) src;
++ signed int *s32src = (signed int *) src;
++ double *f64src = (double *) src;
++ jack_sample_t scale;
++
++ srcidx = channel;
++ switch (bits)
++ {
++ case 16:
++ scale = 1.0f / 0x7fff;
++ for (dstidx = 0; dstidx < nframes; dstidx++)
++ {
++ dst[dstidx] = (jack_sample_t)
++ s16src[srcidx] * scale;
++ srcidx += chcount;
++ }
++ break;
++ case 24:
++ scale = 1.0f / 0x7fffff;
++ for (dstidx = 0; dstidx < nframes; dstidx++)
++ {
++ dst[dstidx] = (jack_sample_t)
++ s32src[srcidx] * scale;
++ srcidx += chcount;
++ }
++ break;
++ case 32:
++ scale = 1.0f / 0x7fffffff;
++ for (dstidx = 0; dstidx < nframes; dstidx++)
++ {
++ dst[dstidx] = (jack_sample_t)
++ s32src[srcidx] * scale;
++ srcidx += chcount;
++ }
++ break;
++ case 64:
++ for (dstidx = 0; dstidx < nframes; dstidx++)
++ {
++ dst[dstidx] = (jack_sample_t) f64src[srcidx];
++ srcidx += chcount;
++ }
++ break;
++ }
++}
++
++
++static void copy_and_convert_out (void *dst, jack_sample_t *src,
++ size_t nframes, int channel, int chcount, int bits)
++{
++ int srcidx;
++ int dstidx;
++ signed short *s16dst = (signed short *) dst;
++ signed int *s32dst = (signed int *) dst;
++ double *f64dst = (double *) dst;
++ jack_sample_t scale;
++
++ dstidx = channel;
++ switch (bits)
++ {
++ case 16:
++ scale = 0x7fff;
++ for (srcidx = 0; srcidx < nframes; srcidx++)
++ {
++ s16dst[dstidx] = (signed short)
++ (src[srcidx] * scale + 0.5f);
++ dstidx += chcount;
++ }
++ break;
++ case 24:
++ scale = 0x7fffff;
++ for (srcidx = 0; srcidx < nframes; srcidx++)
++ {
++ s32dst[dstidx] = (signed int)
++ (src[srcidx] * scale + 0.5f);
++ dstidx += chcount;
++ }
++ break;
++ case 32:
++ scale = 0x7fffffff;
++ for (srcidx = 0; srcidx < nframes; srcidx++)
++ {
++ s32dst[dstidx] = (signed int)
++ (src[srcidx] * scale + 0.5f);
++ dstidx += chcount;
++ }
++ break;
++ case 64:
++ for (srcidx = 0; srcidx < nframes; srcidx++)
++ {
++ f64dst[dstidx] = (double) src[srcidx];
++ dstidx += chcount;
++ }
++ break;
++ }
++}
++
++
++static void set_fragment (int fd, int fragsize)
++{
++ int fragcount;
++ int fragsize_2p;
++ int fragments;
++
++ fragcount = 2;
++ //fragcount = 3;
++ //fragcount = 0xffff / fragsize;
++ fragsize_2p = (int) (log(fragsize) / log(2.0) + 0.5);
++ fragments = ((fragcount << 16) | (fragsize_2p & 0xffff));
++ if (ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &fragments) < 0)
++ {
++ jack_error("OSS: failed to set fragment size: %s@%i",
++ __FILE__, __LINE__);
++ }
++}
++
++
++static int get_fragment (int fd)
++{
++ int fragsize;
++
++ if (ioctl(fd, SNDCTL_DSP_GETBLKSIZE, &fragsize) < 0)
++ {
++ jack_error("OSS: failed to get fragment size: %s@%i",
++ __FILE__, __LINE__);
++ return 0;
++ }
++ return fragsize;
++}
++
++
++static void *io_thread (void *);
++
++
++/* jack driver interface */
++
++
++static int oss_driver_attach (oss_driver_t *driver, jack_engine_t *engine)
++{
++ int port_flags;
++ unsigned int channel;
++ char channel_name[64];
++ jack_port_t *port;
++
++ driver->engine = engine;
++
++ engine->set_buffer_size(engine, driver->period_size);
++ engine->set_sample_rate(engine, driver->sample_rate);
++
++ port_flags = JackPortIsOutput|JackPortIsPhysical|JackPortIsTerminal;
++ for (channel = 0; channel < driver->capture_channels; channel++)
++ {
++ snprintf(channel_name, sizeof(channel_name),
++ "capture_%u", channel + 1);
++ port = jack_port_register(driver->client, channel_name,
++ JACK_DEFAULT_AUDIO_TYPE, port_flags, 0);
++ if (port == NULL)
++ {
++ jack_error("OSS: cannot register port for %s: %s@%i",
++ channel_name, __FILE__, __LINE__);
++ break;
++ }
++ driver->capture_ports =
++ jack_slist_append(driver->capture_ports, port);
++ }
++
++ port_flags = JackPortIsInput|JackPortIsPhysical|JackPortIsTerminal;
++ for (channel = 0; channel < driver->playback_channels; channel++)
++ {
++ snprintf(channel_name, sizeof(channel_name),
++ "playback_%u", channel + 1);
++ port = jack_port_register(driver->client, channel_name,
++ JACK_DEFAULT_AUDIO_TYPE, port_flags, 0);
++ if (port == NULL)
++ {
++ jack_error("OSS: cannot register port for %s: %s@%i",
++ channel_name, __FILE__, __LINE__);
++ break;
++ }
++ driver->playback_ports =
++ jack_slist_append(driver->playback_ports, port);
++ }
++
++ jack_activate(driver->client);
++
++ return 0;
++}
++
++
++static int oss_driver_detach (oss_driver_t *driver, jack_engine_t *engine)
++{
++ JSList *node;
++
++ if (driver->engine == NULL)
++ return -1;
++
++ node = driver->capture_ports;
++ while (node != NULL)
++ {
++ jack_port_unregister(driver->client,
++ ((jack_port_t *) node->data));
++ node = jack_slist_next(node);
++ }
++ jack_slist_free(driver->capture_ports);
++ driver->capture_ports = NULL;
++
++ node = driver->playback_ports;
++ while (node != NULL)
++ {
++ jack_port_unregister(driver->client,
++ ((jack_port_t *) node->data));
++ node = jack_slist_next(node);
++ }
++ jack_slist_free(driver->playback_ports);
++ driver->playback_ports = NULL;
++
++ driver->engine = NULL;
++
++ return 0;
++}
++
++
++static int oss_driver_start (oss_driver_t *driver)
++{
++ int format;
++ int channels;
++ int samplerate;
++ int infd = driver->infd;
++ int outfd = driver->outfd;
++ unsigned int period_size;
++ size_t samplesize;
++ size_t fragsize;
++ const char *indev = driver->indev;
++ const char *outdev = driver->outdev;
++
++ switch (driver->bits)
++ {
++ case 24:
++ case 32:
++ samplesize = sizeof(int);
++ break;
++ case 64:
++ samplesize = sizeof(double);
++ break;
++ case 16:
++ default:
++ samplesize = sizeof(short);
++ break;
++ }
++ if (strcmp(indev, outdev) != 0)
++ {
++ if (driver->capture_channels > 0)
++ {
++ infd = open(indev, O_RDONLY);
++ if (infd < 0)
++ {
++ jack_error(
++ "OSS: failed to open input device %s: %s@%i",
++ indev, __FILE__, __LINE__);
++ }
++ fragsize = driver->period_size *
++ driver->capture_channels * samplesize;
++ set_fragment(infd, fragsize);
++ }
++ else infd = -1;
++
++ if (driver->playback_channels > 0)
++ {
++ outfd = open(outdev, O_WRONLY);
++ if (outfd < 0)
++ {
++ jack_error(
++ "OSS: failed to open output device %s: %s@%i",
++ outdev, __FILE__, __LINE__);
++ }
++ fragsize = driver->period_size *
++ driver->playback_channels * samplesize;
++ set_fragment(outfd, fragsize);
++ }
++ else outfd = -1;
++ }
++ else
++ {
++ if (driver->capture_channels != 0 &&
++ driver->playback_channels == 0)
++ {
++ infd = open(indev, O_RDWR);
++ outfd = -1;
++ if (infd < 0)
++ {
++ jack_error(
++ "OSS: failed to open device %s: %s@%i",
++ indev, __FILE__, __LINE__);
++ return -1;
++ }
++ }
++ else if (driver->capture_channels == 0 &&
++ driver->playback_channels != 0)
++ {
++ infd = -1;
++ outfd = open(outdev, O_RDWR);
++ if (outfd < 0)
++ {
++ jack_error(
++ "OSS: failed to open device %s: %s@%i",
++ outdev, __FILE__, __LINE__);
++ return -1;
++ }
++ }
++ else
++ {
++ infd = outfd = open(indev, O_RDWR);
++ if (infd < 0)
++ {
++ jack_error(
++ "OSS: failed to open device %s: %s@%i",
++ indev, __FILE__, __LINE__);
++ return -1;
++ }
++ }
++ if (infd >= 0 && outfd >= 0)
++ {
++ if (ioctl(infd, SNDCTL_DSP_SETDUPLEX, 0) < 0)
++ {
++ jack_error(
++ "OSS: failed to enable full duplex for %s: %s@%i",
++ indev, __FILE__, __LINE__);
++ }
++ }
++ if (infd >= 0)
++ {
++ fragsize = driver->period_size *
++ driver->capture_channels * samplesize;
++ set_fragment(infd, fragsize);
++ }
++ if (outfd >= 0 && infd < 0)
++ {
++ fragsize = driver->period_size *
++ driver->playback_channels * samplesize;
++ set_fragment(outfd, fragsize);
++ }
++ }
++ driver->infd = infd;
++ driver->outfd = outfd;
++
++ if (infd >= 0)
++ {
++ format = driver->format;
++ if (ioctl(infd, SNDCTL_DSP_SETFMT, &format) < 0)
++ jack_error(
++ "OSS: failed to set format for %s: %s@%i",
++ indev, __FILE__, __LINE__);
++ channels = driver->capture_channels;
++ if (ioctl(infd, SNDCTL_DSP_CHANNELS, &channels) < 0)
++ jack_error(
++ "OSS: failed to set channels for %s: %s@%i",
++ indev, __FILE__, __LINE__);
++ samplerate = driver->sample_rate;
++ if (ioctl(infd, SNDCTL_DSP_SPEED, &samplerate) < 0)
++ jack_error(
++ "OSS: failed to set samplerate for %s: %s@%i",
++ indev, __FILE__, __LINE__);
++ printf("oss_driver: %s : 0x%x/%i/%i (%i)\n", indev,
++ format, channels, samplerate, get_fragment(infd));
++
++ period_size = get_fragment(infd) / samplesize / channels;
++ if (period_size != driver->period_size &&
++ !driver->ignorehwbuf)
++ {
++ printf("oss_driver: period size update: %u\n",
++ period_size);
++ driver->period_size = period_size;
++ driver->period_usecs =
++ ((double) driver->period_size /
++ (double) driver->sample_rate) * 1e6;
++ driver->engine->set_buffer_size(driver->engine,
++ driver->period_size);
++ }
++ }
++
++ if (outfd >= 0 && infd != outfd)
++ {
++ format = driver->format;
++ if (ioctl(outfd, SNDCTL_DSP_SETFMT, &format) < 0)
++ jack_error(
++ "OSS: failed to set format for %s: %s@%i",
++ outdev, __FILE__, __LINE__);
++ channels = driver->playback_channels;
++ if (ioctl(outfd, SNDCTL_DSP_CHANNELS, &channels) < 0)
++ jack_error(
++ "OSS: failed to set channels for %s: %s@%i",
++ outdev, __FILE__, __LINE__);
++ samplerate = driver->sample_rate;
++ if (ioctl(outfd, SNDCTL_DSP_SPEED, &samplerate) < 0)
++ jack_error(
++ "OSS: failed to set samplerate for %s: %s@%i",
++ outdev, __FILE__, __LINE__);
++ printf("oss_driver: %s : 0x%x/%i/%i (%i)\n", outdev,
++ format, channels, samplerate,
++ get_fragment(outfd));
++
++ period_size = get_fragment(outfd) / samplesize / channels;
++ if (period_size != driver->period_size &&
++ !driver->ignorehwbuf)
++ {
++ printf("oss_driver: period size update: %u\n",
++ period_size);
++ driver->period_size = period_size;
++ driver->period_usecs =
++ ((double) driver->period_size /
++ (double) driver->sample_rate) * 1e6;
++ driver->engine->set_buffer_size(driver->engine,
++ driver->period_size);
++ }
++ }
++
++ if (driver->capture_channels > 0)
++ {
++ driver->indevbufsize = driver->period_size *
++ driver->capture_channels * samplesize;
++ driver->indevbuf = malloc(driver->indevbufsize);
++ if (driver->indevbuf == NULL)
++ {
++ jack_error( "OSS: malloc() failed: %s@%i",
++ __FILE__, __LINE__);
++ return -1;
++ }
++ memset(driver->indevbuf, 0x00, driver->indevbufsize);
++ }
++ else
++ {
++ driver->indevbufsize = 0;
++ driver->indevbuf = NULL;
++ }
++
++ if (driver->playback_channels > 0)
++ {
++ driver->outdevbufsize = driver->period_size *
++ driver->playback_channels * samplesize;
++ driver->outdevbuf = malloc(driver->outdevbufsize);
++ if (driver->outdevbuf == NULL)
++ {
++ jack_error("OSS: malloc() failed: %s@%i",
++ __FILE__, __LINE__);
++ return -1;
++ }
++ memset(driver->outdevbuf, 0x00, driver->outdevbufsize);
++ }
++ else
++ {
++ driver->outdevbufsize = 0;
++ driver->outdevbuf = NULL;
++ }
++
++ printf("oss_driver: indevbuf %u B, outdevbuf %u B\n",
++ driver->indevbufsize, driver->outdevbufsize);
++
++ pthread_mutex_init(&driver->mutex_in, NULL);
++ pthread_mutex_init(&driver->mutex_out, NULL);
++# ifdef USE_BARRIER
++ pthread_barrier_init(&driver->barrier, NULL, 2);
++ sem_init(&driver->sem_start, 0, 0);
++# endif
++ driver->run = 1;
++ driver->threads = 0;
++ if (infd >= 0)
++ {
++ if (pthread_create(&driver->thread_in, NULL, io_thread,
++ driver) < 0)
++ {
++ jack_error("OSS: pthread_create() failed: %s@%i",
++ __FILE__, __LINE__);
++ return -1;
++ }
++ driver->threads |= 1;
++ }
++# ifdef USE_BARRIER
++ if (outfd >= 0)
++# else
++ if (outfd >= 0 && infd != outfd)
++# endif
++ {
++ if (pthread_create(&driver->thread_out, NULL, io_thread,
++ driver) < 0)
++ {
++ jack_error("OSS: pthread_create() failed: %s@%i",
++ __FILE__, __LINE__);
++ return -1;
++ }
++ driver->threads |= 2;
++ }
++
++# ifdef USE_BARRIER
++ sem_post(&driver->sem_start);
++ sem_post(&driver->sem_start);
++# endif
++
++ return 0;
++}
++
++
++static int oss_driver_stop (oss_driver_t *driver)
++{
++ void *retval;
++
++ driver->run = 0;
++ if (driver->threads & 1)
++ {
++ if (pthread_join(driver->thread_in, &retval) < 0)
++ {
++ jack_error("OSS: pthread_join() failed: %s@%i",
++ __FILE__, __LINE__);
++ return -1;
++ }
++ }
++ if (driver->threads & 2)
++ {
++ if (pthread_join(driver->thread_out, &retval) < 0)
++ {
++ jack_error("OSS: pthread_join() failed: %s@%i",
++ __FILE__, __LINE__);
++ return -1;
++ }
++ }
++# ifdef USE_BARRIER
++ sem_destroy(&driver->sem_start);
++ pthread_barrier_destroy(&driver->barrier);
++# endif
++ pthread_mutex_destroy(&driver->mutex_in);
++ pthread_mutex_destroy(&driver->mutex_out);
++
++ if (driver->outfd >= 0 && driver->outfd != driver->infd)
++ {
++ close(driver->outfd);
++ driver->outfd = -1;
++ }
++ if (driver->infd >= 0)
++ {
++ close(driver->infd);
++ driver->infd = -1;
++ }
++
++ if (driver->indevbuf != NULL)
++ {
++ free(driver->indevbuf);
++ driver->indevbuf = NULL;
++ }
++ if (driver->outdevbuf != NULL)
++ {
++ free(driver->outdevbuf);
++ driver->outdevbuf = NULL;
++ }
++
++ return 0;
++}
++
++
++static int oss_driver_read (oss_driver_t *driver, jack_nframes_t nframes)
++{
++ int channel;
++ jack_sample_t *portbuf;
++ JSList *node;
++ jack_port_t *port;
++
++ if (nframes != driver->period_size)
++ {
++ jack_error(
++ "OSS: read failed nframes != period_size (%u/%u): %s@%i",
++ nframes, driver->period_size, __FILE__, __LINE__);
++ return -1;
++ }
++
++ pthread_mutex_lock(&driver->mutex_in);
++
++ node = driver->capture_ports;
++ channel = 0;
++ while (node != NULL)
++ {
++ port = (jack_port_t *) node->data;
++
++ if (jack_port_connected(port))
++ {
++ portbuf = jack_port_get_buffer(port, nframes);
++ copy_and_convert_in(portbuf, driver->indevbuf,
++ nframes, channel,
++ driver->capture_channels,
++ driver->bits);
++ }
++
++ node = jack_slist_next(node);
++ channel++;
++ }
++
++ pthread_mutex_unlock(&driver->mutex_in);
++
++ return 0;
++}
++
++
++static int oss_driver_write (oss_driver_t *driver, jack_nframes_t nframes)
++{
++ int channel;
++ jack_sample_t *portbuf;
++ JSList *node;
++ jack_port_t *port;
++
++ if (nframes != driver->period_size)
++ {
++ jack_error(
++ "OSS: write failed nframes != period_size (%u/%u): %s@%i",
++ nframes, driver->period_size, __FILE__, __LINE__);
++ return -1;
++ }
++
++ pthread_mutex_lock(&driver->mutex_out);
++
++ node = driver->playback_ports;
++ channel = 0;
++ while (node != NULL)
++ {
++ port = (jack_port_t *) node->data;
++
++ if (jack_port_connected(port))
++ {
++ portbuf = jack_port_get_buffer(port, nframes);
++ copy_and_convert_out(driver->outdevbuf, portbuf,
++ nframes, channel,
++ driver->playback_channels,
++ driver->bits);
++ }
++
++ node = jack_slist_next(node);
++ channel++;
++ }
++
++ pthread_mutex_unlock(&driver->mutex_out);
++
++ return 0;
++}
++
++
++static int oss_driver_null_cycle (oss_driver_t *driver, jack_nframes_t nframes)
++{
++ pthread_mutex_lock(&driver->mutex_in);
++ memset(driver->indevbuf, 0x00, driver->indevbufsize);
++ pthread_mutex_unlock(&driver->mutex_in);
++
++ pthread_mutex_lock(&driver->mutex_out);
++ memset(driver->outdevbuf, 0x00, driver->outdevbufsize);
++ pthread_mutex_unlock(&driver->mutex_out);
++
++ return 0;
++}
++
++
++static int oss_driver_bufsize (oss_driver_t *driver, jack_nframes_t nframes)
++{
++ oss_driver_stop(driver);
++
++ driver->period_size = nframes;
++ driver->period_usecs =
++ ((double) driver->period_size /
++ (double) driver->sample_rate) * 1e6;
++ printf("oss_driver: period size update: %u\n", driver->period_size);
++
++ oss_driver_start(driver);
++
++ return 0;
++}
++
++
++/* internal driver thread */
++
++
++#ifdef USE_BARRIER
++static inline void synchronize (oss_driver_t *driver)
++{
++ if (driver->threads == 3)
++ {
++ if (pthread_barrier_wait(&driver->barrier) ==
++ PTHREAD_BARRIER_SERIAL_THREAD)
++ {
++ driver->last_wait_ust = jack_get_microseconds();
++ driver->engine->run_cycle(driver->engine,
++ driver->period_size, 0);
++ }
++ }
++ else
++ {
++ driver->last_wait_ust = jack_get_microseconds();
++ driver->engine->run_cycle(driver->engine,
++ driver->period_size, 0);
++ }
++}
++#endif
++
++
++static void *io_thread (void *param)
++{
++ int schedpol;
++ size_t localsize;
++ void *localbuf;
++ oss_driver_t *driver = (oss_driver_t *) param;
++ struct sched_param schedp;
++
++ if (pthread_getschedparam(pthread_self(), &schedpol, &schedp) == 0)
++ {
++ schedpol = SCHED_FIFO;
++ schedp.sched_priority = sched_get_priority_max(SCHED_FIFO) - 1;
++ if (pthread_setschedparam(pthread_self(), schedpol,
++ &schedp) < 0)
++ {
++ puts("oss_driver: pthread_setschedparam() failed\n");
++ }
++ }
++ else
++ {
++ puts("oss_driver: pthread_getschedparam() failed\n");
++ }
++
++# ifdef USE_BARRIER
++ sem_wait(&driver->sem_start);
++
++ if (pthread_self() == driver->thread_in)
++ {
++ localsize = driver->indevbufsize;
++ localbuf = malloc(localsize);
++ if (localbuf == NULL)
++ {
++ jack_error("OSS: malloc() failed: %s@%i",
++ __FILE__, __LINE__);
++ return NULL;
++ }
++
++ while (driver->run)
++ {
++ if (read(driver->infd, localbuf, localsize) <
++ (ssize_t) localsize)
++ {
++ /*jack_error("OSS: read() failed: %s@%i",
++ __FILE__, __LINE__);*/
++ break;
++ }
++
++ pthread_mutex_lock(&driver->mutex_in);
++ memcpy(driver->indevbuf, localbuf, localsize);
++ pthread_mutex_unlock(&driver->mutex_in);
++
++ synchronize(driver);
++ }
++
++ free(localbuf);
++ }
++ else if (pthread_self() == driver->thread_out)
++ {
++ localsize = driver->outdevbufsize;
++ localbuf = malloc(localsize);
++ if (localbuf == NULL)
++ {
++ jack_error("OSS: malloc() failed: %s@%i",
++ __FILE__, __LINE__);
++ return NULL;
++ }
++
++ while (driver->run)
++ {
++ pthread_mutex_lock(&driver->mutex_out);
++ memcpy(localbuf, driver->outdevbuf, localsize);
++ pthread_mutex_unlock(&driver->mutex_out);
++
++ if (write(driver->outfd, localbuf, localsize) <
++ (ssize_t) localsize)
++ {
++ /*jack_error("OSS: write() failed: %s@%i",
++ __FILE__, __LINE__);*/
++ break;
++ }
++
++ synchronize(driver);
++ }
++
++ free(localbuf);
++ }
++# else
++ localsize = (driver->indevbufsize >= driver->outdevbufsize) ?
++ driver->indevbufsize : driver->outdevbufsize;
++ localbuf = malloc(localsize);
++ if (localbuf == NULL)
++ {
++ jack_error("OSS: malloc() failed: %s@%i", __FILE__, __LINE__);
++ return NULL;
++ }
++
++ while (driver->run)
++ {
++ if (driver->playback_channels > 0)
++ {
++ pthread_mutex_lock(&driver->mutex_out);
++ memcpy(localbuf, driver->outdevbuf,
++ driver->outdevbufsize);
++ pthread_mutex_unlock(&driver->mutex_out);
++
++ if (write(driver->outfd, localbuf,
++ driver->outdevbufsize) <
++ (ssize_t) driver->outdevbufsize)
++ {
++ jack_error("OSS: write() failed: %s@%i",
++ __FILE__, __LINE__);
++ break;
++ }
++ }
++
++ if (driver->capture_channels > 0)
++ {
++ if (read(driver->infd, localbuf,
++ driver->indevbufsize) <
++ (ssize_t) driver->indevbufsize)
++ {
++ jack_error("OSS: read() failed: %s@%i",
++ __FILE__, __LINE__);
++ break;
++ }
++
++ pthread_mutex_lock(&driver->mutex_in);
++ memcpy(driver->indevbuf, localbuf,
++ driver->indevbufsize);
++ pthread_mutex_unlock(&driver->mutex_in);
++ }
++
++ driver->last_wait_ust = jack_get_microseconds();
++ driver->engine->run_cycle(driver->engine,
++ driver->period_size, 0);
++ }
++
++ free(localbuf);
++# endif
++
++ return NULL;
++}
++
++
++/* jack driver published interface */
++
++
++const char driver_client_name[] = "oss";
++
++
++void driver_finish (jack_driver_t *);
++
++
++jack_driver_desc_t * driver_get_descriptor ()
++{
++ jack_driver_desc_t *desc;
++ jack_driver_param_desc_t *params;
++
++ desc = (jack_driver_desc_t *) calloc(1, sizeof(jack_driver_desc_t));
++ if (desc == NULL)
++ {
++ printf("oss_driver: malloc() failed: %s@%i\n",
++ __FILE__, __LINE__);
++ return NULL;
++ }
++ strcpy(desc->name, driver_client_name);
++ desc->nparams = 8;
++
++ params = calloc(desc->nparams, sizeof(jack_driver_param_desc_t));
++ memcpy(params, oss_params,
++ OSS_DRIVER_N_PARAMS * sizeof(jack_driver_param_desc_t));
++ desc->params = params;
++
++ return desc;
++}
++
++
++jack_driver_t * driver_initialize (jack_client_t *client,
++ JSList * params)
++{
++ int bits = OSS_DRIVER_DEF_BITS;
++ jack_nframes_t sample_rate = OSS_DRIVER_DEF_FS;
++ jack_nframes_t period_size = OSS_DRIVER_DEF_BLKSIZE;
++ unsigned int capture_channels = OSS_DRIVER_DEF_INS;
++ unsigned int playback_channels = OSS_DRIVER_DEF_OUTS;
++ const JSList *pnode;
++ const jack_driver_param_t *param;
++ oss_driver_t *driver;
++
++ driver = (oss_driver_t *) malloc(sizeof(oss_driver_t));
++ if (driver == NULL)
++ {
++ jack_error("OSS: malloc() failed: %s@%i", __FILE__, __LINE__);
++ return NULL;
++ }
++ jack_driver_init((jack_driver_t *) driver);
++
++ driver->attach = (JackDriverAttachFunction) oss_driver_attach;
++ driver->detach = (JackDriverDetachFunction) oss_driver_detach;
++ driver->start = (JackDriverStartFunction) oss_driver_start;
++ driver->stop = (JackDriverStopFunction) oss_driver_stop;
++ driver->read = (JackDriverReadFunction) oss_driver_read;
++ driver->write = (JackDriverWriteFunction) oss_driver_write;
++ driver->null_cycle = (JackDriverNullCycleFunction)
++ oss_driver_null_cycle;
++ driver->bufsize = (JackDriverBufSizeFunction) oss_driver_bufsize;
++
++ driver->indev = NULL;
++ driver->outdev = NULL;
++ driver->ignorehwbuf = 0;
++
++ pnode = params;
++ while (pnode != NULL)
++ {
++ param = (const jack_driver_param_t *) pnode->data;
++
++ switch (param->character)
++ {
++ case 's':
++ sample_rate = param->value.ui;
++ break;
++ case 'b':
++ period_size = param->value.ui;
++ break;
++ case 'w':
++ bits = param->value.i;
++ break;
++ case 'c':
++ capture_channels = param->value.ui;
++ break;
++ case 'p':
++ playback_channels = param->value.ui;
++ break;
++ case 'i':
++ driver->indev = strdup(param->value.str);
++ break;
++ case 'o':
++ driver->outdev = strdup(param->value.str);
++ break;
++ case 'd':
++ driver->ignorehwbuf = 1;
++ break;
++ case 'h':
++ puts("-s <fs>\tsample rate");
++ puts("-b <size>\tperiod size");
++ puts("-w <bits>\tword length");
++ puts("-c <chs>\tcapture channels");
++ puts("-p <chs>\tplayback channels");
++ puts("-i <dev>\tcapture device");
++ puts("-o <dev>\tplayback device");
++ puts("-h\tthis help");
++ break;
++ }
++ pnode = jack_slist_next(pnode);
++ }
++
++ driver->sample_rate = sample_rate;
++ driver->period_size = period_size;
++ driver->bits = bits;
++ driver->capture_channels = capture_channels;
++ driver->playback_channels = playback_channels;
++
++ driver->period_usecs =
++ ((double) period_size / (double) sample_rate) * 1e6;
++ driver->last_wait_ust = 0;
++
++ driver->finish = driver_finish;
++
++ if (driver->indev == NULL)
++ driver->indev = strdup("/dev/dsp");
++ if (driver->outdev == NULL)
++ driver->outdev = strdup(driver->indev);
++ driver->infd = -1;
++ driver->outfd = -1;
++ switch (driver->bits)
++ {
++# ifndef OSS_ENDIAN
++# ifdef __GNUC__
++# if (defined(__i386__) || defined(__alpha__) || defined(__arm__) || defined(__x86_64__))
++# define OSS_LITTLE_ENDIAN 1234
++# define OSS_ENDIAN OSS_LITTLE_ENDIAN
++# else
++# define OSS_BIG_ENDIAN 4321
++# define OSS_ENDIAN OSS_BIG_ENDIAN
++# endif
++# else /* __GNUC__ */
++# if (defined(_AIX) || defined(AIX) || defined(sparc) || defined(__hppa) || defined(PPC) || defined(__powerpc__) && !defined(i386) && !defined(__i386) && !defined(__i386__))
++# define OSS_BIG_ENDIAN 4321
++# define OSS_ENDIAN OSS_BIG_ENDIAN
++# else
++# define OSS_LITTLE_ENDIAN 1234
++# define OSS_ENDIAN OSS_LITTLE_ENDIAN
++# endif
++# endif /* __GNUC__ */
++# endif /* OSS_ENDIAN */
++# if (OSS_ENDIAN == 1234)
++ /* little-endian architectures */
++ case 24: /* little-endian LSB aligned 24-bits in 32-bits integer */
++ driver->format = 0x00008000;
++ break;
++ case 32: /* little-endian 32-bit integer */
++ driver->format = 0x00001000;
++ break;
++ case 64: /* native-endian 64-bit float */
++ driver->format = 0x00004000;
++ break;
++ case 16: /* little-endian 16-bit integer */
++ default:
++ driver->format = 0x00000010;
++ break;
++ /* big-endian architectures */
++# else
++ case 24: /* big-endian LSB aligned 24-bits in 32-bits integer */
++ break;
++ driver->format = 0x00010000;
++ case 32: /* big-endian 32-bit integer */
++ driver->format = 0x00002000;
++ break;
++ case 64: /* native-endian 64-bit float */
++ driver->format = 0x00004000;
++ break;
++ case 16: /* big-endian 16-bit integer */
++ default:
++ driver->format = 0x00000020;
++# endif
++ }
++
++ driver->indevbuf = driver->outdevbuf = NULL;
++
++ driver->capture_ports = NULL;
++ driver->playback_ports = NULL;
++
++ driver->engine = NULL;
++ driver->client = client;
++
++ return ((jack_driver_t *) driver);
++}
++
++
++void driver_finish (jack_driver_t *driver)
++{
++ free(((oss_driver_t *) driver)->indev);
++ free(((oss_driver_t *) driver)->outdev);
++ free(driver);
++}
++
+diff -urN jack-audio-connection-kit-0.94.0/drivers/oss/oss_driver.h drivers/oss/oss_driver.h
+--- jack-audio-connection-kit-0.94.0/drivers/oss/oss_driver.h 1970-01-01 02:00:00.000000000 +0200
++++ drivers/oss/oss_driver.h 2004-02-14 17:23:01.000000000 +0200
+@@ -0,0 +1,92 @@
++/*
++
++ OSS driver for Jack
++ Copyright (C) 2003-2004 Jussi Laako <jussi@sonarnerd.net>
++
++ 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., 59 Temple Place, Suite 330, Boston,
++ MA 02111-1307 USA
++
++*/
++
++
++#ifndef __JACK_OSS_DRIVER_H__
++#define __JACK_OSS_DRIVER_H__
++
++#ifndef USE_BARRIER
++#include <pthread.h>
++#else
++#include <pthread.h>
++#include <semaphore.h>
++#endif
++
++#include <jack/types.h>
++#include <jack/jslist.h>
++#include <jack/driver.h>
++#include <jack/jack.h>
++
++
++#define OSS_DRIVER_DEF_FS 44100
++#define OSS_DRIVER_DEF_BLKSIZE 1024
++#define OSS_DRIVER_DEF_BITS 16
++#define OSS_DRIVER_DEF_INS 2
++#define OSS_DRIVER_DEF_OUTS 2
++
++
++typedef jack_default_audio_sample_t jack_sample_t;
++
++typedef struct _oss_driver
++{
++ JACK_DRIVER_DECL
++
++ jack_nframes_t sample_rate;
++ jack_nframes_t period_size;
++ int bits;
++ unsigned int capture_channels;
++ unsigned int playback_channels;
++
++ char *indev;
++ char *outdev;
++ int infd;
++ int outfd;
++ int format;
++ int ignorehwbuf;
++
++ size_t indevbufsize;
++ size_t outdevbufsize;
++ size_t portbufsize;
++ void *indevbuf;
++ void *outdevbuf;
++
++ JSList *capture_ports;
++ JSList *playback_ports;
++
++ jack_engine_t *engine;
++ jack_client_t *client;
++
++ volatile int run;
++ volatile int threads;
++ pthread_t thread_in;
++ pthread_t thread_out;
++ pthread_mutex_t mutex_in;
++ pthread_mutex_t mutex_out;
++# ifdef USE_BARRIER
++ pthread_barrier_t barrier;
++ sem_t sem_start;
++# endif
++} oss_driver_t;
++
++
++#endif
++