ports/audio/pulseaudio/files/patch-src_modules_oss_module-oss.c
Gleb Popov b1ecad53b0 audio/pulseaudio: Update to 16.1
Bump PORTREVISION on consumers.

Sponsored by:	Serenity Cybersecurity, LLC

PR:		262713
2023-08-07 19:34:07 +03:00

280 lines
9.7 KiB
C

--- src/modules/oss/module-oss.c.orig 2022-06-21 10:54:48 UTC
+++ src/modules/oss/module-oss.c
@@ -121,9 +121,6 @@ struct userdata {
int fd;
int mode;
- int mixer_fd;
- int mixer_devmask;
-
int nfrags, frag_size, orig_frag_size;
bool shutdown;
@@ -819,75 +816,145 @@ static int source_set_state_in_io_thread_cb(pa_source
return 0;
}
+static int open_mixer(struct userdata *u, int *p_devmask) {
+ int mixer_fd;
+
+ mixer_fd = pa_oss_open_mixer_for_device(u->device_name);
+ if (mixer_fd < 0)
+ return (mixer_fd);
+
+ if (ioctl(mixer_fd, SOUND_MIXER_READ_DEVMASK, p_devmask) < 0) {
+ pa_log_warn("SOUND_MIXER_READ_DEVMASK failed: %s", pa_cstrerror(errno));
+ pa_close(mixer_fd);
+ return (-1);
+ }
+ return (mixer_fd);
+}
+
+static void oss_get_dummy_volume(const pa_sample_spec *ss, pa_cvolume *volume) {
+ char cv[PA_CVOLUME_SNPRINT_VERBOSE_MAX];
+ unsigned vol;
+
+ pa_assert(ss);
+ pa_assert(volume);
+
+ vol = 100 | (100 << 8);
+
+ pa_cvolume_reset(volume, ss->channels);
+
+ volume->values[0] = PA_CLAMP_VOLUME(((vol & 0xFF) * PA_VOLUME_NORM) / 100);
+
+ if (volume->channels >= 2)
+ volume->values[1] = PA_CLAMP_VOLUME((((vol >> 8) & 0xFF) * PA_VOLUME_NORM) / 100);
+
+ pa_log_debug("Read dummy settings: %s", pa_cvolume_snprint_verbose(cv, sizeof(cv), volume, NULL, false));
+}
+
static void sink_get_volume(pa_sink *s) {
struct userdata *u;
+ int mixer_fd;
+ int mixer_devmask;
+
pa_assert_se(u = s->userdata);
- pa_assert(u->mixer_devmask & (SOUND_MASK_VOLUME|SOUND_MASK_PCM));
+ mixer_fd = open_mixer(u, &mixer_devmask);
+ if (mixer_fd < 0) {
+ oss_get_dummy_volume(&s->sample_spec, &s->real_volume);
+ return;
+ }
- if (u->mixer_devmask & SOUND_MASK_VOLUME)
- if (pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_READ_VOLUME, &s->sample_spec, &s->real_volume) >= 0)
- return;
+ if (mixer_devmask & SOUND_MASK_VOLUME)
+ if (pa_oss_get_volume(mixer_fd, SOUND_MIXER_READ_VOLUME, &s->sample_spec, &s->real_volume) >= 0)
+ goto done;
- if (u->mixer_devmask & SOUND_MASK_PCM)
- if (pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_READ_PCM, &s->sample_spec, &s->real_volume) >= 0)
- return;
+ if (mixer_devmask & SOUND_MASK_PCM)
+ if (pa_oss_get_volume(mixer_fd, SOUND_MIXER_READ_PCM, &s->sample_spec, &s->real_volume) >= 0)
+ goto done;
+ oss_get_dummy_volume(&s->sample_spec, &s->real_volume);
+
pa_log_info("Device doesn't support reading mixer settings: %s", pa_cstrerror(errno));
+done:
+ pa_close(mixer_fd);
}
static void sink_set_volume(pa_sink *s) {
struct userdata *u;
+ int mixer_fd;
+ int mixer_devmask;
+
pa_assert_se(u = s->userdata);
- pa_assert(u->mixer_devmask & (SOUND_MASK_VOLUME|SOUND_MASK_PCM));
+ mixer_fd = open_mixer(u, &mixer_devmask);
+ if (mixer_fd < 0)
+ return;
- if (u->mixer_devmask & SOUND_MASK_VOLUME)
- (void) pa_oss_set_volume(u->mixer_fd, SOUND_MIXER_WRITE_VOLUME, &s->sample_spec, &s->real_volume);
+ if (mixer_devmask & SOUND_MASK_VOLUME)
+ (void) pa_oss_set_volume(mixer_fd, SOUND_MIXER_WRITE_VOLUME, &s->sample_spec, &s->real_volume);
- if (u->mixer_devmask & SOUND_MASK_PCM)
- (void) pa_oss_set_volume(u->mixer_fd, SOUND_MIXER_WRITE_PCM, &s->sample_spec, &s->real_volume);
+ if (mixer_devmask & SOUND_MASK_PCM)
+ (void) pa_oss_set_volume(mixer_fd, SOUND_MIXER_WRITE_PCM, &s->sample_spec, &s->real_volume);
+
+ pa_close(mixer_fd);
}
static void source_get_volume(pa_source *s) {
struct userdata *u;
+ int mixer_fd;
+ int mixer_devmask;
+
pa_assert_se(u = s->userdata);
- pa_assert(u->mixer_devmask & (SOUND_MASK_MIC|SOUND_MASK_IGAIN|SOUND_MASK_RECLEV));
+ mixer_fd = open_mixer(u, &mixer_devmask);
+ if (mixer_fd < 0) {
+ oss_get_dummy_volume(&s->sample_spec, &s->real_volume);
+ return;
+ }
- if (u->mixer_devmask & SOUND_MASK_IGAIN)
- if (pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_READ_IGAIN, &s->sample_spec, &s->real_volume) >= 0)
- return;
+ if (mixer_devmask & SOUND_MASK_IGAIN)
+ if (pa_oss_get_volume(mixer_fd, SOUND_MIXER_READ_IGAIN, &s->sample_spec, &s->real_volume) >= 0)
+ goto done;
- if (u->mixer_devmask & SOUND_MASK_RECLEV)
- if (pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_READ_RECLEV, &s->sample_spec, &s->real_volume) >= 0)
- return;
+ if (mixer_devmask & SOUND_MASK_RECLEV)
+ if (pa_oss_get_volume(mixer_fd, SOUND_MIXER_READ_RECLEV, &s->sample_spec, &s->real_volume) >= 0)
+ goto done;
- if (u->mixer_devmask & SOUND_MASK_MIC)
- if (pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_READ_MIC, &s->sample_spec, &s->real_volume) >= 0)
- return;
+ if (mixer_devmask & SOUND_MASK_MIC)
+ if (pa_oss_get_volume(mixer_fd, SOUND_MIXER_READ_MIC, &s->sample_spec, &s->real_volume) >= 0)
+ goto done;
+ oss_get_dummy_volume(&s->sample_spec, &s->real_volume);
+
pa_log_info("Device doesn't support reading mixer settings: %s", pa_cstrerror(errno));
+done:
+ pa_close(mixer_fd);
}
static void source_set_volume(pa_source *s) {
struct userdata *u;
+ int mixer_fd;
+ int mixer_devmask;
+
pa_assert_se(u = s->userdata);
- pa_assert(u->mixer_devmask & (SOUND_MASK_MIC|SOUND_MASK_IGAIN|SOUND_MASK_RECLEV));
+ mixer_fd = open_mixer(u, &mixer_devmask);
+ if (mixer_fd < 0)
+ return;
- if (u->mixer_devmask & SOUND_MASK_IGAIN)
- (void) pa_oss_set_volume(u->mixer_fd, SOUND_MIXER_WRITE_IGAIN, &s->sample_spec, &s->real_volume);
+ if (mixer_devmask & SOUND_MASK_IGAIN)
+ (void) pa_oss_set_volume(mixer_fd, SOUND_MIXER_WRITE_IGAIN, &s->sample_spec, &s->real_volume);
- if (u->mixer_devmask & SOUND_MASK_RECLEV)
- (void) pa_oss_set_volume(u->mixer_fd, SOUND_MIXER_WRITE_RECLEV, &s->sample_spec, &s->real_volume);
+ if (mixer_devmask & SOUND_MASK_RECLEV)
+ (void) pa_oss_set_volume(mixer_fd, SOUND_MIXER_WRITE_RECLEV, &s->sample_spec, &s->real_volume);
- if (u->mixer_devmask & SOUND_MASK_MIC)
- (void) pa_oss_set_volume(u->mixer_fd, SOUND_MIXER_WRITE_MIC, &s->sample_spec, &s->real_volume);
+ if (mixer_devmask & SOUND_MASK_MIC)
+ (void) pa_oss_set_volume(mixer_fd, SOUND_MIXER_WRITE_MIC, &s->sample_spec, &s->real_volume);
+
+ pa_close(mixer_fd);
}
static void thread_func(void *userdata) {
@@ -1158,16 +1225,6 @@ static void thread_func(void *userdata) {
revents = pollfd->revents;
} else
revents = 0;
-
- /* check for mixer shutdown, if any */
- if ((revents & (POLLOUT | POLLIN)) == 0) {
- int mixer_fd = u->mixer_fd;
- int devmask;
- if (mixer_fd > -1 && ioctl(mixer_fd, SOUND_MIXER_READ_DEVMASK, &devmask) < 0) {
- pa_log("Mixer shutdown.");
- goto fail;
- }
- }
}
fail:
@@ -1245,6 +1302,8 @@ int pa__init(pa_module*m) {
}
#ifndef __FreeBSD__
+/* Disable mmap. The OSS on FreeBSD doesn't support read & write on
+ the same socket */
if (use_mmap && mode == O_WRONLY) {
pa_log_info("Device opened for playback only, cannot do memory mapping, falling back to UNIX write() mode.");
use_mmap = false;
@@ -1277,8 +1336,6 @@ int pa__init(pa_module*m) {
u->module = m;
m->userdata = u;
u->fd = fd;
- u->mixer_fd = -1;
- u->mixer_devmask = 0;
u->use_getospace = u->use_getispace = true;
u->use_getodelay = true;
u->mode = mode;
@@ -1449,36 +1506,19 @@ int pa__init(pa_module*m) {
u->out_mmap_memblocks = pa_xnew0(pa_memblock*, u->out_nfrags);
}
- if ((u->mixer_fd = pa_oss_open_mixer_for_device(u->device_name)) >= 0) {
- bool do_close = true;
-
- if (ioctl(u->mixer_fd, SOUND_MIXER_READ_DEVMASK, &u->mixer_devmask) < 0)
- pa_log_warn("SOUND_MIXER_READ_DEVMASK failed: %s", pa_cstrerror(errno));
- else {
- if (u->sink && (u->mixer_devmask & (SOUND_MASK_VOLUME|SOUND_MASK_PCM))) {
- pa_log_debug("Found hardware mixer track for playback.");
- pa_sink_set_get_volume_callback(u->sink, sink_get_volume);
- pa_sink_set_set_volume_callback(u->sink, sink_set_volume);
- u->sink->n_volume_steps = 101;
- do_close = false;
- }
-
- if (u->source && (u->mixer_devmask & (SOUND_MASK_MIC|SOUND_MASK_RECLEV|SOUND_MASK_IGAIN))) {
- pa_log_debug("Found hardware mixer track for recording.");
- pa_source_set_get_volume_callback(u->source, source_get_volume);
- pa_source_set_set_volume_callback(u->source, source_set_volume);
- u->source->n_volume_steps = 101;
- do_close = false;
- }
- }
-
- if (do_close) {
- pa_close(u->mixer_fd);
- u->mixer_fd = -1;
- u->mixer_devmask = 0;
- }
+ if (u->sink) {
+ pa_log_debug("Found hardware mixer track for playback.");
+ pa_sink_set_get_volume_callback(u->sink, sink_get_volume);
+ pa_sink_set_set_volume_callback(u->sink, sink_set_volume);
+ u->sink->n_volume_steps = 101;
}
+ if (u->source) {
+ pa_log_debug("Found hardware mixer track for recording.");
+ pa_source_set_get_volume_callback(u->source, source_get_volume);
+ pa_source_set_set_volume_callback(u->source, source_set_volume);
+ u->source->n_volume_steps = 101;
+ }
go_on:
pa_assert(u->source || u->sink);
@@ -1594,9 +1634,6 @@ void pa__done(pa_module*m) {
if (u->fd >= 0)
pa_close(u->fd);
-
- if (u->mixer_fd >= 0)
- pa_close(u->mixer_fd);
pa_xfree(u->device_name);