├── .codespell-ignore ├── .editorconfig ├── .gitattributes ├── .gitignore ├── .gitlab-ci.yml ├── .gitlab ├── ci │ └── check_missing_headers.sh └── issue_templates │ ├── .gitkeep │ ├── bluetooth issue.md │ └── issue.md ├── CODE_OF_CONDUCT.md ├── COPYING ├── INSTALL.md ├── LICENSE ├── Makefile.in ├── NEWS ├── README.md ├── autogen.sh ├── cross-x86.txt ├── doc ├── Doxyfile.in ├── DoxygenLayout.xml ├── custom.css ├── dox │ ├── api │ │ ├── index.dox │ │ ├── spa-buffer.dox │ │ ├── spa-design.dox │ │ ├── spa-index.dox │ │ ├── spa-plugins.dox │ │ └── spa-pod.dox │ ├── config │ │ ├── index.md │ │ ├── libpipewire-modules.7.md │ │ ├── pipewire-client.conf.5.md │ │ ├── pipewire-filter-chain.conf.5.md │ │ ├── pipewire-jack.conf.5.md │ │ ├── pipewire-props.7.md │ │ ├── pipewire-pulse-modules.7.md │ │ ├── pipewire-pulse.conf.5.md │ │ ├── pipewire.conf.5.md │ │ └── xref.md │ ├── index.dox │ ├── internals │ │ ├── access.dox │ │ ├── audio.dox │ │ ├── daemon.dox │ │ ├── design.dox │ │ ├── dma-buf.dox │ │ ├── index.dox │ │ ├── latency.dox │ │ ├── library.dox │ │ ├── midi.dox │ │ ├── objects.dox │ │ ├── portal.dox │ │ ├── protocol.dox │ │ ├── pulseaudio.dox │ │ ├── scheduling.dox │ │ ├── session-manager.dox │ │ └── tag.dox │ ├── modules.dox │ ├── overview.dox │ ├── programs │ │ ├── index.md │ │ ├── pipewire-pulse.1.md │ │ ├── pipewire.1.md │ │ ├── pw-cat.1.md │ │ ├── pw-cli.1.md │ │ ├── pw-config.1.md │ │ ├── pw-container.1.md │ │ ├── pw-dot.1.md │ │ ├── pw-dump.1.md │ │ ├── pw-jack.1.md │ │ ├── pw-link.1.md │ │ ├── pw-loopback.1.md │ │ ├── pw-metadata.1.md │ │ ├── pw-mididump.1.md │ │ ├── pw-mon.1.md │ │ ├── pw-profiler.1.md │ │ ├── pw-reserve.1.md │ │ ├── pw-top.1.md │ │ ├── pw-v4l2.1.md │ │ ├── spa-acp-tool.1.md │ │ ├── spa-inspect.1.md │ │ ├── spa-json-dump.1.md │ │ ├── spa-monitor.1.md │ │ └── spa-resample.1.md │ ├── pulse-modules.dox │ ├── pulse-modules.inc │ └── tutorial │ │ ├── index.dox │ │ ├── tutorial1.dox │ │ ├── tutorial2.dox │ │ ├── tutorial3.dox │ │ ├── tutorial4.dox │ │ ├── tutorial5.dox │ │ └── tutorial6.dox ├── doxygen-awesome.css ├── examples.dox.in ├── examples │ ├── tutorial1.c │ ├── tutorial2.c │ ├── tutorial3.c │ ├── tutorial4.c │ ├── tutorial5.c │ └── tutorial6.c ├── input-filter-h.sh ├── input-filter-md.py ├── input-filter.py ├── man-fixup.py ├── meson.build └── tree.dox ├── include └── valgrind │ ├── memcheck.h │ └── valgrind.h ├── meson.build ├── meson_options.txt ├── pipewire-alsa ├── alsa-plugins │ ├── ctl_pipewire.c │ ├── meson.build │ └── pcm_pipewire.c ├── conf │ ├── 50-pipewire.conf │ ├── 99-pipewire-default.conf │ └── meson.build └── tests │ ├── meson.build │ └── test-pipewire-alsa-stress.c ├── pipewire-jack ├── examples │ ├── ump-source.c │ └── video-dsp-play.c ├── jack │ ├── control.h │ ├── intclient.h │ ├── jack.h │ ├── jslist.h │ ├── metadata.h │ ├── midiport.h │ ├── net.h │ ├── ringbuffer.h │ ├── session.h │ ├── statistics.h │ ├── systemdeps.h │ ├── thread.h │ ├── transport.h │ ├── types.h │ ├── uuid.h │ ├── weakjack.h │ └── weakmacros.h ├── meson.build └── src │ ├── control.c │ ├── dummy.c │ ├── export.c │ ├── meson.build │ ├── metadata.c │ ├── net.c │ ├── pipewire-jack-extensions.h │ ├── pipewire-jack.c │ ├── pw-jack.in │ ├── ringbuffer.c │ ├── statistics.c │ └── uuid.c ├── pipewire-v4l2 ├── meson.build └── src │ ├── meson.build │ ├── pipewire-v4l2.c │ ├── pipewire-v4l2.h │ ├── pw-v4l2.in │ └── v4l2-func.c ├── po ├── LINGUAS ├── POTFILES.in ├── POTFILES.skip ├── af.po ├── as.po ├── be.po ├── bg.po ├── bn_IN.po ├── ca.po ├── cs.po ├── da.po ├── de.po ├── de_CH.po ├── el.po ├── eo.po ├── es.po ├── fi.po ├── fr.po ├── gl.po ├── gu.po ├── he.po ├── hi.po ├── hr.po ├── hu.po ├── id.po ├── it.po ├── ja.po ├── ka.po ├── kk.po ├── kn.po ├── ko.po ├── lt.po ├── meson.build ├── ml.po ├── mr.po ├── my.po ├── nl.po ├── nn.po ├── oc.po ├── or.po ├── pa.po ├── pipewire.pot ├── pl.po ├── pt.po ├── pt_BR.po ├── ro.po ├── ru.po ├── si.po ├── sk.po ├── sl.po ├── sr.po ├── sr@latin.po ├── sv.po ├── ta.po ├── te.po ├── tr.po ├── uk.po ├── zh_CN.po └── zh_TW.po ├── pw-uninstalled.sh ├── spa ├── examples │ ├── adapter-control.c │ ├── example-control.c │ ├── local-libcamera.c │ ├── local-v4l2.c │ ├── local-videotestsrc.c │ └── meson.build ├── include-private │ └── spa-private │ │ └── dbus-helpers.h ├── include │ ├── meson.build │ └── spa │ │ ├── buffer │ │ ├── alloc.h │ │ ├── buffer.h │ │ ├── meta.h │ │ └── type-info.h │ │ ├── control │ │ ├── control.h │ │ ├── type-info.h │ │ └── ump-utils.h │ │ ├── debug │ │ ├── buffer.h │ │ ├── context.h │ │ ├── dict.h │ │ ├── file.h │ │ ├── format.h │ │ ├── log.h │ │ ├── mem.h │ │ ├── node.h │ │ ├── pod.h │ │ └── types.h │ │ ├── filter-graph │ │ └── filter-graph.h │ │ ├── graph │ │ └── graph.h │ │ ├── interfaces │ │ └── audio │ │ │ └── aec.h │ │ ├── monitor │ │ ├── device.h │ │ ├── event.h │ │ ├── type-info.h │ │ └── utils.h │ │ ├── node │ │ ├── command.h │ │ ├── event.h │ │ ├── io.h │ │ ├── keys.h │ │ ├── node.h │ │ ├── type-info.h │ │ └── utils.h │ │ ├── param │ │ ├── audio │ │ │ ├── aac-types.h │ │ │ ├── aac-utils.h │ │ │ ├── aac.h │ │ │ ├── ac3-utils.h │ │ │ ├── ac3.h │ │ │ ├── alac-utils.h │ │ │ ├── alac.h │ │ │ ├── amr-types.h │ │ │ ├── amr-utils.h │ │ │ ├── amr.h │ │ │ ├── ape-utils.h │ │ │ ├── ape.h │ │ │ ├── compressed.h │ │ │ ├── dsd-utils.h │ │ │ ├── dsd.h │ │ │ ├── dsp-utils.h │ │ │ ├── dsp.h │ │ │ ├── dts-types.h │ │ │ ├── dts-utils.h │ │ │ ├── dts.h │ │ │ ├── eac3-utils.h │ │ │ ├── eac3.h │ │ │ ├── flac-utils.h │ │ │ ├── flac.h │ │ │ ├── format-utils.h │ │ │ ├── format.h │ │ │ ├── iec958-types.h │ │ │ ├── iec958-utils.h │ │ │ ├── iec958.h │ │ │ ├── layout.h │ │ │ ├── mp3-types.h │ │ │ ├── mp3-utils.h │ │ │ ├── mp3.h │ │ │ ├── mpegh-utils.h │ │ │ ├── mpegh.h │ │ │ ├── opus.h │ │ │ ├── ra-utils.h │ │ │ ├── ra.h │ │ │ ├── raw-json.h │ │ │ ├── raw-types.h │ │ │ ├── raw-utils.h │ │ │ ├── raw.h │ │ │ ├── truehd-utils.h │ │ │ ├── truehd.h │ │ │ ├── type-info.h │ │ │ ├── vorbis-utils.h │ │ │ ├── vorbis.h │ │ │ ├── wma-types.h │ │ │ ├── wma-utils.h │ │ │ └── wma.h │ │ ├── bluetooth │ │ │ ├── audio.h │ │ │ └── type-info.h │ │ ├── buffers-types.h │ │ ├── buffers.h │ │ ├── format-types.h │ │ ├── format-utils.h │ │ ├── format.h │ │ ├── latency-types.h │ │ ├── latency-utils.h │ │ ├── latency.h │ │ ├── param-types.h │ │ ├── param.h │ │ ├── port-config-types.h │ │ ├── port-config.h │ │ ├── profile-types.h │ │ ├── profile.h │ │ ├── profiler-types.h │ │ ├── profiler.h │ │ ├── props-types.h │ │ ├── props.h │ │ ├── route-types.h │ │ ├── route.h │ │ ├── tag-types.h │ │ ├── tag-utils.h │ │ ├── tag.h │ │ ├── type-info.h │ │ └── video │ │ │ ├── chroma.h │ │ │ ├── color.h │ │ │ ├── dsp-utils.h │ │ │ ├── dsp.h │ │ │ ├── encoded.h │ │ │ ├── format-utils.h │ │ │ ├── format.h │ │ │ ├── h264-utils.h │ │ │ ├── h264.h │ │ │ ├── h265-utils.h │ │ │ ├── h265.h │ │ │ ├── mjpg-utils.h │ │ │ ├── mjpg.h │ │ │ ├── multiview.h │ │ │ ├── raw-types.h │ │ │ ├── raw-utils.h │ │ │ ├── raw.h │ │ │ └── type-info.h │ │ ├── pod │ │ ├── builder.h │ │ ├── command.h │ │ ├── compare.h │ │ ├── dynamic.h │ │ ├── event.h │ │ ├── filter.h │ │ ├── iter.h │ │ ├── parser.h │ │ ├── pod.h │ │ ├── simplify.h │ │ └── vararg.h │ │ ├── support │ │ ├── cpu.h │ │ ├── dbus.h │ │ ├── i18n.h │ │ ├── log-impl.h │ │ ├── log.h │ │ ├── loop.h │ │ ├── plugin-loader.h │ │ ├── plugin.h │ │ ├── system.h │ │ └── thread.h │ │ └── utils │ │ ├── ansi.h │ │ ├── atomic.h │ │ ├── cleanup.h │ │ ├── defs.h │ │ ├── dict.h │ │ ├── dll.h │ │ ├── endian.h │ │ ├── enum-types.h │ │ ├── hook.h │ │ ├── json-core.h │ │ ├── json-pod.h │ │ ├── json.h │ │ ├── keys.h │ │ ├── list.h │ │ ├── names.h │ │ ├── ratelimit.h │ │ ├── result.h │ │ ├── ringbuffer.h │ │ ├── string.h │ │ ├── type-info.h │ │ └── type.h ├── lib │ ├── lib.c │ └── meson.build ├── meson.build ├── plugins │ ├── aec │ │ ├── aec-null.c │ │ ├── aec-webrtc.cpp │ │ └── meson.build │ ├── alsa │ │ ├── 90-pipewire-alsa.rules │ │ ├── acp-tool.c │ │ ├── acp │ │ │ ├── acp.c │ │ │ ├── acp.h │ │ │ ├── alsa-mixer.c │ │ │ ├── alsa-mixer.h │ │ │ ├── alsa-ucm.c │ │ │ ├── alsa-ucm.h │ │ │ ├── alsa-util.c │ │ │ ├── alsa-util.h │ │ │ ├── array.h │ │ │ ├── card.h │ │ │ ├── channelmap.h │ │ │ ├── compat.c │ │ │ ├── compat.h │ │ │ ├── conf-parser.c │ │ │ ├── conf-parser.h │ │ │ ├── device-port.h │ │ │ ├── dynarray.h │ │ │ ├── hashmap.h │ │ │ ├── idxset.h │ │ │ ├── llist.h │ │ │ ├── meson.build │ │ │ ├── proplist.h │ │ │ └── volume.h │ │ ├── alsa-acp-device.c │ │ ├── alsa-compress-offload-device.c │ │ ├── alsa-compress-offload-sink.c │ │ ├── alsa-pcm-device.c │ │ ├── alsa-pcm-sink.c │ │ ├── alsa-pcm-source.c │ │ ├── alsa-pcm.c │ │ ├── alsa-pcm.h │ │ ├── alsa-seq-bridge.c │ │ ├── alsa-seq.c │ │ ├── alsa-seq.h │ │ ├── alsa-udev.c │ │ ├── alsa.c │ │ ├── alsa.h │ │ ├── compress-offload-api-util.c │ │ ├── compress-offload-api-util.h │ │ ├── compress-offload-api.c │ │ ├── compress-offload-api.h │ │ ├── meson.build │ │ ├── mixer │ │ │ ├── meson.build │ │ │ ├── paths │ │ │ │ ├── analog-input-aux.conf │ │ │ │ ├── analog-input-dock-mic.conf │ │ │ │ ├── analog-input-fm.conf │ │ │ │ ├── analog-input-front-mic.conf │ │ │ │ ├── analog-input-headphone-mic.conf │ │ │ │ ├── analog-input-headset-mic.conf │ │ │ │ ├── analog-input-internal-mic-always.conf │ │ │ │ ├── analog-input-internal-mic.conf │ │ │ │ ├── analog-input-linein.conf │ │ │ │ ├── analog-input-mic-line.conf │ │ │ │ ├── analog-input-mic.conf │ │ │ │ ├── analog-input-mic.conf.common │ │ │ │ ├── analog-input-rear-mic.conf │ │ │ │ ├── analog-input-tvtuner.conf │ │ │ │ ├── analog-input-video.conf │ │ │ │ ├── analog-input.conf │ │ │ │ ├── analog-input.conf.common │ │ │ │ ├── analog-output-chat.conf │ │ │ │ ├── analog-output-headphones-2.conf │ │ │ │ ├── analog-output-headphones.conf │ │ │ │ ├── analog-output-lineout.conf │ │ │ │ ├── analog-output-mono.conf │ │ │ │ ├── analog-output-speaker-always.conf │ │ │ │ ├── analog-output-speaker.conf │ │ │ │ ├── analog-output.conf │ │ │ │ ├── analog-output.conf.common │ │ │ │ ├── audigy-analog-output-mirror.conf │ │ │ │ ├── audigy-analog-output.conf │ │ │ │ ├── hdmi-output-0.conf │ │ │ │ ├── hdmi-output-1.conf │ │ │ │ ├── hdmi-output-10.conf │ │ │ │ ├── hdmi-output-2.conf │ │ │ │ ├── hdmi-output-3.conf │ │ │ │ ├── hdmi-output-4.conf │ │ │ │ ├── hdmi-output-5.conf │ │ │ │ ├── hdmi-output-6.conf │ │ │ │ ├── hdmi-output-7.conf │ │ │ │ ├── hdmi-output-8.conf │ │ │ │ ├── hdmi-output-9.conf │ │ │ │ ├── iec958-stereo-input.conf │ │ │ │ ├── iec958-stereo-output.conf │ │ │ │ ├── steelseries-arctis-output-chat-common.conf │ │ │ │ ├── steelseries-arctis-output-game-common.conf │ │ │ │ ├── usb-gaming-headset-input.conf │ │ │ │ ├── usb-gaming-headset-output-mono.conf │ │ │ │ ├── usb-gaming-headset-output-stereo.conf │ │ │ │ └── virtual-surround-7.1.conf │ │ │ ├── profile-sets │ │ │ │ ├── 9999-custom.conf │ │ │ │ ├── analog-only.conf │ │ │ │ ├── asus-xonar-se.conf │ │ │ │ ├── audigy.conf │ │ │ │ ├── cmedia-high-speed-true-hdaudio.conf │ │ │ │ ├── default.conf │ │ │ │ ├── dell-dock-tb16-usb-audio.conf │ │ │ │ ├── force-speaker-and-int-mic.conf │ │ │ │ ├── force-speaker.conf │ │ │ │ ├── hdmi-ac3.conf │ │ │ │ ├── hp-tbt-dock-120w-g2.conf │ │ │ │ ├── hp-tbt-dock-audio-module.conf │ │ │ │ ├── kinect-audio.conf │ │ │ │ ├── maudio-fasttrack-pro.conf │ │ │ │ ├── native-instruments-audio4dj.conf │ │ │ │ ├── native-instruments-audio8dj.conf │ │ │ │ ├── native-instruments-komplete-audio6.conf │ │ │ │ ├── native-instruments-korecontroller.conf │ │ │ │ ├── native-instruments-traktor-audio10.conf │ │ │ │ ├── native-instruments-traktor-audio2.conf │ │ │ │ ├── native-instruments-traktor-audio6.conf │ │ │ │ ├── native-instruments-traktorkontrol-s4.conf │ │ │ │ ├── sb-omni-surround-5.1.conf │ │ │ │ ├── sennheiser-gsx.conf │ │ │ │ ├── simple-headphones-mic.conf │ │ │ │ ├── steelseries-arctis-common-usb-audio.conf │ │ │ │ ├── texas-instruments-pcm2902.conf │ │ │ │ └── usb-gaming-headset.conf │ │ │ └── samples │ │ │ │ ├── ATI IXP--Realtek ALC655 rev 0 │ │ │ │ ├── Brooktree Bt878--Bt87x │ │ │ │ ├── Ensoniq AudioPCI--Cirrus Logic CS4297A rev 3 │ │ │ │ ├── HDA ATI HDMI--ATI R6xx HDMI │ │ │ │ ├── HDA Intel--Analog Devices AD1981 │ │ │ │ ├── HDA Intel--Realtek ALC889A │ │ │ │ ├── Intel 82801CA-ICH3--Analog Devices AD1881A │ │ │ │ ├── Logitech USB Speaker--USB Mixer │ │ │ │ ├── USB Audio--USB Mixer │ │ │ │ ├── USB Device 0x46d_0x9a4--USB Mixer │ │ │ │ ├── VIA 8237--Analog Devices AD1888 │ │ │ │ └── VIA 8237--C-Media Electronics CMI9761A+ │ │ ├── test-hw-params.c │ │ └── test-timer.c │ ├── audioconvert │ │ ├── audioadapter.c │ │ ├── audioconvert.c │ │ ├── benchmark-fmt-ops.c │ │ ├── benchmark-resample.c │ │ ├── biquad.c │ │ ├── biquad.h │ │ ├── channelmix-ops-c.c │ │ ├── channelmix-ops-sse.c │ │ ├── channelmix-ops.c │ │ ├── channelmix-ops.h │ │ ├── crossover.c │ │ ├── crossover.h │ │ ├── fmt-ops-avx2.c │ │ ├── fmt-ops-c.c │ │ ├── fmt-ops-neon.c │ │ ├── fmt-ops-rvv.c │ │ ├── fmt-ops-sse2.c │ │ ├── fmt-ops-sse41.c │ │ ├── fmt-ops-ssse3.c │ │ ├── fmt-ops.c │ │ ├── fmt-ops.h │ │ ├── hilbert.h │ │ ├── law.h │ │ ├── meson.build │ │ ├── peaks-ops-c.c │ │ ├── peaks-ops-sse.c │ │ ├── peaks-ops.c │ │ ├── peaks-ops.h │ │ ├── plugin.c │ │ ├── resample-native-avx.c │ │ ├── resample-native-c.c │ │ ├── resample-native-impl.h │ │ ├── resample-native-neon.c │ │ ├── resample-native-sse.c │ │ ├── resample-native-ssse3.c │ │ ├── resample-native.c │ │ ├── resample-peaks.c │ │ ├── resample.h │ │ ├── spa-resample-dump-coeffs.c │ │ ├── spa-resample.c │ │ ├── test-audioadapter.c │ │ ├── test-audioconvert.c │ │ ├── test-channelmix.c │ │ ├── test-fmt-ops.c │ │ ├── test-peaks.c │ │ ├── test-resample-delay.c │ │ ├── test-resample.c │ │ ├── test-source.c │ │ ├── volume-ops-c.c │ │ ├── volume-ops-sse.c │ │ ├── volume-ops.c │ │ ├── volume-ops.h │ │ ├── wavfile.c │ │ └── wavfile.h │ ├── audiomixer │ │ ├── audiomixer.c │ │ ├── benchmark-mix-ops.c │ │ ├── meson.build │ │ ├── mix-ops-avx.c │ │ ├── mix-ops-c.c │ │ ├── mix-ops-sse.c │ │ ├── mix-ops-sse2.c │ │ ├── mix-ops.c │ │ ├── mix-ops.h │ │ ├── mixer-dsp.c │ │ ├── plugin.c │ │ └── test-mix-ops.c │ ├── audiotestsrc │ │ ├── audiotestsrc.c │ │ ├── meson.build │ │ ├── plugin.c │ │ └── render.c │ ├── avb │ │ ├── avb-pcm-sink.c │ │ ├── avb-pcm-source.c │ │ ├── avb-pcm.c │ │ ├── avb-pcm.h │ │ ├── avb.c │ │ ├── avb.h │ │ ├── avbtp │ │ │ └── packets.h │ │ └── meson.build │ ├── bluez5 │ │ ├── README-MIDI.md │ │ ├── README-OPUS-A2DP.md │ │ ├── README-SBC-XQ.md │ │ ├── README-Telephony.md │ │ ├── a2dp-codec-aac.c │ │ ├── a2dp-codec-aptx.c │ │ ├── a2dp-codec-caps.h │ │ ├── a2dp-codec-faststream.c │ │ ├── a2dp-codec-lc3plus.c │ │ ├── a2dp-codec-ldac.c │ │ ├── a2dp-codec-opus-g.c │ │ ├── a2dp-codec-opus.c │ │ ├── a2dp-codec-sbc.c │ │ ├── asha-codec-g722.c │ │ ├── backend-hsphfpd.c │ │ ├── backend-native.c │ │ ├── backend-ofono.c │ │ ├── bap-codec-caps.h │ │ ├── bap-codec-lc3.c │ │ ├── bluez-hardware.conf │ │ ├── bluez5-dbus.c │ │ ├── bluez5-device.c │ │ ├── bt-latency.h │ │ ├── codec-loader.c │ │ ├── codec-loader.h │ │ ├── dbus-monitor.c │ │ ├── dbus-monitor.h │ │ ├── decode-buffer.h │ │ ├── defs.h │ │ ├── g722 │ │ │ ├── g722_enc_dec.h │ │ │ └── g722_encode.c │ │ ├── hci.c │ │ ├── iso-io.c │ │ ├── iso-io.h │ │ ├── media-codecs.c │ │ ├── media-codecs.h │ │ ├── media-sink.c │ │ ├── media-source.c │ │ ├── meson.build │ │ ├── midi-enum.c │ │ ├── midi-node.c │ │ ├── midi-parser.c │ │ ├── midi-server.c │ │ ├── midi.h │ │ ├── modemmanager.c │ │ ├── modemmanager.h │ │ ├── org.bluez.xml │ │ ├── player.c │ │ ├── player.h │ │ ├── plugin.c │ │ ├── quirks.c │ │ ├── rate-control.h │ │ ├── rtp.h │ │ ├── sco-io.c │ │ ├── sco-sink.c │ │ ├── sco-source.c │ │ ├── telephony.c │ │ ├── telephony.h │ │ ├── test-midi.c │ │ ├── upower.c │ │ └── upower.h │ ├── control │ │ ├── meson.build │ │ ├── mixer.c │ │ └── plugin.c │ ├── ffmpeg │ │ ├── ffmpeg-dec.c │ │ ├── ffmpeg-enc.c │ │ ├── ffmpeg.c │ │ ├── ffmpeg.h │ │ └── meson.build │ ├── filter-graph │ │ ├── audio-dsp-avx.c │ │ ├── audio-dsp-c.c │ │ ├── audio-dsp-impl.h │ │ ├── audio-dsp-sse.c │ │ ├── audio-dsp.c │ │ ├── audio-dsp.h │ │ ├── audio-plugin.h │ │ ├── biquad.h │ │ ├── builtin_plugin.c │ │ ├── convolver.c │ │ ├── convolver.h │ │ ├── ebur128_plugin.c │ │ ├── ffmpeg_plugin.c │ │ ├── filter-graph.c │ │ ├── ladspa.h │ │ ├── ladspa_plugin.c │ │ ├── lv2_plugin.c │ │ ├── meson.build │ │ ├── pffft.c │ │ ├── pffft.h │ │ └── sofa_plugin.c │ ├── jack │ │ ├── jack-client.c │ │ ├── jack-client.h │ │ ├── jack-device.c │ │ ├── jack-sink.c │ │ ├── jack-source.c │ │ ├── meson.build │ │ └── plugin.c │ ├── libcamera │ │ ├── libcamera-device.cpp │ │ ├── libcamera-manager.cpp │ │ ├── libcamera-manager.hpp │ │ ├── libcamera-source.cpp │ │ ├── libcamera-utils.cpp │ │ ├── libcamera.c │ │ ├── libcamera.h │ │ └── meson.build │ ├── meson.build │ ├── support │ │ ├── cpu-arm.c │ │ ├── cpu-riscv.c │ │ ├── cpu-x86.c │ │ ├── cpu.c │ │ ├── dbus.c │ │ ├── evl-plugin.c │ │ ├── evl-system.c │ │ ├── journal.c │ │ ├── logger.c │ │ ├── loop.c │ │ ├── meson.build │ │ ├── node-driver.c │ │ ├── null-audio-sink.c │ │ ├── plugin.c │ │ └── system.c │ ├── test │ │ ├── fakesink.c │ │ ├── fakesrc.c │ │ ├── meson.build │ │ ├── plugin.c │ │ └── test-helper.h │ ├── v4l2 │ │ ├── meson.build │ │ ├── v4l2-device.c │ │ ├── v4l2-source.c │ │ ├── v4l2-udev.c │ │ ├── v4l2-utils.c │ │ ├── v4l2.c │ │ └── v4l2.h │ ├── videoconvert │ │ ├── meson.build │ │ ├── plugin.c │ │ ├── videoadapter.c │ │ ├── videoconvert-dummy.c │ │ └── videoconvert-ffmpeg.c │ ├── videotestsrc │ │ ├── draw.c │ │ ├── meson.build │ │ ├── plugin.c │ │ └── videotestsrc.c │ ├── volume │ │ ├── meson.build │ │ ├── plugin.c │ │ └── volume.c │ └── vulkan │ │ ├── dmabuf.h │ │ ├── dmabuf_fallback.c │ │ ├── dmabuf_linux.c │ │ ├── meson.build │ │ ├── pixel-formats.c │ │ ├── pixel-formats.h │ │ ├── plugin.c │ │ ├── shaders │ │ ├── disk-intersection.comp │ │ ├── filter-color.comp │ │ ├── filter.comp │ │ ├── filter.spv │ │ ├── main.comp │ │ └── main.spv │ │ ├── utils.c │ │ ├── utils.h │ │ ├── vulkan-blit-dsp-filter.c │ │ ├── vulkan-blit-filter.c │ │ ├── vulkan-blit-utils.c │ │ ├── vulkan-blit-utils.h │ │ ├── vulkan-compute-filter.c │ │ ├── vulkan-compute-source.c │ │ ├── vulkan-compute-utils.c │ │ ├── vulkan-compute-utils.h │ │ ├── vulkan-types.h │ │ ├── vulkan-utils.c │ │ └── vulkan-utils.h ├── tests │ ├── benchmark-dict.c │ ├── benchmark-pod.c │ ├── meson.build │ ├── spa-include-test-template.c │ └── stress-ringbuffer.c └── tools │ ├── meson.build │ ├── spa-inspect.c │ ├── spa-json-dump.c │ └── spa-monitor.c ├── src ├── daemon │ ├── client.conf.avail │ │ ├── 20-upmix.conf.in │ │ └── meson.build │ ├── client.conf.in │ ├── filter-chain.conf.in │ ├── filter-chain │ │ ├── 35-ebur128.conf │ │ ├── 36-dcblock.conf │ │ ├── demonic.conf │ │ ├── meson.build │ │ ├── sink-dolby-pro-logic-ii.conf │ │ ├── sink-dolby-surround.conf │ │ ├── sink-eq6.conf │ │ ├── sink-make-LFE.conf │ │ ├── sink-matrix-spatialiser.conf │ │ ├── sink-mix-FL-FR.conf │ │ ├── sink-upmix-5.1-filter.conf │ │ ├── sink-virtual-surround-5.1-kemar.conf │ │ ├── sink-virtual-surround-7.1-hesuvi.conf │ │ ├── source-duplicate-FL.conf │ │ ├── source-rnnoise.conf │ │ ├── spatializer-7.1.conf │ │ └── spatializer-single.conf │ ├── jack.conf.in │ ├── meson.build │ ├── minimal.conf.in │ ├── pipewire-aes67.conf.in │ ├── pipewire-avb.conf.in │ ├── pipewire-pulse.conf.avail │ │ ├── 20-upmix.conf.in │ │ └── meson.build │ ├── pipewire-pulse.conf.in │ ├── pipewire-vulkan.conf.in │ ├── pipewire.c │ ├── pipewire.conf.avail │ │ ├── 10-rates.conf.in │ │ ├── 20-upmix.conf.in │ │ ├── 50-raop.conf.in │ │ └── meson.build │ ├── pipewire.conf.in │ ├── pipewire.desktop.in │ └── systemd │ │ ├── meson.build │ │ ├── system │ │ ├── meson.build │ │ ├── pipewire-manager.socket │ │ ├── pipewire-pulse.service.in │ │ ├── pipewire-pulse.socket │ │ ├── pipewire.service.in │ │ └── pipewire.socket │ │ └── user │ │ ├── filter-chain.service.in │ │ ├── meson.build │ │ ├── pipewire-pulse.service.in │ │ ├── pipewire-pulse.socket │ │ ├── pipewire.service.in │ │ └── pipewire.socket ├── examples │ ├── audio-capture.c │ ├── audio-dsp-filter.c │ ├── audio-dsp-src.c │ ├── audio-src-ring.c │ ├── audio-src-ring2.c │ ├── audio-src.c │ ├── bluez-session.c │ ├── export-sink.c │ ├── export-source.c │ ├── export-spa-device.c │ ├── export-spa.c │ ├── gmain.c │ ├── internal.c │ ├── local-v4l2.c │ ├── meson.build │ ├── midi-src.c │ ├── sdl.h │ ├── video-dsp-play.c │ ├── video-dsp-src.c │ ├── video-play-fixate.c │ ├── video-play-pull.c │ ├── video-play-reneg.c │ ├── video-play.c │ ├── video-src-alloc.c │ ├── video-src-fixate.c │ ├── video-src-reneg.c │ └── video-src.c ├── gst │ ├── .editorconfig │ ├── gstpipewire.c │ ├── gstpipewireclock.c │ ├── gstpipewireclock.h │ ├── gstpipewirecore.c │ ├── gstpipewirecore.h │ ├── gstpipewiredeviceprovider.c │ ├── gstpipewiredeviceprovider.h │ ├── gstpipewireformat.c │ ├── gstpipewireformat.h │ ├── gstpipewirepool.c │ ├── gstpipewirepool.h │ ├── gstpipewiresink.c │ ├── gstpipewiresink.h │ ├── gstpipewiresrc.c │ ├── gstpipewiresrc.h │ ├── gstpipewirestream.c │ ├── gstpipewirestream.h │ └── meson.build ├── meson.build ├── modules │ ├── flatpak-utils.h │ ├── meson.build │ ├── module-access.c │ ├── module-adapter.c │ ├── module-adapter │ │ ├── adapter.c │ │ └── adapter.h │ ├── module-avb.c │ ├── module-avb │ │ ├── aaf.h │ │ ├── acmp.c │ │ ├── acmp.h │ │ ├── adp.c │ │ ├── adp.h │ │ ├── aecp-aem-descriptors.h │ │ ├── aecp-aem.c │ │ ├── aecp-aem.h │ │ ├── aecp.c │ │ ├── aecp.h │ │ ├── avb.c │ │ ├── avb.h │ │ ├── avdecc.c │ │ ├── descriptors.h │ │ ├── iec61883.h │ │ ├── internal.h │ │ ├── maap.c │ │ ├── maap.h │ │ ├── mmrp.c │ │ ├── mmrp.h │ │ ├── mrp.c │ │ ├── mrp.h │ │ ├── msrp.c │ │ ├── msrp.h │ │ ├── mvrp.c │ │ ├── mvrp.h │ │ ├── packets.h │ │ ├── srp.c │ │ ├── srp.h │ │ ├── stream.c │ │ ├── stream.h │ │ └── utils.h │ ├── module-client-device.c │ ├── module-client-device │ │ ├── client-device.h │ │ ├── protocol-native.c │ │ ├── proxy-device.c │ │ └── resource-device.c │ ├── module-client-node.c │ ├── module-client-node │ │ ├── client-node.c │ │ ├── client-node.h │ │ ├── protocol-native.c │ │ ├── remote-node.c │ │ └── v0 │ │ │ ├── client-node.c │ │ │ ├── client-node.h │ │ │ ├── ext-client-node.h │ │ │ ├── protocol-native.c │ │ │ ├── transport.c │ │ │ └── transport.h │ ├── module-combine-stream.c │ ├── module-echo-cancel.c │ ├── module-example-filter.c │ ├── module-example-sink.c │ ├── module-example-source.c │ ├── module-fallback-sink.c │ ├── module-ffado-driver.c │ ├── module-filter-chain.c │ ├── module-jack-tunnel.c │ ├── module-jack-tunnel │ │ └── weakjack.h │ ├── module-jackdbus-detect.c │ ├── module-link-factory.c │ ├── module-loopback.c │ ├── module-metadata.c │ ├── module-metadata │ │ ├── metadata.c │ │ ├── protocol-native.c │ │ └── proxy-metadata.c │ ├── module-netjack2-driver.c │ ├── module-netjack2-manager.c │ ├── module-netjack2 │ │ ├── packets.h │ │ └── peer.c │ ├── module-parametric-equalizer.c │ ├── module-pipe-tunnel.c │ ├── module-portal.c │ ├── module-profiler.c │ ├── module-profiler │ │ └── protocol-native.c │ ├── module-protocol-native.c │ ├── module-protocol-native │ │ ├── connection.c │ │ ├── connection.h │ │ ├── defs.h │ │ ├── local-socket.c │ │ ├── portal-screencast.c │ │ ├── protocol-footer.c │ │ ├── protocol-footer.h │ │ ├── protocol-native.c │ │ ├── security-context.c │ │ ├── test-connection.c │ │ └── v0 │ │ │ ├── interfaces.h │ │ │ ├── protocol-native.c │ │ │ └── typemap.h │ ├── module-protocol-pulse.c │ ├── module-protocol-pulse │ │ ├── client.c │ │ ├── client.h │ │ ├── cmd.c │ │ ├── cmd.h │ │ ├── collect.c │ │ ├── collect.h │ │ ├── commands.h │ │ ├── dbus-name.c │ │ ├── dbus-name.h │ │ ├── defs.h │ │ ├── extension.c │ │ ├── extension.h │ │ ├── format.c │ │ ├── format.h │ │ ├── internal.h │ │ ├── log.h │ │ ├── manager.c │ │ ├── manager.h │ │ ├── message-handler.c │ │ ├── message-handler.h │ │ ├── message.c │ │ ├── message.h │ │ ├── module.c │ │ ├── module.h │ │ ├── modules │ │ │ ├── module-alsa-sink.c │ │ │ ├── module-alsa-source.c │ │ │ ├── module-always-sink.c │ │ │ ├── module-combine-sink.c │ │ │ ├── module-device-manager.c │ │ │ ├── module-device-restore.c │ │ │ ├── module-echo-cancel.c │ │ │ ├── module-gsettings.c │ │ │ ├── module-jackdbus-detect.c │ │ │ ├── module-ladspa-sink.c │ │ │ ├── module-ladspa-source.c │ │ │ ├── module-loopback.c │ │ │ ├── module-native-protocol-tcp.c │ │ │ ├── module-null-sink.c │ │ │ ├── module-pipe-sink.c │ │ │ ├── module-pipe-source.c │ │ │ ├── module-raop-discover.c │ │ │ ├── module-remap-sink.c │ │ │ ├── module-remap-source.c │ │ │ ├── module-roc-sink-input.c │ │ │ ├── module-roc-sink.c │ │ │ ├── module-roc-source.c │ │ │ ├── module-rtp-recv.c │ │ │ ├── module-rtp-send.c │ │ │ ├── module-simple-protocol-tcp.c │ │ │ ├── module-stream-restore.c │ │ │ ├── module-switch-on-connect.c │ │ │ ├── module-tunnel-sink.c │ │ │ ├── module-tunnel-source.c │ │ │ ├── module-virtual-sink.c │ │ │ ├── module-virtual-source.c │ │ │ ├── module-x11-bell.c │ │ │ ├── module-zeroconf-discover.c │ │ │ ├── module-zeroconf-publish.c │ │ │ └── org.freedesktop.pulseaudio.gschema.xml │ │ ├── operation.c │ │ ├── operation.h │ │ ├── pending-sample.c │ │ ├── pending-sample.h │ │ ├── pulse-server.c │ │ ├── pulse-server.h │ │ ├── quirks.c │ │ ├── quirks.h │ │ ├── remap.c │ │ ├── remap.h │ │ ├── reply.c │ │ ├── reply.h │ │ ├── sample-play.c │ │ ├── sample-play.h │ │ ├── sample.c │ │ ├── sample.h │ │ ├── server.c │ │ ├── server.h │ │ ├── snap-policy.c │ │ ├── snap-policy.h │ │ ├── stream.c │ │ ├── stream.h │ │ ├── utils.c │ │ ├── utils.h │ │ ├── volume.c │ │ └── volume.h │ ├── module-protocol-simple.c │ ├── module-pulse-tunnel.c │ ├── module-raop-discover.c │ ├── module-raop-sink.c │ ├── module-raop │ │ ├── rtsp-client.c │ │ └── rtsp-client.h │ ├── module-roc-sink.c │ ├── module-roc-source.c │ ├── module-roc │ │ └── common.h │ ├── module-rt.c │ ├── module-rt │ │ ├── 20-pw-defaults.conf.in │ │ ├── 25-pw-rlimits.conf.in │ │ └── meson.build │ ├── module-rtp-sap.c │ ├── module-rtp-session.c │ ├── module-rtp-sink.c │ ├── module-rtp-source.c │ ├── module-rtp │ │ ├── apple-midi.h │ │ ├── audio.c │ │ ├── midi.c │ │ ├── opus.c │ │ ├── ptp.h │ │ ├── rtp.h │ │ ├── sap.h │ │ ├── stream.c │ │ └── stream.h │ ├── module-session-manager.c │ ├── module-session-manager │ │ ├── client-endpoint │ │ │ ├── client-endpoint.c │ │ │ ├── client-endpoint.h │ │ │ ├── endpoint-stream.c │ │ │ ├── endpoint-stream.h │ │ │ ├── endpoint.c │ │ │ └── endpoint.h │ │ ├── client-session │ │ │ ├── client-session.c │ │ │ ├── client-session.h │ │ │ ├── endpoint-link.c │ │ │ ├── endpoint-link.h │ │ │ ├── session.c │ │ │ └── session.h │ │ ├── endpoint-link.c │ │ ├── endpoint-stream.c │ │ ├── endpoint.c │ │ ├── protocol-native.c │ │ ├── proxy-session-manager.c │ │ └── session.c │ ├── module-snapcast-discover.c │ ├── module-spa-device-factory.c │ ├── module-spa-device.c │ ├── module-spa-node-factory.c │ ├── module-spa-node.c │ ├── module-vban-recv.c │ ├── module-vban-send.c │ ├── module-vban │ │ ├── audio.c │ │ ├── midi.c │ │ ├── stream.c │ │ ├── stream.h │ │ └── vban.h │ ├── module-x11-bell.c │ ├── module-zeroconf-discover.c │ ├── module-zeroconf-discover │ │ ├── avahi-poll.c │ │ └── avahi-poll.h │ ├── network-utils.h │ └── spa │ │ ├── spa-device.c │ │ ├── spa-device.h │ │ ├── spa-node.c │ │ └── spa-node.h ├── pipewire │ ├── array.h │ ├── buffers.c │ ├── buffers.h │ ├── client.h │ ├── conf.c │ ├── conf.h │ ├── context.c │ ├── context.h │ ├── control.c │ ├── control.h │ ├── core.c │ ├── core.h │ ├── data-loop.c │ ├── data-loop.h │ ├── device.h │ ├── extensions │ │ ├── client-node.h │ │ ├── meson.build │ │ ├── metadata.h │ │ ├── profiler.h │ │ ├── protocol-native.h │ │ ├── security-context.h │ │ ├── session-manager.h │ │ └── session-manager │ │ │ ├── impl-interfaces.h │ │ │ ├── interfaces.h │ │ │ ├── introspect-funcs.h │ │ │ ├── introspect.h │ │ │ └── keys.h │ ├── factory.h │ ├── filter.c │ ├── filter.h │ ├── global.c │ ├── global.h │ ├── i18n.h │ ├── impl-client.c │ ├── impl-client.h │ ├── impl-core.c │ ├── impl-core.h │ ├── impl-device.c │ ├── impl-device.h │ ├── impl-factory.c │ ├── impl-factory.h │ ├── impl-link.c │ ├── impl-link.h │ ├── impl-metadata.c │ ├── impl-metadata.h │ ├── impl-module.c │ ├── impl-module.h │ ├── impl-node.c │ ├── impl-node.h │ ├── impl-port.c │ ├── impl-port.h │ ├── impl.h │ ├── introspect.c │ ├── keys.h │ ├── link.h │ ├── log.c │ ├── log.h │ ├── loop.c │ ├── loop.h │ ├── main-loop.c │ ├── main-loop.h │ ├── map.h │ ├── mem.c │ ├── mem.h │ ├── meson.build │ ├── module.h │ ├── node.h │ ├── permission.h │ ├── pipewire.c │ ├── pipewire.h │ ├── port.h │ ├── private.h │ ├── properties.c │ ├── properties.h │ ├── protocol.c │ ├── protocol.h │ ├── proxy.c │ ├── proxy.h │ ├── resource.c │ ├── resource.h │ ├── settings.c │ ├── stream.c │ ├── stream.h │ ├── thread-loop.c │ ├── thread-loop.h │ ├── thread.c │ ├── thread.h │ ├── type.h │ ├── utils.c │ ├── utils.h │ ├── version.h.in │ ├── work-queue.c │ └── work-queue.h ├── tests │ ├── meson.build │ ├── test-cpp.cpp │ ├── test-endpoint.c │ ├── test-filter.c │ ├── test-interfaces.c │ ├── test-security-context.c │ └── test-stream.c └── tools │ ├── dfffile.c │ ├── dfffile.h │ ├── dsffile.c │ ├── dsffile.h │ ├── meson.build │ ├── midifile.c │ ├── midifile.h │ ├── pw-cat.c │ ├── pw-cli.c │ ├── pw-config.c │ ├── pw-container.c │ ├── pw-dot.c │ ├── pw-dump.c │ ├── pw-link.c │ ├── pw-loopback.c │ ├── pw-metadata.c │ ├── pw-mididump.c │ ├── pw-mon.c │ ├── pw-profiler.c │ ├── pw-reserve.c │ ├── pw-top.c │ ├── reserve.c │ └── reserve.h ├── subprojects ├── libcamera.wrap ├── media-session.wrap ├── webrtc-audio-processing.wrap └── wireplumber.wrap ├── template.test.in └── test ├── data └── test-spa-json.txt ├── meson.build ├── pwtest-compat.c ├── pwtest-implementation.h ├── pwtest.c ├── pwtest.h ├── test-array.c ├── test-client.c ├── test-config.c ├── test-context.c ├── test-example.c ├── test-functional.c ├── test-lib.c ├── test-logger.c ├── test-loop.c ├── test-map.c ├── test-properties.c ├── test-pwtest.c ├── test-spa-buffer.c ├── test-spa-control.c ├── test-spa-json.c ├── test-spa-log.c ├── test-spa-node.c ├── test-spa-pod.c ├── test-spa-utils.c ├── test-support.c └── test-utils.c /.codespell-ignore: -------------------------------------------------------------------------------- 1 | ba 2 | capela 3 | cas 4 | crasher 5 | datas 6 | endcode 7 | files' 8 | goin 9 | hda 10 | hist 11 | hve 12 | inport 13 | nd 14 | mmaped 15 | od 16 | ot 17 | parm 18 | sinc 19 | stdio 20 | uint -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = tab 6 | indent_size = 8 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | # Use 2 spaces for meson files 13 | [*.build] 14 | indent_style = space 15 | indent_size = 2 16 | 17 | [*.yml] 18 | indent_style = space 19 | indent_size = 2 20 | 21 | [*.{conf,conf.in}] 22 | indent_style = space 23 | indent_size = 4 24 | 25 | [*.{xml,xml.in}] 26 | indent_style = space 27 | indent_size = 2 28 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | test/data/*.txt diff 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .* 2 | !.gitlab 3 | ABOUT-NLS 4 | *~ 5 | *.tar.gz 6 | *.tar.xz 7 | *.o 8 | cscope.out 9 | cscope.in.out 10 | cscope.po.out 11 | Makefile 12 | subprojects/lua* 13 | subprojects/wireplumber 14 | subprojects/media-session 15 | subprojects/packagecache 16 | subprojects/googletest* 17 | subprojects/gtest.wrap 18 | subprojects/libyaml.wrap 19 | subprojects/libyaml 20 | subprojects/libcamera 21 | subprojects/webrtc-audio-processing 22 | 23 | # Created by https://www.gitignore.io/api/vim 24 | 25 | ### Vim ### 26 | # Swap 27 | [._]*.s[a-v][a-z] 28 | [._]*.sw[a-p] 29 | [._]s[a-rt-v][a-z] 30 | [._]ss[a-gi-z] 31 | [._]sw[a-p] 32 | 33 | # Session 34 | Session.vim 35 | 36 | # Temporary 37 | .netrwhist 38 | *~ 39 | # Auto-generated tag files 40 | tags 41 | # Persistent undo 42 | [._]*.un~ 43 | 44 | 45 | # End of https://www.gitignore.io/api/vim 46 | -------------------------------------------------------------------------------- /.gitlab/ci/check_missing_headers.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This script will tell you if there are headers in the source tree 4 | # that have not been installed in $PREFIX 5 | 6 | LIST="" 7 | 8 | for i in $(find spa/include -name '*.h' | sed s#spa/include/##); 9 | do 10 | [ -f "$PREFIX/include/spa-0.2/$i" ] || LIST="$i $LIST" 11 | done 12 | 13 | for i in $(find src/pipewire -name '*.h' -a -not -name '*private.h' | sed s#src/##); 14 | do 15 | [ -f "$PREFIX/include/pipewire-0.3/$i" ] || LIST="$i $LIST" 16 | done 17 | 18 | for i in $LIST; 19 | do 20 | echo "$i not installed" 21 | done 22 | 23 | if [ "$LIST" != "" ]; 24 | then 25 | exit 1 26 | fi 27 | 28 | exit 0 29 | -------------------------------------------------------------------------------- /.gitlab/issue_templates/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PipeWire/pipewire/0e8a8e9844ba2aeb34048ead76eb8b36b45147f6/.gitlab/issue_templates/.gitkeep -------------------------------------------------------------------------------- /.gitlab/issue_templates/bluetooth issue.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | - PipeWire version (`pipewire --version`): 6 | - Distribution and distribution version (`PRETTY_NAME` from `/etc/os-release`): 7 | - Desktop Environment: 8 | - Kernel version (`uname -r`): 9 | - BlueZ version (`bluetoothctl --version`): 10 | - `lsusb`: 11 | ``` 12 | # paste the output of "lsusb" here 13 | ``` 14 | - Bluetooth devices: 15 | 16 | ``` 17 | # paste the output of "bluetoothctl devices" here 18 | ``` 19 | 20 | ## Description of Problem: 21 | 22 | 23 | ## How Reproducible: 24 | 25 | 26 | ### Steps to Reproduce: 27 | 28 | 29 | 1. 30 | 2. 31 | 3. 32 | 33 | 34 | ### Actual Results: 35 | 36 | 37 | ### Expected Results: 38 | 39 | 40 | # Additional Info (as attachments): 41 | 42 | - `pw-dump > pw-dump.log`: 43 | - Bluetooth debug log, see [here](https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Troubleshooting#bluetooth): 44 | -------------------------------------------------------------------------------- /.gitlab/issue_templates/issue.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | - PipeWire version (`pipewire --version`): 4 | - Distribution and distribution version (`PRETTY_NAME` from `/etc/os-release`): 5 | - Desktop Environment: 6 | - Kernel version (`uname -r`): 7 | 8 | ## Description of Problem: 9 | 10 | 11 | ## How Reproducible: 12 | 13 | 14 | ### Steps to Reproduce: 15 | 16 | 1. 17 | 2. 18 | 3. 19 | 20 | 21 | ### Actual Results: 22 | 23 | 24 | ### Expected Results: 25 | 26 | 27 | # Additional Info (as attachments): 28 | 29 | - `pw-dump > pw-dump.log`: 30 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | Copyright © 2018 Wim Taymans 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a 4 | copy of this software and associated documentation files (the "Software"), 5 | to deal in the Software without restriction, including without limitation 6 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | and/or sell copies of the Software, and to permit persons to whom the 8 | Software is furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice (including the next 11 | paragraph) shall be included in all copies or substantial portions of the 12 | Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | DEALINGS IN THE SOFTWARE. 21 | 22 | --- 23 | 24 | The above is the version of the MIT "Expat" License used by X.org: 25 | 26 | http://cgit.freedesktop.org/xorg/xserver/tree/COPYING 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | All PipeWire source files are licensed under the MIT License. 2 | (see file COPYING for details) 3 | 4 | With the exception of: 5 | 6 | libspa-alsa.so in spa/plugins/alsa, which contains LGPL code from 7 | Pulseaudio and is thus licensed as LGPL. 8 | 9 | libjackserver.so which links against the GPL2 jack/control.h, which 10 | makes it GPL2 11 | 12 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Only there to make jhbuild happy 4 | 5 | if [ -z "$MESON" ]; then 6 | MESON=$(which meson) 7 | fi 8 | if [ -z "$MESON" ]; then 9 | echo "error: Meson not found." 10 | echo "Install meson to configure and build PipeWire. If meson" \ 11 | "is already installed, set the environment variable MESON" \ 12 | "to the binary's path." 13 | exit 1; 14 | fi 15 | 16 | mkdir -p builddir 17 | $MESON setup "$@" builddir # use 'autogen.sh --reconfigure' to update 18 | ln -sf builddir/Makefile Makefile 19 | -------------------------------------------------------------------------------- /cross-x86.txt: -------------------------------------------------------------------------------- 1 | [binaries] 2 | c = 'gcc' 3 | cpp = 'g++' 4 | ld = 'ld' 5 | cmake = 'cmake' 6 | strip = 'strip' 7 | pkg-config = 'pkg-config' 8 | 9 | [properties] 10 | pkg_config_libdir = '/usr/lib/pkgconfig' 11 | ld_args = '-m elf_i386' 12 | 13 | [built-in options] 14 | c_args = '-m32 -msse' 15 | c_link_args = '-m32 -msse' 16 | cpp_args = '-m32 -msse' 17 | cpp_link_args = '-m32 -msse' 18 | 19 | [host_machine] 20 | system = 'linux' 21 | cpu_family = 'x86' 22 | cpu = 'i686' 23 | endian = 'little' 24 | -------------------------------------------------------------------------------- /doc/dox/api/spa-design.dox: -------------------------------------------------------------------------------- 1 | /** \page page_spa_design SPA Design 2 | 3 | # Conventions 4 | 5 | ## Types 6 | 7 | Types are generally divided into two categories: 8 | 9 | - String types: They identify interfaces and highlevel object types. 10 | - Integer types: These are enumerations used in the parts where high 11 | performance/ease of use/low space overhead is needed. 12 | 13 | The SPA type is system is static and very simple but still allows you 14 | to make and introspect complex object type hierarchies. 15 | 16 | See the type system docs for more info. 17 | 18 | ## Error Codes 19 | 20 | SPA uses negative integers as errno style error codes. Functions that return an 21 | int result code generated an error when < 0. `spa_strerror()` can be used to 22 | get a string representation of the error code. 23 | 24 | SPA also has a way to encode asynchronous results. This is done by setting a 25 | high bit (bit 30, the `ASYNC_BIT`) in the result code and a sequence number 26 | in the lower bits. This result is normally identified as a positive success 27 | result code and the sequence number can later be matched to the completion 28 | event. 29 | 30 | ## Useful Macros 31 | 32 | SPA comes with some useful macros defined in `` and a 33 | number of utility functions, see \ref spa_utils. 34 | 35 | */ 36 | -------------------------------------------------------------------------------- /doc/dox/config/pipewire-filter-chain.conf.5.md: -------------------------------------------------------------------------------- 1 | \page page_man_pipewire-filter-chain_conf_5 filter-chain.conf 2 | 3 | PipeWire example configuration for running audio filters. 4 | 5 | \tableofcontents 6 | 7 | # SYNOPSIS 8 | 9 | *$XDG_CONFIG_HOME/pipewire/filter-chain.conf* 10 | 11 | *$(PIPEWIRE_CONFIG_DIR)/filter-chain.conf* 12 | 13 | *$(PIPEWIRE_CONFDATADIR)/filter-chain.conf* 14 | 15 | *$(PIPEWIRE_CONFDATADIR)/filter-chain.conf.d/* 16 | 17 | *$(PIPEWIRE_CONFIG_DIR)/filter-chain.conf.d/* 18 | 19 | *$XDG_CONFIG_HOME/pipewire/filter-chain.conf.d/* 20 | 21 | # DESCRIPTION 22 | 23 | When \ref page_man_pipewire_1 "pipewire(1)" is run using 24 | this configuration file, `pipewire -c filter-chain.conf`, 25 | it starts a PipeWire client application that publishes 26 | nodes that apply various audio filters to their input. 27 | 28 | It is a normal PipeWire client application in all respects. 29 | 30 | Drop-in configuration files `filter-chain.conf.d/*.conf` can be used 31 | to modify the filter configuration, see \ref pipewire_conf__drop-in_configuration_files "pipewire.conf(5)". 32 | Some examples are in *$(PIPEWIRE_CONFDATADIR)/filter-chain/* 33 | 34 | # AUTHORS 35 | 36 | The PipeWire Developers <$(PACKAGE_BUGREPORT)>; 37 | PipeWire is available from <$(PACKAGE_URL)> 38 | 39 | # SEE ALSO 40 | 41 | \ref page_man_pipewire_1 "pipewire(1)", 42 | \ref page_man_pipewire_conf_5 "pipewire.conf(5)" 43 | -------------------------------------------------------------------------------- /doc/dox/config/pipewire-pulse-modules.7.md: -------------------------------------------------------------------------------- 1 | \page page_man_pipewire-pulse-modules_7 pipewire-pulse-modules 2 | 3 | PipeWire Pulseaudio modules 4 | 5 | # DESCRIPTION 6 | 7 | \include{doc} pulse-modules.inc 8 | 9 | # BUILT-IN MODULES 10 | 11 | $(PIPEWIRE_PULSE_MODULES) 12 | 13 | # AUTHORS 14 | 15 | The PipeWire Developers <$(PACKAGE_BUGREPORT)>; 16 | PipeWire is available from <$(PACKAGE_URL)> 17 | 18 | # SEE ALSO 19 | 20 | \ref page_man_pipewire-pulse_1 "pipewire-pulse(1)" 21 | -------------------------------------------------------------------------------- /doc/dox/config/xref.md: -------------------------------------------------------------------------------- 1 | \page page_config_xref Index 2 | 3 | \ref page_man_pipewire_conf_5 "pipewire.conf" 4 | 5 | @SECREF@ pipewire.conf 6 | 7 | \ref page_man_pipewire-pulse_conf_5 "pipewire-pulse.conf" 8 | 9 | @SECREF@ pipewire-pulse.conf 10 | 11 | \ref page_man_pipewire-client_conf_5 "client.conf" 12 | 13 | @SECREF@ client.conf 14 | 15 | \ref page_man_pipewire-jack_conf_5 "jack.conf" 16 | 17 | @SECREF@ jack.conf 18 | 19 | **Runtime settings** 20 | 21 | @SECREF@ pipewire-settings 22 | 23 | **Environment variables** 24 | 25 | @SECREF@ pipewire-env client-env jack-env pulse-env 26 | 27 | **Object properties** 28 | 29 | @SECREF@ props 30 | 31 | **Monitor properties** 32 | 33 | @SECREF@ monitor-prop 34 | 35 | **Device properties** 36 | 37 | @SECREF@ device-prop 38 | 39 | **Node properties** 40 | 41 | @SECREF@ node-prop 42 | 43 | **Port properties** 44 | 45 | @SECREF@ port-prop 46 | 47 | **Client properties** 48 | 49 | @SECREF@ client-prop 50 | 51 | \see pw_keys in API documentation. 52 | -------------------------------------------------------------------------------- /doc/dox/internals/index.dox: -------------------------------------------------------------------------------- 1 | /** \page page_internals Internals 2 | 3 | # Internals 4 | 5 | - \subpage page_design 6 | - \subpage page_audio 7 | - \subpage page_access 8 | - \subpage page_portal 9 | - \subpage page_midi 10 | - \subpage page_objects_design 11 | - \subpage page_library 12 | - \subpage page_dma_buf 13 | - \subpage page_scheduling 14 | - \subpage page_latency 15 | - \subpage page_tag 16 | - \subpage page_native_protocol 17 | 18 | 19 | # Components 20 | 21 | - \subpage page_daemon 22 | - \subpage page_session_manager 23 | 24 | # Backends 25 | 26 | - \subpage page_pulseaudio 27 | 28 | */ 29 | -------------------------------------------------------------------------------- /doc/dox/programs/index.md: -------------------------------------------------------------------------------- 1 | \page page_programs Programs 2 | 3 | Manual pages: 4 | 5 | - \subpage page_man_pipewire_1 6 | - \subpage page_man_pipewire-pulse_1 7 | - \subpage page_man_pw-cat_1 8 | - \subpage page_man_pw-cli_1 9 | - \subpage page_man_pw-config_1 10 | - \subpage page_man_pw-container_1 11 | - \subpage page_man_pw-dot_1 12 | - \subpage page_man_pw-dump_1 13 | - \subpage page_man_pw-jack_1 14 | - \subpage page_man_pw-link_1 15 | - \subpage page_man_pw-loopback_1 16 | - \subpage page_man_pw-metadata_1 17 | - \subpage page_man_pw-mididump_1 18 | - \subpage page_man_pw-mon_1 19 | - \subpage page_man_pw-profiler_1 20 | - \subpage page_man_pw-reserve_1 21 | - \subpage page_man_pw-top_1 22 | - \subpage page_man_pw-v4l2_1 23 | - \subpage page_man_spa-acp-tool_1 24 | - \subpage page_man_spa-inspect_1 25 | - \subpage page_man_spa-json-dump_1 26 | - \subpage page_man_spa-monitor_1 27 | - \subpage page_man_spa-resample_1 28 | -------------------------------------------------------------------------------- /doc/dox/programs/pw-dot.1.md: -------------------------------------------------------------------------------- 1 | \page page_man_pw-dot_1 pw-dot 2 | 3 | The PipeWire dot graph dump 4 | 5 | # SYNOPSIS 6 | 7 | **pw-dot** \[*options*\] 8 | 9 | # DESCRIPTION 10 | 11 | Create a .dot file of the PipeWire graph. 12 | 13 | The .dot file can then be visualized with a tool like **dotty** or 14 | rendered to a PNG file with `dot -Tpng pw.dot -o pw.png`. 15 | 16 | # OPTIONS 17 | 18 | \par -r | \--remote=NAME 19 | The name the remote instance to connect to. If left unspecified, a 20 | connection is made to the default PipeWire instance. 21 | 22 | \par -h | \--help 23 | Show help. 24 | 25 | \par \--version 26 | Show version information. 27 | 28 | \par -a | \--all 29 | Show all object types. 30 | 31 | \par -s | \--smart 32 | Show linked objects only. 33 | 34 | \par -d | \--detail 35 | Show all object properties. 36 | 37 | \par -o FILE | \--output=FILE 38 | Output file name (Default pw.dot). Use - for stdout. 39 | 40 | \par -L | \--lr 41 | Lay the graph from left to right, instead of dot's default top to 42 | bottom. 43 | 44 | \par -9 | \--90 45 | Lay the graph using 90-degree angles in edges. 46 | 47 | # AUTHORS 48 | 49 | The PipeWire Developers <$(PACKAGE_BUGREPORT)>; 50 | PipeWire is available from <$(PACKAGE_URL)> 51 | 52 | # SEE ALSO 53 | 54 | \ref page_man_pipewire_1 "pipewire(1)", 55 | \ref page_man_pw-cli_1 "pw-cli(1)", 56 | \ref page_man_pw-mon_1 "pw-mon(1)", 57 | -------------------------------------------------------------------------------- /doc/dox/programs/pw-dump.1.md: -------------------------------------------------------------------------------- 1 | \page page_man_pw-dump_1 pw-dump 2 | 3 | The PipeWire state dumper 4 | 5 | # SYNOPSIS 6 | 7 | **pw-dump** \[*options*\] 8 | 9 | # DESCRIPTION 10 | 11 | The *pw-dump* program produces a representation of the current PipeWire 12 | state as JSON, including the information on nodes, devices, modules, 13 | ports, and other objects. 14 | 15 | # OPTIONS 16 | 17 | \par -h | \--help 18 | Show help. 19 | 20 | \par -r | \--remote=NAME 21 | The name of the *remote* instance to dump. If left unspecified, a 22 | connection is made to the default PipeWire instance. 23 | 24 | \par -m | \--monitor 25 | Monitor PipeWire state changes, and output JSON arrays describing 26 | changes. 27 | 28 | \par -N | \--no-colors 29 | Disable color output. 30 | 31 | \par -C | \--color=WHEN 32 | Whether to enable color support. WHEN is `never`, `always`, or `auto`. 33 | 34 | # AUTHORS 35 | 36 | The PipeWire Developers <$(PACKAGE_BUGREPORT)>; 37 | PipeWire is available from <$(PACKAGE_URL)> 38 | 39 | # SEE ALSO 40 | 41 | \ref page_man_pipewire_1 "pipewire(1)", 42 | \ref page_man_pw-cli_1 "pw-cli(1)", 43 | \ref page_man_pw-top_1 "pw-top(1)", 44 | -------------------------------------------------------------------------------- /doc/dox/programs/pw-jack.1.md: -------------------------------------------------------------------------------- 1 | \page page_man_pw-jack_1 pw-jack 2 | 3 | Use PipeWire instead of JACK 4 | 5 | # SYNOPSIS 6 | 7 | **pw-jack** \[*options*\] *COMMAND* \[*ARGUMENTS...*\] 8 | 9 | # DESCRIPTION 10 | 11 | **pw-jack** modifies the `LD_LIBRARY_PATH` environment variable so that 12 | applications will load PipeWire's reimplementation of the JACK client 13 | libraries instead of JACK's own libraries. This results in JACK clients 14 | being redirected to PipeWire. 15 | 16 | If PipeWire's reimplementation of the JACK client libraries has been 17 | installed as a system-wide replacement for JACK's own libraries, then 18 | the whole system already behaves in that way, in which case **pw-jack** 19 | has no practical effect. 20 | 21 | # OPTIONS 22 | 23 | \par -h 24 | Show help. 25 | 26 | \par -r NAME 27 | The name of the remote instance to connect to. If left unspecified, a 28 | connection is made to the default PipeWire instance. 29 | 30 | \par -v 31 | Verbose operation. 32 | 33 | # EXAMPLES 34 | 35 | \par pw-jack sndfile-jackplay /usr/share/sounds/freedesktop/stereo/bell.oga 36 | 37 | # AUTHORS 38 | 39 | The PipeWire Developers <$(PACKAGE_BUGREPORT)>; 40 | PipeWire is available from <$(PACKAGE_URL)> 41 | 42 | # SEE ALSO 43 | 44 | \ref page_man_pipewire_1 "pipewire(1)", 45 | **jackd(1)**, 46 | -------------------------------------------------------------------------------- /doc/dox/programs/pw-mididump.1.md: -------------------------------------------------------------------------------- 1 | \page page_man_pw-mididump_1 pw-mididump 2 | 3 | The PipeWire MIDI dump 4 | 5 | # SYNOPSIS 6 | 7 | **pw-mididump** \[*options*\] \[*FILE*\] 8 | 9 | # DESCRIPTION 10 | 11 | Dump MIDI messages to stdout. 12 | 13 | When a MIDI file is given, the events inside the file are printed. 14 | 15 | When no file is given, **pw-mididump** creates a PipeWire MIDI input 16 | stream and will print all MIDI events received on the port to stdout. 17 | 18 | # OPTIONS 19 | 20 | \par -r | \--remote=NAME 21 | The name the remote instance to monitor. If left unspecified, a 22 | connection is made to the default PipeWire instance. 23 | 24 | \par -h | \--help 25 | Show help. 26 | 27 | \par \--version 28 | Show version information. 29 | 30 | # AUTHORS 31 | 32 | The PipeWire Developers <$(PACKAGE_BUGREPORT)>; 33 | PipeWire is available from <$(PACKAGE_URL)> 34 | 35 | # SEE ALSO 36 | 37 | \ref page_man_pipewire_1 "pipewire(1)", 38 | \ref page_man_pw-cat_1 "pw-cat(1)" 39 | -------------------------------------------------------------------------------- /doc/dox/programs/pw-mon.1.md: -------------------------------------------------------------------------------- 1 | \page page_man_pw-mon_1 pw-mon 2 | 3 | The PipeWire monitor 4 | 5 | # SYNOPSIS 6 | 7 | **pw-mon** \[*options*\] 8 | 9 | # DESCRIPTION 10 | 11 | Monitor objects on the PipeWire instance. 12 | 13 | # OPTIONS 14 | 15 | \par -r | \--remote=NAME 16 | The name the *remote* instance to monitor. If left unspecified, a 17 | connection is made to the default PipeWire instance. 18 | 19 | \par -h | \--help 20 | Show help. 21 | 22 | \par \--version 23 | Show version information. 24 | 25 | \par -N | \--color=WHEN 26 | Whether to use color, one of 'never', 'always', or 'auto'. The default 27 | is 'auto'. **-N** is equivalent to **--color=never**. 28 | 29 | # AUTHORS 30 | 31 | The PipeWire Developers <$(PACKAGE_BUGREPORT)>; 32 | PipeWire is available from <$(PACKAGE_URL)> 33 | 34 | # SEE ALSO 35 | 36 | \ref page_man_pipewire_1 "pipewire(1)" 37 | -------------------------------------------------------------------------------- /doc/dox/programs/pw-profiler.1.md: -------------------------------------------------------------------------------- 1 | \page page_man_pw-profiler_1 pw-profiler 2 | 3 | The PipeWire profiler 4 | 5 | # SYNOPSIS 6 | 7 | **pw-profiler** \[*options*\] 8 | 9 | # DESCRIPTION 10 | 11 | Start profiling a PipeWire instance. 12 | 13 | If the server has the profiler module loaded, this program will connect 14 | to it and log the profiler data. Profiler data contains times and 15 | durations when processing nodes and devices started and completed. 16 | 17 | When this program is stopped, a set of **gnuplot** files and a script to 18 | generate SVG files from the .plot files is generated, along with a .html 19 | file to visualize the profiling results in a browser. 20 | 21 | This function uses the same data used by *pw-top*. 22 | 23 | # OPTIONS 24 | 25 | \par -r | \--remote=NAME 26 | The name the remote instance to monitor. If left unspecified, a 27 | connection is made to the default PipeWire instance. 28 | 29 | \par -h | \--help 30 | Show help. 31 | 32 | \par \--version 33 | Show version information. 34 | 35 | \par -o | \--output=FILE 36 | Profiler output name (default "profiler.log"). 37 | 38 | # AUTHORS 39 | 40 | The PipeWire Developers <$(PACKAGE_BUGREPORT)>; 41 | PipeWire is available from <$(PACKAGE_URL)> 42 | 43 | # SEE ALSO 44 | 45 | \ref page_man_pipewire_1 "pipewire(1)", 46 | \ref page_man_pw-top_1 "pw-top(1)" 47 | -------------------------------------------------------------------------------- /doc/dox/programs/pw-v4l2.1.md: -------------------------------------------------------------------------------- 1 | \page page_man_pw-v4l2_1 pw-v4l2 2 | 3 | Use PipeWire instead of V4L2 4 | 5 | # SYNOPSIS 6 | 7 | **pw-v4l2** \[*options*\] *COMMAND* \[*ARGUMENTS...*\] 8 | 9 | # DESCRIPTION 10 | 11 | **pw-v4l2** runs a command using a compatibility layer that maps PipeWire 12 | video devices to be visible to applications using V4L2. 13 | 14 | This is implemented by preloading a shared library via LD_PRELOAD, 15 | which translates library calls that try to access V4L2 devices. 16 | 17 | # OPTIONS 18 | 19 | \par -h 20 | Show help. 21 | 22 | \par -r NAME 23 | The name of the remote instance to connect to. If left unspecified, a 24 | connection is made to the default PipeWire instance. 25 | 26 | \par -v 27 | Verbose operation. 28 | 29 | # EXAMPLES 30 | 31 | **pw-v4l2** v4l2-ctl --list-devices 32 | 33 | # AUTHORS 34 | 35 | The PipeWire Developers <$(PACKAGE_BUGREPORT)>; 36 | PipeWire is available from <$(PACKAGE_URL)> 37 | 38 | # SEE ALSO 39 | 40 | \ref page_man_pipewire_1 "pipewire(1)", 41 | -------------------------------------------------------------------------------- /doc/dox/programs/spa-inspect.1.md: -------------------------------------------------------------------------------- 1 | \page page_man_spa-inspect_1 spa-inspect 2 | 3 | The PipeWire SPA plugin information utility 4 | 5 | # SYNOPSIS 6 | 7 | **spa-inspect** *FILE* 8 | 9 | # DESCRIPTION 10 | 11 | Displays information about a SPA plugin. 12 | 13 | Lists the SPA factories contained, and tries to instantiate them. 14 | 15 | # EXAMPLES 16 | 17 | **spa-inspect** $(SPA_PLUGINDIR)/bluez5/libspa-codec-bluez5-sbc.so 18 | 19 | Display information about a plugin. 20 | 21 | # AUTHORS 22 | 23 | The PipeWire Developers <$(PACKAGE_BUGREPORT)>; 24 | PipeWire is available from <$(PACKAGE_URL)> 25 | 26 | # SEE ALSO 27 | 28 | \ref page_man_pipewire_1 "pipewire(1)" 29 | -------------------------------------------------------------------------------- /doc/dox/programs/spa-json-dump.1.md: -------------------------------------------------------------------------------- 1 | \page page_man_spa-json-dump_1 spa-json-dump 2 | 3 | SPA JSON to JSON converter 4 | 5 | # SYNOPSIS 6 | 7 | **spa-json** *[FILE]* 8 | 9 | # DESCRIPTION 10 | 11 | Reads a SPA JSON file or stdin, and outputs it as standard JSON. 12 | 13 | # EXAMPLES 14 | 15 | **spa-json-dump** $(PIPEWIRE_CONFDATADIR)/pipewire.conf 16 | 17 | # AUTHORS 18 | 19 | The PipeWire Developers <$(PACKAGE_BUGREPORT)>; 20 | PipeWire is available from <$(PACKAGE_URL)> 21 | 22 | # SEE ALSO 23 | 24 | \ref page_man_pipewire_1 "pipewire(1)" 25 | -------------------------------------------------------------------------------- /doc/dox/programs/spa-monitor.1.md: -------------------------------------------------------------------------------- 1 | \page page_man_spa-monitor_1 spa-monitor 2 | 3 | The PipeWire SPA device debugging utility 4 | 5 | # SYNOPSIS 6 | 7 | **spa-monitor** *FILE* 8 | 9 | # DESCRIPTION 10 | 11 | Load a SPA plugin and instantiate a device from it. 12 | 13 | This is only useful for debugging device plugins. 14 | 15 | # EXAMPLES 16 | 17 | **spa-monitor** $(SPA_PLUGINDIR)/jack/libspa-jack.so 18 | 19 | # AUTHORS 20 | 21 | The PipeWire Developers <$(PACKAGE_BUGREPORT)>; 22 | PipeWire is available from <$(PACKAGE_URL)> 23 | 24 | # SEE ALSO 25 | 26 | \ref page_man_pipewire_1 "pipewire(1)" 27 | -------------------------------------------------------------------------------- /doc/dox/programs/spa-resample.1.md: -------------------------------------------------------------------------------- 1 | \page page_man_spa-resample_1 spa-resample 2 | 3 | The PipeWire resampler debugging utility 4 | 5 | # SYNOPSIS 6 | 7 | **spa-resample** \[*OPTIONS*\] *INFILE* *OUTFILE* 8 | 9 | # DESCRIPTION 10 | 11 | Use the PipeWire resampler to resample input file to output file, 12 | following the given options. 13 | 14 | This is useful only for testing the resampler. 15 | 16 | # OPTIONS 17 | 18 | \par -r RATE | \--rate=RATE 19 | Output sample rate. 20 | 21 | \par -f FORMAT | \--format=FORMAT 22 | Output sample format (s8 | s16 | s32 | f32 | f64). 23 | 24 | \par -q QUALITY | \--quality=QUALITY 25 | Resampler output quality (0-14). 26 | 27 | \par -c FLAGS | \--cpuflags=FLAGS 28 | See \ref spa_cpu "spa/support/cpu.h". 29 | 30 | \par -h 31 | Show help. 32 | 33 | \par -v 34 | Verbose operation. 35 | 36 | # EXAMPLES 37 | 38 | **spa-resample** -r 48000 -f s32 in.wav out.wav 39 | 40 | # AUTHORS 41 | 42 | The PipeWire Developers <$(PACKAGE_BUGREPORT)>; 43 | PipeWire is available from <$(PACKAGE_URL)> 44 | 45 | # SEE ALSO 46 | 47 | \ref page_man_pipewire_1 "pipewire(1)" 48 | -------------------------------------------------------------------------------- /doc/dox/tutorial/index.dox: -------------------------------------------------------------------------------- 1 | /** \page page_tutorial API Tutorial 2 | 3 | Welcome to the PipeWire API tutorial. The goal is to learn 4 | PipeWire API step-by-step with simple short examples. 5 | 6 | - \subpage page_tutorial1 7 | - \subpage page_tutorial2 8 | - \subpage page_tutorial3 9 | - \subpage page_tutorial4 10 | - \subpage page_tutorial5 11 | - \subpage page_tutorial6 12 | 13 | 14 | # More Example Programs 15 | 16 | - \ref audio-src.c "": \snippet{doc} audio-src.c title 17 | - \ref audio-dsp-filter.c "": \snippet{doc} audio-dsp-filter.c title 18 | - \ref video-play.c "": \snippet{doc} video-play.c title 19 | - \subpage page_examples 20 | 21 | */ 22 | -------------------------------------------------------------------------------- /doc/examples.dox.in: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | \page page_examples List of example programs 4 | 5 | @example_ref@ 6 | 7 | @example_doxygen@ 8 | 9 | */ 10 | -------------------------------------------------------------------------------- /doc/examples/tutorial1.c: -------------------------------------------------------------------------------- 1 | /* 2 | [title] 3 | \ref page_tutorial1 4 | [title] 5 | */ 6 | /* [code] */ 7 | #include 8 | 9 | int main(int argc, char *argv[]) 10 | { 11 | pw_init(&argc, &argv); 12 | 13 | fprintf(stdout, "Compiled with libpipewire %s\n" 14 | "Linked with libpipewire %s\n", 15 | pw_get_headers_version(), 16 | pw_get_library_version()); 17 | return 0; 18 | } 19 | /* [code] */ 20 | -------------------------------------------------------------------------------- /pipewire-alsa/alsa-plugins/meson.build: -------------------------------------------------------------------------------- 1 | pipewire_alsa_plugin_pcm_sources = [ 2 | 'pcm_pipewire.c', 3 | ] 4 | pipewire_alsa_plugin_ctl_sources = [ 5 | 'ctl_pipewire.c', 6 | ] 7 | 8 | pipewire_alsa_plugin_c_args = [ 9 | '-DPIC', 10 | ] 11 | 12 | pipewire_alsa_pcm_plugin = shared_library('asound_module_pcm_pipewire', 13 | pipewire_alsa_plugin_pcm_sources, 14 | c_args : pipewire_alsa_plugin_c_args, 15 | include_directories : [configinc], 16 | dependencies : [pipewire_dep, alsa_dep], 17 | install : true, 18 | install_dir : pipewire_libdir / 'alsa-lib', 19 | ) 20 | pipewire_alsa_ctl_plugin = shared_library('asound_module_ctl_pipewire', 21 | pipewire_alsa_plugin_ctl_sources, 22 | c_args : pipewire_alsa_plugin_c_args, 23 | include_directories : [configinc], 24 | dependencies : [pipewire_dep, alsa_dep, mathlib], 25 | install : true, 26 | install_dir : pipewire_libdir / 'alsa-lib', 27 | ) 28 | -------------------------------------------------------------------------------- /pipewire-alsa/conf/99-pipewire-default.conf: -------------------------------------------------------------------------------- 1 | pcm.!default { 2 | type pipewire 3 | playback_node "-1" 4 | capture_node "-1" 5 | hint { 6 | show on 7 | description "Default ALSA Output (currently PipeWire Media Server)" 8 | } 9 | } 10 | 11 | ctl.!default { 12 | type pipewire 13 | } 14 | -------------------------------------------------------------------------------- /pipewire-alsa/conf/meson.build: -------------------------------------------------------------------------------- 1 | alsaconfdir = pipewire_datadir / 'alsa' / 'alsa.conf.d' 2 | 3 | install_data(['50-pipewire.conf', '99-pipewire-default.conf'], 4 | install_dir: alsaconfdir, 5 | ) 6 | -------------------------------------------------------------------------------- /pipewire-alsa/tests/meson.build: -------------------------------------------------------------------------------- 1 | test_apps = [ 2 | [ 'test-pipewire-alsa-stress', [alsa_dep, pthread_lib] ], 3 | ] 4 | 5 | foreach a : test_apps 6 | executable('pw-' + a[0], a[0] + '.c', 7 | dependencies : a[1], 8 | include_directories: [includes_inc], 9 | install : installed_tests_enabled, 10 | install_dir : installed_tests_execdir 11 | ) 12 | 13 | if installed_tests_enabled 14 | test_conf = configuration_data() 15 | test_conf.set('exec', installed_tests_execdir / 'pw-' + a[0]) 16 | configure_file( 17 | input: installed_tests_template, 18 | output: 'pw-' + a[0] + '.test', 19 | install_dir: installed_tests_metadir, 20 | configuration: test_conf 21 | ) 22 | endif 23 | endforeach 24 | -------------------------------------------------------------------------------- /pipewire-jack/meson.build: -------------------------------------------------------------------------------- 1 | jack_inc = include_directories('.') 2 | if get_option('jack-devel') == true 3 | install_subdir('jack', install_dir: get_option('includedir'), strip_directory: false) 4 | endif 5 | subdir('src') 6 | -------------------------------------------------------------------------------- /pipewire-jack/src/dummy.c: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2020 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include "config.h" 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | static void reg(void) __attribute__ ((constructor)); 16 | static void reg(void) 17 | { 18 | pw_init(NULL, NULL); 19 | } 20 | -------------------------------------------------------------------------------- /pipewire-jack/src/export.c: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2020 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include 6 | 7 | #define JACK_METADATA_PREFIX "http://jackaudio.org/metadata/" 8 | SPA_EXPORT const char *JACK_METADATA_CONNECTED = JACK_METADATA_PREFIX "connected"; 9 | SPA_EXPORT const char *JACK_METADATA_EVENT_TYPES = JACK_METADATA_PREFIX "event-types"; 10 | SPA_EXPORT const char *JACK_METADATA_HARDWARE = JACK_METADATA_PREFIX "hardware"; 11 | SPA_EXPORT const char *JACK_METADATA_ICON_LARGE = JACK_METADATA_PREFIX "icon-large"; 12 | SPA_EXPORT const char *JACK_METADATA_ICON_NAME = JACK_METADATA_PREFIX "icon-name"; 13 | SPA_EXPORT const char *JACK_METADATA_ICON_SMALL = JACK_METADATA_PREFIX "icon-small"; 14 | SPA_EXPORT const char *JACK_METADATA_ORDER = JACK_METADATA_PREFIX "order"; 15 | SPA_EXPORT const char *JACK_METADATA_PORT_GROUP = JACK_METADATA_PREFIX "port-group"; 16 | SPA_EXPORT const char *JACK_METADATA_PRETTY_NAME = JACK_METADATA_PREFIX "pretty-name"; 17 | SPA_EXPORT const char *JACK_METADATA_SIGNAL_TYPE = JACK_METADATA_PREFIX "signal-type"; 18 | #undef JACK_METADATA_PREFIX 19 | -------------------------------------------------------------------------------- /pipewire-jack/src/pipewire-jack-extensions.h: -------------------------------------------------------------------------------- 1 | /* PipeWire JACK extensions */ 2 | /* SPDX-FileCopyrightText: Copyright © 2020 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef PIPEWIRE_JACK_EXTENSIONS_H 6 | #define PIPEWIRE_JACK_EXTENSIONS_H 7 | #include 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | /** 1.0 gamma, full range HDR 0.0 -> 1.0, pre-multiplied 14 | * alpha, BT.2020 primaries, progressive */ 15 | #define JACK_DEFAULT_VIDEO_TYPE "32 bit float RGBA video" 16 | 17 | typedef struct jack_image_size { 18 | uint32_t width; 19 | uint32_t height; 20 | uint32_t stride; 21 | uint32_t flags; 22 | } jack_image_size_t; 23 | 24 | int jack_get_video_image_size(jack_client_t *client, jack_image_size_t *size); 25 | 26 | int jack_set_sample_rate (jack_client_t *client, jack_nframes_t nframes); 27 | 28 | /* raw OSC message */ 29 | #define JACK_DEFAULT_OSC_TYPE "8 bit raw OSC" 30 | 31 | /* MIDI 2.0 UMP type. This contains raw UMP data, which can have MIDI 1.0 or 32 | * MIDI 2.0 packets. The data is an array of 32 bit ints. */ 33 | #define JACK_DEFAULT_UMP_TYPE "32 bit raw UMP" 34 | 35 | #ifdef __cplusplus 36 | } 37 | #endif 38 | 39 | #endif /* PIPEWIRE_JACK_EXTENSIONS_H */ 40 | -------------------------------------------------------------------------------- /pipewire-jack/src/statistics.c: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include 6 | 7 | SPA_EXPORT 8 | float jack_get_max_delayed_usecs (jack_client_t *client) 9 | { 10 | struct client *c = (struct client *) client; 11 | float res = 0.0f; 12 | 13 | spa_return_val_if_fail(c != NULL, 0.0); 14 | 15 | if (c->driver_activation) 16 | res = (float)c->driver_activation->max_delay / SPA_USEC_PER_SEC; 17 | 18 | pw_log_trace("%p: max delay %f", client, res); 19 | return res; 20 | } 21 | 22 | SPA_EXPORT 23 | float jack_get_xrun_delayed_usecs (jack_client_t *client) 24 | { 25 | struct client *c = (struct client *) client; 26 | float res = 0.0f; 27 | 28 | spa_return_val_if_fail(c != NULL, 0.0); 29 | 30 | if (c->driver_activation) 31 | res = (float)c->driver_activation->xrun_delay / SPA_USEC_PER_SEC; 32 | 33 | pw_log_trace("%p: xrun delay %f", client, res); 34 | return res; 35 | } 36 | 37 | SPA_EXPORT 38 | void jack_reset_max_delayed_usecs (jack_client_t *client) 39 | { 40 | struct client *c = (struct client *) client; 41 | 42 | spa_return_if_fail(c != NULL); 43 | 44 | if (c->driver_activation) 45 | c->driver_activation->max_delay = 0; 46 | } 47 | -------------------------------------------------------------------------------- /pipewire-v4l2/meson.build: -------------------------------------------------------------------------------- 1 | subdir('src') 2 | -------------------------------------------------------------------------------- /pipewire-v4l2/src/pipewire-v4l2.h: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2021 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include 6 | #include 7 | 8 | struct fops { 9 | int (*openat)(int dirfd, const char *path, int oflag, mode_t mode); 10 | int (*dup)(int oldfd); 11 | int (*close)(int fd); 12 | int (*ioctl)(int fd, unsigned long request, void *arg); 13 | void *(*mmap)(void *addr, size_t length, int prot, 14 | int flags, int fd, off64_t offset); 15 | int (*munmap)(void *addr, size_t length); 16 | }; 17 | 18 | const struct fops *get_fops(void); 19 | -------------------------------------------------------------------------------- /pipewire-v4l2/src/pw-v4l2.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This file is part of PipeWire. 4 | # SPDX-FileCopyrightText: Copyright © 2021 Wim Taymans 5 | # SPDX-License-Identifier: MIT 6 | 7 | while getopts 'hr:vs:p:' param ; do 8 | case $param in 9 | r) 10 | PIPEWIRE_REMOTE="$OPTARG" 11 | export PIPEWIRE_REMOTE 12 | ;; 13 | v) 14 | if [ -z "$PIPEWIRE_DEBUG" ]; then 15 | PIPEWIRE_DEBUG=3 16 | else 17 | PIPEWIRE_DEBUG=$(( PIPEWIRE_DEBUG + 1 )) 18 | fi 19 | export PIPEWIRE_DEBUG 20 | ;; 21 | *) 22 | echo "$0 - run v4l2 applications on PipeWire" 23 | echo " " 24 | echo "$0 [options] application [arguments]" 25 | echo " " 26 | echo "options:" 27 | echo " -h show brief help" 28 | echo " -r remote daemon name" 29 | echo " -v verbose debug info" 30 | exit 0 31 | ;; 32 | esac 33 | done 34 | 35 | shift $(( OPTIND - 1 )) 36 | 37 | if [ "$PW_UNINSTALLED" = 1 ] ; then 38 | PW_V4L2_LD_PRELOAD="$PW_BUILDDIR"'/pipewire-v4l2/src/libpw-v4l2.so' 39 | else 40 | # shellcheck disable=SC2016 # ${LIB} is interpreted by ld.so, not the shell 41 | PW_V4L2_LD_PRELOAD='@LIBV4L2_PATH@/libpw-v4l2.so' 42 | fi 43 | 44 | if [ "$LD_PRELOAD" = "" ] ; then 45 | LD_PRELOAD="$PW_V4L2_LD_PRELOAD" 46 | else 47 | LD_PRELOAD="$LD_PRELOAD $PW_V4L2_LD_PRELOAD" 48 | fi 49 | 50 | export LD_PRELOAD 51 | 52 | exec "$@" 53 | -------------------------------------------------------------------------------- /po/LINGUAS: -------------------------------------------------------------------------------- 1 | af 2 | as 3 | be 4 | bg 5 | bn_IN 6 | ca 7 | cs 8 | da 9 | de_CH 10 | de 11 | el 12 | es 13 | fi 14 | fr 15 | gl 16 | gu 17 | he 18 | hi 19 | hr 20 | hu 21 | id 22 | it 23 | ja 24 | ka 25 | kk 26 | kn 27 | ko 28 | lt 29 | ml 30 | mr 31 | my 32 | nl 33 | nn 34 | oc 35 | or 36 | pa 37 | pl 38 | pt_BR 39 | pt 40 | ro 41 | ru 42 | sk 43 | sl 44 | sr@latin 45 | sr 46 | sv 47 | ta 48 | te 49 | tr 50 | uk 51 | zh_CN 52 | zh_TW 53 | eo 54 | si 55 | -------------------------------------------------------------------------------- /po/POTFILES.in: -------------------------------------------------------------------------------- 1 | src/daemon/pipewire.c 2 | src/daemon/pipewire.desktop.in 3 | src/modules/module-protocol-pulse/modules/module-tunnel-sink.c 4 | src/modules/module-protocol-pulse/modules/module-tunnel-source.c 5 | src/modules/module-fallback-sink.c 6 | src/modules/module-pulse-tunnel.c 7 | src/modules/module-zeroconf-discover.c 8 | src/tools/pw-cat.c 9 | src/tools/pw-cat.c 10 | src/tools/pw-cli.c 11 | src/tools/pw-dot.c 12 | src/tools/pw-dump.c 13 | src/tools/pw-link.c 14 | src/tools/pw-loopback.c 15 | src/tools/pw-metadata.c 16 | src/tools/pw-mididump.c 17 | src/tools/pw-mon.c 18 | src/tools/pw-profiler.c 19 | src/tools/pw-top.c 20 | spa/plugins/alsa/acp/acp.c 21 | spa/plugins/alsa/acp/alsa-mixer.c 22 | spa/plugins/alsa/acp/alsa-util.c 23 | spa/plugins/alsa/acp/channelmap.h 24 | spa/plugins/alsa/acp/compat.c 25 | spa/plugins/bluez5/bluez5-device.c 26 | -------------------------------------------------------------------------------- /po/POTFILES.skip: -------------------------------------------------------------------------------- 1 | src/daemon/systemd/system/pipewire-pulse.service.in 2 | src/daemon/systemd/system/pipewire.service.in 3 | -------------------------------------------------------------------------------- /po/meson.build: -------------------------------------------------------------------------------- 1 | i18n = import('i18n') 2 | 3 | i18n.gettext( 4 | meson.project_name(), 5 | preset: 'glib', 6 | # Page width is set to 90 characters in order to avoid bad wrapping of the 7 | # bug reporting address. 8 | args: ['--msgid-bugs-address=https://gitlab.freedesktop.org/pipewire/pipewire/issues/new', 9 | '--width=90'], 10 | ) 11 | 12 | po_dir = meson.current_source_dir() 13 | -------------------------------------------------------------------------------- /spa/examples/meson.build: -------------------------------------------------------------------------------- 1 | # Examples, in order from simple to complicated 2 | spa_examples = [ 3 | 'adapter-control', 4 | 'example-control', 5 | 'local-libcamera', 6 | 'local-v4l2', 7 | 'local-videotestsrc', 8 | ] 9 | 10 | if not get_option('examples').allowed() or not get_option('spa-plugins').allowed() 11 | subdir_done() 12 | endif 13 | 14 | spa_examples_extra_deps = { 15 | 'local-v4l2': [sdl_dep], 16 | 'local-videotestsrc': [sdl_dep], 17 | 'local-libcamera': [sdl_dep, libcamera_dep], 18 | } 19 | 20 | foreach c : spa_examples 21 | deps = spa_examples_extra_deps.get(c, []) 22 | 23 | found = true 24 | foreach dep : deps 25 | found = found and dep.found() 26 | endforeach 27 | 28 | if found 29 | executable( 30 | c, 31 | c + '.c', 32 | include_directories : [configinc], 33 | dependencies : [spa_dep, dl_lib, pthread_lib, mathlib] + deps, 34 | install : installed_tests_enabled, 35 | install_dir : installed_tests_execdir / 'examples' / 'spa' 36 | ) 37 | endif 38 | endforeach 39 | -------------------------------------------------------------------------------- /spa/include/meson.build: -------------------------------------------------------------------------------- 1 | spa_sections = [ 2 | 'buffer', 3 | 'control', 4 | 'debug', 5 | 'graph', 6 | 'interfaces', 7 | 'monitor', 8 | 'node', 9 | 'param', 10 | 'pod', 11 | 'support', 12 | 'utils', 13 | ] 14 | 15 | spa_headers = 'spa' # used by doxygen 16 | install_subdir('spa', 17 | install_dir : get_option('includedir') / spa_name, 18 | ) 19 | -------------------------------------------------------------------------------- /spa/include/spa/control/control.h: -------------------------------------------------------------------------------- 1 | /* Simple Plugin API */ 2 | /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_CONTROL_H 6 | #define SPA_CONTROL_H 7 | 8 | #include 9 | #include 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | /** \defgroup spa_control Control 16 | * Control type declarations 17 | */ 18 | 19 | /** 20 | * \addtogroup spa_control 21 | * \{ 22 | */ 23 | 24 | /** Different Control types */ 25 | enum spa_control_type { 26 | SPA_CONTROL_Invalid, 27 | SPA_CONTROL_Properties, /**< SPA_TYPE_OBJECT_Props */ 28 | SPA_CONTROL_Midi, /**< spa_pod_bytes with raw midi data (deprecated, use SPA_CONTROL_UMP) */ 29 | SPA_CONTROL_OSC, /**< spa_pod_bytes with an OSC packet */ 30 | SPA_CONTROL_UMP, /**< spa_pod_bytes with raw UMP (universal MIDI packet) 31 | * data. The UMP 32 bit words are stored in native endian 32 | * format. */ 33 | 34 | _SPA_CONTROL_LAST, /**< not part of ABI */ 35 | }; 36 | 37 | /** 38 | * \} 39 | */ 40 | 41 | #ifdef __cplusplus 42 | } /* extern "C" */ 43 | #endif 44 | 45 | #endif /* SPA_CONTROL_H */ 46 | -------------------------------------------------------------------------------- /spa/include/spa/control/type-info.h: -------------------------------------------------------------------------------- 1 | /* Simple Plugin API */ 2 | /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_CONTROL_TYPES_H 6 | #define SPA_CONTROL_TYPES_H 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | /** 17 | * \addtogroup spa_control 18 | * \{ 19 | */ 20 | 21 | /* base for parameter object enumerations */ 22 | #define SPA_TYPE_INFO_Control SPA_TYPE_INFO_ENUM_BASE "Control" 23 | #define SPA_TYPE_INFO_CONTROL_BASE SPA_TYPE_INFO_Control ":" 24 | 25 | static const struct spa_type_info spa_type_control[] = { 26 | { SPA_CONTROL_Invalid, SPA_TYPE_Int, SPA_TYPE_INFO_CONTROL_BASE "Invalid", NULL }, 27 | { SPA_CONTROL_Properties, SPA_TYPE_Int, SPA_TYPE_INFO_CONTROL_BASE "Properties", NULL }, 28 | { SPA_CONTROL_Midi, SPA_TYPE_Int, SPA_TYPE_INFO_CONTROL_BASE "Midi", NULL }, 29 | { SPA_CONTROL_OSC, SPA_TYPE_Int, SPA_TYPE_INFO_CONTROL_BASE "OSC", NULL }, 30 | { SPA_CONTROL_UMP, SPA_TYPE_Int, SPA_TYPE_INFO_CONTROL_BASE "UMP", NULL }, 31 | { 0, 0, NULL, NULL }, 32 | }; 33 | 34 | /** 35 | * \} 36 | */ 37 | 38 | #ifdef __cplusplus 39 | } /* extern "C" */ 40 | #endif 41 | 42 | #endif /* SPA_CONTROL_TYPES_H */ 43 | -------------------------------------------------------------------------------- /spa/include/spa/debug/dict.h: -------------------------------------------------------------------------------- 1 | /* Simple Plugin API */ 2 | /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_DEBUG_DICT_H 6 | #define SPA_DEBUG_DICT_H 7 | 8 | #include 9 | #include 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | /** 16 | * \addtogroup spa_debug 17 | * \{ 18 | */ 19 | 20 | #ifndef SPA_API_DEBUG_DICT 21 | #ifdef SPA_API_IMPL 22 | #define SPA_API_DEBUG_DICT SPA_API_IMPL 23 | #else 24 | #define SPA_API_DEBUG_DICT static inline 25 | #endif 26 | #endif 27 | 28 | SPA_API_DEBUG_DICT int spa_debugc_dict(struct spa_debug_context *ctx, int indent, const struct spa_dict *dict) 29 | { 30 | const struct spa_dict_item *item; 31 | spa_debugc(ctx, "%*sflags:%08x n_items:%d", indent, "", dict->flags, dict->n_items); 32 | spa_dict_for_each(item, dict) { 33 | spa_debugc(ctx, "%*s %s = \"%s\"", indent, "", item->key, item->value); 34 | } 35 | return 0; 36 | } 37 | 38 | SPA_API_DEBUG_DICT int spa_debug_dict(int indent, const struct spa_dict *dict) 39 | { 40 | return spa_debugc_dict(NULL, indent, dict); 41 | } 42 | /** 43 | * \} 44 | */ 45 | 46 | #ifdef __cplusplus 47 | } /* extern "C" */ 48 | #endif 49 | 50 | #endif /* SPA_DEBUG_DICT_H */ 51 | -------------------------------------------------------------------------------- /spa/include/spa/monitor/event.h: -------------------------------------------------------------------------------- 1 | /* Simple Plugin API */ 2 | /* SPDX-FileCopyrightText: Copyright © 2020 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_EVENT_DEVICE_H 6 | #define SPA_EVENT_DEVICE_H 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | /** 15 | * \addtogroup spa_device 16 | * \{ 17 | */ 18 | 19 | /* object id of SPA_TYPE_EVENT_Device */ 20 | enum spa_device_event { 21 | SPA_DEVICE_EVENT_ObjectConfig, 22 | }; 23 | 24 | #define SPA_DEVICE_EVENT_ID(ev) SPA_EVENT_ID(ev, SPA_TYPE_EVENT_Device) 25 | #define SPA_DEVICE_EVENT_INIT(id) SPA_EVENT_INIT(SPA_TYPE_EVENT_Device, id) 26 | 27 | /* properties for SPA_TYPE_EVENT_Device */ 28 | enum spa_event_device { 29 | SPA_EVENT_DEVICE_START, 30 | 31 | SPA_EVENT_DEVICE_Object, /* an object id (Int) */ 32 | SPA_EVENT_DEVICE_Props, /* properties for an object (SPA_TYPE_OBJECT_Props) */ 33 | }; 34 | 35 | /** 36 | * \} 37 | */ 38 | 39 | #ifdef __cplusplus 40 | } /* extern "C" */ 41 | #endif 42 | 43 | #endif /* SPA_EVENT_DEVICE */ 44 | -------------------------------------------------------------------------------- /spa/include/spa/node/event.h: -------------------------------------------------------------------------------- 1 | /* Simple Plugin API */ 2 | /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_EVENT_NODE_H 6 | #define SPA_EVENT_NODE_H 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | /** 15 | * \addtogroup spa_node 16 | * \{ 17 | */ 18 | 19 | /* object id of SPA_TYPE_EVENT_Node */ 20 | enum spa_node_event { 21 | SPA_NODE_EVENT_Error, 22 | SPA_NODE_EVENT_Buffering, 23 | SPA_NODE_EVENT_RequestRefresh, 24 | SPA_NODE_EVENT_RequestProcess, /*< Ask the driver to start processing 25 | * the graph */ 26 | SPA_NODE_EVENT_User, /* User defined event */ 27 | }; 28 | 29 | #define SPA_NODE_EVENT_ID(ev) SPA_EVENT_ID(ev, SPA_TYPE_EVENT_Node) 30 | #define SPA_NODE_EVENT_INIT(id) SPA_EVENT_INIT(SPA_TYPE_EVENT_Node, id) 31 | 32 | /* properties for SPA_TYPE_EVENT_Node */ 33 | enum spa_event_node { 34 | SPA_EVENT_NODE_START, 35 | 36 | SPA_EVENT_NODE_START_User = 0x1000, 37 | SPA_EVENT_NODE_extra, /** extra info (String) */ 38 | 39 | SPA_EVENT_NODE_START_CUSTOM = 0x1000000, 40 | }; 41 | 42 | /** 43 | * \} 44 | */ 45 | 46 | #ifdef __cplusplus 47 | } /* extern "C" */ 48 | #endif 49 | 50 | #endif /* SPA_EVENT_NODE_H */ 51 | -------------------------------------------------------------------------------- /spa/include/spa/param/audio/ac3.h: -------------------------------------------------------------------------------- 1 | /* Simple Plugin API */ 2 | /* SPDX-FileCopyrightText: Copyright © 2025 Carlos Rafael Giani */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_AUDIO_AC3_H 6 | #define SPA_AUDIO_AC3_H 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | /** 15 | * \addtogroup spa_param 16 | * \{ 17 | */ 18 | 19 | /** Dolby AC-3 audio info. */ 20 | struct spa_audio_info_ac3 { 21 | uint32_t rate; /*< sample rate */ 22 | uint32_t channels; /*< number of channels */ 23 | }; 24 | 25 | #define SPA_AUDIO_INFO_AC3_INIT(...) ((struct spa_audio_info_ac3) { __VA_ARGS__ }) 26 | 27 | /** 28 | * \} 29 | */ 30 | 31 | #ifdef __cplusplus 32 | } /* extern "C" */ 33 | #endif 34 | 35 | #endif /* SPA_AUDIO_AC3_H */ 36 | -------------------------------------------------------------------------------- /spa/include/spa/param/audio/alac.h: -------------------------------------------------------------------------------- 1 | /* Simple Plugin API */ 2 | /* SPDX-FileCopyrightText: Copyright © 2023 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_AUDIO_ALAC_H 6 | #define SPA_AUDIO_ALAC_H 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | /** 15 | * \addtogroup spa_param 16 | * \{ 17 | */ 18 | 19 | struct spa_audio_info_alac { 20 | uint32_t rate; /*< sample rate */ 21 | uint32_t channels; /*< number of channels */ 22 | }; 23 | 24 | #define SPA_AUDIO_INFO_ALAC_INIT(...) ((struct spa_audio_info_alac) { __VA_ARGS__ }) 25 | 26 | /** 27 | * \} 28 | */ 29 | 30 | #ifdef __cplusplus 31 | } /* extern "C" */ 32 | #endif 33 | 34 | #endif /* SPA_AUDIO_ALAC_H */ 35 | -------------------------------------------------------------------------------- /spa/include/spa/param/audio/amr-types.h: -------------------------------------------------------------------------------- 1 | /* Simple Plugin API */ 2 | /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_AUDIO_AMR_TYPES_H 6 | #define SPA_AUDIO_AMR_TYPES_H 7 | 8 | #include 9 | #include 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | /** 16 | * \addtogroup spa_param 17 | * \{ 18 | */ 19 | 20 | #define SPA_TYPE_INFO_AudioAMRBandMode SPA_TYPE_INFO_ENUM_BASE "AudioAMRBandMode" 21 | #define SPA_TYPE_INFO_AUDIO_AMR_BAND_MODE_BASE SPA_TYPE_INFO_AudioAMRBandMode ":" 22 | 23 | static const struct spa_type_info spa_type_audio_amr_band_mode[] = { 24 | { SPA_AUDIO_AMR_BAND_MODE_UNKNOWN, SPA_TYPE_Int, SPA_TYPE_INFO_AUDIO_AMR_BAND_MODE_BASE "UNKNOWN", NULL }, 25 | { SPA_AUDIO_AMR_BAND_MODE_NB, SPA_TYPE_Int, SPA_TYPE_INFO_AUDIO_AMR_BAND_MODE_BASE "NB", NULL }, 26 | { SPA_AUDIO_AMR_BAND_MODE_WB, SPA_TYPE_Int, SPA_TYPE_INFO_AUDIO_AMR_BAND_MODE_BASE "WB", NULL }, 27 | { 0, 0, NULL, NULL }, 28 | }; 29 | /** 30 | * \} 31 | */ 32 | 33 | #ifdef __cplusplus 34 | } /* extern "C" */ 35 | #endif 36 | 37 | #endif /* SPA_AUDIO_AMR_TYPES_H */ 38 | -------------------------------------------------------------------------------- /spa/include/spa/param/audio/amr.h: -------------------------------------------------------------------------------- 1 | /* Simple Plugin API */ 2 | /* SPDX-FileCopyrightText: Copyright © 2023 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_AUDIO_AMR_H 6 | #define SPA_AUDIO_AMR_H 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | /** 15 | * \addtogroup spa_param 16 | * \{ 17 | */ 18 | 19 | enum spa_audio_amr_band_mode { 20 | SPA_AUDIO_AMR_BAND_MODE_UNKNOWN, 21 | SPA_AUDIO_AMR_BAND_MODE_NB, 22 | SPA_AUDIO_AMR_BAND_MODE_WB, 23 | }; 24 | 25 | struct spa_audio_info_amr { 26 | uint32_t rate; /*< sample rate */ 27 | uint32_t channels; /*< number of channels */ 28 | enum spa_audio_amr_band_mode band_mode; 29 | }; 30 | 31 | #define SPA_AUDIO_INFO_AMR_INIT(...) ((struct spa_audio_info_amr) { __VA_ARGS__ }) 32 | 33 | /** 34 | * \} 35 | */ 36 | 37 | #ifdef __cplusplus 38 | } /* extern "C" */ 39 | #endif 40 | 41 | #endif /* SPA_AUDIO_AMR_H */ 42 | -------------------------------------------------------------------------------- /spa/include/spa/param/audio/ape.h: -------------------------------------------------------------------------------- 1 | /* Simple Plugin API */ 2 | /* SPDX-FileCopyrightText: Copyright © 2023 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_AUDIO_APE_H 6 | #define SPA_AUDIO_APE_H 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | /** 15 | * \addtogroup spa_param 16 | * \{ 17 | */ 18 | 19 | struct spa_audio_info_ape { 20 | uint32_t rate; /*< sample rate */ 21 | uint32_t channels; /*< number of channels */ 22 | }; 23 | 24 | #define SPA_AUDIO_INFO_APE_INIT(...) ((struct spa_audio_info_ape) { __VA_ARGS__ }) 25 | 26 | /** 27 | * \} 28 | */ 29 | 30 | #ifdef __cplusplus 31 | } /* extern "C" */ 32 | #endif 33 | 34 | #endif /* SPA_AUDIO_APE_H */ 35 | -------------------------------------------------------------------------------- /spa/include/spa/param/audio/compressed.h: -------------------------------------------------------------------------------- 1 | /* Simple Plugin API */ 2 | /* SPDX-FileCopyrightText: Copyright © 2021 Wim Taymans */ 3 | /* SPDX-FileCopyrightText: Copyright © 2022 Asymptotic Inc. */ 4 | /* SPDX-License-Identifier: MIT */ 5 | 6 | #ifndef SPA_AUDIO_COMPRESSED_H 7 | #define SPA_AUDIO_COMPRESSED_H 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #endif /* SPA_AUDIO_COMPRESSED_H */ 25 | -------------------------------------------------------------------------------- /spa/include/spa/param/audio/dsp.h: -------------------------------------------------------------------------------- 1 | /* Simple Plugin API */ 2 | /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_AUDIO_DSP_H 6 | #define SPA_AUDIO_DSP_H 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | /** 15 | * \addtogroup spa_param 16 | * \{ 17 | */ 18 | 19 | struct spa_audio_info_dsp { 20 | enum spa_audio_format format; /*< format, one of the DSP formats in enum spa_audio_format */ 21 | }; 22 | 23 | #define SPA_AUDIO_INFO_DSP_INIT(...) ((struct spa_audio_info_dsp) { __VA_ARGS__ }) 24 | 25 | /** 26 | * \} 27 | */ 28 | 29 | #ifdef __cplusplus 30 | } /* extern "C" */ 31 | #endif 32 | 33 | #endif /* SPA_AUDIO_DSP_H */ 34 | -------------------------------------------------------------------------------- /spa/include/spa/param/audio/dts-types.h: -------------------------------------------------------------------------------- 1 | /* Simple Plugin API */ 2 | /* SPDX-FileCopyrightText: Copyright © 2025 Carlos Rafael Giani */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_AUDIO_DTS_TYPES_H 6 | #define SPA_AUDIO_DTS_TYPES_H 7 | 8 | #include 9 | #include 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | /** 16 | * \addtogroup spa_param 17 | * \{ 18 | */ 19 | 20 | #define SPA_TYPE_INFO_AudioDTSExtType SPA_TYPE_INFO_ENUM_BASE "AudioDTSExtType" 21 | #define SPA_TYPE_INFO_AUDIO_DTS_EXT_TYPE_BASE SPA_TYPE_INFO_AudioDTSExtType ":" 22 | 23 | static const struct spa_type_info spa_type_audio_dts_ext_type[] = { 24 | { SPA_AUDIO_DTS_EXT_UNKNOWN, SPA_TYPE_Int, SPA_TYPE_INFO_AUDIO_DTS_EXT_TYPE_BASE "UNKNOWN", NULL }, 25 | { SPA_AUDIO_DTS_EXT_NONE, SPA_TYPE_Int, SPA_TYPE_INFO_AUDIO_DTS_EXT_TYPE_BASE "NONE", NULL }, 26 | { SPA_AUDIO_DTS_EXT_HD_HRA, SPA_TYPE_Int, SPA_TYPE_INFO_AUDIO_DTS_EXT_TYPE_BASE "HRA", NULL }, 27 | { SPA_AUDIO_DTS_EXT_HD_MA, SPA_TYPE_Int, SPA_TYPE_INFO_AUDIO_DTS_EXT_TYPE_BASE "MA", NULL }, 28 | { 0, 0, NULL, NULL }, 29 | }; 30 | 31 | /** 32 | * \} 33 | */ 34 | 35 | #ifdef __cplusplus 36 | } /* extern "C" */ 37 | #endif 38 | 39 | #endif /* SPA_AUDIO_DTS_TYPES_H */ 40 | -------------------------------------------------------------------------------- /spa/include/spa/param/audio/eac3.h: -------------------------------------------------------------------------------- 1 | /* Simple Plugin API */ 2 | /* SPDX-FileCopyrightText: Copyright © 2025 Carlos Rafael Giani */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_AUDIO_EAC3_H 6 | #define SPA_AUDIO_EAC3_H 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | /** 15 | * \addtogroup spa_param 16 | * \{ 17 | */ 18 | 19 | /** Dolby E-AC-3 audio info. */ 20 | struct spa_audio_info_eac3 { 21 | uint32_t rate; /*< sample rate */ 22 | uint32_t channels; /*< number of channels */ 23 | }; 24 | 25 | #define SPA_AUDIO_INFO_EAC3_INIT(...) ((struct spa_audio_info_eac3) { __VA_ARGS__ }) 26 | 27 | /** 28 | * \} 29 | */ 30 | 31 | #ifdef __cplusplus 32 | } /* extern "C" */ 33 | #endif 34 | 35 | #endif /* SPA_AUDIO_EAC3_H */ 36 | -------------------------------------------------------------------------------- /spa/include/spa/param/audio/flac.h: -------------------------------------------------------------------------------- 1 | /* Simple Plugin API */ 2 | /* SPDX-FileCopyrightText: Copyright © 2023 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_AUDIO_FLAC_H 6 | #define SPA_AUDIO_FLAC_H 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | /** 15 | * \addtogroup spa_param 16 | * \{ 17 | */ 18 | 19 | struct spa_audio_info_flac { 20 | uint32_t rate; /*< sample rate */ 21 | uint32_t channels; /*< number of channels */ 22 | }; 23 | 24 | #define SPA_AUDIO_INFO_FLAC_INIT(...) ((struct spa_audio_info_flac) { __VA_ARGS__ }) 25 | 26 | /** 27 | * \} 28 | */ 29 | 30 | #ifdef __cplusplus 31 | } /* extern "C" */ 32 | #endif 33 | 34 | #endif /* SPA_AUDIO_FLAC_H */ 35 | -------------------------------------------------------------------------------- /spa/include/spa/param/audio/iec958.h: -------------------------------------------------------------------------------- 1 | /* Simple Plugin API */ 2 | /* SPDX-FileCopyrightText: Copyright © 2021 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_AUDIO_IEC958_H 6 | #define SPA_AUDIO_IEC958_H 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | /** 15 | * \addtogroup spa_param 16 | * \{ 17 | */ 18 | enum spa_audio_iec958_codec { 19 | SPA_AUDIO_IEC958_CODEC_UNKNOWN, 20 | 21 | SPA_AUDIO_IEC958_CODEC_PCM, 22 | SPA_AUDIO_IEC958_CODEC_DTS, 23 | SPA_AUDIO_IEC958_CODEC_AC3, 24 | SPA_AUDIO_IEC958_CODEC_MPEG, /**< MPEG-1 or MPEG-2 (Part 3, not AAC) */ 25 | SPA_AUDIO_IEC958_CODEC_MPEG2_AAC, /**< MPEG-2 AAC */ 26 | 27 | SPA_AUDIO_IEC958_CODEC_EAC3, 28 | 29 | SPA_AUDIO_IEC958_CODEC_TRUEHD, /**< Dolby TrueHD */ 30 | SPA_AUDIO_IEC958_CODEC_DTSHD, /**< DTS-HD Master Audio */ 31 | }; 32 | 33 | struct spa_audio_info_iec958 { 34 | enum spa_audio_iec958_codec codec; /*< codec, one of the values in enum spa_audio_iec958_codec */ 35 | uint32_t flags; /*< extra flags */ 36 | uint32_t rate; /*< sample rate */ 37 | }; 38 | 39 | #define SPA_AUDIO_INFO_IEC958_INIT(...) ((struct spa_audio_info_iec958) { __VA_ARGS__ }) 40 | 41 | /** 42 | * \} 43 | */ 44 | 45 | #ifdef __cplusplus 46 | } /* extern "C" */ 47 | #endif 48 | 49 | #endif /* SPA_AUDIO_IEC958_H */ 50 | -------------------------------------------------------------------------------- /spa/include/spa/param/audio/mpegh.h: -------------------------------------------------------------------------------- 1 | /* Simple Plugin API */ 2 | /* SPDX-FileCopyrightText: Copyright © 2025 Carlos Rafael Giani */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_AUDIO_MPEGH_H 6 | #define SPA_AUDIO_MPEGH_H 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | /** 15 | * \addtogroup spa_param 16 | * \{ 17 | */ 18 | 19 | /** 20 | * MPEG-H 3D audio info. 21 | * 22 | * MPEG-H content is assumed to be provided in the form of an MPEG-H 23 | * 3D Audio Stream (MHAS). MHAS is a lightweight bitstream format that 24 | * encapsulates MPEG-H 3D Audio frames along with associated metadata. 25 | * It serves a similar role to the Annex B byte stream format used for 26 | * H.264, providing framing and synchronization for MPEG-H frames. 27 | * 28 | * MPEG-H is documented in the ISO/IEC 23008-3 specification. 29 | * MHAS is specified in ISO/IEC 23008-3, Clause 14. 30 | */ 31 | struct spa_audio_info_mpegh { 32 | uint32_t rate; /*< sample rate */ 33 | uint32_t channels; /*< number of channels */ 34 | }; 35 | 36 | #define SPA_AUDIO_INFO_MPEGH_INIT(...) ((struct spa_audio_info_mpegh) { __VA_ARGS__ }) 37 | 38 | /** 39 | * \} 40 | */ 41 | 42 | #ifdef __cplusplus 43 | } /* extern "C" */ 44 | #endif 45 | 46 | #endif /* SPA_AUDIO_MPEGH_H */ 47 | -------------------------------------------------------------------------------- /spa/include/spa/param/audio/opus.h: -------------------------------------------------------------------------------- 1 | /* Simple Plugin API */ 2 | /* SPDX-FileCopyrightText: Copyright © 2023 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_AUDIO_OPUS_H 6 | #define SPA_AUDIO_OPUS_H 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | /** 15 | * \addtogroup spa_param 16 | * \{ 17 | */ 18 | 19 | struct spa_audio_info_opus { 20 | uint32_t rate; /*< sample rate */ 21 | uint32_t channels; /*< number of channels */ 22 | }; 23 | 24 | #define SPA_AUDIO_INFO_OPUS_INIT(...) ((struct spa_audio_info_opus) { __VA_ARGS__ }) 25 | 26 | /** 27 | * \} 28 | */ 29 | 30 | #ifdef __cplusplus 31 | } /* extern "C" */ 32 | #endif 33 | 34 | #endif /* SPA_AUDIO_OPUS_H */ 35 | -------------------------------------------------------------------------------- /spa/include/spa/param/audio/ra.h: -------------------------------------------------------------------------------- 1 | /* Simple Plugin API */ 2 | /* SPDX-FileCopyrightText: Copyright © 2023 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_AUDIO_RA_H 6 | #define SPA_AUDIO_RA_H 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | /** 15 | * \addtogroup spa_param 16 | * \{ 17 | */ 18 | 19 | struct spa_audio_info_ra { 20 | uint32_t rate; /*< sample rate */ 21 | uint32_t channels; /*< number of channels */ 22 | }; 23 | 24 | #define SPA_AUDIO_INFO_RA_INIT(...) ((struct spa_audio_info_ra) { __VA_ARGS__ }) 25 | 26 | /** 27 | * \} 28 | */ 29 | 30 | #ifdef __cplusplus 31 | } /* extern "C" */ 32 | #endif 33 | 34 | #endif /* SPA_AUDIO_RA_H */ 35 | -------------------------------------------------------------------------------- /spa/include/spa/param/audio/truehd.h: -------------------------------------------------------------------------------- 1 | /* Simple Plugin API */ 2 | /* SPDX-FileCopyrightText: Copyright © 2025 Carlos Rafael Giani */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_AUDIO_TRUEHD_H 6 | #define SPA_AUDIO_TRUEHD_H 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | /** 15 | * \addtogroup spa_param 16 | * \{ 17 | */ 18 | 19 | /** Dolby TrueHD audio info. */ 20 | struct spa_audio_info_truehd { 21 | uint32_t rate; /*< sample rate */ 22 | uint32_t channels; /*< number of channels */ 23 | }; 24 | 25 | #define SPA_AUDIO_INFO_TRUEHD_INIT(...) ((struct spa_audio_info_truehd) { __VA_ARGS__ }) 26 | 27 | /** 28 | * \} 29 | */ 30 | 31 | #ifdef __cplusplus 32 | } /* extern "C" */ 33 | #endif 34 | 35 | #endif /* SPA_AUDIO_TRUEHD_H */ 36 | -------------------------------------------------------------------------------- /spa/include/spa/param/audio/type-info.h: -------------------------------------------------------------------------------- 1 | /* Simple Plugin API */ 2 | /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_AUDIO_TYPES_H 6 | #define SPA_AUDIO_TYPES_H 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #endif /* SPA_AUDIO_TYPES_H */ 17 | -------------------------------------------------------------------------------- /spa/include/spa/param/audio/vorbis.h: -------------------------------------------------------------------------------- 1 | /* Simple Plugin API */ 2 | /* SPDX-FileCopyrightText: Copyright © 2023 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_AUDIO_VORBIS_H 6 | #define SPA_AUDIO_VORBIS_H 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | /** 15 | * \addtogroup spa_param 16 | * \{ 17 | */ 18 | 19 | struct spa_audio_info_vorbis { 20 | uint32_t rate; /*< sample rate */ 21 | uint32_t channels; /*< number of channels */ 22 | }; 23 | 24 | #define SPA_AUDIO_INFO_VORBIS_INIT(...) ((struct spa_audio_info_vorbis) { __VA_ARGS__ }) 25 | 26 | /** 27 | * \} 28 | */ 29 | 30 | #ifdef __cplusplus 31 | } /* extern "C" */ 32 | #endif 33 | 34 | #endif /* SPA_AUDIO_VORBIS_H */ 35 | -------------------------------------------------------------------------------- /spa/include/spa/param/audio/wma.h: -------------------------------------------------------------------------------- 1 | /* Simple Plugin API */ 2 | /* SPDX-FileCopyrightText: Copyright © 2023 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_AUDIO_WMA_H 6 | #define SPA_AUDIO_WMA_H 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | /** 15 | * \addtogroup spa_param 16 | * \{ 17 | */ 18 | 19 | enum spa_audio_wma_profile { 20 | SPA_AUDIO_WMA_PROFILE_UNKNOWN, 21 | 22 | SPA_AUDIO_WMA_PROFILE_WMA7, 23 | SPA_AUDIO_WMA_PROFILE_WMA8, 24 | SPA_AUDIO_WMA_PROFILE_WMA9, 25 | SPA_AUDIO_WMA_PROFILE_WMA10, 26 | SPA_AUDIO_WMA_PROFILE_WMA9_PRO, 27 | SPA_AUDIO_WMA_PROFILE_WMA9_LOSSLESS, 28 | SPA_AUDIO_WMA_PROFILE_WMA10_LOSSLESS, 29 | 30 | SPA_AUDIO_WMA_PROFILE_CUSTOM = 0x10000, 31 | }; 32 | 33 | struct spa_audio_info_wma { 34 | uint32_t rate; /*< sample rate */ 35 | uint32_t channels; /*< number of channels */ 36 | uint32_t bitrate; /*< stream bitrate */ 37 | uint32_t block_align; /*< block alignment */ 38 | enum spa_audio_wma_profile profile; /*< WMA profile */ 39 | 40 | }; 41 | 42 | #define SPA_AUDIO_INFO_WMA_INIT(...) ((struct spa_audio_info_wma) { __VA_ARGS__ }) 43 | 44 | /** 45 | * \} 46 | */ 47 | 48 | #ifdef __cplusplus 49 | } /* extern "C" */ 50 | #endif 51 | 52 | #endif /* SPA_AUDIO_WMA_H */ 53 | -------------------------------------------------------------------------------- /spa/include/spa/param/format-utils.h: -------------------------------------------------------------------------------- 1 | /* Simple Plugin API */ 2 | /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_PARAM_FORMAT_UTILS_H 6 | #define SPA_PARAM_FORMAT_UTILS_H 7 | 8 | #include 9 | #include 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | 16 | /** 17 | * \addtogroup spa_param 18 | * \{ 19 | */ 20 | 21 | #ifndef SPA_API_FORMAT_UTILS 22 | #ifdef SPA_API_IMPL 23 | #define SPA_API_FORMAT_UTILS SPA_API_IMPL 24 | #else 25 | #define SPA_API_FORMAT_UTILS static inline 26 | #endif 27 | #endif 28 | 29 | SPA_API_FORMAT_UTILS int 30 | spa_format_parse(const struct spa_pod *format, uint32_t *media_type, uint32_t *media_subtype) 31 | { 32 | return spa_pod_parse_object(format, 33 | SPA_TYPE_OBJECT_Format, NULL, 34 | SPA_FORMAT_mediaType, SPA_POD_Id(media_type), 35 | SPA_FORMAT_mediaSubtype, SPA_POD_Id(media_subtype)); 36 | } 37 | 38 | /** 39 | * \} 40 | */ 41 | 42 | #ifdef __cplusplus 43 | } /* extern "C" */ 44 | #endif 45 | 46 | #endif /* SPA_PARAM_FORMAT_UTILS_H */ 47 | -------------------------------------------------------------------------------- /spa/include/spa/param/tag-types.h: -------------------------------------------------------------------------------- 1 | /* Simple Plugin API */ 2 | /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_PARAM_TAG_TYPES_H 6 | #define SPA_PARAM_TAG_TYPES_H 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | /** 17 | * \addtogroup spa_param 18 | * \{ 19 | */ 20 | 21 | #define SPA_TYPE_INFO_PARAM_Tag SPA_TYPE_INFO_PARAM_BASE "Tag" 22 | #define SPA_TYPE_INFO_PARAM_TAG_BASE SPA_TYPE_INFO_PARAM_Tag ":" 23 | 24 | static const struct spa_type_info spa_type_param_tag[] = { 25 | { SPA_PARAM_TAG_START, SPA_TYPE_Id, SPA_TYPE_INFO_PARAM_TAG_BASE, spa_type_param, }, 26 | { SPA_PARAM_TAG_direction, SPA_TYPE_Id, SPA_TYPE_INFO_PARAM_TAG_BASE "direction", spa_type_direction, }, 27 | { SPA_PARAM_TAG_info, SPA_TYPE_Struct, SPA_TYPE_INFO_PARAM_TAG_BASE "info", NULL, }, 28 | { 0, 0, NULL, NULL }, 29 | }; 30 | 31 | /** 32 | * \} 33 | */ 34 | 35 | #ifdef __cplusplus 36 | } /* extern "C" */ 37 | #endif 38 | 39 | #endif /* SPA_PARAM_TAG_TYPES_H */ 40 | -------------------------------------------------------------------------------- /spa/include/spa/param/tag.h: -------------------------------------------------------------------------------- 1 | /* Simple Plugin API */ 2 | /* SPDX-FileCopyrightText: Copyright © 2023 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_PARAM_TAG_H 6 | #define SPA_PARAM_TAG_H 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | /** 15 | * \addtogroup spa_param 16 | * \{ 17 | */ 18 | 19 | /** properties for SPA_TYPE_OBJECT_ParamTag */ 20 | enum spa_param_tag { 21 | SPA_PARAM_TAG_START, 22 | SPA_PARAM_TAG_direction, /**< direction, input/output (Id enum spa_direction) */ 23 | SPA_PARAM_TAG_info, /**< Struct( 24 | * Int: n_items 25 | * (String: key 26 | * String: value)* 27 | * ) */ 28 | }; 29 | 30 | /** helper structure for managing tag objects */ 31 | struct spa_tag_info { 32 | enum spa_direction direction; 33 | const struct spa_pod *info; 34 | }; 35 | 36 | #define SPA_TAG_INFO(dir,...) ((struct spa_tag_info) { .direction = (dir), ## __VA_ARGS__ }) 37 | 38 | /** 39 | * \} 40 | */ 41 | 42 | #ifdef __cplusplus 43 | } /* extern "C" */ 44 | #endif 45 | 46 | #endif /* SPA_PARAM_TAG_H */ 47 | -------------------------------------------------------------------------------- /spa/include/spa/param/type-info.h: -------------------------------------------------------------------------------- 1 | /* Simple Plugin API */ 2 | /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_PARAM_TYPE_INFO_H 6 | #define SPA_PARAM_TYPE_INFO_H 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #endif /* SPA_PARAM_TYPE_INFO_H */ 20 | -------------------------------------------------------------------------------- /spa/include/spa/param/video/dsp.h: -------------------------------------------------------------------------------- 1 | /* Simple Plugin API */ 2 | /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_VIDEO_DSP_H 6 | #define SPA_VIDEO_DSP_H 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | /** 13 | * \addtogroup spa_param 14 | * \{ 15 | */ 16 | 17 | #include 18 | 19 | struct spa_video_info_dsp { 20 | enum spa_video_format format; 21 | uint32_t flags; 22 | uint64_t modifier; 23 | }; 24 | 25 | #define SPA_VIDEO_INFO_DSP_INIT(...) ((struct spa_video_info_dsp) { __VA_ARGS__ }) 26 | 27 | /** 28 | * \} 29 | */ 30 | 31 | #ifdef __cplusplus 32 | } /* extern "C" */ 33 | #endif 34 | 35 | #endif /* SPA_VIDEO_DSP_H */ 36 | -------------------------------------------------------------------------------- /spa/include/spa/param/video/encoded.h: -------------------------------------------------------------------------------- 1 | /* Simple Plugin API */ 2 | /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_VIDEO_ENCODED_H 6 | #define SPA_VIDEO_ENCODED_H 7 | 8 | #include 9 | #include 10 | 11 | #endif /* SPA_VIDEO_ENCODED_H */ 12 | -------------------------------------------------------------------------------- /spa/include/spa/param/video/format.h: -------------------------------------------------------------------------------- 1 | /* Simple Plugin API */ 2 | /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_PARAM_VIDEO_FORMAT_H 6 | #define SPA_PARAM_VIDEO_FORMAT_H 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #ifdef __cplusplus 14 | extern "C" { 15 | #endif 16 | 17 | /** 18 | * \addtogroup spa_param 19 | * \{ 20 | */ 21 | 22 | struct spa_video_info { 23 | uint32_t media_type; 24 | uint32_t media_subtype; 25 | union { 26 | struct spa_video_info_raw raw; 27 | struct spa_video_info_dsp dsp; 28 | struct spa_video_info_h264 h264; 29 | struct spa_video_info_mjpg mjpg; 30 | } info; 31 | }; 32 | 33 | /** 34 | * \} 35 | */ 36 | 37 | #ifdef __cplusplus 38 | } /* extern "C" */ 39 | #endif 40 | 41 | #endif /* SPA_PARAM_VIDEO_FORMAT_H */ 42 | -------------------------------------------------------------------------------- /spa/include/spa/param/video/h264.h: -------------------------------------------------------------------------------- 1 | /* Simple Plugin API */ 2 | /* SPDX-FileCopyrightText: Copyright © 2023 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_VIDEO_H264_H 6 | #define SPA_VIDEO_H264_H 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | /** 15 | * \addtogroup spa_param 16 | * \{ 17 | */ 18 | 19 | enum spa_h264_stream_format { 20 | SPA_H264_STREAM_FORMAT_UNKNOWN = 0, 21 | SPA_H264_STREAM_FORMAT_AVC, 22 | SPA_H264_STREAM_FORMAT_AVC3, 23 | SPA_H264_STREAM_FORMAT_BYTESTREAM 24 | }; 25 | 26 | enum spa_h264_alignment { 27 | SPA_H264_ALIGNMENT_UNKNOWN = 0, 28 | SPA_H264_ALIGNMENT_AU, 29 | SPA_H264_ALIGNMENT_NAL 30 | }; 31 | 32 | struct spa_video_info_h264 { 33 | struct spa_rectangle size; 34 | struct spa_fraction framerate; 35 | struct spa_fraction max_framerate; 36 | enum spa_h264_stream_format stream_format; 37 | enum spa_h264_alignment alignment; 38 | }; 39 | 40 | /** 41 | * \} 42 | */ 43 | 44 | #ifdef __cplusplus 45 | } /* extern "C" */ 46 | #endif 47 | 48 | #endif /* SPA_VIDEO_H264_H */ 49 | -------------------------------------------------------------------------------- /spa/include/spa/param/video/h265.h: -------------------------------------------------------------------------------- 1 | /* Simple Plugin API */ 2 | /* SPDX-FileCopyrightText: Copyright © 2025 Wim Taymans */ 3 | /* SPDX-FileCopyrightText: Copyright © 2025 Arun Raghavan */ 4 | /* SPDX-License-Identifier: MIT */ 5 | 6 | #ifndef SPA_VIDEO_H265_H 7 | #define SPA_VIDEO_H265_H 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | /** 14 | * \addtogroup spa_param 15 | * \{ 16 | */ 17 | 18 | #include 19 | 20 | enum spa_h265_stream_format { 21 | SPA_H265_STREAM_FORMAT_UNKNOWN = 0, 22 | SPA_H265_STREAM_FORMAT_HVC1, 23 | SPA_H265_STREAM_FORMAT_HEV1, 24 | SPA_H265_STREAM_FORMAT_BYTESTREAM 25 | }; 26 | 27 | enum spa_h265_alignment { 28 | SPA_H265_ALIGNMENT_UNKNOWN = 0, 29 | SPA_H265_ALIGNMENT_AU, 30 | SPA_H265_ALIGNMENT_NAL 31 | }; 32 | 33 | struct spa_video_info_h265 { 34 | struct spa_rectangle size; 35 | struct spa_fraction framerate; 36 | struct spa_fraction max_framerate; 37 | enum spa_h265_stream_format stream_format; 38 | enum spa_h265_alignment alignment; 39 | }; 40 | 41 | /** 42 | * \} 43 | */ 44 | 45 | #ifdef __cplusplus 46 | } /* extern "C" */ 47 | #endif 48 | 49 | #endif /* SPA_VIDEO_H265_H */ 50 | -------------------------------------------------------------------------------- /spa/include/spa/param/video/mjpg.h: -------------------------------------------------------------------------------- 1 | /* Simple Plugin API */ 2 | /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_VIDEO_MJPG_H 6 | #define SPA_VIDEO_MJPG_H 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | /** 15 | * \addtogroup spa_param 16 | * \{ 17 | */ 18 | 19 | struct spa_video_info_mjpg { 20 | struct spa_rectangle size; 21 | struct spa_fraction framerate; 22 | struct spa_fraction max_framerate; 23 | }; 24 | 25 | /** 26 | * \} 27 | */ 28 | 29 | #ifdef __cplusplus 30 | } /* extern "C" */ 31 | #endif 32 | 33 | #endif /* SPA_VIDEO_MJPG_H */ 34 | -------------------------------------------------------------------------------- /spa/include/spa/param/video/type-info.h: -------------------------------------------------------------------------------- 1 | /* Simple Plugin API */ 2 | /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_VIDEO_TYPES_H 6 | #define SPA_VIDEO_TYPES_H 7 | 8 | #include 9 | 10 | #endif /* SPA_VIDEO_TYPES_H */ 11 | -------------------------------------------------------------------------------- /spa/include/spa/pod/command.h: -------------------------------------------------------------------------------- 1 | /* Simple Plugin API */ 2 | /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_COMMAND_H 6 | #define SPA_COMMAND_H 7 | 8 | #include 9 | #include 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | /** 16 | * \addtogroup spa_pod 17 | * \{ 18 | */ 19 | 20 | struct spa_command_body { 21 | struct spa_pod_object_body body; 22 | }; 23 | 24 | struct spa_command { 25 | struct spa_pod pod; 26 | struct spa_command_body body; 27 | }; 28 | 29 | #define SPA_COMMAND_TYPE(cmd) ((cmd)->body.body.type) 30 | #define SPA_COMMAND_ID(cmd,type) (SPA_COMMAND_TYPE(cmd) == (type) ? \ 31 | (cmd)->body.body.id : SPA_ID_INVALID) 32 | 33 | #define SPA_COMMAND_INIT_FULL(t,size,type,id,...) ((t) \ 34 | { { (size), SPA_TYPE_Object }, \ 35 | { { (type), (id) }, ##__VA_ARGS__ } }) 36 | 37 | #define SPA_COMMAND_INIT(type,id) \ 38 | SPA_COMMAND_INIT_FULL(struct spa_command, \ 39 | sizeof(struct spa_command_body), type, id) 40 | 41 | /** 42 | * \} 43 | */ 44 | 45 | #ifdef __cplusplus 46 | } /* extern "C" */ 47 | #endif 48 | 49 | #endif /* SPA_COMMAND_H */ 50 | -------------------------------------------------------------------------------- /spa/include/spa/pod/event.h: -------------------------------------------------------------------------------- 1 | /* Simple Plugin API */ 2 | /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_EVENT_H 6 | #define SPA_EVENT_H 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | /** 15 | * \addtogroup spa_pod 16 | * \{ 17 | */ 18 | 19 | struct spa_event_body { 20 | struct spa_pod_object_body body; 21 | }; 22 | 23 | struct spa_event { 24 | struct spa_pod pod; 25 | struct spa_event_body body; 26 | }; 27 | 28 | #define SPA_EVENT_TYPE(ev) ((ev)->body.body.type) 29 | #define SPA_EVENT_ID(ev,type) (SPA_EVENT_TYPE(ev) == (type) ? \ 30 | (ev)->body.body.id : SPA_ID_INVALID) 31 | 32 | #define SPA_EVENT_INIT_FULL(t,size,type,id,...) ((t) \ 33 | { { (size), SPA_TYPE_Object }, \ 34 | { { (type), (id) }, ##__VA_ARGS__ } }) \ 35 | 36 | #define SPA_EVENT_INIT(type,id) \ 37 | SPA_EVENT_INIT_FULL(struct spa_event, \ 38 | sizeof(struct spa_event_body), type, id) 39 | 40 | /** 41 | * \} 42 | */ 43 | 44 | #ifdef __cplusplus 45 | } /* extern "C" */ 46 | #endif 47 | 48 | #endif /* SPA_EVENT_H */ 49 | -------------------------------------------------------------------------------- /spa/include/spa/utils/atomic.h: -------------------------------------------------------------------------------- 1 | /* Atomic operations */ 2 | /* SPDX-FileCopyrightText: Copyright © 2023 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_ATOMIC_H 6 | #define SPA_ATOMIC_H 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | #define SPA_ATOMIC_CAS(v,ov,nv) \ 13 | ({ \ 14 | __typeof__(v) __ov = (ov); \ 15 | __atomic_compare_exchange_n(&(v), &__ov, (nv), \ 16 | 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); \ 17 | }) 18 | 19 | #define SPA_ATOMIC_DEC(s) __atomic_sub_fetch(&(s), 1, __ATOMIC_SEQ_CST) 20 | #define SPA_ATOMIC_INC(s) __atomic_add_fetch(&(s), 1, __ATOMIC_SEQ_CST) 21 | #define SPA_ATOMIC_LOAD(s) __atomic_load_n(&(s), __ATOMIC_SEQ_CST) 22 | #define SPA_ATOMIC_STORE(s,v) __atomic_store_n(&(s), (v), __ATOMIC_SEQ_CST) 23 | #define SPA_ATOMIC_XCHG(s,v) __atomic_exchange_n(&(s), (v), __ATOMIC_SEQ_CST) 24 | 25 | #define SPA_SEQ_WRITE(s) SPA_ATOMIC_INC(s) 26 | #define SPA_SEQ_WRITE_SUCCESS(s1,s2) ((s1) + 1 == (s2) && ((s2) & 1) == 0) 27 | 28 | #define SPA_SEQ_READ(s) SPA_ATOMIC_LOAD(s) 29 | #define SPA_SEQ_READ_SUCCESS(s1,s2) ((s1) == (s2) && ((s2) & 1) == 0) 30 | 31 | #ifdef __cplusplus 32 | } /* extern "C" */ 33 | #endif 34 | 35 | #endif /* SPA_ATOMIC_H */ 36 | -------------------------------------------------------------------------------- /spa/include/spa/utils/endian.h: -------------------------------------------------------------------------------- 1 | /* Spa */ 2 | /* SPDX-FileCopyrightText: Copyright © 2019 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_ENDIAN_H 6 | #define SPA_ENDIAN_H 7 | 8 | #if defined(__FreeBSD__) || defined(__MidnightBSD__) 9 | #include 10 | #define bswap_16 bswap16 11 | #define bswap_32 bswap32 12 | #define bswap_64 bswap64 13 | #elif defined(_MSC_VER) && defined(_WIN32) 14 | #include 15 | #define __LITTLE_ENDIAN 1234 16 | #define __BIG_ENDIAN 4321 17 | #define __BYTE_ORDER __LITTLE_ENDIAN 18 | #define bswap_16 _byteswap_ushort 19 | #define bswap_32 _byteswap_ulong 20 | #define bswap_64 _byteswap_uint64 21 | #else 22 | #include 23 | #include 24 | #endif 25 | 26 | #endif /* SPA_ENDIAN_H */ 27 | -------------------------------------------------------------------------------- /spa/include/spa/utils/ratelimit.h: -------------------------------------------------------------------------------- 1 | /* Ratelimit */ 2 | /* SPDX-FileCopyrightText: Copyright © 2023 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_RATELIMIT_H 6 | #define SPA_RATELIMIT_H 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | #ifdef __cplusplus 14 | extern "C" { 15 | #endif 16 | 17 | #ifndef SPA_API_RATELIMIT 18 | #ifdef SPA_API_IMPL 19 | #define SPA_API_RATELIMIT SPA_API_IMPL 20 | #else 21 | #define SPA_API_RATELIMIT static inline 22 | #endif 23 | #endif 24 | 25 | struct spa_ratelimit { 26 | uint64_t interval; 27 | uint64_t begin; 28 | unsigned burst; 29 | unsigned n_printed; 30 | unsigned n_suppressed; 31 | }; 32 | 33 | SPA_API_RATELIMIT int spa_ratelimit_test(struct spa_ratelimit *r, uint64_t now) 34 | { 35 | unsigned suppressed = 0; 36 | if (r->begin + r->interval < now) { 37 | suppressed = r->n_suppressed; 38 | r->begin = now; 39 | r->n_printed = 0; 40 | r->n_suppressed = 0; 41 | } else if (r->n_printed >= r->burst) { 42 | r->n_suppressed++; 43 | return -1; 44 | } 45 | r->n_printed++; 46 | return suppressed; 47 | } 48 | 49 | #ifdef __cplusplus 50 | } /* extern "C" */ 51 | #endif 52 | 53 | #endif /* SPA_RATELIMIT_H */ 54 | -------------------------------------------------------------------------------- /spa/lib/meson.build: -------------------------------------------------------------------------------- 1 | spa_lib = shared_library('spa', 2 | [ 'lib.c' ], 3 | include_directories : [ configinc ], 4 | dependencies : [ spa_dep, pthread_lib, mathlib ], 5 | install : true, 6 | install_dir : spa_plugindir ) 7 | -------------------------------------------------------------------------------- /spa/plugins/aec/meson.build: -------------------------------------------------------------------------------- 1 | aec_null = shared_library('spa-aec-null', 2 | [ 'aec-null.c' ], 3 | include_directories : [ configinc ], 4 | dependencies : [ spa_dep ], 5 | install : true, 6 | install_dir : spa_plugindir / 'aec') 7 | 8 | if webrtc_dep.found() 9 | aec_webrtc = shared_library('spa-aec-webrtc', 10 | [ 'aec-webrtc.cpp' ], 11 | include_directories : [ configinc ], 12 | dependencies : [ spa_dep, webrtc_dep ], 13 | install : true, 14 | install_dir : spa_plugindir / 'aec') 15 | endif 16 | 17 | -------------------------------------------------------------------------------- /spa/plugins/alsa/acp/meson.build: -------------------------------------------------------------------------------- 1 | acp_sources = [ 2 | 'acp.c', 3 | 'compat.c', 4 | 'alsa-mixer.c', 5 | 'alsa-ucm.c', 6 | 'alsa-util.c', 7 | 'conf-parser.c', 8 | ] 9 | 10 | acp_c_args = [ 11 | '-DHAVE_ALSA_UCM', 12 | '-DHAVE_READLINK', 13 | ] 14 | 15 | acp_lib = static_library( 16 | 'acp', 17 | acp_sources, 18 | c_args : acp_c_args, 19 | include_directories : [configinc, includes_inc ], 20 | dependencies : [ spa_dep, alsa_dep, mathlib, ] 21 | ) 22 | acp_dep = declare_dependency(link_with: acp_lib) 23 | -------------------------------------------------------------------------------- /spa/plugins/alsa/alsa.h: -------------------------------------------------------------------------------- 1 | /* Spa ALSA Source */ 2 | /* SPDX-FileCopyrightText: Copyright © 2021 Red Hat, Inc. */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_ALSA_H 6 | #define SPA_ALSA_H 7 | 8 | #include 9 | 10 | #undef SPA_LOG_TOPIC_DEFAULT 11 | #define SPA_LOG_TOPIC_DEFAULT &alsa_log_topic 12 | extern struct spa_log_topic alsa_log_topic; 13 | 14 | static inline void alsa_log_topic_init(struct spa_log *log) 15 | { 16 | spa_log_topic_init(log, &alsa_log_topic); 17 | } 18 | 19 | #endif /* SPA_ALSA_H */ 20 | -------------------------------------------------------------------------------- /spa/plugins/alsa/compress-offload-api-util.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "compress-offload-api.h" 4 | #include "compress-offload-api-util.h" 5 | 6 | int get_compress_offload_device_direction(int card_nr, int device_nr, 7 | struct spa_log *log, 8 | enum spa_compress_offload_direction *direction) 9 | { 10 | int ret = 0; 11 | struct compress_offload_api_context *device_context; 12 | const struct snd_compr_caps *compr_caps; 13 | 14 | device_context = compress_offload_api_open(card_nr, device_nr, log); 15 | if (device_context == NULL) 16 | return -errno; 17 | 18 | compr_caps = compress_offload_api_get_caps(device_context); 19 | 20 | switch (compr_caps->direction) { 21 | case SND_COMPRESS_PLAYBACK: 22 | *direction = SPA_COMPRESS_OFFLOAD_DIRECTION_PLAYBACK; 23 | break; 24 | case SND_COMPRESS_CAPTURE: 25 | *direction = SPA_COMPRESS_OFFLOAD_DIRECTION_CAPTURE; 26 | break; 27 | default: 28 | spa_log_error(log, "card nr %d device nr %d: unknown direction %#" PRIx32, 29 | card_nr, device_nr, (uint32_t)(compr_caps->direction)); 30 | ret = -EINVAL; 31 | } 32 | 33 | compress_offload_api_close(device_context); 34 | 35 | return ret; 36 | } 37 | -------------------------------------------------------------------------------- /spa/plugins/alsa/mixer/meson.build: -------------------------------------------------------------------------------- 1 | install_subdir('paths', 2 | install_dir : alsadatadir 3 | ) 4 | 5 | install_subdir('profile-sets', 6 | install_dir : alsadatadir 7 | ) 8 | -------------------------------------------------------------------------------- /spa/plugins/alsa/mixer/paths/analog-output-chat.conf: -------------------------------------------------------------------------------- 1 | ; Some gaming devices have a separate "chat" device, this is for voice chat 2 | ; while playing games. This device is just a fairly standard analog mono 3 | ; device, but it's nicer to make it clear that this is the "chat" device 4 | ; as is mentioned in the marketing info and manual. 5 | .include analog-output.conf.common 6 | -------------------------------------------------------------------------------- /spa/plugins/alsa/mixer/paths/audigy-analog-output.conf: -------------------------------------------------------------------------------- 1 | ; Mixer path for the Sound Blaster Audigy series, which uses the EMU10K2 DSP. 2 | ; We target 'PCM Front' and similarly named controls instead of 'Front' et al. 3 | ; because the latter affect volume only in the device's stereo-to-all-speakers 4 | ; mirroring mode, which is not used by most profiles. 5 | ; https://docs.kernel.org/sound/cards/audigy-mixer.html 6 | ; 7 | ; See analog-output.conf.common for an explanation on the directives 8 | 9 | [General] 10 | priority = 99 11 | description-key = analog-output 12 | 13 | [Element Master] 14 | switch = mute 15 | volume = merge 16 | override-map.1 = all 17 | override-map.2 = all-left,all-right 18 | 19 | [Element PCM Front] 20 | volume = merge 21 | override-map.1 = all-front 22 | override-map.2 = front-left,front-right 23 | 24 | [Element PCM Surround] 25 | volume = merge 26 | override-map.1 = all-rear 27 | override-map.2 = rear-left,rear-right 28 | 29 | [Element PCM Side] 30 | volume = merge 31 | override-map.1 = all-side 32 | override-map.2 = side-left,side-right 33 | 34 | [Element PCM Center] 35 | volume = merge 36 | override-map.1 = all-center 37 | override-map.2 = all-center,all-center 38 | 39 | [Element PCM LFE] 40 | volume = merge 41 | override-map.1 = lfe 42 | override-map.2 = lfe,lfe 43 | 44 | .include analog-output.conf.common 45 | -------------------------------------------------------------------------------- /spa/plugins/alsa/mixer/paths/hdmi-output-0.conf: -------------------------------------------------------------------------------- 1 | [General] 2 | description = HDMI / DisplayPort 3 | type = hdmi 4 | priority = 59 5 | eld-device = auto 6 | 7 | [Properties] 8 | device.icon_name = video-display 9 | 10 | [Jack HDMI/DP] 11 | append-pcm-to-name = yes 12 | required = ignore 13 | 14 | [Jack HDMI] 15 | append-pcm-to-name = no 16 | required = ignore 17 | -------------------------------------------------------------------------------- /spa/plugins/alsa/mixer/paths/hdmi-output-1.conf: -------------------------------------------------------------------------------- 1 | [General] 2 | description = HDMI / DisplayPort 2 3 | type = hdmi 4 | priority = 58 5 | eld-device = auto 6 | 7 | [Properties] 8 | device.icon_name = video-display 9 | 10 | [Jack HDMI/DP] 11 | append-pcm-to-name = yes 12 | required = ignore 13 | 14 | [Jack HDMI] 15 | append-pcm-to-name = no 16 | required = ignore 17 | -------------------------------------------------------------------------------- /spa/plugins/alsa/mixer/paths/hdmi-output-10.conf: -------------------------------------------------------------------------------- 1 | [General] 2 | description = HDMI / DisplayPort 11 3 | type = hdmi 4 | priority = 49 5 | eld-device = auto 6 | 7 | [Properties] 8 | device.icon_name = video-display 9 | 10 | [Jack HDMI/DP] 11 | append-pcm-to-name = yes 12 | required = ignore 13 | 14 | [Jack HDMI] 15 | append-pcm-to-name = no 16 | required = ignore 17 | -------------------------------------------------------------------------------- /spa/plugins/alsa/mixer/paths/hdmi-output-2.conf: -------------------------------------------------------------------------------- 1 | [General] 2 | description = HDMI / DisplayPort 3 3 | type = hdmi 4 | priority = 57 5 | eld-device = auto 6 | 7 | [Properties] 8 | device.icon_name = video-display 9 | 10 | [Jack HDMI/DP] 11 | append-pcm-to-name = yes 12 | required = ignore 13 | 14 | [Jack HDMI] 15 | append-pcm-to-name = no 16 | required = ignore 17 | -------------------------------------------------------------------------------- /spa/plugins/alsa/mixer/paths/hdmi-output-3.conf: -------------------------------------------------------------------------------- 1 | [General] 2 | description = HDMI / DisplayPort 4 3 | type = hdmi 4 | priority = 56 5 | eld-device = auto 6 | 7 | [Properties] 8 | device.icon_name = video-display 9 | 10 | [Jack HDMI/DP] 11 | append-pcm-to-name = yes 12 | required = ignore 13 | 14 | [Jack HDMI] 15 | append-pcm-to-name = no 16 | required = ignore 17 | -------------------------------------------------------------------------------- /spa/plugins/alsa/mixer/paths/hdmi-output-4.conf: -------------------------------------------------------------------------------- 1 | [General] 2 | description = HDMI / DisplayPort 5 3 | type = hdmi 4 | priority = 55 5 | eld-device = auto 6 | 7 | [Properties] 8 | device.icon_name = video-display 9 | 10 | [Jack HDMI/DP] 11 | append-pcm-to-name = yes 12 | required = ignore 13 | 14 | [Jack HDMI] 15 | append-pcm-to-name = no 16 | required = ignore 17 | -------------------------------------------------------------------------------- /spa/plugins/alsa/mixer/paths/hdmi-output-5.conf: -------------------------------------------------------------------------------- 1 | [General] 2 | description = HDMI / DisplayPort 6 3 | type = hdmi 4 | priority = 54 5 | eld-device = auto 6 | 7 | [Properties] 8 | device.icon_name = video-display 9 | 10 | [Jack HDMI/DP] 11 | append-pcm-to-name = yes 12 | required = ignore 13 | 14 | [Jack HDMI] 15 | append-pcm-to-name = no 16 | required = ignore 17 | -------------------------------------------------------------------------------- /spa/plugins/alsa/mixer/paths/hdmi-output-6.conf: -------------------------------------------------------------------------------- 1 | [General] 2 | description = HDMI / DisplayPort 7 3 | type = hdmi 4 | priority = 53 5 | eld-device = auto 6 | 7 | [Properties] 8 | device.icon_name = video-display 9 | 10 | [Jack HDMI/DP] 11 | append-pcm-to-name = yes 12 | required = ignore 13 | 14 | [Jack HDMI] 15 | append-pcm-to-name = no 16 | required = ignore 17 | -------------------------------------------------------------------------------- /spa/plugins/alsa/mixer/paths/hdmi-output-7.conf: -------------------------------------------------------------------------------- 1 | [General] 2 | description = HDMI / DisplayPort 8 3 | type = hdmi 4 | priority = 52 5 | eld-device = auto 6 | 7 | [Properties] 8 | device.icon_name = video-display 9 | 10 | [Jack HDMI/DP] 11 | append-pcm-to-name = yes 12 | required = ignore 13 | 14 | [Jack HDMI] 15 | append-pcm-to-name = no 16 | required = ignore 17 | -------------------------------------------------------------------------------- /spa/plugins/alsa/mixer/paths/hdmi-output-8.conf: -------------------------------------------------------------------------------- 1 | [General] 2 | description = HDMI / DisplayPort 9 3 | type = hdmi 4 | priority = 51 5 | eld-device = auto 6 | 7 | [Properties] 8 | device.icon_name = video-display 9 | 10 | [Jack HDMI/DP] 11 | append-pcm-to-name = yes 12 | required = ignore 13 | 14 | [Jack HDMI] 15 | append-pcm-to-name = no 16 | required = ignore 17 | -------------------------------------------------------------------------------- /spa/plugins/alsa/mixer/paths/hdmi-output-9.conf: -------------------------------------------------------------------------------- 1 | [General] 2 | description = HDMI / DisplayPort 10 3 | type = hdmi 4 | priority = 50 5 | eld-device = auto 6 | 7 | [Properties] 8 | device.icon_name = video-display 9 | 10 | [Jack HDMI/DP] 11 | append-pcm-to-name = yes 12 | required = ignore 13 | 14 | [Jack HDMI] 15 | append-pcm-to-name = no 16 | required = ignore 17 | -------------------------------------------------------------------------------- /spa/plugins/alsa/mixer/paths/iec958-stereo-input.conf: -------------------------------------------------------------------------------- 1 | # This file is part of PulseAudio. 2 | # 3 | # PulseAudio is free software; you can redistribute it and/or modify 4 | # it under the terms of the GNU Lesser General Public License as 5 | # published by the Free Software Foundation; either version 2.1 of the 6 | # License, or (at your option) any later version. 7 | # 8 | # PulseAudio is distributed in the hope that it will be useful, but 9 | # WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | # General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU Lesser General Public License 14 | # along with PulseAudio; if not, see . 15 | 16 | [Element PCM Capture Source] 17 | enumeration = select 18 | 19 | [Option PCM Capture Source:IEC958 In] 20 | name = iec958-input 21 | -------------------------------------------------------------------------------- /spa/plugins/alsa/mixer/paths/iec958-stereo-output.conf: -------------------------------------------------------------------------------- 1 | # This file is part of PulseAudio. 2 | # 3 | # PulseAudio is free software; you can redistribute it and/or modify 4 | # it under the terms of the GNU Lesser General Public License as 5 | # published by the Free Software Foundation; either version 2.1 of the 6 | # License, or (at your option) any later version. 7 | # 8 | # PulseAudio is distributed in the hope that it will be useful, but 9 | # WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | # General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU Lesser General Public License 14 | # along with PulseAudio; if not, see . 15 | 16 | 17 | [Element IEC958] 18 | switch = mute 19 | -------------------------------------------------------------------------------- /spa/plugins/alsa/mixer/paths/steelseries-arctis-output-chat-common.conf: -------------------------------------------------------------------------------- 1 | # This file is part of PulseAudio. 2 | # 3 | # PulseAudio is free software; you can redistribute it and/or modify 4 | # it under the terms of the GNU Lesser General Public License as 5 | # published by the Free Software Foundation; either version 2.1 of the 6 | # License, or (at your option) any later version. 7 | # 8 | # PulseAudio is distributed in the hope that it will be useful, but 9 | # WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | # General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU Lesser General Public License 14 | # along with PulseAudio; if not, see . 15 | 16 | ; Steelseries Arctis 5 USB headset stereo chat path. The headset has two 17 | ; output devices. The first one is meant for voice audio, and the second 18 | ; one meant for everything else. The purpose of this unusual design is to 19 | ; provide separate volume controls for voice and other audio, which can be 20 | ; useful in gaming. 21 | 22 | [General] 23 | priority = 50 24 | 25 | [Element Com Speaker] 26 | switch = mute 27 | volume = merge 28 | -------------------------------------------------------------------------------- /spa/plugins/alsa/mixer/paths/steelseries-arctis-output-game-common.conf: -------------------------------------------------------------------------------- 1 | # This file is part of PulseAudio. 2 | # 3 | # PulseAudio is free software; you can redistribute it and/or modify 4 | # it under the terms of the GNU Lesser General Public License as 5 | # published by the Free Software Foundation; either version 2.1 of the 6 | # License, or (at your option) any later version. 7 | # 8 | # PulseAudio is distributed in the hope that it will be useful, but 9 | # WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | # General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU Lesser General Public License 14 | # along with PulseAudio; if not, see . 15 | 16 | ; Steelseries Arctis 5 USB headset stereo game path. The headset has two 17 | ; output devices. The first one is meant for voice audio, and the second 18 | ; one meant for everything else. The purpose of this unusual design is to 19 | ; provide separate volume controls for voice and other audio, which can be 20 | ; useful in gaming. 21 | 22 | [General] 23 | priority = 99 24 | 25 | [Element PCM] 26 | switch = mute 27 | volume = merge 28 | -------------------------------------------------------------------------------- /spa/plugins/alsa/mixer/paths/virtual-surround-7.1.conf: -------------------------------------------------------------------------------- 1 | [Element PCM,1] 2 | switch = mute 3 | volume = merge 4 | override-map.1 = all 5 | override-map.2 = all-left,all-right 6 | -------------------------------------------------------------------------------- /spa/plugins/alsa/mixer/profile-sets/9999-custom.conf: -------------------------------------------------------------------------------- 1 | # This file is part of PulseAudio. 2 | # 3 | # PulseAudio is free software; you can redistribute it and/or modify 4 | # it under the terms of the GNU Lesser General Public License as 5 | # published by the Free Software Foundation; either version 2.1 of the 6 | # License, or (at your option) any later version. 7 | # 8 | # PulseAudio is distributed in the hope that it will be useful, but 9 | # WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | # General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU Lesser General Public License 14 | # along with PulseAudio; if not, see . 15 | 16 | ; Put your custom profiles here. 17 | 18 | ; An example for defining multiple-sink profiles 19 | #[Profile output:analog-stereo+output:iec958-stereo+input:analog-stereo] 20 | #description = Foobar 21 | #output-mappings = analog-stereo iec958-stereo 22 | #input-mappings = analog-stereo 23 | -------------------------------------------------------------------------------- /spa/plugins/alsa/mixer/profile-sets/steelseries-arctis-common-usb-audio.conf: -------------------------------------------------------------------------------- 1 | [General] 2 | auto-profiles = yes 3 | 4 | [Mapping analog-chat] 5 | description-key = gaming-headset-chat 6 | device-strings = hw:%f,0,0 7 | channel-map = left,right 8 | paths-input = analog-input-mic 9 | paths-output = steelseries-arctis-output-chat-common 10 | intended-roles = phone 11 | 12 | [Mapping analog-game] 13 | description-key = gaming-headset-game 14 | device-strings = hw:%f,1,0 15 | channel-map = left,right 16 | paths-output = steelseries-arctis-output-game-common 17 | direction = output 18 | 19 | [Profile output:analog-chat+output:analog-game+input:analog-chat] 20 | output-mappings = analog-chat analog-game 21 | input-mappings = analog-chat 22 | priority = 5100 23 | skip-probe = yes 24 | -------------------------------------------------------------------------------- /spa/plugins/alsa/mixer/samples/Brooktree Bt878--Bt87x: -------------------------------------------------------------------------------- 1 | Simple mixer control 'FM',0 2 | Capabilities: cswitch cswitch-joined cswitch-exclusive 3 | Capture exclusive group: 0 4 | Capture channels: Mono 5 | Mono: Capture [off] 6 | Simple mixer control 'Mic/Line',0 7 | Capabilities: cswitch cswitch-joined cswitch-exclusive 8 | Capture exclusive group: 0 9 | Capture channels: Mono 10 | Mono: Capture [off] 11 | Simple mixer control 'Capture',0 12 | Capabilities: cvolume cvolume-joined 13 | Capture channels: Mono 14 | Limits: Capture 0 - 15 15 | Mono: Capture 13 [87%] 16 | Simple mixer control 'Capture Boost',0 17 | Capabilities: pswitch pswitch-joined 18 | Playback channels: Mono 19 | Mono: Playback [on] 20 | Simple mixer control 'TV Tuner',0 21 | Capabilities: cswitch cswitch-joined cswitch-exclusive 22 | Capture exclusive group: 0 23 | Capture channels: Mono 24 | Mono: Capture [on] 25 | -------------------------------------------------------------------------------- /spa/plugins/alsa/mixer/samples/HDA ATI HDMI--ATI R6xx HDMI: -------------------------------------------------------------------------------- 1 | Simple mixer control 'IEC958',0 2 | Capabilities: pswitch pswitch-joined 3 | Playback channels: Mono 4 | Mono: Playback [on] 5 | -------------------------------------------------------------------------------- /spa/plugins/alsa/mixer/samples/Logitech USB Speaker--USB Mixer: -------------------------------------------------------------------------------- 1 | Simple mixer control 'Bass',0 2 | Capabilities: volume volume-joined 3 | Playback channels: Mono 4 | Capture channels: Mono 5 | Limits: 0 - 48 6 | Mono: 22 [46%] 7 | Simple mixer control 'Bass Boost',0 8 | Capabilities: pswitch pswitch-joined 9 | Playback channels: Mono 10 | Mono: Playback [off] 11 | Simple mixer control 'Treble',0 12 | Capabilities: volume volume-joined 13 | Playback channels: Mono 14 | Capture channels: Mono 15 | Limits: 0 - 48 16 | Mono: 25 [52%] 17 | Simple mixer control 'PCM',0 18 | Capabilities: pvolume pswitch pswitch-joined 19 | Playback channels: Front Left - Front Right 20 | Limits: Playback 0 - 44 21 | Mono: 22 | Front Left: Playback 10 [23%] [-31.00dB] [on] 23 | Front Right: Playback 10 [23%] [-31.00dB] [on] 24 | Simple mixer control 'Auto Gain Control',0 25 | Capabilities: pswitch pswitch-joined 26 | Playback channels: Mono 27 | Mono: Playback [off] 28 | -------------------------------------------------------------------------------- /spa/plugins/alsa/mixer/samples/USB Device 0x46d_0x9a4--USB Mixer: -------------------------------------------------------------------------------- 1 | Simple mixer control 'Mic',0 2 | Capabilities: cvolume cvolume-joined cswitch cswitch-joined 3 | Capture channels: Mono 4 | Limits: Capture 0 - 3072 5 | Mono: Capture 1536 [50%] [23.00dB] [on] 6 | -------------------------------------------------------------------------------- /spa/plugins/audioconvert/crossover.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. 2 | * Use of this source code is governed by a BSD-style license that can be 3 | * found in the LICENSE file. 4 | */ 5 | 6 | #include 7 | #include 8 | 9 | #include "crossover.h" 10 | 11 | void lr4_set(struct lr4 *lr4, enum biquad_type type, float freq) 12 | { 13 | biquad_set(&lr4->bq, type, freq, 0, 0); 14 | lr4->x1 = 0; 15 | lr4->x2 = 0; 16 | lr4->y1 = 0; 17 | lr4->y2 = 0; 18 | lr4->active = type != BQ_NONE; 19 | } 20 | -------------------------------------------------------------------------------- /spa/plugins/audioconvert/crossover.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. 2 | * Use of this source code is governed by a BSD-style license that can be 3 | * found in the LICENSE file. 4 | */ 5 | 6 | #ifndef CROSSOVER_H_ 7 | #define CROSSOVER_H_ 8 | 9 | #include 10 | 11 | #include "biquad.h" 12 | /* An LR4 filter is two biquads with the same parameters connected in series: 13 | * 14 | * x -- [BIQUAD] -- y -- [BIQUAD] -- z 15 | * 16 | * Both biquad filter has the same parameter b[012] and a[12], 17 | * The variable [xyz][12] keep the history values. 18 | */ 19 | struct lr4 { 20 | struct biquad bq; 21 | float x1, x2; 22 | float y1, y2; 23 | bool active; 24 | }; 25 | 26 | void lr4_set(struct lr4 *lr4, enum biquad_type type, float freq); 27 | 28 | #endif /* CROSSOVER_H_ */ 29 | -------------------------------------------------------------------------------- /spa/plugins/audioconvert/hilbert.h: -------------------------------------------------------------------------------- 1 | /* Hilbert function */ 2 | /* SPDX-FileCopyrightText: Copyright © 2021 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef HILBERT_H 6 | #define HILBERT_H 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | static inline void blackman_window(float *taps, int n_taps) 17 | { 18 | int n; 19 | for (n = 0; n < n_taps; n++) { 20 | float w = 2.0f * (float)M_PI * n / (n_taps-1); 21 | taps[n] = 0.3635819f - 0.4891775f * cosf(w) 22 | + 0.1365995f * cosf(2 * w) - 0.0106411f * cosf(3 * w); 23 | } 24 | } 25 | 26 | static inline int hilbert_generate(float *taps, int n_taps) 27 | { 28 | int i; 29 | 30 | if ((n_taps & 1) == 0) 31 | return -EINVAL; 32 | 33 | for (i = 0; i < n_taps; i++) { 34 | int k = -(n_taps / 2) + i; 35 | if (k & 1) { 36 | float pk = (float)M_PI * k; 37 | taps[i] *= (1.0f - cosf(pk)) / pk; 38 | } else { 39 | taps[i] = 0.0f; 40 | } 41 | } 42 | return 0; 43 | } 44 | 45 | static inline void reverse_taps(float *taps, int n_taps) 46 | { 47 | int i; 48 | for (i = 0; i < n_taps/2; i++) 49 | SPA_SWAP(taps[i], taps[n_taps-1-i]); 50 | } 51 | 52 | #ifdef __cplusplus 53 | } /* extern "C" */ 54 | #endif 55 | 56 | #endif /* HILBERT_H */ 57 | -------------------------------------------------------------------------------- /spa/plugins/audioconvert/peaks-ops-c.c: -------------------------------------------------------------------------------- 1 | /* Spa */ 2 | /* SPDX-FileCopyrightText: Copyright © 2022 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include 6 | 7 | #include "peaks-ops.h" 8 | 9 | void peaks_min_max_c(struct peaks *peaks, const float * SPA_RESTRICT src, 10 | uint32_t n_samples, float *min, float *max) 11 | { 12 | uint32_t n; 13 | float t, mi = *min, ma = *max; 14 | for (n = 0; n < n_samples; n++) { 15 | t = src[n]; 16 | mi = fminf(mi, t); 17 | ma = fmaxf(ma, t); 18 | } 19 | *min = mi; 20 | *max = ma; 21 | } 22 | 23 | float peaks_abs_max_c(struct peaks *peaks, const float * SPA_RESTRICT src, 24 | uint32_t n_samples, float max) 25 | { 26 | uint32_t n; 27 | for (n = 0; n < n_samples; n++) 28 | max = fmaxf(fabsf(src[n]), max); 29 | return max; 30 | } 31 | -------------------------------------------------------------------------------- /spa/plugins/audioconvert/plugin.c: -------------------------------------------------------------------------------- 1 | /* Spa Audioconvert plugin */ 2 | /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | extern const struct spa_handle_factory spa_audioconvert_factory; 11 | extern const struct spa_handle_factory spa_audioadapter_factory; 12 | 13 | SPA_LOG_TOPIC_ENUM_DEFINE_REGISTERED; 14 | 15 | SPA_EXPORT 16 | int spa_handle_factory_enum(const struct spa_handle_factory **factory, uint32_t *index) 17 | { 18 | spa_return_val_if_fail(factory != NULL, -EINVAL); 19 | spa_return_val_if_fail(index != NULL, -EINVAL); 20 | 21 | switch (*index) { 22 | case 0: 23 | *factory = &spa_audioconvert_factory; 24 | break; 25 | case 1: 26 | *factory = &spa_audioadapter_factory; 27 | break; 28 | default: 29 | return 0; 30 | } 31 | (*index)++; 32 | return 1; 33 | } 34 | -------------------------------------------------------------------------------- /spa/plugins/audioconvert/resample-native-c.c: -------------------------------------------------------------------------------- 1 | /* Spa */ 2 | /* SPDX-FileCopyrightText: Copyright © 2019 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include "resample-native-impl.h" 6 | 7 | static inline void inner_product_c(float *d, const float * SPA_RESTRICT s, 8 | const float * SPA_RESTRICT taps, uint32_t n_taps) 9 | { 10 | float sum = 0.0f; 11 | #if 1 12 | uint32_t i, j, nt2 = n_taps/2; 13 | for (i = 0, j = n_taps-1; i < nt2; i++, j--) 14 | sum += s[i] * taps[i] + s[j] * taps[j]; 15 | #else 16 | uint32_t i; 17 | for (i = 0; i < n_taps; i++) 18 | sum += s[i] * taps[i]; 19 | #endif 20 | *d = sum; 21 | } 22 | 23 | static inline void inner_product_ip_c(float *d, const float * SPA_RESTRICT s, 24 | const float * SPA_RESTRICT t0, const float * SPA_RESTRICT t1, float x, 25 | uint32_t n_taps) 26 | { 27 | float sum[2] = { 0.0f, 0.0f }; 28 | uint32_t i; 29 | #if 1 30 | uint32_t j, nt2 = n_taps/2; 31 | for (i = 0, j = n_taps-1; i < nt2; i++, j--) { 32 | sum[0] += s[i] * t0[i] + s[j] * t0[j]; 33 | sum[1] += s[i] * t1[i] + s[j] * t1[j]; 34 | } 35 | #else 36 | for (i = 0; i < n_taps; i++) { 37 | sum[0] += s[i] * t0[i]; 38 | sum[1] += s[i] * t1[i]; 39 | } 40 | #endif 41 | *d = (sum[1] - sum[0]) * x + sum[0]; 42 | } 43 | 44 | MAKE_RESAMPLER_FULL(c); 45 | MAKE_RESAMPLER_INTER(c); 46 | -------------------------------------------------------------------------------- /spa/plugins/audioconvert/volume-ops-c.c: -------------------------------------------------------------------------------- 1 | /* Spa */ 2 | /* SPDX-FileCopyrightText: Copyright © 2021 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include "volume-ops.h" 6 | 7 | void 8 | volume_f32_c(struct volume *vol, void * SPA_RESTRICT dst, 9 | const void * SPA_RESTRICT src, float volume, uint32_t n_samples) 10 | { 11 | uint32_t n; 12 | float *d = (float*)dst; 13 | const float *s = (const float*)src; 14 | 15 | if (volume == VOLUME_MIN) { 16 | memset(d, 0, n_samples * sizeof(float)); 17 | } 18 | else if (volume == VOLUME_NORM) { 19 | spa_memcpy(d, s, n_samples * sizeof(float)); 20 | } 21 | else { 22 | for (n = 0; n < n_samples; n++) 23 | d[n] = s[n] * volume; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /spa/plugins/audioconvert/volume-ops-sse.c: -------------------------------------------------------------------------------- 1 | /* Spa */ 2 | /* SPDX-FileCopyrightText: Copyright © 2021 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include "volume-ops.h" 6 | 7 | #include 8 | 9 | void 10 | volume_f32_sse(struct volume *vol, void * SPA_RESTRICT dst, 11 | const void * SPA_RESTRICT src, float volume, uint32_t n_samples) 12 | { 13 | uint32_t n, unrolled; 14 | float *d = (float*)dst; 15 | const float *s = (const float*)src; 16 | 17 | if (volume == VOLUME_MIN) { 18 | memset(d, 0, n_samples * sizeof(float)); 19 | } 20 | else if (volume == VOLUME_NORM) { 21 | spa_memcpy(d, s, n_samples * sizeof(float)); 22 | } 23 | else { 24 | __m128 t[4]; 25 | const __m128 vol = _mm_set1_ps(volume); 26 | 27 | if (SPA_IS_ALIGNED(d, 16) && 28 | SPA_IS_ALIGNED(s, 16)) 29 | unrolled = n_samples & ~15; 30 | else 31 | unrolled = 0; 32 | 33 | for(n = 0; n < unrolled; n += 16) { 34 | t[0] = _mm_load_ps(&s[n]); 35 | t[1] = _mm_load_ps(&s[n+4]); 36 | t[2] = _mm_load_ps(&s[n+8]); 37 | t[3] = _mm_load_ps(&s[n+12]); 38 | _mm_store_ps(&d[n], _mm_mul_ps(t[0], vol)); 39 | _mm_store_ps(&d[n+4], _mm_mul_ps(t[1], vol)); 40 | _mm_store_ps(&d[n+8], _mm_mul_ps(t[2], vol)); 41 | _mm_store_ps(&d[n+12], _mm_mul_ps(t[3], vol)); 42 | } 43 | for(; n < n_samples; n++) 44 | _mm_store_ss(&d[n], _mm_mul_ss(_mm_load_ss(&s[n]), vol)); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /spa/plugins/audioconvert/volume-ops.h: -------------------------------------------------------------------------------- 1 | /* Spa */ 2 | /* SPDX-FileCopyrightText: Copyright © 2021 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | #define VOLUME_MIN 0.0f 12 | #define VOLUME_NORM 1.0f 13 | 14 | struct volume { 15 | uint32_t cpu_flags; 16 | const char *func_name; 17 | 18 | struct spa_log *log; 19 | 20 | uint32_t flags; 21 | 22 | void (*process) (struct volume *vol, void * SPA_RESTRICT dst, 23 | const void * SPA_RESTRICT src, float volume, uint32_t n_samples); 24 | void (*free) (struct volume *vol); 25 | 26 | void *data; 27 | }; 28 | 29 | int volume_init(struct volume *vol); 30 | 31 | #define volume_process(vol,...) (vol)->process(vol, __VA_ARGS__) 32 | #define volume_free(vol) (vol)->free(vol) 33 | 34 | #define DEFINE_FUNCTION(name,arch) \ 35 | void volume_##name##_##arch(struct volume *vol, \ 36 | void * SPA_RESTRICT dst, \ 37 | const void * SPA_RESTRICT src, \ 38 | float volume, uint32_t n_samples); 39 | 40 | #define VOLUME_OPS_MAX_ALIGN 16 41 | 42 | DEFINE_FUNCTION(f32, c); 43 | 44 | #if defined (HAVE_SSE) 45 | DEFINE_FUNCTION(f32, sse); 46 | #endif 47 | 48 | #undef DEFINE_FUNCTION 49 | -------------------------------------------------------------------------------- /spa/plugins/audiomixer/plugin.c: -------------------------------------------------------------------------------- 1 | /* Spa Audiomixer plugin */ 2 | /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | extern const struct spa_handle_factory spa_audiomixer_factory; 11 | extern const struct spa_handle_factory spa_mixer_dsp_factory; 12 | 13 | SPA_LOG_TOPIC_ENUM_DEFINE_REGISTERED; 14 | 15 | SPA_EXPORT 16 | int spa_handle_factory_enum(const struct spa_handle_factory **factory, uint32_t *index) 17 | { 18 | spa_return_val_if_fail(factory != NULL, -EINVAL); 19 | spa_return_val_if_fail(index != NULL, -EINVAL); 20 | 21 | switch (*index) { 22 | case 0: 23 | *factory = &spa_audiomixer_factory; 24 | break; 25 | case 1: 26 | *factory = &spa_mixer_dsp_factory; 27 | break; 28 | default: 29 | return 0; 30 | } 31 | (*index)++; 32 | return 1; 33 | } 34 | -------------------------------------------------------------------------------- /spa/plugins/audiotestsrc/meson.build: -------------------------------------------------------------------------------- 1 | audiotestsrc_sources = ['audiotestsrc.c', 'plugin.c'] 2 | 3 | audiotestsrclib = shared_library('spa-audiotestsrc', 4 | audiotestsrc_sources, 5 | dependencies : [ spa_dep, mathlib ], 6 | install : true, 7 | install_dir : spa_plugindir / 'audiotestsrc') 8 | -------------------------------------------------------------------------------- /spa/plugins/audiotestsrc/plugin.c: -------------------------------------------------------------------------------- 1 | /* Spa Volume plugin */ 2 | /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | extern const struct spa_handle_factory spa_audiotestsrc_factory; 11 | 12 | SPA_LOG_TOPIC_ENUM_DEFINE_REGISTERED; 13 | 14 | SPA_EXPORT 15 | int spa_handle_factory_enum(const struct spa_handle_factory **factory, uint32_t *index) 16 | { 17 | spa_return_val_if_fail(factory != NULL, -EINVAL); 18 | spa_return_val_if_fail(index != NULL, -EINVAL); 19 | 20 | switch (*index) { 21 | case 0: 22 | *factory = &spa_audiotestsrc_factory; 23 | break; 24 | default: 25 | return 0; 26 | } 27 | (*index)++; 28 | return 1; 29 | } 30 | -------------------------------------------------------------------------------- /spa/plugins/avb/avb.c: -------------------------------------------------------------------------------- 1 | /* Spa AVB support */ 2 | /* SPDX-FileCopyrightText: Copyright © 2022 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | #include "avb.h" 11 | 12 | extern const struct spa_handle_factory spa_avb_sink_factory; 13 | extern const struct spa_handle_factory spa_avb_source_factory; 14 | 15 | SPA_LOG_TOPIC_DEFINE(avb_log_topic, "spa.avb"); 16 | 17 | SPA_LOG_TOPIC_ENUM_DEFINE_REGISTERED; 18 | 19 | SPA_EXPORT 20 | int spa_handle_factory_enum(const struct spa_handle_factory **factory, uint32_t *index) 21 | { 22 | spa_return_val_if_fail(factory != NULL, -EINVAL); 23 | spa_return_val_if_fail(index != NULL, -EINVAL); 24 | 25 | switch (*index) { 26 | case 0: 27 | *factory = &spa_avb_sink_factory; 28 | break; 29 | case 1: 30 | *factory = &spa_avb_source_factory; 31 | break; 32 | default: 33 | return 0; 34 | } 35 | (*index)++; 36 | return 1; 37 | } 38 | -------------------------------------------------------------------------------- /spa/plugins/avb/avb.h: -------------------------------------------------------------------------------- 1 | /* Spa AVB */ 2 | /* SPDX-FileCopyrightText: Copyright © 2022 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_AVB_H 6 | #define SPA_AVB_H 7 | 8 | #include 9 | 10 | #undef SPA_LOG_TOPIC_DEFAULT 11 | #define SPA_LOG_TOPIC_DEFAULT &avb_log_topic 12 | extern struct spa_log_topic avb_log_topic; 13 | 14 | static inline void avb_log_topic_init(struct spa_log *log) 15 | { 16 | spa_log_topic_init(log, &avb_log_topic); 17 | } 18 | 19 | #endif /* SPA_AVB_H */ 20 | -------------------------------------------------------------------------------- /spa/plugins/avb/meson.build: -------------------------------------------------------------------------------- 1 | spa_avb_sources = ['avb.c', 2 | 'avb.h', 3 | 'avb-pcm-sink.c', 4 | 'avb-pcm-source.c', 5 | 'avb-pcm.c' ] 6 | 7 | spa_avb = shared_library( 8 | 'spa-avb', 9 | [ spa_avb_sources ], 10 | include_directories : [configinc], 11 | dependencies : [ spa_dep, mathlib, epoll_shim_dep ], 12 | install : true, 13 | install_dir : spa_plugindir / 'avb' 14 | ) 15 | -------------------------------------------------------------------------------- /spa/plugins/bluez5/README-MIDI.md: -------------------------------------------------------------------------------- 1 | ## BLE MIDI & SELinux 2 | 3 | The SELinux configuration on Fedora 37 (as of 2022-11-10) does not 4 | permit access to the bluetoothd APIs needed for BLE MIDI. 5 | 6 | As a workaround, hopefully to be not necessary in future, you can 7 | permit such access by creating a file `blemidi.te` with contents: 8 | 9 | policy_module(blemidi, 1.0); 10 | 11 | require { 12 | type system_dbusd_t; 13 | type unconfined_t; 14 | type bluetooth_t; 15 | } 16 | 17 | allow bluetooth_t unconfined_t:unix_stream_socket { read write }; 18 | allow system_dbusd_t bluetooth_t:unix_stream_socket { read write }; 19 | 20 | Then having package `selinux-policy-devel` installed, running 21 | `make -f /usr/share/selinux/devel/Makefile blemidi.pp`, and finally 22 | to insert the rules via `sudo semodule -i blemidi.pp`. 23 | 24 | The policy change can be removed by `sudo semodule -r blemidi`. 25 | -------------------------------------------------------------------------------- /spa/plugins/bluez5/codec-loader.h: -------------------------------------------------------------------------------- 1 | /* Spa A2DP codec API */ 2 | /* SPDX-FileCopyrightText: Copyright © 2020 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_BLUEZ5_CODEC_LOADER_H_ 6 | #define SPA_BLUEZ5_CODEC_LOADER_H_ 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | #include "a2dp-codec-caps.h" 14 | #include "media-codecs.h" 15 | 16 | const struct media_codec * const *load_media_codecs(struct spa_plugin_loader *loader, struct spa_log *log); 17 | void free_media_codecs(const struct media_codec * const *media_codecs); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /spa/plugins/bluez5/player.h: -------------------------------------------------------------------------------- 1 | /* Spa Bluez5 AVRCP Player */ 2 | /* SPDX-FileCopyrightText: Copyright © 2021 Pauli Virtanen */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_BLUEZ5_PLAYER_H_ 6 | #define SPA_BLUEZ5_PLAYER_H_ 7 | 8 | enum spa_bt_player_state { 9 | SPA_BT_PLAYER_STOPPED, 10 | SPA_BT_PLAYER_PLAYING, 11 | }; 12 | 13 | /** 14 | * Dummy AVRCP player. 15 | * 16 | * Some headsets require an AVRCP player to be present, before their 17 | * AVRCP volume synchronization works. To work around this, we 18 | * register a dummy player that does nothing. 19 | */ 20 | struct spa_bt_player { 21 | enum spa_bt_player_state state; 22 | }; 23 | 24 | struct spa_bt_player *spa_bt_player_new(void *dbus_connection, struct spa_log *log); 25 | void spa_bt_player_destroy(struct spa_bt_player *player); 26 | int spa_bt_player_set_state(struct spa_bt_player *player, 27 | enum spa_bt_player_state state); 28 | int spa_bt_player_register(struct spa_bt_player *player, const char *adapter_path); 29 | int spa_bt_player_unregister(struct spa_bt_player *player, const char *adapter_path); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /spa/plugins/bluez5/upower.h: -------------------------------------------------------------------------------- 1 | /* Spa Bluez5 UPower proxy */ 2 | /* SPDX-FileCopyrightText: Copyright © 2022 Collabora */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef SPA_BLUEZ5_UPOWER_H_ 6 | #define SPA_BLUEZ5_UPOWER_H_ 7 | 8 | #include "defs.h" 9 | 10 | void *upower_register(struct spa_log *log, 11 | void *dbus_connection, 12 | void (*set_battery_level)(unsigned int level, void *user_data), 13 | void *user_data); 14 | void upower_unregister(void *data); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /spa/plugins/control/meson.build: -------------------------------------------------------------------------------- 1 | control_sources = [ 2 | 'mixer.c', 3 | 'plugin.c' 4 | ] 5 | 6 | controllib = shared_library('spa-control', 7 | control_sources, 8 | dependencies : [ spa_dep, mathlib ], 9 | install : true, 10 | install_dir : spa_plugindir / 'control') 11 | -------------------------------------------------------------------------------- /spa/plugins/control/plugin.c: -------------------------------------------------------------------------------- 1 | /* Spa Control plugin */ 2 | /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | extern const struct spa_handle_factory spa_control_mixer_factory; 11 | 12 | SPA_LOG_TOPIC_ENUM_DEFINE_REGISTERED; 13 | 14 | SPA_EXPORT 15 | int spa_handle_factory_enum(const struct spa_handle_factory **factory, uint32_t *index) 16 | { 17 | spa_return_val_if_fail(factory != NULL, -EINVAL); 18 | spa_return_val_if_fail(index != NULL, -EINVAL); 19 | 20 | switch (*index) { 21 | case 0: 22 | *factory = &spa_control_mixer_factory; 23 | break; 24 | default: 25 | return 0; 26 | } 27 | (*index)++; 28 | return 1; 29 | } 30 | -------------------------------------------------------------------------------- /spa/plugins/ffmpeg/ffmpeg.h: -------------------------------------------------------------------------------- 1 | #ifndef SPA_FFMPEG_H 2 | #define SPA_FFMPEG_H 3 | 4 | #include 5 | #include 6 | 7 | struct spa_dict; 8 | struct spa_handle; 9 | struct spa_support; 10 | struct spa_handle_factory; 11 | 12 | int spa_ffmpeg_dec_init(struct spa_handle *handle, const struct spa_dict *info, 13 | const struct spa_support *support, uint32_t n_support); 14 | int spa_ffmpeg_enc_init(struct spa_handle *handle, const struct spa_dict *info, 15 | const struct spa_support *support, uint32_t n_support); 16 | 17 | size_t spa_ffmpeg_dec_get_size(const struct spa_handle_factory *factory, const struct spa_dict *params); 18 | size_t spa_ffmpeg_enc_get_size(const struct spa_handle_factory *factory, const struct spa_dict *params); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /spa/plugins/ffmpeg/meson.build: -------------------------------------------------------------------------------- 1 | ffmpeg_sources = ['ffmpeg.c', 2 | 'ffmpeg-dec.c', 3 | 'ffmpeg-enc.c'] 4 | 5 | ffmpeglib = shared_library('spa-ffmpeg', 6 | ffmpeg_sources, 7 | dependencies : [ spa_dep, avcodec_dep ], 8 | install : true, 9 | install_dir : spa_plugindir / 'ffmpeg') 10 | -------------------------------------------------------------------------------- /spa/plugins/filter-graph/convolver.h: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2021 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include 6 | #include 7 | 8 | #include "audio-dsp.h" 9 | 10 | struct convolver *convolver_new(struct spa_fga_dsp *dsp, int block, int tail, const float *ir, int irlen); 11 | void convolver_free(struct convolver *conv); 12 | 13 | void convolver_reset(struct convolver *conv); 14 | int convolver_run(struct convolver *conv, const float *input, float *output, int length); 15 | -------------------------------------------------------------------------------- /spa/plugins/jack/meson.build: -------------------------------------------------------------------------------- 1 | spa_jack_sources = [ 2 | 'plugin.c', 3 | 'jack-client.c', 4 | 'jack-device.c', 5 | 'jack-sink.c', 6 | 'jack-source.c'] 7 | 8 | spa_jack = shared_library('spa-jack', 9 | spa_jack_sources, 10 | dependencies : [ spa_dep, jack_dep, mathlib ], 11 | install : true, 12 | install_dir : spa_plugindir / 'jack') 13 | -------------------------------------------------------------------------------- /spa/plugins/jack/plugin.c: -------------------------------------------------------------------------------- 1 | /* Spa jack plugin */ 2 | /* SPDX-FileCopyrightText: Copyright © 2019 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | extern const struct spa_handle_factory spa_jack_device_factory; 11 | extern const struct spa_handle_factory spa_jack_source_factory; 12 | extern const struct spa_handle_factory spa_jack_sink_factory; 13 | 14 | SPA_LOG_TOPIC_ENUM_DEFINE_REGISTERED; 15 | 16 | SPA_EXPORT 17 | int spa_handle_factory_enum(const struct spa_handle_factory **factory, uint32_t *index) 18 | { 19 | spa_return_val_if_fail(factory != NULL, -EINVAL); 20 | spa_return_val_if_fail(index != NULL, -EINVAL); 21 | 22 | switch (*index) { 23 | case 0: 24 | *factory = &spa_jack_device_factory; 25 | break; 26 | case 1: 27 | *factory = &spa_jack_source_factory; 28 | break; 29 | case 2: 30 | *factory = &spa_jack_sink_factory; 31 | break; 32 | default: 33 | return 0; 34 | } 35 | (*index)++; 36 | return 1; 37 | } 38 | -------------------------------------------------------------------------------- /spa/plugins/libcamera/libcamera-manager.hpp: -------------------------------------------------------------------------------- 1 | /* Spa libcamera support */ 2 | /* SPDX-FileCopyrightText: Copyright © 2021 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include 6 | 7 | #include 8 | 9 | std::shared_ptr libcamera_manager_acquire(int& res); 10 | -------------------------------------------------------------------------------- /spa/plugins/libcamera/libcamera.c: -------------------------------------------------------------------------------- 1 | /* Spa libcamera support */ 2 | /* SPDX-FileCopyrightText: Copyright © 2020 collabora */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | #include "libcamera.h" 11 | 12 | SPA_LOG_TOPIC_DEFINE(libcamera_log_topic, "spa.libcamera"); 13 | 14 | SPA_LOG_TOPIC_ENUM_DEFINE_REGISTERED; 15 | 16 | SPA_EXPORT 17 | int spa_handle_factory_enum(const struct spa_handle_factory **factory, 18 | uint32_t *index) 19 | { 20 | spa_return_val_if_fail(factory != NULL, -EINVAL); 21 | spa_return_val_if_fail(index != NULL, -EINVAL); 22 | 23 | switch (*index) { 24 | case 0: 25 | *factory = &spa_libcamera_manager_factory; 26 | break; 27 | case 1: 28 | *factory = &spa_libcamera_device_factory; 29 | break; 30 | case 2: 31 | *factory = &spa_libcamera_source_factory; 32 | break; 33 | default: 34 | return 0; 35 | } 36 | (*index)++; 37 | return 1; 38 | } 39 | -------------------------------------------------------------------------------- /spa/plugins/libcamera/libcamera.h: -------------------------------------------------------------------------------- 1 | /* Spa libcamera support */ 2 | /* SPDX-FileCopyrightText: Copyright © 2020 collabora */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif /* __cplusplus */ 15 | 16 | extern const struct spa_handle_factory spa_libcamera_source_factory; 17 | extern const struct spa_handle_factory spa_libcamera_manager_factory; 18 | extern const struct spa_handle_factory spa_libcamera_device_factory; 19 | 20 | #undef SPA_LOG_TOPIC_DEFAULT 21 | #define SPA_LOG_TOPIC_DEFAULT &libcamera_log_topic 22 | extern struct spa_log_topic libcamera_log_topic; 23 | 24 | static inline void libcamera_log_topic_init(struct spa_log *log) 25 | { 26 | spa_log_topic_init(log, &libcamera_log_topic); 27 | } 28 | 29 | #ifdef __cplusplus 30 | } 31 | #endif /* __cplusplus */ 32 | -------------------------------------------------------------------------------- /spa/plugins/libcamera/meson.build: -------------------------------------------------------------------------------- 1 | libcamera_sources = [ 2 | 'libcamera.c', 3 | 'libcamera-manager.cpp', 4 | 'libcamera-device.cpp', 5 | 'libcamera-source.cpp' 6 | ] 7 | 8 | libcameralib = shared_library('spa-libcamera', 9 | libcamera_sources, 10 | include_directories : [ configinc ], 11 | dependencies : [ spa_dep, libcamera_dep, pthread_lib ], 12 | install : true, 13 | install_dir : spa_plugindir / 'libcamera') 14 | -------------------------------------------------------------------------------- /spa/plugins/support/cpu-riscv.c: -------------------------------------------------------------------------------- 1 | /* Spa */ 2 | /* SPDX-FileCopyrightText: Copyright (c) 2023 Institue of Software Chinese Academy of Sciences (ISCAS). */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifdef HAVE_SYS_AUXV_H 6 | #include 7 | #define HWCAP_RV(letter) (1ul << ((letter) - 'A')) 8 | #endif 9 | 10 | static int 11 | riscv_init(struct impl *impl) 12 | { 13 | uint32_t flags = 0; 14 | 15 | #ifdef HAVE_SYS_AUXV_H 16 | const unsigned long hwcap = getauxval(AT_HWCAP); 17 | if (hwcap & HWCAP_RV('V')) 18 | flags |= SPA_CPU_FLAG_RISCV_V; 19 | #endif 20 | 21 | impl->flags = flags; 22 | 23 | return 0; 24 | } 25 | 26 | static int riscv_zero_denormals(void *object, bool enable) 27 | { 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /spa/plugins/support/evl-plugin.c: -------------------------------------------------------------------------------- 1 | /* Spa Support plugin */ 2 | /* SPDX-FileCopyrightText: Copyright © 2019 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | extern const struct spa_handle_factory spa_support_evl_system_factory; 12 | 13 | SPA_LOG_TOPIC_ENUM_DEFINE_REGISTERED; 14 | 15 | SPA_EXPORT 16 | int spa_handle_factory_enum(const struct spa_handle_factory **factory, uint32_t *index) 17 | { 18 | spa_return_val_if_fail(factory != NULL, -EINVAL); 19 | spa_return_val_if_fail(index != NULL, -EINVAL); 20 | 21 | switch (*index) { 22 | case 0: 23 | *factory = &spa_support_evl_system_factory; 24 | break; 25 | default: 26 | return 0; 27 | } 28 | (*index)++; 29 | return 1; 30 | } 31 | -------------------------------------------------------------------------------- /spa/plugins/test/meson.build: -------------------------------------------------------------------------------- 1 | test_sources = ['fakesrc.c', 'fakesink.c', 'plugin.c'] 2 | 3 | testlib = shared_library('spa-test', 4 | test_sources, 5 | dependencies : [ spa_dep, pthread_lib ], 6 | install : true, 7 | install_dir : spa_plugindir / 'test') 8 | -------------------------------------------------------------------------------- /spa/plugins/test/plugin.c: -------------------------------------------------------------------------------- 1 | /* Spa Test plugin */ 2 | /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | extern const struct spa_handle_factory spa_fakesrc_factory; 11 | extern const struct spa_handle_factory spa_fakesink_factory; 12 | 13 | SPA_LOG_TOPIC_ENUM_DEFINE_REGISTERED; 14 | 15 | SPA_EXPORT 16 | int spa_handle_factory_enum(const struct spa_handle_factory **factory, uint32_t *index) 17 | { 18 | spa_return_val_if_fail(factory != NULL, -EINVAL); 19 | spa_return_val_if_fail(index != NULL, -EINVAL); 20 | 21 | switch (*index) { 22 | case 0: 23 | *factory = &spa_fakesrc_factory; 24 | break; 25 | case 1: 26 | *factory = &spa_fakesink_factory; 27 | break; 28 | default: 29 | return 0; 30 | } 31 | (*index)++; 32 | return 1; 33 | } 34 | -------------------------------------------------------------------------------- /spa/plugins/v4l2/meson.build: -------------------------------------------------------------------------------- 1 | v4l2_sources = ['v4l2.c', 2 | 'v4l2-device.c', 3 | 'v4l2-source.c'] 4 | v4l2_dependencies = [ spa_dep, libinotify_dep, mathlib ] 5 | 6 | if libudev_dep.found() 7 | v4l2_sources += [ 'v4l2-udev.c' ] 8 | v4l2_dependencies += [ libudev_dep ] 9 | if logind_dep.found() 10 | v4l2_dependencies += [ logind_dep ] 11 | endif 12 | endif 13 | 14 | v4l2lib = shared_library('spa-v4l2', 15 | v4l2_sources, 16 | include_directories : [ configinc ], 17 | dependencies : v4l2_dependencies, 18 | install : true, 19 | install_dir : spa_plugindir / 'v4l2') 20 | -------------------------------------------------------------------------------- /spa/plugins/v4l2/v4l2.c: -------------------------------------------------------------------------------- 1 | /* Spa V4l2 support */ 2 | /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include "config.h" 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | #include "v4l2.h" 13 | 14 | extern const struct spa_handle_factory spa_v4l2_source_factory; 15 | extern const struct spa_handle_factory spa_v4l2_udev_factory; 16 | extern const struct spa_handle_factory spa_v4l2_device_factory; 17 | 18 | SPA_LOG_TOPIC_DEFINE(v4l2_log_topic, "spa.v4l2"); 19 | 20 | SPA_LOG_TOPIC_ENUM_DEFINE_REGISTERED; 21 | 22 | SPA_EXPORT 23 | int spa_handle_factory_enum(const struct spa_handle_factory **factory, 24 | uint32_t *index) 25 | { 26 | spa_return_val_if_fail(factory != NULL, -EINVAL); 27 | spa_return_val_if_fail(index != NULL, -EINVAL); 28 | 29 | switch (*index) { 30 | case 0: 31 | *factory = &spa_v4l2_source_factory; 32 | break; 33 | case 1: 34 | #ifdef HAVE_LIBUDEV 35 | *factory = &spa_v4l2_udev_factory; 36 | break; 37 | #else 38 | (*index)++; 39 | SPA_FALLTHROUGH; 40 | #endif 41 | case 2: 42 | *factory = &spa_v4l2_device_factory; 43 | break; 44 | default: 45 | return 0; 46 | } 47 | (*index)++; 48 | return 1; 49 | } 50 | -------------------------------------------------------------------------------- /spa/plugins/v4l2/v4l2.h: -------------------------------------------------------------------------------- 1 | /* Spa V4l2 support */ 2 | /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | 11 | #undef SPA_LOG_TOPIC_DEFAULT 12 | #define SPA_LOG_TOPIC_DEFAULT &v4l2_log_topic 13 | extern struct spa_log_topic v4l2_log_topic; 14 | 15 | static inline void v4l2_log_topic_init(struct spa_log *log) 16 | { 17 | spa_log_topic_init(log, &v4l2_log_topic); 18 | } 19 | 20 | struct spa_v4l2_device { 21 | struct spa_log *log; 22 | int fd; 23 | struct v4l2_capability cap; 24 | unsigned int active:1; 25 | unsigned int have_format:1; 26 | char path[64]; 27 | }; 28 | 29 | int spa_v4l2_open(struct spa_v4l2_device *dev, const char *path); 30 | int spa_v4l2_close(struct spa_v4l2_device *dev); 31 | int spa_v4l2_is_capture(struct spa_v4l2_device *dev); 32 | -------------------------------------------------------------------------------- /spa/plugins/videoconvert/meson.build: -------------------------------------------------------------------------------- 1 | videoconvert_sources = [ 2 | 'videoadapter.c', 3 | 'videoconvert-dummy.c', 4 | 'plugin.c' 5 | ] 6 | 7 | extra_cargs = [] 8 | extra_dependencies = [] 9 | 10 | if avcodec_dep.found() and avutil_dep.found() and swscale_dep.found() 11 | videoconvert_ffmpeg = static_library('videoconvert_fmmpeg', 12 | ['videoconvert-ffmpeg.c' ], 13 | dependencies : [ spa_dep, avcodec_dep, avutil_dep, swscale_dep ], 14 | install : false 15 | ) 16 | extra_cargs += '-D HAVE_VIDEOCONVERT_FFMPEG' 17 | extra_dependencies += videoconvert_ffmpeg 18 | endif 19 | 20 | videoconvertlib = shared_library('spa-videoconvert', 21 | videoconvert_sources, 22 | c_args : extra_cargs, 23 | dependencies : [ spa_dep, mathlib ], 24 | link_with : extra_dependencies, 25 | install : true, 26 | install_dir : spa_plugindir / 'videoconvert') 27 | -------------------------------------------------------------------------------- /spa/plugins/videoconvert/plugin.c: -------------------------------------------------------------------------------- 1 | /* Spa videoconvert plugin */ 2 | /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | extern const struct spa_handle_factory spa_videoadapter_factory; 11 | extern const struct spa_handle_factory spa_videoconvert_dummy_factory; 12 | #if HAVE_VIDEOCONVERT_FFMPEG 13 | extern const struct spa_handle_factory spa_videoconvert_ffmpeg_factory; 14 | #endif 15 | 16 | SPA_LOG_TOPIC_ENUM_DEFINE_REGISTERED; 17 | 18 | SPA_EXPORT 19 | int spa_handle_factory_enum(const struct spa_handle_factory **factory, uint32_t *index) 20 | { 21 | spa_return_val_if_fail(factory != NULL, -EINVAL); 22 | spa_return_val_if_fail(index != NULL, -EINVAL); 23 | 24 | switch (*index) { 25 | case 0: 26 | *factory = &spa_videoadapter_factory; 27 | break; 28 | case 1: 29 | *factory = &spa_videoconvert_dummy_factory; 30 | break; 31 | #if HAVE_VIDEOCONVERT_FFMPEG 32 | case 2: 33 | *factory = &spa_videoconvert_ffmpeg_factory; 34 | break; 35 | #endif 36 | default: 37 | return 0; 38 | } 39 | (*index)++; 40 | return 1; 41 | } 42 | -------------------------------------------------------------------------------- /spa/plugins/videotestsrc/meson.build: -------------------------------------------------------------------------------- 1 | videotestsrc_sources = ['videotestsrc.c', 'plugin.c'] 2 | 3 | videotestsrclib = shared_library('spa-videotestsrc', 4 | videotestsrc_sources, 5 | dependencies : [ spa_dep, pthread_lib ], 6 | install : true, 7 | install_dir : spa_plugindir / 'videotestsrc') 8 | -------------------------------------------------------------------------------- /spa/plugins/videotestsrc/plugin.c: -------------------------------------------------------------------------------- 1 | /* Spa Video Test Source plugin */ 2 | /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | extern const struct spa_handle_factory spa_videotestsrc_factory; 11 | 12 | SPA_LOG_TOPIC_ENUM_DEFINE_REGISTERED; 13 | 14 | SPA_EXPORT 15 | int spa_handle_factory_enum(const struct spa_handle_factory **factory, uint32_t *index) 16 | { 17 | spa_return_val_if_fail(factory != NULL, -EINVAL); 18 | spa_return_val_if_fail(index != NULL, -EINVAL); 19 | 20 | switch (*index) { 21 | case 0: 22 | *factory = &spa_videotestsrc_factory; 23 | break; 24 | default: 25 | return 0; 26 | } 27 | (*index)++; 28 | return 1; 29 | } 30 | -------------------------------------------------------------------------------- /spa/plugins/volume/meson.build: -------------------------------------------------------------------------------- 1 | volume_sources = ['volume.c', 'plugin.c'] 2 | 3 | volumelib = shared_library('spa-volume', 4 | volume_sources, 5 | dependencies : [ spa_dep ], 6 | install : true, 7 | install_dir : spa_plugindir / 'volume') 8 | -------------------------------------------------------------------------------- /spa/plugins/volume/plugin.c: -------------------------------------------------------------------------------- 1 | /* Spa Volume plugin */ 2 | /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | extern const struct spa_handle_factory spa_volume_factory; 11 | 12 | SPA_LOG_TOPIC_ENUM_DEFINE_REGISTERED; 13 | 14 | SPA_EXPORT 15 | int spa_handle_factory_enum(const struct spa_handle_factory **factory, uint32_t *index) 16 | { 17 | spa_return_val_if_fail(factory != NULL, -EINVAL); 18 | spa_return_val_if_fail(index != NULL, -EINVAL); 19 | 20 | switch (*index) { 21 | case 0: 22 | *factory = &spa_volume_factory; 23 | break; 24 | default: 25 | return 0; 26 | } 27 | (*index)++; 28 | return 1; 29 | } 30 | -------------------------------------------------------------------------------- /spa/plugins/vulkan/meson.build: -------------------------------------------------------------------------------- 1 | spa_vulkan_sources = [ 2 | 'plugin.c', 3 | 'pixel-formats.c', 4 | 'vulkan-compute-filter.c', 5 | 'vulkan-compute-source.c', 6 | 'vulkan-compute-utils.c', 7 | 'vulkan-blit-filter.c', 8 | 'vulkan-blit-dsp-filter.c', 9 | 'vulkan-blit-utils.c', 10 | 'vulkan-utils.c', 11 | 'utils.c', 12 | ] 13 | 14 | drm = dependency('libdrm') 15 | 16 | if cc.has_header('linux/dma-buf.h') and target_machine.system() == 'linux' 17 | spa_vulkan_sources += files('dmabuf_linux.c') 18 | else 19 | spa_vulkan_sources += files('dmabuf_fallback.c') 20 | endif 21 | 22 | spa_vulkan = shared_library('spa-vulkan', 23 | spa_vulkan_sources, 24 | dependencies : [ spa_dep, vulkan_dep, mathlib, drm ], 25 | install : true, 26 | install_dir : spa_plugindir / 'vulkan') 27 | -------------------------------------------------------------------------------- /spa/plugins/vulkan/pixel-formats.c: -------------------------------------------------------------------------------- 1 | /* Spa */ 2 | /* SPDX-FileCopyrightText: Copyright © 2023 columbarius */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include "pixel-formats.h" 6 | 7 | #include 8 | #include 9 | 10 | struct pixel_info { 11 | uint32_t format; 12 | uint32_t bpp; 13 | } pixel_infos[] = { 14 | { SPA_VIDEO_FORMAT_RGBA_F32, 16 }, 15 | { SPA_VIDEO_FORMAT_BGRA, 4 }, 16 | { SPA_VIDEO_FORMAT_RGBA, 4 }, 17 | { SPA_VIDEO_FORMAT_BGRx, 4 }, 18 | { SPA_VIDEO_FORMAT_RGBx, 4 }, 19 | { SPA_VIDEO_FORMAT_BGR, 3 }, 20 | { SPA_VIDEO_FORMAT_RGB, 3 }, 21 | }; 22 | 23 | bool get_pixel_format_info(uint32_t format, struct pixel_format_info *info) 24 | { 25 | struct pixel_info *p; 26 | SPA_FOR_EACH_ELEMENT(pixel_infos, p) { 27 | if (p->format != format) 28 | continue; 29 | info->bpp = p->bpp; 30 | return true; 31 | } 32 | return false; 33 | } 34 | -------------------------------------------------------------------------------- /spa/plugins/vulkan/pixel-formats.h: -------------------------------------------------------------------------------- 1 | /* Spa */ 2 | /* SPDX-FileCopyrightText: Copyright © 2023 columbarius */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include 6 | #include 7 | 8 | struct pixel_format_info { 9 | uint32_t bpp; // bytes per pixel 10 | }; 11 | 12 | bool get_pixel_format_info(uint32_t format, struct pixel_format_info *info); 13 | -------------------------------------------------------------------------------- /spa/plugins/vulkan/plugin.c: -------------------------------------------------------------------------------- 1 | /* Spa vulkan plugin */ 2 | /* SPDX-FileCopyrightText: Copyright © 2019 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | extern const struct spa_handle_factory spa_vulkan_compute_filter_factory; 11 | extern const struct spa_handle_factory spa_vulkan_compute_source_factory; 12 | extern const struct spa_handle_factory spa_vulkan_blit_filter_factory; 13 | extern const struct spa_handle_factory spa_vulkan_blit_dsp_filter_factory; 14 | 15 | SPA_LOG_TOPIC_ENUM_DEFINE_REGISTERED; 16 | 17 | SPA_EXPORT 18 | int spa_handle_factory_enum(const struct spa_handle_factory **factory, uint32_t *index) 19 | { 20 | spa_return_val_if_fail(factory != NULL, -EINVAL); 21 | spa_return_val_if_fail(index != NULL, -EINVAL); 22 | 23 | switch (*index) { 24 | case 0: 25 | *factory = &spa_vulkan_compute_source_factory; 26 | break; 27 | case 1: 28 | *factory = &spa_vulkan_compute_filter_factory; 29 | break; 30 | case 2: 31 | *factory = &spa_vulkan_blit_filter_factory; 32 | break; 33 | case 3: 34 | *factory = &spa_vulkan_blit_dsp_filter_factory; 35 | break; 36 | default: 37 | return 0; 38 | } 39 | (*index)++; 40 | return 1; 41 | } 42 | -------------------------------------------------------------------------------- /spa/plugins/vulkan/shaders/filter-color.comp: -------------------------------------------------------------------------------- 1 | void mainImage( out vec4 fragColor, in vec2 fragCoord ) 2 | { 3 | vec2 p = fragCoord.xy/iResolution.xy; 4 | 5 | vec4 col = texture(iChannel0, p); 6 | 7 | 8 | //Desaturate 9 | if(p.x<.25) 10 | { 11 | col = vec4( (col.r+col.g+col.b)/3. ); 12 | } 13 | //Invert 14 | else if (p.x<.5) 15 | { 16 | col = vec4(1.) - texture(iChannel0, p); 17 | } 18 | //Chromatic aberration 19 | else if (p.x<.75) 20 | { 21 | vec2 offset = vec2(.01,.0); 22 | col.r = texture(iChannel0, p+offset.xy).r; 23 | col.g = texture(iChannel0, p ).g; 24 | col.b = texture(iChannel0, p+offset.yx).b; 25 | } 26 | //Color switching 27 | else 28 | { 29 | col.rgb = texture(iChannel0, p).brg; 30 | } 31 | 32 | 33 | //Line 34 | if( mod(abs(p.x+.5/iResolution.y),.25)<0.5/iResolution.y ) 35 | col = vec4(1.); 36 | 37 | 38 | fragColor = col; 39 | } 40 | -------------------------------------------------------------------------------- /spa/plugins/vulkan/shaders/filter.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | #extension GL_ARB_separate_shader_objects : enable 3 | 4 | #define WORKGROUP_SIZE 32 5 | layout (local_size_x = WORKGROUP_SIZE, local_size_y = WORKGROUP_SIZE, local_size_z = 1 ) in; 6 | 7 | layout(rgba32f, set = 0, binding = 0) uniform image2D resultImage; 8 | layout(set = 0, binding = 1) uniform sampler2D iChannel0; 9 | 10 | layout( push_constant ) uniform Constants { 11 | float time; 12 | int frame; 13 | int width; 14 | int height; 15 | } PushConstant; 16 | 17 | float iTime; 18 | int iFrame; 19 | vec3 iResolution; 20 | vec4 iMouse; 21 | 22 | void mainImage( out vec4 fragColor, in vec2 fragCoord ); 23 | 24 | void main() 25 | { 26 | iTime = PushConstant.time; 27 | iFrame = PushConstant.frame; 28 | iResolution = vec3(float(PushConstant.width), float(PushConstant.height), 0.0); 29 | iMouse = vec4(0.0, 0.0, 0.0, 0.0); 30 | vec2 coord = vec2(float(gl_GlobalInvocationID.x), 31 | iResolution.y - float(gl_GlobalInvocationID.y)); 32 | vec4 outColor; 33 | 34 | if(coord.x >= iResolution.x || coord.y >= iResolution.y) 35 | return; 36 | 37 | mainImage(outColor, coord); 38 | 39 | imageStore(resultImage, ivec2(gl_GlobalInvocationID.xy), outColor); 40 | } 41 | 42 | //#include "smearcam.comp" 43 | #include "filter-color.comp" 44 | //#include "filter-ripple.comp" 45 | -------------------------------------------------------------------------------- /spa/plugins/vulkan/shaders/filter.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PipeWire/pipewire/0e8a8e9844ba2aeb34048ead76eb8b36b45147f6/spa/plugins/vulkan/shaders/filter.spv -------------------------------------------------------------------------------- /spa/plugins/vulkan/shaders/main.spv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PipeWire/pipewire/0e8a8e9844ba2aeb34048ead76eb8b36b45147f6/spa/plugins/vulkan/shaders/main.spv -------------------------------------------------------------------------------- /spa/plugins/vulkan/utils.h: -------------------------------------------------------------------------------- 1 | /* Spa */ 2 | /* SPDX-FileCopyrightText: Copyright © 2023 columbarius */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include "vulkan-types.h" 6 | #include "spa/pod/builder.h" 7 | 8 | bool find_EnumFormatInfo(struct vulkan_format_infos *fmtInfos, uint32_t index, uint32_t caps, uint32_t *fmt_idx, bool *has_modifier); 9 | 10 | struct spa_pod *build_dsp_EnumFormat(const struct vulkan_format_info *fmt, bool with_modifiers, struct spa_pod_builder *builder); 11 | struct spa_pod *build_raw_EnumFormat(const struct vulkan_format_info *fmt, bool with_modifiers, struct spa_pod_builder *builder); 12 | -------------------------------------------------------------------------------- /spa/tests/spa-include-test-template.c: -------------------------------------------------------------------------------- 1 | #include <@INCLUDE@> 2 | 3 | int main(void) { 4 | return 0; 5 | } 6 | -------------------------------------------------------------------------------- /spa/tools/meson.build: -------------------------------------------------------------------------------- 1 | executable('spa-inspect', 'spa-inspect.c', 2 | dependencies : [ spa_dep, dl_lib ], 3 | install : true) 4 | 5 | executable('spa-monitor', 'spa-monitor.c', 6 | dependencies : [ spa_dep, dl_lib ], 7 | install : true) 8 | 9 | spa_json_dump_exe = executable('spa-json-dump', 'spa-json-dump.c', 10 | dependencies : [ spa_dep, dl_lib, ], 11 | install : true) 12 | -------------------------------------------------------------------------------- /src/daemon/client.conf.avail/20-upmix.conf.in: -------------------------------------------------------------------------------- 1 | # Enables upmixing 2 | stream.properties = { 3 | channelmix.upmix = true 4 | channelmix.upmix-method = psd # none, simple 5 | channelmix.lfe-cutoff = 150 6 | channelmix.fc-cutoff = 12000 7 | channelmix.rear-delay = 12.0 8 | } 9 | -------------------------------------------------------------------------------- /src/daemon/client.conf.avail/meson.build: -------------------------------------------------------------------------------- 1 | conf_files = [ 2 | '20-upmix.conf', 3 | ] 4 | 5 | foreach c : conf_files 6 | res = configure_file(input : '@0@.in'.format(c), 7 | output : c, 8 | configuration : conf_config, 9 | install_dir : pipewire_confdatadir / 'client.conf.avail') 10 | test(f'validate-json-client-@c@', spa_json_dump_exe, args : res) 11 | endforeach 12 | 13 | -------------------------------------------------------------------------------- /src/daemon/filter-chain/meson.build: -------------------------------------------------------------------------------- 1 | conf_files = [ 2 | [ 'demonic.conf', 'demonic.conf' ], 3 | [ 'source-duplicate-FL.conf', 'source-duplicate-FL.conf' ], 4 | [ 'sink-mix-FL-FR.conf', 'sink-mix-FL-FR.conf' ], 5 | [ 'sink-make-LFE.conf', 'sink-make-LFE.conf' ], 6 | [ 'sink-virtual-surround-5.1-kemar.conf', 'sink-virtual-surround-5.1-kemar.conf' ], 7 | [ 'sink-virtual-surround-7.1-hesuvi.conf', 'sink-virtual-surround-7.1-hesuvi.conf' ], 8 | [ 'sink-dolby-surround.conf', 'sink-dolby-surround.conf' ], 9 | [ 'sink-dolby-pro-logic-ii.conf', 'sink-dolby-pro-logic-ii.conf' ], 10 | [ 'sink-eq6.conf', 'sink-eq6.conf' ], 11 | [ 'sink-matrix-spatialiser.conf', 'sink-matrix-spatialiser.conf' ], 12 | [ 'source-rnnoise.conf', 'source-rnnoise.conf' ], 13 | [ 'sink-upmix-5.1-filter.conf', 'sink-upmix-5.1-filter.conf' ], 14 | ] 15 | 16 | foreach c : conf_files 17 | res = configure_file(input : c.get(0), 18 | output : c.get(1), 19 | configuration : conf_config, 20 | install_dir : pipewire_confdatadir / 'filter-chain') 21 | test('validate-json-filter-chain-' + c.get(0), spa_json_dump_exe, args : res) 22 | endforeach 23 | -------------------------------------------------------------------------------- /src/daemon/pipewire-pulse.conf.avail/20-upmix.conf.in: -------------------------------------------------------------------------------- 1 | # Enables upmixing 2 | stream.properties = { 3 | channelmix.upmix = true 4 | channelmix.upmix-method = psd # none, simple 5 | channelmix.lfe-cutoff = 150 6 | channelmix.fc-cutoff = 12000 7 | channelmix.rear-delay = 12.0 8 | } 9 | -------------------------------------------------------------------------------- /src/daemon/pipewire-pulse.conf.avail/meson.build: -------------------------------------------------------------------------------- 1 | conf_files = [ 2 | '20-upmix.conf', 3 | ] 4 | 5 | foreach c : conf_files 6 | res = configure_file(input : '@0@.in'.format(c), 7 | output : c, 8 | configuration : conf_config, 9 | install_dir : pipewire_confdatadir / 'pipewire-pulse.conf.avail') 10 | test(f'validate-json-pulse-@c@', spa_json_dump_exe, args : res) 11 | endforeach 12 | 13 | -------------------------------------------------------------------------------- /src/daemon/pipewire.conf.avail/10-rates.conf.in: -------------------------------------------------------------------------------- 1 | # Adds more common rates 2 | context.properties = { 3 | default.clock.allowed-rates = [ 44100 48000 88200 96000 ] 4 | } 5 | -------------------------------------------------------------------------------- /src/daemon/pipewire.conf.avail/20-upmix.conf.in: -------------------------------------------------------------------------------- 1 | # Enables upmixing 2 | stream.properties = { 3 | channelmix.upmix = true 4 | channelmix.upmix-method = psd # none, simple 5 | channelmix.lfe-cutoff = 150 6 | channelmix.fc-cutoff = 12000 7 | channelmix.rear-delay = 12.0 8 | } 9 | -------------------------------------------------------------------------------- /src/daemon/pipewire.conf.avail/50-raop.conf.in: -------------------------------------------------------------------------------- 1 | context.modules = [ 2 | # Use mDNS to detect and load module-raop-sink 3 | { name = libpipewire-module-raop-discover } 4 | ] 5 | -------------------------------------------------------------------------------- /src/daemon/pipewire.conf.avail/meson.build: -------------------------------------------------------------------------------- 1 | conf_files = [ 2 | '10-rates.conf', 3 | '20-upmix.conf', 4 | '50-raop.conf', 5 | ] 6 | 7 | foreach c : conf_files 8 | res = configure_file(input : '@0@.in'.format(c), 9 | output : c, 10 | configuration : conf_config, 11 | install_dir : pipewire_confdatadir / 'pipewire.conf.avail') 12 | test(f'validate-json-pipewire-@c@', spa_json_dump_exe, args : res) 13 | endforeach 14 | 15 | -------------------------------------------------------------------------------- /src/daemon/pipewire.desktop.in: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Version=1.0 3 | Name=PipeWire Media System 4 | Comment=Start the PipeWire Media System 5 | Exec=pipewire 6 | Terminal=false 7 | Type=Application 8 | X-GNOME-Autostart-Phase=Initialization 9 | X-KDE-autostart-phase=1 10 | -------------------------------------------------------------------------------- /src/daemon/systemd/meson.build: -------------------------------------------------------------------------------- 1 | if get_option('systemd-system-service').allowed() 2 | subdir('system') 3 | endif 4 | if get_option('systemd-user-service').allowed() 5 | subdir('user') 6 | endif 7 | -------------------------------------------------------------------------------- /src/daemon/systemd/system/meson.build: -------------------------------------------------------------------------------- 1 | systemd_system_services_dir = systemd.get_variable('systemdsystemunitdir', pkgconfig_define : [ 'rootprefix', prefix]) 2 | if get_option('systemd-system-unit-dir') != '' 3 | systemd_system_services_dir = get_option('systemd-system-unit-dir') 4 | endif 5 | 6 | install_data(sources : ['pipewire.socket', 'pipewire-manager.socket', 'pipewire-pulse.socket' ], 7 | install_dir : systemd_system_services_dir) 8 | 9 | systemd_config = configuration_data() 10 | systemd_config.set('PW_BINARY', pipewire_bindir / 'pipewire') 11 | systemd_config.set('PW_PULSE_BINARY', pipewire_bindir / 'pipewire-pulse') 12 | 13 | configure_file(input : 'pipewire.service.in', 14 | output : 'pipewire.service', 15 | configuration : systemd_config, 16 | install_dir : systemd_system_services_dir) 17 | 18 | configure_file(input : 'pipewire-pulse.service.in', 19 | output : 'pipewire-pulse.service', 20 | configuration : systemd_config, 21 | install_dir : systemd_system_services_dir) 22 | -------------------------------------------------------------------------------- /src/daemon/systemd/system/pipewire-manager.socket: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=PipeWire Multimedia System Manager Socket 3 | 4 | [Socket] 5 | Service=pipewire.service 6 | Priority=6 7 | ListenStream=%t/pipewire/pipewire-0-manager 8 | SocketUser=pipewire 9 | SocketGroup=pipewire 10 | SocketMode=0600 11 | 12 | [Install] 13 | WantedBy=sockets.target 14 | -------------------------------------------------------------------------------- /src/daemon/systemd/system/pipewire-pulse.service.in: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=PipeWire PulseAudio Service 3 | Requires=pipewire-pulse.socket 4 | Wants=pipewire.service pipewire-session-manager.service 5 | After=pipewire.service pipewire-session-manager.service 6 | 7 | [Service] 8 | LockPersonality=yes 9 | MemoryDenyWriteExecute=yes 10 | NoNewPrivileges=yes 11 | SystemCallArchitectures=native 12 | SystemCallFilter=@system-service 13 | Type=simple 14 | AmbientCapabilities=CAP_SYS_NICE 15 | ExecStart=@PW_PULSE_BINARY@ 16 | Restart=on-failure 17 | User=pipewire 18 | Environment=PIPEWIRE_RUNTIME_DIR=%t/pipewire 19 | Environment=PULSE_RUNTIME_PATH=%t/pulse 20 | 21 | [Install] 22 | Also=pipewire-pulse.socket 23 | WantedBy=pipewire.service 24 | 25 | -------------------------------------------------------------------------------- /src/daemon/systemd/system/pipewire-pulse.socket: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=PipeWire PulseAudio System Socket 3 | 4 | [Socket] 5 | Priority=6 6 | ListenStream=%t/pulse/native 7 | SocketUser=pipewire 8 | SocketGroup=pipewire 9 | SocketMode=0660 10 | 11 | [Install] 12 | WantedBy=sockets.target 13 | -------------------------------------------------------------------------------- /src/daemon/systemd/system/pipewire.service.in: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=PipeWire Multimedia Service 3 | 4 | # We require pipewire.socket to be active before starting the daemon, because 5 | # while it is possible to use the service without the socket, it is not clear 6 | # why it would be desirable. 7 | # 8 | # Installing pipewire and doing `systemctl start pipewire` will not get the 9 | # socket started, which might be confusing and problematic if the server is to 10 | # be restarted later on, as the client autospawn feature might kick in. Also, a 11 | # start of the socket unit will fail, adding to the confusion. 12 | # 13 | # After=pipewire.socket is not needed, as it is already implicit in the 14 | # socket-service relationship, see systemd.socket(5). 15 | Requires=pipewire.socket 16 | 17 | [Service] 18 | LockPersonality=yes 19 | MemoryDenyWriteExecute=yes 20 | NoNewPrivileges=yes 21 | RestrictNamespaces=yes 22 | SystemCallArchitectures=native 23 | SystemCallFilter=@system-service 24 | Type=simple 25 | AmbientCapabilities=CAP_SYS_NICE 26 | ExecStart=@PW_BINARY@ 27 | Restart=on-failure 28 | RuntimeDirectory=pipewire 29 | RuntimeDirectoryPreserve=yes 30 | User=pipewire 31 | Environment=PIPEWIRE_RUNTIME_DIR=%t/pipewire 32 | 33 | [Install] 34 | Also=pipewire.socket pipewire-manager.socket 35 | WantedBy=default.target 36 | -------------------------------------------------------------------------------- /src/daemon/systemd/system/pipewire.socket: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=PipeWire Multimedia System Socket 3 | 4 | [Socket] 5 | Priority=6 6 | ListenStream=%t/pipewire/pipewire-0 7 | SocketUser=pipewire 8 | SocketGroup=pipewire 9 | SocketMode=0660 10 | 11 | [Install] 12 | WantedBy=sockets.target 13 | -------------------------------------------------------------------------------- /src/daemon/systemd/user/filter-chain.service.in: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=PipeWire filter chain daemon 3 | 4 | After=pipewire.service pipewire-session-manager.service 5 | BindsTo=pipewire.service 6 | 7 | [Service] 8 | LockPersonality=yes 9 | MemoryDenyWriteExecute=yes 10 | NoNewPrivileges=yes 11 | RestrictNamespaces=yes 12 | SystemCallArchitectures=native 13 | SystemCallFilter=@system-service 14 | Type=simple 15 | ExecStart=@PW_BINARY@ -c filter-chain.conf 16 | Restart=on-failure 17 | Slice=session.slice 18 | 19 | [Install] 20 | Also=pipewire.socket 21 | WantedBy=default.target 22 | -------------------------------------------------------------------------------- /src/daemon/systemd/user/pipewire-pulse.service.in: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=PipeWire PulseAudio 3 | 4 | # We require pipewire-pulse.socket to be active before starting the daemon, because 5 | # while it is possible to use the service without the socket, it is not clear 6 | # why it would be desirable. 7 | # 8 | # A user installing pipewire and doing `systemctl --user start pipewire-pulse` 9 | # will not get the socket started, which might be confusing and problematic if 10 | # the server is to be restarted later on, as the client autospawn feature 11 | # might kick in. Also, a start of the socket unit will fail, adding to the 12 | # confusion. 13 | # 14 | # After=pipewire-pulse.socket is not needed, as it is already implicit in the 15 | # socket-service relationship, see systemd.socket(5). 16 | Requires=pipewire-pulse.socket 17 | ConditionUser=!root 18 | Wants=pipewire.service pipewire-session-manager.service 19 | After=pipewire.service pipewire-session-manager.service 20 | Conflicts=pulseaudio.service 21 | 22 | [Service] 23 | LockPersonality=yes 24 | MemoryDenyWriteExecute=yes 25 | NoNewPrivileges=yes 26 | RestrictNamespaces=yes 27 | SystemCallArchitectures=native 28 | SystemCallFilter=@system-service 29 | Type=simple 30 | ExecStart=@PW_PULSE_BINARY@ 31 | Restart=on-failure 32 | Slice=session.slice 33 | 34 | [Install] 35 | Also=pipewire-pulse.socket 36 | WantedBy=default.target 37 | -------------------------------------------------------------------------------- /src/daemon/systemd/user/pipewire-pulse.socket: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=PipeWire PulseAudio 3 | ConditionUser=!root 4 | Conflicts=pulseaudio.socket 5 | 6 | [Socket] 7 | Priority=6 8 | ListenStream=%t/pulse/native 9 | 10 | [Install] 11 | WantedBy=sockets.target 12 | -------------------------------------------------------------------------------- /src/daemon/systemd/user/pipewire.service.in: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=PipeWire Multimedia Service 3 | 4 | # We require pipewire.socket to be active before starting the daemon, because 5 | # while it is possible to use the service without the socket, it is not clear 6 | # why it would be desirable. 7 | # 8 | # A user installing pipewire and doing `systemctl --user start pipewire` 9 | # will not get the socket started, which might be confusing and problematic if 10 | # the server is to be restarted later on, as the client autospawn feature 11 | # might kick in. Also, a start of the socket unit will fail, adding to the 12 | # confusion. 13 | # 14 | # After=pipewire.socket is not needed, as it is already implicit in the 15 | # socket-service relationship, see systemd.socket(5). 16 | Requires=pipewire.socket @PW_SERVICE_REQS@ 17 | ConditionUser=!root 18 | 19 | [Service] 20 | LockPersonality=yes 21 | MemoryDenyWriteExecute=yes 22 | NoNewPrivileges=yes 23 | RestrictNamespaces=yes 24 | SystemCallArchitectures=native 25 | SystemCallFilter=@system-service 26 | Type=simple 27 | ExecStart=@PW_BINARY@ 28 | Restart=on-failure 29 | Slice=session.slice 30 | 31 | [Install] 32 | Also=pipewire.socket 33 | WantedBy=default.target 34 | -------------------------------------------------------------------------------- /src/daemon/systemd/user/pipewire.socket: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=PipeWire Multimedia System Sockets 3 | ConditionUser=!root 4 | 5 | [Socket] 6 | Priority=6 7 | ListenStream=%t/pipewire-0 8 | ListenStream=%t/pipewire-0-manager 9 | 10 | [Install] 11 | WantedBy=sockets.target 12 | -------------------------------------------------------------------------------- /src/gst/.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | indent_style = space 3 | indent_size = 2 4 | end_of_line = lf 5 | charset = utf-8 6 | trim_trailing_whitespace = true 7 | insert_final_newline = true 8 | -------------------------------------------------------------------------------- /src/gst/gstpipewireclock.h: -------------------------------------------------------------------------------- 1 | /* GStreamer */ 2 | /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef __GST_PIPEWIRE_CLOCK_H__ 6 | #define __GST_PIPEWIRE_CLOCK_H__ 7 | 8 | #include "config.h" 9 | #include "gstpipewirestream.h" 10 | 11 | #include 12 | #include 13 | 14 | G_BEGIN_DECLS 15 | 16 | #define GST_TYPE_PIPEWIRE_CLOCK (gst_pipewire_clock_get_type()) 17 | G_DECLARE_FINAL_TYPE (GstPipeWireClock, gst_pipewire_clock, GST, PIPEWIRE_CLOCK, GstSystemClock) 18 | 19 | struct _GstPipeWireClock { 20 | GstSystemClock parent; 21 | 22 | GWeakRef stream; 23 | 24 | GstClockTime last_time; 25 | GstClockTimeDiff time_offset; 26 | }; 27 | 28 | GstClock * gst_pipewire_clock_new (GstPipeWireStream *stream, 29 | GstClockTime last_time); 30 | void gst_pipewire_clock_reset (GstPipeWireClock *clock, 31 | GstClockTime time); 32 | 33 | G_END_DECLS 34 | 35 | #endif /* __GST_PIPEWIRE_CLOCK_H__ */ 36 | -------------------------------------------------------------------------------- /src/gst/gstpipewirecore.h: -------------------------------------------------------------------------------- 1 | /* GStreamer */ 2 | /* SPDX-FileCopyrightText: Copyright © 2020 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef __GST_PIPEWIRE_CORE_H__ 6 | #define __GST_PIPEWIRE_CORE_H__ 7 | 8 | #include 9 | 10 | #include 11 | 12 | G_BEGIN_DECLS 13 | 14 | typedef struct _GstPipeWireCore GstPipeWireCore; 15 | 16 | #define GST_PIPEWIRE_DEFAULT_TIMEOUT 30 17 | 18 | /** 19 | * GstPipeWireCore: 20 | * 21 | * Opaque data structure. 22 | */ 23 | struct _GstPipeWireCore { 24 | gint refcount; 25 | int fd; 26 | struct pw_thread_loop *loop; 27 | struct pw_context *context; 28 | struct pw_core *core; 29 | struct spa_hook core_listener; 30 | int last_error; 31 | int last_seq; 32 | int pending_seq; 33 | }; 34 | 35 | GstPipeWireCore *gst_pipewire_core_get (int fd); 36 | void gst_pipewire_core_release (GstPipeWireCore *core); 37 | 38 | G_END_DECLS 39 | 40 | #endif /* __GST_PIPEWIRE_CORE_H__ */ 41 | -------------------------------------------------------------------------------- /src/gst/gstpipewireformat.h: -------------------------------------------------------------------------------- 1 | /* GStreamer */ 2 | /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef _GST_PIPEWIRE_FORMAT_H_ 6 | #define _GST_PIPEWIRE_FORMAT_H_ 7 | 8 | #include 9 | 10 | #include 11 | 12 | G_BEGIN_DECLS 13 | 14 | GPtrArray * gst_caps_to_format_all (GstCaps *caps); 15 | 16 | GstCaps * gst_caps_from_format (const struct spa_pod *format); 17 | 18 | void gst_caps_sanitize (GstCaps **caps); 19 | 20 | void gst_caps_maybe_fixate_dma_format (GstCaps *caps); 21 | 22 | G_END_DECLS 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/gst/meson.build: -------------------------------------------------------------------------------- 1 | pipewire_gst_sources = [ 2 | 'gstpipewire.c', 3 | 'gstpipewirecore.c', 4 | 'gstpipewireclock.c', 5 | 'gstpipewireformat.c', 6 | 'gstpipewirepool.c', 7 | 'gstpipewiresink.c', 8 | 'gstpipewiresrc.c', 9 | 'gstpipewirestream.c', 10 | ] 11 | 12 | if get_option('gstreamer-device-provider').allowed() 13 | pipewire_gst_sources += [ 'gstpipewiredeviceprovider.c' ] 14 | endif 15 | 16 | pipewire_gst_headers = [ 17 | 'gstpipewireclock.h', 18 | 'gstpipewirecore.h', 19 | 'gstpipewiredeviceprovider.h', 20 | 'gstpipewireformat.h', 21 | 'gstpipewirepool.h', 22 | 'gstpipewiresink.h', 23 | 'gstpipewiresrc.h', 24 | 'gstpipewirestream.h', 25 | ] 26 | 27 | pipewire_gst = shared_library('gstpipewire', 28 | pipewire_gst_sources, 29 | include_directories : [ configinc ], 30 | dependencies : [ spa_dep, gst_dep, pipewire_dep, mathlib ], 31 | install : true, 32 | install_dir : '@0@/gstreamer-1.0'.format(get_option('libdir')), 33 | ) 34 | 35 | plugins = [pipewire_gst] 36 | -------------------------------------------------------------------------------- /src/meson.build: -------------------------------------------------------------------------------- 1 | 2 | subdir('pipewire') 3 | subdir('daemon') 4 | subdir('tools') 5 | subdir('modules') 6 | subdir('examples') 7 | if get_option('tests').allowed() 8 | subdir('tests') 9 | endif 10 | 11 | if gst_dep.length() != 0 12 | subdir('gst') 13 | endif 14 | -------------------------------------------------------------------------------- /src/modules/module-adapter/adapter.h: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2019 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef PIPEWIRE_ADAPTER_H 6 | #define PIPEWIRE_ADAPTER_H 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | #define ADAPTER_USAGE PW_KEY_NODE_NAME"= " 15 | 16 | struct pw_impl_node * 17 | pw_adapter_new(struct pw_context *context, 18 | struct spa_node *follower, 19 | struct pw_properties *properties, 20 | size_t user_data_size); 21 | 22 | void *pw_adapter_get_user_data(struct pw_impl_node *node); 23 | 24 | #ifdef __cplusplus 25 | } 26 | #endif 27 | 28 | #endif /* PIPEWIRE_ADAPTER_H */ 29 | -------------------------------------------------------------------------------- /src/modules/module-avb/avb.h: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2022 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef PIPEWIRE_AVB_H 6 | #define PIPEWIRE_AVB_H 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | struct pw_context; 15 | struct pw_properties; 16 | struct pw_avb; 17 | 18 | struct pw_avb *pw_avb_new(struct pw_context *context, 19 | struct pw_properties *props, size_t user_data_size); 20 | void pw_avb_destroy(struct pw_avb *avb); 21 | 22 | #ifdef __cplusplus 23 | } /* extern "C" */ 24 | #endif 25 | 26 | #endif /* PIPEWIRE_AVB_H */ 27 | -------------------------------------------------------------------------------- /src/modules/module-avb/mmrp.h: -------------------------------------------------------------------------------- 1 | /* AVB support */ 2 | /* SPDX-FileCopyrightText: Copyright © 2022 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef AVB_MMRP_H 6 | #define AVB_MMRP_H 7 | 8 | #include "mrp.h" 9 | #include "internal.h" 10 | 11 | #define AVB_MMRP_ETH 0x88f6 12 | #define AVB_MMRP_MAC { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x20 } 13 | 14 | #define AVB_MMRP_ATTRIBUTE_TYPE_SERVICE_REQUIREMENT 1 15 | #define AVB_MMRP_ATTRIBUTE_TYPE_MAC 2 16 | #define AVB_MMRP_ATTRIBUTE_TYPE_VALID(t) ((t)>=1 && (t)<=2) 17 | 18 | struct avb_packet_mmrp_msg { 19 | uint8_t attribute_type; 20 | uint8_t attribute_length; 21 | uint8_t attribute_list[0]; 22 | } __attribute__ ((__packed__)); 23 | 24 | struct avb_packet_mmrp_service_requirement { 25 | unsigned char addr[6]; 26 | } __attribute__ ((__packed__)); 27 | 28 | struct avb_packet_mmrp_mac { 29 | unsigned char addr[6]; 30 | } __attribute__ ((__packed__)); 31 | 32 | struct avb_mmrp; 33 | 34 | struct avb_mmrp_attribute { 35 | struct avb_mrp_attribute *mrp; 36 | uint8_t type; 37 | union { 38 | struct avb_packet_mmrp_service_requirement service_requirement; 39 | struct avb_packet_mmrp_mac mac; 40 | } attr; 41 | }; 42 | 43 | struct avb_mmrp_attribute *avb_mmrp_attribute_new(struct avb_mmrp *mmrp, 44 | uint8_t type); 45 | 46 | struct avb_mmrp *avb_mmrp_register(struct server *server); 47 | 48 | #endif /* AVB_MMRP_H */ 49 | -------------------------------------------------------------------------------- /src/modules/module-avb/mvrp.h: -------------------------------------------------------------------------------- 1 | /* AVB support */ 2 | /* SPDX-FileCopyrightText: Copyright © 2022 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef AVB_MVRP_H 6 | #define AVB_MVRP_H 7 | 8 | #include "mrp.h" 9 | #include "internal.h" 10 | 11 | #define AVB_MVRP_ETH 0x88f5 12 | #define AVB_MVRP_MAC { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x21 }; 13 | 14 | struct avb_packet_mvrp_msg { 15 | uint8_t attribute_type; 16 | uint8_t attribute_length; 17 | uint8_t attribute_list[0]; 18 | } __attribute__ ((__packed__)); 19 | 20 | #define AVB_MVRP_ATTRIBUTE_TYPE_VID 1 21 | #define AVB_MVRP_ATTRIBUTE_TYPE_VALID(t) ((t)==1) 22 | 23 | struct avb_packet_mvrp_vid { 24 | uint16_t vlan; 25 | } __attribute__ ((__packed__)); 26 | 27 | struct avb_mvrp; 28 | 29 | struct avb_mvrp_attribute { 30 | struct avb_mrp_attribute *mrp; 31 | uint8_t type; 32 | union { 33 | struct avb_packet_mvrp_vid vid; 34 | } attr; 35 | }; 36 | 37 | struct avb_mvrp_attribute *avb_mvrp_attribute_new(struct avb_mvrp *mvrp, 38 | uint8_t type); 39 | 40 | struct avb_mvrp *avb_mvrp_register(struct server *server); 41 | 42 | #endif /* AVB_MVRP_H */ 43 | -------------------------------------------------------------------------------- /src/modules/module-avb/srp.c: -------------------------------------------------------------------------------- 1 | /* AVB support */ 2 | /* SPDX-FileCopyrightText: Copyright © 2022 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include 6 | 7 | #include "srp.h" 8 | 9 | struct srp { 10 | struct server *server; 11 | struct spa_hook server_listener; 12 | }; 13 | 14 | static void srp_destroy(void *data) 15 | { 16 | struct srp *srp = data; 17 | spa_hook_remove(&srp->server_listener); 18 | free(srp); 19 | } 20 | 21 | static const struct server_events server_events = { 22 | AVB_VERSION_SERVER_EVENTS, 23 | .destroy = srp_destroy, 24 | }; 25 | 26 | int avb_srp_register(struct server *server) 27 | { 28 | struct srp *srp; 29 | 30 | srp = calloc(1, sizeof(*srp)); 31 | if (srp == NULL) 32 | return -errno; 33 | 34 | srp->server = server; 35 | 36 | avdecc_server_add_listener(server, &srp->server_listener, &server_events, srp); 37 | 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /src/modules/module-avb/srp.h: -------------------------------------------------------------------------------- 1 | /* AVB support */ 2 | /* SPDX-FileCopyrightText: Copyright © 2022 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef AVB_SRP_H 6 | #define AVB_SRP_H 7 | 8 | #include "internal.h" 9 | 10 | int avb_srp_register(struct server *server); 11 | 12 | #endif /* AVB_SRP_H */ 13 | -------------------------------------------------------------------------------- /src/modules/module-client-device/client-device.h: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2019 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef PIPEWIRE_CLIENT_DEVICE_H 6 | #define PIPEWIRE_CLIENT_DEVICE_H 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | #define CLIENT_DEVICE_USAGE "["PW_KEY_DEVICE_NAME"=]" 15 | 16 | struct pw_impl_device * 17 | pw_client_device_new(struct pw_resource *resource, 18 | struct pw_properties *properties); 19 | 20 | #ifdef __cplusplus 21 | } 22 | #endif 23 | 24 | #endif /* PIPEWIRE_CLIENT_DEVICE_H */ 25 | -------------------------------------------------------------------------------- /src/modules/module-client-node/client-node.h: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef PIPEWIRE_CLIENT_NODE_H 6 | #define PIPEWIRE_CLIENT_NODE_H 7 | 8 | #include 9 | #include 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | /** \class pw_impl_client_node 16 | * 17 | * PipeWire client node interface 18 | */ 19 | struct pw_impl_client_node { 20 | struct pw_impl_node *node; 21 | 22 | struct pw_resource *resource; 23 | uint32_t flags; 24 | }; 25 | 26 | struct pw_impl_client_node * 27 | pw_impl_client_node_new(struct pw_resource *resource, 28 | struct pw_properties *properties, 29 | bool do_register); 30 | 31 | void 32 | pw_impl_client_node_destroy(struct pw_impl_client_node *node); 33 | 34 | void pw_impl_client_node_registered(struct pw_impl_client_node *node, struct pw_global *global); 35 | 36 | #ifdef __cplusplus 37 | } 38 | #endif 39 | 40 | #endif /* PIPEWIRE_CLIENT_NODE_H */ 41 | -------------------------------------------------------------------------------- /src/modules/module-client-node/v0/transport.h: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2016 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef __PIPEWIRE_CLIENT_NODE0_TRANSPORT_H__ 6 | #define __PIPEWIRE_CLIENT_NODE0_TRANSPORT_H__ 7 | 8 | #include 9 | 10 | #include 11 | 12 | #include 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | /** information about the transport region \memberof pw_client_node */ 19 | struct pw_client_node0_transport_info { 20 | int memfd; /**< the memfd of the transport area */ 21 | uint32_t offset; /**< offset to map \a memfd at */ 22 | uint32_t size; /**< size of memfd mapping */ 23 | }; 24 | 25 | struct pw_client_node0_transport * 26 | pw_client_node0_transport_new(struct pw_context *context, uint32_t max_input_ports, uint32_t max_output_ports); 27 | 28 | struct pw_client_node0_transport * 29 | pw_client_node0_transport_new_from_info(struct pw_client_node0_transport_info *info); 30 | 31 | int 32 | pw_client_node0_transport_get_info(struct pw_client_node0_transport *trans, 33 | struct pw_client_node0_transport_info *info); 34 | 35 | #ifdef __cplusplus 36 | } /* extern "C" */ 37 | #endif 38 | 39 | #endif /* __PIPEWIRE_CLIENT_NODE0_TRANSPORT_H__ */ 40 | -------------------------------------------------------------------------------- /src/modules/module-protocol-native/defs.h: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | int pw_protocol_native_connect_local_socket(struct pw_protocol_client *client, 6 | const struct spa_dict *props, 7 | void (*done_callback) (void *data, int res), 8 | void *data); 9 | int pw_protocol_native_connect_portal_screencast(struct pw_protocol_client *client, 10 | const struct spa_dict *props, 11 | void (*done_callback) (void *data, int res), 12 | void *data); 13 | 14 | static inline void *get_first_pod_from_data(void *data, uint32_t maxsize, uint64_t offset) 15 | { 16 | void *pod; 17 | if (maxsize <= offset) 18 | return NULL; 19 | 20 | /* spa_pod_parser_advance() rounds up, so round down here to compensate */ 21 | maxsize = SPA_ROUND_DOWN_N(maxsize - offset, 8); 22 | if (maxsize < sizeof(struct spa_pod)) 23 | return NULL; 24 | 25 | pod = SPA_PTROFF(data, offset, void); 26 | if (SPA_POD_BODY_SIZE(pod) > maxsize - sizeof(struct spa_pod)) 27 | return NULL; 28 | return pod; 29 | } 30 | 31 | struct protocol_compat_v2 { 32 | /* v2 typemap */ 33 | struct pw_map types; 34 | unsigned int send_types:1; 35 | }; 36 | -------------------------------------------------------------------------------- /src/modules/module-protocol-native/portal-screencast.c: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | int pw_protocol_native_connect_portal_screencast(struct pw_protocol_client *client, 16 | const struct spa_dict *props, 17 | void (*done_callback) (void *data, int res), 18 | void *data) 19 | { 20 | return -ENOTSUP; 21 | } 22 | -------------------------------------------------------------------------------- /src/modules/module-protocol-native/protocol-footer.h: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | /* 6 | * Protocol footer. 7 | * 8 | * For passing around general state data that is not associated with 9 | * messages sent to objects. 10 | */ 11 | 12 | enum { 13 | FOOTER_CORE_OPCODE_GENERATION = 0, 14 | FOOTER_CORE_OPCODE_LAST 15 | }; 16 | 17 | enum { 18 | FOOTER_CLIENT_OPCODE_GENERATION = 0, 19 | FOOTER_CLIENT_OPCODE_LAST 20 | }; 21 | 22 | struct footer_core_global_state { 23 | uint64_t last_recv_generation; 24 | }; 25 | 26 | struct footer_client_global_state { 27 | }; 28 | 29 | struct footer_demarshal { 30 | int (*demarshal)(void *object, struct spa_pod_parser *parser); 31 | }; 32 | 33 | extern const struct footer_demarshal footer_core_demarshal[FOOTER_CORE_OPCODE_LAST]; 34 | extern const struct footer_demarshal footer_client_demarshal[FOOTER_CLIENT_OPCODE_LAST]; 35 | 36 | void marshal_core_footers(struct footer_core_global_state *state, struct pw_core *core, 37 | struct spa_pod_builder *builder); 38 | void marshal_client_footers(struct footer_client_global_state *state, struct pw_impl_client *client, 39 | struct spa_pod_builder *builder); 40 | -------------------------------------------------------------------------------- /src/modules/module-protocol-pulse/cmd.h: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2022 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef PULSER_SERVER_CMD_H 6 | #define PULSER_SERVER_CMD_H 7 | 8 | #include "internal.h" 9 | 10 | int cmd_run(struct impl *impl); 11 | 12 | #endif /* PULSER_SERVER_CMD_H */ 13 | -------------------------------------------------------------------------------- /src/modules/module-protocol-pulse/dbus-name.h: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2019 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef PULSE_SERVER_DBUS_NAME_H 6 | #define PULSE_SERVER_DBUS_NAME_H 7 | 8 | struct pw_context; 9 | 10 | void *dbus_request_name(struct pw_context *context, const char *name); 11 | void dbus_release_name(void *data); 12 | 13 | #endif /* PULSE_SERVER_DBUS_NAME_H */ 14 | -------------------------------------------------------------------------------- /src/modules/module-protocol-pulse/extension.c: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2020 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include 6 | #include 7 | 8 | #include "client.h" 9 | #include "defs.h" 10 | #include "extension.h" 11 | #include "message.h" 12 | #include "module.h" 13 | 14 | static const struct extension *find_extension_command(struct module *module, uint32_t command) 15 | { 16 | uint32_t i; 17 | 18 | if (module->info->extension == NULL) 19 | return NULL; 20 | 21 | for (i = 0; module->info->extension[i].name; i++) { 22 | if (module->info->extension[i].command == command) 23 | return &module->info->extension[i]; 24 | } 25 | return NULL; 26 | } 27 | 28 | int extension_process(struct module *module, struct client *client, uint32_t tag, struct message *m) 29 | { 30 | uint32_t command; 31 | const struct extension *ext; 32 | int res; 33 | 34 | if ((res = message_get(m, 35 | TAG_U32, &command, 36 | TAG_INVALID)) < 0) 37 | return -EPROTO; 38 | 39 | ext = find_extension_command(module, command); 40 | if (ext == NULL) 41 | return -ENOTSUP; 42 | if (ext->process == NULL) 43 | return -EPROTO; 44 | 45 | pw_log_info("client %p [%s]: %s %s tag:%u", 46 | client, client->name, module->info->name, ext->name, tag); 47 | 48 | return ext->process(module, client, command, tag, m); 49 | } 50 | -------------------------------------------------------------------------------- /src/modules/module-protocol-pulse/extension.h: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2020 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef PULSE_SERVER_EXTENSION_H 6 | #define PULSE_SERVER_EXTENSION_H 7 | 8 | #include 9 | 10 | struct client; 11 | struct message; 12 | struct module; 13 | 14 | struct extension { 15 | const char *name; 16 | uint32_t command; 17 | int (*process)(struct module *module, struct client *client, uint32_t command, 18 | uint32_t tag, struct message *m); 19 | }; 20 | 21 | int extension_process(struct module *module, struct client *client, uint32_t tag, struct message *m); 22 | 23 | #endif /* PULSE_SERVER_EXTENSION_H */ 24 | -------------------------------------------------------------------------------- /src/modules/module-protocol-pulse/log.h: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2021 Red Hat, Inc. */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef PULSE_LOG_H 6 | #define PULSE_LOG_H 7 | 8 | #include 9 | 10 | PW_LOG_TOPIC_EXTERN(mod_topic); 11 | #define PW_LOG_TOPIC_DEFAULT mod_topic 12 | 13 | #endif /* PULSE_LOG_H */ 14 | -------------------------------------------------------------------------------- /src/modules/module-protocol-pulse/message-handler.h: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2021 Pauli Virtanen */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef PULSE_SERVER_MESSAGE_HANDLER_H 6 | #define PULSE_SERVER_MESSAGE_HANDLER_H 7 | 8 | struct pw_manager_object; 9 | 10 | void register_object_message_handlers(struct pw_manager_object *o); 11 | 12 | #endif /* PULSE_SERVER_MESSAGE_HANDLER_H */ 13 | -------------------------------------------------------------------------------- /src/modules/module-protocol-pulse/operation.h: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2020 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef PULSER_SERVER_OPERATION_H 6 | #define PULSER_SERVER_OPERATION_H 7 | 8 | #include 9 | 10 | #include 11 | 12 | struct client; 13 | 14 | struct operation { 15 | struct spa_list link; 16 | struct client *client; 17 | uint32_t tag; 18 | void (*callback) (void *data, struct client *client, uint32_t tag); 19 | void *data; 20 | }; 21 | 22 | int operation_new(struct client *client, uint32_t tag); 23 | int operation_new_cb(struct client *client, uint32_t tag, 24 | void (*callback) (void *data, struct client *client, uint32_t tag), 25 | void *data); 26 | struct operation *operation_find(struct client *client, uint32_t tag); 27 | void operation_free(struct operation *o); 28 | void operation_complete(struct operation *o); 29 | 30 | static inline void operation_free_by_tag(struct client *client, uint32_t tag) 31 | { 32 | struct operation *o = operation_find(client, tag); 33 | if (o) 34 | operation_free(o); 35 | } 36 | 37 | #endif /* PULSER_SERVER_OPERATION_H */ 38 | -------------------------------------------------------------------------------- /src/modules/module-protocol-pulse/pending-sample.h: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2020 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef PULSE_SERVER_PENDING_SAMPLE_H 6 | #define PULSE_SERVER_PENDING_SAMPLE_H 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | struct client; 14 | struct pw_properties; 15 | struct sample; 16 | struct sample_play; 17 | 18 | struct pending_sample { 19 | struct spa_list link; 20 | struct client *client; 21 | struct sample_play *play; 22 | struct spa_hook listener; 23 | struct spa_hook client_listener; 24 | uint32_t tag; 25 | unsigned replied:1; 26 | unsigned done:1; 27 | }; 28 | 29 | int pending_sample_new(struct client *client, struct sample *sample, struct pw_properties *props, uint32_t tag); 30 | void pending_sample_free(struct pending_sample *ps); 31 | 32 | #endif /* PULSE_SERVER_PENDING_SAMPLE_H */ 33 | -------------------------------------------------------------------------------- /src/modules/module-protocol-pulse/pulse-server.h: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2020 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef PIPEWIRE_PROTOCOL_PULSE_H 6 | #define PIPEWIRE_PROTOCOL_PULSE_H 7 | 8 | #include 9 | #include 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | #define PW_PROTOCOL_PULSE_DEFAULT_PORT 4713 16 | #define PW_PROTOCOL_PULSE_DEFAULT_SOCKET "native" 17 | 18 | #define PW_PROTOCOL_PULSE_DEFAULT_SERVER "unix:"PW_PROTOCOL_PULSE_DEFAULT_SOCKET 19 | 20 | #define PW_PROTOCOL_PULSE_USAGE "[ server.address=(tcp:[:]|unix:)[,...] ] " \ 21 | 22 | struct pw_context; 23 | struct pw_properties; 24 | struct pw_protocol_pulse; 25 | struct pw_protocol_pulse_server; 26 | 27 | struct pw_protocol_pulse *pw_protocol_pulse_new(struct pw_context *context, 28 | struct pw_properties *props, size_t user_data_size); 29 | void *pw_protocol_pulse_get_user_data(struct pw_protocol_pulse *pulse); 30 | void pw_protocol_pulse_destroy(struct pw_protocol_pulse *pulse); 31 | 32 | #ifdef __cplusplus 33 | } /* extern "C" */ 34 | #endif 35 | 36 | #endif /* PIPEWIRE_PROTOCOL_PULSE_H */ 37 | -------------------------------------------------------------------------------- /src/modules/module-protocol-pulse/quirks.h: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2021 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef PULSER_SERVER_QUIRKS_H 6 | #define PULSER_SERVER_QUIRKS_H 7 | 8 | #include "client.h" 9 | 10 | #define QUIRK_FORCE_S16_FORMAT (1ull<<0) /** forces S16 sample format in sink and source 11 | * info */ 12 | #define QUIRK_REMOVE_CAPTURE_DONT_MOVE (1ull<<1) /** removes the capture stream DONT_MOVE flag */ 13 | #define QUIRK_BLOCK_SOURCE_VOLUME (1ull<<2) /** block volume changes to sources */ 14 | #define QUIRK_BLOCK_SINK_VOLUME (1ull<<3) /** block volume changes to sinks */ 15 | #define QUIRK_BLOCK_RECORD_STREAM (1ull<<4) /** block creating a record stream */ 16 | #define QUIRK_BLOCK_PLAYBACK_STREAM (1ull<<5) /** block creating a playback stream */ 17 | 18 | int client_update_quirks(struct client *client); 19 | 20 | #endif /* PULSER_SERVER_QUIRKS_H */ 21 | -------------------------------------------------------------------------------- /src/modules/module-protocol-pulse/remap.c: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2020 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include 6 | 7 | #include 8 | 9 | #include "remap.h" 10 | 11 | const struct str_map media_role_map[] = { 12 | { "Movie", "video", }, 13 | { "Music", "music", }, 14 | { "Game", "game", }, 15 | { "Notification", "event", }, 16 | { "Communication", "phone", }, 17 | { "Movie", "animation", }, 18 | { "Production", "production", }, 19 | { "Accessibility", "a11y", }, 20 | { "Test", "test", }, 21 | { NULL, NULL }, 22 | }; 23 | 24 | const struct str_map props_key_map[] = { 25 | { PW_KEY_DEVICE_BUS_PATH, "device.bus_path" }, 26 | { PW_KEY_DEVICE_SYSFS_PATH, "sysfs.path" }, 27 | { PW_KEY_DEVICE_FORM_FACTOR, "device.form_factor" }, 28 | { PW_KEY_DEVICE_ICON_NAME, "device.icon_name" }, 29 | { PW_KEY_DEVICE_INTENDED_ROLES, "device.intended_roles" }, 30 | { PW_KEY_NODE_DESCRIPTION, "device.description" }, 31 | { PW_KEY_MEDIA_ICON_NAME, "media.icon_name" }, 32 | { PW_KEY_APP_ICON_NAME, "application.icon_name" }, 33 | { PW_KEY_APP_PROCESS_MACHINE_ID, "application.process.machine_id" }, 34 | { PW_KEY_APP_PROCESS_SESSION_ID, "application.process.session_id" }, 35 | { PW_KEY_MEDIA_ROLE, "media.role", media_role_map }, 36 | { "pipe.filename", "device.string" }, 37 | { NULL, NULL }, 38 | }; 39 | -------------------------------------------------------------------------------- /src/modules/module-protocol-pulse/remap.h: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2020 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef PULSE_SERVER_REMAP_H 6 | #define PULSE_SERVER_REMAP_H 7 | 8 | #include 9 | 10 | #include 11 | 12 | struct str_map { 13 | const char *pw_str; 14 | const char *pa_str; 15 | const struct str_map *child; 16 | }; 17 | 18 | extern const struct str_map media_role_map[]; 19 | 20 | extern const struct str_map props_key_map[]; 21 | 22 | static inline const struct str_map *str_map_find(const struct str_map *map, const char *pw, const char *pa) 23 | { 24 | size_t i; 25 | for (i = 0; map[i].pw_str; i++) 26 | if ((pw && spa_streq(map[i].pw_str, pw)) || 27 | (pa && spa_streq(map[i].pa_str, pa))) 28 | return &map[i]; 29 | return NULL; 30 | } 31 | 32 | #endif /* PULSE_SERVER_REMAP_H */ 33 | -------------------------------------------------------------------------------- /src/modules/module-protocol-pulse/reply.h: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2020 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef PULSE_SERVER_REPLY_H 6 | #define PULSE_SERVER_REPLY_H 7 | 8 | #include 9 | 10 | #include "client.h" 11 | 12 | struct message; 13 | 14 | struct message *reply_new(const struct client *client, uint32_t tag); 15 | int reply_error(struct client *client, uint32_t command, uint32_t tag, int res); 16 | 17 | static inline int reply_simple_ack(struct client *client, uint32_t tag) 18 | { 19 | return client_queue_message(client, reply_new(client, tag)); 20 | } 21 | 22 | #endif /* PULSE_SERVER_REPLY_H */ 23 | -------------------------------------------------------------------------------- /src/modules/module-protocol-pulse/sample.c: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2020 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include "internal.h" 12 | #include "log.h" 13 | #include "sample.h" 14 | 15 | void sample_free(struct sample *sample) 16 | { 17 | struct impl * const impl = sample->impl; 18 | 19 | pw_log_info("free sample id:%u name:%s", sample->index, sample->name); 20 | 21 | impl->stat.sample_cache -= sample->length; 22 | 23 | if (sample->index != SPA_ID_INVALID) 24 | pw_map_remove(&impl->samples, sample->index); 25 | 26 | pw_properties_free(sample->props); 27 | 28 | free(sample->buffer); 29 | free(sample); 30 | } 31 | -------------------------------------------------------------------------------- /src/modules/module-protocol-pulse/sample.h: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2020 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef PULSE_SERVER_SAMPLE_H 6 | #define PULSE_SERVER_SAMPLE_H 7 | 8 | #include 9 | 10 | #include "format.h" 11 | 12 | struct impl; 13 | struct pw_properties; 14 | 15 | struct sample { 16 | int ref; 17 | uint32_t index; 18 | struct impl *impl; 19 | const char *name; 20 | struct sample_spec ss; 21 | struct channel_map map; 22 | struct pw_properties *props; 23 | uint32_t length; 24 | uint8_t *buffer; 25 | }; 26 | 27 | void sample_free(struct sample *sample); 28 | 29 | static inline struct sample *sample_ref(struct sample *sample) 30 | { 31 | sample->ref++; 32 | return sample; 33 | } 34 | 35 | static inline void sample_unref(struct sample *sample) 36 | { 37 | if (--sample->ref == 0) 38 | sample_free(sample); 39 | } 40 | 41 | #endif /* PULSE_SERVER_SAMPLE_H */ 42 | -------------------------------------------------------------------------------- /src/modules/module-protocol-pulse/server.h: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2020 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef PULSER_SERVER_SERVER_H 6 | #define PULSER_SERVER_SERVER_H 7 | 8 | #include 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | struct impl; 16 | struct pw_array; 17 | struct spa_source; 18 | 19 | struct server { 20 | struct spa_list link; 21 | struct impl *impl; 22 | 23 | struct sockaddr_storage addr; 24 | 25 | struct spa_source *source; 26 | struct spa_list clients; 27 | 28 | uint32_t max_clients; 29 | uint32_t listen_backlog; 30 | char client_access[64]; 31 | 32 | uint32_t n_clients; 33 | uint32_t wait_clients; 34 | unsigned int activated:1; 35 | }; 36 | 37 | int servers_create_and_start(struct impl *impl, const char *addresses, struct pw_array *servers); 38 | void server_free(struct server *server); 39 | 40 | #endif /* PULSER_SERVER_SERVER_H */ 41 | -------------------------------------------------------------------------------- /src/modules/module-protocol-pulse/snap-policy.h: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2022 Canonical Ltd. */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef _SNAP_POLICY_H_ 6 | #define _SNAP_POLICY_H_ 7 | 8 | typedef enum _pw_sandbox_access { 9 | PW_SANDBOX_ACCESS_NONE = 0, 10 | PW_SANDBOX_ACCESS_NOT_A_SANDBOX = 1 << 0, 11 | PW_SANDBOX_ACCESS_RECORD = 1 << 1, 12 | PW_SANDBOX_ACCESS_PLAYBACK = 1 << 2, 13 | PW_SANDBOX_ACCESS_ALL = (PW_SANDBOX_ACCESS_PLAYBACK | PW_SANDBOX_ACCESS_RECORD), 14 | } pw_sandbox_access_t; 15 | 16 | #define PW_KEY_SNAP_ID "pipewire.snap.id" 17 | #define PW_KEY_SNAP_PLAYBACK_ALLOWED "pipewire.snap.audio.playback" 18 | #define PW_KEY_SNAP_RECORD_ALLOWED "pipewire.snap.audio.record" 19 | 20 | pw_sandbox_access_t pw_snap_get_audio_permissions(struct client *client, int fd, char **app_id); 21 | 22 | #endif // _SNAP_POLICY_H_ 23 | -------------------------------------------------------------------------------- /src/modules/module-protocol-pulse/utils.h: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2020 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef PULSE_SERVER_UTILS_H 6 | #define PULSE_SERVER_UTILS_H 7 | 8 | #include 9 | #include 10 | 11 | struct client; 12 | struct pw_context; 13 | 14 | int get_runtime_dir(char *buf, size_t buflen); 15 | int check_flatpak(struct client *client, pid_t pid); 16 | pid_t get_client_pid(struct client *client, int client_fd); 17 | const char *get_server_name(struct pw_context *context); 18 | int create_pid_file(void); 19 | int notify_startup(void); 20 | 21 | #endif /* PULSE_SERVER_UTILS_H */ 22 | -------------------------------------------------------------------------------- /src/modules/module-rt/20-pw-defaults.conf.in: -------------------------------------------------------------------------------- 1 | # This file was installed by PipeWire project for buffer locking to always work 2 | 3 | # Required to memlock audio buffers for all client types 4 | # 5 | # This will match all PAM users i.e. those going through the login procedure but 6 | # it should not get applied to system daemons, since they are run bypassing PAM. 7 | # 8 | # While at first glance this might appear very relevant, in fact abusing this 9 | # can at most allow for either more rapid OOM or enhance malicious system memory 10 | # thrashing while evading systemd-oomd limits that are based on the requirement 11 | # that swap utilization must be high before issues arise. As such it's perfectly 12 | # reasonable to just set a limit where each client can lock a few megabytes with 13 | # nearly no impact on regular systems. Meanwhile malicious attackers can OOM 14 | # just as they could. And instead tooling for OOM and resource abuse should be 15 | # improved, if such denial of service attacks are a serious consideration at all. 16 | # 17 | # Starting with Linux 5.16 or systemd v253 the default is 8192 which is plenty 18 | # good enough and this file should not be installed on such systems. 19 | # 20 | * - memlock @PAM_MEMLOCK@ 21 | -------------------------------------------------------------------------------- /src/modules/module-rt/25-pw-rlimits.conf.in: -------------------------------------------------------------------------------- 1 | # This file was installed by PipeWire project for its libpipewire-module-rt.so 2 | 3 | # It is up to the distribution/user to create the @MATCH@ group and to add the 4 | # relevant users to the group. 5 | # 6 | # PipeWire will fall back to the RTKit DBus service when the user is not able to 7 | # acquire RT priorities with rlimits. 8 | # 9 | # If the group is not automatically created, the match rule will never be true 10 | # and this file will have no effect. 11 | # 12 | @MATCH@ - rtprio @RTPRIO@ 13 | @MATCH@ - nice @NICE@ 14 | @MATCH@ - memlock @MEMLOCK@ 15 | -------------------------------------------------------------------------------- /src/modules/module-rtp/apple-midi.h: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2023 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef PIPEWIRE_APPLE_MIDI_H 6 | #define PIPEWIRE_APPLE_MIDI_H 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | struct rtp_apple_midi { 15 | uint32_t cmd; 16 | uint32_t protocol; 17 | uint32_t initiator; 18 | uint32_t ssrc; 19 | char name[0]; 20 | } __attribute__ ((packed)); 21 | 22 | struct rtp_apple_midi_ck { 23 | uint32_t cmd; 24 | uint32_t ssrc; 25 | uint8_t count; 26 | uint8_t padding[3]; 27 | uint32_t ts1_h; 28 | uint32_t ts1_l; 29 | uint32_t ts2_h; 30 | uint32_t ts2_l; 31 | uint32_t ts3_h; 32 | uint32_t ts3_l; 33 | } __attribute__ ((packed)); 34 | 35 | struct rtp_apple_midi_rs { 36 | uint32_t cmd; 37 | uint32_t ssrc; 38 | uint32_t seqnum; 39 | } __attribute__ ((packed)); 40 | 41 | #define APPLE_MIDI_CMD_IN (0xffff0000 | 'I'<<8 | 'N') 42 | #define APPLE_MIDI_CMD_NO (0xffff0000 | 'N'<<8 | 'O') 43 | #define APPLE_MIDI_CMD_OK (0xffff0000 | 'O'<<8 | 'K') 44 | #define APPLE_MIDI_CMD_CK (0xffff0000 | 'C'<<8 | 'K') 45 | #define APPLE_MIDI_CMD_BY (0xffff0000 | 'B'<<8 | 'Y') 46 | #define APPLE_MIDI_CMD_RS (0xffff0000 | 'R'<<8 | 'S') 47 | 48 | #ifdef __cplusplus 49 | } 50 | #endif 51 | 52 | #endif /* PIPEWIRE_APPLE_MIDI_H */ 53 | -------------------------------------------------------------------------------- /src/modules/module-rtp/sap.h: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2022 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef PIPEWIRE_SAP_H 6 | #define PIPEWIRE_SAP_H 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | struct sap_header { 13 | #if __BYTE_ORDER == __LITTLE_ENDIAN 14 | unsigned c:1; 15 | unsigned e:1; 16 | unsigned t:1; 17 | unsigned r:1; 18 | unsigned a:1; 19 | unsigned v:3; 20 | #elif __BYTE_ORDER == __BIG_ENDIAN 21 | unsigned v:3; 22 | unsigned a:1; 23 | unsigned r:1; 24 | unsigned t:1; 25 | unsigned e:1; 26 | unsigned c:1; 27 | #else 28 | #error "Unknown byte order" 29 | #endif 30 | uint8_t auth_len; 31 | uint16_t msg_id_hash; 32 | } __attribute__ ((packed)); 33 | 34 | #ifdef __cplusplus 35 | } 36 | #endif 37 | 38 | #endif /* PIPEWIRE_SAP_H */ 39 | -------------------------------------------------------------------------------- /src/modules/module-session-manager/client-endpoint/endpoint.h: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2019 Collabora Ltd. */ 3 | /* @author George Kiagiadakis */ 4 | /* SPDX-License-Identifier: MIT */ 5 | 6 | #ifndef MODULE_SESSION_MANAGER_ENDPOINT_H 7 | #define MODULE_SESSION_MANAGER_ENDPOINT_H 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | struct client_endpoint; 14 | 15 | struct endpoint { 16 | struct client_endpoint *client_ep; 17 | struct pw_global *global; 18 | uint32_t n_params; 19 | struct spa_pod **params; 20 | struct pw_endpoint_info info; 21 | struct pw_properties *props; /* wrapper of info.props */ 22 | }; 23 | 24 | int endpoint_init(struct endpoint *this, 25 | struct client_endpoint *client_ep, 26 | struct pw_context *context, 27 | struct pw_properties *properties); 28 | 29 | void endpoint_clear(struct endpoint *this); 30 | 31 | int endpoint_update(struct endpoint *this, 32 | uint32_t change_mask, 33 | uint32_t n_params, 34 | const struct spa_pod **params, 35 | const struct pw_endpoint_info *info); 36 | 37 | #ifdef __cplusplus 38 | } /* extern "C" */ 39 | #endif 40 | 41 | #endif /* MODULE_SESSION_MANAGER_ENDPOINT_H */ 42 | -------------------------------------------------------------------------------- /src/modules/module-session-manager/client-session/session.h: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2019 Collabora Ltd. */ 3 | /* @author George Kiagiadakis */ 4 | /* SPDX-License-Identifier: MIT */ 5 | 6 | #ifndef MODULE_SESSION_MANAGER_SESSION_H 7 | #define MODULE_SESSION_MANAGER_SESSION_H 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | struct client_session; 15 | 16 | struct session { 17 | struct client_session *client_sess; 18 | struct pw_global *global; 19 | uint32_t n_params; 20 | struct spa_pod **params; 21 | struct pw_session_info info; 22 | struct pw_properties *props; /* wrapper of info.props */ 23 | }; 24 | 25 | int session_init(struct session *this, 26 | struct client_session *client_sess, 27 | struct pw_context *context, 28 | struct pw_properties *properties); 29 | 30 | void session_clear(struct session *this); 31 | 32 | int session_update(struct session *this, 33 | uint32_t change_mask, 34 | uint32_t n_params, 35 | const struct spa_pod **params, 36 | const struct pw_session_info *info); 37 | 38 | #ifdef __cplusplus 39 | } /* extern "C" */ 40 | #endif 41 | 42 | #endif /* MODULE_SESSION_MANAGER_SESSION_H */ 43 | -------------------------------------------------------------------------------- /src/modules/module-zeroconf-discover/avahi-poll.h: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2021 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include 6 | 7 | #include 8 | 9 | AvahiPoll* pw_avahi_poll_new(struct pw_loop *loop); 10 | 11 | void pw_avahi_poll_free(AvahiPoll *p); 12 | -------------------------------------------------------------------------------- /src/modules/spa/spa-device.h: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef PIPEWIRE_SPA_DEVICE_H 6 | #define PIPEWIRE_SPA_DEVICE_H 7 | 8 | #include 9 | 10 | #include 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | enum pw_spa_device_flags { 17 | PW_SPA_DEVICE_FLAG_DISABLE = (1 << 0), 18 | PW_SPA_DEVICE_FLAG_NO_REGISTER = (1 << 1), 19 | }; 20 | 21 | struct pw_impl_device * 22 | pw_spa_device_new(struct pw_context *context, 23 | enum pw_spa_device_flags flags, 24 | struct spa_device *device, 25 | struct spa_handle *handle, 26 | struct pw_properties *properties, 27 | size_t user_data_size); 28 | 29 | struct pw_impl_device * 30 | pw_spa_device_load(struct pw_context *context, 31 | const char *factory_name, 32 | enum pw_spa_device_flags flags, 33 | struct pw_properties *properties, 34 | size_t user_data_size); 35 | 36 | void *pw_spa_device_get_user_data(struct pw_impl_device *device); 37 | 38 | #ifdef __cplusplus 39 | } 40 | #endif 41 | 42 | #endif /* PIPEWIRE_SPA_DEVICE_H */ 43 | -------------------------------------------------------------------------------- /src/modules/spa/spa-node.h: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef PIPEWIRE_SPA_NODE_H 6 | #define PIPEWIRE_SPA_NODE_H 7 | 8 | #include 9 | 10 | #include 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | enum pw_spa_node_flags { 17 | PW_SPA_NODE_FLAG_ACTIVATE = (1 << 0), 18 | PW_SPA_NODE_FLAG_NO_REGISTER = (1 << 1), 19 | PW_SPA_NODE_FLAG_ASYNC = (1 << 2), 20 | }; 21 | 22 | struct pw_impl_node * 23 | pw_spa_node_new(struct pw_context *context, 24 | enum pw_spa_node_flags flags, 25 | struct spa_node *node, 26 | struct spa_handle *handle, 27 | struct pw_properties *properties, 28 | size_t user_data_size); 29 | 30 | struct pw_impl_node * 31 | pw_spa_node_load(struct pw_context *context, 32 | const char *factory_name, 33 | enum pw_spa_node_flags flags, 34 | struct pw_properties *properties, 35 | size_t user_data_size); 36 | 37 | void *pw_spa_node_get_user_data(struct pw_impl_node *node); 38 | 39 | #ifdef __cplusplus 40 | } 41 | #endif 42 | 43 | #endif /* PIPEWIRE_SPA_NODE_H */ 44 | -------------------------------------------------------------------------------- /src/pipewire/extensions/meson.build: -------------------------------------------------------------------------------- 1 | pipewire_ext_sm_headers = [ 2 | 'session-manager/impl-interfaces.h', 3 | 'session-manager/interfaces.h', 4 | 'session-manager/introspect.h', 5 | 'session-manager/introspect-funcs.h', 6 | 'session-manager/keys.h', 7 | ] 8 | 9 | pipewire_ext_headers = [ 10 | 'client-node.h', 11 | 'metadata.h', 12 | 'profiler.h', 13 | 'protocol-native.h', 14 | 'security-context.h', 15 | 'session-manager.h', 16 | ] 17 | 18 | install_headers(pipewire_ext_sm_headers, 19 | subdir : pipewire_headers_dir / 'extensions' / 'session-manager') 20 | 21 | install_headers(pipewire_ext_headers, 22 | subdir : pipewire_headers_dir / 'extensions') 23 | -------------------------------------------------------------------------------- /src/pipewire/extensions/session-manager.h: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2019 Collabora Ltd. */ 3 | /* @author George Kiagiadakis */ 4 | /* SPDX-License-Identifier: MIT */ 5 | 6 | #ifndef PIPEWIRE_EXT_SESSION_MANAGER_H 7 | #define PIPEWIRE_EXT_SESSION_MANAGER_H 8 | 9 | /** \defgroup pw_session_manager Session Manager 10 | * Session manager interface 11 | */ 12 | 13 | /** 14 | * \addtogroup pw_session_manager 15 | * \{ 16 | */ 17 | 18 | #include "session-manager/introspect.h" 19 | #include "session-manager/interfaces.h" 20 | #include "session-manager/impl-interfaces.h" 21 | #include "session-manager/keys.h" 22 | 23 | /** 24 | * \} 25 | */ 26 | 27 | #endif /* PIPEWIRE_EXT_SESSION_MANAGER_H */ 28 | -------------------------------------------------------------------------------- /src/pipewire/i18n.h: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2021 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef PIPEWIRE_I18N_H 6 | #define PIPEWIRE_I18N_H 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | /** \defgroup pw_gettext Internationalization 15 | * Gettext interface 16 | */ 17 | 18 | /** 19 | * \addtogroup pw_gettext 20 | * \{ 21 | */ 22 | 23 | SPA_FORMAT_ARG_FUNC(1) const char *pw_gettext(const char *msgid); 24 | SPA_FORMAT_ARG_FUNC(1) const char *pw_ngettext(const char *msgid, const char *msgid_plural, unsigned long int n); 25 | 26 | #define _(String) (pw_gettext(String)) 27 | #define N_(String) (String) 28 | 29 | /** 30 | * \} 31 | */ 32 | 33 | #ifdef __cplusplus 34 | } 35 | #endif 36 | 37 | #endif /* PIPEWIRE_I18N_H */ 38 | -------------------------------------------------------------------------------- /src/pipewire/impl.h: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2019 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef PIPEWIRE_IMPL_H 6 | #define PIPEWIRE_IMPL_H 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | /** 13 | * \addtogroup api_pw_impl 14 | */ 15 | 16 | struct pw_impl_client; 17 | struct pw_impl_module; 18 | struct pw_global; 19 | struct pw_node; 20 | struct pw_impl_port; 21 | struct pw_resource; 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | #ifdef __cplusplus 39 | } 40 | #endif 41 | 42 | #endif /* PIPEWIRE_IMPL_H */ 43 | -------------------------------------------------------------------------------- /src/pipewire/type.h: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef PIPEWIRE_TYPE_H 6 | #define PIPEWIRE_TYPE_H 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | /** \defgroup pw_type Type info 15 | * Type information 16 | */ 17 | 18 | /** 19 | * \addtogroup pw_type 20 | * \{ 21 | */ 22 | 23 | enum { 24 | PW_TYPE_FIRST = SPA_TYPE_VENDOR_PipeWire, 25 | }; 26 | 27 | #define PW_TYPE_INFO_BASE "PipeWire:" 28 | 29 | #define PW_TYPE_INFO_Object PW_TYPE_INFO_BASE "Object" 30 | #define PW_TYPE_INFO_OBJECT_BASE PW_TYPE_INFO_Object ":" 31 | 32 | #define PW_TYPE_INFO_Interface PW_TYPE_INFO_BASE "Interface" 33 | #define PW_TYPE_INFO_INTERFACE_BASE PW_TYPE_INFO_Interface ":" 34 | 35 | const struct spa_type_info * pw_type_info(void); 36 | 37 | /** 38 | * \} 39 | */ 40 | 41 | #ifdef __cplusplus 42 | } 43 | #endif 44 | 45 | #endif /* PIPEWIRE_TYPE_H */ 46 | -------------------------------------------------------------------------------- /src/pipewire/work-queue.h: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #ifndef PIPEWIRE_WORK_QUEUE_H 6 | #define PIPEWIRE_WORK_QUEUE_H 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | /** \defgroup pw_work_queue Work Queue 13 | * Queued processing of work items. 14 | */ 15 | 16 | /** 17 | * \addtogroup pw_work_queue 18 | * \{ 19 | */ 20 | struct pw_work_queue; 21 | 22 | #include 23 | 24 | typedef void (*pw_work_func_t) (void *obj, void *data, int res, uint32_t id); 25 | 26 | struct pw_work_queue * 27 | pw_work_queue_new(struct pw_loop *loop); 28 | 29 | void 30 | pw_work_queue_destroy(struct pw_work_queue *queue); 31 | 32 | uint32_t 33 | pw_work_queue_add(struct pw_work_queue *queue, 34 | void *obj, int res, 35 | pw_work_func_t func, void *data); 36 | 37 | int 38 | pw_work_queue_cancel(struct pw_work_queue *queue, void *obj, uint32_t id); 39 | 40 | int 41 | pw_work_queue_complete(struct pw_work_queue *queue, void *obj, uint32_t seq, int res); 42 | 43 | /** 44 | * \} 45 | */ 46 | 47 | #ifdef __cplusplus 48 | } 49 | #endif 50 | 51 | #endif /* PIPEWIRE_WORK_QUEUE_H */ 52 | -------------------------------------------------------------------------------- /src/tests/test-cpp.cpp: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2018 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | pw_init(&argc, &argv); 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /src/tools/dfffile.h: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2023 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include 6 | 7 | #include 8 | 9 | struct dff_file; 10 | 11 | struct dff_file_info { 12 | uint32_t channel_type; 13 | uint32_t channels; 14 | uint32_t rate; 15 | bool lsb; 16 | uint64_t samples; 17 | uint64_t length; 18 | uint32_t blocksize; 19 | }; 20 | 21 | struct dff_layout { 22 | int32_t interleave; 23 | uint32_t channels; 24 | bool lsb; 25 | }; 26 | 27 | struct dff_file * dff_file_open(const char *filename, const char *mode, struct dff_file_info *info); 28 | 29 | ssize_t dff_file_read(struct dff_file *f, void *data, size_t samples, const struct dff_layout *layout); 30 | 31 | int dff_file_close(struct dff_file *f); 32 | -------------------------------------------------------------------------------- /src/tools/dsffile.h: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2021 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include 6 | 7 | #include 8 | 9 | struct dsf_file; 10 | 11 | struct dsf_file_info { 12 | uint32_t channel_type; 13 | uint32_t channels; 14 | uint32_t rate; 15 | bool lsb; 16 | uint64_t samples; 17 | uint64_t length; 18 | uint32_t blocksize; 19 | }; 20 | 21 | struct dsf_layout { 22 | int32_t interleave; 23 | uint32_t channels; 24 | bool lsb; 25 | }; 26 | 27 | struct dsf_file * dsf_file_open(const char *filename, const char *mode, struct dsf_file_info *info); 28 | 29 | ssize_t dsf_file_read(struct dsf_file *f, void *data, size_t samples, const struct dsf_layout *layout); 30 | 31 | int dsf_file_close(struct dsf_file *f); 32 | -------------------------------------------------------------------------------- /src/tools/midifile.h: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2020 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include 6 | 7 | #include 8 | 9 | struct midi_file; 10 | 11 | struct midi_event { 12 | #define MIDI_EVENT_TYPE_MIDI1 0 13 | #define MIDI_EVENT_TYPE_UMP 1 14 | uint32_t type; 15 | uint32_t track; 16 | double sec; 17 | uint8_t *data; 18 | uint32_t size; 19 | struct { 20 | uint32_t offset; 21 | uint32_t size; 22 | union { 23 | struct { 24 | uint32_t uspqn; /* microseconds per quarter note */ 25 | } tempo; 26 | } parsed; 27 | } meta; 28 | }; 29 | 30 | struct midi_file_info { 31 | uint16_t format; 32 | uint16_t ntracks; 33 | uint16_t division; 34 | }; 35 | 36 | struct midi_file * 37 | midi_file_open(const char *filename, const char *mode, struct midi_file_info *info); 38 | 39 | int midi_file_close(struct midi_file *mf); 40 | 41 | int midi_file_next_time(struct midi_file *mf, double *sec); 42 | 43 | int midi_file_read_event(struct midi_file *mf, struct midi_event *event); 44 | 45 | int midi_file_write_event(struct midi_file *mf, const struct midi_event *event); 46 | 47 | int midi_file_dump_event(FILE *out, const struct midi_event *event); 48 | -------------------------------------------------------------------------------- /subprojects/libcamera.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | url = https://git.libcamera.org/libcamera/libcamera.git 3 | revision = head 4 | -------------------------------------------------------------------------------- /subprojects/media-session.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | url = https://gitlab.freedesktop.org/pipewire/media-session.git 3 | revision = head 4 | 5 | -------------------------------------------------------------------------------- /subprojects/webrtc-audio-processing.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | directory = webrtc-audio-processing 3 | url = https://gitlab.freedesktop.org/pulseaudio/webrtc-audio-processing.git 4 | push-url = git@gitlab.freedesktop.org:pulseaudio/webrtc-audio-processing.git 5 | revision = v2.1 6 | 7 | [provide] 8 | dependency_names = webrtc-audio-processing-2 9 | -------------------------------------------------------------------------------- /subprojects/wireplumber.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | url = https://gitlab.freedesktop.org/pipewire/wireplumber.git 3 | revision = master 4 | -------------------------------------------------------------------------------- /template.test.in: -------------------------------------------------------------------------------- 1 | [Test] 2 | Type=session 3 | Exec=@exec@ 4 | -------------------------------------------------------------------------------- /test/data/test-spa-json.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PipeWire/pipewire/0e8a8e9844ba2aeb34048ead76eb8b36b45147f6/test/data/test-spa-json.txt -------------------------------------------------------------------------------- /test/pwtest-compat.c: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2021 Red Hat, Inc. */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include "config.h" 6 | 7 | #ifndef HAVE_SIGABBREV_NP 8 | #include 9 | #include 10 | 11 | /* glibc >= 2.32 */ 12 | static inline const char *sigabbrev_np(int sig) 13 | { 14 | #define SIGABBREV(a_) case SIG##a_: return #a_ 15 | switch(sig) { 16 | SIGABBREV(INT); 17 | SIGABBREV(ABRT); 18 | SIGABBREV(BUS); 19 | SIGABBREV(SEGV); 20 | SIGABBREV(ALRM); 21 | SIGABBREV(CHLD); 22 | SIGABBREV(HUP); 23 | SIGABBREV(PIPE); 24 | SIGABBREV(CONT); 25 | SIGABBREV(STOP); 26 | SIGABBREV(ILL); 27 | SIGABBREV(KILL); 28 | SIGABBREV(TERM); 29 | } 30 | #undef SIGABBREV 31 | 32 | return NULL; 33 | } 34 | 35 | #endif /* HAVE_SIGABBREV_NP */ 36 | -------------------------------------------------------------------------------- /test/test-functional.c: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2019 Wim Taymans */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include "config.h" 6 | 7 | #include 8 | 9 | #include "pwtest.h" 10 | 11 | PWTEST(openal_info_test) 12 | { 13 | #ifdef OPENAL_INFO_PATH 14 | int status = pwtest_spawn(OPENAL_INFO_PATH, (char *[]){ "openal-info", NULL }); 15 | pwtest_int_eq(WEXITSTATUS(status), 0); 16 | return PWTEST_PASS; 17 | #else 18 | return PWTEST_SKIP; 19 | #endif 20 | } 21 | 22 | PWTEST(pactl_test) 23 | { 24 | #ifdef PACTL_PATH 25 | int status = pwtest_spawn(PACTL_PATH, (char *[]){ "pactl", "info", NULL }); 26 | pwtest_int_eq(WEXITSTATUS(status), 0); 27 | return PWTEST_PASS; 28 | #else 29 | return PWTEST_SKIP; 30 | #endif 31 | } 32 | 33 | PWTEST_SUITE(pw_array) 34 | { 35 | pwtest_add(pactl_test, PWTEST_ARG_DAEMON); 36 | pwtest_add(openal_info_test, PWTEST_ARG_DAEMON); 37 | 38 | return PWTEST_PASS; 39 | } 40 | -------------------------------------------------------------------------------- /test/test-lib.c: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2021 Red Hat, Inc. */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include "config.h" 6 | 7 | #include "pwtest.h" 8 | 9 | #include "pipewire/pipewire.h" 10 | 11 | PWTEST(library_version) 12 | { 13 | const char *libversion, *headerversion; 14 | char version_expected[64]; 15 | 16 | pw_init(0, NULL); 17 | libversion = pw_get_library_version(); 18 | headerversion = pw_get_headers_version(); 19 | 20 | spa_scnprintf(version_expected, sizeof(version_expected), 21 | "%d.%d.%d", PW_MAJOR, PW_MINOR, PW_MICRO); 22 | 23 | pwtest_str_eq(headerversion, version_expected); 24 | pwtest_str_eq(libversion, version_expected); 25 | 26 | pw_deinit(); 27 | 28 | return PWTEST_PASS; 29 | } 30 | 31 | PWTEST(init_deinit) 32 | { 33 | pw_init(0, NULL); 34 | pw_deinit(); 35 | pw_init(0, NULL); 36 | pw_init(0, NULL); 37 | pw_deinit(); 38 | pw_deinit(); 39 | return PWTEST_PASS; 40 | } 41 | 42 | PWTEST_SUITE(properties) 43 | { 44 | pwtest_add(library_version, PWTEST_NOARG); 45 | pwtest_add(init_deinit, PWTEST_NOARG); 46 | 47 | return PWTEST_PASS; 48 | } 49 | -------------------------------------------------------------------------------- /test/test-pwtest.c: -------------------------------------------------------------------------------- 1 | /* PipeWire */ 2 | /* SPDX-FileCopyrightText: Copyright © 2021 Red Hat, Inc. */ 3 | /* SPDX-License-Identifier: MIT */ 4 | 5 | #include "config.h" 6 | 7 | #include "pwtest.h" 8 | 9 | #include 10 | 11 | #include "pwtest-compat.c" 12 | 13 | PWTEST(compat_sigabbrev_np) 14 | { 15 | #ifndef HAVE_SIGABBREV_NP 16 | pwtest_str_eq(sigabbrev_np(SIGABRT), "ABRT"); 17 | pwtest_str_eq(sigabbrev_np(SIGSEGV), "SEGV"); 18 | pwtest_str_eq(sigabbrev_np(SIGSTOP), "STOP"); 19 | pwtest_str_eq(sigabbrev_np(SIGCHLD), "CHLD"); 20 | pwtest_str_eq(sigabbrev_np(SIGTERM), "TERM"); 21 | pwtest_str_eq(sigabbrev_np(SIGKILL), "KILL"); 22 | pwtest_str_eq(sigabbrev_np(12345), NULL); 23 | 24 | return PWTEST_PASS; 25 | #else 26 | return PWTEST_SKIP; 27 | #endif 28 | } 29 | 30 | PWTEST_SUITE(pwtest) 31 | { 32 | pwtest_add(compat_sigabbrev_np, PWTEST_NOARG); 33 | 34 | return PWTEST_PASS; 35 | } 36 | --------------------------------------------------------------------------------