/* $Id$ */
/***
- This file is part of polypaudio.
+ This file is part of PulseAudio.
- polypaudio is free software; you can redistribute it and/or modify
+ PulseAudio is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
- polypaudio is distributed in the hope that it will be useful, but
+ PulseAudio 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 Lesser General Public License
- along with polypaudio; if not, write to the Free Software
+ along with PulseAudio; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA.
***/
#include <pthread.h>
#include <unistd.h>
#include <sys/socket.h>
+#include <sys/stat.h>
#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <signal.h>
+#ifdef __linux__
#include <linux/sockios.h>
+#endif
-#include <polyp/polypaudio.h>
-#include <polypcore/llist.h>
-#include <polypcore/gccmacro.h>
+#include <pulse/pulseaudio.h>
+#include <pulsecore/llist.h>
+#include <pulsecore/gccmacro.h>
typedef enum {
FD_INFO_MIXER,
pa_stream *rec_stream;
pa_io_event *io_event;
+ pa_io_event_flags_t io_flags;
void *buf;
size_t rec_offset;
static int (*_close)(int) = NULL;
static int (*_open)(const char *, int, mode_t) = NULL;
static FILE* (*_fopen)(const char *path, const char *mode) = NULL;
+#ifdef HAVE_OPEN64
static int (*_open64)(const char *, int, mode_t) = NULL;
static FILE* (*_fopen64)(const char *path, const char *mode) = NULL;
+#endif
static int (*_fclose)(FILE *f) = NULL;
static int (*_access)(const char *, int) = NULL;
static void reset_params(fd_info *i) {
assert(i);
- i->sample_spec.format = PA_SAMPLE_ULAW;
+ i->sample_spec.format = PA_SAMPLE_U8;
i->sample_spec.channels = 1;
i->sample_spec.rate = 8000;
i->fragment_size = 0;
return e;
if (pa_get_binary_name(p, sizeof(p)))
- snprintf(buf, n, "OSS Emulation[%s]", pa_path_get_filename(p));
+ snprintf(buf, n, "OSS Emulation[%s]", p);
else
snprintf(buf, n, "OSS");
i->play_stream = NULL;
i->rec_stream = NULL;
i->io_event = NULL;
+ i->io_flags = 0;
pthread_mutex_init(&i->mutex, NULL);
i->ref = 1;
i->buf = NULL;
char t[PA_SAMPLE_SPEC_SNPRINT_MAX];
fs = pa_frame_size(&i->sample_spec);
+
+ /* Don't fix things more than necessary */
+ if ((i->fragment_size % fs) == 0 &&
+ i->n_fragments >= 2 &&
+ i->fragment_size > 0)
+ return;
+
i->fragment_size = (i->fragment_size/fs)*fs;
/* Number of fragments set? */
if (i->io_event) {
pa_mainloop_api *api;
- pa_io_event_flags_t flags;
size_t n;
api = pa_threaded_mainloop_get_api(i->mainloop);
- flags = 0;
-
if (s == i->play_stream) {
n = pa_stream_writable_size(i->play_stream);
if (n == (size_t)-1) {
}
if (n >= i->fragment_size)
- flags |= PA_IO_EVENT_INPUT;
+ i->io_flags |= PA_IO_EVENT_INPUT;
+ else
+ i->io_flags &= ~PA_IO_EVENT_INPUT;
}
if (s == i->rec_stream) {
}
if (n >= i->fragment_size)
- flags |= PA_IO_EVENT_OUTPUT;
+ i->io_flags |= PA_IO_EVENT_OUTPUT;
+ else
+ i->io_flags &= ~PA_IO_EVENT_OUTPUT;
}
- api->io_enable(i->io_event, flags);
+ api->io_enable(i->io_event, i->io_flags);
}
}
api = pa_threaded_mainloop_get_api(i->mainloop);
api->io_free(i->io_event);
i->io_event = NULL;
+ i->io_flags = 0;
}
if (i->thread_fd >= 0) {
static int fd_info_copy_data(fd_info *i, int force) {
size_t n;
- pa_io_event_flags_t flags;
if (!i->play_stream && !i->rec_stream)
return -1;
- flags = 0;
-
if ((i->play_stream) && (pa_stream_get_state(i->play_stream) == PA_STREAM_READY)) {
n = pa_stream_writable_size(i->play_stream);
}
if (n >= i->fragment_size)
- flags |= PA_IO_EVENT_INPUT;
+ i->io_flags |= PA_IO_EVENT_INPUT;
+ else
+ i->io_flags &= ~PA_IO_EVENT_INPUT;
}
if ((i->rec_stream) && (pa_stream_get_state(i->rec_stream) == PA_STREAM_READY)) {
}
if (n >= i->fragment_size)
- flags |= PA_IO_EVENT_OUTPUT;
+ i->io_flags |= PA_IO_EVENT_OUTPUT;
+ else
+ i->io_flags &= ~PA_IO_EVENT_OUTPUT;
}
if (i->io_event) {
pa_mainloop_api *api;
api = pa_threaded_mainloop_get_api(i->mainloop);
- api->io_enable(i->io_event, flags);
+ api->io_enable(i->io_event, i->io_flags);
}
return 0;
pa_mainloop_api *api;
int ret;
int f;
- pa_io_event_flags_t ioflags;
debug(DEBUG_LEVEL_NORMAL, __FILE__": dsp_open()\n");
switch (flags & O_ACCMODE) {
case O_RDONLY:
- ioflags = PA_IO_EVENT_OUTPUT;
+ i->io_flags = PA_IO_EVENT_OUTPUT;
shutdown(i->thread_fd, SHUT_RD);
shutdown(i->app_fd, SHUT_WR);
break;
case O_WRONLY:
- ioflags = PA_IO_EVENT_INPUT;
+ i->io_flags = PA_IO_EVENT_INPUT;
shutdown(i->thread_fd, SHUT_WR);
shutdown(i->app_fd, SHUT_RD);
break;
case O_RDWR:
- ioflags = PA_IO_EVENT_INPUT | PA_IO_EVENT_OUTPUT;
+ i->io_flags = PA_IO_EVENT_INPUT | PA_IO_EVENT_OUTPUT;
break;
default:
return -1;
}
- if (!(i->io_event = api->io_new(api, i->thread_fd, ioflags, io_event_cb, i)))
+ if (!(i->io_event = api->io_new(api, i->thread_fd, i->io_flags, io_event_cb, i)))
goto fail;
pa_threaded_mainloop_unlock(i->mainloop);
static int sndstat_open(int flags, int *_errno) {
static const char sndstat[] =
- "Sound Driver:3.8.1a-980706 (Polypaudio Virtual OSS)\n"
+ "Sound Driver:3.8.1a-980706 (PulseAudio Virtual OSS)\n"
"Kernel: POSIX\n"
"Config options: 0\n"
"\n"
"Installed drivers:\n"
- "Type 255: Polypaudio Virtual OSS\n"
+ "Type 255: PulseAudio Virtual OSS\n"
"\n"
"Card config:\n"
- "Polypaudio Virtual OSS\n"
+ "PulseAudio Virtual OSS\n"
"\n"
"Audio devices:\n"
- "0: Polypaudio Virtual OSS\n"
+ "0: PulseAudio Virtual OSS\n"
"\n"
"Synth devices: NOT ENABLED IN CONFIG\n"
"\n"
"Timers:\n"
"\n"
"Mixers:\n"
- "0: Polypaudio Virtual OSS\n";
+ "0: PulseAudio Virtual OSS\n";
char fn[] = "/tmp/padsp-sndstat-XXXXXX";
mode_t u;
debug(DEBUG_LEVEL_NORMAL, __FILE__": sndstat_open()\n");
- if (flags != O_RDONLY && flags != (O_RDONLY|O_LARGEFILE)) {
+ if (flags != O_RDONLY
+#ifdef O_LARGEFILE
+ && flags != (O_RDONLY|O_LARGEFILE)
+#endif
+ ) {
*_errno = EACCES;
debug(DEBUG_LEVEL_NORMAL, __FILE__": bad access!\n");
goto fail;
debug(DEBUG_LEVEL_VERBOSE, __FILE__": open(%s)\n", filename);
va_start(args, flags);
- if (flags & O_CREAT)
+ if (flags & O_CREAT) {
+ if (sizeof(mode_t) < sizeof(int))
+ mode = va_arg(args, int);
+ else
mode = va_arg(args, mode_t);
+ }
va_end(args);
if (!function_enter()) {
pa_operation *o;
if (request == SOUND_MIXER_READ_PCM)
- o = pa_context_set_sink_volume_by_index(i->context, i->sink_index, pv, NULL, NULL);
+ o = pa_context_set_sink_volume_by_index(i->context, i->sink_index, pv, context_success_cb, i);
else
- o = pa_context_set_source_volume_by_index(i->context, i->source_index, pv, NULL, NULL);
+ o = pa_context_set_source_volume_by_index(i->context, i->source_index, pv, context_success_cb, i);
if (!o)
debug(DEBUG_LEVEL_NORMAL, __FILE__":Failed set volume: %s", pa_strerror(pa_context_errno(i->context)));
debug(DEBUG_LEVEL_NORMAL, __FILE__": SOUND_MIXER_INFO\n");
memset(mi, 0, sizeof(mixer_info));
- strncpy(mi->id, "POLYPAUDIO", sizeof(mi->id));
- strncpy(mi->name, "Polypaudio Virtual OSS", sizeof(mi->name));
+ strncpy(mi->id, "PULSEAUDIO", sizeof(mi->id));
+ strncpy(mi->name, "PulseAudio Virtual OSS", sizeof(mi->name));
pa_threaded_mainloop_lock(i->mainloop);
mi->modify_counter = i->volume_modify_count;
pa_threaded_mainloop_unlock(i->mainloop);
}
static int dsp_flush_fd(int fd) {
+#ifdef SIOCINQ
int l;
if (ioctl(fd, SIOCINQ, &l) < 0) {
}
return 0;
+#else
+# warning "Your platform does not support SIOCINQ, something might not work as intended."
+ return 0;
+#endif
}
static int dsp_flush_socket(fd_info *i) {
}
static int dsp_empty_socket(fd_info *i) {
+#ifdef SIOCINQ
int ret = -1;
/* Empty the socket */
}
return ret;
+#else
+# warning "Your platform does not support SIOCINQ, something might not work as intended."
+ return 0;
+#endif
}
static int dsp_drain(fd_info *i) {
i->fragment_size = 1 << (*(int*) argp);
i->n_fragments = (*(int*) argp) >> 16;
-
+
+ /* 0x7FFF means that we can set whatever we like */
+ if (i->n_fragments == 0x7FFF)
+ i->n_fragments = 12;
+
free_streams(i);
pa_threaded_mainloop_unlock(i->mainloop);
case SNDCTL_DSP_GETCAPS:
debug(DEBUG_LEVEL_NORMAL, __FILE__": SNDCTL_DSP_CAPS\n");
- *(int*) argp = DSP_CAP_DUPLEX | DSP_CAP_MULTI;
+ *(int*) argp = DSP_CAP_DUPLEX
+#ifdef DSP_CAP_MULTI
+ | DSP_CAP_MULTI
+#endif
+ ;
break;
case SNDCTL_DSP_GETODELAY: {
}
exit_loop:
-
+
+#ifdef SIOCINQ
if (ioctl(i->thread_fd, SIOCINQ, &l) < 0)
debug(DEBUG_LEVEL_NORMAL, __FILE__": SIOCINQ failed: %s\n", strerror(errno));
else
*(int*) argp += l;
+#else
+# warning "Your platform does not support SIOCINQ, something might not work as intended."
+#endif
pa_threaded_mainloop_unlock(i->mainloop);
case SNDCTL_DSP_GETOSPACE:
case SNDCTL_DSP_GETISPACE: {
audio_buf_info *bi = (audio_buf_info*) argp;
- int l;
+ int l = 0;
size_t k = 0;
if (request == SNDCTL_DSP_GETOSPACE)
} else
k = i->fragment_size * i->n_fragments;
+#ifdef SIOCINQ
if (ioctl(i->thread_fd, SIOCINQ, &l) < 0) {
debug(DEBUG_LEVEL_NORMAL, __FILE__": SIOCINQ failed: %s\n", strerror(errno));
l = 0;
}
+#else
+# warning "Your platform does not dsp_flush_fd, something might not work as intended."
+#endif
bi->bytes = k > (size_t) l ? k - l : 0;
} else {
} else
k = 0;
+#ifdef SIOCINQ
if (ioctl(i->app_fd, SIOCINQ, &l) < 0) {
debug(DEBUG_LEVEL_NORMAL, __FILE__": SIOCINQ failed: %s\n", strerror(errno));
l = 0;
}
-
+#else
+# warning "Your platform does not dsp_flush_fd, something might not work as intended."
+#endif
bi->bytes = k + l;
}
break;
}
-
+
+ case SNDCTL_DSP_GETIPTR:
+ debug(DEBUG_LEVEL_NORMAL, __FILE__": invalid ioctl SNDCTL_DSP_GETIPTR\n");
+ goto inval;
+
+ case SNDCTL_DSP_GETOPTR:
+ debug(DEBUG_LEVEL_NORMAL, __FILE__": invalid ioctl SNDCTL_DSP_GETOPTR\n");
+ goto inval;
+
default:
debug(DEBUG_LEVEL_NORMAL, __FILE__": unknown ioctl 0x%08lx\n", request);
+inval:
*_errno = EINVAL;
goto fail;
}
return 0;
}
+#ifdef HAVE_OPEN64
+
int open64(const char *filename, int flags, ...) {
va_list args;
mode_t mode = 0;
return open(filename, flags, mode);
}
+#endif
+
FILE* fopen(const char *filename, const char *mode) {
FILE *f = NULL;
int fd;
return f;
}
+#ifdef HAVE_OPEN64
+
FILE *fopen64(const char *filename, const char *mode) {
debug(DEBUG_LEVEL_VERBOSE, __FILE__": fopen64(%s)\n", filename);
return fopen(filename, mode);
}
+#endif
+
int fclose(FILE *f) {
fd_info *i;