X-Git-Url: https://code.delx.au/pulseaudio/blobdiff_plain/36550f4a66ae28e1b81b9b818c38cd0fcd1302a1..fa499dad06ba6558111cdef64c18f2401e803cff:/polyp/module-oss-mmap.c diff --git a/polyp/module-oss-mmap.c b/polyp/module-oss-mmap.c index 5c3be1ad..8aecd560 100644 --- a/polyp/module-oss-mmap.c +++ b/polyp/module-oss-mmap.c @@ -4,7 +4,7 @@ This file is part of polypaudio. polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published + 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. @@ -13,7 +13,7 @@ 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 + You should have received a copy of the GNU Lesser General Public License along with polypaudio; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. @@ -45,6 +45,13 @@ #include "util.h" #include "modargs.h" #include "xmalloc.h" +#include "log.h" +#include "module-oss-mmap-symdef.h" + +PA_MODULE_AUTHOR("Lennart Poettering") +PA_MODULE_DESCRIPTION("OSS Sink/Source (mmap)") +PA_MODULE_VERSION(PACKAGE_VERSION) +PA_MODULE_USAGE("sink_name= source_name= device= record= playback= format= channels= rate= fragments= fragment_size=") struct userdata { struct pa_sink *sink; @@ -122,7 +129,7 @@ static void do_write(struct userdata *u) { update_usage(u); if (ioctl(u->fd, SNDCTL_DSP_GETOPTR, &info) < 0) { - fprintf(stderr, "SNDCTL_DSP_GETOPTR: %s\n", strerror(errno)); + pa_log(__FILE__": SNDCTL_DSP_GETOPTR: %s\n", strerror(errno)); return; } @@ -184,7 +191,7 @@ static void do_read(struct userdata *u) { update_usage(u); if (ioctl(u->fd, SNDCTL_DSP_GETIPTR, &info) < 0) { - fprintf(stderr, "SNDCTL_DSP_GETIPTR: %s\n", strerror(errno)); + pa_log(__FILE__": SNDCTL_DSP_GETIPTR: %s\n", strerror(errno)); return; } @@ -205,7 +212,7 @@ static void io_callback(struct pa_mainloop_api *m, struct pa_io_event *e, int fd do_write(u); } -static uint32_t sink_get_latency_cb(struct pa_sink *s) { +static pa_usec_t sink_get_latency_cb(struct pa_sink *s) { struct userdata *u = s->userdata; assert(s && u); @@ -213,7 +220,7 @@ static uint32_t sink_get_latency_cb(struct pa_sink *s) { return pa_bytes_to_usec(u->out_fill, &s->sample_spec); } -int pa_module_init(struct pa_core *c, struct pa_module*m) { +int pa__init(struct pa_core *c, struct pa_module*m) { struct audio_buf_info info; struct userdata *u = NULL; const char *p; @@ -230,31 +237,32 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) { u->core = c; if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { - fprintf(stderr, __FILE__": failed to parse module arguments.\n"); + pa_log(__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 arguments.\n"); + if (pa_modargs_get_value_boolean(ma, "record", &record) < 0 || pa_modargs_get_value_boolean(ma, "playback", &playback) < 0) { + pa_log(__FILE__": record= and playback= expect numeric arguments.\n"); 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"); + if (!playback && !record) { + pa_log(__FILE__": neither playback nor record enabled for device.\n"); goto fail; } + mode = (playback&&record) ? O_RDWR : (playback ? O_WRONLY : (record ? O_RDONLY : 0)); + nfrags = 12; frag_size = 1024; - if (pa_modargs_get_value_u32(ma, "fragments", &nfrags) < 0 || nfrags < 2 || pa_modargs_get_value_u32(ma, "fragment_size", &frag_size) < 0 || frag_size < 1) { - fprintf(stderr, __FILE__": failed to parse fragments arguments\n"); + if (pa_modargs_get_value_s32(ma, "fragments", &nfrags) < 0 || pa_modargs_get_value_s32(ma, "fragment_size", &frag_size) < 0) { + pa_log(__FILE__": failed to parse fragments arguments\n"); goto fail; } u->sample_spec = c->default_sample_spec; if (pa_modargs_get_sample_spec(ma, &u->sample_spec) < 0) { - fprintf(stderr, __FILE__": failed to parse sample specification\n"); + pa_log(__FILE__": failed to parse sample specification\n"); goto fail; } @@ -262,33 +270,34 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) { goto fail; if (!(caps & DSP_CAP_MMAP) || !(caps & DSP_CAP_REALTIME) || !(caps & DSP_CAP_TRIGGER)) { - fprintf(stderr, "OSS device not mmap capable.\n"); + pa_log(__FILE__": OSS device not mmap capable.\n"); goto fail; } - fprintf(stderr, "module-oss: device opened in %s mode.\n", mode == O_WRONLY ? "O_WRONLY" : (mode == O_RDONLY ? "O_RDONLY" : "O_RDWR")); - - if (pa_oss_set_fragments(u->fd, nfrags, frag_size) < 0) - goto fail; + pa_log(__FILE__": device opened in %s mode.\n", mode == O_WRONLY ? "O_WRONLY" : (mode == O_RDONLY ? "O_RDONLY" : "O_RDWR")); + + if (nfrags >= 2 && frag_size >= 1) + if (pa_oss_set_fragments(u->fd, nfrags, frag_size) < 0) + goto fail; if (pa_oss_auto_format(u->fd, &u->sample_spec) < 0) goto fail; if (mode != O_WRONLY) { if (ioctl(u->fd, SNDCTL_DSP_GETISPACE, &info) < 0) { - fprintf(stderr, "SNDCTL_DSP_GETISPACE: %s\n", strerror(errno)); + pa_log(__FILE__": SNDCTL_DSP_GETISPACE: %s\n", strerror(errno)); goto fail; } - fprintf(stderr, "module-oss-mmap: input -- %u fragments of size %u.\n", info.fragstotal, info.fragsize); + pa_log(__FILE__": input -- %u fragments of size %u.\n", info.fragstotal, info.fragsize); u->in_mmap_length = (u->in_fragment_size = info.fragsize) * (u->in_fragments = info.fragstotal); if ((u->in_mmap = mmap(NULL, u->in_mmap_length, PROT_READ, MAP_SHARED, u->fd, 0)) == MAP_FAILED) { if (mode == O_RDWR) { - fprintf(stderr, "module-oss-mmap: mmap failed for input. Changing to O_WRONLY mode.\n"); + pa_log(__FILE__": mmap failed for input. Changing to O_WRONLY mode.\n"); mode = O_WRONLY; } else { - fprintf(stderr, "modeule-oss-mmap: mmap(): %s\n", strerror(errno)); + pa_log(__FILE__": mmap(): %s\n", strerror(errno)); goto fail; } } else { @@ -307,19 +316,19 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) { if (mode != O_RDONLY) { if (ioctl(u->fd, SNDCTL_DSP_GETOSPACE, &info) < 0) { - fprintf(stderr, "SNDCTL_DSP_GETOSPACE: %s\n", strerror(errno)); + pa_log(__FILE__": SNDCTL_DSP_GETOSPACE: %s\n", strerror(errno)); goto fail; } - fprintf(stderr, "module-oss: output -- %u fragments of size %u.\n", info.fragstotal, info.fragsize); + pa_log(__FILE__": output -- %u fragments of size %u.\n", info.fragstotal, info.fragsize); u->out_mmap_length = (u->out_fragment_size = info.fragsize) * (u->out_fragments = info.fragstotal); if ((u->out_mmap = mmap(NULL, u->out_mmap_length, PROT_WRITE, MAP_SHARED, u->fd, 0)) == MAP_FAILED) { if (mode == O_RDWR) { - fprintf(stderr, "module-oss-mmap: mmap filed for output. Changing to O_RDONLY mode.\n"); + pa_log(__FILE__": mmap filed for output. Changing to O_RDONLY mode.\n"); mode = O_RDONLY; } else { - fprintf(stderr, "module-oss-mmap: mmap(): %s\n", strerror(errno)); + pa_log(__FILE__": mmap(): %s\n", strerror(errno)); goto fail; } } else { @@ -340,12 +349,12 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) { zero = 0; if (ioctl(u->fd, SNDCTL_DSP_SETTRIGGER, &zero) < 0) { - fprintf(stderr, "SNDCTL_DSP_SETTRIGGER: %s\n", strerror(errno)); + pa_log(__FILE__": SNDCTL_DSP_SETTRIGGER: %s\n", strerror(errno)); goto fail; } if (ioctl(u->fd, SNDCTL_DSP_SETTRIGGER, &enable_bits) < 0) { - fprintf(stderr, "SNDCTL_DSP_SETTRIGGER: %s\n", strerror(errno)); + pa_log(__FILE__": SNDCTL_DSP_SETTRIGGER: %s\n", strerror(errno)); goto fail; } @@ -359,7 +368,7 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) { return 0; fail: - pa_module_done(c, m); + pa__done(c, m); if (ma) pa_modargs_free(ma); @@ -367,7 +376,7 @@ fail: return -1; } -void pa_module_done(struct pa_core *c, struct pa_module*m) { +void pa__done(struct pa_core *c, struct pa_module*m) { struct userdata *u; assert(c && m); @@ -396,11 +405,15 @@ void pa_module_done(struct pa_core *c, struct pa_module*m) { if (u->out_mmap && u->out_mmap != MAP_FAILED) munmap(u->out_mmap, u->out_mmap_length); - if (u->sink) - pa_sink_free(u->sink); + if (u->sink) { + pa_sink_disconnect(u->sink); + pa_sink_unref(u->sink); + } - if (u->source) - pa_source_free(u->source); + if (u->source) { + pa_source_disconnect(u->source); + pa_source_unref(u->source); + } if (u->io_event) u->core->mainloop->io_free(u->io_event);