[linux-audio-dev] [PATCH] oss support for jack

Jussi Laako jussi.laako at pp.inet.fi
Fri Nov 14 20:47:27 UTC 2003


Hi,

I've written preliminary OSS driver for JACK. Patch for jack 0.80
attached.

This is by no means final, this is something pre-alpha, but seems to
work at least with alsaplayer. It's likely to contains errors in jack
driver implementation. All comments/patches/anything is welcome..

If you are compiling with OSS Lite, please comment out the non-S16
formats.

RedHat RPMs and patch available at http://www.sonarnerd.net/linux/ ,
SuSE 9 packages coming.


-- 
Jussi Laako <jussi.laako at pp.inet.fi>
-------------- next part --------------
--- jack-audio-connection-kit-0.80.0/configure.in	2003-08-29 01:21:07.000000000 +0300
+++ jackit/configure.in	2003-11-14 00:43:54.000000000 +0200
@@ -112,8 +112,8 @@
 
 JACK_CORE_CFLAGS="-I\$(top_srcdir) -D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS -Wall $SHM_FLAGS"
 
-JACK_CFLAGS="$JACK_CORE_CFLAGS -g"
-JACK_OPT_CFLAGS="$JACK_CORE_CFLAGS -O3 -fomit-frame-pointer -ffast-math -fstrength-reduce -funroll-loops -fmove-all-movables"
+JACK_CFLAGS="$JACK_CORE_CFLAGS -g $CFLAGS"
+JACK_OPT_CFLAGS="$JACK_CORE_CFLAGS -march=pentium2 -mcpu=pentium4 -O3 -ffast-math -funroll-loops -fprefetch-loop-arrays"
 
 AC_ARG_ENABLE(optimize,
               [  --enable-optimize       ask the compiler for its best optimizations],
@@ -295,6 +295,7 @@
 drivers/Makefile
 drivers/alsa/Makefile
 drivers/dummy/Makefile
+drivers/oss/Makefile
 example-clients/Makefile
 doc/Makefile
 doc/reference.doxygen
--- jack-audio-connection-kit-0.80.0/drivers/Makefile.am	2003-08-29 02:41:21.000000000 +0300
+++ jackit/drivers/Makefile.am	2003-11-14 00:43:54.000000000 +0200
@@ -6,6 +6,6 @@
 ALSA_DIR =
 endif
 
-SUBDIRS = dummy $(ALSA_DIR)
+SUBDIRS = dummy $(ALSA_DIR) oss
 
-DIST_SUBDIRS = dummy alsa 
+DIST_SUBDIRS = dummy alsa oss
--- jack-audio-connection-kit-0.80.0/drivers/oss/oss_driver.h	1970-01-01 02:00:00.000000000 +0200
+++ jackit/drivers/oss/oss_driver.h	2003-11-14 20:40:04.000000000 +0200
@@ -0,0 +1,76 @@
+/*
+
+	OSS driver for Jack
+	Copyright (C) 2003 Jussi Laako <jussi at 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__
+
+#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
+#define OSS_DRIVER_MAX_PORTS	16
+
+
+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;
+
+	size_t indevbufsize;
+	size_t outdevbufsize;
+	size_t portbufsize;
+	void *indevbuf;
+	void *outdevbuf;
+	jack_sample_t *inportbufs[OSS_DRIVER_MAX_PORTS];
+	jack_sample_t *outportbufs[OSS_DRIVER_MAX_PORTS];
+
+	JSList *capture_ports;
+	JSList *playback_ports;
+
+	jack_engine_t *engine;
+	jack_client_t *client;
+} oss_driver_t;
+
+
+#endif
+
--- jack-audio-connection-kit-0.80.0/drivers/oss/oss_driver.c	1970-01-01 02:00:00.000000000 +0200
+++ jackit/drivers/oss/oss_driver.c	2003-11-14 22:13:40.000000000 +0200
@@ -0,0 +1,694 @@
+/*
+
+	OSS driver for Jack
+	Copyright (C) 2003 Jussi Laako <jussi at 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 <jack/types.h>
+#include <jack/internal.h>
+#include <jack/engine.h>
+#include <jack/time.h>
+
+#include "oss_driver.h"
+
+// #undef DEBUG_WAKEUP
+
+
+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;
+	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 / 0x7fffff00;
+			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;
+	}
+}
+
+
+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;
+	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 = 0x7fffff00;
+			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;
+	}
+}
+
+
+static void set_fragment (int fd, int fragsize, int fragcount)
+{
+	int fragsize_2p;
+	int fragments;
+
+	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 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 channel;
+	size_t samplesize;
+	size_t fragsize;
+	const char *indev = driver->indev;
+	const char *outdev = driver->outdev;
+
+	switch (driver->bits)
+	{
+		case 0:
+			samplesize = sizeof(unsigned int);
+			break;
+		case 24:
+		case 32:
+			samplesize = sizeof(int);
+			break;
+		case 16:
+		default:
+			samplesize = sizeof(short);
+			break;
+	}
+	if (strcmp(indev, outdev) != 0)
+	{
+		infd = open(indev, O_RDONLY);
+		outfd = open(outdev, O_WRONLY);
+		if (infd < 0)
+		{
+			jack_error(
+				"OSS: failed to open input device %s: %s@%i",
+				indev, __FILE__, __LINE__);
+		}
+		if (outfd < 0)
+		{
+			jack_error(
+				"OSS: failed to open output device %s: %s@%i",
+				outdev, __FILE__, __LINE__);
+		}
+		fragsize = driver->period_size * driver->capture_channels * 
+			samplesize;
+		//set_fragment(infd, fragsize, 0xffff / fragsize);
+		set_fragment(infd, fragsize, 2);
+		fragsize = driver->period_size * driver->playback_channels *
+			samplesize;
+		//set_fragment(outfd, fragsize, 0xffff / fragsize);
+		set_fragment(outfd, fragsize, 2);
+	}
+	else
+	{
+		infd = outfd = open(indev, O_RDWR);
+		if (infd < 0)
+		{
+			jack_error(
+				"OSS: failed to open device %s: %s@%i",
+				indev, __FILE__, __LINE__);
+		}
+		fragsize = driver->period_size * driver->capture_channels * 
+			samplesize;
+		//set_fragment(infd, fragsize, 0xffff / fragsize);
+		set_fragment(infd, fragsize, 2);
+		if (ioctl(infd, SNDCTL_DSP_SETDUPLEX, 0) < 0)
+		{
+			jack_error(
+				"OSS: failed to enable full duplex for %s: %s@%i",
+				indev, __FILE__, __LINE__);
+		}
+	}
+	driver->infd = infd;
+	driver->outfd = outfd;
+	
+	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));
+
+	if (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));
+	}
+
+	driver->indevbufsize = driver->period_size * 
+		driver->capture_channels * samplesize;
+	driver->outdevbufsize = driver->period_size * 
+		driver->playback_channels * samplesize;
+	driver->indevbuf = malloc(driver->indevbufsize);
+	driver->outdevbuf = malloc(driver->outdevbufsize);
+	if (driver->indevbuf == NULL || driver->outdevbuf == NULL)
+	{
+		jack_error("OSS: malloc() failed: %s@%i", __FILE__, __LINE__);
+		return -1;
+		
+	}
+	memset(driver->indevbuf, 0x00, driver->indevbufsize);
+	memset(driver->outdevbuf, 0x00, driver->outdevbufsize);
+	printf("oss_driver: indevbuf %u B, outdevbuf %u B\n",
+		driver->indevbufsize, driver->outdevbufsize);
+
+	driver->portbufsize = driver->period_size * sizeof(jack_sample_t);
+	for (channel = 0; channel < driver->capture_channels; channel++)
+	{
+		driver->inportbufs[channel] = (jack_sample_t *) 
+			malloc(driver->portbufsize);
+		if (driver->inportbufs[channel] == NULL)
+		{
+			jack_error("OSS: malloc() failed: %s@%i",
+				__FILE__, __LINE__);
+			return -1;
+		}
+		memset(driver->inportbufs[channel], 0x00, 
+			driver->portbufsize);
+	}
+	for (channel = 0; channel < driver->playback_channels; channel++)
+	{
+		driver->outportbufs[channel] = (jack_sample_t *) 
+			malloc(driver->portbufsize);
+		if (driver->outportbufs[channel] == NULL)
+		{
+			jack_error("OSS: malloc() failed: %s@%i",
+				__FILE__, __LINE__);
+			return -1;
+		}
+		memset(driver->outportbufs[channel], 0x00, 
+			driver->portbufsize);
+	}
+	printf("oss_driver: %u period buffers of size %u B\n", 
+		driver->capture_channels + driver->playback_channels,
+		driver->portbufsize);
+
+	return 0;
+}
+
+
+static int oss_driver_stop (oss_driver_t *driver)
+{
+	unsigned int channel;
+
+	if (driver->outfd >= 0 && driver->outfd != driver->infd)
+	{
+		close(driver->outfd);
+		driver->outfd = -1;
+	}
+	if (driver->infd >= 0)
+	{
+		close(driver->infd);
+		driver->infd = -1;
+	}
+
+	for (channel = 0; channel < driver->capture_channels; channel++)
+	{
+		if (driver->inportbufs[channel] != NULL)
+		{
+			free(driver->inportbufs[channel]);
+			driver->inportbufs[channel] = NULL;
+		}
+	}
+	for (channel = 0; channel < driver->playback_channels; channel++)
+	{
+		if (driver->outportbufs[channel] != NULL)
+		{
+			free(driver->outportbufs[channel]);
+			driver->outportbufs[channel] = NULL;
+		}
+	}
+	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;
+	}
+
+	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++;
+	}
+
+	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;
+	}
+
+	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++;
+	}
+
+	return 0;
+}
+
+
+static int oss_driver_null_cycle (oss_driver_t *driver, jack_nframes_t nframes)
+{
+	return 0;
+}
+
+
+static jack_nframes_t oss_driver_wait (oss_driver_t *driver, int fd, 
+	int *status, float *delayed_usecs)
+{
+	*status = 0;
+	*delayed_usecs = 0;
+
+	if (write(driver->outfd, driver->outdevbuf, driver->outdevbufsize) <
+		(ssize_t) driver->outdevbufsize)
+	{
+		//jack_error("OSS: write() failed: %s@%i", __FILE__, __LINE__);
+		oss_driver_stop(driver);
+		*status = 1;
+	}
+
+	if (read(driver->infd, driver->indevbuf, driver->indevbufsize) <
+		(ssize_t) driver->indevbufsize)
+	{
+		//jack_error("OSS: read() failed: %s@%i", __FILE__, __LINE__);
+		oss_driver_stop(driver);
+		*status = 1;
+	}
+
+	driver->last_wait_ust = jack_get_microseconds();
+
+	return driver->period_size;
+}
+
+
+/* - */
+
+
+const char driver_client_name[] = "oss";
+
+
+void driver_finish (jack_driver_t *);
+
+
+jack_driver_t * driver_initialize (jack_client_t *client, 
+	int argc, char *argv[])
+{
+	int opt;
+	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;
+
+	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->wait = (JackDriverWaitFunction) oss_driver_wait;
+
+	driver->indev = NULL;
+	driver->outdev = NULL;
+	opt = 1;
+	while (opt < (argc - 1))
+	{
+		if (strcmp(argv[opt], "-s") == 0)
+			sample_rate = (jack_nframes_t) atol(argv[++opt]);
+		if (strcmp(argv[opt], "-b") == 0)
+			period_size = (jack_nframes_t) atol(argv[++opt]);
+		if (strcmp(argv[opt], "-w") == 0)
+			bits = atoi(argv[++opt]);
+		if (strcmp(argv[opt], "-c") == 0)
+			capture_channels = (unsigned int) atoi(argv[++opt]);
+		if (strcmp(argv[opt], "-p") == 0)
+			playback_channels = (unsigned int) atoi(argv[++opt]);
+		if (strcmp(argv[opt], "-i") == 0)
+			driver->indev = strdup(argv[++opt]);
+		if (strcmp(argv[opt], "-o") == 0)
+			driver->outdev = strdup(argv[++opt]);
+		if (strcmp(argv[opt], "-h") == 0)
+		{
+			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");
+		}
+		opt++;
+	}
+	
+	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)
+	{
+		case 0:
+			driver->format = AFMT_SPDIF_RAW;
+			break;
+		case 24:
+			driver->format = AFMT_S24_NE;
+			break;
+		case 32:
+			driver->format = AFMT_S32_NE;
+			break;
+		case 16:
+		default:
+			driver->format = AFMT_S16_NE;
+			break;
+	}
+
+	driver->indevbuf = driver->outdevbuf = NULL;
+	memset(driver->inportbufs, 0x00, sizeof(driver->inportbufs));
+	memset(driver->outportbufs, 0x00, sizeof(driver->outportbufs));
+
+	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);
+}
+


More information about the Linux-audio-dev mailing list