diff options
author | Lennart Poettering <lennart@poettering.net> | 2004-06-16 00:05:30 +0000 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2004-06-16 00:05:30 +0000 |
commit | 4b86ff0e6cfea2c34be71ebe1102eb307bd5dc0b (patch) | |
tree | 3f4e164f9b1c72464c647b9369fc98e127494514 /src/module-oss.c | |
parent | a8f788111cb0b18ca3517a51657881d5ffcfabae (diff) |
got mmap oss output working
git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@20 fefdeb5f-60dc-0310-8127-8f9354f1896f
Diffstat (limited to 'src/module-oss.c')
-rw-r--r-- | src/module-oss.c | 60 |
1 files changed, 27 insertions, 33 deletions
diff --git a/src/module-oss.c b/src/module-oss.c index bb8112b0..170d864d 100644 --- a/src/module-oss.c +++ b/src/module-oss.c @@ -14,6 +14,8 @@ #include "sink.h" #include "source.h" #include "module.h" +#include "oss.h" +#include "sample.h" struct userdata { struct sink *sink; @@ -23,7 +25,9 @@ struct userdata { struct memchunk memchunk, silence; - uint32_t in_fragment_size, out_fragment_size, sample_size; + uint32_t in_fragment_size, out_fragment_size, sample_size, sample_usec; + + int fd; }; static void do_write(struct userdata *u) { @@ -92,12 +96,26 @@ static void io_callback(struct iochannel *io, void*userdata) { do_read(u); } +static uint32_t sink_get_latency_cb(struct sink *s) { + int arg; + struct userdata *u = s->userdata; + assert(s && u); + + if (ioctl(u->fd, SNDCTL_DSP_GETODELAY, &arg) < 0) { + fprintf(stderr, "module-oss: device doesn't support SNDCTL_DSP_GETODELAY.\n"); + s->get_latency = NULL; + return 0; + } + + return arg/u->sample_size*u->sample_usec; +} + int module_init(struct core *c, struct module*m) { struct audio_buf_info info; struct userdata *u = NULL; char *p; int fd = -1; - int format, channels, speed, frag_size, in_frag_size, out_frag_size; + int frag_size, in_frag_size, out_frag_size; int mode; struct sample_spec ss; assert(c && m); @@ -136,37 +154,8 @@ int module_init(struct core *c, struct module*m) { goto fail; } - format = AFMT_S16_NE; - if (ioctl(fd, SNDCTL_DSP_SETFMT, &format) < 0 || format != AFMT_S16_NE) { - int f = AFMT_S16_NE == AFMT_S16_LE ? AFMT_S16_BE : AFMT_S16_LE; - format = f; - if (ioctl(fd, SNDCTL_DSP_SETFMT, &format) < 0 || format != f) { - format = AFMT_U8; - if (ioctl(fd, SNDCTL_DSP_SETFMT, &format) < 0 || format != AFMT_U8) { - fprintf(stderr, "SNDCTL_DSP_SETFMT: %s\n", format != AFMT_U8 ? "No supported sample format" : strerror(errno)); - goto fail; - } else - ss.format = SAMPLE_U8; - } else - ss.format = f == AFMT_S16_LE ? SAMPLE_S16LE : SAMPLE_S16BE; - } else - ss.format = SAMPLE_S16NE; - - channels = 2; - if (ioctl(fd, SNDCTL_DSP_CHANNELS, &channels) < 0) { - fprintf(stderr, "SNDCTL_DSP_CHANNELS: %s\n", strerror(errno)); - goto fail; - } - assert(channels); - ss.channels = channels; - - speed = 44100; - if (ioctl(fd, SNDCTL_DSP_SPEED, &speed) < 0) { - fprintf(stderr, "SNDCTL_DSP_SPEED: %s\n", strerror(errno)); + if (oss_auto_format(fd, &ss) < 0) goto fail; - } - assert(speed); - ss.rate = speed; if (ioctl(fd, SNDCTL_DSP_GETBLKSIZE, &frag_size) < 0) { fprintf(stderr, "SNDCTL_DSP_GETBLKSIZE: %s\n", strerror(errno)); @@ -193,12 +182,15 @@ int module_init(struct core *c, struct module*m) { if (mode != O_RDONLY) { u->sink = sink_new(c, "dsp", &ss); assert(u->sink); + u->sink->get_latency = sink_get_latency_cb; + u->sink->userdata = u; } else u->sink = NULL; if (mode != O_WRONLY) { u->source = source_new(c, "dsp", &ss); assert(u->source); + u->source->userdata = u; } else u->source = NULL; @@ -207,16 +199,18 @@ int module_init(struct core *c, struct module*m) { u->io = iochannel_new(c->mainloop, u->source ? fd : -1, u->sink ? fd : 0); assert(u->io); iochannel_set_callback(u->io, io_callback, u); + u->fd = fd; u->memchunk.memblock = NULL; u->memchunk.length = 0; u->sample_size = sample_size(&ss); + u->sample_usec = 1000000/ss.rate; u->out_fragment_size = out_frag_size; u->in_fragment_size = in_frag_size; u->silence.memblock = memblock_new(u->silence.length = u->out_fragment_size); assert(u->silence.memblock); - silence(u->silence.memblock, &ss); + silence_memblock(u->silence.memblock, &ss); u->silence.index = 0; m->userdata = u; |