When resuming an OSS device ask for the very same fragment settings as we did the first time

In OSS it is only possible to request fragment sizes that are powers of
2. However actually selected fragment sizes may be arbitrary values.
This means that it is not always possible to request the same fragment
size after a suspend that was used before the suspend because we simply
cannot express it in the request. To work around that we should issue
the same request as we did the first time.
This commit is contained in:
Lennart Poettering 2009-01-22 01:15:49 +01:00
parent 3be4c31ee0
commit bb23932e9a
2 changed files with 7 additions and 3 deletions

View file

@ -121,7 +121,7 @@ struct userdata {
int mixer_fd; int mixer_fd;
int mixer_devmask; int mixer_devmask;
int nfrags, frag_size; int nfrags, frag_size, orig_frag_size;
pa_bool_t use_mmap; pa_bool_t use_mmap;
unsigned out_mmap_current, in_mmap_current; unsigned out_mmap_current, in_mmap_current;
@ -536,7 +536,7 @@ static int unsuspend(struct userdata *u) {
} }
if (u->nfrags >= 2 && u->frag_size >= 1) if (u->nfrags >= 2 && u->frag_size >= 1)
if (pa_oss_set_fragments(u->fd, u->nfrags, u->frag_size) < 0) { if (pa_oss_set_fragments(u->fd, u->nfrags, u->orig_frag_size) < 0) {
pa_log_warn("Resume failed, couldn't set original fragment settings."); pa_log_warn("Resume failed, couldn't set original fragment settings.");
goto fail; goto fail;
} }
@ -1146,7 +1146,7 @@ int pa__init(pa_module*m) {
struct userdata *u = NULL; struct userdata *u = NULL;
const char *dev; const char *dev;
int fd = -1; int fd = -1;
int nfrags, frag_size; int nfrags, orig_frag_size, frag_size;
int mode, caps; int mode, caps;
pa_bool_t record = TRUE, playback = TRUE, use_mmap = TRUE; pa_bool_t record = TRUE, playback = TRUE, use_mmap = TRUE;
pa_sample_spec ss; pa_sample_spec ss;
@ -1218,6 +1218,7 @@ int pa__init(pa_module*m) {
pa_log_info("Device opened in %s mode.", mode == O_WRONLY ? "O_WRONLY" : (mode == O_RDONLY ? "O_RDONLY" : "O_RDWR")); pa_log_info("Device opened in %s mode.", mode == O_WRONLY ? "O_WRONLY" : (mode == O_RDONLY ? "O_RDONLY" : "O_RDWR"));
orig_frag_size = frag_size;
if (nfrags >= 2 && frag_size >= 1) if (nfrags >= 2 && frag_size >= 1)
if (pa_oss_set_fragments(fd, nfrags, frag_size) < 0) if (pa_oss_set_fragments(fd, nfrags, frag_size) < 0)
goto fail; goto fail;
@ -1245,6 +1246,7 @@ int pa__init(pa_module*m) {
u->device_name = pa_xstrdup(dev); u->device_name = pa_xstrdup(dev);
u->in_nfrags = u->out_nfrags = (uint32_t) (u->nfrags = nfrags); u->in_nfrags = u->out_nfrags = (uint32_t) (u->nfrags = nfrags);
u->out_fragment_size = u->in_fragment_size = (uint32_t) (u->frag_size = frag_size); u->out_fragment_size = u->in_fragment_size = (uint32_t) (u->frag_size = frag_size);
u->orig_frag_size = orig_frag_size;
u->use_mmap = use_mmap; u->use_mmap = use_mmap;
u->rtpoll = pa_rtpoll_new(); u->rtpoll = pa_rtpoll_new();
pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll); pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll);

View file

@ -250,6 +250,8 @@ int pa_oss_set_fragments(int fd, int nfrags, int frag_size) {
int arg; int arg;
arg = ((int) nfrags << 16) | simple_log2(frag_size); arg = ((int) nfrags << 16) | simple_log2(frag_size);
pa_log_debug("Asking for %i fragments of size %i (requested %i)", nfrags, 1 << simple_log2(frag_size), frag_size);
if (ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &arg) < 0) { if (ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &arg) < 0) {
pa_log("SNDCTL_DSP_SETFRAGMENT: %s", pa_cstrerror(errno)); pa_log("SNDCTL_DSP_SETFRAGMENT: %s", pa_cstrerror(errno));
return -1; return -1;