From d4e0d51c157dea740d35089f077451b6ec7b11a5 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 11 Jul 2004 23:21:32 +0000 Subject: make module-oss-* use modargs git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@63 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/main.c | 2 +- src/module-oss-mmap.c | 68 +++++++++++++++++++++++++------------------------- src/module-oss.c | 62 ++++++++++++++++++++++++++------------------- src/module-pipe-sink.c | 4 +-- src/oss-util.c | 54 +++++++++++++++++++++++++++++++++++++++ src/oss-util.h | 1 + src/todo | 14 +++++------ 7 files changed, 135 insertions(+), 70 deletions(-) (limited to 'src') diff --git a/src/main.c b/src/main.c index e2d86b48..8ba554c8 100644 --- a/src/main.c +++ b/src/main.c @@ -42,7 +42,7 @@ int main(int argc, char *argv[]) { c = pa_core_new(pa_mainloop_get_api(mainloop)); assert(c); - pa_module_load(c, "module-oss-mmap", "/dev/dsp"); + pa_module_load(c, "module-oss-mmap", "device=/dev/dsp playback=1 record=1"); /* pa_module_load(c, "module-oss-mmap", "/dev/dsp1");*/ /* pa_module_load(c, "module-pipe-sink", NULL);*/ pa_module_load(c, "module-simple-protocol-tcp", NULL); diff --git a/src/module-oss-mmap.c b/src/module-oss-mmap.c index 772abf99..a9e13086 100644 --- a/src/module-oss-mmap.c +++ b/src/module-oss-mmap.c @@ -18,6 +18,7 @@ #include "oss-util.h" #include "sample-util.h" #include "util.h" +#include "modargs.h" struct userdata { struct pa_sink *sink; @@ -38,8 +39,18 @@ struct userdata { unsigned out_current, in_current; }; -void module_done(struct pa_core *c, struct pa_module*m); +static const char* const valid_modargs[] = { + "sink_name", + "source_name", + "device", + "record", + "playback", + NULL +}; +#define DEFAULT_SINK_NAME "oss_output" +#define DEFAULT_SOURCE_NAME "oss_input" +#define DEFAULT_DEVICE "/dev/dsp" static void out_fill_memblocks(struct userdata *u, unsigned n) { assert(u && u->out_memblocks); @@ -163,10 +174,12 @@ static uint32_t sink_get_latency_cb(struct pa_sink *s) { int pa_module_init(struct pa_core *c, struct pa_module*m) { struct audio_buf_info info; struct userdata *u = NULL; - char *p; + const char *p; int frag_size; - int mode, caps, caps_read = 0; + int mode, caps; int enable_bits = 0, zero = 0; + int playback = 1, record = 1; + struct pa_modargs *ma = NULL; assert(c && m); m->userdata = u = malloc(sizeof(struct userdata)); @@ -174,39 +187,26 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) { memset(u, 0, sizeof(struct userdata)); u->fd = -1; u->core = c; - - p = m->argument ? m->argument : "/dev/dsp"; - if ((u->fd = open(p, (mode = O_RDWR)|O_NDELAY)) >= 0) { - ioctl(u->fd, SNDCTL_DSP_SETDUPLEX, 0); - - if (ioctl(u->fd, SNDCTL_DSP_GETCAPS, &caps) < 0) { - fprintf(stderr, "SNDCTL_DSP_GETCAPS: %s\n", strerror(errno)); - goto fail; - } - if (!(caps & DSP_CAP_DUPLEX)) { - close(u->fd); - u->fd = -1; - } else - caps_read = 1; + if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { + fprintf(stderr, __FILE__": failed to parse module arguments.\n"); + goto fail; } - - if (u->fd < 0) { - if ((u->fd = open(p, (mode = O_WRONLY)|O_NDELAY)) < 0) { - if ((u->fd = open(p, (mode = O_RDONLY)|O_NDELAY)) < 0) { - fprintf(stderr, "open('%s'): %s\n", p, strerror(errno)); - goto fail; - } - } + + if (pa_modargs_get_value_u32(ma, "record", &record) < 0 || pa_modargs_get_value_u32(ma, "playback", &playback) < 0) { + fprintf(stderr, __FILE__": record= and playback= expect numeric arguments.\n"); + goto fail; } - if (!caps_read) { - if (ioctl(u->fd, SNDCTL_DSP_GETCAPS, &caps) < 0) { - fprintf(stderr, "SNDCTL_DSP_GETCAPS: %s\n", strerror(errno)); - goto fail; - } + mode = (playback&&record) ? O_RDWR : (playback ? O_WRONLY : (record ? O_RDONLY : 0)); + if (mode == 0) { + fprintf(stderr, __FILE__": neither playback nor record enabled for device.\n"); + goto fail; } - + + if ((u->fd = pa_oss_open(p = pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), &mode, &caps)) < 0) + goto fail; + if (!(caps & DSP_CAP_MMAP) || !(caps & DSP_CAP_REALTIME) || !(caps & DSP_CAP_TRIGGER)) { fprintf(stderr, "OSS device not mmap capable.\n"); goto fail; @@ -242,7 +242,7 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) { } } else { - u->source = pa_source_new(c, "oss_input", 0, &u->sample_spec); + u->source = pa_source_new(c, pa_modargs_get_value(ma, "source_name", DEFAULT_SOURCE_NAME), 0, &u->sample_spec); assert(u->source); u->source->userdata = u; pa_source_set_owner(u->source, m); @@ -276,7 +276,7 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) { } else { pa_silence_memory(u->out_mmap, u->out_mmap_length, &u->sample_spec); - u->sink = pa_sink_new(c, "oss_output", 0, &u->sample_spec); + u->sink = pa_sink_new(c, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME), 0, &u->sample_spec); assert(u->sink); u->sink->get_latency = sink_get_latency_cb; u->sink->userdata = u; @@ -309,7 +309,7 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) { return 0; fail: - module_done(c, m); + pa_module_done(c, m); return -1; } diff --git a/src/module-oss.c b/src/module-oss.c index b0677584..31ca2dba 100644 --- a/src/module-oss.c +++ b/src/module-oss.c @@ -17,6 +17,7 @@ #include "oss-util.h" #include "sample-util.h" #include "util.h" +#include "modargs.h" struct userdata { struct pa_sink *sink; @@ -31,6 +32,19 @@ struct userdata { int fd; }; +static const char* const valid_modargs[] = { + "sink_name", + "source_name", + "device", + "record", + "playback", + NULL +}; + +#define DEFAULT_SINK_NAME "oss_output" +#define DEFAULT_SOURCE_NAME "oss_input" +#define DEFAULT_DEVICE "/dev/dsp" + static void do_write(struct userdata *u) { struct pa_memchunk *memchunk; ssize_t r; @@ -115,39 +129,34 @@ static uint32_t sink_get_latency_cb(struct pa_sink *s) { int pa_module_init(struct pa_core *c, struct pa_module*m) { struct audio_buf_info info; struct userdata *u = NULL; - char *p; + const char *p; int fd = -1; int frag_size, in_frag_size, out_frag_size; int mode; + uint32_t record = 1, playback = 1; struct pa_sample_spec ss; + struct pa_modargs *ma = NULL; assert(c && m); - p = m->argument ? m->argument : "/dev/dsp"; - if ((fd = open(p, (mode = O_RDWR)|O_NDELAY)) >= 0) { - int caps; - - ioctl(fd, SNDCTL_DSP_SETDUPLEX, 0); - - if (ioctl(fd, SNDCTL_DSP_GETCAPS, &caps) < 0) { - fprintf(stderr, "SNDCTL_DSP_GETCAPS: %s\n", strerror(errno)); - goto fail; - } - - if (!(caps & DSP_CAP_DUPLEX)) { - close(fd); - fd = -1; - } + if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { + fprintf(stderr, __FILE__": failed to parse module arguments.\n"); + goto fail; + } + + if (pa_modargs_get_value_u32(ma, "record", &record) < 0 || pa_modargs_get_value_u32(ma, "playback", &playback) < 0) { + fprintf(stderr, __FILE__": record= and playback= expect numeric argument.\n"); + goto fail; } - if (fd < 0) { - if ((fd = open(p, (mode = O_WRONLY)|O_NDELAY)) < 0) { - if ((fd = open(p, (mode = O_RDONLY)|O_NDELAY)) < 0) { - fprintf(stderr, "open('%s'): %s\n", p, strerror(errno)); - goto fail; - } - } + mode = (playback&&record) ? O_RDWR : (playback ? O_WRONLY : (record ? O_RDONLY : 0)); + if (mode == 0) { + fprintf(stderr, __FILE__": neither playback nor record enabled for device.\n"); + goto fail; } + if ((fd = pa_oss_open(p = pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), &mode, NULL)) < 0) + goto fail; + fprintf(stderr, "module-oss: device opened in %s mode.\n", mode == O_WRONLY ? "O_WRONLY" : (mode == O_RDONLY ? "O_RDONLY" : "O_RDWR")); frag_size = ((int) 12 << 16) | 10; /* nfrags = 12; frag_size = 2^10 */ @@ -182,7 +191,7 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) { u->core = c; if (mode != O_WRONLY) { - u->source = pa_source_new(c, "oss_input", 0, &ss); + u->source = pa_source_new(c, pa_modargs_get_value(ma, "source_name", DEFAULT_SOURCE_NAME), 0, &ss); assert(u->source); u->source->userdata = u; pa_source_set_owner(u->source, m); @@ -191,7 +200,7 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) { u->source = NULL; if (mode != O_RDONLY) { - u->sink = pa_sink_new(c, "oss_output", 0, &ss); + u->sink = pa_sink_new(c, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME), 0, &ss); assert(u->sink); u->sink->get_latency = sink_get_latency_cb; u->sink->userdata = u; @@ -226,6 +235,9 @@ fail: if (fd >= 0) close(fd); + if (ma) + pa_modargs_free(ma); + return -1; } diff --git a/src/module-pipe-sink.c b/src/module-pipe-sink.c index e5e97b51..29767ea8 100644 --- a/src/module-pipe-sink.c +++ b/src/module-pipe-sink.c @@ -34,7 +34,7 @@ static const char* const valid_modargs[] = { "rate", "channels", "format", - "sink", + "sink_name", NULL }; @@ -131,7 +131,7 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) { assert(u->filename); u->core = c; - if (!(u->sink = pa_sink_new(c, pa_modargs_get_value(ma, "sink", DEFAULT_SINK_NAME), 0, &ss))) { + if (!(u->sink = pa_sink_new(c, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME), 0, &ss))) { fprintf(stderr, __FILE__": failed to create sink.\n"); goto fail; } diff --git a/src/oss-util.c b/src/oss-util.c index 9c4f55ca..f1e07017 100644 --- a/src/oss-util.c +++ b/src/oss-util.c @@ -4,9 +4,63 @@ #include #include #include +#include +#include +#include +#include #include "oss-util.h" +int pa_oss_open(const char *device, int *mode, int* pcaps) { + int fd = -1; + assert(device && mode && (*mode == O_RDWR || *mode == O_RDONLY || *mode == O_WRONLY)); + + if (*mode == O_RDWR) { + if ((fd = open(device, O_RDWR|O_NDELAY)) >= 0) { + int dcaps, *tcaps; + ioctl(fd, SNDCTL_DSP_SETDUPLEX, 0); + + tcaps = pcaps ? pcaps : &dcaps; + + if (ioctl(fd, SNDCTL_DSP_GETCAPS, tcaps) < 0) { + fprintf(stderr, __FILE__": SNDCTL_DSP_GETCAPS: %s\n", strerror(errno)); + goto fail; + } + + if (*tcaps & DSP_CAP_DUPLEX) + return fd; + + close(fd); + } + + if ((fd = open(device, (*mode = O_WRONLY)|O_NDELAY)) < 0) { + if ((fd = open(device, (*mode = O_RDONLY)|O_NDELAY)) < 0) { + fprintf(stderr, __FILE__": open('%s'): %s\n", device, strerror(errno)); + goto fail; + } + } + } else { + if ((fd = open(device, *mode|O_NDELAY)) < 0) { + fprintf(stderr, __FILE__": open('%s'): %s\n", device, strerror(errno)); + goto fail; + } + } + + if (pcaps) { + if (ioctl(fd, SNDCTL_DSP_GETCAPS, pcaps) < 0) { + fprintf(stderr, "SNDCTL_DSP_GETCAPS: %s\n", strerror(errno)); + goto fail; + } + } + + return fd; + +fail: + if (fd >= 0) + close(fd); + return fd; +} + int pa_oss_auto_format(int fd, struct pa_sample_spec *ss) { int format, channels, speed; diff --git a/src/oss-util.h b/src/oss-util.h index cf12e8e6..030afba4 100644 --- a/src/oss-util.h +++ b/src/oss-util.h @@ -3,6 +3,7 @@ #include "sample.h" +int pa_oss_open(const char *device, int *mode, int* pcaps); int pa_oss_auto_format(int fd, struct pa_sample_spec *ss); #endif diff --git a/src/todo b/src/todo index b131ac73..febdca7c 100644 --- a/src/todo +++ b/src/todo @@ -1,13 +1,7 @@ - native library/protocol: more functions (esp. latency) -- make all modules use modargs.c: - module-oss.c - module-oss-mmap.c -- cmdline -- daemonizing - -- move more stuff from module-oss[-dma] to liboss-util +- cmdline & daemonizing - prefix modules/libraries with pa_ @@ -17,7 +11,10 @@ - svn-id and license in every file - documentation -- eliminate global variables +- eliminate global variables: + pa_default_sample_spec + pa_memblock_count + pa_memblock_total -- post 0.1 - future cancellation @@ -27,6 +24,7 @@ - slp/rendezvous - doxygen - make mcalign merge chunks +- modinfo drivers: - libao -- cgit