From 554b01b6b3a82d201da9a10c54187a66b4804501 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 16 Jul 2004 17:51:53 +0000 Subject: make oss sample spec configurable git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@77 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/module-oss-mmap.c | 27 +++++++++++++++----- src/module-oss.c | 27 +++++++++++++++----- src/oss-util.c | 70 ++++++++++++++++++++++++++++++++++++++------------- src/oss-util.h | 2 ++ src/polypaudio.run | 17 +++++++------ src/todo | 2 +- 6 files changed, 108 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/module-oss-mmap.c b/src/module-oss-mmap.c index ceaae493..2b43cbad 100644 --- a/src/module-oss-mmap.c +++ b/src/module-oss-mmap.c @@ -45,6 +45,11 @@ static const char* const valid_modargs[] = { "device", "record", "playback", + "fragments", + "fragment_size", + "format", + "rate", + "channels", NULL }; @@ -175,7 +180,7 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) { struct audio_buf_info info; struct userdata *u = NULL; const char *p; - int frag_size; + int nfrags, frag_size; int mode, caps; int enable_bits = 0, zero = 0; int playback = 1, record = 1; @@ -204,6 +209,19 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) { goto fail; } + 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"); + 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"); + goto fail; + } + if ((u->fd = pa_oss_open(p = pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), &mode, &caps)) < 0) goto fail; @@ -214,12 +232,9 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) { 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 */ - if (ioctl(u->fd, SNDCTL_DSP_SETFRAGMENT, &frag_size) < 0) { - fprintf(stderr, "SNDCTL_DSP_SETFRAGMENT: %s\n", strerror(errno)); + 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; diff --git a/src/module-oss.c b/src/module-oss.c index 48d10486..324bab3b 100644 --- a/src/module-oss.c +++ b/src/module-oss.c @@ -38,6 +38,11 @@ static const char* const valid_modargs[] = { "device", "record", "playback", + "fragments", + "fragment_size", + "format", + "rate", + "channels", NULL }; @@ -131,7 +136,7 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) { struct userdata *u = NULL; const char *p; int fd = -1; - int frag_size, in_frag_size, out_frag_size; + int nfrags, frag_size, in_frag_size, out_frag_size; int mode; uint32_t record = 1, playback = 1; struct pa_sample_spec ss; @@ -154,16 +159,26 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) { goto fail; } + 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"); + goto fail; + } + + ss = c->default_sample_spec; + if (pa_modargs_get_sample_spec(ma, &ss) < 0) { + fprintf(stderr, __FILE__": failed to parse sample specification\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 */ - if (ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &frag_size) < 0) { - fprintf(stderr, "SNDCTL_DSP_SETFRAGMENT: %s\n", strerror(errno)); + + if (pa_oss_set_fragments(fd, nfrags, frag_size) < 0) goto fail; - } if (pa_oss_auto_format(fd, &ss) < 0) goto fail; diff --git a/src/oss-util.c b/src/oss-util.c index f1e07017..7be91dcb 100644 --- a/src/oss-util.c +++ b/src/oss-util.c @@ -62,27 +62,39 @@ fail: } int pa_oss_auto_format(int fd, struct pa_sample_spec *ss) { - int format, channels, speed; + int format, channels, speed, reqformat; + static const int format_trans[] = { + [PA_SAMPLE_U8] = AFMT_U8, + [PA_SAMPLE_ALAW] = AFMT_A_LAW, + [PA_SAMPLE_ULAW] = AFMT_MU_LAW, + [PA_SAMPLE_S16LE] = AFMT_S16_LE, + [PA_SAMPLE_S16BE] = AFMT_S16_BE, + [PA_SAMPLE_FLOAT32LE] = AFMT_QUERY, /* not supported */ + [PA_SAMPLE_FLOAT32BE] = AFMT_QUERY, /* not supported */ + }; assert(fd >= 0 && ss); - - 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)); - return -1; + + reqformat = format = format_trans[ss->format]; + if (reqformat == AFMT_QUERY || ioctl(fd, SNDCTL_DSP_SETFMT, &format) < 0 || format != reqformat) { + 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)); + return -1; + } else + ss->format = PA_SAMPLE_U8; } else - ss->format = PA_SAMPLE_U8; + ss->format = f == AFMT_S16_LE ? PA_SAMPLE_S16LE : PA_SAMPLE_S16BE; } else - ss->format = f == AFMT_S16_LE ? PA_SAMPLE_S16LE : PA_SAMPLE_S16BE; - } else - ss->format = PA_SAMPLE_S16NE; + ss->format = PA_SAMPLE_S16NE; + } - channels = 2; + channels = ss->channels; if (ioctl(fd, SNDCTL_DSP_CHANNELS, &channels) < 0) { fprintf(stderr, "SNDCTL_DSP_CHANNELS: %s\n", strerror(errno)); return -1; @@ -90,7 +102,7 @@ int pa_oss_auto_format(int fd, struct pa_sample_spec *ss) { assert(channels); ss->channels = channels; - speed = 44100; + speed = ss->rate; if (ioctl(fd, SNDCTL_DSP_SPEED, &speed) < 0) { fprintf(stderr, "SNDCTL_DSP_SPEED: %s\n", strerror(errno)); return -1; @@ -100,3 +112,27 @@ int pa_oss_auto_format(int fd, struct pa_sample_spec *ss) { return 0; } + +static int log2(int v) { + int k = 0; + + for (;;) { + v >>= 1; + if (!v) break; + k++; + } + + return k; +} + +int pa_oss_set_fragments(int fd, int nfrags, int frag_size) { + int arg; + arg = ((int) nfrags << 16) | log2(frag_size); + + if (ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &arg) < 0) { + fprintf(stderr, "SNDCTL_DSP_SETFRAGMENT: %s\n", strerror(errno)); + return -1; + } + + return 0; +} diff --git a/src/oss-util.h b/src/oss-util.h index 030afba4..a62eee1d 100644 --- a/src/oss-util.h +++ b/src/oss-util.h @@ -6,4 +6,6 @@ int pa_oss_open(const char *device, int *mode, int* pcaps); int pa_oss_auto_format(int fd, struct pa_sample_spec *ss); +int pa_oss_set_fragments(int fd, int frags, int frag_size); + #endif diff --git a/src/polypaudio.run b/src/polypaudio.run index 2698c538..25af2df6 100755 --- a/src/polypaudio.run +++ b/src/polypaudio.run @@ -1,13 +1,10 @@ #!./polypaudio -F # Load audio drivers -load module-alsa-sink -load module-alsa-source device=plughw:1,0 -#load module-oss-mmap device="/dev/dsp" - -# Make some devices default -sink_default alsa_output -source_default alsa_input +#load module-alsa-sink +#load module-alsa-source device=plughw:1,0 +#load module-oss device="/dev/dsp" +load module-oss-mmap device="/dev/dsp" # Load several protocols load module-esound-protocol-tcp @@ -18,3 +15,9 @@ load module-cli-protocol-unix # Load the CLI module load module-cli +.nofail + +# Make some devices default +sink_default alsa_output +source_default alsa_input + diff --git a/src/todo b/src/todo index 8a97ca6a..225fb227 100644 --- a/src/todo +++ b/src/todo @@ -1,4 +1,4 @@ -- make the sample spec configurable for oss devices +- run depmod once again - prefix modules/libraries with pa_ - rename files - svn-id and license in every file -- cgit