From 18301dfca56ba8545549e80f84423d83a46c6b64 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 2 Oct 2007 20:26:08 +0000 Subject: a lot of minor cleanups git-svn-id: file:///home/lennart/svn/public/libsydney/trunk@36 9ba3c220-e4d3-45a2-8aa3-73fcc9aff6ce --- src/oss.c | 201 ++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 104 insertions(+), 97 deletions(-) (limited to 'src/oss.c') diff --git a/src/oss.c b/src/oss.c index d09f8aa..3ad1a9d 100644 --- a/src/oss.c +++ b/src/oss.c @@ -1,3 +1,7 @@ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include @@ -31,7 +35,7 @@ struct oss_stream { sa_converter_t converter_read, converter_write; size_t read_fragment_size, write_fragment_size; unsigned read_nfragments, write_nfragments; - sa_thread_t *thread; + sa_thread *thread; int socket_fds[2]; sa_bufferq_t bufferq; }; @@ -47,6 +51,9 @@ static int simple_log2(int v) { return k; } +#ifdef HAVE_CONFIG_H +#include +#endif static size_t fixup_bps(size_t s, size_t bps1, size_t bps2) { return (s*bps2)/bps1; @@ -54,12 +61,12 @@ static size_t fixup_bps(size_t s, size_t bps1, size_t bps2) { int driver_open(sa_stream_t *s) { oss_stream_t *oss; - char *n; + const char *n; int f, arg, bs, r, phase, i, found, suggested, fs, l, m; unsigned c; size_t real_bps = 0, bps; int loops = 0; - + static const int format_map[_SA_PCM_FORMAT_MAX] = { [SA_PCM_FORMAT_U8] = AFMT_U8, [SA_PCM_FORMAT_ULAW] = AFMT_MU_LAW, @@ -98,23 +105,23 @@ int driver_open(sa_stream_t *s) { * device again. */ if ((oss->fd = open(n, s->mode == SA_MODE_RDONLY ? O_RDONLY : (s->mode == SA_MODE_WRONLY ? O_WRONLY : O_RDWR) | O_NOCTTY | O_NONBLOCK)) < 0) { - + if (errno == ENODEV || errno == ENOENT) r = SA_ERROR_NO_DEVICE; else r = SA_ERROR_SYSTEM; - + goto fail; } - + fcntl(oss->fd, F_SETFL, fcntl(oss->fd, F_GETFL) & ~O_NONBLOCK); /* FIXME*/ - + if (!s->device) { if (!(n = sa_strdup(n))) { r = SA_ERROR_OOM; goto fail; } - + s->device = n; } @@ -122,12 +129,12 @@ int driver_open(sa_stream_t *s) { if (s->mode & SA_MODE_WRONLY) { bs = s->write_lower_watermark; } - + if (s->mode & SA_MODE_RDONLY) { int rbs; - + rbs = s->read_upper_watermark; - + if (s->mode & SA_MODE_WRONLY) bs = bs > rbs ? bs : rbs; else @@ -145,14 +152,14 @@ int driver_open(sa_stream_t *s) { if (m > 0x7FFF) m = 0x7FFF; printf("Asking OSS for: %u fragments, %u fragsize\n", m, 1 << l); - + arg = (m << 16) | l; - + ioctl(oss->fd, SNDCTL_DSP_SETFRAGMENT, &arg); /* We ignore errors on this call, since it's merely a hint anyway */ - + if (s->codec) { - + if (strcmp(s->codec, SA_CODEC_AC3) == 0) f = AFMT_AC3; else if (strcmp(s->codec, SA_CODEC_MPEG) == 0) @@ -161,27 +168,27 @@ int driver_open(sa_stream_t *s) { r = SA_ERROR_NO_CODEC; goto fail; } - + } else f = format_map[s->pcm_attrs.format]; - + bs = 0; - + for (;;) { arg = f; - + if (ioctl(oss->fd, SNDCTL_DSP_SETFMT, &arg) < 0) { r = SA_ERROR_SYSTEM; goto fail; } - + if (arg == f) break; - + /* Hmm, the device doesn't support what we're looking for, * let's try our luck */ - - if (f == AFMT_S16_LE && !bs) { + + if (f == AFMT_S16_LE && !bs) { f = AFMT_S16_BE; bs = 1; } else if (f == AFMT_S16_BE && !bs) { @@ -206,39 +213,39 @@ int driver_open(sa_stream_t *s) { goto fail; } } - + if (!s->codec) { - + switch (f) { case AFMT_MU_LAW: oss->real_pcm_attrs.format = SA_PCM_FORMAT_ULAW; break; - + case AFMT_A_LAW: oss->real_pcm_attrs.format = SA_PCM_FORMAT_ALAW; break; - + case AFMT_U8: oss->real_pcm_attrs.format = SA_PCM_FORMAT_U8; break; - + case AFMT_S16_LE: oss->real_pcm_attrs.format = SA_PCM_FORMAT_S16_LE; break; - + case AFMT_S16_BE: oss->real_pcm_attrs.format = SA_PCM_FORMAT_S16_BE; break; - + default: sa_assert_not_reached(); } - - + + found = 0; - + if (s->adjust_nchannels >= 0) { - + /* First try more channels ... */ for (c = s->pcm_attrs.nchannels; c < 8 || c == s->pcm_attrs.nchannels; c ++) { arg = c; @@ -246,13 +253,13 @@ int driver_open(sa_stream_t *s) { r = SA_ERROR_SYSTEM; goto fail; } - + if (arg == (int) c) { found = 1; break; } } - + /* ... then try less channels */ if (!found) { for (c = s->pcm_attrs.nchannels - 1; c > 0; c --) { @@ -261,7 +268,7 @@ int driver_open(sa_stream_t *s) { r = SA_ERROR_SYSTEM; goto fail; } - + if (arg == (int) c) { found = 1; break; @@ -269,7 +276,7 @@ int driver_open(sa_stream_t *s) { } } } else { - + /* First try less channels ... */ for (c = s->pcm_attrs.nchannels; c > 0; c --) { arg = c; @@ -277,13 +284,13 @@ int driver_open(sa_stream_t *s) { r = SA_ERROR_SYSTEM; goto fail; } - + if (arg == (int) c) { found = 1; break; } } - + /* ... then try more channels */ if (!found) { for (c = s->pcm_attrs.nchannels + 1; c < 8; c ++) { @@ -292,28 +299,28 @@ int driver_open(sa_stream_t *s) { r = SA_ERROR_SYSTEM; goto fail; } - + if (arg == (int) c) { found = 1; break; } } - } + } } - + if (!found) { errno = EIO; r = SA_ERROR_SYSTEM; goto fail; } - + oss->real_pcm_attrs.nchannels = c; - + if (!(oss->real_pcm_attrs.channel_map = sa_new(sa_channel_t, c))) { r = SA_ERROR_OOM; goto fail; } - + switch (c) { case 8: oss->real_pcm_attrs.channel_map[7] = SA_CHANNEL_REAR_RIGHT; @@ -335,25 +342,25 @@ int driver_open(sa_stream_t *s) { oss->real_pcm_attrs.channel_map[0] = SA_CHANNEL_MONO; break; } - + r = s->pcm_attrs.rate; - + if (r < 8000) r = 8000; - + suggested = 0; phase = 0; - + for (;;) { arg = r; - + if (ioctl(oss->fd, SNDCTL_DSP_SPEED, &arg) < 0) { r = SA_ERROR_SYSTEM; goto fail; } sa_assert(arg > 0); - + if (arg >= r*0.95 || arg <= r *1.05) break; @@ -361,20 +368,20 @@ int driver_open(sa_stream_t *s) { suggested = arg; if (s->adjust_rate >= 0) { - + if (phase == 0) { /* Find the next higher sample rate to try */ - + for (i = 0; i < (int) SA_ELEMENTSOF(try_rates); i++) { /* Yes, we could optimize a little here */ - + if (try_rates[i] > r) { r = try_rates[i]; - break; + break; } } - - + + if (i == SA_ELEMENTSOF(try_rates)) { phase = 1; r = s->pcm_attrs.rate; @@ -393,23 +400,23 @@ int driver_open(sa_stream_t *s) { break; } } - + sa_assert(i > 0); } - + } else { if (phase == 0) { /* Find the next lower sample rate to try */ for (i = SA_ELEMENTSOF(try_rates); i > 0; i--) { - + if (try_rates[i-1] < r) { r = try_rates[i-1]; - break; + break; } } - + if (i == 0) { phase = 1; r = s->pcm_attrs.rate; @@ -428,7 +435,7 @@ int driver_open(sa_stream_t *s) { break; } } - + sa_assert(i < (int) SA_ELEMENTSOF(try_rates)); } } @@ -463,38 +470,38 @@ int driver_open(sa_stream_t *s) { oss->read_fragment_size = arg; oss->read_nfragments = 2; } - + if (s->mode & SA_MODE_WRONLY) { oss->write_fragment_size = arg; oss->write_nfragments = 2; } } - + /* Now, let's use GETxSPACE */ if (s->mode & SA_MODE_RDONLY) { audio_buf_info info; - + if (ioctl(oss->fd, SNDCTL_DSP_GETISPACE, &info) >= 0) { oss->read_fragment_size = info.fragsize; oss->read_nfragments = info.fragstotal; } } - + if (s->mode & SA_MODE_WRONLY) { audio_buf_info info; - + if (ioctl(oss->fd, SNDCTL_DSP_GETOSPACE, &info) >= 0) { oss->write_fragment_size = info.fragsize; oss->write_nfragments = info.fragstotal; } } - + if (s->mode & SA_MODE_WRONLY && (oss->write_fragment_size <= 0 || oss->write_nfragments <= 1)) { errno = EIO; r = SA_ERROR_SYSTEM; goto fail; } - + if (s->mode & SA_MODE_RDONLY && (oss->read_fragment_size <= 0 || oss->read_nfragments <= 1)) { errno = EIO; r = SA_ERROR_SYSTEM; @@ -502,7 +509,7 @@ int driver_open(sa_stream_t *s) { } if (!s->codec) { - + if (s->adjust_nchannels != 0) { sa_channel_t *cm; @@ -524,7 +531,7 @@ int driver_open(sa_stream_t *s) { if (s->mode & SA_MODE_RDONLY) if ((r = sa_converter_init(&oss->converter_read, &oss->real_pcm_attrs, &s->pcm_attrs, s->dynamic_rate_enabled)) < 0) goto fail; - + if (s->mode & SA_MODE_WRONLY) if ((r = sa_converter_init(&oss->converter_write, &s->pcm_attrs, &oss->real_pcm_attrs, s->dynamic_rate_enabled)) < 0) goto fail; @@ -542,7 +549,7 @@ int driver_open(sa_stream_t *s) { s->write_upper_watermark = oss->write_fragment_size * oss->write_nfragments; } } - + if (s->mode & SA_MODE_RDONLY) printf("Chosen for read: %u fragments, %u fragsize\n", oss->read_nfragments, oss->read_fragment_size); @@ -551,7 +558,7 @@ int driver_open(sa_stream_t *s) { if (sa_bufferq_init(&oss->bufferq, s->pcm_attrs.nchannels, s->pcm_sample_size) < 0) goto fail; - + return SA_SUCCESS; fail: @@ -566,19 +573,19 @@ int driver_destroy(sa_stream_t *s) { if (oss->thread) driver_stop_thread(s); - + if (oss->fd >= 0) close(oss->fd); - + sa_bufferq_done(&oss->bufferq); - + sa_free(oss->real_pcm_attrs.channel_map); sa_converter_done(&oss->converter_read); sa_converter_done(&oss->converter_write); sa_free(oss); } - + return SA_SUCCESS; } @@ -586,7 +593,7 @@ static int feed(sa_stream_t *s) { oss_stream_t *oss = OSS_STREAM(s); size_t w; int ret; - + sa_assert(s); for (;;) { @@ -612,10 +619,10 @@ static int feed(sa_stream_t *s) { drop = 1; s->state = SA_STATE_RUNNING; - + } else { nbytes = w > oss->write_fragment_size ? oss->write_fragment_size : w; - + if (!(d = sa_converter_get_zero_buffer(&oss->converter_write, nbytes))) return SA_ERROR_OOM; @@ -627,17 +634,17 @@ static int feed(sa_stream_t *s) { while (nbytes > 0) { ssize_t l; - + if ((l = write(oss->fd, d, nbytes)) < 0) return SA_ERROR_SYSTEM; - + sa_assert(l > 0); - + nbytes -= l; d += l; w -= 1; - + if (drop) sa_bufferq_drop(&oss->bufferq, l); } @@ -667,15 +674,15 @@ static void thread_func(void *data) { if (s->callback(s, SA_EVENT_INIT_THREAD) < 0) return; } - + memset(pollfds, 0, sizeof(pollfds)); pollfds[POLLFD_SOCKET_FD].fd = oss->socket_fds[0]; pollfds[POLLFD_SOCKET_FD].events = POLLIN; - + pollfds[POLLFD_OSS_FD].fd = oss->fd; pollfds[POLLFD_OSS_FD].events = ((s->mode & SA_MODE_RDONLY) ? POLLIN : 0) | ((s->mode & SA_MODE_WRONLY) ? POLLOUT : 0); - + for (;;) { int ret; if (poll(pollfds, POLLFD_MAX, -1) < 0) { @@ -732,7 +739,7 @@ int driver_start_thread(sa_stream_t *s, sa_event_callback_t callback) { if (!(oss->thread = sa_thread_new(thread_func, s))) return SA_ERROR_OOM; - + return SA_SUCCESS; } @@ -743,13 +750,13 @@ int driver_stop_thread(sa_stream_t *s) { if (oss->socket_fds[0] >= 0) close(oss->socket_fds[0]); - + if (oss->socket_fds[1] >= 0) close(oss->socket_fds[1]); - + if (oss->thread) sa_thread_free(oss->thread); - + oss->thread = NULL; oss->socket_fds[0] = oss->socket_fds[1] = -1; @@ -762,7 +769,7 @@ int driver_change_read_volume(sa_stream_t *s, const int32_t vol[]) { sa_return_val_if_fail(!s->codec, SA_ERROR_NOT_SUPPORTED); sa_converter_set_volume(&oss->converter_read, vol); - + return SA_SUCCESS; } @@ -772,7 +779,7 @@ int driver_change_write_volume(sa_stream_t *s, const int32_t vol[]) { sa_return_val_if_fail(!s->codec, SA_ERROR_NOT_SUPPORTED); sa_converter_set_volume(&oss->converter_write, vol); - + return SA_SUCCESS; } @@ -806,7 +813,7 @@ int driver_pwrite(sa_stream_t *s, const void *data, size_t nbytes, int64_t offse if ((ret = sa_bufferq_push(&oss->bufferq, 0, data, nbytes, offset, whence, SA_BUFFERQ_ITEM_STATIC))) return ret; - + ret = feed(s); ret2 = sa_bufferq_realloc(&oss->bufferq); @@ -843,7 +850,7 @@ int driver_drain(sa_stream_t *s) { if (ioctl(oss->fd, SNDCTL_DSP_SYNC, NULL) < 0) return SA_ERROR_SYSTEM; - + return SA_SUCCESS; } -- cgit