From 5b5a25a14d11746e94baf2c11cb8d23137e19ffc Mon Sep 17 00:00:00 2001 From: Alexander Shursha Date: Fri, 29 Nov 2024 11:18:32 +0300 Subject: [PATCH 1/9] Fix link_args in src/modules/echo-cancel/meson.build Authored-by: Gleb Popov Sponsored by: Future Crew, LLC --- src/modules/echo-cancel/meson.build | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/modules/echo-cancel/meson.build b/src/modules/echo-cancel/meson.build index 94420c289..3bf67bb76 100644 --- a/src/modules/echo-cancel/meson.build +++ b/src/modules/echo-cancel/meson.build @@ -15,6 +15,8 @@ libwebrtc_util_sources = [ if host_machine.system() == 'darwin' ignore_unresolved_symbols_link_args = ['-Wl,-undefined,dynamic_lookup'] +elif host_machine.system() == 'freebsd' + ignore_unresolved_symbols_link_args = [''] else ignore_unresolved_symbols_link_args = ['-Wl,--unresolved-symbols=ignore-in-object-files'] endif From 16b3d14c590045c89ee3ea1faa80bc2dfe2dbcc3 Mon Sep 17 00:00:00 2001 From: Alexander Shursha Date: Fri, 29 Nov 2024 11:24:09 +0300 Subject: [PATCH 2/9] Disable udev in src/modules/meson.build Authored-by: Gleb Popov Sponsored by: Future Crew, LLC --- src/modules/meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/meson.build b/src/modules/meson.build index 05267c93a..fea7cca21 100644 --- a/src/modules/meson.build +++ b/src/modules/meson.build @@ -221,7 +221,7 @@ if libsystemd_dep.found() or libelogind_dep.found() ] endif -if udev_dep.found() +if udev_dep.found() and host_machine.system() != 'freebsd' all_modules += [ [ 'module-udev-detect', 'module-udev-detect.c', [], [], [udev_dep] ] ] if get_option('hal-compat') all_modules += [ [ 'module-hal-detect', 'module-hal-detect-compat.c' ] ] From 21e1f22478c552c5f2791bad7ad4b817ad5d8974 Mon Sep 17 00:00:00 2001 From: Alexander Shursha Date: Fri, 29 Nov 2024 11:33:17 +0300 Subject: [PATCH 3/9] Fix for detachable USB audio devices. Authored-by: Hans Petter Selasky Co-authored-by: Gleb Popov --- src/modules/oss/module-oss.c | 176 +++++++++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) diff --git a/src/modules/oss/module-oss.c b/src/modules/oss/module-oss.c index 048822c97..f87d9886d 100644 --- a/src/modules/oss/module-oss.c +++ b/src/modules/oss/module-oss.c @@ -121,8 +121,10 @@ struct userdata { int fd; int mode; + #ifndef __FreeBSD__ int mixer_fd; int mixer_devmask; + #endif int nfrags, frag_size, orig_frag_size; @@ -819,11 +821,53 @@ static int source_set_state_in_io_thread_cb(pa_source *s, pa_source_state_t new_ return 0; } +#ifdef __FreeBSD__ +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)); +} +#endif + static void sink_get_volume(pa_sink *s) { struct userdata *u; +#ifdef __FreeBSD__ + int mixer_fd; + int mixer_devmask; +#endif + pa_assert_se(u = s->userdata); +#ifndef __FreeBSD__ pa_assert(u->mixer_devmask & (SOUND_MASK_VOLUME|SOUND_MASK_PCM)); if (u->mixer_devmask & SOUND_MASK_VOLUME) @@ -833,15 +877,43 @@ static void sink_get_volume(pa_sink *s) { 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; +#else + mixer_fd = open_mixer(u, &mixer_devmask); + if (mixer_fd < 0) { + oss_get_dummy_volume(&s->sample_spec, &s->real_volume); + 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 (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); +#endif pa_log_info("Device doesn't support reading mixer settings: %s", pa_cstrerror(errno)); + +#ifdef __FreeBSD__ +done: + pa_close(mixer_fd); +#endif } static void sink_set_volume(pa_sink *s) { struct userdata *u; +#ifdef __FreeBSD__ + int mixer_fd; + int mixer_devmask; +#endif + pa_assert_se(u = s->userdata); +#ifndef __FreeBSD__ pa_assert(u->mixer_devmask & (SOUND_MASK_VOLUME|SOUND_MASK_PCM)); if (u->mixer_devmask & SOUND_MASK_VOLUME) @@ -849,13 +921,32 @@ static void sink_set_volume(pa_sink *s) { 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); +#else + mixer_fd = open_mixer(u, &mixer_devmask); + if (mixer_fd < 0) + return; + + if (mixer_devmask & SOUND_MASK_VOLUME) + (void) pa_oss_set_volume(mixer_fd, SOUND_MIXER_WRITE_VOLUME, &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); +#endif } static void source_get_volume(pa_source *s) { struct userdata *u; +#ifdef __FreeBSD__ + int mixer_fd; + int mixer_devmask; +#endif + pa_assert_se(u = s->userdata); +#ifndef __FreeBSD__ pa_assert(u->mixer_devmask & (SOUND_MASK_MIC|SOUND_MASK_IGAIN|SOUND_MASK_RECLEV)); if (u->mixer_devmask & SOUND_MASK_IGAIN) @@ -869,15 +960,47 @@ static void source_get_volume(pa_source *s) { 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; +#else + mixer_fd = open_mixer(u, &mixer_devmask); + if (mixer_fd < 0) { + oss_get_dummy_volume(&s->sample_spec, &s->real_volume); + 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 (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 (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); +#endif pa_log_info("Device doesn't support reading mixer settings: %s", pa_cstrerror(errno)); + +#ifdef __FreeBSD__ + done: + pa_close(mixer_fd); +#endif } static void source_set_volume(pa_source *s) { struct userdata *u; +#ifdef __FreeBSD__ + int mixer_fd; + int mixer_devmask; +#endif + pa_assert_se(u = s->userdata); +#ifndef __FreeBSD__ pa_assert(u->mixer_devmask & (SOUND_MASK_MIC|SOUND_MASK_IGAIN|SOUND_MASK_RECLEV)); if (u->mixer_devmask & SOUND_MASK_IGAIN) @@ -888,6 +1011,22 @@ static void source_set_volume(pa_source *s) { 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); +#else + mixer_fd = open_mixer(u, &mixer_devmask); + if (mixer_fd < 0) + return; + + if (mixer_devmask & SOUND_MASK_IGAIN) + (void) pa_oss_set_volume(mixer_fd, SOUND_MIXER_WRITE_IGAIN, &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 (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); +#endif } static void thread_func(void *userdata) { @@ -1159,6 +1298,7 @@ static void thread_func(void *userdata) { } else revents = 0; +#ifndef __FreeBSD__ /* check for mixer shutdown, if any */ if ((revents & (POLLOUT | POLLIN)) == 0) { int mixer_fd = u->mixer_fd; @@ -1168,6 +1308,7 @@ static void thread_func(void *userdata) { goto fail; } } +#endif } fail: @@ -1244,6 +1385,8 @@ int pa__init(pa_module*m) { use_mmap = false; } +/* Disable mmap. The OSS on FreeBSD doesn't support read & write on + the same socket */ #ifndef __FreeBSD__ if (use_mmap && mode == O_WRONLY) { pa_log_info("Device opened for playback only, cannot do memory mapping, falling back to UNIX write() mode."); @@ -1277,8 +1420,10 @@ int pa__init(pa_module*m) { u->module = m; m->userdata = u; u->fd = fd; +#ifndef __FreeBSD__ u->mixer_fd = -1; u->mixer_devmask = 0; +#endif u->use_getospace = u->use_getispace = true; u->use_getodelay = true; u->mode = mode; @@ -1449,6 +1594,7 @@ int pa__init(pa_module*m) { u->out_mmap_memblocks = pa_xnew0(pa_memblock*, u->out_nfrags); } +#ifndef __FreeBSD__ if ((u->mixer_fd = pa_oss_open_mixer_for_device(u->device_name)) >= 0) { bool do_close = true; @@ -1478,7 +1624,35 @@ int pa__init(pa_module*m) { u->mixer_devmask = 0; } } +#else + 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; + } + + 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; + } +#endif go_on: pa_assert(u->source || u->sink); @@ -1595,8 +1769,10 @@ void pa__done(pa_module*m) { if (u->fd >= 0) pa_close(u->fd); +#ifndef __FreeBSD__ if (u->mixer_fd >= 0) pa_close(u->mixer_fd); +#endif pa_xfree(u->device_name); From 10b903176329796e49cbb78986b7420ae6cc5b2d Mon Sep 17 00:00:00 2001 From: Alexander Shursha Date: Fri, 29 Nov 2024 11:40:13 +0300 Subject: [PATCH 4/9] Add defines in oss-util. Authored-by: Jeremy Messenger --- src/modules/oss/oss-util.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/modules/oss/oss-util.c b/src/modules/oss/oss-util.c index 80b6c8c63..5fec9d808 100644 --- a/src/modules/oss/oss-util.c +++ b/src/modules/oss/oss-util.c @@ -39,6 +39,24 @@ #include "oss-util.h" +#ifdef __FreeBSD__ +#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 +#endif + int pa_oss_open(const char *device, int *mode, int* pcaps) { static const int nonblock_io = 1; int fd = -1; From d654c32dc86328e9e9db42f96c9daa3a6fcd04bf Mon Sep 17 00:00:00 2001 From: Alexander Shursha Date: Fri, 29 Nov 2024 11:59:32 +0300 Subject: [PATCH 5/9] speed up startup Authored-by: Baptiste Daroussin --- src/pulsecore/core-util.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index 5d2bae92f..3349d0572 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -2851,11 +2851,20 @@ int pa_close_allv(const int except_fds[]) { #endif +#if defined(__FreeBSD__) + maxfd = 0; + for (int i = 0; except_fds[i] >= 0; i++) + if (except_fds[i] > maxfd) + maxfd = except_fds[i]; + maxfd++; + closefrom(maxfd); +#else if (getrlimit(RLIMIT_NOFILE, &rl) >= 0) maxfd = (int) rl.rlim_max; else maxfd = sysconf(_SC_OPEN_MAX); +#endif for (fd = 3; fd < maxfd; fd++) { int i; bool found; From 416b26d6118ec3f45de15fb774c03a1271ed1275 Mon Sep 17 00:00:00 2001 From: Alexander Shursha Date: Fri, 29 Nov 2024 13:33:19 +0300 Subject: [PATCH 6/9] fix build on armv7 Authored-by: Robert Clausecker --- src/pulsecore/mix_neon.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/pulsecore/mix_neon.c b/src/pulsecore/mix_neon.c index eb02d8165..c2f43d716 100644 --- a/src/pulsecore/mix_neon.c +++ b/src/pulsecore/mix_neon.c @@ -176,8 +176,13 @@ static void pa_mix2_ch4_s16ne_neon(pa_mix_info streams[], int16_t *data, unsigne int32x4_t sv0, sv1; __asm__ __volatile__ ( +#ifndef __FreeBSD__ "vld1.s32 %h[sv0], [%[lin0]] \n\t" "vld1.s32 %h[sv1], [%[lin1]] \n\t" +#else + "vld1.s32 {%e[sv0],%f[sv0]}, [%[lin0]] \n\t" + "vld1.s32 {%e[sv1],%f[sv1]}, [%[lin1]] \n\t" +#endif : [sv0] "=w" (sv0), [sv1] "=w" (sv1) : [lin0] "r" (streams[0].linear), [lin1] "r" (streams[1].linear) : /* clobber list */ From 49714f08d35ddb83729ae2cfd3ffde6f4f2f09f1 Mon Sep 17 00:00:00 2001 From: Alexander Shursha Date: Fri, 29 Nov 2024 13:42:00 +0300 Subject: [PATCH 7/9] Fix creating of shared memory segments by specifying a writable location to store the associated file. Authored-by: Joe Marcus Clarke --- src/pulsecore/shm.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pulsecore/shm.c b/src/pulsecore/shm.c index 694f971b4..a9a321f0b 100644 --- a/src/pulsecore/shm.c +++ b/src/pulsecore/shm.c @@ -105,7 +105,11 @@ static inline size_t shm_marker_size(pa_mem_type_t type) { #ifdef HAVE_SHM_OPEN static char *segment_name(char *fn, size_t l, unsigned id) { +#ifndef __FreeBSD__ pa_snprintf(fn, l, "/pulse-shm-%u", id); +#else + pa_snprintf(fn, l, "/tmp/pulse-shm-%u", id); +#endif return fn; } #endif From d1036eaf4f5cfd97b65f2182ce9526e68a490b3e Mon Sep 17 00:00:00 2001 From: Alexander Shursha Date: Fri, 29 Nov 2024 13:46:59 +0300 Subject: [PATCH 8/9] fix thread naming Authored-by: Baptiste Daroussin --- src/pulsecore/thread-posix.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/pulsecore/thread-posix.c b/src/pulsecore/thread-posix.c index 62b0ec464..f712050b8 100644 --- a/src/pulsecore/thread-posix.c +++ b/src/pulsecore/thread-posix.c @@ -71,6 +71,8 @@ static void* internal_thread_func(void *userdata) { prctl(PR_SET_NAME, t->name); #elif defined(HAVE_PTHREAD_SETNAME_NP) && defined(OS_IS_DARWIN) pthread_setname_np(t->name); +#elif defined(HAVE_PTHREAD_SETNAME_NP) && defined(OS_IS_FREEBSD) + pthread_setname_np(t->id, t->name); #endif t->id = pthread_self(); @@ -184,6 +186,8 @@ void pa_thread_set_name(pa_thread *t, const char *name) { prctl(PR_SET_NAME, name); #elif defined(HAVE_PTHREAD_SETNAME_NP) && defined(OS_IS_DARWIN) pthread_setname_np(name); +#elif defined(HAVE_PTHREAD_SETNAME_NP) && defined(OS_IS_FREEBSD) + pthread_setname_np(t->id, t->name); #endif } @@ -201,7 +205,7 @@ const char *pa_thread_get_name(pa_thread *t) { t->name = NULL; } } -#elif defined(HAVE_PTHREAD_GETNAME_NP) && defined(OS_IS_DARWIN) +#elif defined(HAVE_PTHREAD_GETNAME_NP) && (defined(OS_IS_DARWIN) || defined(OS_IS_FREEBSD)) if (!t->name) { t->name = pa_xmalloc0(17); pthread_getname_np(t->id, t->name, 16); From 63056714c4cdd7d366ab3429ae96cd7d6b803390 Mon Sep 17 00:00:00 2001 From: Alexander Shursha Date: Fri, 29 Nov 2024 13:49:09 +0300 Subject: [PATCH 9/9] Fix cpuset Authored-by: Jan Beich --- src/tests/atomic-test.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/tests/atomic-test.c b/src/tests/atomic-test.c index 86b3d77a9..afa99f8d0 100644 --- a/src/tests/atomic-test.c +++ b/src/tests/atomic-test.c @@ -54,6 +54,11 @@ #define MEMORY_SIZE (8 * 2 * 1024 * 1024) +#ifdef __FreeBSD__ +#include +#define cpu_set_t cpuset_t +#endif + typedef struct io_t { pa_atomic_t *flag;