[Pkg-alsa-devel] [Debian ALSA CVS] debian/alsa-oss (4 files)

David B Harris dbharris-guest@quantz.debian.org
Mon, 01 Mar 2004 01:46:25 +0100


    Date: Monday, March 1, 2004 @ 01:46:25
  Author: dbharris-guest
    Path: /cvsroot/pkg-alsa/debian/alsa-oss

Modified: debian/changelog
 Removed: alsa-oss.c aoss.1 aoss.in

New upstream release of alsa-oss, 1.0.3a


------------------+
 alsa-oss.c       | 2229 -----------------------------------------------------
 aoss.1           |   42 
 aoss.in          |    9 
 debian/changelog |    3 
 4 files changed, 2 insertions(+), 2281 deletions(-)


Index: debian/alsa-oss/alsa-oss.c
diff -u debian/alsa-oss/alsa-oss.c:1.1.1.2 debian/alsa-oss/alsa-oss.c:removed
--- debian/alsa-oss/alsa-oss.c:1.1.1.2	Mon Dec  1 15:06:23 2003
+++ debian/alsa-oss/alsa-oss.c	Mon Mar  1 01:46:25 2004
@@ -1,2229 +0,0 @@
-/*
- *  OSS -> ALSA compatibility layer
- *  Copyright (c) by Abramo Bagnara <abramo@alsa-project.org>
- *
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 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
- *
- */
-
-#define _GNU_SOURCE
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/stat.h>
-#include <sys/poll.h>
-#include <sys/select.h>
-#include <sys/mman.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <dlfcn.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <errno.h>
-#include <assert.h>
-#include <linux/soundcard.h>
-#include <alsa/asoundlib.h>
-
-snd_pcm_uframes_t _snd_pcm_boundary(snd_pcm_t *pcm);
-snd_pcm_uframes_t _snd_pcm_mmap_hw_ptr(snd_pcm_t *pcm);
-
-static int debug = 0;
-
-#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95)
-#define NEW_MACRO_VARARGS
-#endif
-
-#if 1
-#define DEBUG_POLL
-#define DEBUG_SELECT
-#ifdef NEW_MACRO_VARARGS
-#define DEBUG(...) do { if (debug) fprintf(stderr, __VA_ARGS__); } while (0)
-#else /* !NEW_MACRO_VARARGS */
-#define DEBUG(args...) do { if (debug) fprintf(stderr, ##args); } while (0)
-#endif
-#else
-#ifdef NEW_MACRO_VARARGS
-#define DEBUG(...)
-#else /* !NEW_MACRO_VARARGS */
-#define DEBUG(args...)
-#endif
-#endif
-
-int (*_select)(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
-int (*_poll)(struct pollfd *ufds, unsigned int nfds, int timeout);
-int (*_open)(const char *file, int oflag, ...);
-int (*_close)(int fd);
-ssize_t (*_write)(int fd, const void *buf, size_t n);
-ssize_t (*_read)(int fd, void *buf, size_t n);
-int (*_ioctl)(int fd, unsigned long request, ...);
-int (*_fcntl)(int fd, int cmd, ...);
-void *(*_mmap)(void *addr, size_t len, int prot, int flags, int fd, off_t offset);
-int (*_munmap)(void* addr, size_t len);
-
-typedef struct ops {
-	int (*open)(const char *file, int oflag, ...);
-	int (*close)(int fd);
-	ssize_t (*write)(int fd, const void *buf, size_t n);
-	ssize_t (*read)(int fd, void *buf, size_t n);
-	int (*ioctl)(int fd, unsigned long request, ...);
-	int (*fcntl)(int fd, int cmd, ...);
-	void *(*mmap)(void *addr, size_t len, int prot, int flags, int fd, off_t offset);
-	int (*munmap)(int fd, void* addr, size_t len);
-} ops_t;
-
-
-typedef struct {
-	snd_pcm_t *pcm;
-	size_t frame_bytes;
-	snd_pcm_uframes_t period_size;
-	unsigned int periods;
-	snd_pcm_uframes_t buffer_size;
-	size_t bytes;
-	snd_pcm_uframes_t boundary;
-	snd_pcm_uframes_t old_hw_ptr;
-	unsigned int stopped:1;
-	void *mmap_buffer;
-	size_t mmap_bytes;
-	size_t mmap_buffer_bytes;
-	size_t mmap_period_bytes;
-	snd_pcm_channel_area_t *mmap_areas;
-	snd_pcm_uframes_t mmap_advance;
-} oss_dsp_stream_t;
-
-typedef struct {
-	unsigned int channels;
-	unsigned int rate;
-	unsigned int oss_format;
-	snd_pcm_format_t format;
-	unsigned int fragshift;
-	unsigned int maxfrags;
-	unsigned int subdivision;
-	oss_dsp_stream_t streams[2];
-} oss_dsp_t;
-
-
-typedef struct {
-	snd_mixer_t *mix;
-	unsigned int modify_counter;
-	snd_mixer_elem_t *elems[SOUND_MIXER_NRDEVICES];
-} oss_mixer_t;
-
-typedef enum {
-	FD_OSS_DSP,
-	FD_OSS_MIXER,
-	FD_CLASSES,
-} fd_class_t;
-
-static ops_t ops[FD_CLASSES];
-
-typedef struct {
-	int count;
-	fd_class_t class;
-	void *private;
-	void *mmap_area;
-} fd_t;
-
-static int open_max;
-static fd_t **fds;
-
-#define RETRY open_max
-#define OSS_MAJOR 14
-#define OSS_DEVICE_MIXER 0
-#define OSS_DEVICE_SEQUENCER 1
-#define OSS_DEVICE_MIDI 2
-#define OSS_DEVICE_DSP 3
-#define OSS_DEVICE_AUDIO 4
-#define OSS_DEVICE_DSPW 5
-#define OSS_DEVICE_SNDSTAT 6
-#define OSS_DEVICE_MUSIC 8
-#define OSS_DEVICE_DMMIDI 9
-#define OSS_DEVICE_DMFM 10
-#define OSS_DEVICE_AMIXER 11
-#define OSS_DEVICE_ADSP 12
-#define OSS_DEVICE_AMIDI 13
-#define OSS_DEVICE_ADMMIDI 14
-
-static snd_pcm_format_t oss_format_to_alsa(int format)
-{
-	switch (format) {
-	case AFMT_MU_LAW:	return SND_PCM_FORMAT_MU_LAW;
-	case AFMT_A_LAW:	return SND_PCM_FORMAT_A_LAW;
-	case AFMT_IMA_ADPCM:	return SND_PCM_FORMAT_IMA_ADPCM;
-	case AFMT_U8:		return SND_PCM_FORMAT_U8;
-	case AFMT_S16_LE:	return SND_PCM_FORMAT_S16_LE;
-	case AFMT_S16_BE:	return SND_PCM_FORMAT_S16_BE;
-	case AFMT_S8:		return SND_PCM_FORMAT_S8;
-	case AFMT_U16_LE:	return SND_PCM_FORMAT_U16_LE;
-	case AFMT_U16_BE:	return SND_PCM_FORMAT_U16_BE;
-	case AFMT_MPEG:		return SND_PCM_FORMAT_MPEG;
-	default:		return SND_PCM_FORMAT_U8;
-	}
-}
-
-static int alsa_format_to_oss(snd_pcm_format_t format)
-{
-	switch (format) {
-	case SND_PCM_FORMAT_MU_LAW:	return AFMT_MU_LAW;
-	case SND_PCM_FORMAT_A_LAW:	return AFMT_A_LAW;
-	case SND_PCM_FORMAT_IMA_ADPCM:	return AFMT_IMA_ADPCM;
-	case SND_PCM_FORMAT_U8:		return AFMT_U8;
-	case SND_PCM_FORMAT_S16_LE:	return AFMT_S16_LE;
-	case SND_PCM_FORMAT_S16_BE:	return AFMT_S16_BE;
-	case SND_PCM_FORMAT_S8:		return AFMT_S8;
-	case SND_PCM_FORMAT_U16_LE:	return AFMT_U16_LE;
-	case SND_PCM_FORMAT_U16_BE:	return AFMT_U16_BE;
-	case SND_PCM_FORMAT_MPEG:	return AFMT_MPEG;
-	default:			return -EINVAL;
-	}
-}
-
-static int oss_dsp_hw_params(oss_dsp_t *dsp)
-{
-	int k;
-	for (k = 1; k >= 0; --k) {
-		oss_dsp_stream_t *str = &dsp->streams[k];
-		snd_pcm_t *pcm = str->pcm;
-		snd_pcm_hw_params_t *hw;
-		int err;
-		unsigned int rate, periods_min;
-		if (!pcm)
-			continue;
-		str->frame_bytes = snd_pcm_format_physical_width(dsp->format) * dsp->channels / 8;
-		snd_pcm_hw_params_alloca(&hw);
-		snd_pcm_hw_params_any(pcm, hw);
-		dsp->format = oss_format_to_alsa(dsp->oss_format);
-
-		err = snd_pcm_hw_params_set_format(pcm, hw, dsp->format);
-		if (err < 0)
-			return err;
-		err = snd_pcm_hw_params_set_channels(pcm, hw, dsp->channels);
-		if (err < 0)
-			return err;
-
-		err = snd_pcm_hw_params_set_periods_integer(pcm, hw);
-		if (err < 0)
-			return err;
-		rate = dsp->rate;
-		err = snd_pcm_hw_params_set_rate_near(pcm, hw, &rate, 0);
-		if (err < 0)
-			return err;
-
-		if (str->mmap_buffer) {
-			snd_pcm_access_mask_t *mask;
-			snd_pcm_access_mask_alloca(&mask);
-			snd_pcm_access_mask_any(mask);
-			snd_pcm_access_mask_set(mask, SND_PCM_ACCESS_MMAP_INTERLEAVED);
-			snd_pcm_access_mask_set(mask, SND_PCM_ACCESS_MMAP_NONINTERLEAVED);
-			snd_pcm_access_mask_set(mask, SND_PCM_ACCESS_MMAP_COMPLEX);
-			err = snd_pcm_hw_params_set_access_mask(pcm, hw, mask);
-			if (err < 0)
-				return err;
-			err = snd_pcm_hw_params_set_period_size(pcm, hw, str->mmap_period_bytes / str->frame_bytes, 0);
-			if (err < 0)
-				return err;
-			err = snd_pcm_hw_params_set_buffer_size(pcm, hw, str->mmap_buffer_bytes / str->frame_bytes);
-			if (err < 0)
-				return err;
-			err = snd_pcm_hw_params_set_access(pcm, hw, SND_PCM_ACCESS_MMAP_INTERLEAVED);
-			if (err < 0)
-				return err;
-		} else {
-			err = snd_pcm_hw_params_set_access(pcm, hw, SND_PCM_ACCESS_RW_INTERLEAVED);
-			if (err < 0)
-				return err;
-			periods_min = 2;
-			err = snd_pcm_hw_params_set_periods_min(pcm, hw, &periods_min, 0);
-			if (err < 0)
-				return err;
-			if (dsp->maxfrags > 0) {
-				unsigned int periods_max = dsp->maxfrags;
-				err = snd_pcm_hw_params_set_periods_max(pcm, hw,
-									&periods_max, 0);
-				if (err < 0)
-					return err;
-			}
-			if (dsp->fragshift > 0) {
-				snd_pcm_uframes_t s = (1 << dsp->fragshift) / str->frame_bytes;
-				err = snd_pcm_hw_params_set_period_size_near(pcm, hw, &s, 0);
-			} else {
-				snd_pcm_uframes_t s = 16;
-				while (s * 2 < dsp->rate / 4) 
-					s *= 2;
-				err = snd_pcm_hw_params_set_period_size_near(pcm, hw, &s, 0);
-			}
-			if (err < 0)
-				return err;
-		}
-
-		err = snd_pcm_hw_params(pcm, hw);
-#if 0
-		if (debug)
-			snd_pcm_dump_setup(pcm, stderr);
-#endif
-		err = snd_pcm_hw_params_get_rate(hw, &dsp->rate, 0);
-		if (err < 0)
-			return err;
-		dsp->oss_format = alsa_format_to_oss(dsp->format);
-		err = snd_pcm_hw_params_get_period_size(hw, &str->period_size, 0);
-		if (err < 0)
-			return err;
-		err = snd_pcm_hw_params_get_periods(hw, &str->periods, 0);
-		if (err < 0)
-			return err;
-		str->buffer_size = str->periods * str->period_size;
-		free(str->mmap_areas);
-		str->mmap_areas = 0;
-		if (str->mmap_buffer) {
-			unsigned int c;
-			snd_pcm_channel_area_t *a;
-			unsigned int bits_per_sample, bits_per_frame;
-			str->mmap_areas = calloc(dsp->channels, sizeof(*str->mmap_areas));
-			if (!str->mmap_areas)
-				return -ENOMEM;
-			bits_per_sample = snd_pcm_format_physical_width(dsp->format);
-			bits_per_frame = bits_per_sample * dsp->channels;
-			a = str->mmap_areas;
-			for (c = 0; c < dsp->channels; c++, a++) {
-				a->addr = str->mmap_buffer;
-				a->first = bits_per_sample * c;
-				a->step = bits_per_frame;
-			}
-		}
-	}
-	return 0;
-}
-
-static int oss_dsp_sw_params(oss_dsp_t *dsp)
-{
-	int k;
-	for (k = 1; k >= 0; --k) {
-		oss_dsp_stream_t *str = &dsp->streams[k];
-		snd_pcm_t *pcm = str->pcm;
-		snd_pcm_sw_params_t *sw;
-		int err;
-		if (!pcm)
-			continue;
-		snd_pcm_sw_params_alloca(&sw);
-		snd_pcm_sw_params_current(pcm, sw);
-		snd_pcm_sw_params_set_xfer_align(pcm, sw, 1);
-		snd_pcm_sw_params_set_start_threshold(pcm, sw, 
-						      str->stopped ? str->buffer_size + 1 : 1);
-#if 1
-		snd_pcm_sw_params_set_stop_threshold(pcm, sw,
-						     str->mmap_buffer ? LONG_MAX :
-						     str->buffer_size);
-#else
-		snd_pcm_sw_params_set_stop_threshold(pcm, sw,
-						     LONG_MAX);
-		snd_pcm_sw_params_set_silence_threshold(pcm, sw,
-						       str->period_size);
-		snd_pcm_sw_params_set_silence_size(pcm, sw,
-						   str->period_size);
-#endif
-		err = snd_pcm_sw_params(pcm, sw);
-		if (err < 0)
-			return err;
-		str->boundary = _snd_pcm_boundary(pcm);
-	}
-	return 0;
-}
-
-static int oss_dsp_params(oss_dsp_t *dsp)
-{
-	int err;
-	err = oss_dsp_hw_params(dsp);
-	if (err < 0) 
-		return err;
-	err = oss_dsp_sw_params(dsp);
-	if (err < 0) 
-		return err;
-	return 0;
-}
-
-static int oss_dsp_close(int fd)
-{
-	int result = 0;
-	int k;
-	oss_dsp_t *dsp = fds[fd]->private;
-	for (k = 0; k < 2; ++k) {
-		int err;
-		oss_dsp_stream_t *str = &dsp->streams[k];
-		if (!str->pcm)
-			continue;
-		if (k == SND_PCM_STREAM_PLAYBACK) {
-			if (snd_pcm_state(str->pcm) != SND_PCM_STATE_OPEN)
-				snd_pcm_drain(str->pcm);
-		}
-		err = snd_pcm_close(str->pcm);
-		if (err < 0)
-			result = err;
-	}
-	free(dsp);
-	if (result < 0) {
-		errno = -result;
-		result = -1;
-	}
-	DEBUG("close(%d) -> %d", fd, result);
-	if (result < 0)
-		DEBUG("(errno=%d)\n", errno);
-	else
-		DEBUG("\n");
-	return 0;
-}
-
-static int oss_dsp_open(int card, int device, int oflag, mode_t mode)
-{
-	oss_dsp_t *dsp;
-	unsigned int pcm_mode = 0;
-	unsigned int streams, k;
-	int format = AFMT_MU_LAW;
-	int fd = -1;
-	int result;
-	char name[64];
-
-	switch (device) {
-	case OSS_DEVICE_DSP:
-		format = AFMT_U8;
-		sprintf(name, "dsp%d", card);
-		break;
-	case OSS_DEVICE_DSPW:
-		format = AFMT_S16_LE;
-		sprintf(name, "dspW%d", card);
-		break;
-	case OSS_DEVICE_AUDIO:
-		sprintf(name, "audio%d", card);
-		break;
-	case OSS_DEVICE_ADSP:
-		sprintf(name, "adsp%d", card);
-		break;
-	default:
-		return RETRY;
-	}
-	if (mode & O_NONBLOCK)
-		pcm_mode = SND_PCM_NONBLOCK;
-	switch (oflag & O_ACCMODE) {
-	case O_RDONLY:
-		streams = 1 << SND_PCM_STREAM_CAPTURE;
-		break;
-	case O_WRONLY:
-		streams = 1 << SND_PCM_STREAM_PLAYBACK;
-		break;
-	case O_RDWR:
-		streams = ((1 << SND_PCM_STREAM_PLAYBACK) | 
-			   (1 << SND_PCM_STREAM_CAPTURE));
-		break;
-	default:
-		errno = EINVAL;
-		return -1;
-	}
-	fd = _open("/dev/null", oflag & O_ACCMODE);
-	assert(fd >= 0);
-	fds[fd] = calloc(1, sizeof(fd_t));
-	fds[fd]->class = FD_OSS_DSP;
-	dsp = calloc(1, sizeof(oss_dsp_t));
-	if (!dsp) {
-		free(fds[fd]);
-		fds[fd] = NULL;
-		errno = ENOMEM;
-		return -1;
-	}
-	fds[fd]->private = dsp;
-	dsp->channels = 1;
-	dsp->rate = 8000;
-	dsp->oss_format = format;
-	result = -EINVAL;
-	for (k = 0; k < 2; ++k) {
-		if (!(streams & (1 << k)))
-			continue;
-		result = snd_pcm_open(&dsp->streams[k].pcm, name, k, pcm_mode);
-		if (result < 0)
-			break;
-	}
-	if (result < 0) {
-		result = 0;
-		for (k = 0; k < 2; ++k) {
-			if (dsp->streams[k].pcm) {
-				snd_pcm_close(dsp->streams[k].pcm);
-				dsp->streams[k].pcm = NULL;
-			}
-		}
-		/* try to open the default pcm as fallback */
-		if (card == 0 && (device == OSS_DEVICE_DSP || device == OSS_DEVICE_AUDIO))
-			strcpy(name, "default");
-		else
-			sprintf(name, "plughw:%d", card);
-		for (k = 0; k < 2; ++k) {
-			if (!(streams & (1 << k)))
-				continue;
-			result = snd_pcm_open(&dsp->streams[k].pcm, name, k, pcm_mode);
-			if (result < 0)
-				goto _error;
-		}
-	}
-	result = oss_dsp_params(dsp);
-	if (result < 0)
-		goto _error;
-	return fd;
-
- _error:
-	close(fd);
-	errno = -result;
-	return -1;
-}
-
-int oss_mixer_dev(const char *name, unsigned int index)
-{
-	static struct {
-		char *name;
-		unsigned int index;
-	} id[SOUND_MIXER_NRDEVICES] = {
-		[SOUND_MIXER_VOLUME] = { "Master", 0 },
-		[SOUND_MIXER_BASS] = { "Tone Control - Bass", 0 },
-		[SOUND_MIXER_TREBLE] = { "Tone Control - Treble", 0 },
-		[SOUND_MIXER_SYNTH] = { "Synth", 0 },
-		[SOUND_MIXER_PCM] = { "PCM", 0 },
-		[SOUND_MIXER_SPEAKER] = { "PC Speaker",	0 },
-		[SOUND_MIXER_LINE] = { "Line", 0 },
-		[SOUND_MIXER_MIC] = { "Mic", 0 },
-		[SOUND_MIXER_CD] = { "CD", 0 },
-		[SOUND_MIXER_IMIX] = { "Monitor Mix", 0 },
-		[SOUND_MIXER_ALTPCM] = { "PCM",	1 },
-		[SOUND_MIXER_RECLEV] = { "-- nothing --", 0 },
-		[SOUND_MIXER_IGAIN] = { "Capture", 0 },
-		[SOUND_MIXER_OGAIN] = { "Playback", 0 },
-		[SOUND_MIXER_LINE1] = { "Aux", 0 },
-		[SOUND_MIXER_LINE2] = { "Aux", 1 },
-		[SOUND_MIXER_LINE3] = { "Aux", 2 },
-		[SOUND_MIXER_DIGITAL1] = { "Digital", 0 },
-		[SOUND_MIXER_DIGITAL2] = { "Digital", 1 },
-		[SOUND_MIXER_DIGITAL3] = { "Digital", 2 },
-		[SOUND_MIXER_PHONEIN] = { "Phone", 0 },
-		[SOUND_MIXER_PHONEOUT] = { "Phone", 1 },
-		[SOUND_MIXER_VIDEO] = { "Video", 0 },
-		[SOUND_MIXER_RADIO] = { "Radio", 0 },
-		[SOUND_MIXER_MONITOR] = { "Monitor", 0 },
-	};
-	unsigned int k;
-	for (k = 0; k < SOUND_MIXER_NRDEVICES; ++k) {
-		if (index == id[k].index &&
-		    strcmp(name, id[k].name) == 0)
-			return k;
-	}
-	return -1;
-}
-
-static int oss_mixer_close(int fd)
-{
-	int err, result = 0;
-	oss_mixer_t *mixer = fds[fd]->private;
-	err = snd_mixer_close(mixer->mix);
-	if (err < 0)
-		result = err;
-	free(mixer);
-	if (result < 0) {
-		errno = -result;
-		result = -1;
-	}
-	DEBUG("close(%d) -> %d", fd, result);
-	if (result < 0)
-		DEBUG("(errno=%d)\n", errno);
-	else
-		DEBUG("\n");
-	return 0;
-}
-
-static int oss_mixer_elem_callback(snd_mixer_elem_t *elem, unsigned int mask)
-{
-	oss_mixer_t *mixer = snd_mixer_elem_get_callback_private(elem);
-	if (mask == SND_CTL_EVENT_MASK_REMOVE) {
-		int idx = oss_mixer_dev(snd_mixer_selem_get_name(elem),
-					snd_mixer_selem_get_index(elem));
-		if (idx >= 0)
-			mixer->elems[idx] = 0;
-		return 0;
-	}
-	if (mask & SND_CTL_EVENT_MASK_VALUE) {
-		mixer->modify_counter++;
-	}
-	return 0;
-}
-
-static int oss_mixer_callback(snd_mixer_t *mixer, unsigned int mask, 
-			      snd_mixer_elem_t *elem)
-{
-	if (mask & SND_CTL_EVENT_MASK_ADD) {
-		oss_mixer_t *mix = snd_mixer_get_callback_private(mixer);
-		int idx = oss_mixer_dev(snd_mixer_selem_get_name(elem),
-					snd_mixer_selem_get_index(elem));
-		if (idx >= 0) {
-			mix->elems[idx] = elem;
-			snd_mixer_selem_set_playback_volume_range(elem, 0, 100);
-			snd_mixer_selem_set_capture_volume_range(elem, 0, 100);
-			snd_mixer_elem_set_callback(elem, oss_mixer_elem_callback);
-			snd_mixer_elem_set_callback_private(elem, mix);
-		}
-	}
-	return 0;
-}
-
-static int oss_mixer_open(int card, int device, int oflag, mode_t mode ATTRIBUTE_UNUSED)
-{
-	oss_mixer_t *mixer;
-	int fd = -1;
-	int result;
-	char name[64];
-
-	switch (device) {
-	case OSS_DEVICE_MIXER:
-		sprintf(name, "mixer%d", card);
-		break;
-	case OSS_DEVICE_AMIXER:
-		sprintf(name, "amixer%d", card);
-		break;
-	default:
-		return RETRY;
-	}
-	switch (oflag & O_ACCMODE) {
-	case O_RDONLY:
-	case O_WRONLY:
-	case O_RDWR:
-		break;
-	default:
-		errno = EINVAL;
-		return -1;
-	}
-	fd = _open("/dev/null", oflag & O_ACCMODE);
-	assert(fd >= 0);
-	fds[fd] = calloc(1, sizeof(fd_t));
-	fds[fd]->class = FD_OSS_MIXER;
-	mixer = calloc(1, sizeof(oss_mixer_t));
-	if (!mixer) {
-		errno = -ENOMEM;
-		return -1;
-	}
-	fds[fd]->private = mixer;
-	result = snd_mixer_open(&mixer->mix, 0);
-	if (result < 0)
-		goto _error;
-	result = snd_mixer_attach(mixer->mix, name);
-	if (result < 0) {
-		/* try to open the default mixer as fallback */
-		if (card == 0)
-			strcpy(name, "default");
-		else
-			sprintf(name, "hw:%d", card);
-		result = snd_mixer_attach(mixer->mix, name);
-		if (result < 0)
-			goto _error1;
-	}
-	result = snd_mixer_selem_register(mixer->mix, NULL, NULL);
-	if (result < 0)
-		goto _error1;
-	snd_mixer_set_callback(mixer->mix, oss_mixer_callback);
-	snd_mixer_set_callback_private(mixer->mix, mixer);
-	result = snd_mixer_load(mixer->mix);
-	if (result < 0)
-		goto _error1;
-	return fd;
- _error1:
-	snd_mixer_close(mixer->mix);
- _error:
-	close(fd);
-	errno = -result;
-	return -1;
-}
-
-static void error_handler(const char *file ATTRIBUTE_UNUSED,
-			  int line ATTRIBUTE_UNUSED,
-			  const char *func ATTRIBUTE_UNUSED,
-			  int err ATTRIBUTE_UNUSED,
-			  const char *fmt ATTRIBUTE_UNUSED,
-			  ...)
-{
-	/* suppress the error message from alsa-lib */
-}
-
-static int oss_open(const char *file, int oflag, ...)
-{
-	int result;
-	int minor, card, device;
-	struct stat s;
-	mode_t mode;
-	va_list args;
-	va_start(args, oflag);
-	mode = va_arg(args, mode_t);
-	va_end(args);
-	result = stat(file, &s);
-	if (result < 0)
-		return RETRY;
-	if (!S_ISCHR(s.st_mode) || ((s.st_rdev >> 8) & 0xff) != OSS_MAJOR)
-		return RETRY;
-	if (! debug)
-		snd_lib_error_set_handler(error_handler);
-	minor = s.st_rdev & 0xff;
-	card = minor >> 4;
-	device = minor & 0x0f;
-	switch (device) {
-	case OSS_DEVICE_DSP:
-	case OSS_DEVICE_DSPW:
-	case OSS_DEVICE_AUDIO:
-	case OSS_DEVICE_ADSP:
-		result = oss_dsp_open(card, device, oflag, mode);
-		DEBUG("open(\"%s\", %d, %d) -> %d\n", file, oflag, mode, result);
-		return result;
-	case OSS_DEVICE_MIXER:
-	case OSS_DEVICE_AMIXER:
-		result = oss_mixer_open(card, device, oflag, mode);
-		DEBUG("open(\"%s\", %d, %d) -> %d\n", file, oflag, mode, result);
-		return result;
-	default:
-		return RETRY;
-	}
-}
-
-static ssize_t oss_dsp_write(int fd, const void *buf, size_t n)
-{
-	ssize_t result;
-	oss_dsp_t *dsp = fds[fd]->private;
-	oss_dsp_stream_t *str = &dsp->streams[SND_PCM_STREAM_PLAYBACK];
-	snd_pcm_t *pcm = str->pcm;
-	snd_pcm_uframes_t frames;
-	if (!pcm) {
-		errno = EBADFD;
-		result = -1;
-		goto _end;
-	}
-	frames = n / str->frame_bytes;
- _again:
-	result = snd_pcm_writei(pcm, buf, frames);
-	if (result == -EPIPE && 
-	    snd_pcm_state(pcm) == SND_PCM_STATE_XRUN &&
-	    (result = snd_pcm_prepare(pcm)) == 0)
-		goto _again;
-	if (result < 0) {
-		errno = -result;
-		result = -1;
-		goto _end;
-	}
-	result *= str->frame_bytes;
-	str->bytes += result;
- _end:
-	DEBUG("write(%d, %p, %ld) -> %ld", fd, buf, (long)n, (long)result);
-	if (result < 0)
-		DEBUG("(errno=%d)\n", errno);
-	else
-		DEBUG("\n");
-	return result;
-}
-
-static ssize_t oss_dsp_read(int fd, void *buf, size_t n)
-{
-	ssize_t result;
-	oss_dsp_t *dsp = fds[fd]->private;
-	oss_dsp_stream_t *str = &dsp->streams[SND_PCM_STREAM_CAPTURE];
-	snd_pcm_t *pcm = str->pcm;
-	snd_pcm_uframes_t frames;
-	if (!pcm) {
-		errno = EBADFD;
-		result = -1;
-		goto _end;
-	}
-	frames = n / str->frame_bytes;
- _again:
-	result = snd_pcm_readi(pcm, buf, frames);
-	if (result == -EPIPE && 
-	    snd_pcm_state(pcm) == SND_PCM_STATE_XRUN &&
-	    (result = snd_pcm_prepare(pcm)) == 0)
-		goto _again;
-	if (result < 0) {
-		errno = -result;
-		result = -1;
-		goto _end;
-	}
-	result *= str->frame_bytes;
-	str->bytes += result;
- _end:
-	DEBUG("read(%d, %p, %ld) -> %ld", fd, buf, (long)n, (long)result);
-	if (result < 0)
-		DEBUG("(errno=%d)\n", errno);
-	else
-		DEBUG("\n");
-	return result;
-}
-
-#define USE_REWIND 1
-
-static void oss_dsp_mmap_update(oss_dsp_t *dsp, snd_pcm_stream_t stream,
-				snd_pcm_sframes_t delay)
-{
-	oss_dsp_stream_t *str = &dsp->streams[stream];
-	snd_pcm_t *pcm = str->pcm;
-	snd_pcm_sframes_t err;
-	snd_pcm_uframes_t size;
-	const snd_pcm_channel_area_t *areas;
-	switch (stream) {
-	case SND_PCM_STREAM_PLAYBACK:
-		if (delay < 0) {
-			snd_pcm_reset(pcm);
-			str->mmap_advance -= delay;
-			if (str->mmap_advance > dsp->rate / 10)
-				str->mmap_advance = dsp->rate / 10;
-//			fprintf(stderr, "mmap_advance=%ld\n", str->mmap_advance);
-		}
-#if USE_REWIND
-		err = snd_pcm_rewind(pcm, str->buffer_size);
-		if (err < 0)
-			return;
-		size = str->mmap_advance;
-//		fprintf(stderr, "delay=%ld rewind=%ld forward=%ld offset=%ld\n",
-//			delay, err, size, snd_pcm_mmap_offset(pcm));
-#else
-		size = str->mmap_advance - delay;
-#endif
-		while (size > 0) {
-			snd_pcm_uframes_t ofs;
-			snd_pcm_uframes_t frames = size;
-			snd_pcm_mmap_begin(pcm, &areas, &ofs, &frames);
-//			fprintf(stderr, "copy %ld %ld %d\n", ofs, frames, dsp->format);
-			snd_pcm_areas_copy(areas, ofs, str->mmap_areas, ofs, 
-					   dsp->channels, frames,
-					   dsp->format);
-			err = snd_pcm_mmap_commit(pcm, ofs, frames);
-			assert(err == (snd_pcm_sframes_t) frames);
-			size -= frames;
-		}
-		break;
-	case SND_PCM_STREAM_CAPTURE:
-		break;
-	}
-}
-
-
-static int oss_dsp_ioctl(int fd, unsigned long cmd, ...)
-{
-	int result, err = 0;
-	va_list args;
-	void *arg;
-	oss_dsp_t *dsp = fds[fd]->private;
-	oss_dsp_stream_t *str;
-	snd_pcm_t *pcm;
-
-	va_start(args, cmd);
-	arg = va_arg(args, void *);
-	va_end(args);
-	DEBUG("ioctl(%d, ", fd);
-	switch (cmd) {
-	case OSS_GETVERSION:
-		*(int*)arg = SOUND_VERSION;
-		DEBUG("OSS_GETVERSION, %p) -> [%d]\n", arg, *(int*)arg);
-		break;
-	case SNDCTL_DSP_RESET:
-	{
-		int k;
-		DEBUG("SNDCTL_DSP_RESET)\n");
-		result = 0;
-		for (k = 0; k < 2; ++k) {
-			str = &dsp->streams[k];
-			pcm = str->pcm;
-			if (!pcm)
-				continue;
-			err = snd_pcm_drop(pcm);
-			if (err >= 0)
-				err = snd_pcm_prepare(pcm);
-			if (err < 0)
-				result = err;
-			str->bytes = 0;
-		}
-		err = result;
-		break;
-	}
-	case SNDCTL_DSP_SYNC:
-	{
-		int k;
-		DEBUG("SNDCTL_DSP_SYNC)\n");
-		result = 0;
-		for (k = 0; k < 2; ++k) {
-			str = &dsp->streams[k];
-			pcm = str->pcm;
-			if (!pcm)
-				continue;
-			err = snd_pcm_drain(pcm);
-			if (err >= 0)
-				err = snd_pcm_prepare(pcm);
-			if (err < 0)
-				result = err;
-			
-		}
-		err = result;
-		break;
-	}
-	case SNDCTL_DSP_SPEED:
-		dsp->rate = *(int *)arg;
-		err = oss_dsp_params(dsp);
-		DEBUG("SNDCTL_DSP_SPEED, %p[%d]) -> [%d]\n", arg, *(int *)arg, dsp->rate);
-		*(int *)arg = dsp->rate;
-		break;
-	case SNDCTL_DSP_STEREO:
-		if (*(int *)arg)
-			dsp->channels = 2;
-		else
-			dsp->channels = 1;
-		err = oss_dsp_params(dsp);
-		DEBUG("SNDCTL_DSP_STEREO, %p[%d]) -> [%d]\n", arg, *(int *)arg, dsp->channels - 1);
-		*(int *)arg = dsp->channels - 1;
-		break;
-	case SNDCTL_DSP_CHANNELS:
-		dsp->channels = (*(int *)arg);
-		err = oss_dsp_params(dsp);
-		if (err < 0)
-			break;
-		DEBUG("SNDCTL_DSP_CHANNELS, %p[%d]) -> [%d]\n", arg, *(int *)arg, dsp->channels);
-		*(int *)arg = dsp->channels;
-		break;
-	case SNDCTL_DSP_SETFMT:
-		if (*(int *)arg != AFMT_QUERY) {
-			dsp->oss_format = *(int *)arg;
-			err = oss_dsp_params(dsp);
-			if (err < 0)
-				break;
-		}
-		DEBUG("SNDCTL_DSP_SETFMT, %p[%d]) -> [%d]\n", arg, *(int *)arg, dsp->oss_format);
-		*(int *) arg = dsp->oss_format;
-		break;
-	case SNDCTL_DSP_GETBLKSIZE:
-		str = &dsp->streams[SND_PCM_STREAM_PLAYBACK];
-		if (!str->pcm)
-			str = &dsp->streams[SND_PCM_STREAM_CAPTURE];
-		pcm = str->pcm;
-		*(int *) arg = str->period_size * str->frame_bytes;
-		DEBUG("SNDCTL_DSP_GETBLKSIZE, %p) -> [%d]\n", arg, *(int *)arg);
-		break;
-	case SNDCTL_DSP_POST:
-		DEBUG("SNDCTL_DSP_POST)\n");
-		break;
-	case SNDCTL_DSP_SUBDIVIDE:
-		DEBUG("SNDCTL_DSP_SUBDIVIDE, %p[%d])\n", arg, *(int *)arg);
-		dsp->subdivision = *(int *)arg;
-		if (dsp->subdivision < 1)
-			dsp->subdivision = 1;
-		err = oss_dsp_params(dsp);
-		break;
-	case SNDCTL_DSP_SETFRAGMENT:
-	{
-		DEBUG("SNDCTL_DSP_SETFRAGMENT, %p[%x])\n", arg, *(int *)arg);
-		dsp->fragshift = *(int *)arg & 0xffff;
-		if (dsp->fragshift < 4)
-			dsp->fragshift = 4;
-		dsp->maxfrags = ((*(int *)arg) >> 16) & 0xffff;
-		if (dsp->maxfrags < 2)
-			dsp->maxfrags = 2;
-		err = oss_dsp_params(dsp);
-		break;
-	}
-	case SNDCTL_DSP_GETFMTS:
-	{
-		*(int *)arg = (AFMT_MU_LAW | AFMT_A_LAW | AFMT_IMA_ADPCM | 
-			       AFMT_U8 | AFMT_S16_LE | AFMT_S16_BE | 
-			       AFMT_S8 | AFMT_U16_LE | AFMT_U16_BE);
-		DEBUG("SNDCTL_DSP_GETFMTS, %p) -> [%d]\n", arg, *(int *)arg);
-		break;
-	}
-	case SNDCTL_DSP_NONBLOCK:
-	{
-		int k;
-		DEBUG("SNDCTL_DSP_NONBLOCK)\n");
-		result = 0;
-		for (k = 0; k < 2; ++k) {
-			pcm = dsp->streams[k].pcm;
-			if (!pcm)
-				continue;
-			err = snd_pcm_nonblock(pcm, 1);
-			if (err < 0)
-				result = err;
-		}
-		result = err;
-		break;
-	}
-	case SNDCTL_DSP_GETCAPS:
-	{
-		result = DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP;
-		if (dsp->streams[SND_PCM_STREAM_PLAYBACK].pcm && 
-		    dsp->streams[SND_PCM_STREAM_CAPTURE].pcm)
-			result |= DSP_CAP_DUPLEX;
-		*(int*)arg = result;
-		DEBUG("SNDCTL_DSP_GETCAPS, %p) -> [%d]\n", arg, *(int*)arg);
-		break;
-	}
-	case SNDCTL_DSP_GETTRIGGER:
-	{
-		int s = 0;
-		pcm = dsp->streams[SND_PCM_STREAM_PLAYBACK].pcm;
-		if (pcm) {
-			if (snd_pcm_state(pcm) == SND_PCM_STATE_RUNNING)
-				s |= PCM_ENABLE_OUTPUT;
-		}
-		pcm = dsp->streams[SND_PCM_STREAM_CAPTURE].pcm;
-		if (pcm) {
-			if (snd_pcm_state(pcm) == SND_PCM_STATE_RUNNING)
-				s |= PCM_ENABLE_INPUT;
-		}
-		*(int*)arg = s;
-		DEBUG("SNDCTL_DSP_GETTRIGGER, %p) -> [%d]\n", arg, *(int*)arg);
-		break;
-	}		
-	case SNDCTL_DSP_SETTRIGGER:
-	{
-		DEBUG("SNDCTL_DSP_SETTRIGGER, %p[%d])\n", arg, *(int*)arg);
-		result = *(int*) arg;
-		str = &dsp->streams[SND_PCM_STREAM_CAPTURE];
-		pcm = str->pcm;
-		if (pcm) {
-			if (result & PCM_ENABLE_INPUT) {
-				if (str->stopped) {
-					str->stopped = 0;
-					err = oss_dsp_sw_params(dsp);
-					if (err < 0)
-						break;
-					err = snd_pcm_start(pcm);
-					if (err < 0)
-						break;
-				}
-			} else {
-				if (!str->stopped) {
-					str->stopped = 1;
-					err = snd_pcm_drop(pcm);
-					if (err < 0)
-						break;
-					err = oss_dsp_sw_params(dsp);
-					if (err < 0)
-						break;
-					err = snd_pcm_prepare(pcm);
-					if (err < 0)
-						break;
-				}
-			}
-		}
-		str = &dsp->streams[SND_PCM_STREAM_PLAYBACK];
-		pcm = str->pcm;
-		if (pcm) {
-			if (result & PCM_ENABLE_OUTPUT) {
-				if (str->stopped) {
-					str->stopped = 0;
-					err = oss_dsp_sw_params(dsp);
-					if (err < 0)
-						break;
-					if (str->mmap_buffer) {
-						const snd_pcm_channel_area_t *areas;
-						snd_pcm_uframes_t offset;
-						snd_pcm_uframes_t size = str->buffer_size;
-						snd_pcm_mmap_begin(pcm, &areas, &offset, &size);
-						snd_pcm_areas_copy(areas, 0, str->mmap_areas, 0,
-								   dsp->channels, size,
-								   dsp->format);
-						snd_pcm_mmap_commit(pcm, offset, size);
-					}
-					err = snd_pcm_start(pcm);
-					if (err < 0)
-						break;
-				}
-			} else {
-				if (!str->stopped) {
-					str->stopped = 1;
-					err = snd_pcm_drop(pcm);
-					if (err < 0)
-						break;
-					err = oss_dsp_sw_params(dsp);
-					if (err < 0)
-						break;
-					err = snd_pcm_prepare(pcm);
-					if (err < 0)
-						break;
-				}
-			}
-		}
-		break;
-	}
-	case SNDCTL_DSP_GETISPACE:
-	{
-		snd_pcm_sframes_t avail, delay;
-		snd_pcm_state_t state;
-		audio_buf_info *info = arg;
-		str = &dsp->streams[SND_PCM_STREAM_CAPTURE];
-		pcm = str->pcm;
-		if (!pcm) {
-			err = -EINVAL;
-			break;
-		}
-		state = snd_pcm_state(pcm);
-		if (state == SND_PCM_STATE_RUNNING) {
-			snd_pcm_delay(pcm, &delay);
-			if (str->mmap_buffer)
-				oss_dsp_mmap_update(dsp, SND_PCM_STREAM_CAPTURE, delay);
-		}
-		avail = snd_pcm_avail_update(pcm);
-		if (avail < 0)
-			avail = 0;
-		if ((snd_pcm_uframes_t)avail > str->buffer_size)
-			avail = str->buffer_size;
-		info->fragsize = str->period_size * str->frame_bytes;
-		info->fragstotal = str->periods;
-		info->bytes = avail * str->frame_bytes;
-		info->fragments = avail / str->period_size;
-		DEBUG("SNDCTL_DSP_GETISPACE, %p) -> {%d, %d, %d, %d}\n", arg,
-		      info->fragments,
-		      info->fragstotal,
-		      info->fragsize,
-		      info->bytes);
-		break;
-	}
-	case SNDCTL_DSP_GETOSPACE:
-	{
-		snd_pcm_sframes_t avail, delay;
-		snd_pcm_state_t state;
-		audio_buf_info *info = arg;
-		str = &dsp->streams[SND_PCM_STREAM_PLAYBACK];
-		pcm = str->pcm;
-		if (!pcm) {
-			err = -EINVAL;
-			break;
-		}
-		state = snd_pcm_state(pcm);
-		if (state == SND_PCM_STATE_RUNNING || 
-		    state == SND_PCM_STATE_DRAINING) {
-			snd_pcm_delay(pcm, &delay);
-			if (str->mmap_buffer)
-				oss_dsp_mmap_update(dsp, SND_PCM_STREAM_PLAYBACK, delay);
-		}
-		avail = snd_pcm_avail_update(pcm);
-		if (avail < 0 || (snd_pcm_uframes_t)avail > str->buffer_size)
-			avail = str->buffer_size;
-		info->fragsize = str->period_size * str->frame_bytes;
-		info->fragstotal = str->periods;
-		info->bytes = avail * str->frame_bytes;
-		info->fragments = avail / str->period_size;
-		DEBUG("SNDCTL_DSP_GETOSPACE, %p) -> {%d %d %d %d}\n", arg,
-		      info->fragments,
-		      info->fragstotal,
-		      info->fragsize,
-		      info->bytes);
-		break;
-	}
-	case SNDCTL_DSP_GETIPTR:
-	{
-		snd_pcm_sframes_t delay = 0;
-		snd_pcm_uframes_t hw_ptr;
-		snd_pcm_state_t state;
-		count_info *info = arg;
-		str = &dsp->streams[SND_PCM_STREAM_CAPTURE];
-		pcm = str->pcm;
-		if (!pcm) {
-			err = -EINVAL;
-			break;
-		}
-		state = snd_pcm_state(pcm);
-		if (state == SND_PCM_STATE_RUNNING) {
-			snd_pcm_delay(pcm, &delay);
-			if (str->mmap_buffer)
-				oss_dsp_mmap_update(dsp, SND_PCM_STREAM_CAPTURE, delay);
-		}
-		/* FIXME */
-		hw_ptr = _snd_pcm_mmap_hw_ptr(pcm);
-		info->bytes = hw_ptr;
-		info->bytes *= str->frame_bytes;
-		info->ptr = hw_ptr % str->buffer_size;
-		info->ptr *= str->frame_bytes;
-		if (str->mmap_buffer) {
-			ssize_t n = (hw_ptr / str->period_size) - (str->old_hw_ptr / str->period_size);
-			if (n < 0)
-				n += str->boundary / str->period_size;
-			info->blocks = n;
-			str->old_hw_ptr = hw_ptr;
-		} else
-			info->blocks = delay / str->period_size;
-		DEBUG("SNDCTL_DSP_GETIPTR, %p) -> {%d %d %d}\n", arg,
-		      info->bytes,
-		      info->blocks,
-		      info->ptr);
-		break;
-	}
-	case SNDCTL_DSP_GETOPTR:
-	{
-		snd_pcm_sframes_t delay = 0;
-		snd_pcm_uframes_t hw_ptr;
-		snd_pcm_state_t state;
-		count_info *info = arg;
-		str = &dsp->streams[SND_PCM_STREAM_PLAYBACK];
-		pcm = str->pcm;
-		if (!pcm) {
-			err = -EINVAL;
-			break;
-		}
-		state = snd_pcm_state(pcm);
-		if (state == SND_PCM_STATE_RUNNING || 
-		    state == SND_PCM_STATE_DRAINING) {
-			snd_pcm_delay(pcm, &delay);
-			if (str->mmap_buffer)
-				oss_dsp_mmap_update(dsp, SND_PCM_STREAM_PLAYBACK, delay);
-		}
-		/* FIXME */
-		hw_ptr = _snd_pcm_mmap_hw_ptr(pcm);
-		info->bytes = hw_ptr;
-		info->bytes *= str->frame_bytes;
-		info->ptr = hw_ptr % str->buffer_size;
-		info->ptr *= str->frame_bytes;
-		if (str->mmap_buffer) {
-			ssize_t n = (hw_ptr / str->period_size) - (str->old_hw_ptr / str->period_size);
-			if (n < 0)
-				n += str->boundary / str->period_size;
-			info->blocks = n;
-			str->old_hw_ptr = hw_ptr;
-		} else
-			info->blocks = delay / str->period_size;
-		DEBUG("SNDCTL_DSP_GETOPTR, %p) -> {%d %d %d}\n", arg,
-		      info->bytes,
-		      info->blocks,
-		      info->ptr);
-		break;
-	}
-	case SNDCTL_DSP_GETODELAY:
-	{
-		snd_pcm_sframes_t delay = 0;
-		snd_pcm_state_t state;
-		str = &dsp->streams[SND_PCM_STREAM_PLAYBACK];
-		pcm = str->pcm;
-		if (!pcm) {
-			err = -EINVAL;
-			break;
-		}
-		state = snd_pcm_state(pcm);
-		if (state == SND_PCM_STATE_RUNNING || 
-		    state == SND_PCM_STATE_DRAINING) {
-			snd_pcm_delay(pcm, &delay);
-			if (str->mmap_buffer)
-				oss_dsp_mmap_update(dsp, SND_PCM_STREAM_PLAYBACK, delay);
-		}
-		*(int *)arg = delay * str->frame_bytes;
-		DEBUG("SNDCTL_DSP_GETODELAY, %p) -> [%d]\n", arg, *(int*)arg); 
-		break;
-	}
-	case SNDCTL_DSP_SETDUPLEX:
-		DEBUG("SNDCTL_DSP_SETDUPLEX)\n"); 
-		break;
-	case SOUND_PCM_READ_RATE:
-	{
-		*(int *)arg = dsp->rate;
-		DEBUG("SOUND_PCM_READ_RATE, %p) -> [%d]\n", arg, *(int*)arg); 
-		break;
-	}
-	case SOUND_PCM_READ_CHANNELS:
-	{
-		*(int *)arg = dsp->channels;
-		DEBUG("SOUND_PCM_READ_CHANNELS, %p) -> [%d]\n", arg, *(int*)arg); 
-		break;
-	}
-	case SOUND_PCM_READ_BITS:
-	{
-		*(int *)arg = snd_pcm_format_width(dsp->format);
-		DEBUG("SOUND_PCM_READ_BITS, %p) -> [%d]\n", arg, *(int*)arg); 
-		break;
-	}
-	case SNDCTL_DSP_MAPINBUF:
-		DEBUG("SNDCTL_DSP_MAPINBUF)\n");
-		err = -EINVAL;
-		break;
-	case SNDCTL_DSP_MAPOUTBUF:
-		DEBUG("SNDCTL_DSP_MAPOUTBUF)\n");
-		err = -EINVAL;
-		break;
-	case SNDCTL_DSP_SETSYNCRO:
-		DEBUG("SNDCTL_DSP_SETSYNCRO)\n");
-		err = -EINVAL;
-		break;
-	case SOUND_PCM_READ_FILTER:
-		DEBUG("SOUND_PCM_READ_FILTER)\n");
-		err = -EINVAL;
-		break;
-	case SOUND_PCM_WRITE_FILTER:
-		DEBUG("SOUND_PCM_WRITE_FILTER)\n");
-		err = -EINVAL;
-		break;
-	default:
-		DEBUG("%lx, %p)\n", cmd, arg);
-		// return oss_mixer_ioctl(...);
-		err = -ENXIO;
-		break;
-	}
-	if (err >= 0)
-		return 0;
-	DEBUG("dsp ioctl error = %d\n", err);
-	errno = -err;
-	return -1;
-}
-
-static int oss_dsp_fcntl(int fd, int cmd, ...)
-{
-	int result;
-	va_list args;
-	long arg;
-
-	va_start(args, cmd);
-	arg = va_arg(args, long);
-	va_end(args);
-	
-	DEBUG("fcntl(%d, ", fd);
-	result = _fcntl(fd, cmd, arg);
-	if (result < 0)
-		return result;
-	switch (cmd) {
-	case F_DUPFD:
-		DEBUG("F_DUPFD, %ld)\n", arg);
-		fds[arg] = fds[fd];
-		return result;
-	case F_SETFL:
-	{
-		int k;
-		int err;
-		snd_pcm_t *pcm;
-		oss_dsp_t *dsp = fds[fd]->private;
-		DEBUG("F_SETFL, %ld)\n", arg);
-		for (k = 0; k < 2; ++k) {
-			pcm = dsp->streams[k].pcm;
-			if (!pcm)
-				continue;
-			err = snd_pcm_nonblock(pcm, !!(arg & O_NONBLOCK));
-			if (err < 0)
-				result = err;
-		}
-		if (result < 0) {
-			errno = -result;
-			return -1;
-		}
-		return 0;
-	}
-	default:
-		DEBUG("%x, %ld)\n", cmd, arg);
-		return result;
-	}
-	return -1;
-}
-
-static void *oss_dsp_mmap(void *addr ATTRIBUTE_UNUSED, size_t len ATTRIBUTE_UNUSED, int prot, int flags ATTRIBUTE_UNUSED, int fd, off_t offset ATTRIBUTE_UNUSED)
-{
-	int err;
-	void *result;
-	oss_dsp_t *dsp = fds[fd]->private;
-	oss_dsp_stream_t *str;
-	switch (prot & (PROT_READ | PROT_WRITE)) {
-	case PROT_READ:
-		str = &dsp->streams[SND_PCM_STREAM_CAPTURE];
-		break;
-	case PROT_WRITE:
-		str = &dsp->streams[SND_PCM_STREAM_PLAYBACK];
-		break;
-	case PROT_READ | PROT_WRITE:
-		str = &dsp->streams[SND_PCM_STREAM_PLAYBACK];
-		if (!str->pcm)
-			str = &dsp->streams[SND_PCM_STREAM_CAPTURE];
-		break;
-	default:
-		errno = EINVAL;
-		result = MAP_FAILED;
-		goto _end;
-	}
-	if (!str->pcm) {
-		errno = EBADFD;
-		result = MAP_FAILED;
-		goto _end;
-	}
-	assert(!str->mmap_buffer);
-	result = malloc(len);
-	if (!result) {
-		result = MAP_FAILED;
-		goto _end;
-	}
-	str->mmap_buffer = result;
-	str->mmap_bytes = len;
-	str->mmap_period_bytes = str->period_size * str->frame_bytes;
-	str->mmap_buffer_bytes = str->buffer_size * str->frame_bytes;
-	err = oss_dsp_params(dsp);
-	if (err < 0) {
-		free(result);
-		errno = -err;
-		result = MAP_FAILED;
-		goto _end;
-	}
- _end:
-	DEBUG("mmap(%p, %lu, %d, %d, %d, %ld) -> %p\n", addr, (unsigned long)len, prot, flags, fd, offset, result);
-	return result;
-}
-
-static int oss_dsp_munmap(int fd, void *addr ATTRIBUTE_UNUSED, size_t len ATTRIBUTE_UNUSED)
-{
-	int err;
-	oss_dsp_t *dsp = fds[fd]->private;
-	oss_dsp_stream_t *str;
-	DEBUG("munmap(%p, %lu)\n", addr, (unsigned long)len);
-	str = &dsp->streams[SND_PCM_STREAM_PLAYBACK];
-	if (!str->pcm)
-		str = &dsp->streams[SND_PCM_STREAM_CAPTURE];
-	assert(str->mmap_buffer);
-	free(str->mmap_buffer);
-	str->mmap_buffer = 0;
-	str->mmap_bytes = 0;
-	err = oss_dsp_params(dsp);
-	if (err < 0) {
-		errno = -err;
-		return -1;
-	}
-	return 0;
-}
-
-static ssize_t oss_mixer_write(int fd ATTRIBUTE_UNUSED, const void *buf ATTRIBUTE_UNUSED, size_t n ATTRIBUTE_UNUSED)
-{
-	errno = -EBADFD;
-	return -1;
-}
-
-static ssize_t oss_mixer_read(int fd ATTRIBUTE_UNUSED, void *buf ATTRIBUTE_UNUSED, size_t n ATTRIBUTE_UNUSED)
-{
-	errno = -EBADFD;
-	return -1;
-}
-
-
-static int oss_mixer_read_recsrc(oss_mixer_t *mixer, unsigned int *ret)
-{
-	unsigned int mask = 0;
-	unsigned int k;
-	int err = 0;
-	for (k = 0; k < SOUND_MIXER_NRDEVICES; k++) {
-		snd_mixer_elem_t *elem = mixer->elems[k];
-		if (elem && 
-		    snd_mixer_selem_has_capture_switch(elem)) {
-			int sw;
-			err = snd_mixer_selem_get_capture_switch(elem, SND_MIXER_SCHN_FRONT_LEFT, &sw);
-			if (err < 0)
-				break;
-			if (sw)
-				mask |= 1 << k;
-		}
-	}
-	*ret = mask;
-	return err;
-}
-
-
-static int oss_mixer_ioctl(int fd, unsigned long cmd, ...)
-{
-	int err = 0;
-	va_list args;
-	void *arg;
-	oss_mixer_t *mixer = fds[fd]->private;
-	snd_mixer_t *mix = mixer->mix;
-	unsigned int dev;
-
-	va_start(args, cmd);
-	arg = va_arg(args, void *);
-	va_end(args);
-	DEBUG("ioctl(%d, ", fd);
-	switch (cmd) {
-	case OSS_GETVERSION:
-		*(int*)arg = SOUND_VERSION;
-		DEBUG("OSS_GETVERSION, %p) -> [%d]\n", arg, *(int*)arg);
-		break;
-	case SOUND_MIXER_INFO:
-	{
-		mixer_info *info = arg;
-		snd_mixer_handle_events(mix);
-		strcpy(info->id, "alsa-oss");
-		strcpy(info->name, "alsa-oss");
-		info->modify_counter = mixer->modify_counter;
-		DEBUG("SOUND_MIXER_INFO, %p) -> {%s, %s, %d}\n", info, info->id, info->name, info->modify_counter);
-		break;
-	}
-	case SOUND_OLD_MIXER_INFO:
-	{
-		_old_mixer_info *info = arg;
-		strcpy(info->id, "alsa-oss");
-		strcpy(info->name, "alsa-oss");
-		DEBUG("SOUND_OLD_MIXER_INFO, %p) -> {%s, %s}\n", info, info->id, info->name);
-		break;
-	}
-	case SOUND_MIXER_WRITE_RECSRC:
-	{
-		unsigned int k, mask = *(unsigned int *) arg;
-		unsigned int old;
-		int excl = 0;
-		DEBUG("SOUND_MIXER_WRITE_RECSRC, %p) -> [%x]", arg, mask);
-		err = oss_mixer_read_recsrc(mixer, &old);
-		if (err < 0)
-			break;
-		for (k = 0; k < SOUND_MIXER_NRDEVICES; k++) {
-			snd_mixer_elem_t *elem = mixer->elems[k];
-			if (elem && 
-			    snd_mixer_selem_has_capture_switch(elem)) {
-				if (!excl &&
-				    snd_mixer_selem_has_capture_switch_exclusive(elem) &&
-				    mask & ~old) {
-					mask &= ~old;
-					excl = 1;
-				}
-				err = snd_mixer_selem_set_capture_switch_all(elem, !!(mask & 1 << k));
-				if (err < 0)
-					break;
-			}
-		}
-		if (err < 0)
-			break;
-		goto __read_recsrc;
-	}
-	case SOUND_MIXER_READ_RECSRC:
-	{
-		unsigned int mask;
-		DEBUG("SOUND_MIXER_READ_RECSRC, %p) ->", arg);
-	__read_recsrc:
-		err = oss_mixer_read_recsrc(mixer, &mask);
-		*(int *)arg = mask;
-		DEBUG(" [%x]\n", mask);
-		break;
-	}
-	case SOUND_MIXER_READ_DEVMASK:
-	{
-		int k, mask = 0;
-		for (k = 0; k < SOUND_MIXER_NRDEVICES; k++) {
-			snd_mixer_elem_t *elem = mixer->elems[k];
-			if (elem && 
-			    snd_mixer_selem_has_playback_volume(elem))
-				mask |= 1 << k;
-		}
-		*(int *)arg = mask;
-		DEBUG("SOUND_MIXER_READ_DEVMASK, %p) -> [%x]\n", arg, mask);
-		break;
-	}
-	case SOUND_MIXER_READ_RECMASK:
-	{
-		int k, mask = 0;
-		for (k = 0; k < SOUND_MIXER_NRDEVICES; k++) {
-			snd_mixer_elem_t *elem = mixer->elems[k];
-			if (elem &&
-			    snd_mixer_selem_has_capture_switch(elem))
-				mask |= 1 << k;
-		}
-		*(int *)arg = mask;
-		DEBUG("SOUND_MIXER_READ_RECMASK, %p) -> [%x]\n", arg, mask);
-		break;
-	}
-	case SOUND_MIXER_READ_STEREODEVS:
-	{
-		int k, mask = 0;
-		for (k = 0; k < SOUND_MIXER_NRDEVICES; k++) {
-			snd_mixer_elem_t *elem = mixer->elems[k];
-			if (elem && 
-			    snd_mixer_selem_has_playback_volume(elem) &&
-			    !snd_mixer_selem_is_playback_mono(elem))
-				mask |= 1 << k;
-		}
-		*(int *)arg = mask;
-		DEBUG("SOUND_MIXER_READ_STEREODEVS, %p) -> [%x]\n", arg, mask);
-		break;
-	}
-	case SOUND_MIXER_READ_CAPS:
-	{
-		int k;
-		*(int *)arg = 0;
-		for (k = 0; k < SOUND_MIXER_NRDEVICES; k++) {
-			snd_mixer_elem_t *elem = mixer->elems[k];
-			if (elem && 
-			    snd_mixer_selem_has_capture_switch_exclusive(elem)) {
-				* (int*) arg = SOUND_CAP_EXCL_INPUT;
-				break;
-			}
-		}
-		DEBUG("SOUND_MIXER_READ_CAPS, %p) -> [%x]\n", arg, *(int*) arg);
-		break;
-	}
-	default:
-		if (cmd >= MIXER_WRITE(0) && cmd < MIXER_WRITE(SOUND_MIXER_NRDEVICES)) {
-			snd_mixer_elem_t *elem;
-			long lvol, rvol;
-			dev = cmd & 0xff;
-			lvol = *(int *)arg & 0xff;
-			if (lvol > 100)
-				lvol = 100;
-			rvol = (*(int *)arg >> 8) & 0xff;
-			if (rvol > 100)
-				rvol = 100;
-			DEBUG("SOUND_MIXER_WRITE[%d], %p) -> {%ld, %ld}", dev, arg, lvol, rvol);
-			elem = mixer->elems[dev];
-			if (!elem) {
-				err = -EINVAL;
-				break;
-			}
-			if (!snd_mixer_selem_has_playback_volume(elem)) {
-				err = -EINVAL;
-				break;
-			}
-			err = snd_mixer_selem_set_playback_volume(elem, SND_MIXER_SCHN_FRONT_LEFT, lvol);
-			if (err < 0) 
-				break;
-			if (snd_mixer_selem_is_playback_mono(elem)) {
-				if (snd_mixer_selem_has_playback_switch(elem))
-					err = snd_mixer_selem_set_playback_switch(elem, SND_MIXER_SCHN_FRONT_LEFT, lvol != 0);
-				if (err < 0) 
-					break;
-			} else {
-				err = snd_mixer_selem_set_playback_volume(elem, SND_MIXER_SCHN_FRONT_RIGHT, rvol);
-				if (err < 0) 
-					break;
-				if (snd_mixer_selem_has_playback_switch(elem)) {
-					if (snd_mixer_selem_has_playback_switch_joined(elem))
-						err = snd_mixer_selem_set_playback_switch(elem, SND_MIXER_SCHN_FRONT_LEFT, lvol != 0 || rvol != 0);
-					else {
-						err = snd_mixer_selem_set_playback_switch(elem, SND_MIXER_SCHN_FRONT_LEFT, lvol != 0);
-						if (err < 0) 
-							break;
-						err = snd_mixer_selem_set_playback_switch(elem, SND_MIXER_SCHN_FRONT_RIGHT, rvol != 0);
-						if (err < 0) 
-							break;
-					}
-				}
-			}
-			if (!snd_mixer_selem_has_capture_volume(elem))
-				break;
-			err = snd_mixer_selem_set_capture_volume(elem, SND_MIXER_SCHN_FRONT_LEFT, lvol);
-			if (err < 0) 
-				break;
-			if (!snd_mixer_selem_is_capture_mono(elem)) {
-				err = snd_mixer_selem_set_capture_volume(elem, SND_MIXER_SCHN_FRONT_RIGHT, rvol);
-				if (err < 0) 
-					break;
-			}
-			goto __read;
-		}
-		if (cmd >= MIXER_READ(0) && cmd < MIXER_READ(SOUND_MIXER_NRDEVICES)) {
-			snd_mixer_elem_t *elem;
-			long lvol, rvol;
-			int sw;
-			dev = cmd & 0xff;
-			DEBUG("SOUND_MIXER_READ[%d], %p) ->", dev, arg);
-		__read:
-			elem = mixer->elems[dev];
-			if (!elem) {
-				err = -EINVAL;
-				break;
-			}
-			if (!snd_mixer_selem_has_playback_volume(elem)) {
-				err = -EINVAL;
-				break;
-			}
-			err = snd_mixer_selem_get_playback_switch(elem, SND_MIXER_SCHN_FRONT_LEFT, &sw);
-			if (err < 0) 
-				break;
-			if (sw) {
-				err = snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_FRONT_LEFT, &lvol);
-				if (err < 0) 
-					break;
-			} else
-				lvol = 0;
-			if (snd_mixer_selem_is_playback_mono(elem)) {
-				rvol = lvol;
-			} else {
-				err = snd_mixer_selem_get_playback_switch(elem, SND_MIXER_SCHN_FRONT_RIGHT, &sw);
-				if (err < 0) 
-					break;
-				if (sw) {
-					err = snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_FRONT_RIGHT, &rvol);
-					if (err < 0) 
-						break;
-				} else
-					rvol = 0;
-			}
-			* (int*) arg = lvol | (rvol << 8);
-			DEBUG("{%ld, %ld}\n", lvol, rvol);
-			break;
-		}
-		DEBUG("%lx, %p)\n", cmd, arg);
-		err = -ENXIO;
-		break;
-	}
-	if (err >= 0)
-		return 0;
-	errno = -err;
-	return -1;
-}
-
-static int oss_mixer_fcntl(int fd, int cmd, ...)
-{
-	int result;
-	va_list args;
-	long arg;
-
-	va_start(args, cmd);
-	arg = va_arg(args, long);
-	va_end(args);
-	
-	DEBUG("fcntl(%d, ", fd);
-	result = _fcntl(fd, cmd, arg);
-	if (result < 0)
-		return result;
-	switch (cmd) {
-	case F_DUPFD:
-		DEBUG("F_DUPFD, %ld)\n", arg);
-		fds[arg] = fds[fd];
-		return result;
-	default:
-		DEBUG("%x, %ld)\n", cmd, arg);
-		return result;
-	}
-	return -1;
-}
-
-static void *oss_mixer_mmap(void *addr ATTRIBUTE_UNUSED, size_t len ATTRIBUTE_UNUSED, int prot ATTRIBUTE_UNUSED, int flags ATTRIBUTE_UNUSED, int fd ATTRIBUTE_UNUSED, off_t offset ATTRIBUTE_UNUSED)
-{
-	errno = -EBADFD;
-	return MAP_FAILED;
-}
-
-static int oss_mixer_munmap(int fd ATTRIBUTE_UNUSED, void *addr ATTRIBUTE_UNUSED, size_t len ATTRIBUTE_UNUSED)
-{
-	errno = -EBADFD;
-	return -1;
-}
-
-static ops_t ops[FD_CLASSES] = {
-	[FD_OSS_DSP] = {
-		open: oss_open,
-		close: oss_dsp_close,
-		write: oss_dsp_write,
-		read: oss_dsp_read,
-		ioctl: oss_dsp_ioctl,
-		fcntl: oss_dsp_fcntl,
-		mmap: oss_dsp_mmap,
-		munmap: oss_dsp_munmap,
-	},
-	[FD_OSS_MIXER] = {
-		open: oss_open,
-		close: oss_mixer_close,
-		write: oss_mixer_write,
-		read: oss_mixer_read,
-		ioctl: oss_mixer_ioctl,
-		fcntl: oss_mixer_fcntl,
-		mmap: oss_mixer_mmap,
-		munmap: oss_mixer_munmap,
-	},
-};
-
-int open(const char *file, int oflag, ...)
-{
-	va_list args;
-	mode_t mode = 0;
-	int k;
-	int fd;
-
-	if (oflag & O_CREAT) {
-		va_start(args, oflag);
-		mode = va_arg(args, mode_t);
-		va_end(args);
-	}
-	for (k = 0; k < FD_CLASSES; ++k) {
-		if (!ops[k].open)
-			continue;
-		fd = ops[k].open(file, oflag, mode);
-		if (fd != RETRY) {
-			if (fd >= 0)
-				fds[fd]->count++;
-			return fd;
-		}
-	}
-	fd = _open(file, oflag, mode);
-	if (fd >= 0)
-		assert(!fds[fd]);
-	return fd;
-}
-
-int close(int fd)
-{
-	int result = _close(fd);
-	if (result < 0 || fd < 0 || fd >= open_max || !fds[fd])
-		return result;
-	if (--fds[fd]->count == 0) {
-		int err;
-		err = ops[fds[fd]->class].close(fd);
-		assert(err >= 0);
-		free(fds[fd]);
-	}
-	fds[fd] = 0;
-	return result;
-}
-
-ssize_t write(int fd, const void *buf, size_t n)
-{
-	if (fd < 0 || fd >= open_max || !fds[fd])
-		return _write(fd, buf, n);
-	else
-		return ops[fds[fd]->class].write(fd, buf, n);
-}
-
-ssize_t read(int fd, void *buf, size_t n)
-{
-	if (fd < 0 || fd >= open_max || !fds[fd])
-		return _read(fd, buf, n);
-	else
-		return ops[fds[fd]->class].read(fd, buf, n);
-}
-
-int ioctl(int fd, unsigned long request, ...)
-{
-	va_list args;
-	void *arg;
-
-	va_start(args, request);
-	arg = va_arg(args, void *);
-	va_end(args);
-	if (fd < 0 || fd >= open_max || !fds[fd])
-		return _ioctl(fd, request, arg);
-	else 
-		return ops[fds[fd]->class].ioctl(fd, request, arg);
-}
-
-int fcntl(int fd, int cmd, ...)
-{
-	va_list args;
-	void *arg;
-
-	va_start(args, cmd);
-	arg = va_arg(args, void *);
-	va_end(args);
-	if (fd < 0 || fd >= open_max || !fds[fd])
-		return _fcntl(fd, cmd, arg);
-	else
-		return ops[fds[fd]->class].fcntl(fd, cmd, arg);
-}
-
-void *mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset)
-{
-	void *result;
-	if (fd < 0 || fd >= open_max || !fds[fd])
-		return _mmap(addr, len, prot, flags, fd, offset);
-	result = ops[fds[fd]->class].mmap(addr, len, prot, flags, fd, offset);
-	if (result != NULL && result != MAP_FAILED)
-		fds[fd]->mmap_area = result;
-	return result;
-}
-
-int munmap(void *addr, size_t len)
-{
-	int fd;
-	for (fd = 0; fd < open_max; ++fd) {
-		if (fds[fd] && fds[fd]->mmap_area == addr)
-			break;
-	}
-	if (fd >= open_max)
-		return _munmap(addr, len);
-	fds[fd]->mmap_area = 0;
-	return ops[fds[fd]->class].munmap(fd, addr, len);
-}
-
-#ifdef DEBUG_POLL
-void dump_poll(struct pollfd *pfds, unsigned long nfds, int timeout)
-{
-	unsigned int k;
-	fprintf(stderr, "POLL nfds: %ld, timeout: %d\n", nfds, timeout);
-	for (k = 0; k < nfds; ++k) {
-		fprintf(stderr, "fd=%d, events=%x, revents=%x\n", 
-			pfds[k].fd, pfds[k].events, pfds[k].revents);
-	}
-}
-#endif
-
-#ifdef DEBUG_SELECT
-void dump_select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds,
-		 struct timeval *timeout)
-{
-	int k;
-	fprintf(stderr, "SELECT nfds: %d, ", nfds);
-	if (timeout)
-		fprintf(stderr, "timeout: %ld.%06ld\n", timeout->tv_sec, timeout->tv_usec);
-	else
-		fprintf(stderr, "no timeout\n");
-	if (rfds) {
-		fprintf(stderr, "rfds: ");
-		for (k = 0; k < nfds; ++k) {
-			if (FD_ISSET(k, rfds))
-				putc('1', stderr);
-			else
-				putc('0', stderr);
-		}
-		putc('\n', stderr);
-	}
-	if (wfds) {
-		fprintf(stderr, "wfds: ");
-		for (k = 0; k < nfds; ++k) {
-			if (FD_ISSET(k, wfds))
-				putc('1', stderr);
-			else
-				putc('0', stderr);
-		}
-		putc('\n', stderr);
-	}
-	if (efds) {
-		fprintf(stderr, "efds: ");
-		for (k = 0; k < nfds; ++k) {
-			if (FD_ISSET(k, efds))
-				putc('1', stderr);
-			else
-				putc('0', stderr);
-		}
-		putc('\n', stderr);
-	}
-}
-#endif
-
-int snd_pcm_poll_descriptor(snd_pcm_t *pcm)
-{
-	int err;
-	struct pollfd pfds[2];
-	err = snd_pcm_poll_descriptors(pcm, pfds, 2);
-	assert(err == 1);
-	return pfds[0].fd;
-}
-
-int poll(struct pollfd *pfds, unsigned long nfds, int timeout)
-{
-	unsigned int k;
-	unsigned int nfds1;
-	int count, count1;
-	int direct = 1;
-	struct pollfd pfds1[nfds * 2];
-	nfds1 = 0;
-	for (k = 0; k < nfds; ++k) {
-		int fd = pfds[k].fd;
-		pfds[k].revents = 0;
-		if (fd >= open_max || !fds[fd])
-			goto _std1;
-		switch (fds[fd]->class) {
-		case FD_OSS_DSP:
-		{
-			oss_dsp_t *dsp = fds[fd]->private;
-			oss_dsp_stream_t *str;
-			int j;
-			for (j = 0; j < 2; ++j) {
-				str = &dsp->streams[j];
-				if (str->pcm) {
-					pfds1[nfds1].fd = snd_pcm_poll_descriptor(str->pcm);
-					pfds1[nfds1].events = pfds[k].events;
-					pfds1[nfds1].revents = 0;
-					nfds1++;
-				}
-			}
-			direct = 0;
-			break;
-		}
-		default:
-		_std1:
-			pfds1[nfds1].fd = pfds[k].fd;
-			pfds1[nfds1].events = pfds[k].events;
-			pfds1[nfds1].revents = 0;
-			nfds1++;
-			break;
-		}
-	}
-	if (direct)
-		return _poll(pfds, nfds, timeout);
-#ifdef DEBUG_POLL
-	if (debug) {
-		fprintf(stderr, "Orig enter ");
-		dump_poll(pfds, nfds, timeout);
-		fprintf(stderr, "Changed enter ");
-		dump_poll(pfds1, nfds1, timeout);
-	}
-#endif
-	count = _poll(pfds1, nfds1, timeout);
-	if (count <= 0)
-		return count;
-	nfds1 = 0;
-	count1 = 0;
-	for (k = 0; k < nfds; ++k) {
-		int fd = pfds[k].fd;
-		unsigned int revents;
-		if (fd >= open_max || !fds[fd])
-			goto _std2;
-		switch (fds[fd]->class) {
-		case FD_OSS_DSP:
-		{
-			oss_dsp_t *dsp = fds[fd]->private;
-			oss_dsp_stream_t *str;
-			int j;
-			revents = 0;
-			for (j = 0; j < 2; ++j) {
-				str = &dsp->streams[j];
-				if (str->pcm) {
-					revents |= pfds1[nfds1].revents;
-					nfds1++;
-				}
-			}
-			break;
-		}
-		default:
-		_std2:
-			revents = pfds1[nfds1].revents;
-			nfds1++;
-			break;
-		}
-		pfds[k].revents = revents;
-		if (revents)
-			count1++;
-	}
-#ifdef DEBUG_POLL
-	if (debug) {
-		fprintf(stderr, "Changed exit ");
-		dump_poll(pfds1, nfds1, timeout);
-		fprintf(stderr, "Orig exit ");
-		dump_poll(pfds, nfds, timeout);
-	}
-#endif
-	return count1;
-}
-
-int select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds,
-	   struct timeval *timeout)
-{
-	fd_set _rfds1, _wfds1, _efds1;
-	fd_set *rfds1, *wfds1, *efds1;
-	int nfds1 = nfds;
-	int count, count1;
-	int fd;
-	int direct = 1;
-	if (rfds) {
-		_rfds1 = *rfds;
-		rfds1 = &_rfds1;
-	} else
-		rfds1 = NULL;
-	if (wfds) {
-		_wfds1 = *wfds;
-		wfds1 = &_wfds1;
-	} else
-		wfds1 = NULL;
-	if (efds) {
-		_efds1 = *efds;
-		efds1 = &_efds1;
-	} else
-		efds1 = NULL;
-	for (fd = 0; fd < nfds; ++fd) {
-		int r = (rfds && FD_ISSET(fd, rfds));
-		int w = (wfds && FD_ISSET(fd, wfds));
-		int e = (efds && FD_ISSET(fd, efds));
-		if (!(r || w || e))
-			continue;
-		if (!fds[fd])
-			continue;
-		switch (fds[fd]->class) {
-		case FD_OSS_DSP:
-		{
-			oss_dsp_t *dsp = fds[fd]->private;
-			oss_dsp_stream_t *str;
-			int j;
-			if (r)
-				FD_CLR(fd, rfds1);
-			if (w)
-				FD_CLR(fd, wfds1);
-			if (e)
-				FD_CLR(fd, efds1);
-			for (j = 0; j < 2; ++j) {
-				str = &dsp->streams[j];
-				if (str->pcm) {
-					int fd1 = snd_pcm_poll_descriptor(str->pcm);
-					if (fd1 >= nfds1)
-						nfds1 = fd1 + 1;
-					if (r)
-						FD_SET(fd1, rfds1);
-					if (w)
-						FD_SET(fd1, wfds1);
-					if (e)
-						FD_SET(fd1, efds1);
-				}
-			}
-			direct = 0;
-			break;
-		}
-		default:
-			break;
-		}
-	}
-	if (direct)
-		return _select(nfds, rfds, wfds, efds, timeout);
-#ifdef DEBUG_SELECT
-	if (debug) {
-		fprintf(stderr, "Orig enter ");
-		dump_select(nfds, rfds, wfds, efds, timeout);
-		fprintf(stderr, "Changed enter ");
-		dump_select(nfds1, rfds1, wfds1, efds1, timeout);
-	}
-#endif
-	count = _select(nfds1, rfds1, wfds1, efds1, timeout);
-	if (count < 0)
-		return count;
-	if (count == 0) {
-		if (rfds)
-			FD_ZERO(rfds);
-		if (wfds)
-			FD_ZERO(wfds);
-		if (efds)
-			FD_ZERO(efds);
-		return 0;
-	}
-	count1 = 0;
-	for (fd = 0; fd < nfds; ++fd) {
-		int r = (rfds && FD_ISSET(fd, rfds));
-		int w = (wfds && FD_ISSET(fd, wfds));
-		int e = (efds && FD_ISSET(fd, efds));
-		int r1, w1, e1;
-		if (!(r || w || e))
-			continue;
-		if (!fds[fd])
-			continue;
-		switch (fds[fd]->class) {
-		case FD_OSS_DSP:
-		{
-			oss_dsp_t *dsp = fds[fd]->private;
-			oss_dsp_stream_t *str;
-			int j;
-			r1 = w1 = e1 = 0;
-			for (j = 0; j < 2; ++j) {
-				str = &dsp->streams[j];
-				if (str->pcm) {
-					int fd1 = snd_pcm_poll_descriptor(str->pcm);
-					if (r && FD_ISSET(fd1, rfds1))
-						r1++;
-					if (w && FD_ISSET(fd1, wfds1))
-						w1++;
-					if (e && FD_ISSET(fd1, efds1))
-						e1++;
-				}
-			}
-			break;
-		}
-		default:
-			r1 = (r && FD_ISSET(fd, rfds1));
-			w1 = (w && FD_ISSET(fd, wfds1));
-			e1 = (e && FD_ISSET(fd, efds1));
-			break;
-		}
-		if (r && !r1)
-			FD_CLR(fd, rfds);
-		if (w && !w1)
-			FD_CLR(fd, wfds);
-		if (e && !e1)
-			FD_CLR(fd, efds);
-		if (r1 || w1 || e1)
-			count1++;
-	}
-#ifdef DEBUG_SELECT
-	if (debug) {
-		fprintf(stderr, "Changed exit ");
-		dump_select(nfds1, rfds1, wfds1, efds1, timeout);
-		fprintf(stderr, "Orig exit ");
-		dump_select(nfds, rfds, wfds, efds, timeout);
-	}
-#endif
-	return count1;
-}
-
-#if 1
-# define strong_alias(name, aliasname) \
-  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
-strong_alias(open, __open);
-strong_alias(close, __close);
-strong_alias(write, __write);
-strong_alias(read, __read);
-strong_alias(ioctl, __ioctl);
-strong_alias(fcntl, __fcntl);
-strong_alias(mmap, __mmap);
-strong_alias(munmap, __munmap);
-strong_alias(poll, __poll);
-strong_alias(select, __select);
-#else
-int dup(int fd)
-{
-	return fcntl(fd, F_DUPFD, 0);
-}
-
-int dup2(int fd, int fd2)
-{
-	int save;
-
-	if (fd2 < 0 || fd2 >= open_max) {
-		errno = EBADF;
-		return -1;
-	}
-	
-	if (fcntl(fd, F_GETFL) < 0)
-		return -1;
-	
-	if (fd == fd2)
-		return fd2;
-	
-	save = errno;
-	close(fd2);
-	errno = save;
-	
-	return fcntl(fd, F_DUPFD, fd2);
-}
-
-#ifndef O_LARGEFILE
-#define O_LARGEFILE 0100000
-#endif
-
-int open64(const char *file, int oflag, ...)
-{
-	va_list args;
-	mode_t mode = 0;
-
-	if (oflag & O_CREAT) {
-		va_start(args, oflag);
-		mode = va_arg(args, mode_t);
-		va_end(args);
-	}
-	return open(file, oflag | O_LARGEFILE, mode);
-}
-#endif
-
-static void initialize() __attribute__ ((constructor));
-
-static void initialize()
-{
-	char *s = getenv("ALSA_OSS_DEBUG");
-	if (s)
-		debug = 1;
-	open_max = sysconf(_SC_OPEN_MAX);
-	if (open_max < 0)
-		exit(1);
-	fds = calloc(open_max, sizeof(*fds));
-	if (!fds)
-		exit(1);
-	_open = dlsym(RTLD_NEXT, "open");
-	_close = dlsym(RTLD_NEXT, "close");
-	_write = dlsym(RTLD_NEXT, "write");
-	_read = dlsym(RTLD_NEXT, "read");
-	_ioctl = dlsym(RTLD_NEXT, "ioctl");
-	_fcntl = dlsym(RTLD_NEXT, "fcntl");
-	_mmap = dlsym(RTLD_NEXT, "mmap");
-	_munmap = dlsym(RTLD_NEXT, "munmap");
-	_select = dlsym(RTLD_NEXT, "select");
-	_poll = dlsym(RTLD_NEXT, "poll");
-}
-
Index: debian/alsa-oss/aoss.1
diff -u debian/alsa-oss/aoss.1:1.1.1.1 debian/alsa-oss/aoss.1:removed
--- debian/alsa-oss/aoss.1:1.1.1.1	Sat May 31 19:53:54 2003
+++ debian/alsa-oss/aoss.1	Mon Mar  1 01:46:25 2004
@@ -1,42 +0,0 @@
-.TH AOSS 1 "3 October 2001"
-.SH NAME
-aoss \- Wrapper script to facilitate use of the ALSA OSS compatibility
-library.
-.SH SYNOPSYS
-\fBaoss\fP \fIosscommand\fP [arguments]
-
-.SH DESCRIPTION
-\fBaoss\fP is a simple wrapper script which facilitates the use of the
-ALSA OSS compatibility library. It just sets the appropriate LD_PRELOAD
-path and then runs the command.
-
-This is useful in cases where routing settings (which can be made in
-your .asoundrc file) need to be applied to commands that use the OSS
-API.
-
-Examples of asoundrc configuration:
-
-pcm.dsp0 {
-	type plug
-	slave.pcm "hw:0,0"
-}
-
-or
-
-pcm.dsp0 {
-	type plug
-	slave.pcm "dmix"
-}
-
-.SS Arguments
-.TP
-\fIosscommand\fP
-A command that uses the OSS API
-.TP
-\fIarguments\fP
-The appropriate arguments and options for the OSS command.
-.TP
-
-.SH AUTHORS
-The OSS compatibility library is by Abramo Bagnara <abramo@alsa-project.org>.
-The aoss script and this document are by James Tappin <james@xena.uklinux.net>.
Index: debian/alsa-oss/aoss.in
diff -u debian/alsa-oss/aoss.in:1.2 debian/alsa-oss/aoss.in:removed
--- debian/alsa-oss/aoss.in:1.2	Tue Feb 10 17:39:50 2004
+++ debian/alsa-oss/aoss.in	Mon Mar  1 01:46:25 2004
@@ -1,9 +0,0 @@
-#!/bin/sh
-
-# A simple script to facilitate the use of the OSS compatibility library.
-# Usage:
-#	aoss <command> <command options and arguments>
-
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-LD_PRELOAD=@libdir@/libaoss.so "$@"
Index: debian/alsa-oss/debian/changelog
diff -u debian/alsa-oss/debian/changelog:1.16 debian/alsa-oss/debian/changelog:1.17
--- debian/alsa-oss/debian/changelog:1.16	Thu Feb 26 04:41:48 2004
+++ debian/alsa-oss/debian/changelog	Mon Mar  1 01:46:25 2004
@@ -1,6 +1,7 @@
-alsa-oss (1.0.2-2) unstable; urgency=low
+alsa-oss (1.0.3a-1) unstable; urgency=low
 
   * Unreleased
+  * New upstream version
   * David B. Harris:
     - Change my Uploaders: email address from my private address to
       dbharris@debian.org