https://cgit.freebsd.org/ports/commit/audio/pulseaudio/files/patch-src_modules_oss-util.c?id=4ba786e49ded8d06cd62b603daf9951de5f88f1d Upstream patches from 14.2 to 15.0: https://github.com/pulseaudio/pulseaudio/commit/ef8fa7c99752e0c404039a4c0f0c188d7033c431#diff-6c30591ff7b76f1d351f192894d3a1c2ade897dfe3f077af6cea7108ad1f6dbd https://github.com/pulseaudio/pulseaudio/commit/0f70a6f519fa0c499d1bbc194ea8be5195033c3e --- src/modules/oss/oss-util.c.orig 2018-07-13 19:06:14 UTC +++ src/modules/oss/oss-util.c @@ -39,7 +39,24 @@ #include "oss-util.h" +#ifndef DSP_CAP_COPROC +#define DSP_CAP_COPROC 0x00000800 +#endif +#ifndef DSP_CAP_TRIGGER +#define DSP_CAP_TRIGGER 0x00001000 +#endif +#ifndef DSP_CAP_MMAP +#define DSP_CAP_MMAP 0x00002000 +#endif +#ifndef DSP_CAP_MULTI +#define DSP_CAP_MULTI 0x00004000 +#endif +#ifndef DSP_CAP_BIND +#define DSP_CAP_BIND 0x00008000 +#endif + int pa_oss_open(const char *device, int *mode, int* pcaps) { + static const int nonblock_io = 1; int fd = -1; int caps; char *t; @@ -89,6 +106,10 @@ } success: + if (ioctl(fd, FIONBIO, &nonblock_io) < 0) { + pa_log("FIONBIO: %s", pa_cstrerror(errno)); + goto fail; + } t = pa_sprintf_malloc( "%s%s%s%s%s%s%s%s%s%s%s%s%s%s", @@ -164,8 +185,13 @@ [PA_SAMPLE_FLOAT32BE] = AFMT_QUERY, /* not supported */ [PA_SAMPLE_S32LE] = AFMT_QUERY, /* not supported */ [PA_SAMPLE_S32BE] = AFMT_QUERY, /* not supported */ +#if defined(AFMT_S24_LE) && defined(AFMT_S24_BE) + [PA_SAMPLE_S24LE] = AFMT_S24_LE, + [PA_SAMPLE_S24BE] = AFMT_S24_BE, +#else [PA_SAMPLE_S24LE] = AFMT_QUERY, /* not supported */ [PA_SAMPLE_S24BE] = AFMT_QUERY, /* not supported */ +#endif [PA_SAMPLE_S24_32LE] = AFMT_QUERY, /* not supported */ [PA_SAMPLE_S24_32BE] = AFMT_QUERY, /* not supported */ }; @@ -290,41 +316,35 @@ } static int get_device_number(const char *dev) { - const char *p, *e; + const char *p; + const char *e; char *rp = NULL; - int r; + int r = -1; if (!(p = rp = pa_readlink(dev))) { -#ifdef ENOLINK - if (errno != EINVAL && errno != ENOLINK) { -#else - if (errno != EINVAL) { -#endif - r = -1; - goto finish; - } - + if (errno != EINVAL && errno != ENOLINK) + return -2; p = dev; } - if ((e = strrchr(p, '/'))) - p = e+1; - - if (p == 0) { - r = 0; - goto finish; - } - - p = strchr(p, 0) -1; - - if (*p >= '0' && *p <= '9') { - r = *p - '0'; - goto finish; + /* find the last forward slash */ + while ((e = strrchr(p, '/'))) + p = e + 1; + + /* collect unit number at end, if any */ + while (*p) { + if (*p >= '0' && *p <= '9') { + if (r < 0) + r = 0; + else + r *= 10; + r += *p - '0'; + } else { + r = -1; + } + p++; } - r = -1; - -finish: pa_xfree(rp); return r; } @@ -334,7 +354,7 @@ int n, r = -1; int b = 0; - if ((n = get_device_number(dev)) < 0) + if ((n = get_device_number(dev)) == -2) return -1; if (!(f = pa_fopen_cloexec("/dev/sndstat", "r")) && @@ -348,8 +368,8 @@ } while (!feof(f)) { - char line[64]; - int device; + char line[1024] = { 0 }; + unsigned device; if (!fgets(line, sizeof(line), f)) break; @@ -357,26 +377,29 @@ line[strcspn(line, "\r\n")] = 0; if (!b) { - b = pa_streq(line, "Audio devices:"); + b = pa_streq(line, "Audio devices:") || pa_streq(line, "Installed devices:"); continue; } if (line[0] == 0) break; - if (sscanf(line, "%i: ", &device) != 1) + if (sscanf(line, "%u: ", &device) != 1 && sscanf(line, "pcm%u: ", &device) != 1) continue; if (device == n) { char *k = strchr(line, ':'); pa_assert(k); k++; - k += strspn(k, " "); + k += strspn(k, " <"); if (pa_endswith(k, " (DUPLEX)")) k[strlen(k)-9] = 0; - pa_strlcpy(name, k, l); + k[strcspn(k, ">")] = 0; + + // Include the number to disambiguate devices with the same name + pa_snprintf(name, l, "%u - %s", device, k); r = 0; break; } @@ -400,10 +423,10 @@ char *fn; int fd; - if ((n = get_device_number(device)) < 0) + if ((n = get_device_number(device)) == -2) return -1; - if (n == 0) + if (n == -1) if ((fd = open_mixer("/dev/mixer")) >= 0) return fd;