Compare commits

..

98 commits

Author SHA1 Message Date
Wim Taymans
3f79bcae5d 1.4.4 2025-05-29 09:17:47 +02:00
Jonas Holmberg
fc9aa51619 pod: declare offset as unused in spa_pod_builder_bytes_end()
Fixes compiler warning:

/usr/include/spa-0.2/spa/pod/builder.h:357:69: error: unused parameter 'offset'
[-Werror=unused-parameter]
2025-05-29 09:08:40 +02:00
Wim Taymans
62a719d71a adapter:handle -ENOENT when enumerating buffers
When the follower has no buffer suggestion, it can return -ENOENT, which
should not generate an error but simply use the converter buffer
suggestion instead.
2025-05-27 16:14:15 +02:00
Robert Mader
eda42ef2fc gst: src: Change DEFAULT_MIN_BUFFERS back to 1
The change from 1 to 8 was done without justification in the commit
message and possibly for debug purposes. Unfortunately it breaks
negotiation with the libcamera virtual pipeline, which defaults to
4 buffers.

Set the the value to 1 again as successful negotiation - even with an
unusually low number of buffers - is usually more desirable than an
error.

Fixes: 98b7dc7c0 ("gst: don't do set_caps from the pipewire callback")
(cherry picked from commit e81fb77322)
2025-05-26 19:28:32 +02:00
Wim Taymans
c507c4b0ff adapter: negotiate from target to follower
Since 3abda54d80 we prefer the format
of the filter. This reverses the selection of the default value when
negotiating buffers from the target to the follower.

If the follower does not select a reasonable value for the buffer size,
for example, this then results in wrongly sized buffers.

Fix this by reversing the order of allocation from target to follower
where we let the target (converter) select a default value, which is
more likely to be correct.

See #4713, #4619
2025-05-26 15:44:51 +02:00
Wim Taymans
06941f7315 alsa: remove UMP flag from control format
Don't set the UMP type flag on the format. Use the negotiated types flag
to decide what format to output. Add support for output to old style
midi.

Set the UMP type flag only on the new mixer and JACK when UMP is
enabled.

This ensures that only new (or explicitly requesting) apps get UMP and
old apps receive old midi.

This makes JACK running on 1.2 in flatpaks work with midi again.
2025-05-23 17:00:16 +02:00
Wim Taymans
76db05a0f8 Use "8 bit raw midi" for control ports again
There is no need to encode the potential format in the format.dsp of
control ports, this is just for legacy compatibility with JACK apps. The
actual format can be negotiated with the types field.

Fixes midi port visibility with apps compiled against 1.2, such as JACK
apps in flatpaks.
2025-05-23 17:00:05 +02:00
Wim Taymans
483b59a9d9 pod: add bytes start/append/end functions
Add functions to dynamically start and build a bytes pod.
2025-05-23 16:59:54 +02:00
Wim Taymans
331d5e0351 1.4.3 2025-05-22 10:59:37 +02:00
Wim Taymans
b24ceda8b2 filter-graph: lv2 features need a NULL terminator 2025-05-21 15:37:02 +02:00
Wim Taymans
6115a240d1 filter-chain: manage graph from source only
Only react to the capture stream state change and format changes. The
playback and capture streams change state somewhat concurrently and so
the graph state might not be consistent.

Because only the capture stream will trigger the playback stream and
start the processing, we can safely react to capture stream changes
only.
2025-05-21 15:34:01 +02:00
Wim Taymans
2a3f92e67f client-node: let all events go to the node
Just pass all events to the node and only error out when they return an
error value.

Make sure we pass the result values of the command around.
2025-05-21 15:28:08 +02:00
Wim Taymans
61168adb92 adapter: log command errors when no converter 2025-05-20 10:54:48 +02:00
Christian Glombek
603aae2dc8 daemon/pipewire.conf.avail: Add snippet enabling module-raop 2025-05-20 10:54:43 +02:00
Wim Taymans
a968027bdc adapter: handle -ENOTSUP for commands
When using custom commands, the converter might return -ENOTSUP and
we should ignore this.
2025-05-20 10:54:38 +02:00
Wim Taymans
9207fea992 libcemara: take care of index offset when enumerating controls
Add an index offset when enumerating controls. We insert 2 properties
before enumerating the controls so the index of the first control needs
to have an offset of 2.
2025-05-20 10:53:55 +02:00
Wim Taymans
a66377cf42 alsa: only use default rate and channels when valid
Check the user provided rate and channels and only use them to limit the
rate and channels when they are valid.
2025-05-19 12:12:36 +02:00
Wim Taymans
e7610de305 alsa: clamp audio.channels to MAX_CHANNELS
So that we don't end up trying to use too many channels later on.
2025-05-19 12:09:21 +02:00
Robert Mader
2a8d5c1f40 v4l2: Re-enable first buffer skip for jpeg types
The workaround is typically needed with usb-cameras using jpeg streams.
Re-enabling the skip shouldn't affect what the commit was trying to do,
i.e. fix encoded streams like h264 etc.

Fixes: bcf0c0cf8 (v4l2: only skip buffer for raw formats)
(cherry picked from commit e387772dc2)
2025-05-17 15:08:45 +02:00
Wim Taymans
6b9f340219 alsa-seq: remove leftover debug line 2025-05-13 11:20:55 +02:00
Wim Taymans
f5c9944e61 netjack2: reverse send/recv roles in driver/manager
The params contain the send/recv streams from the point of view of the
manager (and not the driver as was assumed before). This means we need
to swap send/recv in the driver, not the manager.

This makes things interoperate with JACK/netjack2.

See #4666
2025-05-13 10:57:04 +02:00
Wim Taymans
835d8b7801 netjack2: add driver.mode again
This configures the default number of audio and midi ports per stream
to 0 depending on the mode.

Improve docs a little.

See #4666
2025-05-13 10:56:12 +02:00
Wim Taymans
f7f2e3e52a netjack2: use strncpy to copy the header
It pads the remaining bytes in the header with 0 bytes so that the
memory doesn't contain uninitialized data.
2025-05-13 10:55:31 +02:00
Wim Taymans
e040430967 netjack2: improve shutdown
Destroy the sources from the io handler immediately when there is an
error so that we don't end up in endless error wakeups.

Schedule the free from the main loop and make sure only one can ever
run.
2025-05-13 10:55:25 +02:00
Wim Taymans
4e0137696f netjack2: fix trace_fp compilation 2025-05-13 10:54:58 +02:00
Wim Taymans
c3e08ad9c9 netjack2: handle connection errors in more cases 2025-05-13 10:54:51 +02:00
Wim Taymans
515de13b8a netjack2: set timeout to sane value again 2025-05-13 10:54:44 +02:00
Wim Taymans
0ea1bc3841 netjack2: implement driver and manager roles correctly
The manager is actually not supposed to decide much about the number of
audio and midi ports. It should just suggest a default when connecting
driver doesn't know.

Add a audio.ports parameters to manager and driver to suggest/ask for
the amount of audio ports. Let the audio.position/audio.channels be a
specification of the channel mask in case it matches the requested
channels, otherwise use AUX channels for the ports.

This means that we must derive the mode (sink/source/audio/midi) from
the ports that are negotiated in the manager and the driver, so delay
this until after negotiation.

Make sure all the possible modes work. For midi only streams, we can't
wait for the session manager to perform a PortConfig so do that
ourselves. Make sure we only use a source trigger when we have a sink.

Fixes #4666
2025-05-13 10:54:32 +02:00
Wim Taymans
b9bad88eed netjack2: make function to clear events
Make a separate function to clear events instead of passing NULL as the
midi buffer and segfaulting.
2025-05-13 10:54:25 +02:00
Wim Taymans
85479cf203 netjack2: copy the node.group to streams
Just in case we want them to be scheduled in the same group.
2025-05-13 10:54:19 +02:00
Wim Taymans
c2c255b5f9 netjack2: keep per stream io_position
And handle the trigger failure with a warning and fallback.
2025-05-13 10:54:06 +02:00
Wim Taymans
dc1f73ceaf netjack2: warn when the trigger fails 2025-05-13 10:53:50 +02:00
Wim Taymans
f3cb35dad3 netjack2: keep position io per stream
Keep a position info for the stream it was set and then use the position
info for the stream that is driving the graph. Otherwise we might use a
destroyed position info.
2025-05-13 10:53:41 +02:00
Wim Taymans
5a00232cdf netjack2: implement ifname in the driver
See #4666
2025-05-13 10:53:34 +02:00
Wim Taymans
3a231a807d netjack2: Improve docs
Remove unused option.
Clarify that channels and midi port are chosen by the server.

See #4666
2025-05-13 10:53:25 +02:00
Wim Taymans
3aaf91d9c6 netjack2: fix the large midi events offset
The midi events have their large data offsets relative to the start of
the buffer and the large data is at the end of the buffer. Because we
copied it down, right after the events, but we didn't adjust the
offsets, calculate a correction offset when unpacking the events.
2025-05-13 10:50:01 +02:00
Wim Taymans
d28d195745 netjack2: set correct max midi buffer size
It depends on the negotiated period size, not the graph quantum.
2025-05-13 10:49:48 +02:00
Wim Taymans
28109587fd netjack2: copy large midi events to the end of the buffer
There is no need to keep an extra free byte at the end and it will cause
us to lose a byte when we copy the large midi events down.
2025-05-13 10:49:37 +02:00
Wim Taymans
9b52c07871 jack: write midi events to end of buffer
There is no need to keep one extra byte at the end of the buffer,
we can write the event up to the last byte.
2025-05-13 10:49:18 +02:00
Wim Taymans
3d33acce1d netjack: handle overflow in midi buffer append 2025-05-13 10:48:55 +02:00
Wim Taymans
1cbe4e1782 ump: handle sysex from UMP to MIDI1 better
SysEx in UMP can span multiple packets. In MIDI1 we can't split them up
into multiple events so we need to collect the complete sysex and then
write out the event.

Fixes SysEx writes to ALSA seq by running the event encoder until a
valid packet is completed.

Also fixes split MIDI1 packets in the JACK API when going through the
tunnel or via netjack.
2025-05-13 10:48:39 +02:00
Wim Taymans
750b88c3ca control: only convert midi/UMP, pass other control types
We should only try to convert MIDI/UMP when the port doesn't support it
but let all the other control types pass through.

Fixes #4692
2025-05-09 12:01:24 +02:00
Wim Taymans
37dbf93cc4 filter-graph: remove useless check 2025-05-09 11:59:31 +02:00
Guido Günther
2d4af3ced5 spa: Add default: statements
This allows to use the library in projects that use `-Wswitch-default`
without any

 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wswitch-default"
 #pragma GCC diagnostic pop

This is useful as as the header is being pulled in via
pipewire/wireplumber headers into projects that might have this warning
enabled and would otherwise fail to build with -Werror.

Signed-off-by: Guido Günther <agx@sigxcpu.org>
2025-05-09 11:58:55 +02:00
Wim Taymans
5d741a2b3c filter-chain: add props only once
Only add the properties offset in the builder after we actually got a
property or else we end up with the same property twice.
2025-05-09 11:54:34 +02:00
Wim Taymans
7d27668fb2 ebur128: fix port name
Fixes #4667
2025-05-09 11:53:37 +02:00
Wim Taymans
0135baa60f alsa-seq: add the source only on success
Otherwise if we have an error with the timerfd, we have the source fd
added and we close the device.
2025-05-09 11:53:07 +02:00
Wim Taymans
49c4c44dce videoconvert: consume input buffer in all cases
Return the input buffer when we get some error so that the other side
can send new data.
2025-05-09 11:52:04 +02:00
Wim Taymans
957bde02cd v4l2: only skip buffer for raw formats
We don't want to skip the first buffer for encoded formats because it
can contain the encoding parameters, in the h264 case, for example.
2025-05-09 11:51:45 +02:00
Wim Taymans
f857a50734 ump: fix program change 2.0 to 1.0 conversion
The program change byte should not be shifted an extra bit, unlike all
the other messages.

Fixes #4664
2025-05-09 11:51:20 +02:00
Wim Taymans
8c1e1ea17f midifile: unpack the UMP SysRT bytes correctly
They are packed in a native endian uint32_t so read it like that and
then use shifts to get the right bytes.
2025-05-09 11:50:43 +02:00
Simon Ruderich
63bf21d7b8 midifile: decode UMP SysRT messages 2025-05-09 11:50:36 +02:00
Wim Taymans
3abda54d80 pod: use default value of filter
When using a filter, it makes more sense to use the default value
of the filter as a first attempt.

One case is in adapter when we try to find a passthrough format first. The
audioconverter suggests a default rate of the graph rate but the follower
filters this out for another unrelated default value and passthrough is not
possible (altough it would be because the default value of the filter is
in the supported follower range).

Fixes #4619
2025-05-09 11:49:08 +02:00
Wim Taymans
d20a1523b6 1.4.2 2025-04-14 11:46:02 +02:00
Wim Taymans
ac42f55916 ebur128: work around libebur128 bug
Versions 1.2.5 and 1.2.6 don't scale the window in ms correctly, leading
to excessive memory allocation, so work around this here.
See https://github.com/jiixyj/libebur128/pull/132

Fixes #4646
2025-04-14 11:19:44 +02:00
Kenny Levinsen
a0be431c7f audioconvert: Increase param length limit to 4096
Parameter values read into a 512 byte long buffer, which is insufficient
for medium to long filter-graph parameters.

Increase the buffer to 4096 bytes to give some wiggle-room.
2025-04-14 09:41:47 +02:00
fossdd
35591922ce doc: fix typo in pw-link(1) 2025-04-14 09:40:10 +02:00
Pauli Virtanen
f120b595f0 pw-loopback: add missing --channel-map long option 2025-04-14 09:40:02 +02:00
Wim Taymans
07f49a7559 raop: fix byte array initialization
Initialize the byte array with bytes instead of a string because the 0
byte at the end of the string does not fit in the array and causes a
compiler warning.
2025-04-14 09:39:18 +02:00
Arun Raghavan
cf5db17aa6 gst: sink: Only add VideoCrop meta for video 2025-04-03 06:15:11 -04:00
Wim Taymans
f0a432118a gst: require a buffer size of at least 1
Setting the default size to 0 and outside of the min/max range now means
that there is no suggestion for the size and it should use the
suggestion of the peer.
2025-04-03 06:14:26 -04:00
Sanchayan Maity
f571253ff3 gst: pipewiresrc: Fixate caps if intersect did not return fixated caps
We might end up in a situation where depending on the pipeline,
intersect might not give us fixated caps.

Possible example of such a pipeline can be below.

gst-launch-1.0 -e pipewiresrc target-object=<path> ! audioconvert !
audio/x-raw,format=S16LE,rate=48000,channels=2 ! lamemp3enc !
filesink location=test.mp3

This results in non-fixated caps like below when intersecting caps from
format param and possible_caps which depends on what we have downstream
in the pipeline.

audio/x-raw, layout=(string)interleaved, format=(string)S16LE, rate=(int)48000, channels=(int)2, channel-mask=(bitmask)0x0000000000000003;
audio/x-raw, layout=(string)interleaved, format=(string)S16LE, rate=(int)48000, channels=(int)2

To fix this, fixate the caps explicitly.
2025-04-03 06:14:02 -04:00
Philippe Normand
99b94015a7 gst: src: Fix buffer pool handling in case of caps renegotiation
In case negotiation is first attempted with unfixed caps, bufferpool support was
unconditionally disabled. Then at a second caps negotiation attempt it wasn't
restored according to the property value.
2025-04-03 06:13:24 -04:00
Sanchayan Maity
48a959bf2e gst: pipewireformat: Do not use RANGE if values are equal
This fixes assertion from the underlying gst_value_collect_int_range
when using gst_caps_set_simple with range types when the values are
equal.
2025-04-03 06:13:13 -04:00
Wim Taymans
1388f16c47 adapter: handle builder overflow 2025-04-02 15:33:54 +02:00
Wim Taymans
ce6d2fce9a audioadapter: init the builder for each param
Or else we keep on adding items until we overflow.
2025-04-02 15:33:54 +02:00
Wim Taymans
98e7ae39c6 impl-link: improve debug log
Log the format after we patch it up and log some context lines.

Move some info log to debug.
2025-04-02 15:33:54 +02:00
Wim Taymans
a9eba98e8e pod: handle builder overflows
When the builder is overflowed, we might get a NULL pod. This is a valid
situation that we need to handle because it can be used to get the
required builder buffer size.
2025-04-02 15:33:54 +02:00
Wim Taymans
2d26fbcddf v4l2: handle nearest set_format
The set_format function can return 1 when the format was adjusted to the
nearest supported format so return this from the port_set_param
function.

This instructs the adapter to recheck the configured format so that it
can store the adjuted format on the converter.
2025-04-02 15:33:54 +02:00
Wim Taymans
8d7175a1e7 adapter: add Header metadata by default
Firefox needs this but we should eventually check the Meta Params to
decide on this.
2025-04-02 15:33:54 +02:00
Philippe Normand
81408597f4 gst: deviceprovider: Fix a leak and a heap-use-after-free
The device passed to gst_device_provider_device_add() is transfer:floating, so
we need increase its ref, otherwise the pointer we keep internally will be a
dangling ref.

Also gst_device_provider_device_remove() doesn't actually release the device, so
we have to do it ourselves.

Fixes #4616
2025-04-02 15:33:54 +02:00
Wim Taymans
58c412c9dc pw-cat: improve sndfile file format debug info
Print the endianness, container name and the sample format nicely
instead of dumping the hex values.
2025-04-02 15:33:54 +02:00
Wim Taymans
081cb6848e pw-cat: prefer AU format when using stdin/stdout
WAV is actually not usable for streaming output by sndfile.

See #4629
2025-04-02 15:33:54 +02:00
Pauli Virtanen
4176caca30 alsa: seq: double-check midi client version
Check midi client version after setting it, to see if it was really
successfully set.  Old kernels without UMP don't know about the midi
version fields, so snd_seq_set_client_midi_version() appears to fail
silently there.
2025-04-02 15:33:54 +02:00
Robert Mader
b87764bd07 systemd: Depend on dbus.service
Solution suggested by Xi Ruoyao.

The dbus user service is required for various features - the summary says:
'dbus (Bluetooth, rt, portal, pw-reserve)'

On session logout the dbus service gets shut down while the Pipewire one
relies on a timeout. If a user logs in again before PW timed out, the
later stays alive but doesn't handle re-connecting to the dbus service
of the new session, breaking the camera portal and potentially other
features.

Thus hard-depend on the dbus service (if enabled at build time) and thus
shut down together with it.

(cherry picked from commit 2625983a23)
2025-03-20 14:05:28 +01:00
Wim Taymans
2eb8cf5dc7 1.4.1 2025-03-14 11:07:06 +01:00
Wim Taymans
fb43eb8ee2 audioconvert: fix the filter-graph samplerate
The filter graph runs before or after the resampler depending on the
direction of the conversion.
2025-03-14 10:16:15 +01:00
Pauli Virtanen
d58d2a2375 spa: acp: indicate ALSA UCM profile errors in UIs
Add "[ALSA UCM error]" to the end of card description, to indicate
something is wrong.
2025-03-14 10:16:08 +01:00
Pauli Virtanen
ba3a36b3d1 spa: acp: allow also too few channels in SplitPCM configs
GoXLR Mini has different numbers of channels actually available (21, 23,
or 25) depending on its firmware/etc, but its UCM profile specifies
always 23. The count can then be bigger or smaller than what is actually
available.

Fail a bit more gracefully in the case of too few channels: create all
the split devices specified by the profile. The channels that aren't
actually available in HW just won't get routed anywhere.

ALSA upstream IIUC is saying that the channel counts should be fixed, so
spew warnings that say the UCM profiles are wrong if they look wrong.
2025-03-14 10:16:05 +01:00
sunyuechi
e16c184228 Add x86 CPU check in meson.build for clang build fix
have_avx = cc.has_argument(avx_args)

gcc generates an error when AVX is unsupported, whereas clang only
produces a warning.

Thus, using Clang on the RISC-V platform incorrectly enables AVX file
compilation, leading to build failures.
2025-03-14 10:15:56 +01:00
Wim Taymans
9696e2c62b loop: remove return from function returning void
Fixes #4603
2025-03-14 10:15:42 +01:00
Wim Taymans
b4d88143da alsa-seq: fix UMP output
We need to set the UMP flag, which is done with
snd_seq_ev_set_ump_data() to make it output the midi data.
2025-03-11 13:30:37 +01:00
Wim Taymans
15e200846a alsa-seq: avoid uninitialized warning 2025-03-11 12:32:28 +01:00
Wim Taymans
f4417f4e2c audioconvert: remove some unused fields 2025-03-11 12:27:36 +01:00
Wim Taymans
edffc87ebf audioconvert: configure resample channels correctly
Depending on the direction of the conversion, we run the resampler
before or after the channelmix. This means we need to use the channel
count before or after the channelmixer instead of always using the
channels after channelmixing.

Fixes #4595
2025-03-11 12:27:33 +01:00
Pauli Virtanen
f7b1ba2a40 spa: avoid casting between snd_seq_event_t & snd_seq_ump_event_t
Although the two structs have same initial sequence, it's not really
correct to cast between their pointers. Alsa-lib also does this only
internally, but not in API.
2025-03-11 12:27:29 +01:00
Pauli Virtanen
4f077e1f27 spa: fix ALSA UMP support detection in meson 2025-03-11 12:27:25 +01:00
Pauli Virtanen
2167945eff spa: alsa: support also MIDI-1.0 IO for ALSA seq
Support also non-UMP IO with ALSA seq, in case either alsa-lib or the
kernel does not have UMP enabled.

Add configuration option "api.alsa.seq.ump" for optionally turning UMP
I/O off, for easier debugging.
2025-03-11 12:27:21 +01:00
Nikolay Borodin
2397a984f7 spa: alsa: allow building without UMP in libalsa
Allow building with older libalsa releases that don't have UMP.
2025-03-11 12:27:18 +01:00
msizanoen
17eaf83fe8 systemd: Disable pipewire user services for root
The `access(2)` based multi-user mediation mechanism doesn't quite work
for the root user, which may cause it to conflict with a running
foreground user session. Prevent this by not running the user service at
all for the root user, which nobody should be doing anyway.
2025-03-11 12:27:14 +01:00
Jan Grulich
8d55213288 stream: don't emit process when disconnecting
Commit b160a72018 introduced this change
before, but it was omitted in e1e0a886d5.

This makes again sure we don't call process callback while disconnecting
stream.

Fixes #3314
2025-03-11 12:27:05 +01:00
Pauli Virtanen
06438cbc9a spa: acp: make spa-acp-tool debug output easier to read
Include log level, file/line numbers, and indent messages for debug
levels.
2025-03-10 09:24:29 +01:00
Pauli Virtanen
ae16463c3c spa: acp: be more noisy when UCM profiles fail to be supported
Generally ALSA UCM profiles should all work as they're supposed to be
device-specific, so be more noisy when the profile fails to be supported
due to the PCM device failing to open.

Some logging on the probe outcome in failure case also makes
spa-acp-tool etc. log output easier to read.
2025-03-10 09:24:26 +01:00
Pauli Virtanen
78981a8d9b spa: acp: in SplitPCM probe channel count and allow excess
In SplitPCM mode, Focusrite Scarlett Gen 4 (USB 1235:8218) UCM profile
specifies "CaptureChannels 2" for the Mic1/2 inputs, but
snd_pcm_hw_params_set_channels(2) fails for the HW device.

Fix by not requiring the channel count to be exact for SplitPCM, but
also allow larger numbers of channels than what UCM profile specifies.
2025-03-10 09:24:23 +01:00
Jan Palus
901401e6f1 module-roc: require roc >= 0.4.0
3270bd4 introduced changes reyling on features from roc 0.4.0
(upstream commit: d18d342)
2025-03-10 09:24:20 +01:00
Frédéric Danis
5c1be35018 bluez5: backend-native: Fix 3way active call hangup
HFP/HF/TWC/BV-03-C test, which setup an active and a held calls,
expects to receive AT+CHLD=1 (release and swap calls) instead of
AT+CHUP on active call hang up request.

As this changes the active call to disconnected and held call to
being active, the call states should be managed in hfp_hf_hangup
instead of waiting for +CIEV (callheld=0) event which will drop
the previously held call before AT+CLCC reply can inform this call
is now active.
2025-03-10 09:24:13 +01:00
Frédéric Danis
79d232c1f2 bluez5: backend-native: Fix incoming call crash
HFP/HF/TWC/BV-01-C test creates an incoming call as soon as the SLC is
completed, i.e. a +CIEV: <callsetup>,1 event just after AT+CHLD=? reply
has been received. This try to parse the rfcomm->telephony_ag->call_list
which has not yet been created.

This commit move the telephony_ag creation to the SLC completed event.
2025-03-10 09:24:10 +01:00
Frédéric Danis
277b80c903 bluez5: backend-native: Fix ECNR support in HFP HF SDP record
Sending AT+ECNR is supported by the native backend
2025-03-10 09:24:07 +01:00
603 changed files with 22412 additions and 36711 deletions

View file

@ -18,8 +18,8 @@ stages:
variables:
FDO_UPSTREAM_REPO: 'pipewire/pipewire'
# ci-templates as of Mar 25th 2024
.templates_sha: &templates_sha ef5e4669b7500834a17ffe9277e15fbb6d977fff
# ci-templates as of Jan 27th 2022
.templates_sha: &templates_sha 0c312d9c7255f46e741d43bcd1930f09cd12efe7
include:
- project: 'freedesktop/ci-templates'
@ -31,15 +31,12 @@ include:
- project: 'freedesktop/ci-templates'
ref: *templates_sha
file: '/templates/alpine.yml'
- project: 'freedesktop/ci-templates'
ref: *templates_sha
file: '/templates/debian.yml'
.fedora:
variables:
# Update this tag when you want to trigger a rebuild
FDO_DISTRIBUTION_TAG: '2025-10-22.0'
FDO_DISTRIBUTION_VERSION: '42'
FDO_DISTRIBUTION_TAG: '2024-12-10.0'
FDO_DISTRIBUTION_VERSION: '40'
FDO_DISTRIBUTION_PACKAGES: >-
alsa-lib-devel
avahi-devel
@ -48,7 +45,6 @@ include:
dbus-devel
doxygen
fdk-aac-free-devel
file
findutils
gcc
gcc-c++
@ -59,7 +55,6 @@ include:
gstreamer1-plugins-base-devel
jack-audio-connection-kit-devel
libasan
liblc3-devel
libcanberra-devel
libebur128-devel
libffado-devel
@ -69,6 +64,7 @@ include:
libubsan
libusb1-devel
lilv-devel
libv4l-devel
libva-devel
libX11-devel
ModemManager-devel
@ -80,7 +76,6 @@ include:
sbc-devel
ShellCheck
SDL2-devel
spandsp-devel
systemd-devel
vulkan-loader-devel
webrtc-audio-processing-devel
@ -92,9 +87,6 @@ include:
openal-soft
readline-devel
pandoc
fftw-libs-single
fftw-devel
onnxruntime-devel
# Uncommenting the following two lines and disabling the meson entry above
# will re-enable use of Meson via pip but please consider using a newer distro
# image first or making the build system compatible instead! This is because
@ -109,7 +101,7 @@ include:
.ubuntu:
variables:
# Update this tag when you want to trigger a rebuild
FDO_DISTRIBUTION_TAG: '2025-05-10.0'
FDO_DISTRIBUTION_TAG: '2024-01-12.0'
FDO_DISTRIBUTION_VERSION: '22.04'
FDO_DISTRIBUTION_PACKAGES: >-
debhelper-compat
@ -130,6 +122,7 @@ include:
libsnapd-glib-dev
libudev-dev
libva-dev
libv4l-dev
libx11-dev
meson
ninja-build
@ -145,34 +138,10 @@ include:
# FDO_DISTRIBUTION_EXEC: >-
# pip3 install meson
.debian:
variables:
# Update this tag when you want to trigger a rebuild
BASE_TAG: '2025-08-10.0'
FDO_DISTRIBUTION_VERSION: 'trixie'
FDO_DISTRIBUTION_PACKAGES: >-
build-essential
dpkg-dev
findutils
git
meson
.debian-archictectures:
parallel:
matrix:
- ARCH:
- amd64
- arm64
- armhf
- i386
- ppc64el
- riscv64
- s390x
.alpine:
variables:
# Update this tag when you want to trigger a rebuild
FDO_DISTRIBUTION_TAG: '2025-03-25.0'
FDO_DISTRIBUTION_TAG: '2024-09-20.0'
FDO_DISTRIBUTION_VERSION: '3.20'
FDO_DISTRIBUTION_PACKAGES: >-
alsa-lib-dev
@ -241,8 +210,7 @@ include:
- echo "Building with meson options $MESON_OPTIONS"
- meson setup "$BUILD_DIR" --prefix="$PREFIX" $MESON_OPTIONS
- meson compile -C "$BUILD_DIR" $COMPILE_ARGS
- echo "Running tests with meson options $MESON_TEST_OPTIONS"
- meson test -C "$BUILD_DIR" --no-rebuild $MESON_TEST_OPTIONS
- meson test -C "$BUILD_DIR" --no-rebuild
- meson install -C "$BUILD_DIR" --no-rebuild
artifacts:
name: pipewire-$CI_COMMIT_SHA
@ -258,18 +226,6 @@ container_ubuntu:
variables:
GIT_STRATEGY: none # no need to pull the whole tree for rebuilding the image
container_debian:
extends:
- .debian
- .debian-archictectures
- .fdo.container-build@debian
stage: container
variables:
GIT_STRATEGY: none # no need to pull the whole tree for rebuilding the image
FDO_DISTRIBUTION_TAG: "$BASE_TAG-$ARCH"
FDO_DISTRIBUTION_EXEC: >-
./.gitlab/ci/setup-debian-cross-container.sh "$ARCH"
container_fedora:
extends:
- .fedora
@ -302,54 +258,9 @@ build_on_ubuntu:
- .fdo.distribution-image@ubuntu
- .build
stage: build
needs:
- job: container_ubuntu
artifacts: false
variables:
MESON_OPTIONS: "-Dsession-managers=[] -Dsnap=enabled"
build_on_debian:
extends:
- .debian
- .debian-archictectures
- .not_coverity
- .fdo.distribution-image@debian
- .build
stage: build
needs:
- job: container_debian
artifacts: false
# ideally
# parallel:
# matrix:
# - ARCH: "$ARCH"
# however https://gitlab.com/gitlab-org/gitlab/-/issues/423553
# ("Expand variables in `needs:parallel:matrix`")
variables:
FDO_DISTRIBUTION_TAG: "$BASE_TAG-$ARCH"
# see /.gitlab/ci/setup-debian-cross-container.sh for installed packages
MESON_OPTIONS: >-
--cross-file /opt/meson-$ARCH.cross
-D c_args=['-UFASTPATH']
-D cpp_args=['-UFASTPATH']
-D auto_features=enabled
-D session-managers=[]
-D bluez5-backend-native-mm=enabled
-D bluez5-codec-lc3plus=disabled
-D bluez5-codec-ldac=disabled
-D bluez5-codec-ldac-dec=disabled
-D libcamera=disabled
-D roc=disabled
-D snap=disabled
-D systemd-user-service=disabled
-D systemd-system-service=disabled
-D onnxruntime=disabled
-D vulkan=enabled
-D ffmpeg=enabled
-D pw-cat-ffmpeg=enabled
MESON_TEST_OPTIONS: >-
--timeout-multiplier=2
.build_on_fedora:
extends:
- .fedora
@ -357,9 +268,6 @@ build_on_debian:
- .fdo.distribution-image@fedora
- .build
stage: build
needs:
- job: container_fedora
artifacts: false
build_on_fedora:
extends:
@ -410,13 +318,11 @@ build_on_fedora_html_docs:
-Dsndfile=enabled
-Dsession-managers=[]
before_script:
- git fetch origin 1.0 1.2 1.4 master
- git fetch origin 1.0 1.2 master
- git branch -f 1.0 origin/1.0
- git clone -b 1.0 . branch-1.0
- git branch -f 1.2 origin/1.2
- git clone -b 1.2 . branch-1.2
- git branch -f 1.4 origin/1.4
- git clone -b 1.4 . branch-1.4
- git branch -f master origin/master
- git clone -b master . branch-master
- !reference [.build, before_script]
@ -429,10 +335,6 @@ build_on_fedora_html_docs:
- meson setup builddir $MESON_OPTIONS
- meson compile -C builddir doc/pipewire-docs
- cd ..
- cd branch-1.4
- meson setup builddir $MESON_OPTIONS
- meson compile -C builddir doc/pipewire-docs
- cd ..
- cd branch-master
- meson setup builddir $MESON_OPTIONS
- meson compile -C builddir doc/pipewire-docs
@ -452,9 +354,6 @@ build_on_alpine:
- .fdo.distribution-image@alpine
- .build
stage: build
needs:
- job: container_alpine
artifacts: false
variables:
MESON_OPTIONS: "-Dsession-managers=[] -Dsnap=disabled -Dlogind=enabled -Dlogind-provider=libelogind"
@ -463,13 +362,13 @@ build_all:
extends:
- .build_on_fedora
variables:
# Fedora doesn't have libfreeaptx, lc3plus, or roc
# Fedora doesn't have libfreeaptx, lc3plus, lc3, or roc
# libcamera has no stable API, so let's not chase that target
MESON_OPTIONS: >-
-Dauto_features=enabled
-Dbluez5-codec-aptx=disabled
-Dbluez5-codec-lc3plus=disabled
-Dbluez5-codec-ldac-dec=disabled
-Dbluez5-codec-lc3=disabled
-Droc=disabled
-Dlibcamera=disabled
-Dsession-managers=[]
@ -589,9 +488,6 @@ build_with_coverity:
- .fdo.suffixed-image@fedora
- .build
stage: analysis
needs:
- job: container_coverity
artifacts: false
script:
- export PATH=/opt/coverity/bin:$PATH
- meson setup "$BUILD_DIR" --prefix="$PREFIX"
@ -667,9 +563,8 @@ check_missing_headers:
- .not_coverity
- .fdo.distribution-image@fedora
stage: analysis
needs:
- job: build_on_fedora
artifacts: true
dependencies:
- build_on_fedora
script:
- export PREFIX=`find -name prefix-*`
- ./.gitlab/ci/check_missing_headers.sh
@ -678,18 +573,18 @@ pages:
extends:
- .not_coverity
stage: pages
needs:
- job: build_on_fedora_html_docs
artifacts: true
dependencies:
- build_on_fedora_html_docs
script:
- mkdir public public/1.0 public/1.2 public/1.4 public/devel
- mkdir public public/1.0 public/1.2 public/devel
- cp -R branch-1.0/builddir/doc/html/* public/1.0/
- cp -R branch-1.2/builddir/doc/html/* public/1.2/
- cp -R branch-1.4/builddir/doc/html/* public/1.4/
- cp -R branch-master/builddir/doc/html/* public/devel/
- (cd public && ln -s 1.4/* .)
- (cd public && ln -s 1.2/* .)
artifacts:
paths:
- public
rules:
- if: $CI_COMMIT_BRANCH == 'master'
- if: $CI_COMMIT_BRANCH == '1.0'
- if: $CI_COMMIT_BRANCH == '1.2'

View file

@ -1,63 +0,0 @@
#!/usr/bin/env bash
set -ex
packages=(
# libapparmor-dev
libasound2-dev
libavahi-client-dev
libavcodec-dev
libavfilter-dev
libavformat-dev
libbluetooth-dev
libcanberra-dev
libdbus-1-dev
libebur128-dev
libfdk-aac-dev
libffado-dev
libfftw3-dev
libfreeaptx-dev
libglib2.0-dev
libgstreamer1.0-dev
libgstreamer-plugins-base1.0-dev
libjack-jackd2-dev
liblc3-dev
liblilv-dev
libmysofa-dev
libopus-dev
libpulse-dev
libreadline-dev
libsbc-dev
libsdl2-dev
# libsnapd-glib-dev
libsndfile1-dev
libspandsp-dev
libssl-dev
libsystemd-dev
libudev-dev
libusb-1.0-0-dev
libvulkan-dev
libwebrtc-audio-processing-dev
libx11-dev
modemmanager-dev
)
arch="$1"
export DEBIAN_FRONTEND=noninteractive
sed -i \
's/^Components:.*$/Components: main contrib non-free non-free-firmware/' \
/etc/apt/sources.list.d/debian.sources
dpkg --add-architecture "$arch"
apt update -y
pkgs=( "crossbuild-essential-$arch" )
for pkg in "${packages[@]}"; do
pkgs+=( "$pkg:$arch" )
done
apt install -y "${pkgs[@]}"
meson env2mfile --cross --debarch "$arch" -o "/opt/meson-$arch.cross"

View file

@ -23,7 +23,6 @@ run: all
PIPEWIRE_CONFIG_DIR=$(BUILD_ROOT)/src/daemon \
ACP_PATHS_DIR=$(SOURCE_ROOT)/spa/plugins/alsa/mixer/paths \
ACP_PROFILES_DIR=$(SOURCE_ROOT)/spa/plugins/alsa/mixer/profile-sets \
PIPEWIRE_LOG_SYSTEMD=false \
$(DBG) $(BUILD_ROOT)/src/daemon/pipewire-uninstalled
run-pulse: all
@ -33,7 +32,6 @@ run-pulse: all
PIPEWIRE_CONFIG_DIR=$(BUILD_ROOT)/src/daemon \
ACP_PATHS_DIR=$(SOURCE_ROOT)/spa/plugins/alsa/mixer/paths \
ACP_PROFILES_DIR=$(SOURCE_ROOT)/spa/plugins/alsa/mixer/profile-sets \
PIPEWIRE_LOG_SYSTEMD=false \
$(DBG) $(BUILD_ROOT)/src/daemon/pipewire-pulse
gdb:

310
NEWS
View file

@ -1,204 +1,136 @@
# PipeWire 1.5.81 (2025-10-16)
# PipeWire 1.4.4 (2025-05-29)
This is the first 1.6 release candidate that is API and ABI
compatible with previous 1.4.x, 1.2.x and 1.0.x releases.
In addition to all the changes backported to 1.4.x, this release
also contains some new features:
This is a quick bugfix release that is API and ABI compatible with
previous 1.x releases.
## Highlights
- The link negotiation code was refactored and improved.
Applications now have more options for selecting the default
values and restricting the available options. The default
negotiation code will now attempt to better match the application
suggested values.
- The loop now has support for locking with priority inversion. Most
of the code was updated to use the locks instead of invoke to
get proper concurrent updates with the loop. The Thread loop
functionality of locks, signal and wait was moved to the SPA loop.
This guarantees better real-time behaviour because inter-thread
synchronization does not have to pass eventfd/epoll.
- The control stream parser was rewritten to be safe against concurrent
updates while parsing, which can occur when parsing shared memory.
It also has extra checks to avoid integer overflows and undefined
behaviour.
- MIDI 2.0 clip support was added to the tools.
- Bluetooth ASHA (Audio Streaming for Hearing Aid) support was added.
- The ALSA node setup was tweaked to provide low latency with the ALSA
Firewire driver.
- Better support for explicit sync. It is now possible to negotiate
extra features to know if a consumer will signal the sync objects and
implement a fallback using a reliable transport.
- Many bug fixes and improvements.
- Provide better compatibility with 1.2 for MIDI.
- Fix mpv buffer negotiation regression.
- Improve GStreamer compatibility with libcamera.
## PipeWire
- Avoid process calls in disconnect in pw-stream. (#3314)
- Disable PipeWire services for root.
- The link negotiation was refactored and improved. Drivers now
always have a lower priority in deciding the final format.
- Backwards compatibility with the v0 protocol was removed.
- pw-stream and pw-filter will now refuse to queue a buffer that
was not dequeued before.
- Object properties will now be updated on the global as well.
- The priority of config overrides is correct now. (#4816)
- Async links now correctly report 1 extra quantum of latency.
- node.exclusive and the new port.exclusive flag are now enforced
by PipeWire itself.
- A new timer-queue helper was added to schedule timeouts.
- node.terminal and node.physical properties are now copied to the
ports to make it possible to create virtual sources and sinks
for JACK applications.
- Port properties will now be dynamically updated when the node
properties they depend on are updated.
- Passive leaf nodes are now handled better. Now they will also
run when the peer is active. (#4915)
- Reliable transport has been added for output ports. This can be
used in some cases if the producer wants to ensure buffers are
consumed by a consumer. (#4885)
- Context properties now support rlimit.<resource> properties to
configure rlimits. (#4047)
## Modules
- Close SyncObj fds.
- module-combine-stream has better Latency reporting.
- The JACK tunnel can now optionally connect ports.
- module-loopback has better Latency reporting.
- A Dolby Surround and Dolby Pro Logic II example filter config
was added.
- Filter-chain can now resample to a specific rate before running the
filters. This is useful when the filter-graph needs to run at a
specific rate.
- Avahi-poll now uses the timer-queue to schedule timeouts.
- Modules are ported to timer-queue instead of using timerfd directly
for non-realtime timers.
## SPA
- The loop now has support for locking with priority inversion. Most
of the code was updated to use the locks instead of invoke to
get proper concurrent updates with the loop. The Thread loop
functionality of locks, signal and wait was moved to the SPA loop.
- UMP to Midi 1.0 conversion was improved, some UMP events are now
converted to multiple Midi 1.0 messages. (#4839)
- The POD filter was refactored and improved. It is now possible to
use the default value of the output by specifying an invalid input
default value.
- The POD parser was made safe for concurrent updates of the memory
it is parsing. This is important when the POD is in shared memory
and the parser should not access invalid memory.
- Some hardcoded channel limits were removed and now use the global
channel limit. More things can dynamically adapt to this global
limit. The max number of channels was then bumped to 128.
- The POD builder is safe to use on shared memory now and tries to
avoid many integer overflows.
- Most debug functions are safe to be used on shared memory.
- User specified Commands and Events are now possible.
- The SPA_IO_CLOCK_FLAG_DISCONT was added to spa_io_clock to signal
a discont in the clock due to clock change.
- AC3, DTS, EAC3, TRUEHD and MPEGH now have helper parser functions.
- H265 was added as a video format. (#4674)
- SPA_PARAM_PeerFormats was added to let a port know about its peer
formats in order to better filter possible conversions.
- More color matrices, transfer functions and color primaries.
- The echo-canceler is enabled now.
- Pro-Audio mode now uses 3 periods by default. This lowers the
latency on some drivers (Firewire). The latency of Firewire is
also reported correctly now.
- The ALSA DLL bandwidth is configurable now.
- The resampler now uses fixed point for the phases and is a little
faster when updating adaptive rates.
- The convolver is a little faster by swapping buffers instead of
copying samples.
- Latency and ProcessLatency support was added to filter-graph.
(#4678)
- Audio channel position support was added to filter-graph.
- A new ffmpeg avfilter plugin was added to filter-graph.
- A new ONNX filter was added to filter-graph.
- A debug, pipe, zeroramp and noisegate filter was added to the
filter-graph. (#4745)
- The filter-graph lv2 plugin now supports options and state.
- videoconvert was greatly improved.
- The v4l2 plugin can negotiate DMABUF with modifiers.
- Colorimetry information was added to v4l2 and libcamera.
- Audioconvert can handle empty buffers more efficiently.
- Improve the POD compare functions for Rectangle.
- There is now a SPA_POD_PROP_FLAG_DROP flag to drop the property when
the property is missing from one side.
- A new FEATURE choice was added that is basically a flags choice with
a FLAG_DROP property.
- Metadata features were added. This is a way to negotiate new features
for the metadata. (#4885)
- DSD playback with pw-cat has been improved.
- Compatibility and xrun prevention for the SOF driver has been
improved. (#4489)
- The filter-graph max plugin can now have 8 input channels.
- Buffer Negotiation between the mixer port and the node ports is much
improved. (#4918)
- An offline AEC benchmark was added.
- Channel positions are now read from HDMI ELD when possible.
- Audioconvert and filter-graph now also support properties of Long
and String types.
## ACP
- It's possible to disable the pro-audio profile.
- Support for Logitech Z407 PC Speakers was improved.
- Support for Razer BlackShark v3.
- Fix volume rounding down causing mute. (#4890)
## Tools
- pw-cat can now play and record MIDI 2.0 Clips, which is the
official format for storing MIDI 2.0 UMP data. pw-midi2play
and pw-midi2record were added as aliases.
- pw-cat can now upload sysex files. The pw-sysex alias was
added for this.
- The pw-link tool now has a -t option to list port latencies.
It also has better monitor support.
- pw-top can now clear the ERR column with the c key.
- pw-cli now keeps the types of the variables it stores and avoid
using wrongly typed variables that can crash things. It can now
also list the available variables.
- pw-dump can now output raw JSON and SPA JSON.
- pw-dump has configurable indentation level.
- pw-mididump can be forced to output MIDI 1.0 messages.
- pw-profiler now uses doubles for extra precision.
- pw-top now marks the async nodes with =.
## Bluetooth
- Telephony improvements.
- ASHA support was added.
- Packet loss concealment was added.
- Improved synchronisation between LE Audio streams in the same group.
- Improved LE Audio device compatibility.
- LC3-24kHz voice codec was added (used by Airpods)
- LDAC decoding support added (requires separate decoder library)
## Pulse-server
- The SUSPEND event is now correctly generated. fail-on-suspend is
now implemented.
- PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND is now implemented. (#4255)
(#4726)
- RTP streams now have stream.properties for extra configuration.
- Timed out streams are now destroyed instead of lingering. (#4901)
- A new help and pipewire-pulse:list-modules core message was added.
## JACK
- Port rename callbacks are now emitted correctly.
- Use safe POD parsing for the control sequences.
## V4l2
- The wrapper now avoids a race while initializing PipeWire. (#4859)
- Provide conversions to old style midi in the ALSA sequencer.
- Negotiate only to UMP when using a newer library.
- Fix negotiation direction for buffers, prefer the converter
suggestion instead of the application until we can be sure
applications make good suggestions.
## GStreamer
- Colorimetry support was added.
- Cursor metadata is now exposed as ROI metadata.
- Many more updates.
## Docs
- Document the client-node flow a bit more.
- Allow a minimum of 1 buffers again instead of 8. libcamera will
allocate only 4 buffers so we need to support this.
Older versions:
# PipeWire 1.4.3 (2025-05-22)
This is a bugfix release that is API and ABI compatible with
previous 1.x releases.
## Highlights
- Many netjack2 improvements. The driver/manager roles were fixed,
MIDI is written correctly and errors are handled better.
- Improvements to UMP sysex handling.
- More small bug fixes and improvements.
## PipeWire
- Let all commands go to the node. This makes it possible to send
custom commands.
## Modules
- Many netjack2 improvements. The driver/manager roles were fixed,
MIDI is written correctly and errors are handled better.
- Improve the filter-graph state management in filter-chain.
## SPA
- Use default value of filter. (#4619)
- Fix UMP program change conversion to MIDI 1.0. (#4664)
- Skip only the first buffer for raw formats in v4l2 to avoid
dropping important headers when dealing with encoded formats.
- Fix ebur128 port name. (#4667)
- Only convert UMP/MIDI, pass other controls. Fixes OSC and other
control types in the mixer. (#4692)
- Improve UMP sysex handling in alsa seq.
- Improve ALSA audio.channels support. Only use this when the value
is within the valid range.
## Tools
- debug UMP SysRT messages correctly in pw-mididump.
## JACK
- Handle sysex in UMP better by appending the converted midi1
sysex.
# PipeWire 1.4.2 (2025-04-14)
This is a bugfix release that is API and ABI compatible with
previous 1.x releases.
## Highlights
- Do extra checks for MIDI to avoid 100% CPU usage on older kernels.
- Fix some potential crashes in POD builder.
- pw-cat streaming improvements on stdout/stdin.
- Small fixes and improvements.
## PipeWire
- Make the service files depend on DBus to avoid startup races.
## SPA
- Do extra checks for MIDI to avoid 100% CPU usage on older kernels.
- Use Header metadata by default in videoadapter.
- Handle set_format result from v4l2 better.
- Handle crash when POD builder overflows in the filter.
- Work around a libebur128 bug. (#4646)
## Tools
- pw-cat prefers AU format when streaming on stdout/stdin. (#4629)
- Improve pw-cat verbose sndfile format debug.
- Add the missing --channel-map long option to pw-loopback.
## GStreamer
- Fix a leak in the deviceprovider. (#4616)
- Fix negotiation and make renegotiation better.
# PipeWire 1.4.1 (2025-03-14)
This is a quick bugfix release that is API and ABI compatible with
previous 1.x releases.
## Highlights
- Handle SplitPCM wrong channels specifications. This fixes some
problems with disappearing devices.
- Add backwards compatibility support for when the kernel does not
support UMP. Also fix UMP output. This restores MIDI support for
older kernels/ALSA.
- Fix a crash in audioconvert because the resampler was not using the
right number of channels.
- Some compilation fixes and small improvements.
## PipeWire
- Don't emit events when disconnecting a stream. (#3314)
- Fix some compilation problems. (#4603)
## Modules
- Bump the ROC requirement to version 0.4.0
## SPA
- Handle SplitPCM too few or too many channels. Add an error string
to the device names when the UCM config has an error.
- Add backwards compatibility support for when the kernel does not
support UMP.
- Configure the channels in the resampler correctly in all
cases. (#4595)
- Fix UMP output.
- Use the right samplerate of the filter-graph in audioconvert in
all cases.
## Bluetooth
- Fix a crash with an incomming call.
# PipeWire 1.4.0 (2025-03-06)
This is the 1.4 release that is API and ABI compatible with previous

View file

@ -38,7 +38,6 @@ IGNORE_PREFIX = pw_ \
spa_ \
SPA_
GENERATE_TREEVIEW = YES
DISABLE_INDEX = NO
SEARCHENGINE = YES
GENERATE_LATEX = NO

View file

@ -41,11 +41,6 @@
<tab type="globals" visible="no" title="" intro=""/>
</tab>
<tab type="examples" visible="yes" title="" intro=""/>
<tab type="usergroup" title="PipeWire Versions">
<tab type="user" url="https://docs.pipewire.org/1.2/" title="1.2.x"/>
<tab type="user" url="https://docs.pipewire.org/1.4/" title="1.4.x"/>
<tab type="user" url="https://docs.pipewire.org/devel/" title="Development"/>
</tab>
</navindex>
<!-- Layout definition for a class page -->

View file

@ -1,4 +1,4 @@
html {
:root {
/* --page-background-color: #729fcf; */
--primary-color: #729fcf;
--primary-dark-color: #729fcf;
@ -8,7 +8,7 @@ html {
}
@media (prefers-color-scheme: light) {
html {
:root {
--code-background: #f5f5f5;
--code-foreground: #333333;
--fragment-background: #f5f5f5;

View file

@ -33,7 +33,7 @@ POD's can contain a number of basic SPA types:
- `SPA_TYPE_Bytes`: A byte array.
- `SPA_TYPE_Rectangle`: A rectangle with width and height.
- `SPA_TYPE_Fraction`: A fraction with numerator and denominator.
- `SPA_TYPE_Bitmap`: An array of bits. Deprecated and unused.
- `SPA_TYPE_Bitmap`: An array of bits.
POD's can be grouped together in these container types:
@ -435,11 +435,10 @@ spa_pod_parser_get_object(&p,
\endcode
`spa_pod_get_values()` is a useful function. It returns a
`struct spa_pod*` with and array of values. For invalid PODs
it returns the POD and no values. For normal PODs it returns
the POD and one value. For choice values it returns the choice
type and an array of values. If the choice doesn't fit even a
single value, the array will have no values.
`struct spa_pod*` with and array of values. For normal POD's
and choice none values, it simply returns the POD and one value.
For other choice values it returns the choice type and an array
of values:
\code{.c}
struct spa_pod *value;
@ -1020,9 +1019,8 @@ A choice contains an array of possible values.
child2 and child3, in steps of child4 in the value array.
- Enum (3) : child1 is a default value, options are any value from
the value array, preferred values come first.
- Flags (4) : only child1 is a flag value. When filtering, the flags
are AND-ed together.
- Flags (4) : child1 is a default value, options are any value from
the value array, preferred values come first.
- flags: must be 0
## Pod (20)

View file

@ -48,7 +48,7 @@ ALSA client match rules.
In addition, the PipeWire context configuration sections
may also be specified, see \ref page_man_pipewire_conf_5 "pipewire.conf(5)".
# STREAM PROPERTIES @IDX@ client.conf stream.properties
# STREAM PROPERTIES @IDX@ client.conf
The client configuration files contain a stream.properties section that configures the options for client streams:
```css
@ -93,7 +93,7 @@ A list of object properties that can be applied to streams can be found in
and
\ref props__audio_converter_properties "pipewire-props(7) Audio Adapter Properties"
# STREAM RULES @IDX@ client.conf stream.rules
# STREAM RULES @IDX@ client.conf
You can add \ref pipewire_conf__match_rules "match rules, see pipewire(1)"
to set properties for certain streams and filters.
@ -127,7 +127,7 @@ stream.rules = [
Will set the node.name of Firefox to "My Name".
# ALSA CLIENT PROPERTIES @IDX@ client.conf alsa.properties
# ALSA CLIENT PROPERTIES @IDX@ client.conf
An `alsa.properties` section can be added to configure client applications
that connect via the PipeWire ALSA plugin.
@ -169,7 +169,7 @@ The number of bytes in the alsa buffer. The default is 0, which is to allow any
This controls the volume curve used on the ALSA mixer. Possible values are `cubic` and
`linear`. The default is to use `cubic`.
# ALSA CLIENT RULES @IDX@ client.conf alsa.rules
# ALSA CLIENT RULES @IDX@ client.conf
It is possible to set ALSA client specific properties by using
\ref pipewire_conf__match_rules "Match rules, see pipewire(1)". You can

View file

@ -38,7 +38,7 @@ JACK client match rules.
In addition, the PipeWire context configuration sections
may also be specified, see \ref page_man_pipewire_conf_5 "pipewire.conf(5)".
# JACK PROPERTIES @IDX@ jack.conf jack.properties
# JACK PROPERTIES @IDX@ jack.conf
The configuration file can contain an extra JACK specific section called `jack.properties` like this:
```css
@ -206,7 +206,7 @@ JACK apps don't know about this flag yet and refuse to show the port.
Set this to true for applications that know how to handle MIDI2 ports.
\endparblock
# MATCH RULES @IDX@ jack.conf jack.rules
# MATCH RULES @IDX@ jack.conf
`jack.rules` provides an `update-props` action that takes an object with properties that are updated
on the client and node object of the jack client.

View file

@ -36,96 +36,13 @@ type. Other properties control settings of a specific kinds of device
or node (ALSA, Bluetooth, ...), and have meaning only for those
objects.
# CUSTOMIZING PROPERTIES @IDX@ props
Usually, all the properties are configured in the session manager
configuration. For how to configure them, see the session manager
documentation. In minimal PipeWire setups without a session manager,
they can be configured via
\ref pipewire_conf__context_objects "context.objects in pipewire.conf(5)".
Usually, all device properties are configured in the session manager
configuration, see the session manager documentation.
Application properties are configured in
``client.conf`` (for native PipeWire and ALSA applications),
``pipewire-pulse.conf`` (for Pulseaudio applications), and
``jack.conf`` (for JACK applications).
In minimal PipeWire setups without a session manager,
the device properties can be configured via
\ref pipewire_conf__context_objects "context.objects in pipewire.conf(5)"
when creating the devices.
## Examples
Device configuration using WirePlumber (requires WirePlumber restart to apply).
See [WirePlumber configuration](https://pipewire.pages.freedesktop.org/wireplumber/daemon/configuration.html)
```css
# ~/.config/wireplumber/wireplumber.conf.d/custom-props.conf
monitor.alsa.properties = {
alsa.udev.expose-busy = true
}
monitor.alsa.rules = [
{
matches = [ { device.name = "~alsa_card.pci-.*" } ],
actions = { update-props = { api.alsa.soft-mixer = true } }
},
{
matches = [ { node.name = "alsa_output.pci-0000_03_00.1.hdmi-stereo-extra3" } ]
actions = { update-props = { node.description = "Main Audio" } }
}
]
monitor.alsa-midi.properties = {
api.alsa.seq.ump = true
}
monitor.bluez.properties = {
bluez5.hfphsp-backend = ofono
}
monitor.bluez.rules = [
{
matches = [ { device.name = "~bluez_card.*" } ],
actions = { update-props = { bluez5.dummy-avrcp player = true } }
}
]
```
Native client configuration (requires client application restart to apply).
See \ref client_conf__stream_rules "pipewire-client.conf(5)"
```css
# ~/.config/pipewire/client.conf/custom-props.conf
stream.rules = [
{
matches = [ { application.name = "pw-play" } ]
actions = { update-props = { node.description = "Some pw-cat stream" } }
}
]
```
Pulseaudio client configuration (requires \ref page_man_pipewire-pulse_1 "pipewire-pulse(1)" restart to apply).
See \ref pipewire-pulse_conf__stream_rules "pipewire-pulse.conf(5)"
```css
# ~/.config/pipewire/pipewire-pulse.conf/custom-props.conf
stream.rules = [
{
matches = [ { application.name = "paplay" } ]
actions = { update-props = { node.description = "Some paplay stream" } }
}
]
```
JACK client configuration (requires client restart to apply).
See \ref jack_conf__match_rules "pipewire-jack.conf(5)"
```css
# ~/.config/pipewire/jack.conf/custom-props.conf
jack.rules = [
{
matches = [ { client.name = "jack_delay" } ]
actions = { update-props = { node.description = "Some JACK node" } }
}
]
```
\see [WirePlumber configuration](https://pipewire.pages.freedesktop.org/wireplumber/daemon/configuration.html)
# COMMON DEVICE PROPERTIES @IDX@ props
@ -174,12 +91,12 @@ ie. for example `device.Param.Props = { ... }` to set `Props`.
@PAR@ device-prop device.product.id # integer
\parblock
\copydoc PW_KEY_DEVICE_PRODUCT_ID
\copydoc PW_KEY_DEVICE_PRODUCT_NAME
\endparblock
@PAR@ device-prop device.product.name # string
\parblock
\copydoc PW_KEY_DEVICE_PRODUCT_NAME
\copydoc PW_KEY_DEVICE_PRODUCT_ID
\endparblock
@PAR@ device-prop device.class # string
@ -226,14 +143,11 @@ real or virtual devices.
These contain properties to identify the node or to display the node in a GUI application.
@PAR@ node-prop node.name # string
@PAR@ node-prop node.name
A (unique) name for the node. This is usually set on sink and sources to identify them
as targets for linking by the session manager.
@PAR@ node-prop node.nick # string
A short name for the node.
@PAR@ node-prop node.description # string
@PAR@ node-prop node.description
A human readable description of the node or stream.
@PAR@ node-prop media.name
@ -424,14 +338,14 @@ a sink or source.
@PAR@ node-prop node.exclusive = false
If this node wants to be linked exclusively to the sink/source.
@PAR@ node-prop target.object = <node.name|object.serial>
Where the node should link to, this can be a node.name or an object.serial.
@PAR@ node-prop node.target = <node.name|object.id>
Where this node should be linked to. This can be a node.name or an object.id of a node. This property is
deprecated, the target.object property should be used instead, which uses the more unique object.serial as
a possible target.
@PAR@ node-prop target.object = <node.name|object.serial>
Where the node should link to, this can be a node.name or an object.serial.
@PAR@ node-prop node.dont-reconnect = false
\parblock
When the node has a target configured and the target is destroyed, destroy the node as well.
@ -441,13 +355,6 @@ Note that if a stream should appear/disappear in sync with the target, a session
should be written instead.
\endparblock
@PAR@ node-prop node.dont-fallback = false
If linking this node to its specified target does not succeed, session
manager should not fall back to linking it to the default target.
@PAR@ node-prop node.dont-move = false
Whether the node target may be changed using metadata.
@PAR@ node-prop node.passive = false
\parblock
This is a passive node and so it should not keep sinks/sources busy. This property makes the session manager create passive links to the sink/sources. If the node is not otherwise linked (via a non-passive link), the node and the sink it is linked to are idle (and eventually suspended).
@ -464,13 +371,6 @@ Instruct the session manager to not remix the channels of a stream. Normally the
@PAR@ node-prop priority.session # integer
The priority for selecting this node as the default source or sink.
@PAR@ node-prop session.suspend-timeout-seconds = 3 # float
Timeout in seconds, after which an idle node is suspended.
Value ``0`` means the node will not be suspended.
@PAR@ node-prop state.restore-props = true
Whether session manager should save state for this node.
## Format Properties
Streams and also most device nodes can be configured in a certain format with properties.
@ -740,12 +640,8 @@ See \ref spa_param_port_config for the meaning.
## Monitor properties
@PAR@ monitor-prop alsa.use-acp = true # boolean
@PAR@ monitor-prop alsa.use-acp # boolean
Use \ref monitor-prop__alsa_card_profiles "ALSA Card Profiles" (ACP) for device configuration.
This autodetects available ALSA devices and configures port and hardware mixers.
@PAR@ monitor-prop alsa.use-ucm # boolean
Enable or disable UCM for all devices. Default: unset.
@PAR@ monitor-prop alsa.udev.expose-busy # boolean
Expose the ALSA card even if it is busy/in use. Default false. This can be useful when some
@ -762,7 +658,7 @@ When ACP is enabled and a UCM configuration is available for a device, by
default it is used instead of the ACP profiles. This option allows you to
disable this and use the ACP profiles instead.
This option does nothing if `alsa.use-acp` is set to `false`.
This option does nothing if `api.alsa.use-acp` is set to `false`.
\endparblock
@PAR@ device-prop api.alsa.soft-mixer = false # boolean
@ -822,13 +718,6 @@ some devices.
\copydoc SPA_KEY_API_ALSA_SPLIT_ENABLE
\endparblock
@PAR@ device-prop api.acp.disable-pro-audio = false # boolean
Disable the "Pro Audio" profile for this device.
@PAR@ device-prop api.acp.use-eld-channels = false # boolean
Use the channel count and mapping the connected HDMI device
provides via ELD information.
## Node properties
@PAR@ node-prop audio.channels # integer
@ -843,9 +732,6 @@ The audio format to open the device in. By default this is "UNKNOWN", which will
@PAR@ node-prop audio.position # JSON array of strings
The audio position of the channels in the device. This is auto detected based on the profile. You can configure an array of channel positions, like "[ FL, FR ]".
@PAR@ node-prop audio.layout # string
The audio layout of the channels in the device. You can use any of the predefined layouts, like "Stereo", "5.1" etc.
@PAR@ node-prop audio.allowed-rates # JSON array of integers
\parblock
The allowed audio rates to open the device with. Default is "[ ]", which means the device can be opened in any supported rate.
@ -892,12 +778,6 @@ Setting this to 0 makes htimestamp never get disabled.
Disable timer-based scheduling, and use IRQ for scheduling instead.
The "Pro Audio" profile will usually enable this setting, if it is expected it works on the hardware.
@PAR@ node-prop api.alsa.dll-bandwidth-max # double
Sets the maximum bandwidth of the DLL (delay-locked loop) filter used to smooth out rate adjustments.
The default value may be too responsive in some scenarios.
For example, with UAC2 pitch control, the host reacts more slowly compared to local resampling,
so using a lower bandwidth helps avoid oscillations or instability.
@PAR@ node-prop api.alsa.auto-link = false # boolean
Link follower PCM devices to the driver PCM device when using IRQ-based scheduling.
The "Pro Audio" profile will usually enable this setting, if it is expected it works on the hardware.
@ -911,18 +791,12 @@ Static set the device systemic latency, in nanoseconds.
@PAR@ node-prop api.alsa.path # string
UNDOCUMENTED
@PAR@ node-prop api.alsa.pcm.card # integer
Card index to open. Usually determined from `api.alsa.path`.
@PAR@ node-prop api.alsa.open.ucm # boolean
Open device using UCM.
@PAR@ node-prop api.alsa.bind-ctls # boolean
UNDOCUMENTED
@PAR@ node-prop api.alsa.bind-ctl.NAME # boolean
UNDOCUMENTED
@PAR@ node-prop iec958.codecs # JSON array of string
Enable only specific IEC958 codecs. This can be used to disable some codecs the hardware supports.
Available values: PCM, AC3, DTS, MPEG, MPEG2-AAC, EAC3, TRUEHD, DTSHD
@ -944,34 +818,6 @@ Informative property.
Informative property.
\endparblock
@PAR@ node-prop api.alsa.dsd-lsb = false # boolean
Use LSB bit order for DSD audio output.
# ALSA MIDI PROPERTIES @IDX@ props
## Node properties
For ALSA MIDI in Wireplumber, MIDI bridge node properties are
configured in the monitor properties.
@PAR@ monitor-prop api.alsa.seq.ump = true # boolean
Use MIDI 2.0 if possible.
@PAR@ monitor-prop api.alsa.seq.min-pool = 500 # integer
UNDOCUMENTED
@PAR@ monitor-prop api.alsa.seq.max-pool = 2000 # integer
UNDOCUMENTED
@PAR@ monitor-prop clock.name = "clock.system.monotonic" # string
Clock to follow.
@PAR@ monitor-prop api.alsa.path = "default" # string
Sequencer device to use.
@PAR@ monitor-prop api.alsa.disable-longname = true # boolean
If card long name should not be passed to MIDI port.
# BLUETOOTH PROPERTIES @IDX@ props
@ -1117,26 +963,6 @@ Maximum number of octets supported per codec frame for the LC3 codec (default: 4
@PAR@ monitor-prop bluez5.bap-server-capabilities.max_frames # integer
Maximum number of codec frames supported per SDU for the LC3 codec (default: 2).
@PAR@ monitor-prop bluez5.bap-server-capabilities.sink.locations # JSON or integer
Sink audio locations of the server, as channel positions or PACS bitmask.
Example: `FL,FR`
@PAR@ monitor-prop bluez5.bap-server-capabilities.sink.contexts # integer
Available sink contexts PACS bitmask of the the server.
@PAR@ monitor-prop bluez5.bap-server-capabilities.sink.supported-contexts # integer
Supported sink contexts PACS bitmask of the the server.
@PAR@ monitor-prop bluez5.bap-server-capabilities.source.locations # JSON or integer
Source audio locations of the server, as channel positions or PACS bitmask.
Example: `FL,FR`
@PAR@ monitor-prop bluez5.bap-server-capabilities.source.contexts # integer
Available source contexts PACS bitmask of the the server.
@PAR@ monitor-prop bluez5.bap-server-capabilities.source.supported-contexts # integer
Supported source contexts PACS bitmask of the the server.
## Device properties
@PAR@ device-prop bluez5.auto-connect # boolean
@ -1171,31 +997,6 @@ PipeWire Opus Pro Audio duplex encoding mode: audio, voip, lowdelay
@PAR@ device-prop bluez5.bap.cig = "auto" # integer, or 'auto'
Set CIG ID for BAP unicast streams of the device.
@PAR@ device-prop bluez5.bap.preset = "auto" # string
BAP QoS preset name that needed to be used with vendor config.
This property is experimental.
Available: "48_2_1", ... as in the BAP specification.
@PAR@ device-prop bluez5.bap.rtn # integer
BAP QoS preset name that needed to be used with vendor config.
This property is experimental.
Default: as per QoS preset.
@PAR@ device-prop bluez5.bap.latency # integer
BAP QoS latency that needs to be applied for vendor defined preset
This property is experimental.
Default: as QoS preset.
@PAR@ device-prop bluez5.bap.delay = 40000 # integer
BAP QoS delay that needs to be applied for vendor defined preset
This property is experimental.
Default: as per QoS preset.
@PAR@ device-prop bluez5.framing = false # boolean
BAP QoS framing that needs to be applied for vendor defined preset
This property is experimental.
Default: as per QoS preset.
## Node properties
@PAR@ node-prop bluez5.media-source-role # string
@ -1206,17 +1007,6 @@ this instance. Available values:
- input: appear as source node.
\endparblock
@PAR@ node-prop bluez5.decode-buffer.latency # integer
Applies on media source nodes and defines the target amount
of samples to be buffered on the output of the decoder.
Default: 0, which means it is automatically determined.
@PAR@ node-prop node.latency-offset-msec # string
Applies only for BLE MIDI nodes.
Latency adjustment to apply on the node. Larger values add a
constant latency, but reduces timing jitter caused by Bluetooth
transport.
# PORT PROPERTIES @IDX@ props
Port properties are usually not directly configurable via PipeWire

View file

@ -54,7 +54,7 @@ for the detailed description.
In addition, the PipeWire context configuration sections
may also be specified, see \ref page_man_pipewire_conf_5 "pipewire.conf(5)".
# STREAM PROPERTIES @IDX@ pipewire-pulse.conf stream.properties
# STREAM PROPERTIES @IDX@ pipewire-pulse.conf
The `stream.properties` section contains properties for streams created
by the pipewire-pulse server.
@ -100,18 +100,18 @@ stream.properties = {
}
```
# STREAM RULES @IDX@ pipewire-pulse.conf stream.rules
# STREAM RULES @IDX@ pipewire-pulse.conf
The `stream.rules` section works the same as
\ref client_conf__stream_rules "pipewire-client.conf(5) stream.rules".
# PULSEAUDIO PROPERTIES @IDX@ pipewire-pulse.conf pulse.properties
# PULSEAUDIO PROPERTIES @IDX@ pipewire-pulse.conf
For `pulse.properties` section,
see \ref page_module_protocol_pulse "libpipewire-module-protocol-pulse(7)"
for available options.
# PULSEAUDIO RULES @IDX@ pipewire-pulse.conf pulse.rules
# PULSEAUDIO RULES @IDX@ pipewire-pulse.conf
For each client, a set of rules can be written in `pulse.rules`
section to configure quirks of the client or to force some pulse

View file

@ -140,7 +140,7 @@ Array of dictionaries. Match rules for modifying device properties
on the server.
# CONTEXT PROPERTIES @IDX@ pipewire.conf context.properties
# CONTEXT PROPERTIES @IDX@ pipewire.conf
Available PipeWire properties in `context.properties` and possible
default values.
@ -275,20 +275,6 @@ Warn about failures to lock memory.
@PAR@ pipewire.conf mem.mlock-all = false
Try to mlock all current and future memory by the process.
@PAR@ pipewire.conf rlimit.nofile = 4096
Try to set the max file descriptor number resource limit of the process.
A value of -1 raises the limit to the system defined hard maximum value.
The file resource limit is usually 1024 and should only be raised if the
program does not use the select() system call. PipeWire does normally not
use select().
@PAR@ pipewire.conf rlimit.*resource* = *value*
Set resource limits. *resource* can be one of: as, core, cpu,
data, fsize, locks, memlock, msgqueue, nice, nofile, nproc, rss, rtprio,
rttime, sigpending or stack. See the documentation of setrlimit to get the
meaning of these resources. A value of -1 will set the maximum allowed
limit.
@PAR@ pipewire.conf settings.check-quantum = false
Check if the quantum in the settings metadata update is compatible
with the configured limits.
@ -316,7 +302,7 @@ the `context.modules` and `context.objects` sections can declare
additional conditions that control whether a module or object is loaded
depending on what properties are present.
# SPA LIBRARIES @IDX@ pipewire.conf context.spa-libs
# SPA LIBRARIES @IDX@ pipewire.conf
SPA plugins are loaded based on their factory-name. This is a well
known name that uniquely describes the features that the plugin should
@ -345,7 +331,7 @@ context.spa-libs = {
}
```
# MODULES @IDX@ pipewire.conf context.modules
# MODULES @IDX@ pipewire.conf
PipeWire modules to be loaded. See
\ref page_man_libpipewire-modules_7 "libpipewire-modules(7)".
@ -378,7 +364,7 @@ A \ref pipewire_conf__match_rules "match rule" `matches` condition.
The module is loaded only if one of the expressions in the array matches
to a context property.
# CONTEXT OBJECTS @IDX@ pipewire.conf context.objects
# CONTEXT OBJECTS @IDX@ pipewire.conf
The `context.objects` section allows you to make some objects from factories (usually created
by loading modules in `context.modules`).
@ -431,7 +417,7 @@ context.objects = [
]
```
# COMMAND EXECUTION @IDX@ pipewire.conf context.exec
# COMMAND EXECUTION @IDX@ pipewire.conf
The `context.exec` section can be used to start arbitrary commands as
part of the initialization of the PipeWire program.
@ -604,7 +590,7 @@ matches = [
```
# CONTEXT PROPERTIES RULES @IDX@ pipewire.conf context.properties.rules
# CONTEXT PROPERTIES RULES @IDX@ pipewire.conf
`context.properties.rules` can be used to dynamically update the properties
based on other properties.
@ -628,7 +614,7 @@ context.properties.rules = [
}
```
# NODE RULES @IDX@ pipewire.conf node.rules
# NODE RULES @IDX@ pipewire.conf
The node.rules are evaluated every time the properties on a node are set
or updated. This can be used on the server side to override client set
@ -661,7 +647,7 @@ node.rules = [
Will set the `node.force-quantum` property of `jack_simple_client` to 512.
# DEVICE RULES @IDX@ pipewire.conf device.rules
# DEVICE RULES @IDX@ pipewire.conf
The device.rules are evaluated every time the properties on a device are set
or updated. This can be used on the server side to override client set

View file

@ -48,6 +48,5 @@ See \ref page_api.
- [Bluetooth, PipeWire and Whatsapp calls](https://gjhenrique.com/pipewire.html)
- [Intoduction to PipeWire](https://bootlin.com/blog/an-introduction-to-pipewire/)
- [A custom PipeWire node](https://bootlin.com/blog/a-custom-pipewire-node/)
- [FOSDEM 2025 talk and slides](https://fosdem.org/2025/schedule/event/fosdem-2025-4749-pipewire-state-of-the-union/)
*/

View file

@ -44,8 +44,6 @@ The native protocol and object model is similar to
serialization/deserialization of messages. This is because the data structures
in the messages are more complicated and not easily expressible in XML.
See \ref page_module_protocol_native for details.
See also \ref page_native_protocol for the documentation of the protocol
messages.
# Extensibility

View file

@ -1,115 +0,0 @@
/** \page page_driver Driver architecture and workflow
This document explains how drivers are structured and how they operate.
This is useful to know both for debugging and for writing new drivers.
(For details about how the graph does scheduling, which is tied to the driver,
see \ref page_scheduling ).
# Clocks
A driver is a node that starts graph cycles. Typically, this is accomplished
by using a timer that periodically invokes a callback, or by an interrupt.
Drivers use the monotonic system clock as the reference for timestamping. Note
that "monotonic system clock" does not refer to the \c MONOTONIC_RAW clock in
Linux, but rather, to the regular monotonic clock.
Drivers may actually be run by a custom internal clock instead of the monotonic
system clock. One example would be a sound card DAC's clock. Another would be
a network adapter with a built in PHC. Or, the driver may be using a system
clock other than the monotonic system clock. The driver then needs to perform
some sort of timestamp translation and drift compensation from that internal
clock to the monotonic clock, since it still needs to generate monotonic clock
timestamps for the beginning cycle. (More on that below.)
# Updates and graph cycle start
Every time a driver starts a graph cycle, it must update the contents of the
\ref spa_io_clock instance that is assigned to them through the
\ref spa_node_methods::set_io callback. The fields of the struct must be
updated as follows:
- \ref spa_io_clock::nsec : Must be set to the time (according to the monotonic
system clock) when the cycle that the driver is about to trigger started. To
minimize jitter, it is usually a good idea to increment this by a fixed amount
except for when the driver starts and when discontinuities occur in its clock.
- \ref spa_io_clock::rate : Set to a value that can translate samples to nanoseconds.
- \ref spa_io_clock::position : Current cycle position, in samples. This is the
ideal position of the graph cycle (this is explained in greater detail further below).
It is incremented by the duration (in samples) at the beginning of each cycle. If
a discontinuity is experienced by the driver that results in a discontinuity in the
position of the old and the current cycle, consider setting the
\ref SPA_IO_CLOCK_FLAG_DISCONT flag to inform other nodes about this.
- \ref spa_io_clock::duration : Duration of this new cycle, in samples.
- \ref spa_io_clock::rate_diff : A decimal value that is set to whatever correction
factor the driver applied to for a drift between an internal driver clock and the
monotonic system clock. A value above 1.0 means that the internal driver clock
is faster than the monotonic system clock, and vice versa. Always set this to
1.0 if the driver is directly using the monotonic clock.
- \ref spa_io_clock::next_nsec : Must be set to the time (according to the monotonic
system clock) when the cycle that comes after the current one is to be started. In
some cases, this may actually be in the past relative to nsec, for example, when
some internal driver clock experienced a discontinuity. Consider setting the
\ref SPA_IO_CLOCK_FLAG_DISCONT flag in such a case. Just like with nsec, to
minimize jitter, it is usually a good idea to increment this by a fixed amount
except for when the driver starts and when discontinuities occur in its clock.
The driver node signals the start of the graph cycle by calling \ref spa_node_call_ready
with the \ref SPA_STATUS_HAVE_DATA and \ref SPA_STATUS_NEED_DATA flags passed
to that function call. That call must happen inside the thread that runs the
data loop assigned to the driver node.
As mentioned above, the \ref spa_io_clock::position field is the _ideal_ position
of the graph cycle, in samples. This contrasts with \ref spa_io_clock::nsec, which
is the moment in monotonic clock time when the cycle _actually_ happens. This is an
important distinction when driver is run by a clock that is different to the monotonic
clock. In that case, the \ref spa_io_clock::nsec timestamps are adjusted to match the
pace of that different clock (explained in the section below). In such a case,
\ref spa_io_clock::position still is incremented by the duration in samples. This
is important, since nodes and modules may use this field as an offset within their own
internal ring buffers or similar structures, using the position field as an offset within
said data structures. This requires the position field to advance in a continuous way.
By incrementing by the duration, this requirement is met.
# Using clocks other than the monotonic clock
As mentioned earlier, the driver may be run by an internal clock that is different
to the monotonic clock. If that other clock can be directly used for scheduling
graph cycle initiations, then it is sufficient to compute the offset between that
clock and the monotonic clock (that is, offset = monotonic_clock_time - other_clock_time)
at each cycle and use that offset to translate that other clock's time to the monotonic
clock time. This is accomplished by adding that offset to the \ref spa_io_clock::nsec
and \ref spa_io_clock::next_nsec fields. For example, when the driver uses the realtime
system clock instead of the monotonic system clock, then that realtime clock can still
be used with \c timerfd to schedule callback invocations within the data loop. Then,
computing the (monotonic_clock_time - realtime_clock_time) offset is sufficient, as
mentioned, to be able to translate clock's time to monotonic time for \ref spa_io_clock::nsec
and \ref spa_io_clock::next_nsec (which require monotonic clock timestamps).
If however that other clock cannot be used for scheduling graph cycle initiations directly
(for example, because the API of that clock has no functionality to trigger callbacks),
then, in addition to the aforementioned offset, the driver has to use the monotonic clock
for triggering callbacks (usually via \c timerfd) and adjust the time when callbacks are
invoked such that they match the pace of that other clock.
As an example (clock speed difference exaggerated for sake of clarity), suppose the other
clock is twice as fast as the monotonic clock. Then the monotonic clock timestamps have
to be calculated in a manner that halves the durations between said timestamps, and the
\ref spa_io_clock::rate_diff field is set to 2.0.
The dummy node driver uses a DLL for this purpose. It is fed the difference between the
expected position (in samples) and the actual position (derived from the current time
of the driver's internal clock), passes the delta between these two quantities into the
DLL, and the DLL computes a correction factor (2.0 in the above example) which is used
for scaling durations between \c timerfd timeouts. This forms a control loop, since the
correction factor causes the durations between the timeouts to be adjusted such that the
difference between the expected position and the actual position reaches zero. Keep in
mind the notes above about \ref spa_io_clock::position being the ideal position of the
graph cycle, meaning that even in this case, the duration it is incremented by is
_not_ scaled by the correction factor; the duration in samples remains unchanged.
(Other popular control loop mechanisms that are suitable alternatives to the DLL are
PID controllers and Kalman filters.)
*/

View file

@ -11,9 +11,6 @@
- \subpage page_library
- \subpage page_dma_buf
- \subpage page_scheduling
- \subpage page_driver
- \subpage page_latency
- \subpage page_tag
- \subpage page_native_protocol

View file

@ -1,282 +0,0 @@
/** \page page_latency Latency support
This document explains how the latency in the PipeWire graph is implemented.
# Use Cases
## A node port has a latency
Applications need to be able to query the latency of a port.
Linked Nodes need to be informed of the latency of a port.
## dynamically update port latencies
It needs to be possible to dynamically update the latency of a port and this
should inform all linked ports/nodes of the updated latency.
## Linked nodes add latency to the signal
When two nodes/ports have a latency, the signal is delayed by the sum of
the nodes latencies.
## Calculate the signal delay upstream and downstream
A node might need to know how much a signal was delayed since it arrived
in the node.
A node might need to know how much the signal will be delayed before it
exists the graph.
## Detect latency mismatch
When a signal travels through 2 different parts of the graph with different
latencies and then eventually join, there is a latency mismatch. It should
be possible to detect this mismatch.
# Concepts
## Port Latency
The fundamental object for implementing latency reporting in PipeWire is the
Latency object.
It consists of a direction (input/output) and min/max latency values. The latency
values can express a latency relative to the graph quantum, the samplerate or in
nanoseconds. There is a mininum and maximum latency value in the Latency object.
The direction of the latency object determines how the latency object propagates.
- SPA_DIRECTION_OUTPUT Latency objects move from output ports downstream and contain
the latency from all nodes upstream. An output latency received on an input port
should instruct the node to update the output latency on its output ports related
to this input port. This corresponds to the JackCaptureLatency.
- SPA_DIRECTION_INPUT Latency objects move from input ports upstream and contain
the latency from all nodes downstream. An input latency received on an output port
should instruct the node to update the input latency on its input ports related
to this output port. This corresponds to the JackPlaybackLatency.
PipeWire will automatically propagate Latency objects from ports to all linked ports
in the graph. Output Latency objects on output ports are propagated to linked input
ports and input Latency objects on input ports are propagated to linked output ports.
If a port has links with multiple other ports, the Latency objects are merged by
taking the min of the min values and the max of the max values of all latency objects
on the other ports.
This way, Output Latency always describes the aggragated total upstream latency of
signal up to the port and Input latency describes the aggregated downstream latency
of the signal from the port.
## Node ProcessLatency
This is a per node property and applies to the latency introduced by the node
logic itself.
This mostly works if (almost) all data processing ports (input/output) participate in
the same data processing with the same latency, which is a common use case.
ProcessLatency is mostly used to easily calculate Output and Input Latency on ports.
We can simply add the ProcessLatency to all latency values in the ports Latency objects
to obtain the corresponding Latency object for the other ports.
# Latency updates
Latency params on the ports can be updated as needed. This can happen because some upstream or
downstream latency changed or when the ProcessLatency of a node changes.
When the ProcessLatency changes, the procedure to notify of latency changes is:
- Take output latency on input port, add new ProcessLatency, set new latency on output
port. This propagates the new latency downstream.
- Take input latency on output port, add new ProcessLatency, set new latency on input
port. This propagates the new latency upstream.
PipeWire will automatically aggregate latency from links and propagate the new latencies
down and upstream.
# Async nodes
When a node has the node.async property set to true, it will be considered an async
node and will be scheduled differently, see scheduling.dox.
A link between a port of an async node and another port (async or not) is called an
async link and will have the link.async=true property.
An async link will add 1 quantum of latency between the nodes it links. A special
exception is made for the output ports of the driver node, which do not add latency.
The Latency param will be updated with 1 extra quantum when they travel over an async
link.
# Examples
## A source node with a given ProcessLatency
When we have a source with a ProcessLatency, for example, of 1024 samples:
```
+----------+ + Latency: [{ "direction": "output", "min-rate": 1024, "max-rate": 1024 } ]
| FL ---+ Latency: [{ "direction": "input", "min-rate": 0, "max-rate": 0 } ]
| source +
| FR ---+ Latency: [{ "direction": "output", "min-rate": 1024, "max-rate": 1024 } ]
+----------+ + Latency: [{ "direction": "input", "min-rate": 0, "max-rate": 0 } ]
^
|
ProcessLatency: [ { "quantum": 0, "rate": 1024, "ns": 0 } ]
```
Both output ports have an output latency of 1024 samples and no input latency.
## A sink node with a given ProcessLatency
When we have a sink with a ProcessLatency, for example, of 512 samples:
```
Latency: [{ "direction": "output", "min-rate": 0, "max-rate": 0 } ]
Latency: [{ "direction": "input", "min-rate": 512, "max-rate": 512 } ]
^
| +----------+
+---- FL |
| sink | <- ProcessLatency: [ { "quantum": 0, "rate": 512, "ns": 0 } ]
+---- FR |
| +----------+
v
Latency: [{ "direction": "output", "min-rate": 0, "max-rate": 0 } ]
Latency: [{ "direction": "input", "min-rate": 512, "max-rate": 512 } ]
```
Both input ports have an input latency of 512 samples and no output latency.
## A source and sink node linked together
With the source and sink from above, if we link the FL channels, the input latency
from the input port of the sink is propagated to the output port of the source
and the output latency of the output port is propagated to the input port of the
sink:
```
Latency: [{ "direction": "output", "min-rate": 1024, "max-rate": 1024 } ]
Latency: [{ "direction": "input", "min-rate": 512, "max-rate": 512 } ]
^
| Latency: [{ "direction": "output", "min-rate": 1024, "max-rate": 1024 } ]
| Latency: [{ "direction": "input", "min-rate": 512, "max-rate": 512 } ]
| |
+----------+v v+--------+
| FL ------------ FL |
| source + | sink |
| FR --+ FR |
+----------+ | +--------+
v
Latency: [{ "direction": "output", "min-rate": 1024, "max-rate": 1024 } ]
Latency: [{ "direction": "input", "min-rate": 0, "max-rate": 0 } ]
```
## Insert a latency node
If we place a node with a 256 sample latency in the above source-sink graph:
```
Latency: [{ "direction": "output", "min-rate": 1024, "max-rate": 1024 } ]
Latency: [{ "direction": "input", "min-rate": 768, "max-rate": 768 } ]
^
| Latency: [{ "direction": "output", "min-rate": 1024, "max-rate": 1024 } ]
| Latency: [{ "direction": "input", "min-rate": 768, "max-rate": 768 } ]
| ^
| | Latency: [{ "direction": "output", "min-rate": 1280, "max-rate": 1280 } ]
| | Latency: [{ "direction": "input", "min-rate": 512, "max-rate": 512 } ]
| | ^
| | |
+----------+v v+--------+v +-------+
| FL ------------ FL FL --------- FL |
| source + | node | ^ | sink |
| . | . | . |
+----------+ +--------+ | +-------+
v
Latency: [{ "direction": "output", "min-rate": 1280, "max-rate": 1280 } ]
Latency: [{ "direction": "input", "min-rate": 512, "max-rate": 512 } ]
```
See how the output latency propagates and is increased going downstream and the
input latency is increased and traveling upstream.
## Link a port to two port with different latencies
When we introduce a sink2 with different input latency and link this to
the node FL output port, it will aggregate the two input latencies by
taking the min of min and max of max.
```
Latency: [{ "direction": "output", "min-rate": 1024, "max-rate": 1024 } ]
Latency: [{ "direction": "input", "min-rate": 768, "max-rate": 2304 } ]
^
| Latency: [{ "direction": "output", "min-rate": 1024, "max-rate": 1024 } ]
| Latency: [{ "direction": "input", "min-rate": 768, "max-rate": 2304 } ]
| ^
| | Latency: [{ "direction": "output", "min-rate": 1280, "max-rate": 1280 } ]
| | Latency: [{ "direction": "input", "min-rate": 512, "max-rate": 2048 } ]
| | ^
| | | Latency: [{ "direction": "output", "min-rate": 1280, "max-rate": 1280 } ]
| | | Latency: [{ "direction": "input", "min-rate": 512, "max-rate": 512 } ]
| | | ^
| | | |
+----------+v v+--------+v v +-------+
| FL ------------ FL FL --------- FL |
| source + | node | \ | sink |
| . | . \ . |
+----------+ +--------+ \ +-------+
\
\ +-------+
+--- FL |
^ | sink2 |
| . .
| +-------+
v
Latency: [{ "direction": "output", "min-rate": 1280, "max-rate": 1280 } ]
Latency: [{ "direction": "input", "min-rate": 2048, "max-rate": 2048 } ]
```
The source node now knows that its output signal will be delayed between 768 amd 2304 samples
depending on the path in the graph.
We also see that node.FL has different min/max-rate input latencies. This information can be
used to insert a delay node to align the latencies again. For example, if we delay the signal
between node.FL and FL.sink with 1536 samples, the latencies will be aligned again.
## An async output stream and sink node linked together
The sink has 1 quantum of Input latency. The stream has no output latency. When the Input latency
travels over the async link 1 quantum of latency is added and the Input latency on the stream is
now 2 quanta. Similar for the stream Output latency that receives an additional 1 quantum of
latency when it arrives in the sink over the async link.
```
Latency: [{ "direction": "output", "min-quantum": 0, "max-quantum": 0 } ]
Latency: [{ "direction": "input", "min-quantum": 2, "max-quantum": 2 } ]
^
| Latency: [{ "direction": "output", "min-quantum": 1, "max-quantum": 1 } ]
| Latency: [{ "direction": "input", "min-quantum": 1, "max-quantum": 1 } ]
| |
+----------+v v+--------+
| async FL ------------ FL |
| stream + | sink |
| FR --+ FR |
+----------+ | +--------+
v
Latency: [{ "direction": "output", "min-quantum": 0, "max-quantum": 0 } ]
Latency: [{ "direction": "input", "min-quantum": 0, "max-quantum": 0 } ]
```
*/

View file

@ -92,9 +92,6 @@ The media session will check the permissions on `/dev/snd/seq` before
attempting to create this node. It will also use inotify to wait
until the sequencer device node is accessible.
Currently, the session manager does not try to link control messages
automatically.
## JACK
JACK assumes all `"application/control"` ports are MIDI ports.
@ -105,12 +102,11 @@ filtering out the \ref SPA_CONTROL_Midi, \ref SPA_CONTROL_OSC and
converted to control messages in a similar way.
Normally, all MIDI and UMP messages are converted to MIDI1 jack events unless
the JACK port was created with an explcit "32 bit raw UMP" format or with
the JackPortIsMIDI2 flag, in which case the raw UMP is passed to the JACK
application directly. For output ports,
the JACK port was created with an explcit "32 bits raw UMP" format, in which
case the raw UMP is passed to the JACK application directly. For output ports,
the JACK events are assumed to be MIDI1 and converted to UMP unless the port
has the "32 bit raw UMP" format or the JackPortIsMIDI2 flag, in which case
the UMP messages are simply passed on.
has the "32 bit raw UMP" format, in which case the UMP messages are simply
passed on.
There is a 1 to 1 mapping between the JACK events and control
messages so there is no information loss or need for complicated

View file

@ -712,7 +712,7 @@ The info event is emitted when binding or when the device information changed.
): props
Struct(
Int: n_params
( Id: id
( Int: id
Int: flags )*
): param_info
)
@ -1091,77 +1091,6 @@ It creates a server Node that can be controlled from a client. Processing will h
in the client. It is used by pw-stream and pw-filter to implement the PipeWire media
processing nodes.
To create a client-node, one must first connect to the server and then make a
ClientNode proxy and do Core::CreateObject with the client-node factory.
This will create a server side ClientNode resource that can be controlled with the
proxy.
After the proxy is set up, the conversation between client and server goes as
follows:
```
client server
| |
|---------------------------------------->|
| ClientNode::Update | send initial node configuration
| |
|<----------------------------------------|
| Core::AddMem | memory for node activation
|<----------------------------------------|
| ClientNode::SetActivation | the node activation
|<----------------------------------------|
| ClientNode::Transport | the node transport
|<----------------------------------------|
| ClientNode::SetIO | clock IO
| |
|---------------------------------------->|
| ClientNode::SetActive(true) | set the node active
| |
|<----------------------------------------|
| ClientNode::SetParam | optional volume restore/settings
|<----------------------------------------|
| ClientNode::SetParam | optional PortConfig if needed
|---------------------------------------->|
| ClientNode::Update | Upload changed params
| |
|---------------------------------------->|
| ClientNode::PortUpdate | config for each port
. .
|<----------------------------------------|
| ClientNode::PortSetMixInfo | mixer inputs for each linked port
|<----------------------------------------|
| ClientNode::PortSetParam | Latency of the ports
|<----------------------------------------|
| ClientNode::SetActivation | activation of port peers
|---------------------------------------->|
| ClientNode::PortUpdate | Ack port updates
. .
|<----------------------------------------|
| ClientNode::PortSetParam | formats of the ports
|---------------------------------------->|
| ClientNode::PortUpdate | Ack port format update
. .
|<----------------------------------------|
| Core::AddMem | memory for the port buffers
|<----------------------------------------|
| ClientNode::PortUseBuffers | buffers for a port
. .
|<----------------------------------------|
| Core::AddMem | memory for driver activation
|<----------------------------------------|
| ClientNode::SetActivation | the driver activation
|<----------------------------------------|
| ClientNode::SetIO | driver Position IO
|<----------------------------------------|
| Core::AddMem | memory for port IO
|<----------------------------------------|
| ClientNode::PortSetIO | buffers/async-buffers port IO
. .
|<----------------------------------------|
| ClientNode::Command | Start command
. .
```
## ClientNode methods
### ClientNode::GetNode (Opcode 1)

View file

@ -2,26 +2,26 @@
This document tries to explain how the PipeWire graph is scheduled.
Graphs are constructed from linked nodes together with their ports. This
Graph are constructed from linked nodes together with their ports. This
results in a dependency graph between nodes. Special care is taken for
loopback links so that the graph remains a directed graph.
# Processing threads
The server (and clients) has two processing threads:
The server (and clients) have two processing threads:
- A main thread that will do all IPC with clients and server and configure the
- A main thread that will do all IPC with clients and server and configures the
nodes in the graph for processing.
- One (or more) data processing threads that only do the data processing.
- A (or more) data processing thread that only does the data processing.
The data processing threads are given realtime priority and are designed to
run with as little overhead as possible. All of the node resources such as
buffers, I/O areas and metadata will be set up in shared memory before the
buffers, io areas and metadata will be set up in shared memory before the
node is scheduled to run.
This document describes the processing that happens in the data processing
thread after the main thread has configured it.
thread after the main-thread has configured it.
# Nodes
@ -41,7 +41,7 @@ Each node also has:
+-v---------+
activation {
status:OK, // bitmask of NEED_DATA, HAVE_DATA or OK
pending:0, // number of unsatisfied dependencies needed to be able to run
pending:0, // number of unsatisfied dependencies to be able to run
required:0 // number of dependencies with other nodes
}
```
@ -152,15 +152,14 @@ will then:
- Check the previous cycle. Did it complete? Mark xrun on unfinished nodes.
- Perform reposition requests if any, timebase changes, etc..
- The pending counter of each follower node is set to the required field.
- Update the cycle counter in the driver activation io.
- It then loops over all targets of the driver and atomically decrements the required
field of the activation record. When the required field is 0, the eventfd is signaled
and the node can be scheduled.
In our example above, nodes A and B will have their pending state decremented. Node A
In our example above, Node A and B will have their pending state decremented. Node A
will be 0 and will be triggered first (node B has 2 pending dependencies to start with and
will not be triggered yet). The driver itself also has 2 dependencies left and will not
be triggered (completed) yet.
be triggered (complete) yet.
## Scheduling node A
@ -172,7 +171,7 @@ After processing, node A goes through the list of targets and decrements each pe
field (node A has a reference to B and the driver).
In our above example, the driver is decremented (from 2 to 1) but is not yet triggered.
Node B is decremented (from 1 to 0) and is triggered by writing to the eventfd.
node B is decremented (from 1 to 0) and is triggered by writing to the eventfd.
## Scheduling node B
@ -185,131 +184,11 @@ driver (from 1 to 0) and triggers the driver.
The graph always completes after the driver is triggered and scheduled. All required
fields from all the nodes in the target list of the driver are now 0.
The driver calculates some stats about CPU time etc.
The driver calculates some stats about cpu time etc.
# Async scheduling
# Remote nodes.
When a node has the node.async property set to true, it will be considered an async
node and will be scheduled differently.
Async nodes don't increment the pending counter of their peers and the upstream peers
also don't increment the async node pending counters. Only the driver increments the
pending counter to the async node.
This means that the async nodes do not depend on any other node and also are not a
dependency for other nodes. This also means that the async nodes can be scheduled as
soon as the driver has started the graph.
The completion of the async node does not influence the completion of the graph in
any way and async nodes are therefore interesting when real-time performance can not
be guaranteed, for example when the processing threads are not running with a real-time
priority.
A link between a port of an async node and another port (async or not) is called an
async link and will have the link.async=true property.
Because async nodes then run concurrently with other nodes, a method must be in place
to avoid concurrent access to buffer data. This is done by sending a spa_io_async_buffers
I/O to the (mixer) ports of an async link. The spa_io_async_buffers has 2 spa_io_buffer
slots.
The driver will increment a cycle counter for each cycle that it starts. Output ports
will write to the spa_io_async_buffers (cycle+1)&1 slot and input ports will read from
(cycle&1) slots. This way the async node will always consume the output of the previous
cycle and will provide data for the next cycle. They will therefore always add 1 cycle
of latency in the graph.
A special exception is made for the output ports of the driver node. When the driver is
started, the output port buffers are copied to the previous cycle spa_io_buffer slot.
This way, the async nodes will immediately pick up the new data from the driver source.
Because there are 2 buffers in flight on the spa_io_async_buffers I/O area, the link needs
to negotiate at least 2 buffers for this to work.
## Example
A, B, C are async nodes and have async links between their ports. The async
link has the spa_io_async_buffers with 2 slots (named 0 and 1) below. All the
slots are empty.
```
+--------+ +-------+ +-------+
| A | | B | | C |
| 0 -( )-> 0 0 -( )-> 0 |
| 1 ( ) 1 1 ( ) 1 |
+--------+ +-------+ +-------+
```
cycle 0: A produces a buffer AB0 on the output port in the (cycle+1)&1 slot (1).
B consumes slot cycle&1 (0) with the empty buffer and produces BC0 in slot 1
C consumes slot cycle&1 (0) with the empty buffer
```
+--------+ +-------+ +-------+
| A | | B | | C |
| (AB0) 0 -( )-> 0 ( ) 0 -( )-> 0 ( ) |
| 1 (AB0) 1 1 (BC0) 1 |
+--------+ +-------+ +-------+
```
cycle 1: A produces a buffer AB1 on the output port in the (cycle+1)&1 slot (0).
B consumes slot cycle&1 (1) with buffer AB0 and produces BC1 in slot 0
C consumes slot cycle&1 (1) with buffer BC0
```
+--------+ +-------+ +-------+
| A | | B | | C |
| (AB1) 0 -(AB1)-> 0 (AB0) 0 -(BC1)-> 0 (BC0) |
| 1 (AB0) 1 1 (BC0) 1 |
+--------+ +-------+ +-------+
```
cycle 2: A produces a buffer AB2 on the output port in the (cycle+1)&1 slot (1).
B consumes slot cycle&1 (0) with buffer AB1 and produces BC2 in slot 1
C consumes slot cycle&1 (0) with buffer BC1
```
+--------+ +-------+ +-------+
| A | | B | | C |
| (AB2) 0 -(AB1)-> 0 (AB1) 0 -(BC1)-> 0 (BC1) |
| 1 (AB2) 1 1 (BC2) 1 |
+--------+ +-------+ +-------+
```
Each async link adds 1 cycle of latency to the chain. Notice how AB0 from cycle 0,
produces BC1 in cycle 1, which arrives in node C at cycle 2.
## Latency reporting
Because the latency is really introduced by the links, the additional cycle of
latency is added when the SPA_PARAM_Latency is copied between the output and
input ports of a link.
It is possible for a sync node A to be linked to another sync node D and an
async node B:
```
+--------+ +-------+
| A | | B |
| (AB1) 0 -(AB1)-> 0 (AB0) 0 ...
| 1 \(AB0) 1 1
+--------+ \ +-------+
\
\ +-------+
\ | D |
-(AB1)-> 0 (AB1) |
| |
+-------+
```
The output latency on A's output port is what A reports. When it is copied to the
input port of B, 1 cycle is added and when it is copied to D, nothing is added.
# Remote nodes
For remote nodes, the eventfd and the activation are transferred from the server
For remote nodes, the eventfd and the activation is transferred from the server
to the client.
This means that writing to the remote client eventfd will wake the client directly
@ -319,7 +198,7 @@ All remote clients also get the activation and eventfd of the peer and driver th
are linked to and can directly trigger peers and drivers without going to the
server first.
## Remote driver nodes
## Remote driver nodes.
Remote drivers start the graph cycle directly without going to the server first.
@ -327,8 +206,7 @@ After they complete (and only when the profiler is active), they will trigger an
extra eventfd to signal the server that the graph completed. This is used by the
server to generate the profiler info.
# Lazy scheduling
## Lazy scheduling
Normally, a driver will wake up the graph and all the followers need to process
the data in sync. There are cases where:
@ -350,7 +228,7 @@ When the graph is started or partially controlled by RequestProcess events and
commands we say we have lazy scheduling. The driver is not always scheduling according
to its own rhythm but also depending on the follower.
We cannot just enable lazy scheduling when no follower will emit RequestProcess events
We can't just enable lazy scheduling when no follower will emit RequestProcess events
or when no driver will listen for RequestProcess commands. Two new node properties are
defined:
@ -365,9 +243,9 @@ defined:
>1 means request events as a follower are supported with increasing preference
We can only enable lazy scheduling when both the driver and (at least one) follower
have the node.supports-lazy and node.supports-request properties respectively.
has the node.supports-lazy and node.supports-request property respectively.
Nodes can end up as a driver (is_driver()) and lazy scheduling can be enabled (is_lazy()),
Node can end up as a driver (is_driver()) and lazy scheduling can be enabled (is_lazy()),
which results in the following cases:
driver producer
@ -424,7 +302,7 @@ Some use cases:
consumer
- node.driver = false
-> producer selected as driver, consumer is a simple follower.
-> producer selected as driver, consumer is simple follower.
lazy scheduling inactive (no lazy driver or no request follower)

View file

@ -1,70 +0,0 @@
/** \page page_tag Tag support
This document explains how stream specific metadata is transported in
the PipeWire graph.
The metadata is a dictionary of string key/value pairs with information
such as the author, track, copyright, album information etc.
# Use Cases
## A stream/node/port has some metadata
Applications need to be able to query the Tag of a port/node/stream.
Linked Nodes need to be informed of the upstream and downstream tags.
## dynamically update tags
It needs to be possible to dynamically update the tags of a port/node/stream
and this should inform all linked ports/nodes of the updated tags.
## Aggregate tags upstream and downstream
A node might need to know all the upstream and downstream tags. Each node can
add or remove metadata in the Tag param.
A mixer node might need to combine the Tags of the two input streams and
generate a combined tag.
# Concepts
## Port Tags
The fundamental object for implementing metadata reporting in PipeWire is the
Tag object.
It consists of a direction (input/output) and one or more generic dictionaries
with string key/value pairs.
The direction of the tag object determines how the object propagates in the graph.
- SPA_DIRECTION_OUTPUT Tag objects move from output ports downstream and contain
the metadata from all nodes upstream. An output tag received on an input port
should instruct the node to update the output tag on its output ports related
to this input port.
- SPA_DIRECTION_INPUT Tag objects move from input ports upstream and contain
the metadata from all nodes downstream. An input tag received on an output port
should instruct the node to update the input tag on its input ports related
to this output port.
PipeWire will automatically propagate Tag objects from ports to all linked ports
in the graph. Output Tag objects on output ports are propagated to linked input
ports and input Tag objects on input ports are propagated to linked output ports.
If a port has links with multiple other ports, the Tag objects are merged by
appending the dictionaties to the Tag param. Intermediate nodes or sinks are allowed
to take the multiple dictionaries in a Tag and combine them into one dictionary if
they would like to do so.
This way, Output Tag always describes the aggragated total upstream metadata of
signal up to the port and Input tag describes the aggregated downstream metadata
of the signal from the port.
# Tag updates
Tag params on the ports can be updated as needed. This can happen because some upstream or
downstream Tag changed or when the metadata of a node/port/stream changes.
*/

View file

@ -14,10 +14,6 @@ Play and record media with PipeWire
**pw-midirecord** \[*options*\] \[*FILE* \| -\]
**pw-midi2play** \[*options*\] \[*FILE* \| -\]
**pw-midi2record** \[*options*\] \[*FILE* \| -\]
**pw-dsdplay** \[*options*\] \[*FILE* \| -\]
# DESCRIPTION
@ -28,10 +24,10 @@ supported by `libsndfile` for PCM capture and playback. When capturing
PCM, the filename extension is used to guess the file format with the
WAV file format as the default.
It understands standard MIDI files and MIDI 2.0 clip files for playback
and recording. This tool will not render MIDI files, it will simply make
the MIDI events available to the graph. You need a MIDI renderer such as
qsynth, timidity or a hardware MIDI renderer to hear the MIDI.
It understands standard MIDI files for playback and recording. This tool
will not render MIDI files, it will simply make the MIDI events
available to the graph. You need a MIDI renderer such as qsynth,
timidity or a hardware MIDI rendered to hear the MIDI.
DSD playback is supported with the DSF file format. This tool will only
work with native DSD capable hardware and will produce an error when no
@ -57,13 +53,13 @@ connection is made to the default PipeWire instance.
\par -p | \--playback
Playback mode. Read data from the specified file, and play it back. If
the tool is called under the name **pw-play**, **pw-midiplay** or
**pw-midi2play** this is the default.
the tool is called under the name **pw-play** or **pw-midiplay** this is
the default.
\par -r | \--record
Recording mode. Capture data and write it to the specified file. If the
tool is called under the name **pw-record**, **pw-midirecord** or
**pw-midi2record** this is the default.
tool is called under the name **pw-record** or **pw-midirecord** this is
the default.
\par -m | \--midi
MIDI mode. *FILE* is a MIDI file. If the tool is called under the name
@ -73,14 +69,6 @@ simply provide the MIDI events in the graph. You need a separate MIDI
renderer such as qsynth, timidity or a hardware renderer to hear the
MIDI.
\par -c | \--midi-clip
MIDI 2.0 clip mode. *FILE* is a MIDI 2.0 clip file. If the tool is called
under the name **pw-midi2play** or **pw-midi2record** this is the default.
Note that this program will *not* render the MIDI events into audible
samples, it will simply provide the MIDI events in the graph. You need a
separate MIDI renderer such as qsynth, timidity or a hardware renderer to
hear the MIDI.
\par -d | \--dsd
DSD mode. *FILE* is a DSF file. If the tool is called under the name
**pw-dsdplay** this is the default. Note that this program will *not*

View file

@ -33,10 +33,6 @@ for many commands.
\par quit | q
Exit from **pw-cli**
\par list-vars
List all currently known variables and their type. Some commands create
objects that are identified with a variable.
# MODULE MANAGEMENT
Modules are loaded and unloaded in the local instance, thus the pw-cli
@ -52,12 +48,12 @@ For most modules it is OK to be loaded more than once.
This command returns a module variable that can be used to unload the
module.
The local module is *not* visible in the remote instance. It is not
The locally module is *not* visible in the remote instance. It is not
possible in PipeWire to load modules in a remote instance.
\endparblock
\par unload-module *module-var*
Unload a module, specified by its variable.
Unload a module, specified either by its variable.
# OBJECT INTROSPECTION

View file

@ -4,7 +4,7 @@ The PipeWire Link Command
# SYNOPSIS
**pw-link** \[*options*\] -o|-i|-l|-t \[*out-pattern*\] \[*in-pattern*\]
**pw-link** \[*options*\] -o-l \[*out-pattern*\] \[*in-pattern*\]
**pw-link** \[*options*\] *output* *input*
@ -42,9 +42,6 @@ List input ports
\par -l | \--links
List links
\par -t | \--latency
List port latencies
\par -m | \--monitor
Monitor links and ports. **pw-link** will not exit but monitor and print
new and destroyed ports or links.

View file

@ -14,7 +14,7 @@ node and device statistics.
A hierarchical view is shown of Driver nodes and follower nodes. The
Driver nodes are actively using a timer to schedule dataflow in the
followers. The followers of a driver node as shown below their driver
with a + sign (or = for async nodes) in a tree-like representation.
with a + sign in a tree-like representation.
The columns presented are as follows:
@ -173,20 +173,10 @@ For Video formats, the layout is \<pixelformat\>
\parblock
Name assigned to the device/node, as found in *pw-dump* node.name
Names are prefixed by *+*/*=* when they are linked to a driver (entry
above with no +/=)
Names are prefixed by *+* when they are linked to a driver (entry
above with no +)
\endparblock
# COMMANDS
The following keys can be used in the interactive mode:
\par q
Quit
\par c
Clear the ERR counters. This does *not* clear the counters globally,
it will only reset the counters in this instance of *pw-top*.
# OPTIONS

View file

@ -9,12 +9,12 @@ PipeWire API step-by-step with simple short examples.
- \subpage page_tutorial4
- \subpage page_tutorial5
- \subpage page_tutorial6
- \subpage page_tutorial7
# More Example Programs
- \ref audio-src.c "": \snippet{doc} audio-src.c title
- \ref audio-dsp-filter.c "": \snippet{doc} audio-dsp-filter.c title
- \ref video-play.c "": \snippet{doc} video-play.c title
- \subpage page_examples

View file

@ -1,6 +1,6 @@
/** \page page_tutorial6 Tutorial - Part 6: Binding Objects
\ref page_tutorial5 | \ref page_tutorial "Index" | \ref page_tutorial7
\ref page_tutorial5 | \ref page_tutorial "Index"
In this tutorial we show how to bind to an object so that we can
receive events and call methods on the object.
@ -64,6 +64,6 @@ you created. Otherwise, they will be leaked:
}
\endcode
\ref page_tutorial5 | \ref page_tutorial "Index" | \ref page_tutorial7
\ref page_tutorial5 | \ref page_tutorial "Index"
*/

View file

@ -1,242 +0,0 @@
/** \page page_tutorial7 Tutorial - Part 7: Creating an Audio DSP Filter
\ref page_tutorial6 | \ref page_tutorial "Index"
In this tutorial we show how to use \ref pw_filter "pw_filter" to create
a real-time audio processing filter. This is useful for implementing audio
effects, equalizers, analyzers, and other DSP applications.
Let's take a look at the code before we break it down:
\snippet tutorial7.c code
Save as tutorial7.c and compile with:
gcc -Wall tutorial7.c -o tutorial7 -lm $(pkg-config --cflags --libs libpipewire-0.3)
## Overview
Unlike \ref pw_stream "pw_stream" which is designed for applications that
produce or consume audio data, \ref pw_filter "pw_filter" is designed for
applications that process existing audio streams. Filters have both input
and output ports and operate in the DSP domain using 32-bit floating point
samples.
## Setting up the Filter
We start with the usual boilerplate and define our data structure:
\code{.c}
struct data {
struct pw_main_loop *loop;
struct pw_filter *filter;
struct port *in_port;
struct port *out_port;
};
\endcode
The filter object manages both input and output ports. Each port represents
an audio channel that can be connected to other applications.
## Creating the Filter
\code{.c}
data.filter = pw_filter_new_simple(
pw_main_loop_get_loop(data.loop),
"audio-filter",
pw_properties_new(
PW_KEY_MEDIA_TYPE, "Audio",
PW_KEY_MEDIA_CATEGORY, "Filter",
PW_KEY_MEDIA_ROLE, "DSP",
NULL),
&filter_events,
&data);
\endcode
We use `pw_filter_new_simple()` which automatically manages the core connection
for us. The properties are important:
- `PW_KEY_MEDIA_TYPE`: "Audio" indicates this is an audio filter
- `PW_KEY_MEDIA_CATEGORY`: "Filter" tells the session manager this processes audio
- `PW_KEY_MEDIA_ROLE`: "DSP" indicates this is for audio processing
## Adding Ports
Next we add input and output ports:
\code{.c}
data.in_port = pw_filter_add_port(data.filter,
PW_DIRECTION_INPUT,
PW_FILTER_PORT_FLAG_MAP_BUFFERS,
sizeof(struct port),
pw_properties_new(
PW_KEY_FORMAT_DSP, "32 bit float mono audio",
PW_KEY_PORT_NAME, "input",
NULL),
NULL, 0);
data.out_port = pw_filter_add_port(data.filter,
PW_DIRECTION_OUTPUT,
PW_FILTER_PORT_FLAG_MAP_BUFFERS,
sizeof(struct port),
pw_properties_new(
PW_KEY_FORMAT_DSP, "32 bit float mono audio",
PW_KEY_PORT_NAME, "output",
NULL),
NULL, 0);
\endcode
Key points about filter ports:
- `PW_DIRECTION_INPUT` and `PW_DIRECTION_OUTPUT` specify the port direction
- `PW_FILTER_PORT_FLAG_MAP_BUFFERS` allows direct memory access to buffers
- `PW_KEY_FORMAT_DSP` indicates this uses 32-bit float DSP format
- DSP ports work with normalized floating-point samples (typically -1.0 to 1.0)
## Setting Process Latency
\code{.c}
params[n_params++] = spa_process_latency_build(&b,
SPA_PARAM_ProcessLatency,
&SPA_PROCESS_LATENCY_INFO_INIT(
.ns = 10 * SPA_NSEC_PER_MSEC
));
\endcode
This tells PipeWire that our filter adds 10 milliseconds of processing latency.
This information helps the audio system maintain proper timing and latency
compensation throughout the audio graph.
## Connecting the Filter
\code{.c}
if (pw_filter_connect(data.filter,
PW_FILTER_FLAG_RT_PROCESS,
params, n_params) < 0) {
fprintf(stderr, "can't connect\n");
return -1;
}
\endcode
The `PW_FILTER_FLAG_RT_PROCESS` flag ensures our process callback runs in the
real-time audio thread. This is crucial for low-latency audio processing but
means our process function must be real-time safe (no allocations, file I/O,
or blocking operations).
## The Process Callback
The heart of the filter is the process callback:
\snippet tutorial7.c on_process
The process function is called for each audio buffer and works as follows:
1. Get the number of samples to process from `position->clock.duration`
2. Get input and output buffer pointers using `pw_filter_get_dsp_buffer()`
3. Process the audio data (here we just copy input to output)
4. The framework handles queueing the processed buffers
### Key Points about DSP Processing:
- **Float Format**: DSP buffers use 32-bit float samples, typically normalized to [-1.0, 1.0]
- **Real-time Safe**: The process function runs in the audio thread and must be real-time safe
- **Buffer Management**: `pw_filter_get_dsp_buffer()` handles the buffer lifecycle automatically
- **Sample-accurate**: Processing happens at the audio sample rate with precise timing
## Advanced Usage
This example shows a simple passthrough, but you can implement any audio processing:
\code{.c}
/* Example: Simple volume control */
for (uint32_t i = 0; i < n_samples; i++) {
out[i] = in[i] * 0.5f; // Reduce volume by half
}
/* Example: Simple high-pass filter */
static float last_sample = 0.0f;
float alpha = 0.99f;
for (uint32_t i = 0; i < n_samples; i++) {
out[i] = alpha * (out[i] + in[i] - last_sample);
last_sample = in[i];
}
\endcode
## Comparison with pw_stream
| Feature | pw_stream | pw_filter |
|---------|-----------|-----------|
| **Use case** | Audio playback/recording | Audio processing/effects |
| **Data format** | Various (S16, S32, etc.) | 32-bit float DSP |
| **Ports** | Single direction | Input and output |
| **Buffer management** | Manual queue/dequeue | Automatic via get_dsp_buffer |
| **Typical apps** | Media players, recorders | Equalizers, effects, analyzers |
## Connecting and Linking the Filter
### Manual Linking Options
Filters require manual connection by design. You can connect them using:
#### Using pw-link command line:
\code{.sh}
# List output ports (sources)
pw-link -o
# List input ports (sinks)
pw-link -i
# List existing connections
pw-link -l
# Connect a source to filter input
pw-link "source_app:output_FL" "audio-filter:input"
# Connect filter output to sink
pw-link "audio-filter:output" "sink_app:input_FL"
\endcode
### Understanding Filter Auto-Connection Behavior
**Important**: Unlike audio sources and sinks, filters are **not automatically connected** by WirePlumber. This is by design because filters are meant to be explicitly inserted into audio chains where needed.
**Why filters don't auto-connect**:
- Filters process existing audio streams rather than generate/consume them
- Auto-connecting filters could create unwanted audio processing
- Filters typically require specific placement in the audio graph
- Manual connection gives users control over when/where effects are applied
### Testing the Filter
The filter requires manual connection to test. Here's the recommended workflow:
1. **Start an audio source** (e.g., `pw-play music.wav`)
2. **Run your filter** (`./tutorial7`)
3. **Check available ports**:
```sh
# List output ports
pw-link -o | grep -E "(pw-play|audio-filter)"
# List input ports
pw-link -i | grep -E "(audio-filter|playback)"
```
4. **Connect the audio chain manually**:
```sh
# Connect source -> filter -> sink
pw-link "pw-play:output_FL" "audio-filter:input"
pw-link "audio-filter:output" "alsa_output.pci-0000_00_1f.3.analog-stereo:playback_FL"
```
You should hear the audio pass through your filter. Modify the process function
to add effects like volume changes, filtering, or other audio processing.
**Alternative: Use a patchbay tool**
- **Helvum**: `flatpak install flathub org.pipewire.Helvum`
- **qpwgraph**: Available in most Linux distributions
- **Carla**: Full-featured audio plugin host
These tools provide graphical interfaces for connecting PipeWire nodes and are ideal for experimenting with filter placement.
\ref page_tutorial6 | \ref page_tutorial "Index"
*/

File diff suppressed because it is too large Load diff

View file

@ -1,152 +0,0 @@
/*
[title]
\ref page_tutorial7
[title]
*/
/* [code] */
#include <stdio.h>
#include <errno.h>
#include <math.h>
#include <signal.h>
#include <spa/pod/builder.h>
#include <spa/param/latency-utils.h>
#include <pipewire/pipewire.h>
#include <pipewire/filter.h>
struct data;
struct port {
struct data *data;
};
struct data {
struct pw_main_loop *loop;
struct pw_filter *filter;
struct port *in_port;
struct port *out_port;
};
/* [on_process] */
static void on_process(void *userdata, struct spa_io_position *position)
{
struct data *data = userdata;
float *in, *out;
uint32_t n_samples = position->clock.duration;
pw_log_trace("do process %d", n_samples);
in = pw_filter_get_dsp_buffer(data->in_port, n_samples);
out = pw_filter_get_dsp_buffer(data->out_port, n_samples);
if (in == NULL || out == NULL)
return;
/* Simple passthrough - copy input to output.
* Here you could implement any audio processing:
* - Filters (lowpass, highpass, bandpass)
* - Effects (reverb, delay, distortion)
* - Dynamic processing (compressor, limiter)
* - Equalization
* - etc.
*/
memcpy(out, in, n_samples * sizeof(float));
}
/* [on_process] */
static const struct pw_filter_events filter_events = {
PW_VERSION_FILTER_EVENTS,
.process = on_process,
};
static void do_quit(void *userdata, int signal_number)
{
struct data *data = userdata;
pw_main_loop_quit(data->loop);
}
int main(int argc, char *argv[])
{
struct data data = { 0, };
const struct spa_pod *params[1];
uint32_t n_params = 0;
uint8_t buffer[1024];
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
pw_init(&argc, &argv);
/* make a main loop. If you already have another main loop, you can add
* the fd of this pipewire mainloop to it. */
data.loop = pw_main_loop_new(NULL);
pw_loop_add_signal(pw_main_loop_get_loop(data.loop), SIGINT, do_quit, &data);
pw_loop_add_signal(pw_main_loop_get_loop(data.loop), SIGTERM, do_quit, &data);
/* Create a simple filter, the simple filter manages the core and remote
* objects for you if you don't need to deal with them.
*
* Pass your events and a user_data pointer as the last arguments. This
* will inform you about the filter state. The most important event
* you need to listen to is the process event where you need to process
* the data.
*/
data.filter = pw_filter_new_simple(
pw_main_loop_get_loop(data.loop),
"audio-filter",
pw_properties_new(
PW_KEY_MEDIA_TYPE, "Audio",
PW_KEY_MEDIA_CATEGORY, "Filter",
PW_KEY_MEDIA_ROLE, "DSP",
NULL),
&filter_events,
&data);
/* make an audio DSP input port */
data.in_port = pw_filter_add_port(data.filter,
PW_DIRECTION_INPUT,
PW_FILTER_PORT_FLAG_MAP_BUFFERS,
sizeof(struct port),
pw_properties_new(
PW_KEY_FORMAT_DSP, "32 bit float mono audio",
PW_KEY_PORT_NAME, "input",
NULL),
NULL, 0);
/* make an audio DSP output port */
data.out_port = pw_filter_add_port(data.filter,
PW_DIRECTION_OUTPUT,
PW_FILTER_PORT_FLAG_MAP_BUFFERS,
sizeof(struct port),
pw_properties_new(
PW_KEY_FORMAT_DSP, "32 bit float mono audio",
PW_KEY_PORT_NAME, "output",
NULL),
NULL, 0);
/* Set processing latency information */
params[n_params++] = spa_process_latency_build(&b,
SPA_PARAM_ProcessLatency,
&SPA_PROCESS_LATENCY_INFO_INIT(
.ns = 10 * SPA_NSEC_PER_MSEC
));
/* Now connect this filter. We ask that our process function is
* called in a realtime thread. */
if (pw_filter_connect(data.filter,
PW_FILTER_FLAG_RT_PROCESS,
params, n_params) < 0) {
fprintf(stderr, "can't connect\n");
return -1;
}
/* and wait while we let things run */
pw_main_loop_run(data.loop);
pw_filter_destroy(data.filter);
pw_main_loop_destroy(data.loop);
pw_deinit();
return 0;
}
/* [code] */

View file

@ -25,7 +25,7 @@ Assumes BUILD_DIR environment variable is set.
containing all index items from the specified section.
# Section title @IDX@ <section> [<alternative index name>]
# Section title @IDX@ <section>
Adds the section title to the index, and expands to an anchor
@ -51,7 +51,7 @@ def index_key(section, name):
BUILD_DIR = os.environ["BUILD_DIR"]
PAR_RE = r"^@PAR@\s+([^\s]*)[ \t]+(\S+)(.*)$"
IDX_RE = r"^(#+)(.*)@IDX@[ \t]+(\S+)([ \t]+\S+)?[ \t]*$"
IDX_RE = r"^(#+)(.*)@IDX@[ \t]+(\S+)[ \t]*$"
SECREF_RE = r"^@SECREF@[ \t]+([^\n]*)[ \t]*$"
@ -71,16 +71,10 @@ def main(args):
level = m.group(1)
title = name = m.group(2).strip()
section = m.group(3)
alt = m.group(4)
if title == title.upper():
name = name.capitalize()
key = index_key(section, name)
text = f"{level} {title} {{#{key}}}"
if alt and alt.strip():
alt_key = index_key(section, alt.strip())
if alt_key != key:
text += f"\n\\anchor {alt_key}"
return text
return f"{level} {title} {{#{key}}}"
def secref(m):
import os
@ -154,12 +148,9 @@ def load_index(sections, text):
def idx(m):
name = m.group(2).strip()
section = m.group(3)
alt = m.group(4)
if name == name.upper():
name = name.capitalize()
sections.setdefault(section, []).append(name)
if alt and alt.strip():
sections.setdefault(section, []).append(alt.strip())
return ""
text = re.sub(PAR_RE, par, text, flags=re.M)

View file

@ -58,8 +58,6 @@ extra_docs = [
'dox/internals/index.dox',
'dox/internals/design.dox',
'dox/internals/access.dox',
'dox/internals/latency.dox',
'dox/internals/tag.dox',
'dox/internals/midi.dox',
'dox/internals/portal.dox',
'dox/internals/daemon.dox',
@ -68,7 +66,6 @@ extra_docs = [
'dox/internals/objects.dox',
'dox/internals/audio.dox',
'dox/internals/scheduling.dox',
'dox/internals/driver.dox',
'dox/internals/protocol.dox',
'dox/internals/pulseaudio.dox',
'dox/internals/dma-buf.dox',
@ -79,7 +76,6 @@ extra_docs = [
'dox/tutorial/tutorial4.dox',
'dox/tutorial/tutorial5.dox',
'dox/tutorial/tutorial6.dox',
'dox/tutorial/tutorial7.dox',
'dox/api/index.dox',
'dox/api/spa-index.dox',
'dox/api/spa-plugins.dox',
@ -174,7 +170,6 @@ example_files = [
'tutorial4.c',
'tutorial5.c',
'tutorial6.c',
'tutorial7.c',
]
example_dep_files = []
foreach h : example_files

View file

@ -43,7 +43,6 @@ This determines the ordering of items in Doxygen sidebar.
\addtogroup pw_protocol
\addtogroup pw_resource
\addtogroup pw_thread_loop
\addtogroup pw_timer_queue
\addtogroup pw_work_queue
\}

View file

@ -1,10 +1,10 @@
project('pipewire', ['c' ],
version : '1.5.81',
version : '1.4.4',
license : [ 'MIT', 'LGPL-2.1-or-later', 'GPL-2.0-only' ],
meson_version : '>= 0.61.1',
default_options : [ 'warning_level=3',
'c_std=gnu11',
'cpp_std=c++20',
'cpp_std=c++17',
'b_pie=true',
#'b_sanitize=address,undefined',
'buildtype=debugoptimized' ])
@ -81,7 +81,6 @@ pkgconfig = import('pkgconfig')
common_flags = [
'-fvisibility=hidden',
'-fno-strict-aliasing',
'-fno-strict-overflow',
'-Werror=suggest-attribute=format',
'-Wsign-compare',
'-Wpointer-arith',
@ -115,11 +114,10 @@ cc_flags = common_flags + [
'-Werror=old-style-definition',
'-Werror=missing-parameter-type',
'-Werror=strict-prototypes',
'-DSPA_AUDIO_MAX_CHANNELS=128u',
]
add_project_arguments(cc.get_supported_arguments(cc_flags), language: 'c')
add_project_arguments(cc_native.get_supported_arguments(cc_flags),
language: 'c', native: true)
cc_flags_native = cc_native.get_supported_arguments(cc_flags)
have_cpp = add_languages('cpp', native: false, required : false)
@ -279,9 +277,11 @@ endforeach
cdata.set('HAVE_PIDFD_OPEN',
cc.get_define('SYS_pidfd_open', prefix: '#include <sys/syscall.h>') != '')
systemd_dep = dependency('libsystemd', required: get_option('libsystemd'))
systemd = dependency('systemd', required: get_option('systemd'))
systemd_dep = dependency('libsystemd',required: get_option('systemd'))
summary({'systemd conf data': systemd.found()}, bool_yn: true)
summary({'libsystemd': systemd_dep.found()}, bool_yn: true)
cdata.set('HAVE_SYSTEMD', systemd_dep.found())
cdata.set('HAVE_SYSTEMD', systemd.found() and systemd_dep.found())
logind_dep = dependency(get_option('logind-provider'), required: get_option('logind'))
summary({'logind': logind_dep.found()}, bool_yn: true)
@ -321,7 +321,7 @@ cdata.set('HAVE_DBUS', dbus_dep.found())
sdl_dep = dependency('sdl2', required : get_option('sdl2'))
summary({'SDL2 (video examples)': sdl_dep.found()}, bool_yn: true, section: 'Misc dependencies')
drm_dep = dependency('libdrm', required : false)
fftw_dep = dependency('fftw3f', required : get_option('fftw'))
fftw_dep = dependency('fftw3f', required : false)
summary({'fftw3f (filter-chain convolver)': fftw_dep.found()}, bool_yn: true, section: 'Misc dependencies')
cdata.set('HAVE_FFTW', fftw_dep.found())
@ -340,23 +340,12 @@ endif
pw_cat_ffmpeg = get_option('pw-cat-ffmpeg')
ffmpeg = get_option('ffmpeg')
if pw_cat_ffmpeg.allowed() or ffmpeg.allowed()
# libswscale is only used by videoconvert. FFmpeg might however be used for
# compressed audio (both for decoding said compressed audio and for parsing
# it in pw-cat). If users only care about audio, then libswscale would still
# become a requirement if its required flag is defined only by FFmpeg options.
# Make the videoconvert option a factor in swscale_dep as well to avoid this.
videoconvert = get_option('videoconvert')
avcodec_dep = dependency('libavcodec', required: pw_cat_ffmpeg.enabled() or ffmpeg.enabled())
avformat_dep = dependency('libavformat', required: pw_cat_ffmpeg.enabled())
avfilter_dep = dependency('libavfilter', required: ffmpeg.enabled())
avutil_dep = dependency('libavutil', required: pw_cat_ffmpeg.enabled() or ffmpeg.enabled())
swscale_dep = dependency('libswscale', required: (pw_cat_ffmpeg.enabled() or ffmpeg.enabled()) and videoconvert.enabled())
swscale_dep = dependency('libswscale', required: pw_cat_ffmpeg.enabled() or ffmpeg.enabled())
else
avcodec_dep = dependency('', required: false)
avformat_dep = dependency('', required: false)
avfilter_dep = dependency('', required: false)
avutil_dep = dependency('', required: false)
swscale_dep = dependency('', required: false)
endif
cdata.set('HAVE_PW_CAT_FFMPEG_INTEGRATION', pw_cat_ffmpeg.allowed())
@ -391,6 +380,9 @@ libusb_dep = dependency('libusb-1.0', required : get_option('libusb'))
summary({'libusb (Bluetooth quirks)': libusb_dep.found()}, bool_yn: true, section: 'Backend')
cdata.set('HAVE_LIBUSB', libusb_dep.found())
cap_lib = dependency('libcap', required : false)
cdata.set('HAVE_LIBCAP', cap_lib.found())
glib2_dep = dependency('glib-2.0', required : get_option('flatpak'))
summary({'GLib-2.0 (Flatpak support)': glib2_dep.found()}, bool_yn: true, section: 'Misc dependencies')
flatpak_support = glib2_dep.found()
@ -418,7 +410,6 @@ gst_deps_def = {
gst_dep = []
gst_dma_drm_found = false
gst_shm_allocator_found = false
foreach depname, kwargs: gst_deps_def
dep = dependency(depname, required: gst_option, kwargs: kwargs)
summary({depname: dep.found()}, bool_yn: true, section: 'GStreamer modules')
@ -434,13 +425,9 @@ foreach depname, kwargs: gst_deps_def
if depname == 'gstreamer-allocators-1.0' and dep.version().version_compare('>= 1.23.1')
gst_dma_drm_found = true
gst_shm_allocator_found = true
endif
endforeach
summary({'gstreamer SHM allocator': gst_shm_allocator_found}, bool_yn: true, section: 'Backend')
cdata.set('HAVE_GSTREAMER_SHM_ALLOCATOR', gst_shm_allocator_found)
# This code relies on the array being empty if any dependency was not found
gst_dp_found = gst_dep.length() > 0
summary({'gstreamer-device-provider': gst_dp_found}, bool_yn: true, section: 'Backend')
@ -634,8 +621,6 @@ devenv.prepend('GST_PLUGIN_PATH', builddir / 'src'/ 'gst')
devenv.prepend('ALSA_PLUGIN_DIR', builddir / 'pipewire-alsa' / 'alsa-plugins')
devenv.prepend('LD_LIBRARY_PATH', builddir / 'pipewire-jack' / 'src')
devenv.set('PIPEWIRE_LOG_SYSTEMD', 'false')
devenv.set('PW_UNINSTALLED', '1')
devenv.set('PW_BUILDDIR', meson.project_build_root())
meson.add_devenv(devenv)

View file

@ -30,8 +30,8 @@ option('gstreamer-device-provider',
description: 'Build GStreamer device provider plugin',
type: 'feature',
value: 'auto')
option('libsystemd',
description: 'Enable code that depends on libsystemd',
option('systemd',
description: 'Enable systemd integration',
type: 'feature',
value: 'auto')
option('logind',
@ -48,9 +48,9 @@ option('systemd-system-service',
type: 'feature',
value: 'disabled')
option('systemd-user-service',
description: 'Install systemd user service file',
description: 'Install systemd user service file (ignored without systemd)',
type: 'feature',
value: 'auto')
value: 'enabled')
option('selinux',
description: 'Enable SELinux integration',
type: 'feature',
@ -129,10 +129,6 @@ option('bluez5-codec-ldac',
description: 'Enable LDAC Sony open source codec implementation',
type: 'feature',
value: 'auto')
option('bluez5-codec-ldac-dec',
description: 'Enable LDAC Sony open source codec decoding',
type: 'feature',
value: 'auto')
option('bluez5-codec-aac',
description: 'Enable Fraunhofer FDK AAC open source codec implementation',
type: 'feature',
@ -153,10 +149,6 @@ option('bluez5-codec-g722',
description: 'Enable G722 open source codec implementation',
type: 'feature',
value: 'auto')
option('bluez5-plc-spandsp',
description: 'Enable SpanDSP for packet loss concealment',
type: 'feature',
value: 'auto')
option('control',
description: 'Enable control spa plugin integration',
type: 'feature',
@ -387,11 +379,3 @@ option('ebur128',
description: 'Enable code that depends on ebur128',
type: 'feature',
value: 'auto')
option('fftw',
description: 'Enable code that depends on fftw',
type: 'feature',
value: 'auto')
option('onnxruntime',
description: 'Enable code that depends on onnxruntime',
type: 'feature',
value: 'auto')

View file

@ -22,11 +22,9 @@ PW_LOG_TOPIC_STATIC(alsa_log_topic, "alsa.ctl");
#define VOLUME_MIN ((uint32_t) 0U)
#define VOLUME_MAX ((uint32_t) 0x10000U)
#define MAX_CHANNELS SPA_AUDIO_MAX_CHANNELS
struct volume {
uint32_t channels;
long values[MAX_CHANNELS];
long values[SPA_AUDIO_MAX_CHANNELS];
};
typedef struct {
@ -500,7 +498,7 @@ static struct spa_pod *build_volume_mute(struct spa_pod_builder *b, struct volum
spa_pod_builder_push_object(b, &f[0],
SPA_TYPE_OBJECT_Props, SPA_PARAM_Props);
if (volume) {
float volumes[MAX_CHANNELS];
float volumes[SPA_AUDIO_MAX_CHANNELS];
uint32_t i, n_volumes = 0;
n_volumes = volume->channels;
@ -852,11 +850,11 @@ static void parse_props(struct global *g, const struct spa_pod *param, bool devi
break;
case SPA_PROP_channelVolumes:
{
float volumes[MAX_CHANNELS];
float volumes[SPA_AUDIO_MAX_CHANNELS];
uint32_t n_volumes, i;
n_volumes = spa_pod_copy_array(&prop->value, SPA_TYPE_Float,
volumes, SPA_N_ELEMENTS(volumes));
volumes, SPA_AUDIO_MAX_CHANNELS);
g->node.channel_volume.channels = n_volumes;
for (i = 0; i < n_volumes; i++)

View file

@ -30,8 +30,8 @@ PW_LOG_TOPIC_STATIC(alsa_log_topic, "alsa.pcm");
#define MIN_BUFFERS 2u
#define MAX_BUFFERS 64u
#define MAX_CHANNELS 64
#define MAX_RATE (48000*8)
#define MAX_CHANNELS SPA_AUDIO_MAX_CHANNELS
#define MIN_PERIOD 64
@ -617,7 +617,6 @@ static int snd_pcm_pipewire_stop(snd_pcm_ioplug_t *io)
if (pw->activated && pw->stream != NULL) {
pw_stream_set_active(pw->stream, false);
pw->activated = false;
pw_thread_loop_signal(pw->main_loop, false);
}
pw_thread_loop_unlock(pw->main_loop);
return 0;
@ -643,7 +642,7 @@ static int snd_pcm_pipewire_pause(snd_pcm_ioplug_t * io, int enable)
#define _FORMAT_BE(p, fmt) p ? SPA_AUDIO_FORMAT_UNKNOWN : SPA_AUDIO_FORMAT_ ## fmt ## _OE
#endif
static int set_default_channels(uint32_t channels, uint32_t position[MAX_CHANNELS])
static int set_default_channels(uint32_t channels, uint32_t position[SPA_AUDIO_MAX_CHANNELS])
{
switch (channels) {
case 8:
@ -916,16 +915,12 @@ static int snd_pcm_pipewire_set_chmap(snd_pcm_ioplug_t * io,
default:
return -EINVAL;
}
if (map->channels > MAX_CHANNELS)
return -ENOTSUP;
for (i = 0; i < map->channels; i++) {
char buf[8];
position[i] = chmap_to_channel(map->pos[i]);
pw_log_debug("map %d: %s / %s", i,
snd_pcm_chmap_name(map->pos[i]),
spa_type_audio_channel_make_short_name(position[i],
buf, sizeof(buf), "UNK"));
spa_debug_type_find_short_name(spa_type_audio_channel,
position[i]));
}
return 1;
}

View file

@ -102,7 +102,6 @@ struct notify {
#define NOTIFY_TYPE_SHUTDOWN ((7<<4)|NOTIFY_ACTIVE_FLAG)
#define NOTIFY_TYPE_LATENCY ((8<<4)|NOTIFY_ACTIVE_FLAG)
#define NOTIFY_TYPE_TOTAL_LATENCY ((9<<4)|NOTIFY_ACTIVE_FLAG)
#define NOTIFY_TYPE_PORT_RENAME ((10<<4)|NOTIFY_ACTIVE_FLAG)
int type;
struct object *object;
int arg1;
@ -172,7 +171,6 @@ struct object {
} port_link;
struct {
unsigned long flags;
char old_name[REAL_JACK_PORT_NAME_SIZE+1];
char name[REAL_JACK_PORT_NAME_SIZE+1];
char alias1[REAL_JACK_PORT_NAME_SIZE+1];
char alias2[REAL_JACK_PORT_NAME_SIZE+1];
@ -233,13 +231,6 @@ struct buffer {
uint32_t n_mem;
};
struct mix_info {
struct spa_pod_parser parser;
struct spa_pod_frame frame;
struct spa_pod_control control;
const void *control_body;
};
struct mix {
struct spa_list link;
struct spa_list port_link;
@ -254,8 +245,6 @@ struct mix {
struct buffer buffers[MAX_BUFFERS];
uint32_t n_buffers;
struct mix_info mix_info;
unsigned int to_free:1;
};
@ -637,8 +626,8 @@ do_mix_set_io(struct spa_loop *loop, bool async, uint32_t seq,
static inline void mix_set_io(struct mix *mix, void *data, size_t size)
{
struct io_info info = { .mix = mix, .data = data, .size = size };
pw_loop_locked(mix->port->client->loop->loop,
do_mix_set_io, SPA_ID_INVALID, &info, sizeof(info), NULL);
pw_data_loop_invoke(mix->port->client->loop,
do_mix_set_io, SPA_ID_INVALID, &info, sizeof(info), false, NULL);
}
static void init_mix(struct mix *mix, uint32_t mix_id, struct port *port, uint32_t peer_id)
@ -1094,16 +1083,6 @@ static void on_notify_event(void *data, uint64_t count)
notify->arg1,
c->portregistration_arg);
break;
case NOTIFY_TYPE_PORT_RENAME:
if (o->registered != notify->arg1)
break;
pw_log_debug("%p: port rename %u %s->%s", c, o->serial,
o->port.old_name, o->port.name);
do_callback(c, rename_callback, c->active,
o->serial,
o->port.old_name, o->port.name,
c->rename_arg);
break;
case NOTIFY_TYPE_CONNECT:
if (o->registered == notify->arg1)
break;
@ -1204,9 +1183,6 @@ static int queue_notify(struct client *c, int type, struct object *o, int arg1,
emit = c->portregistration_callback != NULL && o != NULL;
o->visible = arg1;
break;
case NOTIFY_TYPE_PORT_RENAME:
emit = c->rename_callback != NULL && o != NULL;
break;
case NOTIFY_TYPE_CONNECT:
emit = c->connect_callback != NULL && o != NULL;
break;
@ -1501,8 +1477,7 @@ static inline int event_compare(uint8_t s1, uint8_t s2)
return priotab[(s2>>4) & 7] - priotab[(s1>>4) & 7];
}
static inline int event_sort(struct spa_pod_control *a, const void *abody,
struct spa_pod_control *b, const void *bbody)
static inline int event_sort(struct spa_pod_control *a, struct spa_pod_control *b)
{
if (a->offset < b->offset)
return -1;
@ -1513,18 +1488,18 @@ static inline int event_sort(struct spa_pod_control *a, const void *abody,
switch(a->type) {
case SPA_CONTROL_Midi:
{
const uint8_t *sa = abody, *sb = bbody;
uint8_t *sa = SPA_POD_BODY(&a->value), *sb = SPA_POD_BODY(&b->value);
if (SPA_POD_BODY_SIZE(&a->value) < 1 || SPA_POD_BODY_SIZE(&b->value) < 1)
return 0;
return event_compare(sa[0], sb[0]);
}
case SPA_CONTROL_UMP:
{
const uint32_t *sa = abody, *sb = bbody;
uint32_t *sa = SPA_POD_BODY(&a->value), *sb = SPA_POD_BODY(&b->value);
if (SPA_POD_BODY_SIZE(&a->value) < 4 || SPA_POD_BODY_SIZE(&b->value) < 4)
return 0;
if (((sa[0] >> 28) != 2 && (sa[0] >> 28) != 4) ||
((sb[0] >> 28) != 2 && (sb[0] >> 28) != 4))
if ((sa[0] >> 28) != 2 || (sa[0] >> 28) != 4 ||
(sb[0] >> 28) != 2 || (sb[0] >> 28) != 4)
return 0;
return event_compare(sa[0] >> 16, sb[0] >> 16);
}
@ -1608,54 +1583,56 @@ static inline int midi_event_write(void *port_buffer,
return 0;
}
static void convert_to_event(struct mix_info **mix, uint32_t n_mix, void *midi, bool fix, uint32_t type)
static void convert_to_event(struct spa_pod_sequence **seq, uint32_t n_seq, void *midi, bool fix, uint32_t type)
{
struct spa_pod_control *c[n_seq];
uint64_t state = 0;
uint32_t i;
int res = 0;
bool in_sysex = false;
while (true) {
struct mix_info *next = NULL;
uint32_t next_index = 0;
struct spa_pod_control *control;
size_t size;
uint8_t *data;
uint64_t state = 0;
for (i = 0; i < n_seq; i++)
c[i] = spa_pod_control_first(&seq[i]->body);
for (i = 0; i < n_mix; i++) {
struct mix_info *m = mix[i];
if (next == NULL || event_sort(&m->control, m->control_body,
&next->control, next->control_body) <= 0) {
next = m;
while (true) {
struct spa_pod_control *next = NULL;
uint32_t next_index = 0;
for (i = 0; i < n_seq; i++) {
if (!spa_pod_control_is_inside(&seq[i]->body,
SPA_POD_BODY_SIZE(seq[i]), c[i]))
continue;
if (next == NULL || event_sort(c[i], next) <= 0) {
next = c[i];
next_index = i;
}
}
if (SPA_UNLIKELY(next == NULL))
break;
control = &next->control;
data = (uint8_t*)next->control_body;
size = SPA_POD_BODY_SIZE(&control->value);
switch(control->type) {
switch(next->type) {
case SPA_CONTROL_OSC:
if (!TYPE_ID_CAN_OSC(type))
break;
SPA_FALLTHROUGH;
case SPA_CONTROL_Midi:
{
uint8_t *data = SPA_POD_BODY(&next->value);
size_t size = SPA_POD_BODY_SIZE(&next->value);
if (type == TYPE_ID_UMP) {
while (size > 0) {
uint32_t ump[4];
int ump_size = spa_ump_from_midi(&data, &size, ump, sizeof(ump), 0, &state);
if (ump_size <= 0)
break;
if ((res = midi_event_write(midi, control->offset,
if ((res = midi_event_write(midi, next->offset,
(uint8_t*)ump, ump_size, false)) < 0)
break;
}
} else {
res = midi_event_write(midi, control->offset, data, size, fix);
res = midi_event_write(midi, next->offset, data, size, fix);
}
if (res < 0)
pw_log_warn("midi %p: can't write event: %s", midi,
@ -1664,43 +1641,38 @@ static void convert_to_event(struct mix_info **mix, uint32_t n_mix, void *midi,
}
case SPA_CONTROL_UMP:
{
if (type == TYPE_ID_MIDI) {
void *data = SPA_POD_BODY(&next->value);
size_t size = SPA_POD_BODY_SIZE(&next->value);
uint8_t ev[32];
const uint32_t *d = (uint32_t*)data;
while (size > 0) {
bool was_sysex = in_sysex;
int ev_size = spa_ump_to_midi(&d, &size, ev, sizeof(ev), &state);
if (type == TYPE_ID_MIDI) {
int ev_size = spa_ump_to_midi(data, size, ev, sizeof(ev));
if (ev_size <= 0)
break;
size = ev_size;
data = ev;
if (!in_sysex && ev[0] == 0xf0)
in_sysex = true;
if (in_sysex && ev[ev_size-1] == 0xf7)
in_sysex = false;
if (was_sysex)
res = midi_event_append(midi, ev, ev_size);
else
res = midi_event_write(midi, control->offset, ev, ev_size, fix);
if (res < 0)
} else if (type != TYPE_ID_UMP)
break;
}
} else if (type == TYPE_ID_UMP) {
res = midi_event_write(midi, control->offset, data, size, fix);
}
if (was_sysex)
res = midi_event_append(midi, data, size);
else
res = midi_event_write(midi, next->offset, data, size, fix);
if (res < 0)
pw_log_warn("midi %p: can't write event: %s", midi,
spa_strerror(res));
break;
}
}
if (spa_pod_parser_get_control_body(&next->parser,
&next->control, &next->control_body) < 0) {
spa_pod_parser_pop(&next->parser, &next->frame);
mix[next_index] = mix[--n_mix];
}
c[next_index] = spa_pod_control_next(c[next_index]);
}
}
@ -2524,16 +2496,16 @@ static int client_node_command(void *data, const struct spa_command *command)
case SPA_NODE_COMMAND_Suspend:
case SPA_NODE_COMMAND_Pause:
if (c->started) {
pw_loop_locked(c->loop->loop,
do_unprepare_client, SPA_ID_INVALID, NULL, 0, c);
pw_data_loop_invoke(c->loop,
do_unprepare_client, SPA_ID_INVALID, NULL, 0, false, c);
c->started = false;
}
break;
case SPA_NODE_COMMAND_Start:
if (!c->started) {
pw_loop_locked(c->loop->loop,
do_prepare_client, SPA_ID_INVALID, NULL, 0, c);
pw_data_loop_invoke(c->loop,
do_prepare_client, SPA_ID_INVALID, NULL, 0, false, c);
c->started = true;
}
break;
@ -2577,11 +2549,28 @@ static int param_enum_format(struct client *c, struct port *p,
case TYPE_ID_UMP:
case TYPE_ID_OSC:
case TYPE_ID_MIDI:
*param = spa_pod_builder_add_object(b,
SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
{
struct spa_pod_frame f;
int32_t types = 0;
spa_pod_builder_push_object(b, &f,
SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat);
spa_pod_builder_add(b,
SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_application),
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_control));
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_control),
0);
if (p->object->port.type_id == TYPE_ID_UMP)
types |= 1u<<SPA_CONTROL_UMP;
if (p->object->port.type_id == TYPE_ID_OSC)
types |= 1u<<SPA_CONTROL_OSC;
if (types != 0)
spa_pod_builder_add(b,
SPA_FORMAT_CONTROL_types, SPA_POD_CHOICE_FLAGS_Int(types),
0);
*param = spa_pod_builder_pop(b, &f);
break;
}
case TYPE_ID_VIDEO:
*param = spa_pod_builder_add_object(b,
SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
@ -3307,8 +3296,8 @@ static int client_node_set_activation(void *data,
link->trigger = link->activation->server_version < 1 ? trigger_link_v0 : trigger_link_v1;
spa_list_append(&c->links, &link->link);
pw_loop_locked(c->loop->loop,
do_add_link, SPA_ID_INVALID, NULL, 0, link);
pw_data_loop_invoke(c->loop,
do_add_link, SPA_ID_INVALID, NULL, 0, false, link);
}
else {
link = find_activation(&c->links, node_id);
@ -3318,8 +3307,8 @@ static int client_node_set_activation(void *data,
}
spa_list_remove(&link->link);
pw_loop_locked(c->loop->loop,
do_remove_link, SPA_ID_INVALID, NULL, 0, link);
pw_data_loop_invoke(c->loop,
do_remove_link, SPA_ID_INVALID, NULL, 0, false, link);
queue_free_link(c, link);
}
@ -3685,67 +3674,6 @@ static const struct pw_node_events node_events = {
.info = node_info,
};
#define FILTER_NAME " ()[].:*$"
#define FILTER_PORT " ()[].*$"
static void filter_name(char *str, const char *filter, char filter_char)
{
char *p;
for (p = str; *p; p++) {
if (strchr(filter, *p) != NULL)
*p = filter_char;
}
}
static int update_port_name(struct object *o, const char *name)
{
struct object *ot = o->port.node, *op;
struct client *c = o->client;
char tmp[REAL_JACK_PORT_NAME_SIZE+1];
char port_name[REAL_JACK_PORT_NAME_SIZE+1];
if (o->port.is_monitor && !c->merge_monitor)
snprintf(tmp, sizeof(tmp), "%.*s%s:%s",
(int)(JACK_CLIENT_NAME_SIZE-(sizeof(MONITOR_EXT)-1)),
ot->node.name, MONITOR_EXT, name);
else
snprintf(tmp, sizeof(tmp), "%s:%s", ot->node.name, name);
if (c->filter_name)
filter_name(tmp, FILTER_PORT, c->filter_char);
op = find_port_by_name(c, tmp);
if (op != NULL && op != o)
snprintf(port_name, sizeof(port_name), "%.*s-%u",
(int)(sizeof(tmp)-11), tmp, o->serial);
else
snprintf(port_name, sizeof(port_name), "%s", tmp);
if (spa_streq(port_name, o->port.name))
return 0;
strcpy(o->port.old_name, o->port.name);
strcpy(o->port.name, port_name);
return 1;
}
static void port_info(void *data, const struct pw_port_info *info)
{
struct object *o = data;
struct client *c = o->client;
if (info->change_mask & PW_PORT_CHANGE_MASK_PROPS) {
const char *str = spa_dict_lookup(info->props, PW_KEY_PORT_NAME);
if (str != NULL) {
if (update_port_name(o, str) > 0) {
pw_log_info("%p: port rename %u %s->%s", c, o->serial,
o->port.old_name, o->port.name);
queue_notify(c, NOTIFY_TYPE_PORT_RENAME, o, 1, NULL);
}
}
}
}
static void port_param(void *data, int seq,
uint32_t id, uint32_t index, uint32_t next,
const struct spa_pod *param)
@ -3768,16 +3696,27 @@ static void port_param(void *data, int seq,
static const struct pw_port_events port_events = {
PW_VERSION_PORT_EVENTS,
.info = port_info,
.param = port_param,
};
#define FILTER_NAME " ()[].:*$"
#define FILTER_PORT " ()[].*$"
static void filter_name(char *str, const char *filter, char filter_char)
{
char *p;
for (p = str; *p; p++) {
if (strchr(filter, *p) != NULL)
*p = filter_char;
}
}
static void registry_event_global(void *data, uint32_t id,
uint32_t permissions, const char *type, uint32_t version,
const struct spa_dict *props)
{
struct client *c = (struct client *) data;
struct object *o, *ot;
struct object *o, *ot, *op;
const char *str;
bool do_emit = true, do_sync = false;
uint32_t serial;
@ -3843,8 +3782,6 @@ static void registry_event_global(void *data, uint32_t id,
}
if (str == NULL)
str = node_name;
if (str == NULL)
str = spa_dict_lookup(props, PW_KEY_OBJECT_PATH);
if (str == NULL)
str = "node";
@ -3900,7 +3837,6 @@ static void registry_event_global(void *data, uint32_t id,
uint32_t node_id;
bool is_monitor = false;
char tmp[REAL_JACK_PORT_NAME_SIZE+1];
const char *name;
if ((str = spa_dict_lookup(props, PW_KEY_FORMAT_DSP)) == NULL)
str = "other";
@ -3916,7 +3852,7 @@ static void registry_event_global(void *data, uint32_t id,
spa_strstartswith(str, "jack:flags:"))
flags = atoi(str+11);
if ((name = spa_dict_lookup(props, PW_KEY_PORT_NAME)) == NULL)
if ((str = spa_dict_lookup(props, PW_KEY_PORT_NAME)) == NULL)
goto exit;
if (type_id == TYPE_ID_UMP && c->flag_midi2)
@ -3952,7 +3888,7 @@ static void registry_event_global(void *data, uint32_t id,
o = NULL;
if (node_id == c->node_id) {
snprintf(tmp, sizeof(tmp), "%s:%s", c->name, name);
snprintf(tmp, sizeof(tmp), "%s:%s", c->name, str);
o = find_port_by_name(c, tmp);
if (o != NULL)
pw_log_info("%p: %s found our port %p", c, tmp, o);
@ -3970,7 +3906,6 @@ static void registry_event_global(void *data, uint32_t id,
o->port.node = ot;
o->port.latency[SPA_DIRECTION_INPUT] = SPA_LATENCY_INFO(SPA_DIRECTION_INPUT);
o->port.latency[SPA_DIRECTION_OUTPUT] = SPA_LATENCY_INFO(SPA_DIRECTION_OUTPUT);
o->port.type_id = type_id;
do_emit = node_is_active(c, ot);
@ -3992,11 +3927,26 @@ static void registry_event_global(void *data, uint32_t id,
pthread_mutex_lock(&c->context.lock);
spa_list_append(&c->context.objects, &o->link);
pthread_mutex_unlock(&c->context.lock);
}
o->port.flags = flags;
o->port.node_id = node_id;
o->port.is_monitor = is_monitor;
if (is_monitor && !c->merge_monitor)
snprintf(tmp, sizeof(tmp), "%.*s%s:%s",
(int)(JACK_CLIENT_NAME_SIZE-(sizeof(MONITOR_EXT)-1)),
ot->node.name, MONITOR_EXT, str);
else
snprintf(tmp, sizeof(tmp), "%s:%s", ot->node.name, str);
if (c->filter_name)
filter_name(tmp, FILTER_PORT, c->filter_char);
op = find_port_by_name(c, tmp);
if (op != NULL)
snprintf(o->port.name, sizeof(o->port.name), "%.*s-%u",
(int)(sizeof(tmp)-11), tmp, serial);
else
snprintf(o->port.name, sizeof(o->port.name), "%s", tmp);
o->port.type_id = type_id;
}
if (c->fill_aliases) {
if ((str = spa_dict_lookup(props, PW_KEY_OBJECT_PATH)) != NULL)
@ -4005,6 +3955,7 @@ static void registry_event_global(void *data, uint32_t id,
if ((str = spa_dict_lookup(props, PW_KEY_PORT_ALIAS)) != NULL)
snprintf(o->port.alias2, sizeof(o->port.alias2), "%s", str);
}
if ((str = spa_dict_lookup(props, PW_KEY_PORT_ID)) != NULL) {
o->port.system_id = atoi(str);
snprintf(o->port.system, sizeof(o->port.system), "system:%s_%d",
@ -4013,8 +3964,9 @@ static void registry_event_global(void *data, uint32_t id,
o->port.system_id+1);
}
if (node_id != c->node_id)
update_port_name(o, name);
o->port.flags = flags;
o->port.node_id = node_id;
o->port.is_monitor = is_monitor;
pw_log_debug("%p: %p add port %d name:%s %d", c, o, id,
o->port.name, type_id);
@ -5803,15 +5755,13 @@ static void *get_buffer_input_midi(struct port *p, jack_nframes_t frames)
struct mix *mix;
void *ptr = p->emptyptr;
struct midi_buffer *mb = (struct midi_buffer*)midi_scratch;
struct mix_info *mix_info[MAX_MIX];
uint32_t n_mix_info = 0;
struct spa_pod_sequence *seq[MAX_MIX];
uint32_t n_seq = 0;
spa_list_for_each(mix, &p->mix, port_link) {
struct spa_data *d;
struct buffer *b;
struct mix_info *mi = &mix->mix_info;
struct spa_pod_sequence seq;
const void *seq_body;
void *pod;
if (mix->id == SPA_ID_INVALID)
continue;
@ -5823,24 +5773,21 @@ static void *get_buffer_input_midi(struct port *p, jack_nframes_t frames)
continue;
d = &b->datas[0];
spa_pod_parser_init_from_data(&mi->parser, d->data, d->maxsize,
d->chunk->offset, d->chunk->size);
if (spa_pod_parser_push_sequence_body(&mi->parser,
&mi->frame, &seq, &seq_body) < 0)
if ((pod = spa_pod_from_data(d->data, d->maxsize, d->chunk->offset, d->chunk->size)) == NULL)
continue;
if (spa_pod_parser_get_control_body(&mi->parser,
&mi->control, &mi->control_body) < 0)
if (!spa_pod_is_sequence(pod))
continue;
mix_info[n_mix_info++] = mi;
if (n_mix_info == MAX_MIX)
seq[n_seq++] = pod;
if (n_seq == MAX_MIX)
break;
}
midi_init_buffer(mb, MIDI_SCRATCH_FRAMES, frames);
/* first convert to a thread local scratch buffer, then memcpy into
* the per port buffer. This makes it possible to call this function concurrently
* but also have different pointers per port */
convert_to_event(mix_info, n_mix_info, mb, p->client->fix_midi_events, p->object->port.type_id);
convert_to_event(seq, n_seq, mb, p->client->fix_midi_events, p->object->port.type_id);
memcpy(ptr, mb, sizeof(struct midi_buffer) + (mb->event_count
* sizeof(struct midi_event)));
if (mb->write_pos > 0) {
@ -5907,26 +5854,21 @@ void * jack_port_get_buffer (jack_port_t *port, jack_nframes_t frames)
goto done;
if (TYPE_ID_IS_EVENT(o->port.type_id)) {
struct mix_info *mix_info[1], mi;
struct spa_pod_sequence *seq[1];
struct spa_data *d;
struct spa_pod_sequence seq;
const void *seq_body;
void *pod;
ptr = midi_scratch;
midi_init_buffer(ptr, MIDI_SCRATCH_FRAMES, frames);
d = &b->datas[0];
spa_pod_parser_init_from_data(&mi.parser, d->data, d->maxsize,
d->chunk->offset, d->chunk->size);
if (spa_pod_parser_push_sequence_body(&mi.parser,
&mi.frame, &seq, &seq_body) < 0)
if ((pod = spa_pod_from_data(d->data, d->maxsize,
d->chunk->offset, d->chunk->size)) == NULL)
goto done;
if (spa_pod_parser_get_control_body(&mi.parser,
&mi.control, &mi.control_body) < 0)
if (!spa_pod_is_sequence(pod))
goto done;
mix_info[0] = &mi;
convert_to_event(mix_info, 1, ptr, c->fix_midi_events, o->port.type_id);
seq[0] = pod;
convert_to_event(seq, 1, ptr, c->fix_midi_events, o->port.type_id);
} else {
ptr = get_buffer_data(b, frames);
}

View file

@ -772,19 +772,6 @@ static int v4l2_dup(int oldfd)
return do_dup(oldfd, FD_MAP_DUP);
}
/* Deferred PipeWire init (called on first device access) */
static void pipewire_init_func(void)
{
pw_init(NULL, NULL);
PW_LOG_TOPIC_INIT(v4l2_log_topic);
}
static void ensure_pipewire_init(void)
{
static pthread_once_t pipewire_once = PTHREAD_ONCE_INIT;
pthread_once(&pipewire_once, pipewire_init_func);
}
static int v4l2_openat(int dirfd, const char *path, int oflag, mode_t mode)
{
int res, flags;
@ -808,8 +795,6 @@ static int v4l2_openat(int dirfd, const char *path, int oflag, mode_t mode)
if (passthrough)
return globals.old_fops.openat(dirfd, path, oflag, mode);
ensure_pipewire_init();
pw_log_info("path:%s oflag:%d mode:%d", path, oflag, mode);
if ((file = find_file_by_dev(dev_id)) != NULL) {
@ -1400,6 +1385,7 @@ static int vidioc_enum_framesizes(struct file *file, struct v4l2_frmsizeenum *ar
spa_list_for_each(p, &g->param_list, link) {
const struct format_info *fi;
uint32_t media_type, media_subtype, format;
struct spa_rectangle size;
if (p->id != SPA_PARAM_EnumFormat || p->param == NULL)
continue;
@ -1423,96 +1409,22 @@ static int vidioc_enum_framesizes(struct file *file, struct v4l2_frmsizeenum *ar
if (fi->fourcc != arg->pixel_format)
continue;
const struct spa_pod_prop *size_prop = spa_pod_find_prop(p->param, NULL, SPA_FORMAT_VIDEO_size);
if (!size_prop)
if (spa_pod_parse_object(p->param,
SPA_TYPE_OBJECT_Format, NULL,
SPA_FORMAT_VIDEO_size, SPA_POD_Rectangle(&size)) < 0)
continue;
uint32_t n_sizes, choice;
const struct spa_pod *size_pods = spa_pod_get_values(&size_prop->value, &n_sizes, &choice);
if (!size_pods || n_sizes <= 0)
continue;
const struct spa_rectangle *sizes = SPA_POD_BODY_CONST(size_pods);
if (size_pods->type != SPA_TYPE_Rectangle || size_pods->size != sizeof(*sizes))
continue;
switch (choice) {
case SPA_CHOICE_Enum:
n_sizes -= 1;
sizes += 1;
SPA_FALLTHROUGH;
case SPA_CHOICE_None:
arg->type = V4L2_FRMSIZE_TYPE_DISCRETE;
arg->discrete.width = size.width;
arg->discrete.height = size.height;
for (size_t i = 0; i < n_sizes; i++, count++) {
arg->discrete.width = sizes[i].width;
arg->discrete.height = sizes[i].height;
pw_log_debug("count:%u %.4s %ux%u", count, (char*)&fi->fourcc,
arg->discrete.width, arg->discrete.height);
pw_log_debug("count:%d %.4s %dx%d", count, (char*)&fi->fourcc,
size.width, size.height);
if (count == arg->index) {
found = true;
break;
}
}
break;
case SPA_CHOICE_Range:
if (n_sizes < 3)
continue;
arg->type = V4L2_FRMSIZE_TYPE_CONTINUOUS;
arg->stepwise.min_width = sizes[1].width;
arg->stepwise.min_height = sizes[1].height;
arg->stepwise.max_width = sizes[2].width;
arg->stepwise.max_height = sizes[2].height;
arg->stepwise.step_width = arg->stepwise.step_height = 1;
pw_log_debug("count:%u %.4s (%ux%u)-(%ux%u)", count, (char*)&fi->fourcc,
arg->stepwise.min_width, arg->stepwise.min_height,
arg->stepwise.max_width, arg->stepwise.max_height);
if (count == arg->index) {
found = true;
break;
}
count++;
break;
case SPA_CHOICE_Step:
if (n_sizes < 4)
continue;
arg->type = V4L2_FRMSIZE_TYPE_CONTINUOUS;
arg->stepwise.min_width = sizes[1].width;
arg->stepwise.min_height = sizes[1].height;
arg->stepwise.max_width = sizes[2].width;
arg->stepwise.max_height = sizes[2].height;
arg->stepwise.step_width = sizes[3].width;
arg->stepwise.step_height = sizes[3].height;
pw_log_debug("count:%u %.4s (%ux%u)-(%ux%u)/(+%u,%u)", count, (char*)&fi->fourcc,
arg->stepwise.min_width, arg->stepwise.min_height,
arg->stepwise.min_width, arg->stepwise.min_height,
arg->stepwise.step_width, arg->stepwise.step_height);
if (count == arg->index) {
found = true;
break;
}
count++;
break;
default:
continue;
}
if (found)
break;
}
pw_thread_loop_unlock(file->loop);
@ -2188,7 +2100,7 @@ static struct {
{ V4L2_CID_SATURATION, SPA_PROP_saturation },
{ V4L2_CID_HUE, SPA_PROP_hue },
{ V4L2_CID_GAMMA, SPA_PROP_gamma },
{ V4L2_CID_EXPOSURE_ABSOLUTE, SPA_PROP_exposure },
{ V4L2_CID_EXPOSURE, SPA_PROP_exposure },
{ V4L2_CID_GAIN, SPA_PROP_gain },
{ V4L2_CID_SHARPNESS, SPA_PROP_sharpness },
};
@ -2399,8 +2311,6 @@ static int vidioc_s_ctrl(struct file *file, struct v4l2_control *arg)
struct spa_pod_frame f[1];
struct spa_pod *param;
pod = spa_pod_get_values(type, &n_vals, &choice);
if (n_vals < 1)
break;
spa_pod_builder_push_object(&b, &f[0],
SPA_TYPE_OBJECT_Props, SPA_PARAM_Props);
@ -2653,14 +2563,10 @@ static void initialize(void)
globals.old_fops.ioctl = dlsym(RTLD_NEXT, "ioctl");
globals.old_fops.mmap = dlsym(RTLD_NEXT, "mmap64");
globals.old_fops.munmap = dlsym(RTLD_NEXT, "munmap");
/* NOTE:
* We avoid calling pw_init() here (constructor/early init path) because
* that can deadlock in certain host processes (e.g. Zoom >= 5.0) when
* the preload causes PipeWire initialisation to run too early.
*
* PipeWire initialisation (pw_init + PW_LOG_TOPIC_INIT) is deferred
* to ensure it runs on-demand in the first actual V4L2 open call.
*/
pw_init(NULL, NULL);
PW_LOG_TOPIC_INIT(v4l2_log_topic);
pthread_mutex_init(&globals.lock, NULL);
pw_array_init(&globals.file_maps, 1024);
pw_array_init(&globals.fd_maps, 256);

View file

@ -1,5 +1,4 @@
af
ar
as
be
bg

797
po/ar.po
View file

@ -1,797 +0,0 @@
# Arabic translation of PipeWire
# This file is distributed under the same license as the pipewire package.
#
# SPDX-FileCopyrightText: 2025 r <r>
msgid ""
msgstr ""
"Project-Id-Version: pipewire\n"
"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/issues/"
"new\n"
"POT-Creation-Date: 2024-02-25 03:43+0300\n"
"PO-Revision-Date: 2025-06-22 13:09+0200\n"
"Last-Translator: r <r>\n"
"Language-Team: Arabic <kde-i18n-doc@kde.org>\n"
"Language: ar\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && "
"n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
"X-Generator: Lokalize 25.04.0\n"
#: src/daemon/pipewire.c:26
#, c-format
msgid ""
"%s [options]\n"
" -h, --help Show this help\n"
" --version Show version\n"
" -c, --config Load config (Default %s)\n"
msgstr ""
"%s [خيارات]\n"
" -h, --help إظهار هذه المساعدة\n"
" --version إظهار الإصدار\n"
" -c, --config تحميل التضبيط (الافتراضي %s)\n"
#: src/daemon/pipewire.desktop.in:4
msgid "PipeWire Media System"
msgstr "نظام الوسائط بايب‌واير"
#: src/daemon/pipewire.desktop.in:5
msgid "Start the PipeWire Media System"
msgstr "ابدأ نظام الوسائط بايب‌واير"
#: src/modules/module-protocol-pulse/modules/module-tunnel-sink.c:159
#: src/modules/module-protocol-pulse/modules/module-tunnel-source.c:159
#, c-format
msgid "Tunnel to %s%s%s"
msgstr "نفّق إلى %s%s%s"
#: src/modules/module-fallback-sink.c:40
msgid "Dummy Output"
msgstr "إخراج وهمي"
#: src/modules/module-pulse-tunnel.c:774
#, c-format
msgid "Tunnel for %s@%s"
msgstr "نفّق ل %s@%s"
#: src/modules/module-zeroconf-discover.c:315
msgid "Unknown device"
msgstr "جهاز غير معروف"
#: src/modules/module-zeroconf-discover.c:327
#, c-format
msgid "%s on %s@%s"
msgstr "%s على %s@%s"
#: src/modules/module-zeroconf-discover.c:331
#, c-format
msgid "%s on %s"
msgstr "%s على %s"
#: src/tools/pw-cat.c:991
#, c-format
msgid ""
"%s [options] [<file>|-]\n"
" -h, --help Show this help\n"
" --version Show version\n"
" -v, --verbose Enable verbose operations\n"
"\n"
msgstr ""
"%s [خيارات] [<file>|-]\n"
" -h, --help إظهار هذه المساعدة\n"
" --version إظهار الإصدار\n"
" -v, --verbose تمكين العمليات المطولة\n"
"\n"
#: src/tools/pw-cat.c:998
#, c-format
msgid ""
" -R, --remote Remote daemon name\n"
" --media-type Set media type (default %s)\n"
" --media-category Set media category (default %s)\n"
" --media-role Set media role (default %s)\n"
" --target Set node target serial or name "
"(default %s)\n"
" 0 means don't link\n"
" --latency Set node latency (default %s)\n"
" Xunit (unit = s, ms, us, ns)\n"
" or direct samples (256)\n"
" the rate is the one of the source "
"file\n"
" -P --properties Set node properties\n"
"\n"
msgstr ""
"-R, --remote اسم العملية الخفية البعيدة\n"
" --media-type تعيين نوع الوسائط (الافتراضي %s)\n"
" --media-category تعيين فئة الوسائط (الافتراضي %s)\n"
" --media-role تعيين دور الوسائط (الافتراضي %s)\n"
" --target تعيين المسلسل أو اسم هدف العُقدة "
"\n (الافتراضي %s)"
" 0 يعني عدم الربط\n"
" --latency تعيين زمن انتقال العُقدة (الافتراضي %s"
")\n"
" وحدة X (الوحدة = s, ms, us, ns)\n"
" أو عينات مباشرة (256)\n"
" المعدل هو معدل ملف المصدر\n"
" -P --properties تعيين خصائص العُقدة\n"
"\n"
#: src/tools/pw-cat.c:1016
#, c-format
msgid ""
" --rate Sample rate (req. for rec) (default "
"%u)\n"
" --channels Number of channels (req. for rec) "
"(default %u)\n"
" --channel-map Channel map\n"
" one of: \"stereo\", "
"\"surround-51\",... or\n"
" comma separated list of channel "
"names: eg. \"FL,FR\"\n"
" --format Sample format %s (req. for rec) "
"(default %s)\n"
" --volume Stream volume 0-1.0 (default %.3f)\n"
" -q --quality Resampler quality (0 - 15) (default "
"%d)\n"
"\n"
msgstr ""
"--rate معدل العينة (مطلوب للتسجيل) (الافتراضي %u)\n"
" --channels عدد القنوات (مطلوب للتسجيل) (الافتراضي"
" %u)\n"
" --channel-map خريطة القنوات\n"
" أحد الخيارات: \"مِجساميّ\", \"محيط"
"ي-51\",... أو\n"
" قائمة بأسماء القنوات مفصولة بفاصلة"
": مثال \"FL,FR\"\n"
" --format تنسيق العينة %s (مطلوب للتسجيل) (الافت"
"راضي %s)\n"
" --volume حجم البث 0-1.0 (الافتراضي %.3f)\n"
" -q --quality جودة إعادة التشكيل (0 - 15) (الافتراضي"
" %d)\n"
"\n"
#: src/tools/pw-cat.c:1033
msgid ""
" -p, --playback Playback mode\n"
" -r, --record Recording mode\n"
" -m, --midi Midi mode\n"
" -d, --dsd DSD mode\n"
" -o, --encoded Encoded mode\n"
"\n"
msgstr ""
"-p, --playback وضع التشغيل\n"
" -r, --record وضع التسجيل\n"
" -m, --midi وضع Midi\n"
" -d, --dsd وضع DSD\n"
" -o, --encoded الوضع المرمّز\n"
"\n"
#: src/tools/pw-cli.c:2252
#, c-format
msgid ""
"%s [options] [command]\n"
" -h, --help Show this help\n"
" --version Show version\n"
" -d, --daemon Start as daemon (Default false)\n"
" -r, --remote Remote daemon name\n"
" -m, --monitor Monitor activity\n"
"\n"
msgstr ""
"%s [خيارات] [أمر]\n"
" -h, --help إظهار هذه المساعدة\n"
" --version إظهار الإصدار\n"
" -d, --daemon بدء كخفي (افتراضي خطأ)\n"
" -r, --remote اسم الخفي البعيد\n"
" -m, --monitor مراقبة النشاط\n"
"\n"
#: spa/plugins/alsa/acp/acp.c:327
msgid "Pro Audio"
msgstr "صوت احترافي"
#: spa/plugins/alsa/acp/acp.c:488 spa/plugins/alsa/acp/alsa-mixer.c:4633
#: spa/plugins/bluez5/bluez5-device.c:1701
msgid "Off"
msgstr "معطل"
#: spa/plugins/alsa/acp/alsa-mixer.c:2652
msgid "Input"
msgstr "الإدخال"
#: spa/plugins/alsa/acp/alsa-mixer.c:2653
msgid "Docking Station Input"
msgstr "إدخال محطة الإرساء"
#: spa/plugins/alsa/acp/alsa-mixer.c:2654
msgid "Docking Station Microphone"
msgstr "ميكروفون محطة الإرساء"
#: spa/plugins/alsa/acp/alsa-mixer.c:2655
msgid "Docking Station Line In"
msgstr "مدخل خطي محط الارساء"
#: spa/plugins/alsa/acp/alsa-mixer.c:2656
#: spa/plugins/alsa/acp/alsa-mixer.c:2747
msgid "Line In"
msgstr "مدخل خطي"
#: spa/plugins/alsa/acp/alsa-mixer.c:2657
#: spa/plugins/alsa/acp/alsa-mixer.c:2741
#: spa/plugins/bluez5/bluez5-device.c:1989
msgid "Microphone"
msgstr "ميكروفون"
#: spa/plugins/alsa/acp/alsa-mixer.c:2658
#: spa/plugins/alsa/acp/alsa-mixer.c:2742
msgid "Front Microphone"
msgstr "ميكروفون أمامي"
#: spa/plugins/alsa/acp/alsa-mixer.c:2659
#: spa/plugins/alsa/acp/alsa-mixer.c:2743
msgid "Rear Microphone"
msgstr "ميكروفون خلفي"
#: spa/plugins/alsa/acp/alsa-mixer.c:2660
msgid "External Microphone"
msgstr "ميكروفون خارجي"
#: spa/plugins/alsa/acp/alsa-mixer.c:2661
#: spa/plugins/alsa/acp/alsa-mixer.c:2745
msgid "Internal Microphone"
msgstr "ميكروفون داخلي"
#: spa/plugins/alsa/acp/alsa-mixer.c:2662
#: spa/plugins/alsa/acp/alsa-mixer.c:2748
msgid "Radio"
msgstr "راديو"
#: spa/plugins/alsa/acp/alsa-mixer.c:2663
#: spa/plugins/alsa/acp/alsa-mixer.c:2749
msgid "Video"
msgstr "مرئيّ"
#: spa/plugins/alsa/acp/alsa-mixer.c:2664
msgid "Automatic Gain Control"
msgstr "التحكم التلقائي في الكسب"
#: spa/plugins/alsa/acp/alsa-mixer.c:2665
msgid "No Automatic Gain Control"
msgstr "دون التحكم التلقائي في الكسب"
#: spa/plugins/alsa/acp/alsa-mixer.c:2666
msgid "Boost"
msgstr "تعزيز"
#: spa/plugins/alsa/acp/alsa-mixer.c:2667
msgid "No Boost"
msgstr "دون تعزيز"
#: spa/plugins/alsa/acp/alsa-mixer.c:2668
msgid "Amplifier"
msgstr ""
""
"مُضَخِّم"
#: spa/plugins/alsa/acp/alsa-mixer.c:2669
msgid "No Amplifier"
msgstr "دون مُضَخِّم"
#: spa/plugins/alsa/acp/alsa-mixer.c:2670
msgid "Bass Boost"
msgstr "تعزيز القرار"
#: spa/plugins/alsa/acp/alsa-mixer.c:2671
msgid "No Bass Boost"
msgstr "دون تعزيز القرار"
#: spa/plugins/alsa/acp/alsa-mixer.c:2672
#: spa/plugins/bluez5/bluez5-device.c:1995
msgid "Speaker"
msgstr "مكبر صوت"
#: spa/plugins/alsa/acp/alsa-mixer.c:2673
#: spa/plugins/alsa/acp/alsa-mixer.c:2751
msgid "Headphones"
msgstr "سماعات الأذن"
#: spa/plugins/alsa/acp/alsa-mixer.c:2740
msgid "Analog Input"
msgstr "إدخال التناظري"
#: spa/plugins/alsa/acp/alsa-mixer.c:2744
msgid "Dock Microphone"
msgstr "ميكروفون محطة الارساء"
#: spa/plugins/alsa/acp/alsa-mixer.c:2746
msgid "Headset Microphone"
msgstr "ميكروفون سماعة الرأس"
#: spa/plugins/alsa/acp/alsa-mixer.c:2750
msgid "Analog Output"
msgstr "إخراج تناظري"
#: spa/plugins/alsa/acp/alsa-mixer.c:2752
msgid "Headphones 2"
msgstr "سماعات الأذن 2"
#: spa/plugins/alsa/acp/alsa-mixer.c:2753
msgid "Headphones Mono Output"
msgstr "سماعات الأذن أحادية الإخراج"
#: spa/plugins/alsa/acp/alsa-mixer.c:2754
msgid "Line Out"
msgstr "مخرج خطي"
#: spa/plugins/alsa/acp/alsa-mixer.c:2755
msgid "Analog Mono Output"
msgstr "إخراج أحادي تناظري"
#: spa/plugins/alsa/acp/alsa-mixer.c:2756
msgid "Speakers"
msgstr "مكبرات الصوت"
#: spa/plugins/alsa/acp/alsa-mixer.c:2757
msgid "HDMI / DisplayPort"
msgstr "HDMI / ديسبلاي بورت"
#: spa/plugins/alsa/acp/alsa-mixer.c:2758
msgid "Digital Output (S/PDIF)"
msgstr "إخراج الرقمي (S/PDIF)"
#: spa/plugins/alsa/acp/alsa-mixer.c:2759
msgid "Digital Input (S/PDIF)"
msgstr "إدخال الرقمي (S/PDIF)"
#: spa/plugins/alsa/acp/alsa-mixer.c:2760
msgid "Multichannel Input"
msgstr "إدخال متعدد القنوات"
#: spa/plugins/alsa/acp/alsa-mixer.c:2761
msgid "Multichannel Output"
msgstr "إخراج متعدد القنوات"
#: spa/plugins/alsa/acp/alsa-mixer.c:2762
msgid "Game Output"
msgstr "إخراج اللعبة"
#: spa/plugins/alsa/acp/alsa-mixer.c:2763
#: spa/plugins/alsa/acp/alsa-mixer.c:2764
msgid "Chat Output"
msgstr "إخراج المحادثة"
#: spa/plugins/alsa/acp/alsa-mixer.c:2765
msgid "Chat Input"
msgstr "إدخال المحادثة"
#: spa/plugins/alsa/acp/alsa-mixer.c:2766
msgid "Virtual Surround 7.1"
msgstr "محيطي تخيلي 7.1"
#: spa/plugins/alsa/acp/alsa-mixer.c:4456
msgid "Analog Mono"
msgstr "تناظري أحادي"
#: spa/plugins/alsa/acp/alsa-mixer.c:4457
msgid "Analog Mono (Left)"
msgstr "تناظري أحادي (يسار)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4458
msgid "Analog Mono (Right)"
msgstr "تناظري أحادي (يمين)"
#. Note: Not translated to "Analog Stereo Input", because the source
#. * name gets "Input" appended to it automatically, so adding "Input"
#. * here would lead to the source name to become "Analog Stereo Input
#. * Input". The same logic applies to analog-stereo-output,
#. * multichannel-input and multichannel-output.
#: spa/plugins/alsa/acp/alsa-mixer.c:4459
#: spa/plugins/alsa/acp/alsa-mixer.c:4467
#: spa/plugins/alsa/acp/alsa-mixer.c:4468
msgid "Analog Stereo"
msgstr "مِجْساميّ تناظري"
#: spa/plugins/alsa/acp/alsa-mixer.c:4460
msgid "Mono"
msgstr "أحادي"
#: spa/plugins/alsa/acp/alsa-mixer.c:4461
msgid "Stereo"
msgstr "مِجْساميّ"
#: spa/plugins/alsa/acp/alsa-mixer.c:4469
#: spa/plugins/alsa/acp/alsa-mixer.c:4627
#: spa/plugins/bluez5/bluez5-device.c:1977
msgid "Headset"
msgstr "سماعة الرأس"
#: spa/plugins/alsa/acp/alsa-mixer.c:4470
#: spa/plugins/alsa/acp/alsa-mixer.c:4628
msgid "Speakerphone"
msgstr "مكبر صوت الجوّال"
#: spa/plugins/alsa/acp/alsa-mixer.c:4471
#: spa/plugins/alsa/acp/alsa-mixer.c:4472
msgid "Multichannel"
msgstr "متعدد القنوات"
#: spa/plugins/alsa/acp/alsa-mixer.c:4473
msgid "Analog Surround 2.1"
msgstr "تناظري محيطي 2.1"
#: spa/plugins/alsa/acp/alsa-mixer.c:4474
msgid "Analog Surround 3.0"
msgstr "تناظري محيطي 3.0"
#: spa/plugins/alsa/acp/alsa-mixer.c:4475
msgid "Analog Surround 3.1"
msgstr "تناظري محيطي 3.1"
#: spa/plugins/alsa/acp/alsa-mixer.c:4476
msgid "Analog Surround 4.0"
msgstr "تناظري محيطي 4.0"
#: spa/plugins/alsa/acp/alsa-mixer.c:4477
msgid "Analog Surround 4.1"
msgstr "تناظري محيطي 4.1"
#: spa/plugins/alsa/acp/alsa-mixer.c:4478
msgid "Analog Surround 5.0"
msgstr "تناظري محيطي 5.0"
#: spa/plugins/alsa/acp/alsa-mixer.c:4479
msgid "Analog Surround 5.1"
msgstr "تناظري محيطي 5.1"
#: spa/plugins/alsa/acp/alsa-mixer.c:4480
msgid "Analog Surround 6.0"
msgstr "تناظري محيطي 6.0"
#: spa/plugins/alsa/acp/alsa-mixer.c:4481
msgid "Analog Surround 6.1"
msgstr "تناظري محيطي 6.1"
#: spa/plugins/alsa/acp/alsa-mixer.c:4482
msgid "Analog Surround 7.0"
msgstr "تناظري محيطي 7.0"
#: spa/plugins/alsa/acp/alsa-mixer.c:4483
msgid "Analog Surround 7.1"
msgstr "تناظري محيطي 7.1"
#: spa/plugins/alsa/acp/alsa-mixer.c:4484
msgid "Digital Stereo (IEC958)"
msgstr "مِجْساميّ رقمي (IEC958)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4485
msgid "Digital Surround 4.0 (IEC958/AC3)"
msgstr "محيطي رقمي 4.0 (IEC958/AC3)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4486
msgid "Digital Surround 5.1 (IEC958/AC3)"
msgstr "محيطي رقمي 5.1 (IEC958/AC3)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4487
msgid "Digital Surround 5.1 (IEC958/DTS)"
msgstr "محيطي رقمي 5.1 (IEC958/DTS)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4488
msgid "Digital Stereo (HDMI)"
msgstr "مِجْساميّ رقمي (HDMI)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4489
msgid "Digital Surround 5.1 (HDMI)"
msgstr "محيطي رقمي 5.1 (HDMI)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4490
msgid "Chat"
msgstr "محادثة"
#: spa/plugins/alsa/acp/alsa-mixer.c:4491
msgid "Game"
msgstr "لعبة"
#: spa/plugins/alsa/acp/alsa-mixer.c:4625
msgid "Analog Mono Duplex"
msgstr "تناظري أحادي مزدوج"
#: spa/plugins/alsa/acp/alsa-mixer.c:4626
msgid "Analog Stereo Duplex"
msgstr "مِجْساميّ تناظري مزدوج"
#: spa/plugins/alsa/acp/alsa-mixer.c:4629
msgid "Digital Stereo Duplex (IEC958)"
msgstr "مِجْساميّ رقمي مزدوج (IEC958)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4630
msgid "Multichannel Duplex"
msgstr "مزدوج متعدد القنوات"
#: spa/plugins/alsa/acp/alsa-mixer.c:4631
msgid "Stereo Duplex"
msgstr "مِجساميّ مزدوج"
#: spa/plugins/alsa/acp/alsa-mixer.c:4632
msgid "Mono Chat + 7.1 Surround"
msgstr "محادثة أحادية + محيطي 7.1"
#: spa/plugins/alsa/acp/alsa-mixer.c:4733
#, c-format
msgid "%s Output"
msgstr "إخراج %s"
#: spa/plugins/alsa/acp/alsa-mixer.c:4741
#, c-format
msgid "%s Input"
msgstr "إدخال %s"
#: spa/plugins/alsa/acp/alsa-util.c:1220 spa/plugins/alsa/acp/alsa-util.c:1314
#, c-format
msgid ""
"snd_pcm_avail() returned a value that is exceptionally large: %lu byte (%lu "
"ms).\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
"to the ALSA developers."
msgid_plural ""
"snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu "
"ms).\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
"to the ALSA developers."
msgstr[0] ""
"أرجعت الدالة snd_pcm_avail() قيمة كبيرة بشكل استثنائي: %lu بايت "
"(%lu مللي ثانية).\n"
"من المرجح أن يكون هذا خطأ في برنامج تشغيل ALSA '%s'. يُرجى الإبلاغ عن هذه المش"
"كلة "
"لمطوري ALSA."
msgstr[1] ""
"أرجعت الدالة snd_pcm_avail() قيمة كبيرة بشكل استثنائي: %lu بايتات "
"(%lu مللي ثانية).\n"
"من المرجح أن يكون هذا خطأ في برنامج تشغيل ALSA '%s'. يُرجى الإبلاغ عن هذه المش"
"كلة "
"لمطوري ALSA."
msgstr[2] ""
"أرجعت الدالة snd_pcm_avail() قيمة كبيرة بشكل استثنائي: %lu بايتات "
"(%lu مللي ثانية).\n"
"من المرجح أن يكون هذا خطأ في برنامج تشغيل ALSA '%s'. يُرجى الإبلاغ عن هذه المش"
"كلة "
"لمطوري ALSA."
msgstr[3] ""
"أرجعت الدالة snd_pcm_avail() قيمة كبيرة بشكل استثنائي: %lu بايتات "
"(%lu مللي ثانية).\n"
"من المرجح أن يكون هذا خطأ في برنامج تشغيل ALSA '%s'. يُرجى الإبلاغ عن هذه المش"
"كلة "
"لمطوري ALSA."
msgstr[4] ""
"أرجعت الدالة snd_pcm_avail() قيمة كبيرة بشكل استثنائي: %lu بايتات "
"(%lu مللي ثانية).\n"
"من المرجح أن يكون هذا خطأ في برنامج تشغيل ALSA '%s'. يُرجى الإبلاغ عن هذه المش"
"كلة "
"لمطوري ALSA."
msgstr[5] ""
"أرجعت الدالة snd_pcm_avail() قيمة كبيرة بشكل استثنائي: %lu بايتات "
"(%lu مللي ثانية).\n"
"من المرجح أن يكون هذا خطأ في برنامج تشغيل ALSA '%s'. يُرجى الإبلاغ عن هذه المش"
"كلة "
"لمطوري ALSA."
#: spa/plugins/alsa/acp/alsa-util.c:1286
#, c-format
msgid ""
"snd_pcm_delay() returned a value that is exceptionally large: %li byte "
"(%s%lu ms).\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
"to the ALSA developers."
msgid_plural ""
"snd_pcm_delay() returned a value that is exceptionally large: %li bytes "
"(%s%lu ms).\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
"to the ALSA developers."
msgstr[0] ""
"أرجعت الدالة snd_pcm_delay() قيمة كبيرة بشكل استثنائي: %li بايت "
"(%s%lu مللي ثانية).\n"
"من المرجح أن يكون هذا خطأ في برنامج تشغيل ALSA '%s'. يُرجى الإبلاغ عن هذه المش"
"كلة "
"لمطوري ALSA."
msgstr[1] ""
"أرجعت الدالة snd_pcm_delay() قيمة كبيرة بشكل استثنائي: %li بايتات "
"(%s%lu مللي ثانية).\n"
"من المرجح أن يكون هذا خطأ في برنامج تشغيل ALSA '%s'. يُرجى الإبلاغ عن هذه المش"
"كلة "
"لمطوري ALSA."
msgstr[2] ""
"أرجعت الدالة snd_pcm_delay() قيمة كبيرة بشكل استثنائي: %li بايتات "
"(%s%lu مللي ثانية).\n"
"من المرجح أن يكون هذا خطأ في برنامج تشغيل ALSA '%s'. يُرجى الإبلاغ عن هذه المش"
"كلة "
"لمطوري ALSA."
msgstr[3] ""
"أرجعت الدالة snd_pcm_delay() قيمة كبيرة بشكل استثنائي: %li بايتات "
"(%s%lu مللي ثانية).\n"
"من المرجح أن يكون هذا خطأ في برنامج تشغيل ALSA '%s'. يُرجى الإبلاغ عن هذه المش"
"كلة "
"لمطوري ALSA."
msgstr[4] ""
"أرجعت الدالة snd_pcm_delay() قيمة كبيرة بشكل استثنائي: %li بايتات "
"(%s%lu مللي ثانية).\n"
"من المرجح أن يكون هذا خطأ في برنامج تشغيل ALSA '%s'. يُرجى الإبلاغ عن هذه المش"
"كلة "
"لمطوري ALSA."
msgstr[5] ""
"أرجعت الدالة snd_pcm_delay() قيمة كبيرة بشكل استثنائي: %li بايتات "
"(%s%lu مللي ثانية).\n"
"من المرجح أن يكون هذا خطأ في برنامج تشغيل ALSA '%s'. يُرجى الإبلاغ عن هذه المش"
"كلة "
"لمطوري ALSA."
#: spa/plugins/alsa/acp/alsa-util.c:1333
#, c-format
msgid ""
"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
"%lu.\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
"to the ALSA developers."
msgstr ""
"أرجعت الدالة snd_pcm_avail_delay() قيمًا غريبة: التأخير %lu أقل من avail "
"(%lu مللي ثانية).\n"
"من المرجح أن يكون هذا خطأ في برنامج تشغيل ALSA '%s'. يُرجى الإبلاغ عن هذه المش"
"كلة "
"لمطوري ALSA."
#: spa/plugins/alsa/acp/alsa-util.c:1376
#, c-format
msgid ""
"snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu byte "
"(%lu ms).\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
"to the ALSA developers."
msgid_plural ""
"snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes "
"(%lu ms).\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
"to the ALSA developers."
msgstr[0] ""
"أرجعت الدالة snd_pcm_mmap_begin() قيمة كبيرة بشكل استثنائي: %lu بايت "
"(%lu مللي ثانية).\n"
"من المرجح أن يكون هذا خطأ في برنامج تشغيل ALSA '%s'. يُرجى الإبلاغ عن هذه المش"
"كلة "
"لمطوري ALSA."
msgstr[1] ""
"أرجعت الدالة snd_pcm_mmap_begin() قيمة كبيرة بشكل استثنائي: %lu بايتات "
"(%lu مللي ثانية).\n"
"من المرجح أن يكون هذا خطأ في برنامج تشغيل ALSA '%s'. يُرجى الإبلاغ عن هذه المش"
"كلة "
"لمطوري ALSA."
msgstr[2] ""
"أرجعت الدالة snd_pcm_mmap_begin() قيمة كبيرة بشكل استثنائي: %lu بايتات "
"(%lu مللي ثانية).\n"
"من المرجح أن يكون هذا خطأ في برنامج تشغيل ALSA '%s'. يُرجى الإبلاغ عن هذه المش"
"كلة "
"لمطوري ALSA."
msgstr[3] ""
"أرجعت الدالة snd_pcm_mmap_begin() قيمة كبيرة بشكل استثنائي: %lu بايتات "
"(%lu مللي ثانية).\n"
"من المرجح أن يكون هذا خطأ في برنامج تشغيل ALSA '%s'. يُرجى الإبلاغ عن هذه المش"
"كلة "
"لمطوري ALSA."
msgstr[4] ""
"أرجعت الدالة snd_pcm_mmap_begin() قيمة كبيرة بشكل استثنائي: %lu بايتات "
"(%lu مللي ثانية).\n"
"من المرجح أن يكون هذا خطأ في برنامج تشغيل ALSA '%s'. يُرجى الإبلاغ عن هذه المش"
"كلة "
"لمطوري ALSA."
msgstr[5] ""
"أرجعت الدالة snd_pcm_mmap_begin() قيمة كبيرة بشكل استثنائي: %lu بايتات "
"(%lu مللي ثانية).\n"
"من المرجح أن يكون هذا خطأ في برنامج تشغيل ALSA '%s'. يُرجى الإبلاغ عن هذه المش"
"كلة "
"لمطوري ALSA."
#: spa/plugins/alsa/acp/channelmap.h:457
msgid "(invalid)"
msgstr "(غير صالح)"
#: spa/plugins/alsa/acp/compat.c:193
msgid "Built-in Audio"
msgstr "صوت مدمج"
#: spa/plugins/alsa/acp/compat.c:198
msgid "Modem"
msgstr "مودم"
#: spa/plugins/bluez5/bluez5-device.c:1712
msgid "Audio Gateway (A2DP Source & HSP/HFP AG)"
msgstr "بوابة الصوت (مصدر A2DP و HSP/HFP AG)"
#: spa/plugins/bluez5/bluez5-device.c:1760
#, c-format
msgid "High Fidelity Playback (A2DP Sink, codec %s)"
msgstr "تشغيل عالي الدقة (A2DP Sink, codec %s)"
#: spa/plugins/bluez5/bluez5-device.c:1763
#, c-format
msgid "High Fidelity Duplex (A2DP Source/Sink, codec %s)"
msgstr "مزدوج عالي الدقة (مصدر A2DP/Sink, codec %s)"
#: spa/plugins/bluez5/bluez5-device.c:1771
msgid "High Fidelity Playback (A2DP Sink)"
msgstr "تشغيل عالي الدقة (A2DP Sink)"
#: spa/plugins/bluez5/bluez5-device.c:1773
msgid "High Fidelity Duplex (A2DP Source/Sink)"
msgstr "مزدوج عالي الدقة (مصدر A2DP/Sink)"
#: spa/plugins/bluez5/bluez5-device.c:1823
#, c-format
msgid "High Fidelity Playback (BAP Sink, codec %s)"
msgstr "تشغيل عالي الدقة (BAP Sink, codec %s)"
#: spa/plugins/bluez5/bluez5-device.c:1828
#, c-format
msgid "High Fidelity Input (BAP Source, codec %s)"
msgstr "إدخال عالي الدقة (مصدر BAP, codec %s)"
#: spa/plugins/bluez5/bluez5-device.c:1832
#, c-format
msgid "High Fidelity Duplex (BAP Source/Sink, codec %s)"
msgstr "مزدوج عالي الدقة (مصدر BAP/Sink, codec %s)"
#: spa/plugins/bluez5/bluez5-device.c:1841
msgid "High Fidelity Playback (BAP Sink)"
msgstr "تشغيل عالي الدقة (BAP Sink)"
#: spa/plugins/bluez5/bluez5-device.c:1845
msgid "High Fidelity Input (BAP Source)"
msgstr "إدخال عالي الدقة (مصدر BAP)"
#: spa/plugins/bluez5/bluez5-device.c:1848
msgid "High Fidelity Duplex (BAP Source/Sink)"
msgstr "مزدوج عالي الدقة (مصدر BAP/Sink)"
#: spa/plugins/bluez5/bluez5-device.c:1897
#, c-format
msgid "Headset Head Unit (HSP/HFP, codec %s)"
msgstr "وحدة رأس سماعة الرأس (HSP/HFP, codec %s)"
#: spa/plugins/bluez5/bluez5-device.c:1978
#: spa/plugins/bluez5/bluez5-device.c:1983
#: spa/plugins/bluez5/bluez5-device.c:1990
#: spa/plugins/bluez5/bluez5-device.c:1996
#: spa/plugins/bluez5/bluez5-device.c:2002
#: spa/plugins/bluez5/bluez5-device.c:2008
#: spa/plugins/bluez5/bluez5-device.c:2014
#: spa/plugins/bluez5/bluez5-device.c:2020
#: spa/plugins/bluez5/bluez5-device.c:2026
msgid "Handsfree"
msgstr "دون استخدام اليدين"
#: spa/plugins/bluez5/bluez5-device.c:1984
msgid "Handsfree (HFP)"
msgstr "دون استخدام اليدين (HFP)"
#: spa/plugins/bluez5/bluez5-device.c:2001
msgid "Headphone"
msgstr "سماعة الأذن"
#: spa/plugins/bluez5/bluez5-device.c:2007
msgid "Portable"
msgstr "محمول"
#: spa/plugins/bluez5/bluez5-device.c:2013
msgid "Car"
msgstr "سيارة"
#: spa/plugins/bluez5/bluez5-device.c:2019
msgid "HiFi"
msgstr "HiFi"
#: spa/plugins/bluez5/bluez5-device.c:2025
msgid "Phone"
msgstr "جوّال"
#: spa/plugins/bluez5/bluez5-device.c:2032
msgid "Bluetooth"
msgstr "بلوتوث"
#: spa/plugins/bluez5/bluez5-device.c:2033
msgid "Bluetooth (HFP)"
msgstr "بلوتوث (HFP)"

390
po/ca.po
View file

@ -5,7 +5,7 @@
# Xavier Conde Rueda <xavi.conde@gmail.com>, 2008.
# Agustí Grau <fletxa@gmail.com>, 2009.
# Judith Pintó Subirada <judithp@gmail.com>
# Jordi Mas i Herǹandez, <jmas@softcatala.org>, 2022-2025
# Jordi Mas i Herǹandez, <jmas@softcatala.org>, 2022-2023
#
# This file is translated according to the glossary and style guide of
# Softcatalà. If you plan to modify this file, please read first the page
@ -16,7 +16,7 @@
# Aquest fitxer s'ha de traduir d'acord amb el recull de termes i la guia
# d'estil de Softcatalà. Si voleu modificar aquest fitxer, llegiu si
# us plau la pàgina de catalanització del projecte Fedora a:
# https://www.softcatala.org/projectes/fedora/
# http://www.softcatala.org/projectes/fedora/
# i contacteu l'anterior traductor/a.
# Josep Torné Llavall <josep.torne@gmail.com>, 2009, 2012.
# Robert Antoni Buj Gelonch <rbuj@fedoraproject.org>, 2016. #zanata
@ -27,9 +27,10 @@
msgid ""
msgstr ""
"Project-Id-Version: pipewire\n"
"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/-/issues\n"
"POT-Creation-Date: 2025-07-20 15:32+0000\n"
"PO-Revision-Date: 2025-06-20 21:46+0200\n"
"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/-/"
"issues\n"
"POT-Creation-Date: 2023-06-06 15:28+0000\n"
"PO-Revision-Date: 2023-06-06 22:39+0200\n"
"Last-Translator: Jordi Mas i Herǹandez, <jmas@softcatala.org>,\n"
"Language-Team: Catalan <fedora@softcatala.net>\n"
"Language: ca\n"
@ -37,64 +38,60 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 3.2.2\n"
"X-Generator: Poedit 2.4.2\n"
#: src/daemon/pipewire.c:29
#: src/daemon/pipewire.c:26
#, c-format
msgid ""
"%s [options]\n"
" -h, --help Show this help\n"
" -v, --verbose Increase verbosity by one level\n"
" --version Show version\n"
" -c, --config Load config (Default %s)\n"
" -P --properties Set context properties\n"
msgstr ""
"%s [opcions]\n"
" -h, --help Mostra aquesta ajuda\n"
" -v, --verbose Augmenta la verbositat en un nivell\n"
" --version Mostra la versió\n"
" -c, --config Carrega la configuració (predeterminada %s)\n"
" -P --properties Estableix les propietats del context\n"
"\n"
" -c, --config Carrega la configuració "
"(predeterminada %s)\n"
#: src/daemon/pipewire.desktop.in:3
#: src/daemon/pipewire.desktop.in:4
msgid "PipeWire Media System"
msgstr "Sistema multimèdia PipeWire"
#: src/daemon/pipewire.desktop.in:4
#: src/daemon/pipewire.desktop.in:5
msgid "Start the PipeWire Media System"
msgstr "Inicia el sistema multimèdia PipeWire"
#: src/modules/module-protocol-pulse/modules/module-tunnel-sink.c:159
#: src/modules/module-protocol-pulse/modules/module-tunnel-source.c:159
#: src/modules/module-protocol-pulse/modules/module-tunnel-sink.c:141
#: src/modules/module-protocol-pulse/modules/module-tunnel-source.c:141
#, c-format
msgid "Tunnel to %s%s%s"
msgstr "Túnel cap a %s%s%s"
#: src/modules/module-fallback-sink.c:40
#: src/modules/module-fallback-sink.c:31
msgid "Dummy Output"
msgstr "Sortida fictícia"
#: src/modules/module-pulse-tunnel.c:760
#: src/modules/module-pulse-tunnel.c:844
#, c-format
msgid "Tunnel for %s@%s"
msgstr "Túnel per a %s@%s"
#: src/modules/module-zeroconf-discover.c:320
#: src/modules/module-zeroconf-discover.c:315
msgid "Unknown device"
msgstr "Dispositiu desconegut"
#: src/modules/module-zeroconf-discover.c:332
#: src/modules/module-zeroconf-discover.c:327
#, c-format
msgid "%s on %s@%s"
msgstr "%s en %s@%s"
#: src/modules/module-zeroconf-discover.c:336
#: src/modules/module-zeroconf-discover.c:331
#, c-format
msgid "%s on %s"
msgstr "%s en %s"
#: src/tools/pw-cat.c:1044
#: src/tools/pw-cat.c:974
#, c-format
msgid ""
"%s [options] [<file>|-]\n"
@ -108,68 +105,86 @@ msgstr ""
" --version Mostra la versió\n"
" -v, --verbose Habilita les operacions detallades\n"
#: src/tools/pw-cat.c:1051
#: src/tools/pw-cat.c:981
#, c-format
msgid ""
" -R, --remote Remote daemon name\n"
" --media-type Set media type (default %s)\n"
" --media-category Set media category (default %s)\n"
" --media-role Set media role (default %s)\n"
" --target Set node target serial or name (default %s)\n"
" --target Set node target serial or name "
"(default %s)\n"
" 0 means don't link\n"
" --latency Set node latency (default %s)\n"
" Xunit (unit = s, ms, us, ns)\n"
" or direct samples (256)\n"
" the rate is the one of the source file\n"
" the rate is the one of the source "
"file\n"
" -P --properties Set node properties\n"
"\n"
msgstr ""
" -R, --remote Nom del dimoni remot\n"
" --media-type Estableix el tipus de mitjà (per defecte %s)\n"
" --media-category Estableix la categoria del mitjà (per defecte %s)\n"
" --media-role Estableix el rol del mitjà (per defecte %s)\n"
" --target Estableix l'objectiu sèrie o el nom del node (per defecte %s)\n"
" --media-type Estableix el tipus de mitjà (per "
"defecte %s)\n"
" --media-category Estableix la categoria del "
"mitjà (per defecte %s)\n"
" --media-role Estableix el rol del mitjà (per "
"defecte %s)\n"
" --target Estableix l'objectiu sèrie o el nom "
"del node (per defecte %s)\n"
" 0 vol dir que no enllaça\n"
" --latency Estableix latència del node (per defecte %s)\n"
" --latency Estableix latència del node (per "
"defecte %s)\n"
" Xunit (unitat = s, ms, us, ns)\n"
" o mostres directes (256)\n"
" la taxa és la del fitxer d'origen\n"
" -P --properties Estableix les propietats del node\n"
" -P --properties Estableix les propietats del "
"node\n"
"\n"
#: src/tools/pw-cat.c:1069
#: src/tools/pw-cat.c:999
#, c-format
msgid ""
" --rate Sample rate (req. for rec) (default %u)\n"
" --channels Number of channels (req. for rec) (default %u)\n"
" --rate Sample rate (req. for rec) (default "
"%u)\n"
" --channels Number of channels (req. for rec) "
"(default %u)\n"
" --channel-map Channel map\n"
" one of: \"stereo\", \"surround-51\",... or\n"
" comma separated list of channel names: eg. \"FL,FR\"\n"
" --format Sample format %s (req. for rec) (default %s)\n"
" one of: \"stereo\", "
"\"surround-51\",... or\n"
" comma separated list of channel "
"names: eg. \"FL,FR\"\n"
" --format Sample format %s (req. for rec) "
"(default %s)\n"
" --volume Stream volume 0-1.0 (default %.3f)\n"
" -q --quality Resampler quality (0 - 15) (default %d)\n"
" -a, --raw RAW mode\n"
" -q --quality Resampler quality (0 - 15) (default "
"%d)\n"
"\n"
msgstr ""
" --rate Freqüència de mostreig (req. per a rec) (predeterminat %u)\n"
" --channels Nombre de canals (req. per a rec) (predeterminat %u)\n"
" --rate Freqüència de mostreig (req. per a "
"rec) (predeterminat %u)\n"
" --channels Nombre de canals (req. per a rec) "
"(predeterminat %u)\n"
" --channel-map Mapa de canals\n"
" un dels següents: \"stereo\", \"surround-51\",... o\n"
" llista separada per comes dels noms dels canals: per exemple. «FL,FR»\n"
" --format Format de mostra %s (req. per a rec) (predeterminat %s)\n"
" --volume Volum del flux 0-1.0 (predeterminat %.3f)\n"
" -q --quality Qualitat de remostrador (0 - 15) (predeterminat %d)\n"
" -a, --raw Mode RAW\n"
" un dels següents: \"stereo\", "
"\"surround-51\",... o\n"
" llista separada per comes dels "
"noms dels canals: per exemple. «FL,FR»\n"
" --format Format de mostra %s (req. per a rec) "
"(predeterminat %s)\n"
" --volume Volum del flux 0-1.0 (predeterminat "
"%.3f)\n"
" -q --quality Qualitat de remostrador (0 - 15) "
"(predeterminal %d)\n"
"\n"
#: src/tools/pw-cat.c:1087
#: src/tools/pw-cat.c:1016
msgid ""
" -p, --playback Playback mode\n"
" -r, --record Recording mode\n"
" -m, --midi Midi mode\n"
" -d, --dsd DSD mode\n"
" -o, --encoded Encoded mode\n"
" -s, --sysex SysEx mode\n"
"\n"
msgstr ""
" -p, --playback Mode de reproducció\n"
@ -177,10 +192,9 @@ msgstr ""
" -m, --midi Mode MIDI\n"
" -d, --dsd Mode DSD\n"
" -o, --encoded Mode codificat\n"
" -s, --sysex Mode SysEx\n"
"\n"
#: src/tools/pw-cli.c:2386
#: src/tools/pw-cli.c:2220
#, c-format
msgid ""
"%s [options] [command]\n"
@ -194,25 +208,21 @@ msgstr ""
"%s [opcions] [ordre]\n"
" -h, --help Mostra aquesta ajuda\n"
" --version Mostra la versió\n"
" -d, --daemon Inicia com a dimoni (fals per defecte)\n"
" -d, --daemon Inicia com a dimoni (fals per "
"defecte)\n"
" -r, --remote Nom del dimoni remot\n"
" -m, --monitor Monitor d'activitat\n"
"\n"
#: spa/plugins/alsa/acp/acp.c:351
#: spa/plugins/alsa/acp/acp.c:303
msgid "Pro Audio"
msgstr "Pro Audio"
#: spa/plugins/alsa/acp/acp.c:520 spa/plugins/alsa/acp/alsa-mixer.c:4635
#: spa/plugins/bluez5/bluez5-device.c:1974
#: spa/plugins/alsa/acp/acp.c:427 spa/plugins/alsa/acp/alsa-mixer.c:4648
#: spa/plugins/bluez5/bluez5-device.c:1586
msgid "Off"
msgstr "Inactiu"
#: spa/plugins/alsa/acp/acp.c:603
#, c-format
msgid "%s [ALSA UCM error]"
msgstr "%s [Error d'ALSA UCM]"
#: spa/plugins/alsa/acp/alsa-mixer.c:2652
msgid "Input"
msgstr "Entrada"
@ -236,7 +246,7 @@ msgstr "Entrada de línia"
#: spa/plugins/alsa/acp/alsa-mixer.c:2657
#: spa/plugins/alsa/acp/alsa-mixer.c:2741
#: spa/plugins/bluez5/bluez5-device.c:2372
#: spa/plugins/bluez5/bluez5-device.c:1831
msgid "Microphone"
msgstr "Micròfon"
@ -302,15 +312,12 @@ msgid "No Bass Boost"
msgstr "Sense accentuació dels baixos"
#: spa/plugins/alsa/acp/alsa-mixer.c:2672
#: spa/plugins/bluez5/bluez5-device.c:2378
#: spa/plugins/bluez5/bluez5-device.c:1837
msgid "Speaker"
msgstr "Altaveu"
#. Don't call it "headset", the HF one has the mic
#: spa/plugins/alsa/acp/alsa-mixer.c:2673
#: spa/plugins/alsa/acp/alsa-mixer.c:2751
#: spa/plugins/bluez5/bluez5-device.c:2384
#: spa/plugins/bluez5/bluez5-device.c:2451
msgid "Headphones"
msgstr "Auriculars"
@ -387,15 +394,15 @@ msgstr "Entrada del xat"
msgid "Virtual Surround 7.1"
msgstr "Envoltant virtual 7.1"
#: spa/plugins/alsa/acp/alsa-mixer.c:4458
#: spa/plugins/alsa/acp/alsa-mixer.c:4471
msgid "Analog Mono"
msgstr "Mono analògic"
#: spa/plugins/alsa/acp/alsa-mixer.c:4459
#: spa/plugins/alsa/acp/alsa-mixer.c:4472
msgid "Analog Mono (Left)"
msgstr "Mono analògic (esquerra)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4460
#: spa/plugins/alsa/acp/alsa-mixer.c:4473
msgid "Analog Mono (Right)"
msgstr "Mono analògic (dreta)"
@ -404,307 +411,338 @@ msgstr "Mono analògic (dreta)"
#. * here would lead to the source name to become "Analog Stereo Input
#. * Input". The same logic applies to analog-stereo-output,
#. * multichannel-input and multichannel-output.
#: spa/plugins/alsa/acp/alsa-mixer.c:4461
#: spa/plugins/alsa/acp/alsa-mixer.c:4469
#: spa/plugins/alsa/acp/alsa-mixer.c:4470
#: spa/plugins/alsa/acp/alsa-mixer.c:4474
#: spa/plugins/alsa/acp/alsa-mixer.c:4482
#: spa/plugins/alsa/acp/alsa-mixer.c:4483
msgid "Analog Stereo"
msgstr "Estèreo analògic"
#: spa/plugins/alsa/acp/alsa-mixer.c:4462
#: spa/plugins/alsa/acp/alsa-mixer.c:4475
msgid "Mono"
msgstr "Mono"
#: spa/plugins/alsa/acp/alsa-mixer.c:4463
#: spa/plugins/alsa/acp/alsa-mixer.c:4476
msgid "Stereo"
msgstr "Estèreo"
#: spa/plugins/alsa/acp/alsa-mixer.c:4471
#: spa/plugins/alsa/acp/alsa-mixer.c:4629
#: spa/plugins/bluez5/bluez5-device.c:2360
#: spa/plugins/alsa/acp/alsa-mixer.c:4484
#: spa/plugins/alsa/acp/alsa-mixer.c:4642
#: spa/plugins/bluez5/bluez5-device.c:1819
msgid "Headset"
msgstr "Auriculars"
#: spa/plugins/alsa/acp/alsa-mixer.c:4472
#: spa/plugins/alsa/acp/alsa-mixer.c:4630
#: spa/plugins/alsa/acp/alsa-mixer.c:4485
#: spa/plugins/alsa/acp/alsa-mixer.c:4643
msgid "Speakerphone"
msgstr "Altaveu del telèfon"
#: spa/plugins/alsa/acp/alsa-mixer.c:4473
#: spa/plugins/alsa/acp/alsa-mixer.c:4474
#: spa/plugins/alsa/acp/alsa-mixer.c:4486
#: spa/plugins/alsa/acp/alsa-mixer.c:4487
msgid "Multichannel"
msgstr "Multicanal"
#: spa/plugins/alsa/acp/alsa-mixer.c:4475
#: spa/plugins/alsa/acp/alsa-mixer.c:4488
msgid "Analog Surround 2.1"
msgstr "Envoltant analògic 2.1"
#: spa/plugins/alsa/acp/alsa-mixer.c:4476
#: spa/plugins/alsa/acp/alsa-mixer.c:4489
msgid "Analog Surround 3.0"
msgstr "Envoltant analògic 3.0"
#: spa/plugins/alsa/acp/alsa-mixer.c:4477
#: spa/plugins/alsa/acp/alsa-mixer.c:4490
msgid "Analog Surround 3.1"
msgstr "Envoltant analògic 3.1"
#: spa/plugins/alsa/acp/alsa-mixer.c:4478
#: spa/plugins/alsa/acp/alsa-mixer.c:4491
msgid "Analog Surround 4.0"
msgstr "Envoltant analògic 4.0"
#: spa/plugins/alsa/acp/alsa-mixer.c:4479
#: spa/plugins/alsa/acp/alsa-mixer.c:4492
msgid "Analog Surround 4.1"
msgstr "Envoltant analògic 4.1"
#: spa/plugins/alsa/acp/alsa-mixer.c:4480
#: spa/plugins/alsa/acp/alsa-mixer.c:4493
msgid "Analog Surround 5.0"
msgstr "Envoltant analògic 5.0"
#: spa/plugins/alsa/acp/alsa-mixer.c:4481
#: spa/plugins/alsa/acp/alsa-mixer.c:4494
msgid "Analog Surround 5.1"
msgstr "Envoltant analògic 5.1"
#: spa/plugins/alsa/acp/alsa-mixer.c:4482
#: spa/plugins/alsa/acp/alsa-mixer.c:4495
msgid "Analog Surround 6.0"
msgstr "Envoltant analògic 6.0"
#: spa/plugins/alsa/acp/alsa-mixer.c:4483
#: spa/plugins/alsa/acp/alsa-mixer.c:4496
msgid "Analog Surround 6.1"
msgstr "Envoltant analògic 6.1"
#: spa/plugins/alsa/acp/alsa-mixer.c:4484
#: spa/plugins/alsa/acp/alsa-mixer.c:4497
msgid "Analog Surround 7.0"
msgstr "Envoltant analògic 7.0"
#: spa/plugins/alsa/acp/alsa-mixer.c:4485
#: spa/plugins/alsa/acp/alsa-mixer.c:4498
msgid "Analog Surround 7.1"
msgstr "Envoltant analògic 7.1"
#: spa/plugins/alsa/acp/alsa-mixer.c:4486
#: spa/plugins/alsa/acp/alsa-mixer.c:4499
msgid "Digital Stereo (IEC958)"
msgstr "Estèreo digital (IEC958)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4487
#: spa/plugins/alsa/acp/alsa-mixer.c:4500
msgid "Digital Surround 4.0 (IEC958/AC3)"
msgstr "Envoltant digital 4.0 (IEC958/AC3)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4488
#: spa/plugins/alsa/acp/alsa-mixer.c:4501
msgid "Digital Surround 5.1 (IEC958/AC3)"
msgstr "Envoltant digital 5.1 (IEC958/AC3)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4489
#: spa/plugins/alsa/acp/alsa-mixer.c:4502
msgid "Digital Surround 5.1 (IEC958/DTS)"
msgstr "Envoltant digital 5.1 (IEC958/DTS)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4490
#: spa/plugins/alsa/acp/alsa-mixer.c:4503
msgid "Digital Stereo (HDMI)"
msgstr "Estèreo digital (HDMI)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4491
#: spa/plugins/alsa/acp/alsa-mixer.c:4504
msgid "Digital Surround 5.1 (HDMI)"
msgstr "Envoltant digital 5.1 (HDMI)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4492
#: spa/plugins/alsa/acp/alsa-mixer.c:4505
msgid "Chat"
msgstr "Xat"
#: spa/plugins/alsa/acp/alsa-mixer.c:4493
#: spa/plugins/alsa/acp/alsa-mixer.c:4506
msgid "Game"
msgstr "Joc"
#: spa/plugins/alsa/acp/alsa-mixer.c:4627
#: spa/plugins/alsa/acp/alsa-mixer.c:4640
msgid "Analog Mono Duplex"
msgstr "Dúplex mono analògic"
#: spa/plugins/alsa/acp/alsa-mixer.c:4628
#: spa/plugins/alsa/acp/alsa-mixer.c:4641
msgid "Analog Stereo Duplex"
msgstr "Dúplex estèreo analògic"
#: spa/plugins/alsa/acp/alsa-mixer.c:4631
#: spa/plugins/alsa/acp/alsa-mixer.c:4644
msgid "Digital Stereo Duplex (IEC958)"
msgstr "Dúplex estèreo digital (IEC958)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4632
#: spa/plugins/alsa/acp/alsa-mixer.c:4645
msgid "Multichannel Duplex"
msgstr "Dúplex Multicanal"
#: spa/plugins/alsa/acp/alsa-mixer.c:4633
#: spa/plugins/alsa/acp/alsa-mixer.c:4646
msgid "Stereo Duplex"
msgstr "Dúplex estèreo"
#: spa/plugins/alsa/acp/alsa-mixer.c:4634
#: spa/plugins/alsa/acp/alsa-mixer.c:4647
msgid "Mono Chat + 7.1 Surround"
msgstr "Xat mono + 7.1 envoltant"
#: spa/plugins/alsa/acp/alsa-mixer.c:4735
#: spa/plugins/alsa/acp/alsa-mixer.c:4748
#, c-format
msgid "%s Output"
msgstr "Sortida %s"
#: spa/plugins/alsa/acp/alsa-mixer.c:4743
#: spa/plugins/alsa/acp/alsa-mixer.c:4756
#, c-format
msgid "%s Input"
msgstr "Entrada %s"
#: spa/plugins/alsa/acp/alsa-util.c:1233 spa/plugins/alsa/acp/alsa-util.c:1327
#: spa/plugins/alsa/acp/alsa-util.c:1187 spa/plugins/alsa/acp/alsa-util.c:1281
#, c-format
msgid ""
"snd_pcm_avail() returned a value that is exceptionally large: %lu byte (%lu ms).\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers."
"snd_pcm_avail() returned a value that is exceptionally large: %lu byte (%lu "
"ms).\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
"to the ALSA developers."
msgid_plural ""
"snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu ms).\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers."
"snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu "
"ms).\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
"to the ALSA developers."
msgstr[0] ""
"snd_pcm_avail() ha retornat un valor excepcionalment gran: %lu byte (%lu ms).\n"
"Probablement es tracta d'un error del controlador de l'ALSA «%s». Informeu d'aquest incident als desenvolupadors de l'ALSA."
"snd_pcm_avail() ha retornat un valor excepcionalment gran: %lu byte (%lu "
"ms).\n"
"Probablement es tracta d'un error del controlador de l'ALSA «%s». Informeu "
"d'aquest incident als desenvolupadors de l'ALSA."
msgstr[1] ""
"snd_pcm_avail() ha retornat un valor excepcionalment gran: %lu bytes (%lu ms).\n"
"Probablement es tracta d'un error del controlador de l'ALSA «%s». Informeu d'aquest incident als desenvolupadors de l'ALSA."
"snd_pcm_avail() ha retornat un valor excepcionalment gran: %lu bytes (%lu "
"ms).\n"
"Probablement es tracta d'un error del controlador de l'ALSA «%s». Informeu "
"d'aquest incident als desenvolupadors de l'ALSA."
#: spa/plugins/alsa/acp/alsa-util.c:1299
#: spa/plugins/alsa/acp/alsa-util.c:1253
#, c-format
msgid ""
"snd_pcm_delay() returned a value that is exceptionally large: %li byte (%s%lu ms).\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers."
"snd_pcm_delay() returned a value that is exceptionally large: %li byte "
"(%s%lu ms).\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
"to the ALSA developers."
msgid_plural ""
"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s%lu ms).\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers."
"snd_pcm_delay() returned a value that is exceptionally large: %li bytes "
"(%s%lu ms).\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
"to the ALSA developers."
msgstr[0] ""
"snd_pcm_delay() ha retornat un valor excepcionalment gran: %li byte (%s%lu ms).\n"
"Probablement es tracta d'un error del controlador de l'ALSA «%s». Informeu d'aquest incident als desenvolupadors de l'ALSA."
"snd_pcm_delay() ha retornat un valor excepcionalment gran: %li byte (%s%lu "
"ms).\n"
"Probablement es tracta d'un error del controlador de l'ALSA «%s». Informeu "
"d'aquest incident als desenvolupadors de l'ALSA."
msgstr[1] ""
"snd_pcm_delay() ha retornat un valor excepcionalment gran: %li bytes (%s%lu ms).\n"
"Probablement es tracta d'un error del controlador de l'ALSA «%s». Informeu d'aquest incident als desenvolupadors de l'ALSA."
"snd_pcm_delay() ha retornat un valor excepcionalment gran: %li bytes (%s%lu "
"ms).\n"
"Probablement es tracta d'un error del controlador de l'ALSA «%s». Informeu "
"d'aquest incident als desenvolupadors de l'ALSA."
#: spa/plugins/alsa/acp/alsa-util.c:1346
#: spa/plugins/alsa/acp/alsa-util.c:1300
#, c-format
msgid ""
"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail %lu.\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers."
"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
"%lu.\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
"to the ALSA developers."
msgstr ""
"snd_pcm_avail() ha retornat un valor excepcionalment gran: %lu bytes (%lu ms).\n"
"Probablement es tracta d'un error del controlador d'ALSA «%s». Informeu d'aquest problema als desenvolupadors d'ALSA."
"snd_pcm_avail() ha retornat un valor excepcionalment gran: %lu bytes (%lu "
"ms).\n"
"Probablement es tracta d'un error del controlador d'ALSA «%s». Informeu "
"d'aquest problema als desenvolupadors d'ALSA."
#: spa/plugins/alsa/acp/alsa-util.c:1389
#: spa/plugins/alsa/acp/alsa-util.c:1343
#, c-format
msgid ""
"snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu byte (%lu ms).\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers."
"snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu byte "
"(%lu ms).\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
"to the ALSA developers."
msgid_plural ""
"snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes (%lu ms).\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers."
"snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes "
"(%lu ms).\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
"to the ALSA developers."
msgstr[0] ""
"snd_pcm_mmap_begin() ha retornat un valor excepcionalment gran: %lu byte (%lu ms).\n"
"Probablement es tracta d'un error del controlador de l'ALSA «%s». Informeu d'aquest incident als desenvolupadors de l'ALSA."
"snd_pcm_mmap_begin() ha retornat un valor excepcionalment gran: %lu byte "
"(%lu ms).\n"
"Probablement es tracta d'un error del controlador de l'ALSA «%s». Informeu "
"d'aquest incident als desenvolupadors de l'ALSA."
msgstr[1] ""
"snd_pcm_mmap_begin() ha retornat un valor excepcionalment gran: %lu bytes (%lu ms).\n"
"Probablement es tracta d'un error del controlador de l'ALSA «%s». Informeu d'aquest incident als desenvolupadors de l'ALSA."
"snd_pcm_mmap_begin() ha retornat un valor excepcionalment gran: %lu bytes "
"(%lu ms).\n"
"Probablement es tracta d'un error del controlador de l'ALSA «%s». Informeu "
"d'aquest incident als desenvolupadors de l'ALSA."
#: spa/plugins/alsa/acp/channelmap.h:457
msgid "(invalid)"
msgstr "(incorrecte)"
#: spa/plugins/alsa/acp/compat.c:194
#: spa/plugins/alsa/acp/compat.c:189
msgid "Built-in Audio"
msgstr "Àudio intern"
#: spa/plugins/alsa/acp/compat.c:199
#: spa/plugins/alsa/acp/compat.c:194
msgid "Modem"
msgstr "Mòdem"
#: spa/plugins/bluez5/bluez5-device.c:1985
#: spa/plugins/bluez5/bluez5-device.c:1597
msgid "Audio Gateway (A2DP Source & HSP/HFP AG)"
msgstr "Passarel·la d'àudio (A2DP Source & HSP/HFP AG)"
#: spa/plugins/bluez5/bluez5-device.c:2014
msgid "Audio Streaming for Hearing Aids (ASHA Sink)"
msgstr "Retransmissió d'àudio per als audiòfons (ASHA Sink)"
#: spa/plugins/bluez5/bluez5-device.c:2057
#: spa/plugins/bluez5/bluez5-device.c:1622
#, c-format
msgid "High Fidelity Playback (A2DP Sink, codec %s)"
msgstr "Reproducció d'alta fidelitat (Sink A2DP, còdec %s)"
#: spa/plugins/bluez5/bluez5-device.c:2060
#: spa/plugins/bluez5/bluez5-device.c:1625
#, c-format
msgid "High Fidelity Duplex (A2DP Source/Sink, codec %s)"
msgstr "Dúplex d'alta fidelitat (A2DP Source/Sink, còdec %s)"
#: spa/plugins/bluez5/bluez5-device.c:2068
#: spa/plugins/bluez5/bluez5-device.c:1633
msgid "High Fidelity Playback (A2DP Sink)"
msgstr "Reproducció d'alta fidelitat (A2DP Sink)"
#: spa/plugins/bluez5/bluez5-device.c:2070
#: spa/plugins/bluez5/bluez5-device.c:1635
msgid "High Fidelity Duplex (A2DP Source/Sink)"
msgstr "Dúplex d'alta fidelitat (A2DP Source/Sink)"
#: spa/plugins/bluez5/bluez5-device.c:2144
#: spa/plugins/bluez5/bluez5-device.c:1677
#, c-format
msgid "High Fidelity Playback (BAP Sink, codec %s)"
msgstr "Reproducció d'alta fidelitat (sortida BAP, còdec %s)"
#: spa/plugins/bluez5/bluez5-device.c:2149
#: spa/plugins/bluez5/bluez5-device.c:1681
#, c-format
msgid "High Fidelity Input (BAP Source, codec %s)"
msgstr "Entrada d'alta fidelitat (font A2DP, còdec %s)"
#: spa/plugins/bluez5/bluez5-device.c:2153
#: spa/plugins/bluez5/bluez5-device.c:1685
#, c-format
msgid "High Fidelity Duplex (BAP Source/Sink, codec %s)"
msgstr "Dúplex d'alta fidelitat (BAP Source/Sink, còdec %s)"
#: spa/plugins/bluez5/bluez5-device.c:2162
#: spa/plugins/bluez5/bluez5-device.c:1693
msgid "High Fidelity Playback (BAP Sink)"
msgstr "Reproducció d'alta fidelitat (Sortida BAP)"
#: spa/plugins/bluez5/bluez5-device.c:2166
#: spa/plugins/bluez5/bluez5-device.c:1696
msgid "High Fidelity Input (BAP Source)"
msgstr "Entrada d'alta fidelitat (Font BAP)"
#: spa/plugins/bluez5/bluez5-device.c:2169
#: spa/plugins/bluez5/bluez5-device.c:1699
msgid "High Fidelity Duplex (BAP Source/Sink)"
msgstr "Dúplex d'alta fidelitat (BAP Source/Sink)"
#: spa/plugins/bluez5/bluez5-device.c:2209
#: spa/plugins/bluez5/bluez5-device.c:1735
#, c-format
msgid "Headset Head Unit (HSP/HFP, codec %s)"
msgstr "Unitat d'auriculars pel cap (HSP/HFP, còdec %s)"
msgstr "Unitat d'ariculars pel cap (HSP/HFP, còdec %s)"
#: spa/plugins/bluez5/bluez5-device.c:2361
#: spa/plugins/bluez5/bluez5-device.c:2366
#: spa/plugins/bluez5/bluez5-device.c:2373
#: spa/plugins/bluez5/bluez5-device.c:2379
#: spa/plugins/bluez5/bluez5-device.c:2385
#: spa/plugins/bluez5/bluez5-device.c:2391
#: spa/plugins/bluez5/bluez5-device.c:2397
#: spa/plugins/bluez5/bluez5-device.c:2403
#: spa/plugins/bluez5/bluez5-device.c:2409
#: spa/plugins/bluez5/bluez5-device.c:1740
msgid "Headset Head Unit (HSP/HFP)"
msgstr "Unitat d'ariculars pel cap (HSP/HFP)"
#: spa/plugins/bluez5/bluez5-device.c:1820
#: spa/plugins/bluez5/bluez5-device.c:1825
#: spa/plugins/bluez5/bluez5-device.c:1832
#: spa/plugins/bluez5/bluez5-device.c:1838
#: spa/plugins/bluez5/bluez5-device.c:1844
#: spa/plugins/bluez5/bluez5-device.c:1850
#: spa/plugins/bluez5/bluez5-device.c:1856
#: spa/plugins/bluez5/bluez5-device.c:1862
#: spa/plugins/bluez5/bluez5-device.c:1868
msgid "Handsfree"
msgstr "Mans lliures"
#: spa/plugins/bluez5/bluez5-device.c:2367
#: spa/plugins/bluez5/bluez5-device.c:1826
msgid "Handsfree (HFP)"
msgstr "Mans lliures (HFP)"
#: spa/plugins/bluez5/bluez5-device.c:2390
#: spa/plugins/bluez5/bluez5-device.c:1843
msgid "Headphone"
msgstr "Auricular"
#: spa/plugins/bluez5/bluez5-device.c:1849
msgid "Portable"
msgstr "Portable"
#: spa/plugins/bluez5/bluez5-device.c:2396
#: spa/plugins/bluez5/bluez5-device.c:1855
msgid "Car"
msgstr "Cotxe"
#: spa/plugins/bluez5/bluez5-device.c:2402
#: spa/plugins/bluez5/bluez5-device.c:1861
msgid "HiFi"
msgstr "HiFi"
#: spa/plugins/bluez5/bluez5-device.c:2408
#: spa/plugins/bluez5/bluez5-device.c:1867
msgid "Phone"
msgstr "Telèfon"
#: spa/plugins/bluez5/bluez5-device.c:2415
#: spa/plugins/bluez5/bluez5-device.c:1874
msgid "Bluetooth"
msgstr "Bluetooth"
#: spa/plugins/bluez5/bluez5-device.c:2416
#: spa/plugins/bluez5/bluez5-device.c:1875
msgid "Bluetooth (HFP)"
msgstr "Bluetooth (HFP)"

View file

@ -9,15 +9,15 @@ msgstr ""
"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/-/"
"issues\n"
"POT-Creation-Date: 2021-08-26 03:31+0000\n"
"PO-Revision-Date: 2025-10-02 11:36+0630\n"
"Last-Translator: zayar lwin <lw1nzayar@yandex.com>\n"
"PO-Revision-Date: 2021-08-26 21:52+0630\n"
"Language-Team: lw1nzayar@yandex.com\n"
"Language: my\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Poedit 3.7\n"
"X-Generator: Poedit 2.4.2\n"
"Last-Translator: zayar lwin <lw1nzayar@yandex.com>\n"
"Language: my\n"
#: src/daemon/pipewire.c:45
#, c-format
@ -27,24 +27,23 @@ msgid ""
" --version Show version\n"
" -c, --config Load config (Default %s)\n"
msgstr ""
"%s [options]\r\n"
" -h, --help Show this help\r\n"
" --version Show version\r\n"
" -c, --config Load config (Default %s)\r\n"
"\n"
"%s [options]\n"
" -h, --help Show this help\n"
" --version Show version\n"
" -c, --config Load config (Default %s)\n"
#: src/daemon/pipewire.desktop.in:4
msgid "PipeWire Media System"
msgstr "ပိုက်ဝိုင်ယာ မီဒီယာစစ်"
msgstr "ပိုက်ဝိုင်ယာ မီဒီယာစစ်စတမ်"
#: src/daemon/pipewire.desktop.in:5
msgid "Start the PipeWire Media System"
msgstr "ပိုက်ဝိုင်ယာ မီဒီယာစစ် စတင်ရန်"
msgstr "ပိုက်ဝိုင်ယာ မီဒီယာစစ်စတမ် စတင်ရန်"
#: src/examples/media-session/alsa-monitor.c:588
#: spa/plugins/alsa/acp/compat.c:189
msgid "Built-in Audio"
msgstr "မူလပါရှိပြီးအသံကိရိယာ"
msgstr "နဂိုတည်းကထည့်သွင်းထားသည်ံ့ အသံကရိယာ"
#: src/examples/media-session/alsa-monitor.c:592
#: spa/plugins/alsa/acp/compat.c:194
@ -54,7 +53,7 @@ msgstr "ဆ.သ.ရ-စက်"
#: src/examples/media-session/alsa-monitor.c:601
#: src/modules/module-zeroconf-discover.c:296
msgid "Unknown device"
msgstr "မသိ"
msgstr "မသိသောစက်"
#: src/modules/module-protocol-pulse/modules/module-tunnel-sink.c:173
#: src/modules/module-protocol-pulse/modules/module-tunnel-source.c:173
@ -70,12 +69,12 @@ msgstr "%s@%sအတွက် လုံခြုံစွာဒေတာပို
#: src/modules/module-zeroconf-discover.c:308
#, c-format
msgid "%s on %s@%s"
msgstr "%s on %s@%s"
msgstr ""
#: src/modules/module-zeroconf-discover.c:312
#, c-format
msgid "%s on %s"
msgstr "%s on %s"
msgstr ""
#: src/tools/pw-cat.c:1016
#, c-format
@ -86,11 +85,6 @@ msgid ""
" -v, --verbose Enable verbose operations\n"
"\n"
msgstr ""
"%s [options] <file>\r\n"
" -h, --help Show this help\r\n"
" --version Show version\r\n"
" -v, --verbose Enable verbose operations\r\n"
"\r\n"
#: src/tools/pw-cat.c:1023
#, c-format
@ -109,20 +103,6 @@ msgid ""
" --list-targets List available targets for --target\n"
"\n"
msgstr ""
" -R, --remote Remote daemon name\r\n"
" --media-type Set media type (default %s)\r\n"
" --media-category Set media category (default %s)\r\n"
" --media-role Set media role (default %s)\r\n"
" --target Set node target (default %s)\r\n"
" 0 means don't link\r\n"
" --latency Set node latency (default %s)\r\n"
" Xunit (unit = s, ms, us, ns)\r\n"
" or direct samples (256)\r\n"
" the rate is the one of the source "
"file\r\n"
" --list-targets List available targets for --"
"target\r\n"
"\r\n"
#: src/tools/pw-cat.c:1041
#, c-format
@ -143,22 +123,6 @@ msgid ""
"%d)\n"
"\n"
msgstr ""
" --rate Sample rate (req. for rec) (default "
"%u)\r\n"
" --channels Number of channels (req. for rec) "
"(default %u)\r\n"
" --channel-map Channel map\r\n"
" one of: \"stereo\", "
"\"surround-51\",... or\r\n"
" comma separated list of channel "
"names: eg. \"FL,FR\"\r\n"
" --format Sample format %s (req. for rec) "
"(default %s)\r\n"
" --volume Stream volume 0-1.0 (default %.3f)"
"\r\n"
" -q --quality Resampler quality (0 - 15) (default "
"%d)\r\n"
"\r\n"
#: src/tools/pw-cat.c:1058
msgid ""
@ -167,10 +131,6 @@ msgid ""
" -m, --midi Midi mode\n"
"\n"
msgstr ""
" -p, --playback Playback mode\r\n"
" -r, --record Recording mode\r\n"
" -m, --midi Midi mode\r\n"
"\r\n"
#: src/tools/pw-cli.c:2954
#, c-format
@ -182,12 +142,6 @@ msgid ""
" -r, --remote Remote daemon name\n"
"\n"
msgstr ""
"%s [options] [command]\r\n"
" -h, --help Show this help\r\n"
" --version Show version\r\n"
" -d, --daemon Start as daemon (Default false)\r\n"
" -r, --remote Remote daemon name\r\n"
"\r\n"
#: spa/plugins/alsa/acp/acp.c:306
msgid "Pro Audio"
@ -519,12 +473,12 @@ msgstr "မိုနို စကားပြောဆိုသံ + ၇.၁ ပ
#: spa/plugins/alsa/acp/alsa-mixer.c:4750
#, c-format
msgid "%s Output"
msgstr "%s အသံထုတ်"
msgstr "%s ထုတ်ပို့ကရိယာ"
#: spa/plugins/alsa/acp/alsa-mixer.c:4757
#, c-format
msgid "%s Input"
msgstr "%s အသံသွင်း"
msgstr "%s လက်ခံကရိယာ"
#: spa/plugins/alsa/acp/alsa-util.c:1173 spa/plugins/alsa/acp/alsa-util.c:1267
#, c-format
@ -539,26 +493,20 @@ msgid_plural ""
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
"to the ALSA developers."
msgstr[0] ""
"snd_pcm_avail() မှ ပြန်ပေးသည့်တန်ဖိုးသည် အလွန်ကြီးမားနေသည်- %lu ဘိုက် (%lu ms)။\n"
"ဖြစ်နိုင်ခြေအများဆုံးမှာ ALSA ဒရိုက်ဗာ %s တွင် ပရိုဂရမ်အမှားတစ်ခုရှိနေခြင်းဖြစ်သည်။ ဤပြဿနာအား "
"ALSA ရေးသားသူများထံသို့ သတင်းပို့ပေးပါ။"
#: spa/plugins/alsa/acp/alsa-util.c:1239
#, c-format
msgid ""
"snd_pcm_delay() returned a value that is exceptionally large: %li byte "
"(%s%lu ms).\n"
"snd_pcm_delay() returned a value that is exceptionally large: %li byte (%s"
"%lu ms).\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
"to the ALSA developers."
msgid_plural ""
"snd_pcm_delay() returned a value that is exceptionally large: %li bytes "
"(%s%lu ms).\n"
"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s"
"%lu ms).\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
"to the ALSA developers."
msgstr[0] ""
"snd_pcm_delay() မှ ပြန်ပေးသည့်တန်ဖိုးသည် အလွန်ကြီးမားနေသည်- %li ဘိုက် (%s%lu ms)။\n"
"ဖြစ်နိုင်ခြေအများဆုံးမှာ ALSA ဒရိုက်ဗာ %s တွင် ပရိုဂရမ်အမှားတစ်ခုရှိနေခြင်းဖြစ်သည်။ ဤပြဿနာအား "
"ALSA ရေးသားသူများထံသို့ သတင်းပို့ပေးပါ။"
#: spa/plugins/alsa/acp/alsa-util.c:1286
#, c-format
@ -568,10 +516,6 @@ msgid ""
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
"to the ALSA developers."
msgstr ""
"snd_pcm_avail_delay() မှ ထူးဆန်းသောတန်ဖိုးများ ပြန်ပေးခဲ့သည်- နှောင့်နှေးမှု %lu သည် ရနိုင်မှု %lu "
"ထက် နည်းနေပါသည်။\n"
"ဖြစ်နိုင်ခြေအများဆုံးမှာ ALSA ဒရိုက်ဘာ '%s တွင် ပရိုဂရမ်အမှားတစ်ခုရှိနေခြင်းဖြစ်သည်။ ဤပြဿနာအား "
"ALSA ရေးသားသူများထံသို့ သတင်းပို့ပေးပါ။"
#: spa/plugins/alsa/acp/alsa-util.c:1329
#, c-format
@ -586,9 +530,6 @@ msgid_plural ""
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
"to the ALSA developers."
msgstr[0] ""
"snd_pcm_mmap_begin() မှ ပြန်ပေးသည့်တန်ဖိုးသည် အလွန်ကြီးမားနေသည်- %lu ဘိုက် (%lu ms)။\n"
"ဖြစ်နိုင်ခြေအများဆုံးမှာ ALSA ဒရိုက်ဗာ %s တွင် ပရိုဂရမ်အမှားတစ်ခုရှိနေခြင်းဖြစ်သည်။ ဤပြဿနာအား "
"ALSA ရေးသားသူများထံသို့ သတင်းပို့ပေးပါ။"
#: spa/plugins/alsa/acp/channelmap.h:466
msgid "(invalid)"

View file

@ -272,7 +272,7 @@ msgstr "Contraròtle automatic del ganh"
#: spa/plugins/alsa/acp/alsa-mixer.c:2665
msgid "No Automatic Gain Control"
msgstr "Cap de contraròtle automatic del ganh"
msgstr "Pas de contraròtle automatic del ganh"
#: spa/plugins/alsa/acp/alsa-mixer.c:2666
msgid "Boost"
@ -288,7 +288,7 @@ msgstr "Amplificador"
#: spa/plugins/alsa/acp/alsa-mixer.c:2669
msgid "No Amplifier"
msgstr "Cap d'amplificador"
msgstr "Pas d'amplificador"
#: spa/plugins/alsa/acp/alsa-mixer.c:2670
msgid "Bass Boost"
@ -296,7 +296,7 @@ msgstr "Amplificacion bassas"
#: spa/plugins/alsa/acp/alsa-mixer.c:2671
msgid "No Bass Boost"
msgstr "Cap d'amplificacion de las bassas"
msgstr "Pas d'amplificacion de las bassas"
#: spa/plugins/alsa/acp/alsa-mixer.c:2672
#: spa/plugins/bluez5/bluez5-device.c:1995
@ -531,12 +531,12 @@ msgstr "Messatjariá mono + Surround 7.1"
#: spa/plugins/alsa/acp/alsa-mixer.c:4733
#, c-format
msgid "%s Output"
msgstr "Sortida %s"
msgstr "%s Sortida"
#: spa/plugins/alsa/acp/alsa-mixer.c:4741
#, c-format
msgid "%s Input"
msgstr "Entrada %s"
msgstr "%s Entrada"
#: spa/plugins/alsa/acp/alsa-util.c:1220 spa/plugins/alsa/acp/alsa-util.c:1314
#, c-format

115
po/pl.po
View file

@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: pipewire\n"
"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/-/"
"issues\n"
"POT-Creation-Date: 2025-09-13 03:33+0000\n"
"PO-Revision-Date: 2025-09-13 11:47+0200\n"
"POT-Creation-Date: 2025-01-09 15:25+0000\n"
"PO-Revision-Date: 2025-02-09 14:55+0100\n"
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
"Language-Team: Polish <community-poland@mozilla.org>\n"
"Language: pl\n"
@ -38,11 +38,11 @@ msgstr ""
"%s)\n"
" -P --properties Ustawia właściwości kontekstu\n"
#: src/daemon/pipewire.desktop.in:3
#: src/daemon/pipewire.desktop.in:4
msgid "PipeWire Media System"
msgstr "System multimediów PipeWire"
#: src/daemon/pipewire.desktop.in:4
#: src/daemon/pipewire.desktop.in:5
msgid "Start the PipeWire Media System"
msgstr "Uruchomienie systemu multimediów PipeWire"
@ -75,7 +75,7 @@ msgstr "%s na %s@%s"
msgid "%s on %s"
msgstr "%s na %s"
#: src/tools/pw-cat.c:1084
#: src/tools/pw-cat.c:973
#, c-format
msgid ""
"%s [options] [<file>|-]\n"
@ -90,7 +90,7 @@ msgstr ""
" -v, --verbose Wyświetla więcej komunikatów\n"
"\n"
#: src/tools/pw-cat.c:1091
#: src/tools/pw-cat.c:980
#, c-format
msgid ""
" -R, --remote Remote daemon name\n"
@ -128,7 +128,7 @@ msgstr ""
" -P --properties Ustawia właściwości węzła\n"
"\n"
#: src/tools/pw-cat.c:1109
#: src/tools/pw-cat.c:998
#, c-format
msgid ""
" --rate Sample rate (req. for rec) (default "
@ -146,9 +146,6 @@ msgid ""
" -q --quality Resampler quality (0 - 15) (default "
"%d)\n"
" -a, --raw RAW mode\n"
" -M, --force-midi Force midi format, one of \"midi\" "
"or \"ump\", (default ump)\n"
" -n, --sample-count COUNT Stop after COUNT samples\n"
"\n"
msgstr ""
" --rate Częstotliwość próbki (wymagane do "
@ -167,21 +164,15 @@ msgstr ""
" -q --quality Jakość resamplera od 0 do 15 "
"(domyślnie %d)\n"
" -a, --raw Tryb RAW\n"
" -M, --force-midi Wymusza format MIDI, można użyć "
"„midi”\n"
" albo „ump” (domyślnie ump)\n"
" -n, --sample-count LICZBA Zatrzymuje po LICZBIE próbek\n"
"\n"
#: src/tools/pw-cat.c:1129
#: src/tools/pw-cat.c:1016
msgid ""
" -p, --playback Playback mode\n"
" -r, --record Recording mode\n"
" -m, --midi Midi mode\n"
" -d, --dsd DSD mode\n"
" -o, --encoded Encoded mode\n"
" -s, --sysex SysEx mode\n"
" -c, --midi-clip MIDI clip mode\n"
"\n"
msgstr ""
" -p, --playback Tryb odtwarzania\n"
@ -189,11 +180,9 @@ msgstr ""
" -m, --midi Tryb MIDI\n"
" -d, --dsd Tryb DSD\n"
" -o, --encoded Tryb zakodowany\n"
" -s, --sysex Tryb SysEx\n"
" -c, --midi-clip Tryb klipu MIDI\n"
"\n"
#: src/tools/pw-cli.c:2386
#: src/tools/pw-cli.c:2306
#, c-format
msgid ""
"%s [options] [command]\n"
@ -213,20 +202,15 @@ msgstr ""
" -m, --monitor Monitoruje aktywność\n"
"\n"
#: spa/plugins/alsa/acp/acp.c:351
#: spa/plugins/alsa/acp/acp.c:347
msgid "Pro Audio"
msgstr "Dźwięk w zastosowaniach profesjonalnych"
#: spa/plugins/alsa/acp/acp.c:527 spa/plugins/alsa/acp/alsa-mixer.c:4635
#: spa/plugins/bluez5/bluez5-device.c:1974
#: spa/plugins/alsa/acp/acp.c:507 spa/plugins/alsa/acp/alsa-mixer.c:4635
#: spa/plugins/bluez5/bluez5-device.c:1795
msgid "Off"
msgstr "Wyłączone"
#: spa/plugins/alsa/acp/acp.c:610
#, c-format
msgid "%s [ALSA UCM error]"
msgstr "%s [błąd UCM biblioteki ALSA]"
#: spa/plugins/alsa/acp/alsa-mixer.c:2652
msgid "Input"
msgstr "Wejście"
@ -250,7 +234,7 @@ msgstr "Wejście liniowe"
#: spa/plugins/alsa/acp/alsa-mixer.c:2657
#: spa/plugins/alsa/acp/alsa-mixer.c:2741
#: spa/plugins/bluez5/bluez5-device.c:2372
#: spa/plugins/bluez5/bluez5-device.c:2139
msgid "Microphone"
msgstr "Mikrofon"
@ -316,15 +300,12 @@ msgid "No Bass Boost"
msgstr "Brak podbicia basów"
#: spa/plugins/alsa/acp/alsa-mixer.c:2672
#: spa/plugins/bluez5/bluez5-device.c:2378
#: spa/plugins/bluez5/bluez5-device.c:2145
msgid "Speaker"
msgstr "Głośnik"
#. Don't call it "headset", the HF one has the mic
#: spa/plugins/alsa/acp/alsa-mixer.c:2673
#: spa/plugins/alsa/acp/alsa-mixer.c:2751
#: spa/plugins/bluez5/bluez5-device.c:2384
#: spa/plugins/bluez5/bluez5-device.c:2451
msgid "Headphones"
msgstr "Słuchawki"
@ -434,7 +415,7 @@ msgstr "Stereo"
#: spa/plugins/alsa/acp/alsa-mixer.c:4471
#: spa/plugins/alsa/acp/alsa-mixer.c:4629
#: spa/plugins/bluez5/bluez5-device.c:2360
#: spa/plugins/bluez5/bluez5-device.c:2127
msgid "Headset"
msgstr "Słuchawki z mikrofonem"
@ -650,108 +631,112 @@ msgstr[2] ""
msgid "(invalid)"
msgstr "(nieprawidłowe)"
#: spa/plugins/alsa/acp/compat.c:194
#: spa/plugins/alsa/acp/compat.c:193
msgid "Built-in Audio"
msgstr "Wbudowany dźwięk"
#: spa/plugins/alsa/acp/compat.c:199
#: spa/plugins/alsa/acp/compat.c:198
msgid "Modem"
msgstr "Modem"
#: spa/plugins/bluez5/bluez5-device.c:1985
#: spa/plugins/bluez5/bluez5-device.c:1806
msgid "Audio Gateway (A2DP Source & HSP/HFP AG)"
msgstr "Bramka dźwięku (źródło A2DP i AG HSP/HFP)"
#: spa/plugins/bluez5/bluez5-device.c:2014
#: spa/plugins/bluez5/bluez5-device.c:1834
msgid "Audio Streaming for Hearing Aids (ASHA Sink)"
msgstr "Przesyłanie dźwięku do aparatów słuchowych (odpływ ASHA)"
#: spa/plugins/bluez5/bluez5-device.c:2057
#: spa/plugins/bluez5/bluez5-device.c:1874
#, c-format
msgid "High Fidelity Playback (A2DP Sink, codec %s)"
msgstr "Odtwarzanie o wysokiej dokładności (odpływ A2DP, kodek %s)"
#: spa/plugins/bluez5/bluez5-device.c:2060
#: spa/plugins/bluez5/bluez5-device.c:1877
#, c-format
msgid "High Fidelity Duplex (A2DP Source/Sink, codec %s)"
msgstr "Dupleks o wysokiej dokładności (źródło/odpływ A2DP, kodek %s)"
#: spa/plugins/bluez5/bluez5-device.c:2068
#: spa/plugins/bluez5/bluez5-device.c:1885
msgid "High Fidelity Playback (A2DP Sink)"
msgstr "Odtwarzanie o wysokiej dokładności (odpływ A2DP)"
#: spa/plugins/bluez5/bluez5-device.c:2070
#: spa/plugins/bluez5/bluez5-device.c:1887
msgid "High Fidelity Duplex (A2DP Source/Sink)"
msgstr "Dupleks o wysokiej dokładności (źródło/odpływ A2DP)"
#: spa/plugins/bluez5/bluez5-device.c:2144
#: spa/plugins/bluez5/bluez5-device.c:1937
#, c-format
msgid "High Fidelity Playback (BAP Sink, codec %s)"
msgstr "Odtwarzanie o wysokiej dokładności (odpływ BAP, kodek %s)"
#: spa/plugins/bluez5/bluez5-device.c:2149
#: spa/plugins/bluez5/bluez5-device.c:1942
#, c-format
msgid "High Fidelity Input (BAP Source, codec %s)"
msgstr "Wejście o wysokiej dokładności (źródło BAP, kodek %s)"
#: spa/plugins/bluez5/bluez5-device.c:2153
#: spa/plugins/bluez5/bluez5-device.c:1946
#, c-format
msgid "High Fidelity Duplex (BAP Source/Sink, codec %s)"
msgstr "Dupleks o wysokiej dokładności (źródło/odpływ BAP, kodek %s)"
#: spa/plugins/bluez5/bluez5-device.c:2162
#: spa/plugins/bluez5/bluez5-device.c:1955
msgid "High Fidelity Playback (BAP Sink)"
msgstr "Odtwarzanie o wysokiej dokładności (odpływ BAP)"
#: spa/plugins/bluez5/bluez5-device.c:2166
#: spa/plugins/bluez5/bluez5-device.c:1959
msgid "High Fidelity Input (BAP Source)"
msgstr "Wejście o wysokiej dokładności (źródło BAP)"
#: spa/plugins/bluez5/bluez5-device.c:2169
#: spa/plugins/bluez5/bluez5-device.c:1962
msgid "High Fidelity Duplex (BAP Source/Sink)"
msgstr "Dupleks o wysokiej dokładności (źródło/odpływ BAP)"
#: spa/plugins/bluez5/bluez5-device.c:2209
#: spa/plugins/bluez5/bluez5-device.c:2008
#, c-format
msgid "Headset Head Unit (HSP/HFP, codec %s)"
msgstr "Jednostka główna słuchawek z mikrofonem (HSP/HFP, kodek %s)"
#: spa/plugins/bluez5/bluez5-device.c:2361
#: spa/plugins/bluez5/bluez5-device.c:2366
#: spa/plugins/bluez5/bluez5-device.c:2373
#: spa/plugins/bluez5/bluez5-device.c:2379
#: spa/plugins/bluez5/bluez5-device.c:2385
#: spa/plugins/bluez5/bluez5-device.c:2391
#: spa/plugins/bluez5/bluez5-device.c:2397
#: spa/plugins/bluez5/bluez5-device.c:2403
#: spa/plugins/bluez5/bluez5-device.c:2409
#: spa/plugins/bluez5/bluez5-device.c:2128
#: spa/plugins/bluez5/bluez5-device.c:2133
#: spa/plugins/bluez5/bluez5-device.c:2140
#: spa/plugins/bluez5/bluez5-device.c:2146
#: spa/plugins/bluez5/bluez5-device.c:2152
#: spa/plugins/bluez5/bluez5-device.c:2158
#: spa/plugins/bluez5/bluez5-device.c:2164
#: spa/plugins/bluez5/bluez5-device.c:2170
#: spa/plugins/bluez5/bluez5-device.c:2176
msgid "Handsfree"
msgstr "Zestaw głośnomówiący"
#: spa/plugins/bluez5/bluez5-device.c:2367
#: spa/plugins/bluez5/bluez5-device.c:2134
msgid "Handsfree (HFP)"
msgstr "Zestaw głośnomówiący (HFP)"
#: spa/plugins/bluez5/bluez5-device.c:2390
#: spa/plugins/bluez5/bluez5-device.c:2151
msgid "Headphone"
msgstr "Słuchawki"
#: spa/plugins/bluez5/bluez5-device.c:2157
msgid "Portable"
msgstr "Przenośne"
#: spa/plugins/bluez5/bluez5-device.c:2396
#: spa/plugins/bluez5/bluez5-device.c:2163
msgid "Car"
msgstr "Samochód"
#: spa/plugins/bluez5/bluez5-device.c:2402
#: spa/plugins/bluez5/bluez5-device.c:2169
msgid "HiFi"
msgstr "HiFi"
#: spa/plugins/bluez5/bluez5-device.c:2408
#: spa/plugins/bluez5/bluez5-device.c:2175
msgid "Phone"
msgstr "Telefon"
#: spa/plugins/bluez5/bluez5-device.c:2415
#: spa/plugins/bluez5/bluez5-device.c:2182
msgid "Bluetooth"
msgstr "Bluetooth"
#: spa/plugins/bluez5/bluez5-device.c:2416
#: spa/plugins/bluez5/bluez5-device.c:2183
msgid "Bluetooth (HFP)"
msgstr "Bluetooth (HFP)"

137
po/sl.po
View file

@ -9,16 +9,16 @@ msgstr ""
"Project-Id-Version: PipeWire master\n"
"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/-/"
"issues\n"
"POT-Creation-Date: 2025-09-11 03:34+0000\n"
"PO-Revision-Date: 2025-09-11 11:47+0200\n"
"POT-Creation-Date: 2025-01-09 15:25+0000\n"
"PO-Revision-Date: 2025-01-23 09:23+0100\n"
"Last-Translator: Martin Srebotnjak <miles@filmsi.net>\n"
"Language-Team: Slovenian <gnome-si@googlegroups.com>\n"
"Language: sl\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100>=3 && "
"n%100<=4 ? 2 : 3);\n"
"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100>=3 && n"
"%100<=4 ? 2 : 3);\n"
"X-Generator: Poedit 2.2.1\n"
#: src/daemon/pipewire.c:29
@ -37,13 +37,13 @@ msgstr ""
" --version Pokaži različico\n"
" -c, --config Naloži prilagoditev config (privzeto "
"%s)\n"
" -P --properties Določi lastnosti konteksta\n"
" -P properties Določi lastnosti konteksta\n"
#: src/daemon/pipewire.desktop.in:3
#: src/daemon/pipewire.desktop.in:4
msgid "PipeWire Media System"
msgstr "Medijski sistem PipeWire"
#: src/daemon/pipewire.desktop.in:4
#: src/daemon/pipewire.desktop.in:5
msgid "Start the PipeWire Media System"
msgstr "Zaženite medijski sistem PipeWire"
@ -76,7 +76,7 @@ msgstr "%s na %s@%s"
msgid "%s on %s"
msgstr "%s na %s"
#: src/tools/pw-cat.c:1084
#: src/tools/pw-cat.c:973
#, c-format
msgid ""
"%s [options] [<file>|-]\n"
@ -92,7 +92,7 @@ msgstr ""
"\n"
"</file>\n"
#: src/tools/pw-cat.c:1091
#: src/tools/pw-cat.c:980
#, c-format
msgid ""
" -R, --remote Remote daemon name\n"
@ -129,7 +129,7 @@ msgstr ""
" -P --properties Nastavi lastnosti vozlišča\n"
"\n"
#: src/tools/pw-cat.c:1109
#: src/tools/pw-cat.c:998
#, c-format
msgid ""
" --rate Sample rate (req. for rec) (default "
@ -147,17 +147,14 @@ msgid ""
" -q --quality Resampler quality (0 - 15) (default "
"%d)\n"
" -a, --raw RAW mode\n"
" -M, --force-midi Force midi format, one of \"midi\" "
"or \"ump\", (default ump)\n"
" -n, --sample-count COUNT Stop after COUNT samples\n"
"\n"
msgstr ""
" --rate Mera vzorčenja (zaht. za rec) "
"(privzeto %u)\n"
" --channels Število kanalov (zaht. za snemanje) "
" --rate Mera vzorčenja (zahtevano za rec) "
"(privzeto %u)\n"
" --channels Število kanalov (zahteva za "
"snemanje) (privzeto %u)\n"
" --channel-map Preslikava kanalov\n"
" Ena izmed: \"stereo\", "
" Ena izmed: \"Stereo\", "
"\"surround-51\",... ali\n"
" seznam imen kanalov, ločen z "
"vejico: npr. \"FL,FR\"\n"
@ -167,20 +164,16 @@ msgstr ""
" -q --quality Kakovost prevzorčenja (0 - 15) "
"(privzeto %d)\n"
" -a, --raw neobdelan način (RAW)\n"
" -M, --force-midi Vsili zapis midi, eden izmed "
"\"midi\" ali \"ump\" (privzeto ump)\n"
" -n, --sample-count ŠTEVEC Ustavi po ŠTEVEC vzorcih\n"
"\n"
"\n"
#: src/tools/pw-cat.c:1129
#: src/tools/pw-cat.c:1016
msgid ""
" -p, --playback Playback mode\n"
" -r, --record Recording mode\n"
" -m, --midi Midi mode\n"
" -d, --dsd DSD mode\n"
" -o, --encoded Encoded mode\n"
" -s, --sysex SysEx mode\n"
" -c, --midi-clip MIDI clip mode\n"
"\n"
msgstr ""
" -p, --playback Način predvajanja\n"
@ -188,11 +181,9 @@ msgstr ""
" -m, --midi Midi način\n"
" -d, --dsd Način DSD\n"
" -o, --encoded Kodiran način\n"
" -s, --sysex Način SysEx\n"
" -c, --midi-clip Način posnetka MIDI\n"
"\n"
#: src/tools/pw-cli.c:2386
#: src/tools/pw-cli.c:2306
#, c-format
msgid ""
"%s [options] [command]\n"
@ -212,20 +203,15 @@ msgstr ""
" -m, --monitor Spremljaj dejavnosti\n"
"\n"
#: spa/plugins/alsa/acp/acp.c:351
#: spa/plugins/alsa/acp/acp.c:347
msgid "Pro Audio"
msgstr "Profesionalni zvok"
#: spa/plugins/alsa/acp/acp.c:527 spa/plugins/alsa/acp/alsa-mixer.c:4635
#: spa/plugins/bluez5/bluez5-device.c:1974
#: spa/plugins/alsa/acp/acp.c:507 spa/plugins/alsa/acp/alsa-mixer.c:4635
#: spa/plugins/bluez5/bluez5-device.c:1795
msgid "Off"
msgstr "Izklopljeno"
#: spa/plugins/alsa/acp/acp.c:610
#, c-format
msgid "%s [ALSA UCM error]"
msgstr "%s [napaka ALSA UCM]"
#: spa/plugins/alsa/acp/alsa-mixer.c:2652
msgid "Input"
msgstr "Vhod"
@ -249,7 +235,7 @@ msgstr "Linijski vhod"
#: spa/plugins/alsa/acp/alsa-mixer.c:2657
#: spa/plugins/alsa/acp/alsa-mixer.c:2741
#: spa/plugins/bluez5/bluez5-device.c:2372
#: spa/plugins/bluez5/bluez5-device.c:2139
msgid "Microphone"
msgstr "Mikrofon"
@ -315,15 +301,12 @@ msgid "No Bass Boost"
msgstr "Brez ojačitve nizkih tonov"
#: spa/plugins/alsa/acp/alsa-mixer.c:2672
#: spa/plugins/bluez5/bluez5-device.c:2378
#: spa/plugins/bluez5/bluez5-device.c:2145
msgid "Speaker"
msgstr "Zvočnik"
#. Don't call it "headset", the HF one has the mic
#: spa/plugins/alsa/acp/alsa-mixer.c:2673
#: spa/plugins/alsa/acp/alsa-mixer.c:2751
#: spa/plugins/bluez5/bluez5-device.c:2384
#: spa/plugins/bluez5/bluez5-device.c:2451
msgid "Headphones"
msgstr "Slušalke"
@ -433,7 +416,7 @@ msgstr "Stereo"
#: spa/plugins/alsa/acp/alsa-mixer.c:4471
#: spa/plugins/alsa/acp/alsa-mixer.c:4629
#: spa/plugins/bluez5/bluez5-device.c:2360
#: spa/plugins/bluez5/bluez5-device.c:2127
msgid "Headset"
msgstr "Slušalka"
@ -592,13 +575,13 @@ msgstr[3] ""
#: spa/plugins/alsa/acp/alsa-util.c:1299
#, c-format
msgid ""
"snd_pcm_delay() returned a value that is exceptionally large: %li byte "
"(%s%lu ms).\n"
"snd_pcm_delay() returned a value that is exceptionally large: %li byte (%s"
"%lu ms).\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
"to the ALSA developers."
msgid_plural ""
"snd_pcm_delay() returned a value that is exceptionally large: %li bytes "
"(%s%lu ms).\n"
"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s"
"%lu ms).\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
"to the ALSA developers."
msgstr[0] ""
@ -672,108 +655,112 @@ msgstr[3] ""
msgid "(invalid)"
msgstr "(neveljavno)"
#: spa/plugins/alsa/acp/compat.c:194
#: spa/plugins/alsa/acp/compat.c:193
msgid "Built-in Audio"
msgstr "Vgrajen zvok"
#: spa/plugins/alsa/acp/compat.c:199
#: spa/plugins/alsa/acp/compat.c:198
msgid "Modem"
msgstr "Modem"
#: spa/plugins/bluez5/bluez5-device.c:1985
#: spa/plugins/bluez5/bluez5-device.c:1806
msgid "Audio Gateway (A2DP Source & HSP/HFP AG)"
msgstr "Zvožni prehod (vir A2DP in HSP/HFP AG)"
#: spa/plugins/bluez5/bluez5-device.c:2014
#: spa/plugins/bluez5/bluez5-device.c:1834
msgid "Audio Streaming for Hearing Aids (ASHA Sink)"
msgstr "Pretakanje zvoka za slušne aparate (ponor ASHA)"
#: spa/plugins/bluez5/bluez5-device.c:2057
#: spa/plugins/bluez5/bluez5-device.c:1874
#, c-format
msgid "High Fidelity Playback (A2DP Sink, codec %s)"
msgstr "Predvajanje visoke ločljivosti (ponor A2DP, kodek %s)"
#: spa/plugins/bluez5/bluez5-device.c:2060
#: spa/plugins/bluez5/bluez5-device.c:1877
#, c-format
msgid "High Fidelity Duplex (A2DP Source/Sink, codec %s)"
msgstr "Dupleks visoke ločljivosti (vir/ponor A2DP, kodek %s)"
#: spa/plugins/bluez5/bluez5-device.c:2068
#: spa/plugins/bluez5/bluez5-device.c:1885
msgid "High Fidelity Playback (A2DP Sink)"
msgstr "Predvajanje visoke ločljivosti (ponor A2DP)"
#: spa/plugins/bluez5/bluez5-device.c:2070
#: spa/plugins/bluez5/bluez5-device.c:1887
msgid "High Fidelity Duplex (A2DP Source/Sink)"
msgstr "Dupleks visoke ločljivosti (vir/ponor A2DP)"
#: spa/plugins/bluez5/bluez5-device.c:2144
#: spa/plugins/bluez5/bluez5-device.c:1937
#, c-format
msgid "High Fidelity Playback (BAP Sink, codec %s)"
msgstr "Predvajanje visoke ločljivosti (ponor BAP, kodek %s)"
#: spa/plugins/bluez5/bluez5-device.c:2149
#: spa/plugins/bluez5/bluez5-device.c:1942
#, c-format
msgid "High Fidelity Input (BAP Source, codec %s)"
msgstr "Vhod visoke ločljivosti (vir BAP, kodek %s)"
#: spa/plugins/bluez5/bluez5-device.c:2153
#: spa/plugins/bluez5/bluez5-device.c:1946
#, c-format
msgid "High Fidelity Duplex (BAP Source/Sink, codec %s)"
msgstr "Dupleks visoke ločljivosti (vir/ponor BAP, kodek %s)"
#: spa/plugins/bluez5/bluez5-device.c:2162
#: spa/plugins/bluez5/bluez5-device.c:1955
msgid "High Fidelity Playback (BAP Sink)"
msgstr "Predvajanje visoke ločljivosti (ponor BAP)"
#: spa/plugins/bluez5/bluez5-device.c:2166
#: spa/plugins/bluez5/bluez5-device.c:1959
msgid "High Fidelity Input (BAP Source)"
msgstr "Vhod visoke ločljivosti (vir BAP)"
#: spa/plugins/bluez5/bluez5-device.c:2169
#: spa/plugins/bluez5/bluez5-device.c:1962
msgid "High Fidelity Duplex (BAP Source/Sink)"
msgstr "Dupleks visoke ločljivosti (vir/ponor BAP)"
#: spa/plugins/bluez5/bluez5-device.c:2209
#: spa/plugins/bluez5/bluez5-device.c:2008
#, c-format
msgid "Headset Head Unit (HSP/HFP, codec %s)"
msgstr "Naglavna enota slušalk (HSP/HFP, kodek %s)"
#: spa/plugins/bluez5/bluez5-device.c:2361
#: spa/plugins/bluez5/bluez5-device.c:2366
#: spa/plugins/bluez5/bluez5-device.c:2373
#: spa/plugins/bluez5/bluez5-device.c:2379
#: spa/plugins/bluez5/bluez5-device.c:2385
#: spa/plugins/bluez5/bluez5-device.c:2391
#: spa/plugins/bluez5/bluez5-device.c:2397
#: spa/plugins/bluez5/bluez5-device.c:2403
#: spa/plugins/bluez5/bluez5-device.c:2409
#: spa/plugins/bluez5/bluez5-device.c:2128
#: spa/plugins/bluez5/bluez5-device.c:2133
#: spa/plugins/bluez5/bluez5-device.c:2140
#: spa/plugins/bluez5/bluez5-device.c:2146
#: spa/plugins/bluez5/bluez5-device.c:2152
#: spa/plugins/bluez5/bluez5-device.c:2158
#: spa/plugins/bluez5/bluez5-device.c:2164
#: spa/plugins/bluez5/bluez5-device.c:2170
#: spa/plugins/bluez5/bluez5-device.c:2176
msgid "Handsfree"
msgstr "Prostoročno telefoniranje"
#: spa/plugins/bluez5/bluez5-device.c:2367
#: spa/plugins/bluez5/bluez5-device.c:2134
msgid "Handsfree (HFP)"
msgstr "Prostoročno telefoniranje (HFP)"
#: spa/plugins/bluez5/bluez5-device.c:2390
#: spa/plugins/bluez5/bluez5-device.c:2151
msgid "Headphone"
msgstr "Slušalke"
#: spa/plugins/bluez5/bluez5-device.c:2157
msgid "Portable"
msgstr "Prenosna naprava"
#: spa/plugins/bluez5/bluez5-device.c:2396
#: spa/plugins/bluez5/bluez5-device.c:2163
msgid "Car"
msgstr "Avtomobil"
#: spa/plugins/bluez5/bluez5-device.c:2402
#: spa/plugins/bluez5/bluez5-device.c:2169
msgid "HiFi"
msgstr "HiFi"
#: spa/plugins/bluez5/bluez5-device.c:2408
#: spa/plugins/bluez5/bluez5-device.c:2175
msgid "Phone"
msgstr "Telefon"
#: spa/plugins/bluez5/bluez5-device.c:2415
#: spa/plugins/bluez5/bluez5-device.c:2182
msgid "Bluetooth"
msgstr "Bluetooth"
#: spa/plugins/bluez5/bluez5-device.c:2416
#: spa/plugins/bluez5/bluez5-device.c:2183
msgid "Bluetooth (HFP)"
msgstr "Bluetooth (HFP)"

183
po/sv.po
View file

@ -1,9 +1,9 @@
# Swedish translation for pipewire.
# Copyright © 2008-2025 Free Software Foundation, Inc.
# Copyright © 2008-2024 Free Software Foundation, Inc.
# This file is distributed under the same license as the pipewire package.
# Daniel Nylander <po@danielnylander.se>, 2008, 2012.
# Josef Andersson <josef.andersson@fripost.org>, 2014, 2017.
# Anders Jonsson <anders.jonsson@norsjovallen.se>, 2021, 2022, 2023, 2024, 2025.
# Anders Jonsson <anders.jonsson@norsjovallen.se>, 2021, 2022, 2023, 2024.
#
# Termer:
# input/output: ingång/utgång (det handlar om ljud)
@ -19,8 +19,8 @@ msgstr ""
"Project-Id-Version: pipewire\n"
"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/-/"
"issues\n"
"POT-Creation-Date: 2025-04-16 15:31+0000\n"
"PO-Revision-Date: 2025-04-22 10:43+0200\n"
"POT-Creation-Date: 2024-11-05 03:27+0000\n"
"PO-Revision-Date: 2024-11-07 21:52+0100\n"
"Last-Translator: Anders Jonsson <anders.jonsson@norsjovallen.se>\n"
"Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
"Language: sv\n"
@ -65,7 +65,7 @@ msgstr "Tunnel till %s%s%s"
msgid "Dummy Output"
msgstr "Attrapputgång"
#: src/modules/module-pulse-tunnel.c:760
#: src/modules/module-pulse-tunnel.c:777
#, c-format
msgid "Tunnel for %s@%s"
msgstr "Tunnel för %s@%s"
@ -184,7 +184,7 @@ msgstr ""
" -o, --encoded Kodat läge\n"
"\n"
#: src/tools/pw-cli.c:2306
#: src/tools/pw-cli.c:2318
#, c-format
msgid ""
"%s [options] [command]\n"
@ -198,25 +198,20 @@ msgstr ""
"%s [flaggor] [kommando]\n"
" -h, --help Visa denna hjälp\n"
" --version Show version\n"
" -d, --daemon Starta som demon (standard false)\n"
" -d, --daemon Starta som demon (Standard false)\n"
" -r, --remote Fjärrdemonnamn\n"
" -m, --monitor Övervaka aktivitet\n"
"\n"
#: spa/plugins/alsa/acp/acp.c:350
#: spa/plugins/alsa/acp/acp.c:327
msgid "Pro Audio"
msgstr "Professionellt ljud"
#: spa/plugins/alsa/acp/acp.c:511 spa/plugins/alsa/acp/alsa-mixer.c:4635
#: spa/plugins/bluez5/bluez5-device.c:1802
#: spa/plugins/alsa/acp/acp.c:487 spa/plugins/alsa/acp/alsa-mixer.c:4633
#: spa/plugins/bluez5/bluez5-device.c:1705
msgid "Off"
msgstr "Av"
#: spa/plugins/alsa/acp/acp.c:593
#, c-format
msgid "%s [ALSA UCM error]"
msgstr "%s [ALSA UCM-fel]"
#: spa/plugins/alsa/acp/alsa-mixer.c:2652
msgid "Input"
msgstr "Ingång"
@ -240,7 +235,7 @@ msgstr "Linje in"
#: spa/plugins/alsa/acp/alsa-mixer.c:2657
#: spa/plugins/alsa/acp/alsa-mixer.c:2741
#: spa/plugins/bluez5/bluez5-device.c:2146
#: spa/plugins/bluez5/bluez5-device.c:2026
msgid "Microphone"
msgstr "Mikrofon"
@ -306,7 +301,7 @@ msgid "No Bass Boost"
msgstr "Ingen basökning"
#: spa/plugins/alsa/acp/alsa-mixer.c:2672
#: spa/plugins/bluez5/bluez5-device.c:2152
#: spa/plugins/bluez5/bluez5-device.c:2032
msgid "Speaker"
msgstr "Högtalare"
@ -388,15 +383,15 @@ msgstr "Chatt-ingång"
msgid "Virtual Surround 7.1"
msgstr "Virtual surround 7.1"
#: spa/plugins/alsa/acp/alsa-mixer.c:4458
#: spa/plugins/alsa/acp/alsa-mixer.c:4456
msgid "Analog Mono"
msgstr "Analog mono"
#: spa/plugins/alsa/acp/alsa-mixer.c:4459
#: spa/plugins/alsa/acp/alsa-mixer.c:4457
msgid "Analog Mono (Left)"
msgstr "Analog mono (vänster)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4460
#: spa/plugins/alsa/acp/alsa-mixer.c:4458
msgid "Analog Mono (Right)"
msgstr "Analog mono (höger)"
@ -405,147 +400,147 @@ msgstr "Analog mono (höger)"
#. * here would lead to the source name to become "Analog Stereo Input
#. * Input". The same logic applies to analog-stereo-output,
#. * multichannel-input and multichannel-output.
#: spa/plugins/alsa/acp/alsa-mixer.c:4461
#: spa/plugins/alsa/acp/alsa-mixer.c:4469
#: spa/plugins/alsa/acp/alsa-mixer.c:4470
#: spa/plugins/alsa/acp/alsa-mixer.c:4459
#: spa/plugins/alsa/acp/alsa-mixer.c:4467
#: spa/plugins/alsa/acp/alsa-mixer.c:4468
msgid "Analog Stereo"
msgstr "Analog stereo"
#: spa/plugins/alsa/acp/alsa-mixer.c:4462
#: spa/plugins/alsa/acp/alsa-mixer.c:4460
msgid "Mono"
msgstr "Mono"
#: spa/plugins/alsa/acp/alsa-mixer.c:4463
#: spa/plugins/alsa/acp/alsa-mixer.c:4461
msgid "Stereo"
msgstr "Stereo"
#: spa/plugins/alsa/acp/alsa-mixer.c:4471
#: spa/plugins/alsa/acp/alsa-mixer.c:4629
#: spa/plugins/bluez5/bluez5-device.c:2134
#: spa/plugins/alsa/acp/alsa-mixer.c:4469
#: spa/plugins/alsa/acp/alsa-mixer.c:4627
#: spa/plugins/bluez5/bluez5-device.c:2014
msgid "Headset"
msgstr "Headset"
#: spa/plugins/alsa/acp/alsa-mixer.c:4472
#: spa/plugins/alsa/acp/alsa-mixer.c:4630
#: spa/plugins/alsa/acp/alsa-mixer.c:4470
#: spa/plugins/alsa/acp/alsa-mixer.c:4628
msgid "Speakerphone"
msgstr "Högtalartelefon"
#: spa/plugins/alsa/acp/alsa-mixer.c:4473
#: spa/plugins/alsa/acp/alsa-mixer.c:4474
#: spa/plugins/alsa/acp/alsa-mixer.c:4471
#: spa/plugins/alsa/acp/alsa-mixer.c:4472
msgid "Multichannel"
msgstr "Multikanal"
#: spa/plugins/alsa/acp/alsa-mixer.c:4475
#: spa/plugins/alsa/acp/alsa-mixer.c:4473
msgid "Analog Surround 2.1"
msgstr "Analog surround 2.1"
#: spa/plugins/alsa/acp/alsa-mixer.c:4476
#: spa/plugins/alsa/acp/alsa-mixer.c:4474
msgid "Analog Surround 3.0"
msgstr "Analog surround 3.0"
#: spa/plugins/alsa/acp/alsa-mixer.c:4477
#: spa/plugins/alsa/acp/alsa-mixer.c:4475
msgid "Analog Surround 3.1"
msgstr "Analog surround 3.1"
#: spa/plugins/alsa/acp/alsa-mixer.c:4478
#: spa/plugins/alsa/acp/alsa-mixer.c:4476
msgid "Analog Surround 4.0"
msgstr "Analog surround 4.0"
#: spa/plugins/alsa/acp/alsa-mixer.c:4479
#: spa/plugins/alsa/acp/alsa-mixer.c:4477
msgid "Analog Surround 4.1"
msgstr "Analog surround 4.1"
#: spa/plugins/alsa/acp/alsa-mixer.c:4480
#: spa/plugins/alsa/acp/alsa-mixer.c:4478
msgid "Analog Surround 5.0"
msgstr "Analog surround 5.0"
#: spa/plugins/alsa/acp/alsa-mixer.c:4481
#: spa/plugins/alsa/acp/alsa-mixer.c:4479
msgid "Analog Surround 5.1"
msgstr "Analog surround 5.1"
#: spa/plugins/alsa/acp/alsa-mixer.c:4482
#: spa/plugins/alsa/acp/alsa-mixer.c:4480
msgid "Analog Surround 6.0"
msgstr "Analog surround 6.0"
#: spa/plugins/alsa/acp/alsa-mixer.c:4483
#: spa/plugins/alsa/acp/alsa-mixer.c:4481
msgid "Analog Surround 6.1"
msgstr "Analog surround 6.1"
#: spa/plugins/alsa/acp/alsa-mixer.c:4484
#: spa/plugins/alsa/acp/alsa-mixer.c:4482
msgid "Analog Surround 7.0"
msgstr "Analog surround 7.0"
#: spa/plugins/alsa/acp/alsa-mixer.c:4485
#: spa/plugins/alsa/acp/alsa-mixer.c:4483
msgid "Analog Surround 7.1"
msgstr "Analog surround 7.1"
#: spa/plugins/alsa/acp/alsa-mixer.c:4486
#: spa/plugins/alsa/acp/alsa-mixer.c:4484
msgid "Digital Stereo (IEC958)"
msgstr "Digital stereo (IEC958)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4487
#: spa/plugins/alsa/acp/alsa-mixer.c:4485
msgid "Digital Surround 4.0 (IEC958/AC3)"
msgstr "Digital surround 4.0 (IEC958/AC3)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4488
#: spa/plugins/alsa/acp/alsa-mixer.c:4486
msgid "Digital Surround 5.1 (IEC958/AC3)"
msgstr "Digital surround 5.1 (IEC958/AC3)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4489
#: spa/plugins/alsa/acp/alsa-mixer.c:4487
msgid "Digital Surround 5.1 (IEC958/DTS)"
msgstr "Digital surround 5.1 (IEC958/DTS)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4490
#: spa/plugins/alsa/acp/alsa-mixer.c:4488
msgid "Digital Stereo (HDMI)"
msgstr "Digital stereo (HDMI)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4491
#: spa/plugins/alsa/acp/alsa-mixer.c:4489
msgid "Digital Surround 5.1 (HDMI)"
msgstr "Digital surround 5.1 (HDMI)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4492
#: spa/plugins/alsa/acp/alsa-mixer.c:4490
msgid "Chat"
msgstr "Chatt"
#: spa/plugins/alsa/acp/alsa-mixer.c:4493
#: spa/plugins/alsa/acp/alsa-mixer.c:4491
msgid "Game"
msgstr "Spel"
#: spa/plugins/alsa/acp/alsa-mixer.c:4627
#: spa/plugins/alsa/acp/alsa-mixer.c:4625
msgid "Analog Mono Duplex"
msgstr "Analog mono duplex"
#: spa/plugins/alsa/acp/alsa-mixer.c:4628
#: spa/plugins/alsa/acp/alsa-mixer.c:4626
msgid "Analog Stereo Duplex"
msgstr "Analog stereo duplex"
#: spa/plugins/alsa/acp/alsa-mixer.c:4631
#: spa/plugins/alsa/acp/alsa-mixer.c:4629
msgid "Digital Stereo Duplex (IEC958)"
msgstr "Digital stereo duplex (IEC958)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4632
#: spa/plugins/alsa/acp/alsa-mixer.c:4630
msgid "Multichannel Duplex"
msgstr "Multikanalduplex"
#: spa/plugins/alsa/acp/alsa-mixer.c:4633
#: spa/plugins/alsa/acp/alsa-mixer.c:4631
msgid "Stereo Duplex"
msgstr "Stereo duplex"
#: spa/plugins/alsa/acp/alsa-mixer.c:4634
#: spa/plugins/alsa/acp/alsa-mixer.c:4632
msgid "Mono Chat + 7.1 Surround"
msgstr "Mono Chatt + 7.1 Surround"
#: spa/plugins/alsa/acp/alsa-mixer.c:4735
#: spa/plugins/alsa/acp/alsa-mixer.c:4733
#, c-format
msgid "%s Output"
msgstr "%s-utgång"
#: spa/plugins/alsa/acp/alsa-mixer.c:4743
#: spa/plugins/alsa/acp/alsa-mixer.c:4741
#, c-format
msgid "%s Input"
msgstr "%s-ingång"
#: spa/plugins/alsa/acp/alsa-util.c:1233 spa/plugins/alsa/acp/alsa-util.c:1327
#: spa/plugins/alsa/acp/alsa-util.c:1231 spa/plugins/alsa/acp/alsa-util.c:1325
#, c-format
msgid ""
"snd_pcm_avail() returned a value that is exceptionally large: %lu byte (%lu "
@ -568,7 +563,7 @@ msgstr[1] ""
"Förmodligen är detta ett fel i ALSA-drivrutinen ”%s”. Vänligen rapportera "
"problemet till ALSA-utvecklarna."
#: spa/plugins/alsa/acp/alsa-util.c:1299
#: spa/plugins/alsa/acp/alsa-util.c:1297
#, c-format
msgid ""
"snd_pcm_delay() returned a value that is exceptionally large: %li byte "
@ -591,7 +586,7 @@ msgstr[1] ""
"Förmodligen är detta ett fel i ALSA-drivrutinen ”%s”. Vänligen rapportera "
"problemet till ALSA-utvecklarna."
#: spa/plugins/alsa/acp/alsa-util.c:1346
#: spa/plugins/alsa/acp/alsa-util.c:1344
#, c-format
msgid ""
"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
@ -604,7 +599,7 @@ msgstr ""
"Förmodligen är detta ett fel i ALSA-drivrutinen ”%s”. Vänligen rapportera "
"problemet till ALSA-utvecklarna."
#: spa/plugins/alsa/acp/alsa-util.c:1389
#: spa/plugins/alsa/acp/alsa-util.c:1387
#, c-format
msgid ""
"snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu byte "
@ -639,104 +634,100 @@ msgstr "Inbyggt ljud"
msgid "Modem"
msgstr "Modem"
#: spa/plugins/bluez5/bluez5-device.c:1813
#: spa/plugins/bluez5/bluez5-device.c:1716
msgid "Audio Gateway (A2DP Source & HSP/HFP AG)"
msgstr "Audio gateway (A2DP-källa & HSP/HFP AG)"
#: spa/plugins/bluez5/bluez5-device.c:1841
msgid "Audio Streaming for Hearing Aids (ASHA Sink)"
msgstr "Ljudströmning för hörhjälpmedel (ASHA-utgång)"
#: spa/plugins/bluez5/bluez5-device.c:1881
#: spa/plugins/bluez5/bluez5-device.c:1764
#, c-format
msgid "High Fidelity Playback (A2DP Sink, codec %s)"
msgstr "High fidelity-uppspelning (A2DP-utgång, kodek %s)"
#: spa/plugins/bluez5/bluez5-device.c:1884
#: spa/plugins/bluez5/bluez5-device.c:1767
#, c-format
msgid "High Fidelity Duplex (A2DP Source/Sink, codec %s)"
msgstr "High fidelity duplex (A2DP-källa/utgång, kodek %s)"
#: spa/plugins/bluez5/bluez5-device.c:1892
#: spa/plugins/bluez5/bluez5-device.c:1775
msgid "High Fidelity Playback (A2DP Sink)"
msgstr "High fidelity-uppspelning (A2DP-utgång)"
#: spa/plugins/bluez5/bluez5-device.c:1894
#: spa/plugins/bluez5/bluez5-device.c:1777
msgid "High Fidelity Duplex (A2DP Source/Sink)"
msgstr "High fidelity duplex (A2DP-källa/utgång)"
#: spa/plugins/bluez5/bluez5-device.c:1944
#: spa/plugins/bluez5/bluez5-device.c:1827
#, c-format
msgid "High Fidelity Playback (BAP Sink, codec %s)"
msgstr "High fidelity-uppspelning (BAP-utgång, kodek %s)"
#: spa/plugins/bluez5/bluez5-device.c:1949
#: spa/plugins/bluez5/bluez5-device.c:1832
#, c-format
msgid "High Fidelity Input (BAP Source, codec %s)"
msgstr "High fidelity-ingång (BAP-källa, kodek %s)"
#: spa/plugins/bluez5/bluez5-device.c:1953
#: spa/plugins/bluez5/bluez5-device.c:1836
#, c-format
msgid "High Fidelity Duplex (BAP Source/Sink, codec %s)"
msgstr "High fidelity duplex (BAP-källa/utgång, kodek %s)"
#: spa/plugins/bluez5/bluez5-device.c:1962
#: spa/plugins/bluez5/bluez5-device.c:1845
msgid "High Fidelity Playback (BAP Sink)"
msgstr "High fidelity-uppspelning (BAP-utgång)"
#: spa/plugins/bluez5/bluez5-device.c:1966
#: spa/plugins/bluez5/bluez5-device.c:1849
msgid "High Fidelity Input (BAP Source)"
msgstr "High fidelity-ingång (BAP-källa)"
#: spa/plugins/bluez5/bluez5-device.c:1969
#: spa/plugins/bluez5/bluez5-device.c:1852
msgid "High Fidelity Duplex (BAP Source/Sink)"
msgstr "High fidelity duplex (BAP-källa/utgång)"
#: spa/plugins/bluez5/bluez5-device.c:2015
#: spa/plugins/bluez5/bluez5-device.c:1901
#, c-format
msgid "Headset Head Unit (HSP/HFP, codec %s)"
msgstr "Headset-huvudenhet (HSP/HFP, kodek %s)"
#: spa/plugins/bluez5/bluez5-device.c:2135
#: spa/plugins/bluez5/bluez5-device.c:2140
#: spa/plugins/bluez5/bluez5-device.c:2147
#: spa/plugins/bluez5/bluez5-device.c:2153
#: spa/plugins/bluez5/bluez5-device.c:2159
#: spa/plugins/bluez5/bluez5-device.c:2165
#: spa/plugins/bluez5/bluez5-device.c:2171
#: spa/plugins/bluez5/bluez5-device.c:2177
#: spa/plugins/bluez5/bluez5-device.c:2183
#: spa/plugins/bluez5/bluez5-device.c:2015
#: spa/plugins/bluez5/bluez5-device.c:2020
#: spa/plugins/bluez5/bluez5-device.c:2027
#: spa/plugins/bluez5/bluez5-device.c:2033
#: spa/plugins/bluez5/bluez5-device.c:2039
#: spa/plugins/bluez5/bluez5-device.c:2045
#: spa/plugins/bluez5/bluez5-device.c:2051
#: spa/plugins/bluez5/bluez5-device.c:2057
#: spa/plugins/bluez5/bluez5-device.c:2063
msgid "Handsfree"
msgstr "Handsfree"
#: spa/plugins/bluez5/bluez5-device.c:2141
#: spa/plugins/bluez5/bluez5-device.c:2021
msgid "Handsfree (HFP)"
msgstr "Handsfree (HFP)"
#: spa/plugins/bluez5/bluez5-device.c:2158
#: spa/plugins/bluez5/bluez5-device.c:2038
msgid "Headphone"
msgstr "Hörlurar"
#: spa/plugins/bluez5/bluez5-device.c:2164
#: spa/plugins/bluez5/bluez5-device.c:2044
msgid "Portable"
msgstr "Bärbar"
#: spa/plugins/bluez5/bluez5-device.c:2170
#: spa/plugins/bluez5/bluez5-device.c:2050
msgid "Car"
msgstr "Bil"
#: spa/plugins/bluez5/bluez5-device.c:2176
#: spa/plugins/bluez5/bluez5-device.c:2056
msgid "HiFi"
msgstr "HiFi"
#: spa/plugins/bluez5/bluez5-device.c:2182
#: spa/plugins/bluez5/bluez5-device.c:2062
msgid "Phone"
msgstr "Telefon"
#: spa/plugins/bluez5/bluez5-device.c:2189
#: spa/plugins/bluez5/bluez5-device.c:2069
msgid "Bluetooth"
msgstr "Bluetooth"
#: spa/plugins/bluez5/bluez5-device.c:2190
#: spa/plugins/bluez5/bluez5-device.c:2070
msgid "Bluetooth (HFP)"
msgstr "Bluetooth (HFP)"

341
po/tr.po
View file

@ -1,51 +1,46 @@
# Turkish translation for PipeWire.
# Copyright (C) 2014-2025 PipeWire's COPYRIGHT HOLDER
# Copyright (C) 2014-2024 PipeWire's COPYRIGHT HOLDER
# This file is distributed under the same license as the PipeWire package.
#
# Necdet Yücel <necdetyucel@gmail.com>, 2014.
# Kaan Özdinçer <kaanozdincer@gmail.com>, 2014.
# Muhammet Kara <muhammetk@gmail.com>, 2015, 2016, 2017.
# Oğuz Ersen <oguz@ersen.moe>, 2021-2022.
# Sabri Ünal <yakushabb@gmail.com>, 2024, 2025.
# Sabri Ünal <libreajans@gmail.com>, 2024.
#
msgid ""
msgstr ""
"Project-Id-Version: PipeWire master\n"
"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/-/"
"issues\n"
"POT-Creation-Date: 2025-10-24 15:37+0000\n"
"PO-Revision-Date: 2025-10-24 20:15+0300\n"
"Last-Translator: Sabri Ünal <yakushabb@gmail.com>\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-02-25 03:43+0300\n"
"PO-Revision-Date: 2024-02-25 03:49+0300\n"
"Last-Translator: Sabri Ünal <libreajans@gmail.com>\n"
"Language-Team: Türkçe <takim@gnome.org.tr>\n"
"Language: tr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Poedit 3.8\n"
"X-Generator: Poedit 3.4.2\n"
#: src/daemon/pipewire.c:29
#: src/daemon/pipewire.c:26
#, c-format
msgid ""
"%s [options]\n"
" -h, --help Show this help\n"
" -v, --verbose Increase verbosity by one level\n"
" --version Show version\n"
" -c, --config Load config (Default %s)\n"
" -P --properties Set context properties\n"
msgstr ""
"%s [seçenekler]\n"
" -h, --help Bu yardımı göster\n"
" -v, --verbose Ayrıntı düzeyini bir düzey artır\n"
" --version Sürümü göster\n"
" -c, --config Yapılandırmayı yükle (Öntanımlı %s)\n"
" -P --properties Bağlam özelliklerini ayarla\n"
#: src/daemon/pipewire.desktop.in:3
#: src/daemon/pipewire.desktop.in:4
msgid "PipeWire Media System"
msgstr "PipeWire Ortam Sistemi"
#: src/daemon/pipewire.desktop.in:4
#: src/daemon/pipewire.desktop.in:5
msgid "Start the PipeWire Media System"
msgstr "PipeWire Ortam Sistemini Başlat"
@ -59,26 +54,26 @@ msgstr "%s%s%s tüneli"
msgid "Dummy Output"
msgstr "Temsili Çıkış"
#: src/modules/module-pulse-tunnel.c:760
#: src/modules/module-pulse-tunnel.c:774
#, c-format
msgid "Tunnel for %s@%s"
msgstr "%s@%s için tünel"
#: src/modules/module-zeroconf-discover.c:320
#: src/modules/module-zeroconf-discover.c:315
msgid "Unknown device"
msgstr "Bilinmeyen aygıt"
#: src/modules/module-zeroconf-discover.c:332
#: src/modules/module-zeroconf-discover.c:327
#, c-format
msgid "%s on %s@%s"
msgstr "%s, %s@%s"
#: src/modules/module-zeroconf-discover.c:336
#: src/modules/module-zeroconf-discover.c:331
#, c-format
msgid "%s on %s"
msgstr "%s, %s"
#: src/tools/pw-cat.c:1096
#: src/tools/pw-cat.c:991
#, c-format
msgid ""
"%s [options] [<file>|-]\n"
@ -93,7 +88,7 @@ msgstr ""
" -v, --verbose Ayrıntılı işlemleri etkinleştir\n"
"\n"
#: src/tools/pw-cat.c:1103
#: src/tools/pw-cat.c:998
#, c-format
msgid ""
" -R, --remote Remote daemon name\n"
@ -127,7 +122,7 @@ msgstr ""
" -P --properties Düğüm özelliklerini ayarla\n"
"\n"
#: src/tools/pw-cat.c:1121
#: src/tools/pw-cat.c:1016
#, c-format
msgid ""
" --rate Sample rate (req. for rec) (default "
@ -144,10 +139,6 @@ msgid ""
" --volume Stream volume 0-1.0 (default %.3f)\n"
" -q --quality Resampler quality (0 - 15) (default "
"%d)\n"
" -a, --raw RAW mode\n"
" -M, --force-midi Force midi format, one of \"midi\" "
"or \"ump\", (default ump)\n"
" -n, --sample-count COUNT Stop after COUNT samples\n"
"\n"
msgstr ""
" --rate Örnekleme oranı (kayıt için gerekli) "
@ -165,21 +156,15 @@ msgstr ""
"%.3f)\n"
" -q --quality Yeniden örnekleyici kalitesi (0 - "
"15) (öntanımlı %d)\n"
" -a, --raw HAM kipi\n"
" -M, --force-midi Midi biçimini zorla, ikisinden "
"birisi \"midi\" ya da\"ump\", (öntanımlı ump)\n"
" -n, --sample-count COUNT COUNT örnekleme sonrası dur\n"
"\n"
#: src/tools/pw-cat.c:1141
#: src/tools/pw-cat.c:1033
msgid ""
" -p, --playback Playback mode\n"
" -r, --record Recording mode\n"
" -m, --midi Midi mode\n"
" -d, --dsd DSD mode\n"
" -o, --encoded Encoded mode\n"
" -s, --sysex SysEx mode\n"
" -c, --midi-clip MIDI clip mode\n"
"\n"
msgstr ""
" -p, --playback Çalma kipi\n"
@ -187,11 +172,9 @@ msgstr ""
" -m, --midi Midi kipi\n"
" -d, --dsd DSD kipi\n"
" -o, --encoded Kodlanmış kip\n"
" -s, --sysex SysEx kipi\n"
" -c, --midi-clip MIDI klip kipi\n"
"\n"
#: src/tools/pw-cli.c:2386
#: src/tools/pw-cli.c:2252
#, c-format
msgid ""
"%s [options] [command]\n"
@ -210,203 +193,195 @@ msgstr ""
" -r, --remote Uzak arka plan programı adı\n"
" -m, --monitor Etkinliği izle\n"
#: spa/plugins/alsa/acp/acp.c:361
#: spa/plugins/alsa/acp/acp.c:327
msgid "Pro Audio"
msgstr "Profesyonel Ses"
#: spa/plugins/alsa/acp/acp.c:537 spa/plugins/alsa/acp/alsa-mixer.c:4699
#: spa/plugins/bluez5/bluez5-device.c:1976
#: spa/plugins/alsa/acp/acp.c:488 spa/plugins/alsa/acp/alsa-mixer.c:4633
#: spa/plugins/bluez5/bluez5-device.c:1701
msgid "Off"
msgstr "Kapalı"
#: spa/plugins/alsa/acp/acp.c:620
#, c-format
msgid "%s [ALSA UCM error]"
msgstr "%s [ALSA UCM hatası]"
#: spa/plugins/alsa/acp/alsa-mixer.c:2721
#: spa/plugins/alsa/acp/alsa-mixer.c:2652
msgid "Input"
msgstr "Giriş"
#: spa/plugins/alsa/acp/alsa-mixer.c:2722
#: spa/plugins/alsa/acp/alsa-mixer.c:2653
msgid "Docking Station Input"
msgstr "Yerleştirme İstasyonu Girişi"
#: spa/plugins/alsa/acp/alsa-mixer.c:2723
#: spa/plugins/alsa/acp/alsa-mixer.c:2654
msgid "Docking Station Microphone"
msgstr "Yerleştirme İstasyonu Mikrofonu"
#: spa/plugins/alsa/acp/alsa-mixer.c:2724
#: spa/plugins/alsa/acp/alsa-mixer.c:2655
msgid "Docking Station Line In"
msgstr "Yerleştirme İstasyonu Hat Girişi"
#: spa/plugins/alsa/acp/alsa-mixer.c:2725
#: spa/plugins/alsa/acp/alsa-mixer.c:2816
#: spa/plugins/alsa/acp/alsa-mixer.c:2656
#: spa/plugins/alsa/acp/alsa-mixer.c:2747
msgid "Line In"
msgstr "Hat Girişi"
#: spa/plugins/alsa/acp/alsa-mixer.c:2726
#: spa/plugins/alsa/acp/alsa-mixer.c:2810
#: spa/plugins/bluez5/bluez5-device.c:2374
#: spa/plugins/alsa/acp/alsa-mixer.c:2657
#: spa/plugins/alsa/acp/alsa-mixer.c:2741
#: spa/plugins/bluez5/bluez5-device.c:1989
msgid "Microphone"
msgstr "Mikrofon"
#: spa/plugins/alsa/acp/alsa-mixer.c:2727
#: spa/plugins/alsa/acp/alsa-mixer.c:2811
#: spa/plugins/alsa/acp/alsa-mixer.c:2658
#: spa/plugins/alsa/acp/alsa-mixer.c:2742
msgid "Front Microphone"
msgstr "Ön Mikrofon"
#: spa/plugins/alsa/acp/alsa-mixer.c:2728
#: spa/plugins/alsa/acp/alsa-mixer.c:2812
#: spa/plugins/alsa/acp/alsa-mixer.c:2659
#: spa/plugins/alsa/acp/alsa-mixer.c:2743
msgid "Rear Microphone"
msgstr "Arka Mikrofon"
#: spa/plugins/alsa/acp/alsa-mixer.c:2729
#: spa/plugins/alsa/acp/alsa-mixer.c:2660
msgid "External Microphone"
msgstr "Harici Mikrofon"
#: spa/plugins/alsa/acp/alsa-mixer.c:2730
#: spa/plugins/alsa/acp/alsa-mixer.c:2814
#: spa/plugins/alsa/acp/alsa-mixer.c:2661
#: spa/plugins/alsa/acp/alsa-mixer.c:2745
msgid "Internal Microphone"
msgstr "Dahili Mikrofon"
#: spa/plugins/alsa/acp/alsa-mixer.c:2731
#: spa/plugins/alsa/acp/alsa-mixer.c:2817
#: spa/plugins/alsa/acp/alsa-mixer.c:2662
#: spa/plugins/alsa/acp/alsa-mixer.c:2748
msgid "Radio"
msgstr "Radyo"
#: spa/plugins/alsa/acp/alsa-mixer.c:2732
#: spa/plugins/alsa/acp/alsa-mixer.c:2818
#: spa/plugins/alsa/acp/alsa-mixer.c:2663
#: spa/plugins/alsa/acp/alsa-mixer.c:2749
msgid "Video"
msgstr "Video"
#: spa/plugins/alsa/acp/alsa-mixer.c:2733
#: spa/plugins/alsa/acp/alsa-mixer.c:2664
msgid "Automatic Gain Control"
msgstr "Otomatik Kazanç Denetimi"
#: spa/plugins/alsa/acp/alsa-mixer.c:2734
#: spa/plugins/alsa/acp/alsa-mixer.c:2665
msgid "No Automatic Gain Control"
msgstr "Otomatik Kazanç Denetimi Yok"
#: spa/plugins/alsa/acp/alsa-mixer.c:2735
#: spa/plugins/alsa/acp/alsa-mixer.c:2666
msgid "Boost"
msgstr "Artır"
#: spa/plugins/alsa/acp/alsa-mixer.c:2736
#: spa/plugins/alsa/acp/alsa-mixer.c:2667
msgid "No Boost"
msgstr "Artırma Yok"
#: spa/plugins/alsa/acp/alsa-mixer.c:2737
#: spa/plugins/alsa/acp/alsa-mixer.c:2668
msgid "Amplifier"
msgstr "Yükseltici"
#: spa/plugins/alsa/acp/alsa-mixer.c:2738
#: spa/plugins/alsa/acp/alsa-mixer.c:2669
msgid "No Amplifier"
msgstr "Yükseltici Yok"
#: spa/plugins/alsa/acp/alsa-mixer.c:2739
#: spa/plugins/alsa/acp/alsa-mixer.c:2670
msgid "Bass Boost"
msgstr "Bas Artır"
#: spa/plugins/alsa/acp/alsa-mixer.c:2740
#: spa/plugins/alsa/acp/alsa-mixer.c:2671
msgid "No Bass Boost"
msgstr "Bas Artırma Yok"
#: spa/plugins/alsa/acp/alsa-mixer.c:2741
#: spa/plugins/bluez5/bluez5-device.c:2380
#: spa/plugins/alsa/acp/alsa-mixer.c:2672
#: spa/plugins/bluez5/bluez5-device.c:1995
msgid "Speaker"
msgstr "Hoparlör"
#. Don't call it "headset", the HF one has the mic
#: spa/plugins/alsa/acp/alsa-mixer.c:2742
#: spa/plugins/alsa/acp/alsa-mixer.c:2820
#: spa/plugins/bluez5/bluez5-device.c:2386
#: spa/plugins/bluez5/bluez5-device.c:2453
#: spa/plugins/alsa/acp/alsa-mixer.c:2673
#: spa/plugins/alsa/acp/alsa-mixer.c:2751
msgid "Headphones"
msgstr "Kulaklık"
#: spa/plugins/alsa/acp/alsa-mixer.c:2809
#: spa/plugins/alsa/acp/alsa-mixer.c:2740
msgid "Analog Input"
msgstr "Analog Giriş"
#: spa/plugins/alsa/acp/alsa-mixer.c:2813
#: spa/plugins/alsa/acp/alsa-mixer.c:2744
msgid "Dock Microphone"
msgstr "Yapışık Mikrofon"
#: spa/plugins/alsa/acp/alsa-mixer.c:2815
#: spa/plugins/alsa/acp/alsa-mixer.c:2746
msgid "Headset Microphone"
msgstr "Mikrofonlu Kulaklık"
#: spa/plugins/alsa/acp/alsa-mixer.c:2819
#: spa/plugins/alsa/acp/alsa-mixer.c:2750
msgid "Analog Output"
msgstr "Analog Çıkış"
#: spa/plugins/alsa/acp/alsa-mixer.c:2821
#: spa/plugins/alsa/acp/alsa-mixer.c:2752
msgid "Headphones 2"
msgstr "Kulaklık 2"
#: spa/plugins/alsa/acp/alsa-mixer.c:2822
#: spa/plugins/alsa/acp/alsa-mixer.c:2753
msgid "Headphones Mono Output"
msgstr "Kulaklık Tek Kanallı Çıkış"
#: spa/plugins/alsa/acp/alsa-mixer.c:2823
#: spa/plugins/alsa/acp/alsa-mixer.c:2754
msgid "Line Out"
msgstr "Hat Çıkışı"
#: spa/plugins/alsa/acp/alsa-mixer.c:2824
#: spa/plugins/alsa/acp/alsa-mixer.c:2755
msgid "Analog Mono Output"
msgstr "Analog Tek Kanallı Çıkış"
#: spa/plugins/alsa/acp/alsa-mixer.c:2825
#: spa/plugins/alsa/acp/alsa-mixer.c:2756
msgid "Speakers"
msgstr "Hoparlörler"
#: spa/plugins/alsa/acp/alsa-mixer.c:2826
#: spa/plugins/alsa/acp/alsa-mixer.c:2757
msgid "HDMI / DisplayPort"
msgstr "HDMI / DisplayPort"
#: spa/plugins/alsa/acp/alsa-mixer.c:2827
#: spa/plugins/alsa/acp/alsa-mixer.c:2758
msgid "Digital Output (S/PDIF)"
msgstr "Sayısal Çıkış (S/PDIF)"
#: spa/plugins/alsa/acp/alsa-mixer.c:2828
#: spa/plugins/alsa/acp/alsa-mixer.c:2759
msgid "Digital Input (S/PDIF)"
msgstr "Sayısal Giriş (S/PDIF)"
#: spa/plugins/alsa/acp/alsa-mixer.c:2829
#: spa/plugins/alsa/acp/alsa-mixer.c:2760
msgid "Multichannel Input"
msgstr "Çok Kanallı Giriş"
#: spa/plugins/alsa/acp/alsa-mixer.c:2830
#: spa/plugins/alsa/acp/alsa-mixer.c:2761
msgid "Multichannel Output"
msgstr "Çok Kanallı Çıkış"
#: spa/plugins/alsa/acp/alsa-mixer.c:2831
#: spa/plugins/alsa/acp/alsa-mixer.c:2762
msgid "Game Output"
msgstr "Oyun Çıkışı"
#: spa/plugins/alsa/acp/alsa-mixer.c:2832
#: spa/plugins/alsa/acp/alsa-mixer.c:2833
#: spa/plugins/alsa/acp/alsa-mixer.c:2763
#: spa/plugins/alsa/acp/alsa-mixer.c:2764
msgid "Chat Output"
msgstr "Sohbet Çıkışı"
#: spa/plugins/alsa/acp/alsa-mixer.c:2834
#: spa/plugins/alsa/acp/alsa-mixer.c:2765
msgid "Chat Input"
msgstr "Sohbet Girişi"
#: spa/plugins/alsa/acp/alsa-mixer.c:2835
#: spa/plugins/alsa/acp/alsa-mixer.c:2766
msgid "Virtual Surround 7.1"
msgstr "Sanal Çevresel Ses 7.1"
#: spa/plugins/alsa/acp/alsa-mixer.c:4522
#: spa/plugins/alsa/acp/alsa-mixer.c:4456
msgid "Analog Mono"
msgstr "Analog Tek Kanallı"
#: spa/plugins/alsa/acp/alsa-mixer.c:4523
#: spa/plugins/alsa/acp/alsa-mixer.c:4457
msgid "Analog Mono (Left)"
msgstr "Analog Tek Kanallı (Sol)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4524
#: spa/plugins/alsa/acp/alsa-mixer.c:4458
msgid "Analog Mono (Right)"
msgstr "Analog Tek Kanallı (Sağ)"
@ -415,147 +390,147 @@ msgstr "Analog Tek Kanallı (Sağ)"
#. * here would lead to the source name to become "Analog Stereo Input
#. * Input". The same logic applies to analog-stereo-output,
#. * multichannel-input and multichannel-output.
#: spa/plugins/alsa/acp/alsa-mixer.c:4525
#: spa/plugins/alsa/acp/alsa-mixer.c:4533
#: spa/plugins/alsa/acp/alsa-mixer.c:4534
#: spa/plugins/alsa/acp/alsa-mixer.c:4459
#: spa/plugins/alsa/acp/alsa-mixer.c:4467
#: spa/plugins/alsa/acp/alsa-mixer.c:4468
msgid "Analog Stereo"
msgstr "Analog Stereo"
#: spa/plugins/alsa/acp/alsa-mixer.c:4526
#: spa/plugins/alsa/acp/alsa-mixer.c:4460
msgid "Mono"
msgstr "Tek Kanallı"
#: spa/plugins/alsa/acp/alsa-mixer.c:4527
#: spa/plugins/alsa/acp/alsa-mixer.c:4461
msgid "Stereo"
msgstr "Stereo"
#: spa/plugins/alsa/acp/alsa-mixer.c:4535
#: spa/plugins/alsa/acp/alsa-mixer.c:4693
#: spa/plugins/bluez5/bluez5-device.c:2362
#: spa/plugins/alsa/acp/alsa-mixer.c:4469
#: spa/plugins/alsa/acp/alsa-mixer.c:4627
#: spa/plugins/bluez5/bluez5-device.c:1977
msgid "Headset"
msgstr "Kulaklık"
#: spa/plugins/alsa/acp/alsa-mixer.c:4536
#: spa/plugins/alsa/acp/alsa-mixer.c:4694
#: spa/plugins/alsa/acp/alsa-mixer.c:4470
#: spa/plugins/alsa/acp/alsa-mixer.c:4628
msgid "Speakerphone"
msgstr "Hoparlör"
#: spa/plugins/alsa/acp/alsa-mixer.c:4537
#: spa/plugins/alsa/acp/alsa-mixer.c:4538
#: spa/plugins/alsa/acp/alsa-mixer.c:4471
#: spa/plugins/alsa/acp/alsa-mixer.c:4472
msgid "Multichannel"
msgstr "Çok kanallı"
#: spa/plugins/alsa/acp/alsa-mixer.c:4539
#: spa/plugins/alsa/acp/alsa-mixer.c:4473
msgid "Analog Surround 2.1"
msgstr "Analog Çevresel Ses 2.1"
#: spa/plugins/alsa/acp/alsa-mixer.c:4540
#: spa/plugins/alsa/acp/alsa-mixer.c:4474
msgid "Analog Surround 3.0"
msgstr "Analog Çevresel Ses 3.0"
#: spa/plugins/alsa/acp/alsa-mixer.c:4541
#: spa/plugins/alsa/acp/alsa-mixer.c:4475
msgid "Analog Surround 3.1"
msgstr "Analog Çevresel Ses 3.1"
#: spa/plugins/alsa/acp/alsa-mixer.c:4542
#: spa/plugins/alsa/acp/alsa-mixer.c:4476
msgid "Analog Surround 4.0"
msgstr "Analog Çevresel Ses 4.0"
#: spa/plugins/alsa/acp/alsa-mixer.c:4543
#: spa/plugins/alsa/acp/alsa-mixer.c:4477
msgid "Analog Surround 4.1"
msgstr "Analog Çevresel Ses 4.1"
#: spa/plugins/alsa/acp/alsa-mixer.c:4544
#: spa/plugins/alsa/acp/alsa-mixer.c:4478
msgid "Analog Surround 5.0"
msgstr "Analog Çevresel Ses 5.0"
#: spa/plugins/alsa/acp/alsa-mixer.c:4545
#: spa/plugins/alsa/acp/alsa-mixer.c:4479
msgid "Analog Surround 5.1"
msgstr "Analog Çevresel Ses 5.1"
#: spa/plugins/alsa/acp/alsa-mixer.c:4546
#: spa/plugins/alsa/acp/alsa-mixer.c:4480
msgid "Analog Surround 6.0"
msgstr "Analog Çevresel Ses 6.0"
#: spa/plugins/alsa/acp/alsa-mixer.c:4547
#: spa/plugins/alsa/acp/alsa-mixer.c:4481
msgid "Analog Surround 6.1"
msgstr "Analog Çevresel Ses 6.1"
#: spa/plugins/alsa/acp/alsa-mixer.c:4548
#: spa/plugins/alsa/acp/alsa-mixer.c:4482
msgid "Analog Surround 7.0"
msgstr "Analog Çevresel Ses 7.0"
#: spa/plugins/alsa/acp/alsa-mixer.c:4549
#: spa/plugins/alsa/acp/alsa-mixer.c:4483
msgid "Analog Surround 7.1"
msgstr "Analog Çevresel Ses 7.1"
#: spa/plugins/alsa/acp/alsa-mixer.c:4550
#: spa/plugins/alsa/acp/alsa-mixer.c:4484
msgid "Digital Stereo (IEC958)"
msgstr "Sayısal Stereo (IEC958)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4551
#: spa/plugins/alsa/acp/alsa-mixer.c:4485
msgid "Digital Surround 4.0 (IEC958/AC3)"
msgstr "Sayısal Çevresel Ses 4.0 (IEC958/AC3)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4552
#: spa/plugins/alsa/acp/alsa-mixer.c:4486
msgid "Digital Surround 5.1 (IEC958/AC3)"
msgstr "Sayısal Çevresel Ses 5.1 (IEC958/AC3)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4553
#: spa/plugins/alsa/acp/alsa-mixer.c:4487
msgid "Digital Surround 5.1 (IEC958/DTS)"
msgstr "Sayısal Çevresel Ses 5.1 (IEC958/DTS)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4554
#: spa/plugins/alsa/acp/alsa-mixer.c:4488
msgid "Digital Stereo (HDMI)"
msgstr "Sayısal Stereo (HDMI)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4555
#: spa/plugins/alsa/acp/alsa-mixer.c:4489
msgid "Digital Surround 5.1 (HDMI)"
msgstr "Sayısal Çevresel Ses 5.1 (HDMI)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4556
#: spa/plugins/alsa/acp/alsa-mixer.c:4490
msgid "Chat"
msgstr "Sohbet"
#: spa/plugins/alsa/acp/alsa-mixer.c:4557
#: spa/plugins/alsa/acp/alsa-mixer.c:4491
msgid "Game"
msgstr "Oyun"
#: spa/plugins/alsa/acp/alsa-mixer.c:4691
#: spa/plugins/alsa/acp/alsa-mixer.c:4625
msgid "Analog Mono Duplex"
msgstr "Analog Tek Kanallı İkili"
#: spa/plugins/alsa/acp/alsa-mixer.c:4692
#: spa/plugins/alsa/acp/alsa-mixer.c:4626
msgid "Analog Stereo Duplex"
msgstr "Analog İkili Stereo"
#: spa/plugins/alsa/acp/alsa-mixer.c:4695
#: spa/plugins/alsa/acp/alsa-mixer.c:4629
msgid "Digital Stereo Duplex (IEC958)"
msgstr "Sayısal İkili Stereo (IEC958)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4696
#: spa/plugins/alsa/acp/alsa-mixer.c:4630
msgid "Multichannel Duplex"
msgstr "Çok Kanallı İkili"
#: spa/plugins/alsa/acp/alsa-mixer.c:4697
#: spa/plugins/alsa/acp/alsa-mixer.c:4631
msgid "Stereo Duplex"
msgstr "İkili Stereo"
#: spa/plugins/alsa/acp/alsa-mixer.c:4698
#: spa/plugins/alsa/acp/alsa-mixer.c:4632
msgid "Mono Chat + 7.1 Surround"
msgstr "Tek Kanallı Sohbet + 7.1 Çevresel Ses"
#: spa/plugins/alsa/acp/alsa-mixer.c:4799
#: spa/plugins/alsa/acp/alsa-mixer.c:4733
#, c-format
msgid "%s Output"
msgstr "%s Çıkışı"
#: spa/plugins/alsa/acp/alsa-mixer.c:4807
#: spa/plugins/alsa/acp/alsa-mixer.c:4741
#, c-format
msgid "%s Input"
msgstr "%s Girişi"
#: spa/plugins/alsa/acp/alsa-util.c:1233 spa/plugins/alsa/acp/alsa-util.c:1327
#: spa/plugins/alsa/acp/alsa-util.c:1220 spa/plugins/alsa/acp/alsa-util.c:1314
#, c-format
msgid ""
"snd_pcm_avail() returned a value that is exceptionally large: %lu byte (%lu "
@ -572,16 +547,16 @@ msgstr[0] ""
"Büyük ihtimalle bu bir ALSA sürücüsü '%s' hatasıdır. Lütfen bu sorunu ALSA "
"geliştiricilerine bildirin."
#: spa/plugins/alsa/acp/alsa-util.c:1299
#: spa/plugins/alsa/acp/alsa-util.c:1286
#, c-format
msgid ""
"snd_pcm_delay() returned a value that is exceptionally large: %li byte "
"(%s%lu ms).\n"
"snd_pcm_delay() returned a value that is exceptionally large: %li byte (%s"
"%lu ms).\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
"to the ALSA developers."
msgid_plural ""
"snd_pcm_delay() returned a value that is exceptionally large: %li bytes "
"(%s%lu ms).\n"
"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s"
"%lu ms).\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
"to the ALSA developers."
msgstr[0] ""
@ -589,7 +564,7 @@ msgstr[0] ""
"Büyük ihtimalle bu bir ALSA sürücüsü '%s' hatasıdır. Lütfen bu sorunu ALSA "
"geliştiricilerine bildirin."
#: spa/plugins/alsa/acp/alsa-util.c:1346
#: spa/plugins/alsa/acp/alsa-util.c:1333
#, c-format
msgid ""
"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
@ -602,7 +577,7 @@ msgstr ""
"Büyük ihtimalle bu bir ALSA sürücüsü '%s' hatasıdır. Lütfen bu sorunu ALSA "
"geliştiricilerine bildirin."
#: spa/plugins/alsa/acp/alsa-util.c:1389
#: spa/plugins/alsa/acp/alsa-util.c:1376
#, c-format
msgid ""
"snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu byte "
@ -620,112 +595,112 @@ msgstr[0] ""
"Büyük ihtimalle bu bir ALSA sürücüsü '%s' hatasıdır. Lütfen bu sorunu ALSA "
"geliştiricilerine bildirin."
#: spa/plugins/alsa/acp/channelmap.h:460
#: spa/plugins/alsa/acp/channelmap.h:457
msgid "(invalid)"
msgstr "(geçersiz)"
#: spa/plugins/alsa/acp/compat.c:194
#: spa/plugins/alsa/acp/compat.c:193
msgid "Built-in Audio"
msgstr "Dahili Ses"
#: spa/plugins/alsa/acp/compat.c:199
#: spa/plugins/alsa/acp/compat.c:198
msgid "Modem"
msgstr "Modem"
#: spa/plugins/bluez5/bluez5-device.c:1987
#: spa/plugins/bluez5/bluez5-device.c:1712
msgid "Audio Gateway (A2DP Source & HSP/HFP AG)"
msgstr "Ses Geçidi (A2DP Kaynak & HSP/HFP AG)"
#: spa/plugins/bluez5/bluez5-device.c:2016
msgid "Audio Streaming for Hearing Aids (ASHA Sink)"
msgstr "İşitme Aygıtları İçin Ses Akışı (ASHA Alıcı)"
#: spa/plugins/bluez5/bluez5-device.c:2059
#: spa/plugins/bluez5/bluez5-device.c:1760
#, c-format
msgid "High Fidelity Playback (A2DP Sink, codec %s)"
msgstr "Yüksek Kaliteli Çalma (A2DP Alıcı, çözücü %s)"
#: spa/plugins/bluez5/bluez5-device.c:2062
#: spa/plugins/bluez5/bluez5-device.c:1763
#, c-format
msgid "High Fidelity Duplex (A2DP Source/Sink, codec %s)"
msgstr "Yüksek Kaliteli İkili (A2DP Kaynak/Alıcı, çözücü %s)"
#: spa/plugins/bluez5/bluez5-device.c:2070
#: spa/plugins/bluez5/bluez5-device.c:1771
msgid "High Fidelity Playback (A2DP Sink)"
msgstr "Yüksek Kaliteli Çalma (A2DP Alıcı)"
#: spa/plugins/bluez5/bluez5-device.c:2072
#: spa/plugins/bluez5/bluez5-device.c:1773
msgid "High Fidelity Duplex (A2DP Source/Sink)"
msgstr "Yüksek Kaliteli İkili (A2DP Kaynak/Alıcı)"
#: spa/plugins/bluez5/bluez5-device.c:2146
#: spa/plugins/bluez5/bluez5-device.c:1823
#, c-format
msgid "High Fidelity Playback (BAP Sink, codec %s)"
msgstr "Yüksek Kaliteli Çalma (BAP Alıcı, çözücü %s)"
#: spa/plugins/bluez5/bluez5-device.c:2151
#: spa/plugins/bluez5/bluez5-device.c:1828
#, c-format
msgid "High Fidelity Input (BAP Source, codec %s)"
msgstr "Yüksek Kaliteli Giriş (BAP Kaynak, çözücü %s)"
#: spa/plugins/bluez5/bluez5-device.c:2155
#: spa/plugins/bluez5/bluez5-device.c:1832
#, c-format
msgid "High Fidelity Duplex (BAP Source/Sink, codec %s)"
msgstr "Yüksek Kaliteli İkili (BAP Kaynak/Alıcı, çözücü %s)"
#: spa/plugins/bluez5/bluez5-device.c:2164
#: spa/plugins/bluez5/bluez5-device.c:1841
msgid "High Fidelity Playback (BAP Sink)"
msgstr "Yüksek Kaliteli Çalma (BAP Alıcı)"
#: spa/plugins/bluez5/bluez5-device.c:2168
#: spa/plugins/bluez5/bluez5-device.c:1845
msgid "High Fidelity Input (BAP Source)"
msgstr "Yüksek Kaliteli Giriş (BAP Kaynak)"
#: spa/plugins/bluez5/bluez5-device.c:2171
#: spa/plugins/bluez5/bluez5-device.c:1848
msgid "High Fidelity Duplex (BAP Source/Sink)"
msgstr "Yüksek Kaliteli İkili (BAP Kaynak/Alıcı)"
#: spa/plugins/bluez5/bluez5-device.c:2211
#: spa/plugins/bluez5/bluez5-device.c:1897
#, c-format
msgid "Headset Head Unit (HSP/HFP, codec %s)"
msgstr "Kulaklık Ana Birimi (HSP/HFP, çözücü %s)"
#: spa/plugins/bluez5/bluez5-device.c:2363
#: spa/plugins/bluez5/bluez5-device.c:2368
#: spa/plugins/bluez5/bluez5-device.c:2375
#: spa/plugins/bluez5/bluez5-device.c:2381
#: spa/plugins/bluez5/bluez5-device.c:2387
#: spa/plugins/bluez5/bluez5-device.c:2393
#: spa/plugins/bluez5/bluez5-device.c:2399
#: spa/plugins/bluez5/bluez5-device.c:2405
#: spa/plugins/bluez5/bluez5-device.c:2411
#: spa/plugins/bluez5/bluez5-device.c:1978
#: spa/plugins/bluez5/bluez5-device.c:1983
#: spa/plugins/bluez5/bluez5-device.c:1990
#: spa/plugins/bluez5/bluez5-device.c:1996
#: spa/plugins/bluez5/bluez5-device.c:2002
#: spa/plugins/bluez5/bluez5-device.c:2008
#: spa/plugins/bluez5/bluez5-device.c:2014
#: spa/plugins/bluez5/bluez5-device.c:2020
#: spa/plugins/bluez5/bluez5-device.c:2026
msgid "Handsfree"
msgstr "Ahizesiz"
#: spa/plugins/bluez5/bluez5-device.c:2369
#: spa/plugins/bluez5/bluez5-device.c:1984
msgid "Handsfree (HFP)"
msgstr "Ahizesiz (HFP)"
#: spa/plugins/bluez5/bluez5-device.c:2392
#: spa/plugins/bluez5/bluez5-device.c:2001
msgid "Headphone"
msgstr "Kulaklık"
#: spa/plugins/bluez5/bluez5-device.c:2007
msgid "Portable"
msgstr "Taşınabilir"
#: spa/plugins/bluez5/bluez5-device.c:2398
#: spa/plugins/bluez5/bluez5-device.c:2013
msgid "Car"
msgstr "Araba"
#: spa/plugins/bluez5/bluez5-device.c:2404
#: spa/plugins/bluez5/bluez5-device.c:2019
msgid "HiFi"
msgstr "Yüksek Kalite"
#: spa/plugins/bluez5/bluez5-device.c:2410
#: spa/plugins/bluez5/bluez5-device.c:2025
msgid "Phone"
msgstr "Telefon"
#: spa/plugins/bluez5/bluez5-device.c:2417
#: spa/plugins/bluez5/bluez5-device.c:2032
msgid "Bluetooth"
msgstr "Bluetooth"
#: spa/plugins/bluez5/bluez5-device.c:2418
#: spa/plugins/bluez5/bluez5-device.c:2033
msgid "Bluetooth (HFP)"
msgstr "Bluetooth (HFP)"

View file

@ -6,15 +6,15 @@
# Cheng-Chia Tseng <pswo10680@gmail.com>, 2010, 2012.
# Frank Hill <hxf.prc@gmail.com>, 2015.
# Mingye Wang (Arthur2e5) <arthur200126@gmail.com>, 2015.
# lumingzh <lumingzh@qq.com>, 2024-2025.
# lumingzh <lumingzh@qq.com>, 2024.
#
msgid ""
msgstr ""
"Project-Id-Version: pipewire.master-tx\n"
"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/pipewire/-/"
"issues\n"
"POT-Creation-Date: 2025-09-21 15:33+0000\n"
"PO-Revision-Date: 2025-09-22 08:53+0800\n"
"POT-Creation-Date: 2024-09-09 16:36+0000\n"
"PO-Revision-Date: 2024-10-08 09:41+0800\n"
"Last-Translator: lumingzh <lumingzh@qq.com>\n"
"Language-Team: Chinese (China) <i18n-zh@googlegroups.com>\n"
"Language: zh_CN\n"
@ -22,7 +22,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2016-03-22 13:23+0000\n"
"X-Generator: Gtranslator 49.0\n"
"X-Generator: Gtranslator 47.0\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#: src/daemon/pipewire.c:29
@ -42,11 +42,11 @@ msgstr ""
" -c, --config 加载配置 (默认 %s)\n"
" -P --properties 设置上下文属性\n"
#: src/daemon/pipewire.desktop.in:3
#: src/daemon/pipewire.desktop.in:4
msgid "PipeWire Media System"
msgstr "PipeWire 多媒体系统"
#: src/daemon/pipewire.desktop.in:4
#: src/daemon/pipewire.desktop.in:5
msgid "Start the PipeWire Media System"
msgstr "启动 PipeWire 多媒体系统"
@ -60,26 +60,26 @@ msgstr "至 %s%s%s 的隧道"
msgid "Dummy Output"
msgstr "虚拟输出"
#: src/modules/module-pulse-tunnel.c:760
#: src/modules/module-pulse-tunnel.c:774
#, c-format
msgid "Tunnel for %s@%s"
msgstr "用于 %s@%s 的隧道"
#: src/modules/module-zeroconf-discover.c:320
#: src/modules/module-zeroconf-discover.c:318
msgid "Unknown device"
msgstr "未知设备"
#: src/modules/module-zeroconf-discover.c:332
#: src/modules/module-zeroconf-discover.c:330
#, c-format
msgid "%s on %s@%s"
msgstr "%2$s@%3$s 上的 %1$s"
#: src/modules/module-zeroconf-discover.c:336
#: src/modules/module-zeroconf-discover.c:334
#, c-format
msgid "%s on %s"
msgstr "%2$s 上的 %1$s"
#: src/tools/pw-cat.c:1084
#: src/tools/pw-cat.c:996
#, c-format
msgid ""
"%s [options] [<file>|-]\n"
@ -94,7 +94,7 @@ msgstr ""
" -v, --verbose 输出详细操作\n"
"\n"
#: src/tools/pw-cat.c:1091
#: src/tools/pw-cat.c:1003
#, c-format
msgid ""
" -R, --remote Remote daemon name\n"
@ -126,7 +126,7 @@ msgstr ""
" -P --properties 设置节点属性\n"
"\n"
#: src/tools/pw-cat.c:1109
#: src/tools/pw-cat.c:1021
#, c-format
msgid ""
" --rate Sample rate (req. for rec) (default "
@ -144,9 +144,6 @@ msgid ""
" -q --quality Resampler quality (0 - 15) (default "
"%d)\n"
" -a, --raw RAW mode\n"
" -M, --force-midi Force midi format, one of \"midi\" "
"or \"ump\", (default ump)\n"
" -n, --sample-count COUNT Stop after COUNT samples\n"
"\n"
msgstr ""
" --rate 采样率 (录制模式需要) (默认 %u)\n"
@ -154,27 +151,22 @@ msgstr ""
" --channel-map 通道映射\n"
" \"stereo\", \"surround-51\",... "
"中的其一或\n"
" 以\",\"分隔的通道名列表: 如 "
"\"FL,FR\"\n"
" 以\",\"分隔的通道名列表: 如 \"FL,"
"FR\"\n"
" --format 采样格式 %s (录制模式需要) (默认 "
"%s)\n"
" --volume 媒体流音量 0-1.0 (默认 %.3f)\n"
" -q --quality 重采样质量 (0 - 15) (默认 %d)\n"
" -a, --raw 原生模式\n"
" -M, --force-midi 强制 midi 格式,\"midi\" 或 \"ump\" "
"其一 (默认 ump)\n"
" -n, --sample-count COUNT 计数采样后停止\n"
"\n"
#: src/tools/pw-cat.c:1129
#: src/tools/pw-cat.c:1039
msgid ""
" -p, --playback Playback mode\n"
" -r, --record Recording mode\n"
" -m, --midi Midi mode\n"
" -d, --dsd DSD mode\n"
" -o, --encoded Encoded mode\n"
" -s, --sysex SysEx mode\n"
" -c, --midi-clip MIDI clip mode\n"
"\n"
msgstr ""
" -p, --playback 回放模式\n"
@ -182,11 +174,9 @@ msgstr ""
" -m, --midi Midi 模式\n"
" -d, --dsd DSD 模式\n"
" -o, --encoded 编码模式\n"
" -s, --sysex SysEx 模式\n"
" -c, --midi-clip MIDI 剪辑模式\n"
"\n"
#: src/tools/pw-cli.c:2386
#: src/tools/pw-cli.c:2285
#, c-format
msgid ""
"%s [options] [command]\n"
@ -204,20 +194,15 @@ msgstr ""
" -m, --monitor 监视器活动\n"
"\n"
#: spa/plugins/alsa/acp/acp.c:351
#: spa/plugins/alsa/acp/acp.c:327
msgid "Pro Audio"
msgstr "专业音频"
#: spa/plugins/alsa/acp/acp.c:527 spa/plugins/alsa/acp/alsa-mixer.c:4635
#: spa/plugins/bluez5/bluez5-device.c:1974
#: spa/plugins/alsa/acp/acp.c:488 spa/plugins/alsa/acp/alsa-mixer.c:4633
#: spa/plugins/bluez5/bluez5-device.c:1701
msgid "Off"
msgstr "关"
#: spa/plugins/alsa/acp/acp.c:610
#, c-format
msgid "%s [ALSA UCM error]"
msgstr "%s [ALSA UCM 错误]"
#: spa/plugins/alsa/acp/alsa-mixer.c:2652
msgid "Input"
msgstr "输入"
@ -241,7 +226,7 @@ msgstr "输入插孔"
#: spa/plugins/alsa/acp/alsa-mixer.c:2657
#: spa/plugins/alsa/acp/alsa-mixer.c:2741
#: spa/plugins/bluez5/bluez5-device.c:2372
#: spa/plugins/bluez5/bluez5-device.c:1989
msgid "Microphone"
msgstr "话筒"
@ -307,15 +292,12 @@ msgid "No Bass Boost"
msgstr "无重低音增强"
#: spa/plugins/alsa/acp/alsa-mixer.c:2672
#: spa/plugins/bluez5/bluez5-device.c:2378
#: spa/plugins/bluez5/bluez5-device.c:1995
msgid "Speaker"
msgstr "扬声器"
#. Don't call it "headset", the HF one has the mic
#: spa/plugins/alsa/acp/alsa-mixer.c:2673
#: spa/plugins/alsa/acp/alsa-mixer.c:2751
#: spa/plugins/bluez5/bluez5-device.c:2384
#: spa/plugins/bluez5/bluez5-device.c:2451
msgid "Headphones"
msgstr "模拟耳机"
@ -392,15 +374,15 @@ msgstr "语音输入"
msgid "Virtual Surround 7.1"
msgstr "虚拟环绕 7.1"
#: spa/plugins/alsa/acp/alsa-mixer.c:4458
#: spa/plugins/alsa/acp/alsa-mixer.c:4456
msgid "Analog Mono"
msgstr "模拟单声道"
#: spa/plugins/alsa/acp/alsa-mixer.c:4459
#: spa/plugins/alsa/acp/alsa-mixer.c:4457
msgid "Analog Mono (Left)"
msgstr "模拟单声道 (左声道)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4460
#: spa/plugins/alsa/acp/alsa-mixer.c:4458
msgid "Analog Mono (Right)"
msgstr "模拟单声道 (右声道)"
@ -409,147 +391,147 @@ msgstr "模拟单声道 (右声道)"
#. * here would lead to the source name to become "Analog Stereo Input
#. * Input". The same logic applies to analog-stereo-output,
#. * multichannel-input and multichannel-output.
#: spa/plugins/alsa/acp/alsa-mixer.c:4461
#: spa/plugins/alsa/acp/alsa-mixer.c:4469
#: spa/plugins/alsa/acp/alsa-mixer.c:4470
#: spa/plugins/alsa/acp/alsa-mixer.c:4459
#: spa/plugins/alsa/acp/alsa-mixer.c:4467
#: spa/plugins/alsa/acp/alsa-mixer.c:4468
msgid "Analog Stereo"
msgstr "模拟立体声"
#: spa/plugins/alsa/acp/alsa-mixer.c:4462
#: spa/plugins/alsa/acp/alsa-mixer.c:4460
msgid "Mono"
msgstr "单声道"
#: spa/plugins/alsa/acp/alsa-mixer.c:4463
#: spa/plugins/alsa/acp/alsa-mixer.c:4461
msgid "Stereo"
msgstr "立体声"
#: spa/plugins/alsa/acp/alsa-mixer.c:4471
#: spa/plugins/alsa/acp/alsa-mixer.c:4629
#: spa/plugins/bluez5/bluez5-device.c:2360
#: spa/plugins/alsa/acp/alsa-mixer.c:4469
#: spa/plugins/alsa/acp/alsa-mixer.c:4627
#: spa/plugins/bluez5/bluez5-device.c:1977
msgid "Headset"
msgstr "耳机"
#: spa/plugins/alsa/acp/alsa-mixer.c:4472
#: spa/plugins/alsa/acp/alsa-mixer.c:4630
#: spa/plugins/alsa/acp/alsa-mixer.c:4470
#: spa/plugins/alsa/acp/alsa-mixer.c:4628
msgid "Speakerphone"
msgstr "扬声麦克风"
#: spa/plugins/alsa/acp/alsa-mixer.c:4473
#: spa/plugins/alsa/acp/alsa-mixer.c:4474
#: spa/plugins/alsa/acp/alsa-mixer.c:4471
#: spa/plugins/alsa/acp/alsa-mixer.c:4472
msgid "Multichannel"
msgstr "多声道"
#: spa/plugins/alsa/acp/alsa-mixer.c:4475
#: spa/plugins/alsa/acp/alsa-mixer.c:4473
msgid "Analog Surround 2.1"
msgstr "模拟环绕 2.1"
#: spa/plugins/alsa/acp/alsa-mixer.c:4476
#: spa/plugins/alsa/acp/alsa-mixer.c:4474
msgid "Analog Surround 3.0"
msgstr "模拟环绕 3.0"
#: spa/plugins/alsa/acp/alsa-mixer.c:4477
#: spa/plugins/alsa/acp/alsa-mixer.c:4475
msgid "Analog Surround 3.1"
msgstr "模拟环绕 3.1"
#: spa/plugins/alsa/acp/alsa-mixer.c:4478
#: spa/plugins/alsa/acp/alsa-mixer.c:4476
msgid "Analog Surround 4.0"
msgstr "模拟环绕 4.0"
#: spa/plugins/alsa/acp/alsa-mixer.c:4479
#: spa/plugins/alsa/acp/alsa-mixer.c:4477
msgid "Analog Surround 4.1"
msgstr "模拟环绕 4.1"
#: spa/plugins/alsa/acp/alsa-mixer.c:4480
#: spa/plugins/alsa/acp/alsa-mixer.c:4478
msgid "Analog Surround 5.0"
msgstr "模拟环绕 5.0"
#: spa/plugins/alsa/acp/alsa-mixer.c:4481
#: spa/plugins/alsa/acp/alsa-mixer.c:4479
msgid "Analog Surround 5.1"
msgstr "模拟环绕 5.1"
#: spa/plugins/alsa/acp/alsa-mixer.c:4482
#: spa/plugins/alsa/acp/alsa-mixer.c:4480
msgid "Analog Surround 6.0"
msgstr "模拟环绕 6.0"
#: spa/plugins/alsa/acp/alsa-mixer.c:4483
#: spa/plugins/alsa/acp/alsa-mixer.c:4481
msgid "Analog Surround 6.1"
msgstr "模拟环绕 6.1"
#: spa/plugins/alsa/acp/alsa-mixer.c:4484
#: spa/plugins/alsa/acp/alsa-mixer.c:4482
msgid "Analog Surround 7.0"
msgstr "模拟环绕 7.0"
#: spa/plugins/alsa/acp/alsa-mixer.c:4485
#: spa/plugins/alsa/acp/alsa-mixer.c:4483
msgid "Analog Surround 7.1"
msgstr "模拟环绕 7.1"
#: spa/plugins/alsa/acp/alsa-mixer.c:4486
#: spa/plugins/alsa/acp/alsa-mixer.c:4484
msgid "Digital Stereo (IEC958)"
msgstr "数字立体声 (IEC958)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4487
#: spa/plugins/alsa/acp/alsa-mixer.c:4485
msgid "Digital Surround 4.0 (IEC958/AC3)"
msgstr "数字环绕 4.0 (IEC958/AC3)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4488
#: spa/plugins/alsa/acp/alsa-mixer.c:4486
msgid "Digital Surround 5.1 (IEC958/AC3)"
msgstr "数字环绕 5.1 (IEC958/AC3)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4489
#: spa/plugins/alsa/acp/alsa-mixer.c:4487
msgid "Digital Surround 5.1 (IEC958/DTS)"
msgstr "数字环绕 5.1 (IEC958/DTS)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4490
#: spa/plugins/alsa/acp/alsa-mixer.c:4488
msgid "Digital Stereo (HDMI)"
msgstr "数字立体声 (HDMI)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4491
#: spa/plugins/alsa/acp/alsa-mixer.c:4489
msgid "Digital Surround 5.1 (HDMI)"
msgstr "数字环绕 5.1 (HDMI)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4492
#: spa/plugins/alsa/acp/alsa-mixer.c:4490
msgid "Chat"
msgstr "语音"
#: spa/plugins/alsa/acp/alsa-mixer.c:4493
#: spa/plugins/alsa/acp/alsa-mixer.c:4491
msgid "Game"
msgstr "游戏"
#: spa/plugins/alsa/acp/alsa-mixer.c:4627
#: spa/plugins/alsa/acp/alsa-mixer.c:4625
msgid "Analog Mono Duplex"
msgstr "模拟单声道双工"
#: spa/plugins/alsa/acp/alsa-mixer.c:4628
#: spa/plugins/alsa/acp/alsa-mixer.c:4626
msgid "Analog Stereo Duplex"
msgstr "模拟立体声双工"
#: spa/plugins/alsa/acp/alsa-mixer.c:4631
#: spa/plugins/alsa/acp/alsa-mixer.c:4629
msgid "Digital Stereo Duplex (IEC958)"
msgstr "数字立体声双工 (IEC958)"
#: spa/plugins/alsa/acp/alsa-mixer.c:4632
#: spa/plugins/alsa/acp/alsa-mixer.c:4630
msgid "Multichannel Duplex"
msgstr "多声道双工"
#: spa/plugins/alsa/acp/alsa-mixer.c:4633
#: spa/plugins/alsa/acp/alsa-mixer.c:4631
msgid "Stereo Duplex"
msgstr "模拟立体声双工"
#: spa/plugins/alsa/acp/alsa-mixer.c:4634
#: spa/plugins/alsa/acp/alsa-mixer.c:4632
msgid "Mono Chat + 7.1 Surround"
msgstr "单声道语音 + 7.1 环绕声"
#: spa/plugins/alsa/acp/alsa-mixer.c:4735
#: spa/plugins/alsa/acp/alsa-mixer.c:4733
#, c-format
msgid "%s Output"
msgstr "%s 输出"
#: spa/plugins/alsa/acp/alsa-mixer.c:4743
#: spa/plugins/alsa/acp/alsa-mixer.c:4741
#, c-format
msgid "%s Input"
msgstr "%s 输入"
#: spa/plugins/alsa/acp/alsa-util.c:1233 spa/plugins/alsa/acp/alsa-util.c:1327
#: spa/plugins/alsa/acp/alsa-util.c:1231 spa/plugins/alsa/acp/alsa-util.c:1325
#, c-format
msgid ""
"snd_pcm_avail() returned a value that is exceptionally large: %lu byte (%lu "
@ -565,7 +547,7 @@ msgstr[0] ""
"snd_pcm_avail() 返回的值非常大:%lu 字节(%lu 毫秒)。\n"
"这很可能是由 ALSA 驱动程序 %s 的缺陷导致的。请向 ALSA 开发者报告这个问题。"
#: spa/plugins/alsa/acp/alsa-util.c:1299
#: spa/plugins/alsa/acp/alsa-util.c:1297
#, c-format
msgid ""
"snd_pcm_delay() returned a value that is exceptionally large: %li byte "
@ -581,7 +563,7 @@ msgstr[0] ""
"snd_pcm_delay() 返回的值非常大:%li 字节(%s%lu 毫秒)。\n"
"这很可能是由 ALSA 驱动程序 %s 的缺陷导致的。请向 ALSA 开发者报告这个问题。"
#: spa/plugins/alsa/acp/alsa-util.c:1346
#: spa/plugins/alsa/acp/alsa-util.c:1344
#, c-format
msgid ""
"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
@ -592,7 +574,7 @@ msgstr ""
"snd_pcm_avail_delay() 返回的值非常很奇怪:延迟 %lu 小于可用 (avail) %lu。\n"
"这很可能是由 ALSA 驱动程序 %s 的缺陷导致的。请向 ALSA 开发者报告这个问题。"
#: spa/plugins/alsa/acp/alsa-util.c:1389
#: spa/plugins/alsa/acp/alsa-util.c:1387
#, c-format
msgid ""
"snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu byte "
@ -612,114 +594,111 @@ msgstr[0] ""
msgid "(invalid)"
msgstr "(无效)"
#: spa/plugins/alsa/acp/compat.c:194
#: spa/plugins/alsa/acp/compat.c:193
msgid "Built-in Audio"
msgstr "内置音频"
#: spa/plugins/alsa/acp/compat.c:199
#: spa/plugins/alsa/acp/compat.c:198
msgid "Modem"
msgstr "调制解调器"
#: spa/plugins/bluez5/bluez5-device.c:1985
#: spa/plugins/bluez5/bluez5-device.c:1712
msgid "Audio Gateway (A2DP Source & HSP/HFP AG)"
msgstr "音频网关 (A2DP 信源 或 HSP/HFP 网关)"
#: spa/plugins/bluez5/bluez5-device.c:2014
msgid "Audio Streaming for Hearing Aids (ASHA Sink)"
msgstr "助听器音频流 (ASHA 信宿)"
#: spa/plugins/bluez5/bluez5-device.c:2057
#: spa/plugins/bluez5/bluez5-device.c:1760
#, c-format
msgid "High Fidelity Playback (A2DP Sink, codec %s)"
msgstr "高保真回放 (A2DP 信宿, 编码 %s)"
#: spa/plugins/bluez5/bluez5-device.c:2060
#: spa/plugins/bluez5/bluez5-device.c:1763
#, c-format
msgid "High Fidelity Duplex (A2DP Source/Sink, codec %s)"
msgstr "高保真双工 (A2DP 信源/信宿, 编码 %s)"
#: spa/plugins/bluez5/bluez5-device.c:2068
#: spa/plugins/bluez5/bluez5-device.c:1771
msgid "High Fidelity Playback (A2DP Sink)"
msgstr "高保真回放 (A2DP 信宿)"
#: spa/plugins/bluez5/bluez5-device.c:2070
#: spa/plugins/bluez5/bluez5-device.c:1773
msgid "High Fidelity Duplex (A2DP Source/Sink)"
msgstr "高保真双工 (A2DP 信源/信宿)"
#: spa/plugins/bluez5/bluez5-device.c:2144
#: spa/plugins/bluez5/bluez5-device.c:1823
#, c-format
msgid "High Fidelity Playback (BAP Sink, codec %s)"
msgstr "高保真回放 (BAP 信宿, 编码 %s)"
#: spa/plugins/bluez5/bluez5-device.c:2149
#: spa/plugins/bluez5/bluez5-device.c:1828
#, c-format
msgid "High Fidelity Input (BAP Source, codec %s)"
msgstr "高保真输入 (BAP 信源, 编码 %s)"
#: spa/plugins/bluez5/bluez5-device.c:2153
#: spa/plugins/bluez5/bluez5-device.c:1832
#, c-format
msgid "High Fidelity Duplex (BAP Source/Sink, codec %s)"
msgstr "高保真双工 (BAP 信源/信宿, 编码 %s)"
#: spa/plugins/bluez5/bluez5-device.c:2162
#: spa/plugins/bluez5/bluez5-device.c:1841
msgid "High Fidelity Playback (BAP Sink)"
msgstr "高保真回放 (BAP 信宿)"
#: spa/plugins/bluez5/bluez5-device.c:2166
#: spa/plugins/bluez5/bluez5-device.c:1845
msgid "High Fidelity Input (BAP Source)"
msgstr "高保真输入 (BAP 信源)"
#: spa/plugins/bluez5/bluez5-device.c:2169
#: spa/plugins/bluez5/bluez5-device.c:1848
msgid "High Fidelity Duplex (BAP Source/Sink)"
msgstr "高保真双工 (BAP 信源/信宿)"
#: spa/plugins/bluez5/bluez5-device.c:2209
#: spa/plugins/bluez5/bluez5-device.c:1897
#, c-format
msgid "Headset Head Unit (HSP/HFP, codec %s)"
msgstr "头戴式耳机单元 (HSP/HFP, 编码 %s)"
#: spa/plugins/bluez5/bluez5-device.c:2361
#: spa/plugins/bluez5/bluez5-device.c:2366
#: spa/plugins/bluez5/bluez5-device.c:2373
#: spa/plugins/bluez5/bluez5-device.c:2379
#: spa/plugins/bluez5/bluez5-device.c:2385
#: spa/plugins/bluez5/bluez5-device.c:2391
#: spa/plugins/bluez5/bluez5-device.c:2397
#: spa/plugins/bluez5/bluez5-device.c:2403
#: spa/plugins/bluez5/bluez5-device.c:2409
#: spa/plugins/bluez5/bluez5-device.c:1978
#: spa/plugins/bluez5/bluez5-device.c:1983
#: spa/plugins/bluez5/bluez5-device.c:1990
#: spa/plugins/bluez5/bluez5-device.c:1996
#: spa/plugins/bluez5/bluez5-device.c:2002
#: spa/plugins/bluez5/bluez5-device.c:2008
#: spa/plugins/bluez5/bluez5-device.c:2014
#: spa/plugins/bluez5/bluez5-device.c:2020
#: spa/plugins/bluez5/bluez5-device.c:2026
msgid "Handsfree"
msgstr "免手操作"
#: spa/plugins/bluez5/bluez5-device.c:2367
#: spa/plugins/bluez5/bluez5-device.c:1984
msgid "Handsfree (HFP)"
msgstr "免手操作 (HFP)"
#: spa/plugins/bluez5/bluez5-device.c:2390
#: spa/plugins/bluez5/bluez5-device.c:2001
msgid "Headphone"
msgstr "头戴耳机"
#: spa/plugins/bluez5/bluez5-device.c:2007
msgid "Portable"
msgstr "便携式"
#: spa/plugins/bluez5/bluez5-device.c:2396
#: spa/plugins/bluez5/bluez5-device.c:2013
msgid "Car"
msgstr "车内"
#: spa/plugins/bluez5/bluez5-device.c:2402
#: spa/plugins/bluez5/bluez5-device.c:2019
msgid "HiFi"
msgstr "高保真"
#: spa/plugins/bluez5/bluez5-device.c:2408
#: spa/plugins/bluez5/bluez5-device.c:2025
msgid "Phone"
msgstr "电话"
#: spa/plugins/bluez5/bluez5-device.c:2415
#: spa/plugins/bluez5/bluez5-device.c:2032
msgid "Bluetooth"
msgstr "蓝牙"
#: spa/plugins/bluez5/bluez5-device.c:2416
#: spa/plugins/bluez5/bluez5-device.c:2033
msgid "Bluetooth (HFP)"
msgstr "蓝牙 (HFP)"
#~ msgid "Headphone"
#~ msgstr "头戴耳机"
#~ msgid "Headset Head Unit (HSP/HFP)"
#~ msgstr "头戴式耳机单元 (HSP/HFP)"

View file

@ -53,7 +53,6 @@ export ALSA_PLUGIN_DIR="${BUILDDIR}/pipewire-alsa/alsa-plugins"
export PW_BUILDDIR=$BUILDDIR
export PW_UNINSTALLED=1
export PKG_CONFIG_PATH="${BUILDDIR}/meson-uninstalled/:${PKG_CONFIG_PATH}"
export PIPEWIRE_LOG_SYSTEMD=false
if [ -d "${BUILDDIR}/subprojects/wireplumber" ]; then
# FIXME: find a nice, shell-neutral way to specify a prompt

View file

@ -578,7 +578,7 @@ static int make_nodes(struct data *data)
SPA_PARAM_PORT_CONFIG_direction, SPA_POD_Id(SPA_DIRECTION_OUTPUT),
SPA_PARAM_PORT_CONFIG_mode, SPA_POD_Id(SPA_PARAM_PORT_CONFIG_MODE_dsp),
SPA_PARAM_PORT_CONFIG_format, SPA_POD_Pod(param));
if ((res = spa_node_set_param(data->source_node, SPA_PARAM_PortConfig, 0, param)) < 0) {
if ((res = spa_node_set_param(data->source_node, SPA_PARAM_PortConfig, 0, param) < 0)) {
printf("can't setup source node %d\n", res);
return res;
}
@ -647,7 +647,7 @@ static int make_nodes(struct data *data)
SPA_PARAM_PORT_CONFIG_format, SPA_POD_Pod(param));
if ((res = spa_node_set_param(data->sink_node, SPA_PARAM_PortConfig, 0, param)) < 0) {
if ((res = spa_node_set_param(data->sink_node, SPA_PARAM_PortConfig, 0, param) < 0)) {
printf("can't setup sink node %d\n", res);
return res;
}
@ -987,7 +987,7 @@ int main(int argc, char *argv[])
setlocale(LC_ALL, "");
while ((c = getopt_long(argc, argv, "hd:m:s:t:i:a:c:", long_options, NULL)) != -1) {
while ((c = getopt_long(argc, argv, "hdmstiac:", long_options, NULL)) != -1) {
switch (c) {
case 'h':
show_help(&data, argv[0], false);

View file

@ -24,7 +24,6 @@
#include <SDL2/SDL.h>
#include <spa/support/plugin.h>
#include <spa/utils/keys.h>
#include <spa/utils/names.h>
#include <spa/utils/result.h>
#include <spa/utils/string.h>
@ -84,8 +83,7 @@ struct data {
unsigned int n_buffers;
};
static int load_handle(struct data *data, struct spa_handle **handle, const char *lib, const char *name,
const struct spa_dict *params)
static int load_handle(struct data *data, struct spa_handle **handle, const char *lib, const char *name)
{
int res;
void *hnd;
@ -119,9 +117,9 @@ static int load_handle(struct data *data, struct spa_handle **handle, const char
if (!spa_streq(factory->name, name))
continue;
*handle = calloc(1, spa_handle_factory_get_size(factory, params));
*handle = calloc(1, spa_handle_factory_get_size(factory, NULL));
if ((res = spa_handle_factory_init(factory, *handle,
params, data->support,
NULL, data->support,
data->n_support)) < 0) {
printf("can't make factory instance: %d\n", res);
return res;
@ -131,14 +129,13 @@ static int load_handle(struct data *data, struct spa_handle **handle, const char
return -EBADF;
}
static int make_node(struct data *data, struct spa_node **node, const char *lib, const char *name,
const struct spa_dict *params)
static int make_node(struct data *data, struct spa_node **node, const char *lib, const char *name)
{
struct spa_handle *handle = NULL;
void *iface;
int res;
if ((res = load_handle(data, &handle, lib, name, params)) < 0)
if ((res = load_handle(data, &handle, lib, name)) < 0)
return res;
if ((res = spa_handle_get_interface(handle, SPA_TYPE_INTERFACE_Node, &iface)) < 0) {
@ -240,13 +237,10 @@ static int make_nodes(struct data *data, const char *device)
uint8_t buffer[256];
uint32_t index;
const struct spa_dict_item items[] = {
{ SPA_KEY_API_LIBCAMERA_PATH, device },
};
if ((res = make_node(data, &data->source,
"libcamera/libspa-libcamera.so", SPA_NAME_API_LIBCAMERA_SOURCE,
&SPA_DICT_INIT_ARRAY(items))) < 0) {
if ((res =
make_node(data, &data->source,
"libcamera/libspa-libcamera.so",
SPA_NAME_API_LIBCAMERA_SOURCE)) < 0) {
printf("can't create libcamera-source: %d\n", res);
return res;
}
@ -260,6 +254,14 @@ static int make_nodes(struct data *data, const char *device)
spa_debug_pod(0, NULL, props);
}
spa_pod_builder_init(&b, buffer, sizeof(buffer));
props = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_Props, 0,
SPA_PROP_device, SPA_POD_String(device ? device : "/dev/media0"));
if ((res = spa_node_set_param(data->source, SPA_PARAM_Props, 0, props)) < 0)
printf("got set_props error %d\n", res);
return res;
}
@ -440,18 +442,13 @@ int main(int argc, char *argv[])
struct spa_handle *handle = NULL;
void *iface;
if (argc < 2) {
printf("usage: %s <camera-id>\n", argv[0]);
return EXIT_FAILURE;
}
if ((str = getenv("SPA_PLUGIN_DIR")) == NULL)
str = PLUGINDIR;
data.plugin_dir = str;
if ((res = load_handle(&data, &handle,
"support/libspa-support.so",
SPA_NAME_SUPPORT_SYSTEM, NULL)) < 0)
SPA_NAME_SUPPORT_SYSTEM)) < 0)
return res;
if ((res = spa_handle_get_interface(handle, SPA_TYPE_INTERFACE_System, &iface)) < 0) {
@ -463,7 +460,7 @@ int main(int argc, char *argv[])
if ((res = load_handle(&data, &handle,
"support/libspa-support.so",
SPA_NAME_SUPPORT_LOOP, NULL)) < 0)
SPA_NAME_SUPPORT_LOOP)) < 0)
return res;
if ((res = spa_handle_get_interface(handle, SPA_TYPE_INTERFACE_Loop, &iface)) < 0) {

View file

@ -5,12 +5,12 @@
#ifndef SPA_BUFFER_ALLOC_H
#define SPA_BUFFER_ALLOC_H
#include <spa/buffer/buffer.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <spa/buffer/buffer.h>
#ifndef SPA_API_BUFFER_ALLOC
#ifdef SPA_API_IMPL
#define SPA_API_BUFFER_ALLOC SPA_API_IMPL
@ -122,7 +122,7 @@ SPA_API_BUFFER_ALLOC int spa_buffer_alloc_fill_info(struct spa_buffer_alloc_info
* | | uint32_t offset |
* | | uint32_t size |
* | | int32_t stride |
* | | int32_t flags |
* | | int32_t dummy |
* | | ... <n_datas> chunks |
* | +------------------------------+
* +>| data | memory for n_datas data, aligned

View file

@ -5,13 +5,13 @@
#ifndef SPA_BUFFER_H
#define SPA_BUFFER_H
#include <spa/utils/defs.h>
#include <spa/buffer/meta.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <spa/utils/defs.h>
#include <spa/buffer/meta.h>
#ifndef SPA_API_BUFFER
#ifdef SPA_API_IMPL
#define SPA_API_BUFFER SPA_API_IMPL
@ -118,17 +118,6 @@ SPA_API_BUFFER void *spa_buffer_find_meta_data(const struct spa_buffer *b, uint3
return NULL;
}
SPA_API_BUFFER bool spa_buffer_has_meta_features(const struct spa_buffer *b, uint32_t type, uint32_t features)
{
uint32_t i;
for (i = 0; i < b->n_metas; i++) {
uint32_t t = b->metas[i].type;
if ((t >> 16) == type && (t & features) == features)
return true;
}
return false;
}
/**
* \}
*/

View file

@ -5,13 +5,13 @@
#ifndef SPA_META_H
#define SPA_META_H
#include <spa/utils/defs.h>
#include <spa/pod/pod.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <spa/utils/defs.h>
#include <spa/pod/pod.h>
#ifndef SPA_API_META
#ifdef SPA_API_IMPL
#define SPA_API_META SPA_API_IMPL
@ -37,17 +37,10 @@ enum spa_meta_type {
SPA_META_Busy, /**< don't write to buffer when count > 0 */
SPA_META_VideoTransform, /**< struct spa_meta_transform */
SPA_META_SyncTimeline, /**< struct spa_meta_sync_timeline */
_SPA_META_LAST, /**< not part of ABI/API */
SPA_META_START_custom = 0x200,
SPA_META_START_features = 0x10000, /* features start, these have 0 size, the
* type in the upper 16 bits and a bitmask in
* the lower 16 bits with type specific features. */
};
#define SPA_META_TYPE_FEATURES(type,features) (((type)<<16)|(features))
/**
* A metadata element.
*
@ -190,12 +183,7 @@ struct spa_meta_videotransform {
* this metadata as SPA_PARAM_BUFFERS_metaType when negotiating a buffer
* layout with 2 extra fds.
*/
#define SPA_META_FEATURE_SYNC_TIMELINE_RELEASE (1<<0) /**< metadata supports RELEASE */
struct spa_meta_sync_timeline {
#define SPA_META_SYNC_TIMELINE_UNSCHEDULED_RELEASE (1<<0) /**< this flag is set by the producer and cleared
* by the consumer when it promises to signal
* the release point */
uint32_t flags;
uint32_t padding;
uint64_t acquire_point; /**< the timeline acquire point, this is when the data

View file

@ -5,10 +5,6 @@
#ifndef SPA_BUFFER_TYPES_H
#define SPA_BUFFER_TYPES_H
#include <spa/buffer/buffer.h>
#include <spa/buffer/meta.h>
#include <spa/utils/type.h>
/**
* \addtogroup spa_buffer
* \{
@ -18,6 +14,10 @@
extern "C" {
#endif
#include <spa/buffer/buffer.h>
#include <spa/buffer/meta.h>
#include <spa/utils/type.h>
#define SPA_TYPE_INFO_Buffer SPA_TYPE_INFO_POINTER_BASE "Buffer"
#define SPA_TYPE_INFO_BUFFER_BASE SPA_TYPE_INFO_Buffer ":"

View file

@ -5,13 +5,13 @@
#ifndef SPA_CONTROL_H
#define SPA_CONTROL_H
#include <spa/utils/defs.h>
#include <spa/pod/pod.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <spa/utils/defs.h>
#include <spa/pod/pod.h>
/** \defgroup spa_control Control
* Control type declarations
*/

View file

@ -5,10 +5,6 @@
#ifndef SPA_CONTROL_TYPES_H
#define SPA_CONTROL_TYPES_H
#include <spa/utils/defs.h>
#include <spa/utils/type.h>
#include <spa/control/control.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -18,6 +14,10 @@ extern "C" {
* \{
*/
#include <spa/utils/defs.h>
#include <spa/utils/type.h>
#include <spa/control/control.h>
/* base for parameter object enumerations */
#define SPA_TYPE_INFO_Control SPA_TYPE_INFO_ENUM_BASE "Control"
#define SPA_TYPE_INFO_CONTROL_BASE SPA_TYPE_INFO_Control ":"

View file

@ -6,13 +6,13 @@
#ifndef SPA_CONTROL_UMP_UTILS_H
#define SPA_CONTROL_UMP_UTILS_H
#include <errno.h>
#include <spa/utils/defs.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <errno.h>
#include <spa/utils/defs.h>
#ifndef SPA_API_CONTROL_UMP_UTILS
#ifdef SPA_API_IMPL
#define SPA_API_CONTROL_UMP_UTILS SPA_API_IMPL
@ -48,98 +48,72 @@ SPA_API_CONTROL_UMP_UTILS size_t spa_ump_message_size(uint8_t message_type)
return ump_sizes[message_type & 0xf];
}
SPA_API_CONTROL_UMP_UTILS int spa_ump_to_midi(const uint32_t **ump, size_t *ump_size,
uint8_t *midi, size_t midi_maxsize, uint64_t *state)
SPA_API_CONTROL_UMP_UTILS int spa_ump_to_midi(uint32_t *ump, size_t ump_size,
uint8_t *midi, size_t midi_maxsize)
{
int size = 0;
uint32_t to_consume = 0;
const uint32_t *u = *ump;
if (*ump_size < 4 ||
(to_consume = (spa_ump_message_size(u[0]>>28) * 4)) > *ump_size) {
to_consume = *ump_size;
goto done;
}
if (ump_size < 4)
return 0;
if (midi_maxsize < 8)
return -ENOSPC;
switch (u[0] >> 28) {
switch (ump[0] >> 28) {
case 0x1: /* System Real Time and System Common Messages (except System Exclusive) */
midi[size++] = (u[0] >> 16) & 0xff;
midi[size++] = (ump[0] >> 16) & 0xff;
if (midi[0] >= 0xf1 && midi[0] <= 0xf3) {
midi[size++] = (u[0] >> 8) & 0x7f;
midi[size++] = (ump[0] >> 8) & 0x7f;
if (midi[0] == 0xf2)
midi[size++] = u[0] & 0x7f;
midi[size++] = ump[0] & 0x7f;
}
break;
case 0x2: /* MIDI 1.0 Channel Voice Messages */
midi[size++] = (u[0] >> 16);
midi[size++] = (u[0] >> 8);
midi[size++] = (ump[0] >> 16);
midi[size++] = (ump[0] >> 8);
if (midi[0] < 0xc0 || midi[0] > 0xdf)
midi[size++] = (u[0]);
midi[size++] = (ump[0]);
break;
case 0x3: /* Data Messages (including System Exclusive) */
{
uint8_t status, i, bytes;
status = (u[0] >> 20) & 0xf;
bytes = SPA_CLAMP((u[0] >> 16) & 0xf, 0u, 6u);
if (ump_size < 8)
return 0;
status = (ump[0] >> 20) & 0xf;
bytes = SPA_CLAMP((ump[0] >> 16) & 0xf, 0u, 6u);
if (status == 0 || status == 1)
midi[size++] = 0xf0;
for (i = 0 ; i < bytes; i++)
/* u[0] >> 8 | u[0] | u[1] >> 24 | u[1] >>16 ... */
midi[size++] = u[(i+2)/4] >> ((5-i)%4 * 8);
/* ump[0] >> 8 | ump[0] | ump[1] >> 24 | ump[1] >>16 ... */
midi[size++] = ump[(i+2)/4] >> ((5-i)%4 * 8);
if (status == 0 || status == 3)
midi[size++] = 0xf7;
break;
}
case 0x4: /* MIDI 2.0 Channel Voice Messages */
{
uint8_t status = (u[0] >> 16) | 0x80;
switch (status & 0xf0) {
if (ump_size < 8)
return 0;
midi[size++] = (ump[0] >> 16) | 0x80;
switch (midi[0] & 0xf0) {
case 0xc0:
/* program/bank change */
if (!(u[0] & 1))
*state = 2;
if (*state == 0) {
midi[size++] = (status & 0xf) | 0xb0;
midi[size++] = 0;
midi[size++] = (u[1] >> 8);
to_consume = 0;
*state = 1;
}
else if (*state == 1) {
midi[size++] = (status & 0xf) | 0xb0;
midi[size++] = 32;
midi[size++] = u[1];
to_consume = 0;
*state = 2;
}
else if (*state == 2) {
midi[size++] = status;
midi[size++] = (u[1] >> 24);
*state = 0;
}
midi[size++] = (ump[1] >> 24);
break;
default:
midi[size++] = status;
midi[size++] = (u[0] >> 8) & 0x7f;
midi[size++] = (ump[0] >> 8) & 0x7f;
SPA_FALLTHROUGH;
case 0xd0:
midi[size++] = (u[1] >> 25);
midi[size++] = (ump[1] >> 25);
break;
}
break;
}
case 0x0: /* Utility Messages */
case 0x5: /* Data Messages */
default:
break;
return 0;
}
done:
(*ump_size) -= to_consume;
(*ump) = SPA_PTROFF(*ump, to_consume, uint32_t);
return size;
}
@ -223,15 +197,15 @@ SPA_API_CONTROL_UMP_UTILS int spa_ump_from_midi(uint8_t **midi, size_t *midi_siz
break;
case 0xf2:
to_consume = 3;
prefix |= 0x10000000;
prefix = 0x10000000;
break;
case 0xf1: case 0xf3:
to_consume = 2;
prefix |= 0x10000000;
prefix = 0x10000000;
break;
case 0xf4 ... 0xff:
to_consume = 1;
prefix |= 0x10000000;
prefix = 0x10000000;
break;
default:
return -EIO;

View file

@ -5,11 +5,6 @@
#ifndef SPA_DEBUG_BUFFER_H
#define SPA_DEBUG_BUFFER_H
#include <spa/debug/context.h>
#include <spa/debug/mem.h>
#include <spa/debug/types.h>
#include <spa/buffer/type-info.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -23,6 +18,11 @@ extern "C" {
* \{
*/
#include <spa/debug/context.h>
#include <spa/debug/mem.h>
#include <spa/debug/types.h>
#include <spa/buffer/type-info.h>
#ifndef SPA_API_DEBUG_BUFFER
#ifdef SPA_API_IMPL
#define SPA_API_DEBUG_BUFFER SPA_API_IMPL

View file

@ -5,16 +5,15 @@
#ifndef SPA_DEBUG_CONTEXT_H
#define SPA_DEBUG_CONTEXT_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include <stdarg.h>
#include <ctype.h>
#include <spa/utils/defs.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* \addtogroup spa_debug
* \{

View file

@ -5,9 +5,6 @@
#ifndef SPA_DEBUG_DICT_H
#define SPA_DEBUG_DICT_H
#include <spa/debug/context.h>
#include <spa/utils/dict.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -17,6 +14,9 @@ extern "C" {
* \{
*/
#include <spa/debug/context.h>
#include <spa/utils/dict.h>
#ifndef SPA_API_DEBUG_DICT
#ifdef SPA_API_IMPL
#define SPA_API_DEBUG_DICT SPA_API_IMPL

View file

@ -5,6 +5,10 @@
#ifndef SPA_DEBUG_FILE_H
#define SPA_DEBUG_FILE_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include <stdarg.h>
#include <ctype.h>
@ -17,10 +21,6 @@
#include <spa/debug/mem.h>
#include <spa/debug/pod.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* \addtogroup spa_debug
* \{

View file

@ -5,15 +5,6 @@
#ifndef SPA_DEBUG_FORMAT_H
#define SPA_DEBUG_FORMAT_H
#include <inttypes.h>
#include <spa/pod/iter.h>
#include <spa/utils/string.h>
#include <spa/debug/context.h>
#include <spa/debug/types.h>
#include <spa/param/type-info.h>
#include <spa/param/format-utils.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -23,6 +14,13 @@ extern "C" {
* \{
*/
#include <spa/pod/parser.h>
#include <spa/utils/string.h>
#include <spa/debug/context.h>
#include <spa/debug/types.h>
#include <spa/param/type-info.h>
#include <spa/param/format-utils.h>
#ifndef SPA_API_DEBUG_FORMAT
#ifdef SPA_API_IMPL
#define SPA_API_DEBUG_FORMAT SPA_API_IMPL
@ -43,11 +41,10 @@ spa_debug_strbuf_format_value(struct spa_strbuf *buffer, const struct spa_type_i
break;
case SPA_TYPE_Id:
{
uint32_t value = *(uint32_t *) body;
const char *str = spa_debug_type_find_short_name(info, value);
const char *str = spa_debug_type_find_short_name(info, *(int32_t *) body);
char tmp[64];
if (str == NULL) {
snprintf(tmp, sizeof(tmp), "%" PRIu32, value);
snprintf(tmp, sizeof(tmp), "%d", *(int32_t*)body);
str = tmp;
}
spa_strbuf_append(buffer, "%s", str);
@ -66,7 +63,7 @@ spa_debug_strbuf_format_value(struct spa_strbuf *buffer, const struct spa_type_i
spa_strbuf_append(buffer, "%f", *(double *) body);
break;
case SPA_TYPE_String:
spa_strbuf_append(buffer, "%-*s", size, (char *) body);
spa_strbuf_append(buffer, "%s", (char *) body);
break;
case SPA_TYPE_Rectangle:
{
@ -93,13 +90,11 @@ spa_debug_strbuf_format_value(struct spa_strbuf *buffer, const struct spa_type_i
int i = 0;
info = info && info->values ? info->values : info;
spa_strbuf_append(buffer, "< ");
if (b->child.size >= spa_pod_type_size(b->child.type)) {
SPA_POD_ARRAY_BODY_FOREACH(b, size, p) {
if (i++ > 0)
spa_strbuf_append(buffer, ", ");
spa_debug_strbuf_format_value(buffer, info, b->child.type, p, b->child.size);
}
}
spa_strbuf_append(buffer, " >");
break;
}
@ -133,7 +128,7 @@ SPA_API_DEBUG_FORMAT int spa_debugc_format(struct spa_debug_context *ctx, int in
if (info == NULL)
info = spa_type_format;
if (format == NULL || format->type != SPA_TYPE_Object)
if (format == NULL || SPA_POD_TYPE(format) != SPA_TYPE_Object)
return -EINVAL;
if (spa_format_parse(format, &mtype, &mstype) < 0)
@ -163,11 +158,11 @@ SPA_API_DEBUG_FORMAT int spa_debugc_format(struct spa_debug_context *ctx, int in
type = val->type;
size = val->size;
vals = SPA_POD_BODY(val);
if (type < SPA_TYPE_None || type >= _SPA_TYPE_LAST || n_vals < 1)
if (type < SPA_TYPE_None || type >= _SPA_TYPE_LAST)
continue;
vals = SPA_POD_BODY(val);
ti = spa_debug_type_find(info, prop->key);
key = ti ? ti->name : NULL;

View file

@ -5,6 +5,10 @@
#ifndef SPA_DEBUG_LOG_H
#define SPA_DEBUG_LOG_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include <stdarg.h>
@ -16,10 +20,6 @@
#include <spa/debug/mem.h>
#include <spa/debug/pod.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef SPA_API_DEBUG_LOG
#ifdef SPA_API_IMPL
#define SPA_API_DEBUG_LOG SPA_API_IMPL

View file

@ -5,19 +5,19 @@
#ifndef SPA_DEBUG_MEM_H
#define SPA_DEBUG_MEM_H
#include <inttypes.h>
#include <spa/debug/context.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <inttypes.h>
/**
* \addtogroup spa_debug
* \{
*/
#include <spa/debug/context.h>
#ifndef SPA_API_DEBUG_MEM
#ifdef SPA_API_IMPL
#define SPA_API_DEBUG_MEM SPA_API_IMPL

View file

@ -5,10 +5,6 @@
#ifndef SPA_DEBUG_NODE_H
#define SPA_DEBUG_NODE_H
#include <spa/node/node.h>
#include <spa/debug/context.h>
#include <spa/debug/dict.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -18,6 +14,10 @@ extern "C" {
* \{
*/
#include <spa/node/node.h>
#include <spa/debug/context.h>
#include <spa/debug/dict.h>
#ifndef SPA_API_DEBUG_NODE
#ifdef SPA_API_IMPL
#define SPA_API_DEBUG_NODE SPA_API_IMPL

View file

@ -5,14 +5,6 @@
#ifndef SPA_DEBUG_POD_H
#define SPA_DEBUG_POD_H
#include <inttypes.h>
#include <spa/debug/context.h>
#include <spa/debug/mem.h>
#include <spa/debug/types.h>
#include <spa/pod/pod.h>
#include <spa/pod/iter.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -22,6 +14,12 @@ extern "C" {
* \{
*/
#include <spa/debug/context.h>
#include <spa/debug/mem.h>
#include <spa/debug/types.h>
#include <spa/pod/pod.h>
#include <spa/pod/iter.h>
#ifndef SPA_API_DEBUG_POD
#ifdef SPA_API_IMPL
#define SPA_API_DEBUG_POD SPA_API_IMPL
@ -39,11 +37,11 @@ spa_debugc_pod_value(struct spa_debug_context *ctx, int indent, const struct spa
spa_debugc(ctx, "%*s" "Bool %s", indent, "", (*(int32_t *) body) ? "true" : "false");
break;
case SPA_TYPE_Id:
spa_debugc(ctx, "%*s" "Id %-8" PRIu32 " (%s)", indent, "", *(uint32_t *) body,
spa_debug_type_find_name(info, *(uint32_t *) body));
spa_debugc(ctx, "%*s" "Id %-8d (%s)", indent, "", *(int32_t *) body,
spa_debug_type_find_name(info, *(int32_t *) body));
break;
case SPA_TYPE_Int:
spa_debugc(ctx, "%*s" "Int %" PRId32, indent, "", *(int32_t *) body);
spa_debugc(ctx, "%*s" "Int %d", indent, "", *(int32_t *) body);
break;
case SPA_TYPE_Long:
spa_debugc(ctx, "%*s" "Long %" PRIi64 "", indent, "", *(int64_t *) body);
@ -87,18 +85,13 @@ spa_debugc_pod_value(struct spa_debug_context *ctx, int indent, const struct spa
struct spa_pod_array_body *b = (struct spa_pod_array_body *)body;
void *p;
const struct spa_type_info *ti = spa_debug_type_find(SPA_TYPE_ROOT, b->child.type);
uint32_t min_size = spa_pod_type_size(b->child.type);
spa_debugc(ctx, "%*s" "Array: child.size %" PRIu32 ", child.type %s", indent, "",
spa_debugc(ctx, "%*s" "Array: child.size %d, child.type %s", indent, "",
b->child.size, ti ? ti->name : "unknown");
if (b->child.size < min_size) {
spa_debugc(ctx, "%*s" " INVALID child.size < %" PRIu32, indent, "", min_size);
} else {
info = info && info->values ? info->values : info;
SPA_POD_ARRAY_BODY_FOREACH(b, size, p)
spa_debugc_pod_value(ctx, indent + 2, info, b->child.type, p, b->child.size);
}
break;
}
case SPA_TYPE_Choice:
@ -106,31 +99,20 @@ spa_debugc_pod_value(struct spa_debug_context *ctx, int indent, const struct spa
struct spa_pod_choice_body *b = (struct spa_pod_choice_body *)body;
void *p;
const struct spa_type_info *ti = spa_debug_type_find(spa_type_choice, b->type);
uint32_t min_size = spa_pod_type_size(b->child.type);
spa_debugc(ctx, "%*s" "Choice: type %s, flags %08" PRIx32 " %" PRIu32 " %" PRIu32, indent, "",
spa_debugc(ctx, "%*s" "Choice: type %s, flags %08x %d %d", indent, "",
ti ? ti->name : "unknown", b->flags, size, b->child.size);
if (b->child.size < min_size) {
spa_debugc(ctx, "%*s" "INVALID child.size < %" PRIu32, indent, "", min_size);
} else {
SPA_POD_CHOICE_BODY_FOREACH(b, size, p)
spa_debugc_pod_value(ctx, indent + 2, info, b->child.type, p, b->child.size);
}
break;
}
case SPA_TYPE_Struct:
{
struct spa_pod *b = (struct spa_pod *)body, *p;
spa_debugc(ctx, "%*s" "Struct: size %" PRIu32, indent, "", size);
SPA_POD_FOREACH(b, size, p) {
uint32_t min_size = spa_pod_type_size(p->type);
if (p->size < min_size) {
spa_debugc(ctx, "%*s" "INVALID child.size < %" PRIu32, indent, "", min_size);
} else {
spa_debugc(ctx, "%*s" "Struct: size %d", indent, "", size);
SPA_POD_FOREACH(b, size, p)
spa_debugc_pod_value(ctx, indent + 2, info, p->type, SPA_POD_BODY(p), p->size);
}
}
break;
}
case SPA_TYPE_Object:
@ -143,38 +125,22 @@ spa_debugc_pod_value(struct spa_debug_context *ctx, int indent, const struct spa
ii = ti ? spa_debug_type_find(ti->values, 0) : NULL;
ii = ii ? spa_debug_type_find(ii->values, b->id) : NULL;
spa_debugc(ctx, "%*s" "Object: size %" PRIu32 ", type %s (%" PRIu32 "), id %s (%" PRIu32 ")",
indent, "", size, ti ? ti->name : "unknown", b->type, ii ? ii->name : "unknown", b->id);
spa_debugc(ctx, "%*s" "Object: size %d, type %s (%d), id %s (%d)", indent, "", size,
ti ? ti->name : "unknown", b->type, ii ? ii->name : "unknown", b->id);
info = ti ? ti->values : info;
SPA_POD_OBJECT_BODY_FOREACH(b, size, p) {
static const char custom_prefix[] = SPA_TYPE_INFO_PROPS_BASE "Custom:";
char custom_name[sizeof(custom_prefix) + 16];
const char *name = "unknown";
uint32_t min_size = spa_pod_type_size(p->value.type);
ii = spa_debug_type_find(info, p->key);
if (ii) {
name = ii->name;
} else if (p->key >= SPA_PROP_START_CUSTOM) {
snprintf(custom_name, sizeof(custom_name),
"%s%" PRIu32, custom_prefix, p->key - SPA_PROP_START_CUSTOM);
name = custom_name;
}
spa_debugc(ctx, "%*s" "Prop: key %s (%" PRIu32 "), flags %08" PRIx32,
indent+2, "", name, p->key, p->flags);
spa_debugc(ctx, "%*s" "Prop: key %s (%d), flags %08x", indent+2, "",
ii ? ii->name : "unknown", p->key, p->flags);
if (p->value.size < min_size) {
spa_debugc(ctx, "%*s" "INVALID value.size < %" PRIu32, indent, "", min_size);
} else {
spa_debugc_pod_value(ctx, indent + 4, ii ? ii->values : NULL,
p->value.type,
SPA_POD_CONTENTS(struct spa_pod_prop, p),
p->value.size);
}
}
break;
}
case SPA_TYPE_Sequence:
@ -185,26 +151,20 @@ spa_debugc_pod_value(struct spa_debug_context *ctx, int indent, const struct spa
ti = spa_debug_type_find(info, b->unit);
spa_debugc(ctx, "%*s" "Sequence: size %" PRIu32 ", unit %s", indent, "", size,
spa_debugc(ctx, "%*s" "Sequence: size %d, unit %s", indent, "", size,
ti ? ti->name : "unknown");
SPA_POD_SEQUENCE_BODY_FOREACH(b, size, c) {
uint32_t min_size = spa_pod_type_size(c->value.type);
ii = spa_debug_type_find(spa_type_control, c->type);
spa_debugc(ctx, "%*s" "Control: offset %" PRIu32 ", type %s", indent+2, "",
spa_debugc(ctx, "%*s" "Control: offset %d, type %s", indent+2, "",
c->offset, ii ? ii->name : "unknown");
if (c->value.size < min_size) {
spa_debugc(ctx, "%*s" "INVALID value.size < %" PRIu32, indent, "", min_size);
} else {
spa_debugc_pod_value(ctx, indent + 4, ii ? ii->values : NULL,
c->value.type,
SPA_POD_CONTENTS(struct spa_pod_control, c),
c->value.size);
}
}
break;
}
case SPA_TYPE_Bytes:
@ -216,7 +176,7 @@ spa_debugc_pod_value(struct spa_debug_context *ctx, int indent, const struct spa
spa_debugc_mem(ctx, indent + 2, body, size);
break;
default:
spa_debugc(ctx, "%*s" "unhandled POD type %" PRIu32, indent, "", type);
spa_debugc(ctx, "%*s" "unhandled POD type %d", indent, "", type);
break;
}
return 0;
@ -225,10 +185,10 @@ spa_debugc_pod_value(struct spa_debug_context *ctx, int indent, const struct spa
SPA_API_DEBUG_POD int spa_debugc_pod(struct spa_debug_context *ctx, int indent,
const struct spa_type_info *info, const struct spa_pod *pod)
{
if (pod->size < spa_pod_type_size(pod->type))
return -EINVAL;
return spa_debugc_pod_value(ctx, indent, info ? info : SPA_TYPE_ROOT,
pod->type, SPA_POD_BODY(pod), pod->size);
SPA_POD_TYPE(pod),
SPA_POD_BODY(pod),
SPA_POD_BODY_SIZE(pod));
}
SPA_API_DEBUG_POD int

View file

@ -5,10 +5,6 @@
#ifndef SPA_DEBUG_TYPES_H
#define SPA_DEBUG_TYPES_H
#include <spa/utils/type-info.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -18,6 +14,10 @@ extern "C" {
* \{
*/
#include <spa/utils/type-info.h>
#include <string.h>
#ifndef SPA_API_DEBUG_TYPES
#ifdef SPA_API_IMPL
#define SPA_API_DEBUG_TYPES SPA_API_IMPL

View file

@ -5,16 +5,16 @@
#ifndef SPA_FILTER_GRAPH_H
#define SPA_FILTER_GRAPH_H
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/types.h>
#include <spa/utils/defs.h>
#include <spa/utils/hook.h>
#include <spa/pod/builder.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef SPA_API_FILTER_GRAPH
#ifdef SPA_API_IMPL
#define SPA_API_FILTER_GRAPH SPA_API_IMPL

View file

@ -5,13 +5,6 @@
#ifndef SPA_GRAPH_H
#define SPA_GRAPH_H
#include <spa/utils/atomic.h>
#include <spa/utils/defs.h>
#include <spa/utils/list.h>
#include <spa/utils/hook.h>
#include <spa/node/node.h>
#include <spa/node/io.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -25,6 +18,13 @@ extern "C" {
* \{
*/
#include <spa/utils/atomic.h>
#include <spa/utils/defs.h>
#include <spa/utils/list.h>
#include <spa/utils/hook.h>
#include <spa/node/node.h>
#include <spa/node/io.h>
#ifndef SPA_API_GRAPH
#ifdef SPA_API_IMPL
#define SPA_API_GRAPH SPA_API_IMPL

View file

@ -5,15 +5,15 @@
#ifndef SPA_DEVICE_H
#define SPA_DEVICE_H
#ifdef __cplusplus
extern "C" {
#endif
#include <spa/utils/defs.h>
#include <spa/utils/hook.h>
#include <spa/utils/dict.h>
#include <spa/pod/event.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef SPA_API_DEVICE
#ifdef SPA_API_IMPL
#define SPA_API_DEVICE SPA_API_IMPL

View file

@ -5,12 +5,12 @@
#ifndef SPA_EVENT_DEVICE_H
#define SPA_EVENT_DEVICE_H
#include <spa/pod/event.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <spa/pod/event.h>
/**
* \addtogroup spa_device
* \{

View file

@ -5,14 +5,14 @@
#ifndef SPA_DEVICE_TYPE_INFO_H
#define SPA_DEVICE_TYPE_INFO_H
#include <spa/utils/type-info.h>
#include <spa/monitor/event.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <spa/utils/type-info.h>
#include <spa/monitor/event.h>
/**
* \addtogroup spa_device
* \{

View file

@ -5,13 +5,13 @@
#ifndef SPA_DEVICE_UTILS_H
#define SPA_DEVICE_UTILS_H
#include <spa/pod/builder.h>
#include <spa/monitor/device.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <spa/pod/builder.h>
#include <spa/monitor/device.h>
#ifndef SPA_API_DEVICE_UTILS
#ifdef SPA_API_IMPL
#define SPA_API_DEVICE_UTILS SPA_API_IMPL

View file

@ -5,8 +5,6 @@
#ifndef SPA_COMMAND_NODE_H
#define SPA_COMMAND_NODE_H
#include <spa/pod/command.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -16,6 +14,8 @@ extern "C" {
* \{
*/
#include <spa/pod/command.h>
/* object id of SPA_TYPE_COMMAND_Node */
enum spa_node_command {
SPA_NODE_COMMAND_Suspend, /**< suspend a node, this removes all configured
@ -36,24 +36,12 @@ enum spa_node_command {
SPA_NODE_COMMAND_ParamEnd, /**< end a transaction */
SPA_NODE_COMMAND_RequestProcess,/**< Sent to a driver when some other node emitted
* the RequestProcess event. */
SPA_NODE_COMMAND_User, /**< User defined command */
};
#define SPA_NODE_COMMAND_ID(cmd) SPA_COMMAND_ID(cmd, SPA_TYPE_COMMAND_Node)
#define SPA_NODE_COMMAND_INIT(id) SPA_COMMAND_INIT(SPA_TYPE_COMMAND_Node, id)
/* properties for SPA_TYPE_COMMAND_Node */
enum spa_command_node {
SPA_COMMAND_NODE_START,
SPA_COMMAND_NODE_START_User = 0x1000,
SPA_COMMAND_NODE_extra, /** extra info (String) */
SPA_COMMAND_NODE_START_CUSTOM = 0x1000000,
};
/**
* \}
*/

View file

@ -5,8 +5,6 @@
#ifndef SPA_EVENT_NODE_H
#define SPA_EVENT_NODE_H
#include <spa/pod/event.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -16,6 +14,8 @@ extern "C" {
* \{
*/
#include <spa/pod/event.h>
/* object id of SPA_TYPE_EVENT_Node */
enum spa_node_event {
SPA_NODE_EVENT_Error,
@ -23,7 +23,6 @@ enum spa_node_event {
SPA_NODE_EVENT_RequestRefresh,
SPA_NODE_EVENT_RequestProcess, /*< Ask the driver to start processing
* the graph */
SPA_NODE_EVENT_User, /* User defined event */
};
#define SPA_NODE_EVENT_ID(ev) SPA_EVENT_ID(ev, SPA_TYPE_EVENT_Node)
@ -32,11 +31,6 @@ enum spa_node_event {
/* properties for SPA_TYPE_EVENT_Node */
enum spa_event_node {
SPA_EVENT_NODE_START,
SPA_EVENT_NODE_START_User = 0x1000,
SPA_EVENT_NODE_extra, /** extra info (String) */
SPA_EVENT_NODE_START_CUSTOM = 0x1000000,
};
/**

View file

@ -5,9 +5,6 @@
#ifndef SPA_IO_H
#define SPA_IO_H
#include <spa/utils/defs.h>
#include <spa/pod/pod.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -17,6 +14,9 @@ extern "C" {
* \{
*/
#include <spa/utils/defs.h>
#include <spa/pod/pod.h>
/** IO areas
*
* IO information for a port on a node. This is allocated
@ -114,54 +114,23 @@ struct spa_io_range {
* Driver nodes are supposed to update the contents of \ref SPA_IO_Clock before
* signaling the start of a graph cycle. These updated clock values become
* visible to other nodes in \ref SPA_IO_Position. Non-driver nodes do
* not need to update the contents of their \ref SPA_IO_Clock. Also
* see \ref page_driver for further details.
* not need to update the contents of their \ref SPA_IO_Clock.
*
* The host generally gives each node a separate \ref spa_io_clock in \ref
* SPA_IO_Clock, so that updates made by the driver are not visible in the
* contents of \ref SPA_IO_Clock of other nodes. Instead, \ref SPA_IO_Position
* is used to look up the current graph time.
*
* A node is a driver when \ref spa_io_clock::id and the ID in
* \ref spa_io_position.clock in \ref SPA_IO_Position are the same.
*
* The flags are set by the graph driver at the start of each cycle.
* A node is a driver when \ref spa_io_clock.id in \ref SPA_IO_Clock and
* \ref spa_io_position.clock.id in \ref SPA_IO_Position are the same.
*/
struct spa_io_clock {
#define SPA_IO_CLOCK_FLAG_FREEWHEEL (1u<<0) /**< Graph is freewheeling. It runs at the maximum
* possible rate, only constrained by the processing
* power of the machine it runs on. This can be useful
* for offline processing, where processing in real
* time is not desired. */
#define SPA_IO_CLOCK_FLAG_XRUN_RECOVER (1u<<1) /**< A node's process callback did not complete within
* the last cycle's deadline, resulting in an xrun.
* This flag is not set for the entire graph. Instead,
* it is set at the start of the current cycle before
* a node that experienced an xrun has its process
* callback invoked. After said callback finished, the
* flag is cleared again. That way, the node knows that
* during the last cycle it experienced an xrun. They
* can use this information for example to resynchronize
* or clear custom stale states. */
#define SPA_IO_CLOCK_FLAG_LAZY (1u<<2) /**< The driver uses lazy scheduling. For details, see
* \ref PW_KEY_NODE_SUPPORTS_LAZY . */
#define SPA_IO_CLOCK_FLAG_NO_RATE (1u<<3) /**< The rate of the clock is only approximately.
* It is recommended to use the nsec as a clock source.
#define SPA_IO_CLOCK_FLAG_FREEWHEEL (1u<<0) /* graph is freewheeling */
#define SPA_IO_CLOCK_FLAG_XRUN_RECOVER (1u<<1) /* recovering from xrun */
#define SPA_IO_CLOCK_FLAG_LAZY (1u<<2) /* lazy scheduling */
#define SPA_IO_CLOCK_FLAG_NO_RATE (1u<<3) /* the rate of the clock is only approximately.
* it is recommended to use the nsec as a clock source.
* The rate_diff contains the measured inaccuracy. */
#define SPA_IO_CLOCK_FLAG_DISCONT (1u<<4) /**< The clock experienced a discontinuity in its
* timestamps since the last cycle. If this is set,
* nodes know that timestamps between the last and
* the current cycle cannot be assumed to be
* continuous. Nodes that synchronize playback against
* clock timestamps should resynchronize (for example
* by flushing buffers to avoid incorrect delays).
* This differs from an xrun in that it is not necessariy
* an error and that it is not caused by missed process
* deadlines. If for example a custom network time
* based driver starts to follow a different time
* server, and the offset between that server and its
* local clock consequently suddenly changes, then that
* driver should set this flag. */
uint32_t flags; /**< Clock flags */
uint32_t id; /**< Unique clock id, set by host application */
char name[64]; /**< Clock name prefixed with API, set by node when it receives
@ -169,16 +138,13 @@ struct spa_io_clock {
* can be used to check if nodes share the same clock. */
uint64_t nsec; /**< Time in nanoseconds against monotonic clock
* (CLOCK_MONOTONIC). This fields reflects a real time instant
* in the past, when the current cycle started. The value may
* have jitter. */
* in the past. The value may have jitter. */
struct spa_fraction rate; /**< Rate for position/duration/delay/xrun */
uint64_t position; /**< Current position, in samples @ \ref rate */
uint64_t duration; /**< Duration of current cycle, in samples @ \ref rate */
int64_t delay; /**< Delay between position and hardware, in samples @ \ref rate */
double rate_diff; /**< Rate difference between clock and monotonic time, as a ratio of
* clock speeds. A value higher than 1.0 means that the driver's
* internal clock is faster than the monotonic clock (by that
* factor), and vice versa. */
* clock speeds. */
uint64_t next_nsec; /**< Estimated next wakeup time in nanoseconds.
* This time is a logical start time of the next cycle, and
* is not necessarily in the future.
@ -312,8 +278,8 @@ enum spa_io_position_state {
*
* It is set on all nodes in \ref SPA_IO_Position, and the contents of \ref
* spa_io_position.clock contain the clock updates made by the driving node in
* the graph in its \ref SPA_IO_Clock. Also, the ID in \ref spa_io_position.clock
* will be the clock id of the driving node in the graph.
* the graph in its \ref SPA_IO_Clock. Also, \ref spa_io_position.clock.id
* will contain the clock id of the driving node in the graph.
*
* The position clock indicates the logical start time of the current graph
* cycle.
@ -347,7 +313,7 @@ struct spa_io_position {
* and node rates. The \a flags and \a rate fields may be modified by the node.
*
* The node can request a correction to the resampling rate in its process(), by setting
* \ref SPA_IO_RATE_MATCH_FLAG_ACTIVE on \a flags, and setting \a rate to the desired rate
* \ref SPA_IO_RATE_MATCH_ACTIVE on \a flags, and setting \a rate to the desired rate
* correction. Usually the rate is obtained from DLL or other adaptive mechanism that
* e.g. drives the node buffer fill level toward a specific value.
*

View file

@ -5,14 +5,6 @@
#ifndef SPA_NODE_H
#define SPA_NODE_H
#include <errno.h>
#include <spa/utils/defs.h>
#include <spa/utils/type.h>
#include <spa/utils/hook.h>
#include <spa/buffer/buffer.h>
#include <spa/node/event.h>
#include <spa/node/command.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -27,6 +19,14 @@ extern "C" {
* \{
*/
#include <errno.h>
#include <spa/utils/defs.h>
#include <spa/utils/type.h>
#include <spa/utils/hook.h>
#include <spa/buffer/buffer.h>
#include <spa/node/event.h>
#include <spa/node/command.h>
#ifndef SPA_API_NODE
#ifdef SPA_API_IMPL
#define SPA_API_NODE SPA_API_IMPL

View file

@ -5,12 +5,6 @@
#ifndef SPA_NODE_TYPES_H
#define SPA_NODE_TYPES_H
#include <spa/utils/type.h>
#include <spa/node/command.h>
#include <spa/node/event.h>
#include <spa/node/io.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -20,6 +14,12 @@ extern "C" {
* \{
*/
#include <spa/utils/type.h>
#include <spa/node/command.h>
#include <spa/node/event.h>
#include <spa/node/io.h>
#define SPA_TYPE_INFO_IO SPA_TYPE_INFO_ENUM_BASE "IO"
#define SPA_TYPE_INFO_IO_BASE SPA_TYPE_INFO_IO ":"
@ -46,15 +46,11 @@ static const struct spa_type_info spa_type_node_event_id[] = {
{ SPA_NODE_EVENT_Buffering, SPA_TYPE_EVENT_Node, SPA_TYPE_INFO_NODE_EVENT_BASE "Buffering", NULL },
{ SPA_NODE_EVENT_RequestRefresh, SPA_TYPE_EVENT_Node, SPA_TYPE_INFO_NODE_EVENT_BASE "RequestRefresh", NULL },
{ SPA_NODE_EVENT_RequestProcess, SPA_TYPE_EVENT_Node, SPA_TYPE_INFO_NODE_EVENT_BASE "RequestProcess", NULL },
{ SPA_NODE_EVENT_User, SPA_TYPE_EVENT_Node, SPA_TYPE_INFO_NODE_EVENT_BASE "User", NULL },
{ 0, 0, NULL, NULL },
};
static const struct spa_type_info spa_type_node_event[] = {
{ SPA_EVENT_NODE_START, SPA_TYPE_Id, SPA_TYPE_INFO_NODE_EVENT_BASE, spa_type_node_event_id },
{ SPA_EVENT_NODE_extra, SPA_TYPE_String, SPA_TYPE_INFO_NODE_EVENT_BASE "extra", NULL },
{ 0, 0, NULL, NULL },
};
@ -73,15 +69,11 @@ static const struct spa_type_info spa_type_node_command_id[] = {
{ SPA_NODE_COMMAND_ParamBegin, SPA_TYPE_COMMAND_Node, SPA_TYPE_INFO_NODE_COMMAND_BASE "ParamBegin", NULL },
{ SPA_NODE_COMMAND_ParamEnd, SPA_TYPE_COMMAND_Node, SPA_TYPE_INFO_NODE_COMMAND_BASE "ParamEnd", NULL },
{ SPA_NODE_COMMAND_RequestProcess, SPA_TYPE_COMMAND_Node, SPA_TYPE_INFO_NODE_COMMAND_BASE "RequestProcess", NULL },
{ SPA_NODE_COMMAND_User, SPA_TYPE_COMMAND_Node, SPA_TYPE_INFO_NODE_COMMAND_BASE "User", NULL },
{ 0, 0, NULL, NULL },
};
static const struct spa_type_info spa_type_node_command[] = {
{ SPA_COMMAND_NODE_START, SPA_TYPE_Id, SPA_TYPE_INFO_NODE_COMMAND_BASE, spa_type_node_command_id },
{ SPA_COMMAND_NODE_extra, SPA_TYPE_String, SPA_TYPE_INFO_NODE_COMMAND_BASE "extra", NULL },
{ 0, SPA_TYPE_Id, SPA_TYPE_INFO_NODE_COMMAND_BASE, spa_type_node_command_id },
{ 0, 0, NULL, NULL },
};

View file

@ -5,10 +5,6 @@
#ifndef SPA_NODE_UTILS_H
#define SPA_NODE_UTILS_H
#include <spa/pod/builder.h>
#include <spa/node/node.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -18,6 +14,10 @@ extern "C" {
* \{
*/
#include <spa/pod/builder.h>
#include <spa/node/node.h>
#ifndef SPA_API_NODE_UTILS
#ifdef SPA_API_IMPL
#define SPA_API_NODE_UTILS SPA_API_IMPL

View file

@ -5,13 +5,13 @@
#ifndef SPA_AUDIO_AAC_TYPES_H
#define SPA_AUDIO_AAC_TYPES_H
#include <spa/utils/type.h>
#include <spa/param/audio/aac.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <spa/utils/type.h>
#include <spa/param/audio/aac.h>
/**
* \addtogroup spa_param
* \{

View file

@ -5,11 +5,6 @@
#ifndef SPA_AUDIO_AAC_UTILS_H
#define SPA_AUDIO_AAC_UTILS_H
#include <spa/pod/parser.h>
#include <spa/pod/builder.h>
#include <spa/param/audio/format.h>
#include <spa/param/format-utils.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -19,6 +14,11 @@ extern "C" {
* \{
*/
#include <spa/pod/parser.h>
#include <spa/pod/builder.h>
#include <spa/param/audio/format.h>
#include <spa/param/format-utils.h>
#ifndef SPA_API_AUDIO_AAC_UTILS
#ifdef SPA_API_IMPL
#define SPA_API_AUDIO_AAC_UTILS SPA_API_IMPL

View file

@ -5,12 +5,12 @@
#ifndef SPA_AUDIO_AAC_H
#define SPA_AUDIO_AAC_H
#include <spa/param/audio/raw.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <spa/param/audio/raw.h>
/**
* \addtogroup spa_param
* \{
@ -18,19 +18,19 @@ extern "C" {
enum spa_audio_aac_stream_format {
SPA_AUDIO_AAC_STREAM_FORMAT_UNKNOWN,
/** Raw AAC frames */
/* Raw AAC frames */
SPA_AUDIO_AAC_STREAM_FORMAT_RAW,
/** ISO/IEC 13818-7 MPEG-2 Audio Data Transport Stream (ADTS) */
/* ISO/IEC 13818-7 MPEG-2 Audio Data Transport Stream (ADTS) */
SPA_AUDIO_AAC_STREAM_FORMAT_MP2ADTS,
/** ISO/IEC 14496-3 MPEG-4 Audio Data Transport Stream (ADTS) */
/* ISO/IEC 14496-3 MPEG-4 Audio Data Transport Stream (ADTS) */
SPA_AUDIO_AAC_STREAM_FORMAT_MP4ADTS,
/** ISO/IEC 14496-3 Low Overhead Audio Stream (LOAS) */
/* ISO/IEC 14496-3 Low Overhead Audio Stream (LOAS) */
SPA_AUDIO_AAC_STREAM_FORMAT_MP4LOAS,
/** ISO/IEC 14496-3 Low Overhead Audio Transport Multiplex (LATM) */
/* ISO/IEC 14496-3 Low Overhead Audio Transport Multiplex (LATM) */
SPA_AUDIO_AAC_STREAM_FORMAT_MP4LATM,
/** ISO/IEC 14496-3 Audio Data Interchange Format (ADIF) */
/* ISO/IEC 14496-3 Audio Data Interchange Format (ADIF) */
SPA_AUDIO_AAC_STREAM_FORMAT_ADIF,
/** ISO/IEC 14496-12 MPEG-4 file format */
/* ISO/IEC 14496-12 MPEG-4 file format */
SPA_AUDIO_AAC_STREAM_FORMAT_MP4FF,
SPA_AUDIO_AAC_STREAM_FORMAT_CUSTOM = 0x10000,

View file

@ -1,69 +0,0 @@
/* Simple Plugin API */
/* SPDX-FileCopyrightText: Copyright © 2025 Carlos Rafael Giani */
/* SPDX-License-Identifier: MIT */
#ifndef SPA_AUDIO_AC3_UTILS_H
#define SPA_AUDIO_AC3_UTILS_H
#include <spa/pod/parser.h>
#include <spa/pod/builder.h>
#include <spa/param/audio/format.h>
#include <spa/param/format-utils.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* \addtogroup spa_param
* \{
*/
#ifndef SPA_API_AUDIO_AC3_UTILS
#ifdef SPA_API_IMPL
#define SPA_API_AUDIO_AC3_UTILS SPA_API_IMPL
#else
#define SPA_API_AUDIO_AC3_UTILS static inline
#endif
#endif
SPA_API_AUDIO_AC3_UTILS int
spa_format_audio_ac3_parse(const struct spa_pod *format, struct spa_audio_info_ac3 *info)
{
int res;
res = spa_pod_parse_object(format,
SPA_TYPE_OBJECT_Format, NULL,
SPA_FORMAT_AUDIO_rate, SPA_POD_OPT_Int(&info->rate),
SPA_FORMAT_AUDIO_channels, SPA_POD_OPT_Int(&info->channels));
return res;
}
SPA_API_AUDIO_AC3_UTILS struct spa_pod *
spa_format_audio_ac3_build(struct spa_pod_builder *builder, uint32_t id,
const struct spa_audio_info_ac3 *info)
{
struct spa_pod_frame f;
spa_pod_builder_push_object(builder, &f, SPA_TYPE_OBJECT_Format, id);
spa_pod_builder_add(builder,
SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_audio),
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_ac3),
SPA_FORMAT_AUDIO_format, SPA_POD_Id(SPA_AUDIO_FORMAT_ENCODED),
0);
if (info->rate != 0)
spa_pod_builder_add(builder,
SPA_FORMAT_AUDIO_rate, SPA_POD_Int(info->rate), 0);
if (info->channels != 0)
spa_pod_builder_add(builder,
SPA_FORMAT_AUDIO_channels, SPA_POD_Int(info->channels), 0);
return (struct spa_pod*)spa_pod_builder_pop(builder, &f);
}
/**
* \}
*/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* SPA_AUDIO_AC3_UTILS_H */

View file

@ -1,35 +0,0 @@
/* Simple Plugin API */
/* SPDX-FileCopyrightText: Copyright © 2025 Carlos Rafael Giani */
/* SPDX-License-Identifier: MIT */
#ifndef SPA_AUDIO_AC3_H
#define SPA_AUDIO_AC3_H
#include <spa/param/audio/raw.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* \addtogroup spa_param
* \{
*/
/** Dolby AC-3 audio info. */
struct spa_audio_info_ac3 {
uint32_t rate; /*< sample rate */
uint32_t channels; /*< number of channels */
};
#define SPA_AUDIO_INFO_AC3_INIT(...) ((struct spa_audio_info_ac3) { __VA_ARGS__ })
/**
* \}
*/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* SPA_AUDIO_AC3_H */

View file

@ -5,11 +5,6 @@
#ifndef SPA_AUDIO_ALAC_UTILS_H
#define SPA_AUDIO_ALAC_UTILS_H
#include <spa/pod/parser.h>
#include <spa/pod/builder.h>
#include <spa/param/audio/format.h>
#include <spa/param/format-utils.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -19,6 +14,11 @@ extern "C" {
* \{
*/
#include <spa/pod/parser.h>
#include <spa/pod/builder.h>
#include <spa/param/audio/format.h>
#include <spa/param/format-utils.h>
#ifndef SPA_API_AUDIO_ALAC_UTILS
#ifdef SPA_API_IMPL
#define SPA_API_AUDIO_ALAC_UTILS SPA_API_IMPL

View file

@ -5,12 +5,12 @@
#ifndef SPA_AUDIO_ALAC_H
#define SPA_AUDIO_ALAC_H
#include <spa/param/audio/raw.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <spa/param/audio/raw.h>
/**
* \addtogroup spa_param
* \{

View file

@ -5,13 +5,13 @@
#ifndef SPA_AUDIO_AMR_TYPES_H
#define SPA_AUDIO_AMR_TYPES_H
#include <spa/utils/type.h>
#include <spa/param/audio/amr.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <spa/utils/type.h>
#include <spa/param/audio/amr.h>
/**
* \addtogroup spa_param
* \{

View file

@ -5,11 +5,6 @@
#ifndef SPA_AUDIO_AMR_UTILS_H
#define SPA_AUDIO_AMR_UTILS_H
#include <spa/pod/parser.h>
#include <spa/pod/builder.h>
#include <spa/param/audio/format.h>
#include <spa/param/format-utils.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -19,6 +14,11 @@ extern "C" {
* \{
*/
#include <spa/pod/parser.h>
#include <spa/pod/builder.h>
#include <spa/param/audio/format.h>
#include <spa/param/format-utils.h>
#ifndef SPA_API_AUDIO_AMR_UTILS
#ifdef SPA_API_IMPL
#define SPA_API_AUDIO_AMR_UTILS SPA_API_IMPL

View file

@ -5,12 +5,12 @@
#ifndef SPA_AUDIO_AMR_H
#define SPA_AUDIO_AMR_H
#include <spa/param/audio/raw.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <spa/param/audio/raw.h>
/**
* \addtogroup spa_param
* \{

View file

@ -5,11 +5,6 @@
#ifndef SPA_AUDIO_APE_UTILS_H
#define SPA_AUDIO_APE_UTILS_H
#include <spa/pod/parser.h>
#include <spa/pod/builder.h>
#include <spa/param/audio/format.h>
#include <spa/param/format-utils.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -19,6 +14,11 @@ extern "C" {
* \{
*/
#include <spa/pod/parser.h>
#include <spa/pod/builder.h>
#include <spa/param/audio/format.h>
#include <spa/param/format-utils.h>
#ifndef SPA_API_AUDIO_APE_UTILS
#ifdef SPA_API_IMPL
#define SPA_API_AUDIO_APE_UTILS SPA_API_IMPL

View file

@ -5,12 +5,12 @@
#ifndef SPA_AUDIO_APE_H
#define SPA_AUDIO_APE_H
#include <spa/param/audio/raw.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <spa/param/audio/raw.h>
/**
* \addtogroup spa_param
* \{

View file

@ -7,17 +7,12 @@
#define SPA_AUDIO_COMPRESSED_H
#include <spa/param/audio/aac.h>
#include <spa/param/audio/ac3.h>
#include <spa/param/audio/alac.h>
#include <spa/param/audio/amr.h>
#include <spa/param/audio/ape.h>
#include <spa/param/audio/dts.h>
#include <spa/param/audio/flac.h>
#include <spa/param/audio/mp3.h>
#include <spa/param/audio/mpegh.h>
#include <spa/param/audio/opus.h>
#include <spa/param/audio/ra.h>
#include <spa/param/audio/truehd.h>
#include <spa/param/audio/vorbis.h>
#include <spa/param/audio/wma.h>

View file

@ -5,12 +5,6 @@
#ifndef SPA_AUDIO_DSD_UTILS_H
#define SPA_AUDIO_DSD_UTILS_H
#include <spa/pod/iter.h>
#include <spa/pod/parser.h>
#include <spa/pod/builder.h>
#include <spa/param/format-utils.h>
#include <spa/param/audio/format.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -20,6 +14,11 @@ extern "C" {
* \{
*/
#include <spa/pod/parser.h>
#include <spa/pod/builder.h>
#include <spa/param/format-utils.h>
#include <spa/param/audio/format.h>
#ifndef SPA_API_AUDIO_DSD_UTILS
#ifdef SPA_API_IMPL
#define SPA_API_AUDIO_DSD_UTILS SPA_API_IMPL
@ -42,7 +41,7 @@ spa_format_audio_dsd_parse(const struct spa_pod *format, struct spa_audio_info_d
SPA_FORMAT_AUDIO_channels, SPA_POD_OPT_Int(&info->channels),
SPA_FORMAT_AUDIO_position, SPA_POD_OPT_Pod(&position));
if (position == NULL ||
!spa_pod_copy_array(position, SPA_TYPE_Id, info->position, SPA_N_ELEMENTS(info->position)))
!spa_pod_copy_array(position, SPA_TYPE_Id, info->position, SPA_AUDIO_MAX_CHANNELS))
SPA_FLAG_SET(info->flags, SPA_AUDIO_FLAG_UNPOSITIONED);
return res;

View file

@ -7,13 +7,13 @@
#include <stdint.h>
#include <spa/param/param.h>
#include <spa/param/audio/raw.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <spa/param/param.h>
#include <spa/param/audio/raw.h>
/**
* \addtogroup spa_param
* \{

View file

@ -5,11 +5,6 @@
#ifndef SPA_AUDIO_DSP_UTILS_H
#define SPA_AUDIO_DSP_UTILS_H
#include <spa/pod/parser.h>
#include <spa/pod/builder.h>
#include <spa/param/audio/format.h>
#include <spa/param/format-utils.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -19,6 +14,11 @@ extern "C" {
* \{
*/
#include <spa/pod/parser.h>
#include <spa/pod/builder.h>
#include <spa/param/audio/format.h>
#include <spa/param/format-utils.h>
#ifndef SPA_API_AUDIO_DSP_UTILS
#ifdef SPA_API_IMPL
#define SPA_API_AUDIO_DSP_UTILS SPA_API_IMPL

View file

@ -5,12 +5,12 @@
#ifndef SPA_AUDIO_DSP_H
#define SPA_AUDIO_DSP_H
#include <spa/param/audio/raw.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <spa/param/audio/raw.h>
/**
* \addtogroup spa_param
* \{

View file

@ -1,39 +0,0 @@
/* Simple Plugin API */
/* SPDX-FileCopyrightText: Copyright © 2025 Carlos Rafael Giani */
/* SPDX-License-Identifier: MIT */
#ifndef SPA_AUDIO_DTS_TYPES_H
#define SPA_AUDIO_DTS_TYPES_H
#include <spa/utils/type.h>
#include <spa/param/audio/dts.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* \addtogroup spa_param
* \{
*/
#define SPA_TYPE_INFO_AudioDTSExtType SPA_TYPE_INFO_ENUM_BASE "AudioDTSExtType"
#define SPA_TYPE_INFO_AUDIO_DTS_EXT_TYPE_BASE SPA_TYPE_INFO_AudioDTSExtType ":"
static const struct spa_type_info spa_type_audio_dts_ext_type[] = {
{ SPA_AUDIO_DTS_EXT_UNKNOWN, SPA_TYPE_Int, SPA_TYPE_INFO_AUDIO_DTS_EXT_TYPE_BASE "UNKNOWN", NULL },
{ SPA_AUDIO_DTS_EXT_NONE, SPA_TYPE_Int, SPA_TYPE_INFO_AUDIO_DTS_EXT_TYPE_BASE "NONE", NULL },
{ SPA_AUDIO_DTS_EXT_HD_HRA, SPA_TYPE_Int, SPA_TYPE_INFO_AUDIO_DTS_EXT_TYPE_BASE "HRA", NULL },
{ SPA_AUDIO_DTS_EXT_HD_MA, SPA_TYPE_Int, SPA_TYPE_INFO_AUDIO_DTS_EXT_TYPE_BASE "MA", NULL },
{ 0, 0, NULL, NULL },
};
/**
* \}
*/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* SPA_AUDIO_DTS_TYPES_H */

Some files were not shown because too many files have changed in this diff Show more