Update of /cvsroot/alsa/alsa-oss/alsa In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12689/alsa
Modified Files: Makefile.am alsa-oss.c aoss.in Log Message: - separated libaoss to libaoss (LD_PRELOAD wrapper) and libalsatoss (user space emulation) - some fixes in oss-redir library - note that code is not tested at all, so I'm 100% that it will fail :-( Index: Makefile.am =================================================================== RCS file: /cvsroot/alsa/alsa-oss/alsa/Makefile.am,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Makefile.am 9 Feb 2004 12:36:39 -0000 1.1 +++ Makefile.am 10 Feb 2004 13:39:55 -0000 1.2 @@ -1,10 +1,13 @@ -lib_LTLIBRARIES = libaoss.la +lib_LTLIBRARIES = libalsatoss.la libaoss.la bin_SCRIPTS = aoss man_MANS = aoss.1 EXTRA_DIST = aoss.1 libaoss_la_SOURCES = alsa-oss.c -libaoss_la_LIBADD = -ldl -lasound +libaoss_la_LIBADD = -ldl -lalsatoss + +libalsatoss_la_SOURCES = pcm.c mixer.c +libalsatoss_la_LIBADD = -lasound clean: rm -f aoss Index: alsa-oss.c =================================================================== RCS file: /cvsroot/alsa/alsa-oss/alsa/alsa-oss.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- alsa-oss.c 9 Feb 2004 12:36:39 -0000 1.1 +++ alsa-oss.c 10 Feb 2004 13:39:55 -0000 1.2 @@ -1,6 +1,7 @@ /* * OSS -> ALSA compatibility layer - * Copyright (c) by Abramo Bagnara <[EMAIL PROTECTED]> + * Copyright (c) by Abramo Bagnara <[EMAIL PROTECTED]>, + * Jaroslav Kysela <[EMAIL PROTECTED]> * * * This program is free software; you can redistribute it and/or modify @@ -38,31 +39,7 @@ #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; -static snd_output_t *debug_out = NULL; - -#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 +#include "alsa-oss-emul.h" 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); @@ -76,64 +53,20 @@ 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); + int (*munmap)(void* addr, size_t len); } ops_t; - -typedef struct { - snd_pcm_t *pcm; - size_t frame_bytes; - struct { - snd_pcm_uframes_t period_size; - snd_pcm_uframes_t buffer_size; - snd_pcm_uframes_t boundary; - snd_pcm_uframes_t old_hw_ptr; - size_t mmap_buffer_bytes; - size_t mmap_period_bytes; - } alsa; - struct { - snd_pcm_uframes_t period_size; - unsigned int periods; - snd_pcm_uframes_t buffer_size; - size_t bytes; - } oss; - unsigned int stopped:1; - void *mmap_buffer; - size_t mmap_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; +} fd_class_t; static ops_t ops[FD_CLASSES]; @@ -145,1223 +78,39 @@ } fd_t; static int open_max; +static int poll_fds_add = 0; 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 unsigned int ld2(u_int32_t v) -{ - unsigned r = 0; - - if (v >= 0x10000) { - v >>= 16; - r += 16; - } - if (v >= 0x100) { - v >>= 8; - r += 8; - } - if (v >= 0x10) { - v >>= 4; - r += 4; - } - if (v >= 4) { - v >>= 2; - r += 2; - } - if (v >= 2) - r++; - return r; -} - -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; - rate = dsp->rate; - err = snd_pcm_hw_params_set_rate_near(pcm, hw, &rate, 0); - if (err < 0) - return err; -#if 0 - err = snd_pcm_hw_params_set_periods_integer(pcm, hw); - if (err < 0) - return err; -#endif - - 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->alsa.mmap_period_bytes / str->frame_bytes, 0); - if (err < 0) - return err; - err = snd_pcm_hw_params_set_buffer_size(pcm, hw, str->alsa.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; - s *= 16; - while (s >= 1024 && (err = snd_pcm_hw_params_set_buffer_size(pcm, hw, s)) < 0) - s /= 2; - s = (1 << dsp->fragshift) / str->frame_bytes; - while (s >= 256 && (err = snd_pcm_hw_params_set_period_size(pcm, hw, s, 0)) < 0) - s /= 2; - if (err < 0) { - 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, old_s; - while (s * 2 < dsp->rate / 2) - s *= 2; - old_s = s = s / 2; - while (s >= 1024 && (err = snd_pcm_hw_params_set_buffer_size(pcm, hw, s)) < 0) - s /= 2; - s = old_s; - while (s >= 256 && (err = snd_pcm_hw_params_set_period_size(pcm, hw, s, 0)) < 0) - s /= 2; - if (err < 0) { - s = old_s; - 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 (err < 0) - return err; -#if 0 - if (debug) - snd_pcm_dump_setup(pcm, stderr); -#endif - if (err < 0) - return err; - dsp->oss_format = alsa_format_to_oss(dsp->format); - err = snd_pcm_hw_params_get_period_size(hw, &str->alsa.period_size, 0); - if (err < 0) - return err; - err = snd_pcm_hw_params_get_buffer_size(hw, &str->alsa.buffer_size); - if (err < 0) - return err; - str->oss.buffer_size = 1 << ld2(str->alsa.buffer_size); - if (str->oss.buffer_size < str->alsa.buffer_size) - str->oss.buffer_size *= 2; - str->oss.period_size = 1 << ld2(str->alsa.period_size); - if (str->oss.period_size < str->alsa.period_size) - str->oss.period_size *= 2; - str->oss.periods = str->oss.buffer_size / str->oss.period_size; - if (str->mmap_areas) - free(str->mmap_areas); - str->mmap_areas = NULL; - 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->alsa.buffer_size + 1 : - str->alsa.period_size); -#if 1 - snd_pcm_sw_params_set_stop_threshold(pcm, sw, - str->mmap_buffer ? LONG_MAX : - str->alsa.buffer_size); -#else - snd_pcm_sw_params_set_stop_threshold(pcm, sw, - LONG_MAX); - snd_pcm_sw_params_set_silence_threshold(pcm, sw, - str->alsa.period_size); - snd_pcm_sw_params_set_silence_size(pcm, sw, - str->alsa.period_size); -#endif - err = snd_pcm_sw_params(pcm, sw); - if (err < 0) - return err; - str->alsa.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; -#if 0 - if (debug && debug_out) { - int k; - for (k = 1; k >= 0; --k) { - oss_dsp_stream_t *str = &dsp->streams[k]; - if (str->pcm) - snd_pcm_dump(str->pcm, debug_out); - } - } -#endif - 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]; - - if (debug_out == NULL) { - if (snd_output_stdio_attach(&debug_out, stderr, 0) < 0) - debug_out = NULL; - } - 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) +static int oss_pcm_fcntl(int fd, int cmd, ...) { - 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 == -EPIPE && - snd_pcm_state(pcm) == SND_PCM_STATE_SUSPENDED) { - while ((result = snd_pcm_resume(pcm)) == -EAGAIN) - sleep(1); - if (result < 0 && (result = snd_pcm_prepare(pcm)) == 0) - goto _again; - } - if (result < 0) { - errno = -result; - result = -1; - goto _end; - } - result *= str->frame_bytes; - str->oss.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 == -EPIPE && - snd_pcm_state(pcm) == SND_PCM_STATE_SUSPENDED) { - while ((result = snd_pcm_resume(pcm)) == -EAGAIN) - sleep(1); - if (result < 0 && (result = snd_pcm_prepare(pcm)) == 0) - goto _again; - } - if (result < 0) { - errno = -result; - result = -1; - goto _end; - } - result *= str->frame_bytes; - str->oss.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->alsa.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; + long arg; va_start(args, cmd); - arg = va_arg(args, void *); + arg = va_arg(args, long); 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->oss.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->oss.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->alsa.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->oss.buffer_size) - avail = str->oss.buffer_size; - info->fragsize = str->oss.period_size * str->frame_bytes; - info->fragstotal = str->oss.periods; - info->bytes = avail * str->frame_bytes; - info->fragments = avail / str->oss.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->oss.buffer_size) - avail = str->oss.buffer_size; - info->fragsize = str->oss.period_size * str->frame_bytes; - info->fragstotal = str->oss.periods; - info->bytes = avail * str->frame_bytes; - info->fragments = avail / str->oss.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->oss.buffer_size; - info->ptr *= str->frame_bytes; - if (str->mmap_buffer) { - ssize_t n = (hw_ptr / str->oss.period_size) - (str->alsa.old_hw_ptr / str->oss.period_size); - if (n < 0) - n += str->alsa.boundary / str->oss.period_size; - info->blocks = n; - str->alsa.old_hw_ptr = hw_ptr; - } else - info->blocks = delay / str->oss.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->oss.buffer_size; - info->ptr *= str->frame_bytes; - if (str->mmap_buffer) { - ssize_t n = (hw_ptr / str->oss.period_size) - (str->alsa.old_hw_ptr / str->oss.period_size); - if (n < 0) - n += str->alsa.boundary / str->oss.period_size; - info->blocks = n; - str->alsa.old_hw_ptr = hw_ptr; - } else - info->blocks = delay / str->oss.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; + case F_SETFL: + result = lib_oss_pcm_nonblock(fd, (arg & O_NONBLOCK) ? 1 : 0); + if (result < 0) { + errno = -result; + return -1; + } + return 0; default: - DEBUG("%lx, %p)\n", cmd, arg); - // return oss_mixer_ioctl(...); - err = -ENXIO; - break; + DEBUG("pcm_fcntl(%d, ", fd); + result = _fcntl(fd, cmd, arg); + if (result < 0) + return result; + DEBUG("%x, %ld)\n", cmd, arg); + return result; } - 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, ...) +static int oss_mixer_fcntl(int fd, int cmd, ...) { int result; va_list args; @@ -1370,447 +119,63 @@ 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("mixer_fcntl(%d, ", fd); + result = _fcntl(fd, cmd, arg); + if (result < 0) + return result; 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) +static ssize_t bad_write(int fd ATTRIBUTE_UNUSED, const void *buf ATTRIBUTE_UNUSED, size_t n 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->alsa.mmap_period_bytes = str->oss.period_size * str->frame_bytes; - str->alsa.mmap_buffer_bytes = str->oss.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; + errno = EBADFD; return -1; } -static ssize_t oss_mixer_read(int fd ATTRIBUTE_UNUSED, void *buf ATTRIBUTE_UNUSED, size_t n ATTRIBUTE_UNUSED) +static ssize_t bad_read(int fd ATTRIBUTE_UNUSED, void *buf ATTRIBUTE_UNUSED, size_t n ATTRIBUTE_UNUSED) { - errno = -EBADFD; + errno = EBADFD; return -1; } - -static int oss_mixer_read_recsrc(oss_mixer_t *mixer, unsigned int *ret) +static void *bad_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) { - 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; + errno = EBADFD; + return NULL; } - -static int oss_mixer_ioctl(int fd, unsigned long cmd, ...) +static int bad_munmap(void* addr ATTRIBUTE_UNUSED, size_t len ATTRIBUTE_UNUSED) { - 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; + 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, + [FD_OSS_DSP] = { + close: lib_oss_pcm_close, + write: lib_oss_pcm_write, + read: lib_oss_pcm_read, + ioctl: lib_oss_pcm_ioctl, + fcntl: oss_pcm_fcntl, + mmap: lib_oss_pcm_mmap, + munmap: lib_oss_pcm_munmap, + }, + [FD_OSS_MIXER] = { + close: lib_oss_mixer_close, + write: bad_write, + read: bad_read, + ioctl: lib_oss_mixer_ioctl, fcntl: oss_mixer_fcntl, - mmap: oss_mixer_mmap, - munmap: oss_mixer_munmap, + mmap: bad_mmap, + munmap: bad_munmap, }, }; @@ -1818,7 +183,6 @@ { va_list args; mode_t mode = 0; - int k; int fd; if (oflag & O_CREAT) { @@ -1826,40 +190,44 @@ 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; - } + if (!strncmp(file, "/dev/dsp", 8) || + !strncmp(file, "/dev/adsp", 9) || + !strncmp(file, "/dev/audio", 10)) { + fd = lib_oss_pcm_open(file, oflag); + if (fd >= 0) { + fds[fd]->class = FD_OSS_DSP; + poll_fds_add += lib_oss_pcm_poll_fds(fd); + } + } else if (!strncmp(file, "/dev/mixer", 10)) { + fd = lib_oss_mixer_open(file, oflag); + fds[fd]->class = FD_OSS_MIXER; + } else { + fd = _open(file, oflag, mode); + if (fd >= 0) + assert(fds[fd] == NULL); } - 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) { + if (fd < 0 || fd >= open_max || fds[fd] == NULL) { + return _close(fd); + } else { + fd_t *xfd = fds[fd]; int err; - err = ops[fds[fd]->class].close(fd); + + fds[fd] = NULL; + poll_fds_add -= lib_oss_pcm_poll_fds(fd); + err = ops[xfd->class].close(fd); assert(err >= 0); - free(fds[fd]); + return err; } - fds[fd] = 0; - return result; } ssize_t write(int fd, const void *buf, size_t n) { - if (fd < 0 || fd >= open_max || !fds[fd]) + if (fd < 0 || fd >= open_max || fds[fd] == NULL) return _write(fd, buf, n); else return ops[fds[fd]->class].write(fd, buf, n); @@ -1867,7 +235,7 @@ ssize_t read(int fd, void *buf, size_t n) { - if (fd < 0 || fd >= open_max || !fds[fd]) + if (fd < 0 || fd >= open_max || fds[fd] == NULL) return _read(fd, buf, n); else return ops[fds[fd]->class].read(fd, buf, n); @@ -1881,7 +249,7 @@ va_start(args, request); arg = va_arg(args, void *); va_end(args); - if (fd < 0 || fd >= open_max || !fds[fd]) + if (fd < 0 || fd >= open_max || fds[fd] == NULL) return _ioctl(fd, request, arg); else return ops[fds[fd]->class].ioctl(fd, request, arg); @@ -1895,7 +263,7 @@ va_start(args, cmd); arg = va_arg(args, void *); va_end(args); - if (fd < 0 || fd >= open_max || !fds[fd]) + if (fd < 0 || fd >= open_max || fds[fd] == NULL) return _fcntl(fd, cmd, arg); else return ops[fds[fd]->class].fcntl(fd, cmd, arg); @@ -1904,7 +272,7 @@ 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]) + if (fd < 0 || fd >= open_max || fds[fd] == NULL) 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) @@ -1922,7 +290,7 @@ if (fd >= open_max) return _munmap(addr, len); fds[fd]->mmap_area = 0; - return ops[fds[fd]->class].munmap(fd, addr, len); + return ops[fds[fd]->class].munmap(addr, len); } #ifdef DEBUG_POLL @@ -1980,22 +348,13 @@ } #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]; + struct pollfd pfds1[nfds + poll_fds_add + 16]; nfds1 = 0; for (k = 0; k < nfds; ++k) { int fd = pfds[k].fd; @@ -2005,18 +364,8 @@ 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++; - } - } + lib_oss_pcm_poll_prepare(fd, &pfds1[nfds1]); + nfds1 += lib_oss_pcm_poll_fds(fd); direct = 0; break; } @@ -2032,7 +381,7 @@ if (direct) return _poll(pfds, nfds, timeout); #ifdef DEBUG_POLL - if (debug) { + if (alsa_oss_debug) { fprintf(stderr, "Orig enter "); dump_poll(pfds, nfds, timeout); fprintf(stderr, "Changed enter "); @@ -2052,16 +401,14 @@ switch (fds[fd]->class) { case FD_OSS_DSP: { - oss_dsp_t *dsp = fds[fd]->private; - oss_dsp_stream_t *str; - int j; + int result = lib_oss_pcm_poll_result(fd, &pfds1[nfds1]); revents = 0; - for (j = 0; j < 2; ++j) { - str = &dsp->streams[j]; - if (str->pcm) { - revents |= pfds1[nfds1].revents; - nfds1++; - } + if (result < 0) { + revents |= POLLNVAL; + } else { + revents |= ((result & OSS_WAIT_EVENT_ERROR) ? POLLERR : 0) | + ((result & OSS_WAIT_EVENT_READ) ? POLLIN : 0) | + ((result & OSS_WAIT_EVENT_WRITE) ? POLLOUT : 0); } break; } @@ -2076,7 +423,7 @@ count1++; } #ifdef DEBUG_POLL - if (debug) { + if (alsa_oss_debug) { fprintf(stderr, "Changed exit "); dump_poll(pfds1, nfds1, timeout); fprintf(stderr, "Orig exit "); @@ -2121,29 +468,9 @@ 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); - } - } + lib_oss_pcm_select_prepare(fd, r ? rfds1 : NULL, + w ? wfds1 : NULL, + e ? efds1 : NULL); direct = 0; break; } @@ -2154,7 +481,7 @@ if (direct) return _select(nfds, rfds, wfds, efds, timeout); #ifdef DEBUG_SELECT - if (debug) { + if (alsa_oss_debug) { fprintf(stderr, "Orig enter "); dump_select(nfds, rfds, wfds, efds, timeout); fprintf(stderr, "Changed enter "); @@ -2186,21 +513,20 @@ switch (fds[fd]->class) { case FD_OSS_DSP: { - oss_dsp_t *dsp = fds[fd]->private; - oss_dsp_stream_t *str; - int j; + int result = lib_oss_pcm_select_result(fd, rfds1, wfds1, efds1); 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++; - } + if (result < 0 && e) { + FD_SET(fd, efds); + e1 = 1; + } else if (result & OSS_WAIT_EVENT_ERROR) { + FD_SET(fd, efds); + e1 = 1; + } else if (result & OSS_WAIT_EVENT_READ) { + FD_SET(fd, rfds); + r1 = 1; + } else if (result & OSS_WAIT_EVENT_WRITE) { + FD_SET(fd, wfds); + w1 = 1; } break; } @@ -2220,7 +546,7 @@ count1++; } #ifdef DEBUG_SELECT - if (debug) { + if (alsa_oss_debug) { fprintf(stderr, "Changed exit "); dump_select(nfds1, rfds1, wfds1, efds1, timeout); fprintf(stderr, "Orig exit "); @@ -2293,9 +619,12 @@ static void initialize() { - char *s = getenv("ALSA_OSS_DEBUG"); + char *s = getenv("ALSA_OSS_WRAPPER"); + if (s == NULL) + return; + s = getenv("ALSA_OSS_DEBUG"); if (s) - debug = 1; + alsa_oss_debug = 1; open_max = sysconf(_SC_OPEN_MAX); if (open_max < 0) exit(1); @@ -2313,4 +642,3 @@ _select = dlsym(RTLD_NEXT, "select"); _poll = dlsym(RTLD_NEXT, "poll"); } - Index: aoss.in =================================================================== RCS file: /cvsroot/alsa/alsa-oss/alsa/aoss.in,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- aoss.in 9 Feb 2004 12:36:39 -0000 1.1 +++ aoss.in 10 Feb 2004 13:39:55 -0000 1.2 @@ -6,4 +6,4 @@ [EMAIL PROTECTED]@ [EMAIL PROTECTED]@ [EMAIL PROTECTED]@/libaoss.so $* +ALSA_OSS_WRAPPER=1 [EMAIL PROTECTED]@/libaoss.so $* ------------------------------------------------------- The SF.Net email is sponsored by EclipseCon 2004 Premiere Conference on Open Tools Development and Integration See the breadth of Eclipse activity. February 3-5 in Anaheim, CA. http://www.eclipsecon.org/osdn _______________________________________________ Alsa-cvslog mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/alsa-cvslog