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
606 changed files with 22439 additions and 36826 deletions

View file

@ -18,8 +18,8 @@ stages:
variables: variables:
FDO_UPSTREAM_REPO: 'pipewire/pipewire' FDO_UPSTREAM_REPO: 'pipewire/pipewire'
# ci-templates as of Mar 25th 2024 # ci-templates as of Jan 27th 2022
.templates_sha: &templates_sha ef5e4669b7500834a17ffe9277e15fbb6d977fff .templates_sha: &templates_sha 0c312d9c7255f46e741d43bcd1930f09cd12efe7
include: include:
- project: 'freedesktop/ci-templates' - project: 'freedesktop/ci-templates'
@ -31,15 +31,12 @@ include:
- project: 'freedesktop/ci-templates' - project: 'freedesktop/ci-templates'
ref: *templates_sha ref: *templates_sha
file: '/templates/alpine.yml' file: '/templates/alpine.yml'
- project: 'freedesktop/ci-templates'
ref: *templates_sha
file: '/templates/debian.yml'
.fedora: .fedora:
variables: variables:
# Update this tag when you want to trigger a rebuild # Update this tag when you want to trigger a rebuild
FDO_DISTRIBUTION_TAG: '2025-10-22.0' FDO_DISTRIBUTION_TAG: '2024-12-10.0'
FDO_DISTRIBUTION_VERSION: '42' FDO_DISTRIBUTION_VERSION: '40'
FDO_DISTRIBUTION_PACKAGES: >- FDO_DISTRIBUTION_PACKAGES: >-
alsa-lib-devel alsa-lib-devel
avahi-devel avahi-devel
@ -48,7 +45,6 @@ include:
dbus-devel dbus-devel
doxygen doxygen
fdk-aac-free-devel fdk-aac-free-devel
file
findutils findutils
gcc gcc
gcc-c++ gcc-c++
@ -59,7 +55,6 @@ include:
gstreamer1-plugins-base-devel gstreamer1-plugins-base-devel
jack-audio-connection-kit-devel jack-audio-connection-kit-devel
libasan libasan
liblc3-devel
libcanberra-devel libcanberra-devel
libebur128-devel libebur128-devel
libffado-devel libffado-devel
@ -69,6 +64,7 @@ include:
libubsan libubsan
libusb1-devel libusb1-devel
lilv-devel lilv-devel
libv4l-devel
libva-devel libva-devel
libX11-devel libX11-devel
ModemManager-devel ModemManager-devel
@ -80,7 +76,6 @@ include:
sbc-devel sbc-devel
ShellCheck ShellCheck
SDL2-devel SDL2-devel
spandsp-devel
systemd-devel systemd-devel
vulkan-loader-devel vulkan-loader-devel
webrtc-audio-processing-devel webrtc-audio-processing-devel
@ -92,9 +87,6 @@ include:
openal-soft openal-soft
readline-devel readline-devel
pandoc pandoc
fftw-libs-single
fftw-devel
onnxruntime-devel
# Uncommenting the following two lines and disabling the meson entry above # 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 # 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 # image first or making the build system compatible instead! This is because
@ -109,7 +101,7 @@ include:
.ubuntu: .ubuntu:
variables: variables:
# Update this tag when you want to trigger a rebuild # 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_VERSION: '22.04'
FDO_DISTRIBUTION_PACKAGES: >- FDO_DISTRIBUTION_PACKAGES: >-
debhelper-compat debhelper-compat
@ -130,6 +122,7 @@ include:
libsnapd-glib-dev libsnapd-glib-dev
libudev-dev libudev-dev
libva-dev libva-dev
libv4l-dev
libx11-dev libx11-dev
meson meson
ninja-build ninja-build
@ -145,34 +138,10 @@ include:
# FDO_DISTRIBUTION_EXEC: >- # FDO_DISTRIBUTION_EXEC: >-
# pip3 install meson # 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: .alpine:
variables: variables:
# Update this tag when you want to trigger a rebuild # 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_VERSION: '3.20'
FDO_DISTRIBUTION_PACKAGES: >- FDO_DISTRIBUTION_PACKAGES: >-
alsa-lib-dev alsa-lib-dev
@ -241,8 +210,7 @@ include:
- echo "Building with meson options $MESON_OPTIONS" - echo "Building with meson options $MESON_OPTIONS"
- meson setup "$BUILD_DIR" --prefix="$PREFIX" $MESON_OPTIONS - meson setup "$BUILD_DIR" --prefix="$PREFIX" $MESON_OPTIONS
- meson compile -C "$BUILD_DIR" $COMPILE_ARGS - 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 -C "$BUILD_DIR" --no-rebuild $MESON_TEST_OPTIONS
- meson install -C "$BUILD_DIR" --no-rebuild - meson install -C "$BUILD_DIR" --no-rebuild
artifacts: artifacts:
name: pipewire-$CI_COMMIT_SHA name: pipewire-$CI_COMMIT_SHA
@ -258,18 +226,6 @@ container_ubuntu:
variables: variables:
GIT_STRATEGY: none # no need to pull the whole tree for rebuilding the image 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: container_fedora:
extends: extends:
- .fedora - .fedora
@ -302,54 +258,9 @@ build_on_ubuntu:
- .fdo.distribution-image@ubuntu - .fdo.distribution-image@ubuntu
- .build - .build
stage: build stage: build
needs:
- job: container_ubuntu
artifacts: false
variables: variables:
MESON_OPTIONS: "-Dsession-managers=[] -Dsnap=enabled" 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: .build_on_fedora:
extends: extends:
- .fedora - .fedora
@ -357,9 +268,6 @@ build_on_debian:
- .fdo.distribution-image@fedora - .fdo.distribution-image@fedora
- .build - .build
stage: build stage: build
needs:
- job: container_fedora
artifacts: false
build_on_fedora: build_on_fedora:
extends: extends:
@ -410,13 +318,11 @@ build_on_fedora_html_docs:
-Dsndfile=enabled -Dsndfile=enabled
-Dsession-managers=[] -Dsession-managers=[]
before_script: 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 branch -f 1.0 origin/1.0
- git clone -b 1.0 . branch-1.0 - git clone -b 1.0 . branch-1.0
- git branch -f 1.2 origin/1.2 - git branch -f 1.2 origin/1.2
- git clone -b 1.2 . branch-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 branch -f master origin/master
- git clone -b master . branch-master - git clone -b master . branch-master
- !reference [.build, before_script] - !reference [.build, before_script]
@ -429,10 +335,6 @@ build_on_fedora_html_docs:
- meson setup builddir $MESON_OPTIONS - meson setup builddir $MESON_OPTIONS
- meson compile -C builddir doc/pipewire-docs - meson compile -C builddir doc/pipewire-docs
- cd .. - cd ..
- cd branch-1.4
- meson setup builddir $MESON_OPTIONS
- meson compile -C builddir doc/pipewire-docs
- cd ..
- cd branch-master - cd branch-master
- meson setup builddir $MESON_OPTIONS - meson setup builddir $MESON_OPTIONS
- meson compile -C builddir doc/pipewire-docs - meson compile -C builddir doc/pipewire-docs
@ -452,9 +354,6 @@ build_on_alpine:
- .fdo.distribution-image@alpine - .fdo.distribution-image@alpine
- .build - .build
stage: build stage: build
needs:
- job: container_alpine
artifacts: false
variables: variables:
MESON_OPTIONS: "-Dsession-managers=[] -Dsnap=disabled -Dlogind=enabled -Dlogind-provider=libelogind" MESON_OPTIONS: "-Dsession-managers=[] -Dsnap=disabled -Dlogind=enabled -Dlogind-provider=libelogind"
@ -463,13 +362,13 @@ build_all:
extends: extends:
- .build_on_fedora - .build_on_fedora
variables: 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 # libcamera has no stable API, so let's not chase that target
MESON_OPTIONS: >- MESON_OPTIONS: >-
-Dauto_features=enabled -Dauto_features=enabled
-Dbluez5-codec-aptx=disabled -Dbluez5-codec-aptx=disabled
-Dbluez5-codec-lc3plus=disabled -Dbluez5-codec-lc3plus=disabled
-Dbluez5-codec-ldac-dec=disabled -Dbluez5-codec-lc3=disabled
-Droc=disabled -Droc=disabled
-Dlibcamera=disabled -Dlibcamera=disabled
-Dsession-managers=[] -Dsession-managers=[]
@ -589,9 +488,6 @@ build_with_coverity:
- .fdo.suffixed-image@fedora - .fdo.suffixed-image@fedora
- .build - .build
stage: analysis stage: analysis
needs:
- job: container_coverity
artifacts: false
script: script:
- export PATH=/opt/coverity/bin:$PATH - export PATH=/opt/coverity/bin:$PATH
- meson setup "$BUILD_DIR" --prefix="$PREFIX" - meson setup "$BUILD_DIR" --prefix="$PREFIX"
@ -667,9 +563,8 @@ check_missing_headers:
- .not_coverity - .not_coverity
- .fdo.distribution-image@fedora - .fdo.distribution-image@fedora
stage: analysis stage: analysis
needs: dependencies:
- job: build_on_fedora - build_on_fedora
artifacts: true
script: script:
- export PREFIX=`find -name prefix-*` - export PREFIX=`find -name prefix-*`
- ./.gitlab/ci/check_missing_headers.sh - ./.gitlab/ci/check_missing_headers.sh
@ -678,18 +573,18 @@ pages:
extends: extends:
- .not_coverity - .not_coverity
stage: pages stage: pages
needs: dependencies:
- job: build_on_fedora_html_docs - build_on_fedora_html_docs
artifacts: true
script: 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.0/builddir/doc/html/* public/1.0/
- cp -R branch-1.2/builddir/doc/html/* public/1.2/ - 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/ - cp -R branch-master/builddir/doc/html/* public/devel/
- (cd public && ln -s 1.4/* .) - (cd public && ln -s 1.2/* .)
artifacts: artifacts:
paths: paths:
- public - public
rules: rules:
- if: $CI_COMMIT_BRANCH == 'master' - 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 \ PIPEWIRE_CONFIG_DIR=$(BUILD_ROOT)/src/daemon \
ACP_PATHS_DIR=$(SOURCE_ROOT)/spa/plugins/alsa/mixer/paths \ ACP_PATHS_DIR=$(SOURCE_ROOT)/spa/plugins/alsa/mixer/paths \
ACP_PROFILES_DIR=$(SOURCE_ROOT)/spa/plugins/alsa/mixer/profile-sets \ ACP_PROFILES_DIR=$(SOURCE_ROOT)/spa/plugins/alsa/mixer/profile-sets \
PIPEWIRE_LOG_SYSTEMD=false \
$(DBG) $(BUILD_ROOT)/src/daemon/pipewire-uninstalled $(DBG) $(BUILD_ROOT)/src/daemon/pipewire-uninstalled
run-pulse: all run-pulse: all
@ -33,7 +32,6 @@ run-pulse: all
PIPEWIRE_CONFIG_DIR=$(BUILD_ROOT)/src/daemon \ PIPEWIRE_CONFIG_DIR=$(BUILD_ROOT)/src/daemon \
ACP_PATHS_DIR=$(SOURCE_ROOT)/spa/plugins/alsa/mixer/paths \ ACP_PATHS_DIR=$(SOURCE_ROOT)/spa/plugins/alsa/mixer/paths \
ACP_PROFILES_DIR=$(SOURCE_ROOT)/spa/plugins/alsa/mixer/profile-sets \ ACP_PROFILES_DIR=$(SOURCE_ROOT)/spa/plugins/alsa/mixer/profile-sets \
PIPEWIRE_LOG_SYSTEMD=false \
$(DBG) $(BUILD_ROOT)/src/daemon/pipewire-pulse $(DBG) $(BUILD_ROOT)/src/daemon/pipewire-pulse
gdb: 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 This is a quick bugfix release that is API and ABI compatible with
compatible with previous 1.4.x, 1.2.x and 1.0.x releases. previous 1.x releases.
In addition to all the changes backported to 1.4.x, this release
also contains some new features:
## Highlights ## Highlights
- The link negotiation code was refactored and improved. - Provide better compatibility with 1.2 for MIDI.
Applications now have more options for selecting the default - Fix mpv buffer negotiation regression.
values and restricting the available options. The default - Improve GStreamer compatibility with libcamera.
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.
## 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 ## SPA
- The loop now has support for locking with priority inversion. Most - Provide conversions to old style midi in the ALSA sequencer.
of the code was updated to use the locks instead of invoke to - Negotiate only to UMP when using a newer library.
get proper concurrent updates with the loop. The Thread loop - Fix negotiation direction for buffers, prefer the converter
functionality of locks, signal and wait was moved to the SPA loop. suggestion instead of the application until we can be sure
- UMP to Midi 1.0 conversion was improved, some UMP events are now applications make good suggestions.
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)
## GStreamer ## GStreamer
- Colorimetry support was added. - Allow a minimum of 1 buffers again instead of 8. libcamera will
- Cursor metadata is now exposed as ROI metadata. allocate only 4 buffers so we need to support this.
- Many more updates.
## Docs
- Document the client-node flow a bit more.
Older versions: 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) # PipeWire 1.4.0 (2025-03-06)
This is the 1.4 release that is API and ABI compatible with previous 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_ \
SPA_ SPA_
GENERATE_TREEVIEW = YES GENERATE_TREEVIEW = YES
DISABLE_INDEX = NO
SEARCHENGINE = YES SEARCHENGINE = YES
GENERATE_LATEX = NO GENERATE_LATEX = NO

View file

@ -41,11 +41,6 @@
<tab type="globals" visible="no" title="" intro=""/> <tab type="globals" visible="no" title="" intro=""/>
</tab> </tab>
<tab type="examples" visible="yes" title="" intro=""/> <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> </navindex>
<!-- Layout definition for a class page --> <!-- Layout definition for a class page -->

View file

@ -1,4 +1,4 @@
html { :root {
/* --page-background-color: #729fcf; */ /* --page-background-color: #729fcf; */
--primary-color: #729fcf; --primary-color: #729fcf;
--primary-dark-color: #729fcf; --primary-dark-color: #729fcf;
@ -8,7 +8,7 @@ html {
} }
@media (prefers-color-scheme: light) { @media (prefers-color-scheme: light) {
html { :root {
--code-background: #f5f5f5; --code-background: #f5f5f5;
--code-foreground: #333333; --code-foreground: #333333;
--fragment-background: #f5f5f5; --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_Bytes`: A byte array.
- `SPA_TYPE_Rectangle`: A rectangle with width and height. - `SPA_TYPE_Rectangle`: A rectangle with width and height.
- `SPA_TYPE_Fraction`: A fraction with numerator and denominator. - `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: POD's can be grouped together in these container types:
@ -435,11 +435,10 @@ spa_pod_parser_get_object(&p,
\endcode \endcode
`spa_pod_get_values()` is a useful function. It returns a `spa_pod_get_values()` is a useful function. It returns a
`struct spa_pod*` with and array of values. For invalid PODs `struct spa_pod*` with and array of values. For normal POD's
it returns the POD and no values. For normal PODs it returns and choice none values, it simply returns the POD and one value.
the POD and one value. For choice values it returns the choice For other choice values it returns the choice type and an array
type and an array of values. If the choice doesn't fit even a of values:
single value, the array will have no values.
\code{.c} \code{.c}
struct spa_pod *value; 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. child2 and child3, in steps of child4 in the value array.
- Enum (3) : child1 is a default value, options are any value from - Enum (3) : child1 is a default value, options are any value from
the value array, preferred values come first. the value array, preferred values come first.
- Flags (4) : only child1 is a flag value. When filtering, the flags - Flags (4) : child1 is a default value, options are any value from
are AND-ed together. the value array, preferred values come first.
- flags: must be 0 - flags: must be 0
## Pod (20) ## Pod (20)

View file

@ -48,7 +48,7 @@ ALSA client match rules.
In addition, the PipeWire context configuration sections In addition, the PipeWire context configuration sections
may also be specified, see \ref page_man_pipewire_conf_5 "pipewire.conf(5)". 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: The client configuration files contain a stream.properties section that configures the options for client streams:
```css ```css
@ -93,7 +93,7 @@ A list of object properties that can be applied to streams can be found in
and and
\ref props__audio_converter_properties "pipewire-props(7) Audio Adapter Properties" \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)" You can add \ref pipewire_conf__match_rules "match rules, see pipewire(1)"
to set properties for certain streams and filters. to set properties for certain streams and filters.
@ -127,7 +127,7 @@ stream.rules = [
Will set the node.name of Firefox to "My Name". 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 An `alsa.properties` section can be added to configure client applications
that connect via the PipeWire ALSA plugin. 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 This controls the volume curve used on the ALSA mixer. Possible values are `cubic` and
`linear`. The default is to use `cubic`. `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 It is possible to set ALSA client specific properties by using
\ref pipewire_conf__match_rules "Match rules, see pipewire(1)". You can \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 In addition, the PipeWire context configuration sections
may also be specified, see \ref page_man_pipewire_conf_5 "pipewire.conf(5)". 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: The configuration file can contain an extra JACK specific section called `jack.properties` like this:
```css ```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. Set this to true for applications that know how to handle MIDI2 ports.
\endparblock \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 `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. 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 or node (ALSA, Bluetooth, ...), and have meaning only for those
objects. 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 \see [WirePlumber configuration](https://pipewire.pages.freedesktop.org/wireplumber/daemon/configuration.html)
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" } }
}
]
```
# COMMON DEVICE PROPERTIES @IDX@ props # 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 @PAR@ device-prop device.product.id # integer
\parblock \parblock
\copydoc PW_KEY_DEVICE_PRODUCT_ID \copydoc PW_KEY_DEVICE_PRODUCT_NAME
\endparblock \endparblock
@PAR@ device-prop device.product.name # string @PAR@ device-prop device.product.name # string
\parblock \parblock
\copydoc PW_KEY_DEVICE_PRODUCT_NAME \copydoc PW_KEY_DEVICE_PRODUCT_ID
\endparblock \endparblock
@PAR@ device-prop device.class # string @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. 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 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. as targets for linking by the session manager.
@PAR@ node-prop node.nick # string @PAR@ node-prop node.description
A short name for the node.
@PAR@ node-prop node.description # string
A human readable description of the node or stream. A human readable description of the node or stream.
@PAR@ node-prop media.name @PAR@ node-prop media.name
@ -424,14 +338,14 @@ a sink or source.
@PAR@ node-prop node.exclusive = false @PAR@ node-prop node.exclusive = false
If this node wants to be linked exclusively to the sink/source. 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> @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 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 deprecated, the target.object property should be used instead, which uses the more unique object.serial as
a possible target. 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 @PAR@ node-prop node.dont-reconnect = false
\parblock \parblock
When the node has a target configured and the target is destroyed, destroy the node as well. 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. should be written instead.
\endparblock \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 @PAR@ node-prop node.passive = false
\parblock \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). 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 @PAR@ node-prop priority.session # integer
The priority for selecting this node as the default source or sink. 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 ## Format Properties
Streams and also most device nodes can be configured in a certain format with 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 ## 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. 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 @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 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 default it is used instead of the ACP profiles. This option allows you to
disable this and use the ACP profiles instead. 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 \endparblock
@PAR@ device-prop api.alsa.soft-mixer = false # boolean @PAR@ device-prop api.alsa.soft-mixer = false # boolean
@ -822,13 +718,6 @@ some devices.
\copydoc SPA_KEY_API_ALSA_SPLIT_ENABLE \copydoc SPA_KEY_API_ALSA_SPLIT_ENABLE
\endparblock \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 ## Node properties
@PAR@ node-prop audio.channels # integer @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 @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 ]". 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 @PAR@ node-prop audio.allowed-rates # JSON array of integers
\parblock \parblock
The allowed audio rates to open the device with. Default is "[ ]", which means the device can be opened in any supported rate. 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. 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. 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 @PAR@ node-prop api.alsa.auto-link = false # boolean
Link follower PCM devices to the driver PCM device when using IRQ-based scheduling. 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. 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 @PAR@ node-prop api.alsa.path # string
UNDOCUMENTED 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 @PAR@ node-prop api.alsa.open.ucm # boolean
Open device using UCM. Open device using UCM.
@PAR@ node-prop api.alsa.bind-ctls # boolean @PAR@ node-prop api.alsa.bind-ctls # boolean
UNDOCUMENTED UNDOCUMENTED
@PAR@ node-prop api.alsa.bind-ctl.NAME # boolean
UNDOCUMENTED
@PAR@ node-prop iec958.codecs # JSON array of string @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. 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 Available values: PCM, AC3, DTS, MPEG, MPEG2-AAC, EAC3, TRUEHD, DTSHD
@ -944,34 +818,6 @@ Informative property.
Informative property. Informative property.
\endparblock \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 # 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 @PAR@ monitor-prop bluez5.bap-server-capabilities.max_frames # integer
Maximum number of codec frames supported per SDU for the LC3 codec (default: 2). 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 ## Device properties
@PAR@ device-prop bluez5.auto-connect # boolean @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' @PAR@ device-prop bluez5.bap.cig = "auto" # integer, or 'auto'
Set CIG ID for BAP unicast streams of the device. 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 ## Node properties
@PAR@ node-prop bluez5.media-source-role # string @PAR@ node-prop bluez5.media-source-role # string
@ -1206,17 +1007,6 @@ this instance. Available values:
- input: appear as source node. - input: appear as source node.
\endparblock \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 @IDX@ props
Port properties are usually not directly configurable via PipeWire 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 In addition, the PipeWire context configuration sections
may also be specified, see \ref page_man_pipewire_conf_5 "pipewire.conf(5)". 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 The `stream.properties` section contains properties for streams created
by the pipewire-pulse server. 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 The `stream.rules` section works the same as
\ref client_conf__stream_rules "pipewire-client.conf(5) stream.rules". \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, For `pulse.properties` section,
see \ref page_module_protocol_pulse "libpipewire-module-protocol-pulse(7)" see \ref page_module_protocol_pulse "libpipewire-module-protocol-pulse(7)"
for available options. 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` 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 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. on the server.
# CONTEXT PROPERTIES @IDX@ pipewire.conf context.properties # CONTEXT PROPERTIES @IDX@ pipewire.conf
Available PipeWire properties in `context.properties` and possible Available PipeWire properties in `context.properties` and possible
default values. default values.
@ -275,20 +275,6 @@ Warn about failures to lock memory.
@PAR@ pipewire.conf mem.mlock-all = false @PAR@ pipewire.conf mem.mlock-all = false
Try to mlock all current and future memory by the process. 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 @PAR@ pipewire.conf settings.check-quantum = false
Check if the quantum in the settings metadata update is compatible Check if the quantum in the settings metadata update is compatible
with the configured limits. 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 additional conditions that control whether a module or object is loaded
depending on what properties are present. 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 SPA plugins are loaded based on their factory-name. This is a well
known name that uniquely describes the features that the plugin should 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 PipeWire modules to be loaded. See
\ref page_man_libpipewire-modules_7 "libpipewire-modules(7)". \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 The module is loaded only if one of the expressions in the array matches
to a context property. 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 The `context.objects` section allows you to make some objects from factories (usually created
by loading modules in `context.modules`). 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 The `context.exec` section can be used to start arbitrary commands as
part of the initialization of the PipeWire program. 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 `context.properties.rules` can be used to dynamically update the properties
based on other 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 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 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. 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 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 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) - [Bluetooth, PipeWire and Whatsapp calls](https://gjhenrique.com/pipewire.html)
- [Intoduction to PipeWire](https://bootlin.com/blog/an-introduction-to-pipewire/) - [Intoduction to PipeWire](https://bootlin.com/blog/an-introduction-to-pipewire/)
- [A custom PipeWire node](https://bootlin.com/blog/a-custom-pipewire-node/) - [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 serialization/deserialization of messages. This is because the data structures
in the messages are more complicated and not easily expressible in XML. in the messages are more complicated and not easily expressible in XML.
See \ref page_module_protocol_native for details. See \ref page_module_protocol_native for details.
See also \ref page_native_protocol for the documentation of the protocol
messages.
# Extensibility # 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_library
- \subpage page_dma_buf - \subpage page_dma_buf
- \subpage page_scheduling - \subpage page_scheduling
- \subpage page_driver
- \subpage page_latency
- \subpage page_tag
- \subpage page_native_protocol - \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 attempting to create this node. It will also use inotify to wait
until the sequencer device node is accessible. until the sequencer device node is accessible.
Currently, the session manager does not try to link control messages
automatically.
## JACK ## JACK
JACK assumes all `"application/control"` ports are MIDI ports. 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. converted to control messages in a similar way.
Normally, all MIDI and UMP messages are converted to MIDI1 jack events unless 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 JACK port was created with an explcit "32 bits raw UMP" format, in which
the JackPortIsMIDI2 flag, in which case the raw UMP is passed to the JACK case the raw UMP is passed to the JACK application directly. For output ports,
application directly. For output ports,
the JACK events are assumed to be MIDI1 and converted to UMP unless the port 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 has the "32 bit raw UMP" format, in which case the UMP messages are simply
the UMP messages are simply passed on. passed on.
There is a 1 to 1 mapping between the JACK events and control There is a 1 to 1 mapping between the JACK events and control
messages so there is no information loss or need for complicated messages so there is no information loss or need for complicated

View file

@ -179,7 +179,7 @@ A client requests to bind to the registry object and list the available objects
on the server. on the server.
Like with all bindings, first the client allocates a new proxy id and puts this Like with all bindings, first the client allocates a new proxy id and puts this
as the new_id field. Methods and Events can then be sent and received on the as the new_id field. Methods and Events can then be sent and received on the
new_id (in the message Id field). new_id (in the message Id field).
``` ```
@ -237,7 +237,7 @@ Core::Done event.
Create a new object from a factory of a certain type. Create a new object from a factory of a certain type.
The client allocates a new_id for the proxy. The server will allocate a new The client allocates a new_id for the proxy. The server will allocate a new
resource with the same new_id and from then on, Methods and Events will be resource with the same new_id and from then on, Methods and Events will be
exchanged between the new object of the given type. exchanged between the new object of the given type.
``` ```
@ -290,7 +290,7 @@ server.
String: version String: version
String: name String: name
Long: change_mask Long: change_mask
Struct( Struct(
Int: n_items Int: n_items
(String: key (String: key
String: value)* String: value)*
@ -434,7 +434,7 @@ registry.
Struct( Struct(
Int: id Int: id
Int: global_id Int: global_id
Struct( Struct(
Int: n_items Int: n_items
(String: key (String: key
String: value)* String: value)*
@ -498,7 +498,7 @@ Notify a client about a new global object.
Int: permissions Int: permissions
String: type String: type
Int: version Int: version
Struct( Struct(
Int: n_items Int: n_items
(String: key (String: key
String: value)* String: value)*
@ -556,7 +556,7 @@ Is used to update the properties of a client.
``` ```
Struct( Struct(
Struct( Struct(
Int: n_items Int: n_items
(String: key (String: key
String: value)* String: value)*
@ -610,7 +610,7 @@ when the client info is updated later.
Struct( Struct(
Int: id Int: id
Long: change_mask Long: change_mask
Struct( Struct(
Int: n_items Int: n_items
(String: key (String: key
String: value)* String: value)*
@ -628,7 +628,7 @@ Emitted as the reply of the GetPermissions method.
``` ```
Struct( Struct(
Int: index Int: index
Struct( Struct(
Int: n_permissions Int: n_permissions
(Int: id (Int: id
Int: permission)* Int: permission)*
@ -705,15 +705,15 @@ The info event is emitted when binding or when the device information changed.
Struct( Struct(
Int: id Int: id
Long: change_mask Long: change_mask
Struct( Struct(
Int: n_items Int: n_items
( String: key ( String: key
String: value )* String: value )*
): props ): props
Struct( Struct(
Int: n_params Int: n_params
( Id: id ( Int: id
Int: flags )* Int: flags )*
): param_info ): param_info
) )
``` ```
@ -741,7 +741,7 @@ Emitted as a result of EnumParams or SubscribeParams.
``` ```
- seq: the sequence number send by the client EnumParams or server generated - seq: the sequence number send by the client EnumParams or server generated
in the SubscribeParams case. in the SubscribeParams case.
- id: the param id that is reported, see enum spa_param_type - id: the param id that is reported, see enum spa_param_type
- index: the index of the parameter - index: the index of the parameter
- next: the index of the next parameter - next: the index of the next parameter
- param: the parameter. The object type depends on the id - param: the parameter. The object type depends on the id
@ -768,7 +768,7 @@ Info is emitted when binding to the factory global or when the information chang
String: type String: type
Int: version Int: version
Long: change_mask Long: change_mask
Struct( Struct(
Int: n_items Int: n_items
( String: key ( String: key
String: value )* String: value )*
@ -808,7 +808,7 @@ Info is emitted when binding to the link global or when the information changed.
Int: state Int: state
String: error String: error
Pod: format Pod: format
Struct( Struct(
Int: n_items Int: n_items
( String: key ( String: key
String: value )* String: value )*
@ -850,7 +850,7 @@ Info is emitted when binding to the module global or when the information change
String: filename String: filename
String: args String: args
Long: change_mask Long: change_mask
Struct( Struct(
Int: n_items Int: n_items
( String: key ( String: key
String: value )* String: value )*
@ -926,7 +926,7 @@ Send a Command to the node.
Pod: command Pod: command
) )
``` ```
- command: the command to send. See enum spa_node_command - command: the command to send. See enum spa_node_command
## Node events ## Node events
@ -944,15 +944,15 @@ The info event is emitted when binding or when the node information changed.
Int: n_output_ports Int: n_output_ports
Id: state Id: state
String: error String: error
Struct( Struct(
Int: n_items Int: n_items
( String: key ( String: key
String: value )* String: value )*
): props ): props
Struct( Struct(
Int: n_params Int: n_params
( Int: id ( Int: id
Int: flags )* Int: flags )*
): param_info ): param_info
) )
``` ```
@ -987,7 +987,7 @@ Emitted as a result of EnumParams or SubscribeParams.
``` ```
- seq: the sequence number send by the client EnumParams or server generated - seq: the sequence number send by the client EnumParams or server generated
in the SubscribeParams case. in the SubscribeParams case.
- id: the param id that is reported, see enum spa_param_type - id: the param id that is reported, see enum spa_param_type
- index: the index of the parameter - index: the index of the parameter
- next: the index of the next parameter - next: the index of the next parameter
- param: the parameter. The object type depends on the id - param: the parameter. The object type depends on the id
@ -1040,15 +1040,15 @@ The info event is emitted when binding or when the port information changed.
Int: id Int: id
Int: direction Int: direction
Long: change_mask Long: change_mask
Struct( Struct(
Int: n_items Int: n_items
( String: key ( String: key
String: value )* String: value )*
): props ): props
Struct( Struct(
Int: n_params Int: n_params
( Int: id ( Int: id
Int: flags )* Int: flags )*
): param_info ): param_info
) )
``` ```
@ -1077,7 +1077,7 @@ Emitted as a result of EnumParams or SubscribeParams.
``` ```
- seq: the sequence number send by the client EnumParams or server generated - seq: the sequence number send by the client EnumParams or server generated
in the SubscribeParams case. in the SubscribeParams case.
- id: the param id that is reported, see enum spa_param_type - id: the param id that is reported, see enum spa_param_type
- index: the index of the parameter - index: the index of the parameter
- next: the index of the next parameter - next: the index of the next parameter
@ -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 in the client. It is used by pw-stream and pw-filter to implement the PipeWire media
processing nodes. 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 methods
### ClientNode::GetNode (Opcode 1) ### ClientNode::GetNode (Opcode 1)
@ -1404,7 +1333,7 @@ Add a new port to the node
Struct( Struct(
Int: direction Int: direction
Int: port_id Int: port_id
Struct( Struct(
Int: n_items Int: n_items
( String: key ( String: key
String: value )* String: value )*
@ -1557,7 +1486,7 @@ ports of a node.
Int: port_id Int: port_id
Int: mix_id Int: mix_id
Int: peer_id Int: peer_id
Struct( Struct(
Int: n_items Int: n_items
( String: key ( String: key
String: value )* String: value )*
@ -1641,7 +1570,7 @@ The profiler has no methods
Pod: object Pod: object
) )
``` ```
- object: a SPA_TYPE_OBJECT_Profiler object. See enum spa_profiler - object: a SPA_TYPE_OBJECT_Profiler object. See enum spa_profiler
# Footer {#native-protocol-footer} # Footer {#native-protocol-footer}

View file

@ -2,26 +2,26 @@
This document tries to explain how the PipeWire graph is scheduled. 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 results in a dependency graph between nodes. Special care is taken for
loopback links so that the graph remains a directed graph. loopback links so that the graph remains a directed graph.
# Processing threads # 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. 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 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 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. node is scheduled to run.
This document describes the processing that happens in the data processing 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 # Nodes
@ -41,7 +41,7 @@ Each node also has:
+-v---------+ +-v---------+
activation { activation {
status:OK, // bitmask of NEED_DATA, HAVE_DATA or OK 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 required:0 // number of dependencies with other nodes
} }
``` ```
@ -49,7 +49,7 @@ Each node also has:
The activation record has the following information: The activation record has the following information:
- processing state and pending dependencies. As long as there are pending dependencies - processing state and pending dependencies. As long as there are pending dependencies
the node cannot be processed. This is the only relevant information for actually the node can not be processed. This is the only relevant information for actually
scheduling the graph and is shown in the above illustration. scheduling the graph and is shown in the above illustration.
- Current status of the node and profiling info (TRIGGERED, AWAKE, FINISHED, timestamps - Current status of the node and profiling info (TRIGGERED, AWAKE, FINISHED, timestamps
when the node changed state). when the node changed state).
@ -152,15 +152,14 @@ will then:
- Check the previous cycle. Did it complete? Mark xrun on unfinished nodes. - Check the previous cycle. Did it complete? Mark xrun on unfinished nodes.
- Perform reposition requests if any, timebase changes, etc.. - Perform reposition requests if any, timebase changes, etc..
- The pending counter of each follower node is set to the required field. - 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 - 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 field of the activation record. When the required field is 0, the eventfd is signaled
and the node can be scheduled. 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 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 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 ## Scheduling node A
@ -172,12 +171,12 @@ 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). 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. 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 ## Scheduling node B
Node B is scheduled and processes the input from node A. It then goes through the list of Node B is scheduled and processes the input from node A. It then goes through the list of
targets and decrements the pending fields. It decrements the pending field of the targets and decrements the pending fields. It decrements the pending field of the
driver (from 1 to 0) and triggers the driver. driver (from 1 to 0) and triggers the driver.
## Scheduling the driver ## Scheduling the driver
@ -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 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. 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 For remote nodes, the eventfd and the activation is transferred from the server
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
to the client. to the client.
This means that writing to the remote client eventfd will wake the client directly 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 are linked to and can directly trigger peers and drivers without going to the
server first. server first.
## Remote driver nodes ## Remote driver nodes.
Remote drivers start the graph cycle directly without going to the server first. 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 extra eventfd to signal the server that the graph completed. This is used by the
server to generate the profiler info. 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 Normally, a driver will wake up the graph and all the followers need to process
the data in sync. There are cases where: 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 commands we say we have lazy scheduling. The driver is not always scheduling according
to its own rhythm but also depending on the follower. 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 or when no driver will listen for RequestProcess commands. Two new node properties are
defined: defined:
@ -365,9 +243,9 @@ defined:
>1 means request events as a follower are supported with increasing preference >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 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: which results in the following cases:
driver producer driver producer
@ -424,7 +302,7 @@ Some use cases:
consumer consumer
- node.driver = false - 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) 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-midirecord** \[*options*\] \[*FILE* \| -\]
**pw-midi2play** \[*options*\] \[*FILE* \| -\]
**pw-midi2record** \[*options*\] \[*FILE* \| -\]
**pw-dsdplay** \[*options*\] \[*FILE* \| -\] **pw-dsdplay** \[*options*\] \[*FILE* \| -\]
# DESCRIPTION # 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 PCM, the filename extension is used to guess the file format with the
WAV file format as the default. WAV file format as the default.
It understands standard MIDI files and MIDI 2.0 clip files for playback It understands standard MIDI files for playback and recording. This tool
and recording. This tool will not render MIDI files, it will simply make will not render MIDI files, it will simply make the MIDI events
the MIDI events available to the graph. You need a MIDI renderer such as available to the graph. You need a MIDI renderer such as qsynth,
qsynth, timidity or a hardware MIDI renderer to hear the MIDI. timidity or a hardware MIDI rendered to hear the MIDI.
DSD playback is supported with the DSF file format. This tool will only 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 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 \par -p | \--playback
Playback mode. Read data from the specified file, and play it back. If 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 the tool is called under the name **pw-play** or **pw-midiplay** this is
**pw-midi2play** this is the default. the default.
\par -r | \--record \par -r | \--record
Recording mode. Capture data and write it to the specified file. If the Recording mode. Capture data and write it to the specified file. If the
tool is called under the name **pw-record**, **pw-midirecord** or tool is called under the name **pw-record** or **pw-midirecord** this is
**pw-midi2record** this is the default. the default.
\par -m | \--midi \par -m | \--midi
MIDI mode. *FILE* is a MIDI file. If the tool is called under the name 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 renderer such as qsynth, timidity or a hardware renderer to hear the
MIDI. 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 \par -d | \--dsd
DSD mode. *FILE* is a DSF file. If the tool is called under the name 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* **pw-dsdplay** this is the default. Note that this program will *not*

View file

@ -33,10 +33,6 @@ for many commands.
\par quit | q \par quit | q
Exit from **pw-cli** 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 # MODULE MANAGEMENT
Modules are loaded and unloaded in the local instance, thus the pw-cli 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 This command returns a module variable that can be used to unload the
module. 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. possible in PipeWire to load modules in a remote instance.
\endparblock \endparblock
\par unload-module *module-var* \par unload-module *module-var*
Unload a module, specified by its variable. Unload a module, specified either by its variable.
# OBJECT INTROSPECTION # OBJECT INTROSPECTION

View file

@ -4,7 +4,7 @@ The PipeWire Link Command
# SYNOPSIS # 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* **pw-link** \[*options*\] *output* *input*
@ -42,9 +42,6 @@ List input ports
\par -l | \--links \par -l | \--links
List links List links
\par -t | \--latency
List port latencies
\par -m | \--monitor \par -m | \--monitor
Monitor links and ports. **pw-link** will not exit but monitor and print Monitor links and ports. **pw-link** will not exit but monitor and print
new and destroyed ports or links. 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 A hierarchical view is shown of Driver nodes and follower nodes. The
Driver nodes are actively using a timer to schedule dataflow in 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 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: The columns presented are as follows:
@ -173,20 +173,10 @@ For Video formats, the layout is \<pixelformat\>
\parblock \parblock
Name assigned to the device/node, as found in *pw-dump* node.name 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 Names are prefixed by *+* when they are linked to a driver (entry
above with no +/=) above with no +)
\endparblock \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 # OPTIONS

View file

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

View file

@ -1,6 +1,6 @@
/** \page page_tutorial6 Tutorial - Part 6: Binding Objects /** \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 In this tutorial we show how to bind to an object so that we can
receive events and call methods on the object. receive events and call methods on the object.
@ -64,6 +64,6 @@ you created. Otherwise, they will be leaked:
} }
\endcode \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. 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 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"] BUILD_DIR = os.environ["BUILD_DIR"]
PAR_RE = r"^@PAR@\s+([^\s]*)[ \t]+(\S+)(.*)$" 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]*$" SECREF_RE = r"^@SECREF@[ \t]+([^\n]*)[ \t]*$"
@ -71,16 +71,10 @@ def main(args):
level = m.group(1) level = m.group(1)
title = name = m.group(2).strip() title = name = m.group(2).strip()
section = m.group(3) section = m.group(3)
alt = m.group(4)
if title == title.upper(): if title == title.upper():
name = name.capitalize() name = name.capitalize()
key = index_key(section, name) key = index_key(section, name)
text = f"{level} {title} {{#{key}}}" return 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
def secref(m): def secref(m):
import os import os
@ -154,12 +148,9 @@ def load_index(sections, text):
def idx(m): def idx(m):
name = m.group(2).strip() name = m.group(2).strip()
section = m.group(3) section = m.group(3)
alt = m.group(4)
if name == name.upper(): if name == name.upper():
name = name.capitalize() name = name.capitalize()
sections.setdefault(section, []).append(name) sections.setdefault(section, []).append(name)
if alt and alt.strip():
sections.setdefault(section, []).append(alt.strip())
return "" return ""
text = re.sub(PAR_RE, par, text, flags=re.M) text = re.sub(PAR_RE, par, text, flags=re.M)

View file

@ -58,8 +58,6 @@ extra_docs = [
'dox/internals/index.dox', 'dox/internals/index.dox',
'dox/internals/design.dox', 'dox/internals/design.dox',
'dox/internals/access.dox', 'dox/internals/access.dox',
'dox/internals/latency.dox',
'dox/internals/tag.dox',
'dox/internals/midi.dox', 'dox/internals/midi.dox',
'dox/internals/portal.dox', 'dox/internals/portal.dox',
'dox/internals/daemon.dox', 'dox/internals/daemon.dox',
@ -68,7 +66,6 @@ extra_docs = [
'dox/internals/objects.dox', 'dox/internals/objects.dox',
'dox/internals/audio.dox', 'dox/internals/audio.dox',
'dox/internals/scheduling.dox', 'dox/internals/scheduling.dox',
'dox/internals/driver.dox',
'dox/internals/protocol.dox', 'dox/internals/protocol.dox',
'dox/internals/pulseaudio.dox', 'dox/internals/pulseaudio.dox',
'dox/internals/dma-buf.dox', 'dox/internals/dma-buf.dox',
@ -79,7 +76,6 @@ extra_docs = [
'dox/tutorial/tutorial4.dox', 'dox/tutorial/tutorial4.dox',
'dox/tutorial/tutorial5.dox', 'dox/tutorial/tutorial5.dox',
'dox/tutorial/tutorial6.dox', 'dox/tutorial/tutorial6.dox',
'dox/tutorial/tutorial7.dox',
'dox/api/index.dox', 'dox/api/index.dox',
'dox/api/spa-index.dox', 'dox/api/spa-index.dox',
'dox/api/spa-plugins.dox', 'dox/api/spa-plugins.dox',
@ -174,7 +170,6 @@ example_files = [
'tutorial4.c', 'tutorial4.c',
'tutorial5.c', 'tutorial5.c',
'tutorial6.c', 'tutorial6.c',
'tutorial7.c',
] ]
example_dep_files = [] example_dep_files = []
foreach h : example_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_protocol
\addtogroup pw_resource \addtogroup pw_resource
\addtogroup pw_thread_loop \addtogroup pw_thread_loop
\addtogroup pw_timer_queue
\addtogroup pw_work_queue \addtogroup pw_work_queue
\} \}

View file

@ -1,10 +1,10 @@
project('pipewire', ['c' ], project('pipewire', ['c' ],
version : '1.5.81', version : '1.4.4',
license : [ 'MIT', 'LGPL-2.1-or-later', 'GPL-2.0-only' ], license : [ 'MIT', 'LGPL-2.1-or-later', 'GPL-2.0-only' ],
meson_version : '>= 0.61.1', meson_version : '>= 0.61.1',
default_options : [ 'warning_level=3', default_options : [ 'warning_level=3',
'c_std=gnu11', 'c_std=gnu11',
'cpp_std=c++20', 'cpp_std=c++17',
'b_pie=true', 'b_pie=true',
#'b_sanitize=address,undefined', #'b_sanitize=address,undefined',
'buildtype=debugoptimized' ]) 'buildtype=debugoptimized' ])
@ -81,7 +81,6 @@ pkgconfig = import('pkgconfig')
common_flags = [ common_flags = [
'-fvisibility=hidden', '-fvisibility=hidden',
'-fno-strict-aliasing', '-fno-strict-aliasing',
'-fno-strict-overflow',
'-Werror=suggest-attribute=format', '-Werror=suggest-attribute=format',
'-Wsign-compare', '-Wsign-compare',
'-Wpointer-arith', '-Wpointer-arith',
@ -115,11 +114,10 @@ cc_flags = common_flags + [
'-Werror=old-style-definition', '-Werror=old-style-definition',
'-Werror=missing-parameter-type', '-Werror=missing-parameter-type',
'-Werror=strict-prototypes', '-Werror=strict-prototypes',
'-DSPA_AUDIO_MAX_CHANNELS=128u',
] ]
add_project_arguments(cc.get_supported_arguments(cc_flags), language: 'c') 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) have_cpp = add_languages('cpp', native: false, required : false)
@ -279,9 +277,11 @@ endforeach
cdata.set('HAVE_PIDFD_OPEN', cdata.set('HAVE_PIDFD_OPEN',
cc.get_define('SYS_pidfd_open', prefix: '#include <sys/syscall.h>') != '') 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) 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')) logind_dep = dependency(get_option('logind-provider'), required: get_option('logind'))
summary({'logind': logind_dep.found()}, bool_yn: true) 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')) sdl_dep = dependency('sdl2', required : get_option('sdl2'))
summary({'SDL2 (video examples)': sdl_dep.found()}, bool_yn: true, section: 'Misc dependencies') summary({'SDL2 (video examples)': sdl_dep.found()}, bool_yn: true, section: 'Misc dependencies')
drm_dep = dependency('libdrm', required : false) 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') summary({'fftw3f (filter-chain convolver)': fftw_dep.found()}, bool_yn: true, section: 'Misc dependencies')
cdata.set('HAVE_FFTW', fftw_dep.found()) cdata.set('HAVE_FFTW', fftw_dep.found())
@ -340,23 +340,12 @@ endif
pw_cat_ffmpeg = get_option('pw-cat-ffmpeg') pw_cat_ffmpeg = get_option('pw-cat-ffmpeg')
ffmpeg = get_option('ffmpeg') ffmpeg = get_option('ffmpeg')
if pw_cat_ffmpeg.allowed() or ffmpeg.allowed() 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()) avcodec_dep = dependency('libavcodec', required: pw_cat_ffmpeg.enabled() or ffmpeg.enabled())
avformat_dep = dependency('libavformat', required: pw_cat_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()) 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 else
avcodec_dep = dependency('', required: false) 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 endif
cdata.set('HAVE_PW_CAT_FFMPEG_INTEGRATION', pw_cat_ffmpeg.allowed()) 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') summary({'libusb (Bluetooth quirks)': libusb_dep.found()}, bool_yn: true, section: 'Backend')
cdata.set('HAVE_LIBUSB', libusb_dep.found()) 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')) 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') summary({'GLib-2.0 (Flatpak support)': glib2_dep.found()}, bool_yn: true, section: 'Misc dependencies')
flatpak_support = glib2_dep.found() flatpak_support = glib2_dep.found()
@ -418,7 +410,6 @@ gst_deps_def = {
gst_dep = [] gst_dep = []
gst_dma_drm_found = false gst_dma_drm_found = false
gst_shm_allocator_found = false
foreach depname, kwargs: gst_deps_def foreach depname, kwargs: gst_deps_def
dep = dependency(depname, required: gst_option, kwargs: kwargs) dep = dependency(depname, required: gst_option, kwargs: kwargs)
summary({depname: dep.found()}, bool_yn: true, section: 'GStreamer modules') 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') if depname == 'gstreamer-allocators-1.0' and dep.version().version_compare('>= 1.23.1')
gst_dma_drm_found = true gst_dma_drm_found = true
gst_shm_allocator_found = true
endif endif
endforeach 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 # This code relies on the array being empty if any dependency was not found
gst_dp_found = gst_dep.length() > 0 gst_dp_found = gst_dep.length() > 0
summary({'gstreamer-device-provider': gst_dp_found}, bool_yn: true, section: 'Backend') 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('ALSA_PLUGIN_DIR', builddir / 'pipewire-alsa' / 'alsa-plugins')
devenv.prepend('LD_LIBRARY_PATH', builddir / 'pipewire-jack' / 'src') devenv.prepend('LD_LIBRARY_PATH', builddir / 'pipewire-jack' / 'src')
devenv.set('PIPEWIRE_LOG_SYSTEMD', 'false')
devenv.set('PW_UNINSTALLED', '1') devenv.set('PW_UNINSTALLED', '1')
devenv.set('PW_BUILDDIR', meson.project_build_root())
meson.add_devenv(devenv) meson.add_devenv(devenv)

View file

@ -30,8 +30,8 @@ option('gstreamer-device-provider',
description: 'Build GStreamer device provider plugin', description: 'Build GStreamer device provider plugin',
type: 'feature', type: 'feature',
value: 'auto') value: 'auto')
option('libsystemd', option('systemd',
description: 'Enable code that depends on libsystemd', description: 'Enable systemd integration',
type: 'feature', type: 'feature',
value: 'auto') value: 'auto')
option('logind', option('logind',
@ -48,9 +48,9 @@ option('systemd-system-service',
type: 'feature', type: 'feature',
value: 'disabled') value: 'disabled')
option('systemd-user-service', option('systemd-user-service',
description: 'Install systemd user service file', description: 'Install systemd user service file (ignored without systemd)',
type: 'feature', type: 'feature',
value: 'auto') value: 'enabled')
option('selinux', option('selinux',
description: 'Enable SELinux integration', description: 'Enable SELinux integration',
type: 'feature', type: 'feature',
@ -129,10 +129,6 @@ option('bluez5-codec-ldac',
description: 'Enable LDAC Sony open source codec implementation', description: 'Enable LDAC Sony open source codec implementation',
type: 'feature', type: 'feature',
value: 'auto') value: 'auto')
option('bluez5-codec-ldac-dec',
description: 'Enable LDAC Sony open source codec decoding',
type: 'feature',
value: 'auto')
option('bluez5-codec-aac', option('bluez5-codec-aac',
description: 'Enable Fraunhofer FDK AAC open source codec implementation', description: 'Enable Fraunhofer FDK AAC open source codec implementation',
type: 'feature', type: 'feature',
@ -153,10 +149,6 @@ option('bluez5-codec-g722',
description: 'Enable G722 open source codec implementation', description: 'Enable G722 open source codec implementation',
type: 'feature', type: 'feature',
value: 'auto') value: 'auto')
option('bluez5-plc-spandsp',
description: 'Enable SpanDSP for packet loss concealment',
type: 'feature',
value: 'auto')
option('control', option('control',
description: 'Enable control spa plugin integration', description: 'Enable control spa plugin integration',
type: 'feature', type: 'feature',
@ -387,11 +379,3 @@ option('ebur128',
description: 'Enable code that depends on ebur128', description: 'Enable code that depends on ebur128',
type: 'feature', type: 'feature',
value: 'auto') 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_MIN ((uint32_t) 0U)
#define VOLUME_MAX ((uint32_t) 0x10000U) #define VOLUME_MAX ((uint32_t) 0x10000U)
#define MAX_CHANNELS SPA_AUDIO_MAX_CHANNELS
struct volume { struct volume {
uint32_t channels; uint32_t channels;
long values[MAX_CHANNELS]; long values[SPA_AUDIO_MAX_CHANNELS];
}; };
typedef struct { 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_pod_builder_push_object(b, &f[0],
SPA_TYPE_OBJECT_Props, SPA_PARAM_Props); SPA_TYPE_OBJECT_Props, SPA_PARAM_Props);
if (volume) { if (volume) {
float volumes[MAX_CHANNELS]; float volumes[SPA_AUDIO_MAX_CHANNELS];
uint32_t i, n_volumes = 0; uint32_t i, n_volumes = 0;
n_volumes = volume->channels; n_volumes = volume->channels;
@ -852,11 +850,11 @@ static void parse_props(struct global *g, const struct spa_pod *param, bool devi
break; break;
case SPA_PROP_channelVolumes: case SPA_PROP_channelVolumes:
{ {
float volumes[MAX_CHANNELS]; float volumes[SPA_AUDIO_MAX_CHANNELS];
uint32_t n_volumes, i; uint32_t n_volumes, i;
n_volumes = spa_pod_copy_array(&prop->value, SPA_TYPE_Float, 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; g->node.channel_volume.channels = n_volumes;
for (i = 0; i < n_volumes; i++) 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 MIN_BUFFERS 2u
#define MAX_BUFFERS 64u #define MAX_BUFFERS 64u
#define MAX_CHANNELS 64
#define MAX_RATE (48000*8) #define MAX_RATE (48000*8)
#define MAX_CHANNELS SPA_AUDIO_MAX_CHANNELS
#define MIN_PERIOD 64 #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) { if (pw->activated && pw->stream != NULL) {
pw_stream_set_active(pw->stream, false); pw_stream_set_active(pw->stream, false);
pw->activated = false; pw->activated = false;
pw_thread_loop_signal(pw->main_loop, false);
} }
pw_thread_loop_unlock(pw->main_loop); pw_thread_loop_unlock(pw->main_loop);
return 0; 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 #define _FORMAT_BE(p, fmt) p ? SPA_AUDIO_FORMAT_UNKNOWN : SPA_AUDIO_FORMAT_ ## fmt ## _OE
#endif #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) { switch (channels) {
case 8: case 8:
@ -916,16 +915,12 @@ static int snd_pcm_pipewire_set_chmap(snd_pcm_ioplug_t * io,
default: default:
return -EINVAL; return -EINVAL;
} }
if (map->channels > MAX_CHANNELS)
return -ENOTSUP;
for (i = 0; i < map->channels; i++) { for (i = 0; i < map->channels; i++) {
char buf[8];
position[i] = chmap_to_channel(map->pos[i]); position[i] = chmap_to_channel(map->pos[i]);
pw_log_debug("map %d: %s / %s", i, pw_log_debug("map %d: %s / %s", i,
snd_pcm_chmap_name(map->pos[i]), snd_pcm_chmap_name(map->pos[i]),
spa_type_audio_channel_make_short_name(position[i], spa_debug_type_find_short_name(spa_type_audio_channel,
buf, sizeof(buf), "UNK")); position[i]));
} }
return 1; return 1;
} }

View file

@ -102,7 +102,6 @@ struct notify {
#define NOTIFY_TYPE_SHUTDOWN ((7<<4)|NOTIFY_ACTIVE_FLAG) #define NOTIFY_TYPE_SHUTDOWN ((7<<4)|NOTIFY_ACTIVE_FLAG)
#define NOTIFY_TYPE_LATENCY ((8<<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_TOTAL_LATENCY ((9<<4)|NOTIFY_ACTIVE_FLAG)
#define NOTIFY_TYPE_PORT_RENAME ((10<<4)|NOTIFY_ACTIVE_FLAG)
int type; int type;
struct object *object; struct object *object;
int arg1; int arg1;
@ -172,7 +171,6 @@ struct object {
} port_link; } port_link;
struct { struct {
unsigned long flags; unsigned long flags;
char old_name[REAL_JACK_PORT_NAME_SIZE+1];
char name[REAL_JACK_PORT_NAME_SIZE+1]; char name[REAL_JACK_PORT_NAME_SIZE+1];
char alias1[REAL_JACK_PORT_NAME_SIZE+1]; char alias1[REAL_JACK_PORT_NAME_SIZE+1];
char alias2[REAL_JACK_PORT_NAME_SIZE+1]; char alias2[REAL_JACK_PORT_NAME_SIZE+1];
@ -233,13 +231,6 @@ struct buffer {
uint32_t n_mem; 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 mix {
struct spa_list link; struct spa_list link;
struct spa_list port_link; struct spa_list port_link;
@ -254,8 +245,6 @@ struct mix {
struct buffer buffers[MAX_BUFFERS]; struct buffer buffers[MAX_BUFFERS];
uint32_t n_buffers; uint32_t n_buffers;
struct mix_info mix_info;
unsigned int to_free:1; 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) static inline void mix_set_io(struct mix *mix, void *data, size_t size)
{ {
struct io_info info = { .mix = mix, .data = data, .size = size }; struct io_info info = { .mix = mix, .data = data, .size = size };
pw_loop_locked(mix->port->client->loop->loop, pw_data_loop_invoke(mix->port->client->loop,
do_mix_set_io, SPA_ID_INVALID, &info, sizeof(info), NULL); 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) 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, notify->arg1,
c->portregistration_arg); c->portregistration_arg);
break; 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: case NOTIFY_TYPE_CONNECT:
if (o->registered == notify->arg1) if (o->registered == notify->arg1)
break; 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; emit = c->portregistration_callback != NULL && o != NULL;
o->visible = arg1; o->visible = arg1;
break; break;
case NOTIFY_TYPE_PORT_RENAME:
emit = c->rename_callback != NULL && o != NULL;
break;
case NOTIFY_TYPE_CONNECT: case NOTIFY_TYPE_CONNECT:
emit = c->connect_callback != NULL && o != NULL; emit = c->connect_callback != NULL && o != NULL;
break; 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]; return priotab[(s2>>4) & 7] - priotab[(s1>>4) & 7];
} }
static inline int event_sort(struct spa_pod_control *a, const void *abody, static inline int event_sort(struct spa_pod_control *a, struct spa_pod_control *b)
struct spa_pod_control *b, const void *bbody)
{ {
if (a->offset < b->offset) if (a->offset < b->offset)
return -1; return -1;
@ -1513,18 +1488,18 @@ static inline int event_sort(struct spa_pod_control *a, const void *abody,
switch(a->type) { switch(a->type) {
case SPA_CONTROL_Midi: 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) if (SPA_POD_BODY_SIZE(&a->value) < 1 || SPA_POD_BODY_SIZE(&b->value) < 1)
return 0; return 0;
return event_compare(sa[0], sb[0]); return event_compare(sa[0], sb[0]);
} }
case SPA_CONTROL_UMP: 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) if (SPA_POD_BODY_SIZE(&a->value) < 4 || SPA_POD_BODY_SIZE(&b->value) < 4)
return 0; return 0;
if (((sa[0] >> 28) != 2 && (sa[0] >> 28) != 4) || if ((sa[0] >> 28) != 2 || (sa[0] >> 28) != 4 ||
((sb[0] >> 28) != 2 && (sb[0] >> 28) != 4)) (sb[0] >> 28) != 2 || (sb[0] >> 28) != 4)
return 0; return 0;
return event_compare(sa[0] >> 16, sb[0] >> 16); return event_compare(sa[0] >> 16, sb[0] >> 16);
} }
@ -1608,54 +1583,56 @@ static inline int midi_event_write(void *port_buffer,
return 0; 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; uint32_t i;
int res = 0; int res = 0;
bool in_sysex = false; bool in_sysex = false;
while (true) { for (i = 0; i < n_seq; i++)
struct mix_info *next = NULL; c[i] = spa_pod_control_first(&seq[i]->body);
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_mix; i++) { while (true) {
struct mix_info *m = mix[i]; struct spa_pod_control *next = NULL;
if (next == NULL || event_sort(&m->control, m->control_body, uint32_t next_index = 0;
&next->control, next->control_body) <= 0) {
next = m; 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; next_index = i;
} }
} }
if (SPA_UNLIKELY(next == NULL)) if (SPA_UNLIKELY(next == NULL))
break; break;
control = &next->control; switch(next->type) {
data = (uint8_t*)next->control_body;
size = SPA_POD_BODY_SIZE(&control->value);
switch(control->type) {
case SPA_CONTROL_OSC: case SPA_CONTROL_OSC:
if (!TYPE_ID_CAN_OSC(type)) if (!TYPE_ID_CAN_OSC(type))
break; break;
SPA_FALLTHROUGH; SPA_FALLTHROUGH;
case SPA_CONTROL_Midi: 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) { if (type == TYPE_ID_UMP) {
while (size > 0) { while (size > 0) {
uint32_t ump[4]; uint32_t ump[4];
int ump_size = spa_ump_from_midi(&data, &size, ump, sizeof(ump), 0, &state); int ump_size = spa_ump_from_midi(&data, &size, ump, sizeof(ump), 0, &state);
if (ump_size <= 0) if (ump_size <= 0)
break; break;
if ((res = midi_event_write(midi, control->offset, if ((res = midi_event_write(midi, next->offset,
(uint8_t*)ump, ump_size, false)) < 0) (uint8_t*)ump, ump_size, false)) < 0)
break; break;
} }
} else { } else {
res = midi_event_write(midi, control->offset, data, size, fix); res = midi_event_write(midi, next->offset, data, size, fix);
} }
if (res < 0) if (res < 0)
pw_log_warn("midi %p: can't write event: %s", midi, 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: case SPA_CONTROL_UMP:
{ {
void *data = SPA_POD_BODY(&next->value);
size_t size = SPA_POD_BODY_SIZE(&next->value);
uint8_t ev[32];
bool was_sysex = in_sysex;
if (type == TYPE_ID_MIDI) { if (type == TYPE_ID_MIDI) {
uint8_t ev[32]; int ev_size = spa_ump_to_midi(data, size, ev, sizeof(ev));
const uint32_t *d = (uint32_t*)data; if (ev_size <= 0)
break;
while (size > 0) { size = ev_size;
bool was_sysex = in_sysex; data = ev;
int ev_size = spa_ump_to_midi(&d, &size, ev, sizeof(ev), &state);
if (ev_size <= 0)
break;
if (!in_sysex && ev[0] == 0xf0) if (!in_sysex && ev[0] == 0xf0)
in_sysex = true; in_sysex = true;
if (in_sysex && ev[ev_size-1] == 0xf7) if (in_sysex && ev[ev_size-1] == 0xf7)
in_sysex = false; in_sysex = false;
if (was_sysex) } else if (type != TYPE_ID_UMP)
res = midi_event_append(midi, ev, ev_size); break;
else
res = midi_event_write(midi, control->offset, ev, ev_size, fix); if (was_sysex)
if (res < 0) res = midi_event_append(midi, data, size);
break; else
res = midi_event_write(midi, next->offset, data, size, fix);
}
} else if (type == TYPE_ID_UMP) {
res = midi_event_write(midi, control->offset, data, size, fix);
}
if (res < 0) if (res < 0)
pw_log_warn("midi %p: can't write event: %s", midi, pw_log_warn("midi %p: can't write event: %s", midi,
spa_strerror(res)); spa_strerror(res));
break;
} }
} }
if (spa_pod_parser_get_control_body(&next->parser, c[next_index] = spa_pod_control_next(c[next_index]);
&next->control, &next->control_body) < 0) {
spa_pod_parser_pop(&next->parser, &next->frame);
mix[next_index] = mix[--n_mix];
}
} }
} }
@ -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_Suspend:
case SPA_NODE_COMMAND_Pause: case SPA_NODE_COMMAND_Pause:
if (c->started) { if (c->started) {
pw_loop_locked(c->loop->loop, pw_data_loop_invoke(c->loop,
do_unprepare_client, SPA_ID_INVALID, NULL, 0, c); do_unprepare_client, SPA_ID_INVALID, NULL, 0, false, c);
c->started = false; c->started = false;
} }
break; break;
case SPA_NODE_COMMAND_Start: case SPA_NODE_COMMAND_Start:
if (!c->started) { if (!c->started) {
pw_loop_locked(c->loop->loop, pw_data_loop_invoke(c->loop,
do_prepare_client, SPA_ID_INVALID, NULL, 0, c); do_prepare_client, SPA_ID_INVALID, NULL, 0, false, c);
c->started = true; c->started = true;
} }
break; break;
@ -2577,11 +2549,28 @@ static int param_enum_format(struct client *c, struct port *p,
case TYPE_ID_UMP: case TYPE_ID_UMP:
case TYPE_ID_OSC: case TYPE_ID_OSC:
case TYPE_ID_MIDI: 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_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; break;
}
case TYPE_ID_VIDEO: case TYPE_ID_VIDEO:
*param = spa_pod_builder_add_object(b, *param = spa_pod_builder_add_object(b,
SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat, 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; link->trigger = link->activation->server_version < 1 ? trigger_link_v0 : trigger_link_v1;
spa_list_append(&c->links, &link->link); spa_list_append(&c->links, &link->link);
pw_loop_locked(c->loop->loop, pw_data_loop_invoke(c->loop,
do_add_link, SPA_ID_INVALID, NULL, 0, link); do_add_link, SPA_ID_INVALID, NULL, 0, false, link);
} }
else { else {
link = find_activation(&c->links, node_id); link = find_activation(&c->links, node_id);
@ -3318,8 +3307,8 @@ static int client_node_set_activation(void *data,
} }
spa_list_remove(&link->link); spa_list_remove(&link->link);
pw_loop_locked(c->loop->loop, pw_data_loop_invoke(c->loop,
do_remove_link, SPA_ID_INVALID, NULL, 0, link); do_remove_link, SPA_ID_INVALID, NULL, 0, false, link);
queue_free_link(c, link); queue_free_link(c, link);
} }
@ -3685,67 +3674,6 @@ static const struct pw_node_events node_events = {
.info = node_info, .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, static void port_param(void *data, int seq,
uint32_t id, uint32_t index, uint32_t next, uint32_t id, uint32_t index, uint32_t next,
const struct spa_pod *param) 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 = { static const struct pw_port_events port_events = {
PW_VERSION_PORT_EVENTS, PW_VERSION_PORT_EVENTS,
.info = port_info,
.param = port_param, .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, static void registry_event_global(void *data, uint32_t id,
uint32_t permissions, const char *type, uint32_t version, uint32_t permissions, const char *type, uint32_t version,
const struct spa_dict *props) const struct spa_dict *props)
{ {
struct client *c = (struct client *) data; struct client *c = (struct client *) data;
struct object *o, *ot; struct object *o, *ot, *op;
const char *str; const char *str;
bool do_emit = true, do_sync = false; bool do_emit = true, do_sync = false;
uint32_t serial; uint32_t serial;
@ -3843,8 +3782,6 @@ static void registry_event_global(void *data, uint32_t id,
} }
if (str == NULL) if (str == NULL)
str = node_name; str = node_name;
if (str == NULL)
str = spa_dict_lookup(props, PW_KEY_OBJECT_PATH);
if (str == NULL) if (str == NULL)
str = "node"; str = "node";
@ -3900,7 +3837,6 @@ static void registry_event_global(void *data, uint32_t id,
uint32_t node_id; uint32_t node_id;
bool is_monitor = false; bool is_monitor = false;
char tmp[REAL_JACK_PORT_NAME_SIZE+1]; char tmp[REAL_JACK_PORT_NAME_SIZE+1];
const char *name;
if ((str = spa_dict_lookup(props, PW_KEY_FORMAT_DSP)) == NULL) if ((str = spa_dict_lookup(props, PW_KEY_FORMAT_DSP)) == NULL)
str = "other"; str = "other";
@ -3916,7 +3852,7 @@ static void registry_event_global(void *data, uint32_t id,
spa_strstartswith(str, "jack:flags:")) spa_strstartswith(str, "jack:flags:"))
flags = atoi(str+11); 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; goto exit;
if (type_id == TYPE_ID_UMP && c->flag_midi2) 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; o = NULL;
if (node_id == c->node_id) { 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); o = find_port_by_name(c, tmp);
if (o != NULL) if (o != NULL)
pw_log_info("%p: %s found our port %p", c, tmp, o); 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.node = ot;
o->port.latency[SPA_DIRECTION_INPUT] = SPA_LATENCY_INFO(SPA_DIRECTION_INPUT); 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.latency[SPA_DIRECTION_OUTPUT] = SPA_LATENCY_INFO(SPA_DIRECTION_OUTPUT);
o->port.type_id = type_id;
do_emit = node_is_active(c, ot); 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); pthread_mutex_lock(&c->context.lock);
spa_list_append(&c->context.objects, &o->link); spa_list_append(&c->context.objects, &o->link);
pthread_mutex_unlock(&c->context.lock); pthread_mutex_unlock(&c->context.lock);
}
o->port.flags = flags; if (is_monitor && !c->merge_monitor)
o->port.node_id = node_id; snprintf(tmp, sizeof(tmp), "%.*s%s:%s",
o->port.is_monitor = is_monitor; (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 (c->fill_aliases) {
if ((str = spa_dict_lookup(props, PW_KEY_OBJECT_PATH)) != NULL) 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) if ((str = spa_dict_lookup(props, PW_KEY_PORT_ALIAS)) != NULL)
snprintf(o->port.alias2, sizeof(o->port.alias2), "%s", str); snprintf(o->port.alias2, sizeof(o->port.alias2), "%s", str);
} }
if ((str = spa_dict_lookup(props, PW_KEY_PORT_ID)) != NULL) { if ((str = spa_dict_lookup(props, PW_KEY_PORT_ID)) != NULL) {
o->port.system_id = atoi(str); o->port.system_id = atoi(str);
snprintf(o->port.system, sizeof(o->port.system), "system:%s_%d", 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); o->port.system_id+1);
} }
if (node_id != c->node_id) o->port.flags = flags;
update_port_name(o, name); 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, pw_log_debug("%p: %p add port %d name:%s %d", c, o, id,
o->port.name, type_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; struct mix *mix;
void *ptr = p->emptyptr; void *ptr = p->emptyptr;
struct midi_buffer *mb = (struct midi_buffer*)midi_scratch; struct midi_buffer *mb = (struct midi_buffer*)midi_scratch;
struct mix_info *mix_info[MAX_MIX]; struct spa_pod_sequence *seq[MAX_MIX];
uint32_t n_mix_info = 0; uint32_t n_seq = 0;
spa_list_for_each(mix, &p->mix, port_link) { spa_list_for_each(mix, &p->mix, port_link) {
struct spa_data *d; struct spa_data *d;
struct buffer *b; struct buffer *b;
struct mix_info *mi = &mix->mix_info; void *pod;
struct spa_pod_sequence seq;
const void *seq_body;
if (mix->id == SPA_ID_INVALID) if (mix->id == SPA_ID_INVALID)
continue; continue;
@ -5823,24 +5773,21 @@ static void *get_buffer_input_midi(struct port *p, jack_nframes_t frames)
continue; continue;
d = &b->datas[0]; 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)
continue;
if (spa_pod_parser_get_control_body(&mi->parser,
&mi->control, &mi->control_body) < 0)
continue;
mix_info[n_mix_info++] = mi; if ((pod = spa_pod_from_data(d->data, d->maxsize, d->chunk->offset, d->chunk->size)) == NULL)
if (n_mix_info == MAX_MIX) continue;
if (!spa_pod_is_sequence(pod))
continue;
seq[n_seq++] = pod;
if (n_seq == MAX_MIX)
break; break;
} }
midi_init_buffer(mb, MIDI_SCRATCH_FRAMES, frames); midi_init_buffer(mb, MIDI_SCRATCH_FRAMES, frames);
/* first convert to a thread local scratch buffer, then memcpy into /* first convert to a thread local scratch buffer, then memcpy into
* the per port buffer. This makes it possible to call this function concurrently * the per port buffer. This makes it possible to call this function concurrently
* but also have different pointers per port */ * 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 memcpy(ptr, mb, sizeof(struct midi_buffer) + (mb->event_count
* sizeof(struct midi_event))); * sizeof(struct midi_event)));
if (mb->write_pos > 0) { if (mb->write_pos > 0) {
@ -5907,26 +5854,21 @@ void * jack_port_get_buffer (jack_port_t *port, jack_nframes_t frames)
goto done; goto done;
if (TYPE_ID_IS_EVENT(o->port.type_id)) { 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_data *d;
struct spa_pod_sequence seq; void *pod;
const void *seq_body;
ptr = midi_scratch; ptr = midi_scratch;
midi_init_buffer(ptr, MIDI_SCRATCH_FRAMES, frames); midi_init_buffer(ptr, MIDI_SCRATCH_FRAMES, frames);
d = &b->datas[0]; d = &b->datas[0];
spa_pod_parser_init_from_data(&mi.parser, d->data, d->maxsize, if ((pod = spa_pod_from_data(d->data, d->maxsize,
d->chunk->offset, d->chunk->size); d->chunk->offset, d->chunk->size)) == NULL)
if (spa_pod_parser_push_sequence_body(&mi.parser,
&mi.frame, &seq, &seq_body) < 0)
goto done; goto done;
if (spa_pod_parser_get_control_body(&mi.parser, if (!spa_pod_is_sequence(pod))
&mi.control, &mi.control_body) < 0)
goto done; goto done;
seq[0] = pod;
mix_info[0] = &mi; convert_to_event(seq, 1, ptr, c->fix_midi_events, o->port.type_id);
convert_to_event(mix_info, 1, ptr, c->fix_midi_events, o->port.type_id);
} else { } else {
ptr = get_buffer_data(b, frames); 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); 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) static int v4l2_openat(int dirfd, const char *path, int oflag, mode_t mode)
{ {
int res, flags; int res, flags;
@ -808,8 +795,6 @@ static int v4l2_openat(int dirfd, const char *path, int oflag, mode_t mode)
if (passthrough) if (passthrough)
return globals.old_fops.openat(dirfd, path, oflag, mode); return globals.old_fops.openat(dirfd, path, oflag, mode);
ensure_pipewire_init();
pw_log_info("path:%s oflag:%d mode:%d", path, oflag, mode); pw_log_info("path:%s oflag:%d mode:%d", path, oflag, mode);
if ((file = find_file_by_dev(dev_id)) != NULL) { 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) { spa_list_for_each(p, &g->param_list, link) {
const struct format_info *fi; const struct format_info *fi;
uint32_t media_type, media_subtype, format; uint32_t media_type, media_subtype, format;
struct spa_rectangle size;
if (p->id != SPA_PARAM_EnumFormat || p->param == NULL) if (p->id != SPA_PARAM_EnumFormat || p->param == NULL)
continue; continue;
@ -1423,96 +1409,22 @@ static int vidioc_enum_framesizes(struct file *file, struct v4l2_frmsizeenum *ar
if (fi->fourcc != arg->pixel_format) if (fi->fourcc != arg->pixel_format)
continue; continue;
if (spa_pod_parse_object(p->param,
const struct spa_pod_prop *size_prop = spa_pod_find_prop(p->param, NULL, SPA_FORMAT_VIDEO_size); SPA_TYPE_OBJECT_Format, NULL,
if (!size_prop) SPA_FORMAT_VIDEO_size, SPA_POD_Rectangle(&size)) < 0)
continue; continue;
uint32_t n_sizes, choice; arg->type = V4L2_FRMSIZE_TYPE_DISCRETE;
const struct spa_pod *size_pods = spa_pod_get_values(&size_prop->value, &n_sizes, &choice); arg->discrete.width = size.width;
if (!size_pods || n_sizes <= 0) arg->discrete.height = size.height;
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;
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);
if (count == arg->index) {
found = true;
break;
}
}
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;
} }
count++;
if (found)
break;
} }
pw_thread_loop_unlock(file->loop); pw_thread_loop_unlock(file->loop);
@ -2188,7 +2100,7 @@ static struct {
{ V4L2_CID_SATURATION, SPA_PROP_saturation }, { V4L2_CID_SATURATION, SPA_PROP_saturation },
{ V4L2_CID_HUE, SPA_PROP_hue }, { V4L2_CID_HUE, SPA_PROP_hue },
{ V4L2_CID_GAMMA, SPA_PROP_gamma }, { 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_GAIN, SPA_PROP_gain },
{ V4L2_CID_SHARPNESS, SPA_PROP_sharpness }, { 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_frame f[1];
struct spa_pod *param; struct spa_pod *param;
pod = spa_pod_get_values(type, &n_vals, &choice); pod = spa_pod_get_values(type, &n_vals, &choice);
if (n_vals < 1)
break;
spa_pod_builder_push_object(&b, &f[0], spa_pod_builder_push_object(&b, &f[0],
SPA_TYPE_OBJECT_Props, SPA_PARAM_Props); 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.ioctl = dlsym(RTLD_NEXT, "ioctl");
globals.old_fops.mmap = dlsym(RTLD_NEXT, "mmap64"); globals.old_fops.mmap = dlsym(RTLD_NEXT, "mmap64");
globals.old_fops.munmap = dlsym(RTLD_NEXT, "munmap"); globals.old_fops.munmap = dlsym(RTLD_NEXT, "munmap");
/* NOTE:
* We avoid calling pw_init() here (constructor/early init path) because pw_init(NULL, NULL);
* that can deadlock in certain host processes (e.g. Zoom >= 5.0) when PW_LOG_TOPIC_INIT(v4l2_log_topic);
* 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.
*/
pthread_mutex_init(&globals.lock, NULL); pthread_mutex_init(&globals.lock, NULL);
pw_array_init(&globals.file_maps, 1024); pw_array_init(&globals.file_maps, 1024);
pw_array_init(&globals.fd_maps, 256); pw_array_init(&globals.fd_maps, 256);

View file

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

View file

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

View file

@ -272,7 +272,7 @@ msgstr "Contraròtle automatic del ganh"
#: spa/plugins/alsa/acp/alsa-mixer.c:2665 #: spa/plugins/alsa/acp/alsa-mixer.c:2665
msgid "No Automatic Gain Control" 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 #: spa/plugins/alsa/acp/alsa-mixer.c:2666
msgid "Boost" msgid "Boost"
@ -288,7 +288,7 @@ msgstr "Amplificador"
#: spa/plugins/alsa/acp/alsa-mixer.c:2669 #: spa/plugins/alsa/acp/alsa-mixer.c:2669
msgid "No Amplifier" msgid "No Amplifier"
msgstr "Cap d'amplificador" msgstr "Pas d'amplificador"
#: spa/plugins/alsa/acp/alsa-mixer.c:2670 #: spa/plugins/alsa/acp/alsa-mixer.c:2670
msgid "Bass Boost" msgid "Bass Boost"
@ -296,7 +296,7 @@ msgstr "Amplificacion bassas"
#: spa/plugins/alsa/acp/alsa-mixer.c:2671 #: spa/plugins/alsa/acp/alsa-mixer.c:2671
msgid "No Bass Boost" 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/alsa/acp/alsa-mixer.c:2672
#: spa/plugins/bluez5/bluez5-device.c:1995 #: 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 #: spa/plugins/alsa/acp/alsa-mixer.c:4733
#, c-format #, c-format
msgid "%s Output" msgid "%s Output"
msgstr "Sortida %s" msgstr "%s Sortida"
#: spa/plugins/alsa/acp/alsa-mixer.c:4741 #: spa/plugins/alsa/acp/alsa-mixer.c:4741
#, c-format #, c-format
msgid "%s Input" 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 #: spa/plugins/alsa/acp/alsa-util.c:1220 spa/plugins/alsa/acp/alsa-util.c:1314
#, c-format #, c-format

115
po/pl.po
View file

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

137
po/sl.po
View file

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

183
po/sv.po
View file

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

341
po/tr.po
View file

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

View file

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

View file

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

View file

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

View file

@ -5,13 +5,13 @@
#ifndef SPA_BUFFER_H #ifndef SPA_BUFFER_H
#define SPA_BUFFER_H #define SPA_BUFFER_H
#include <spa/utils/defs.h>
#include <spa/buffer/meta.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#include <spa/utils/defs.h>
#include <spa/buffer/meta.h>
#ifndef SPA_API_BUFFER #ifndef SPA_API_BUFFER
#ifdef SPA_API_IMPL #ifdef SPA_API_IMPL
#define SPA_API_BUFFER 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; 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 #ifndef SPA_META_H
#define SPA_META_H #define SPA_META_H
#include <spa/utils/defs.h>
#include <spa/pod/pod.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#include <spa/utils/defs.h>
#include <spa/pod/pod.h>
#ifndef SPA_API_META #ifndef SPA_API_META
#ifdef SPA_API_IMPL #ifdef SPA_API_IMPL
#define SPA_API_META 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_Busy, /**< don't write to buffer when count > 0 */
SPA_META_VideoTransform, /**< struct spa_meta_transform */ SPA_META_VideoTransform, /**< struct spa_meta_transform */
SPA_META_SyncTimeline, /**< struct spa_meta_sync_timeline */ SPA_META_SyncTimeline, /**< struct spa_meta_sync_timeline */
_SPA_META_LAST, /**< not part of ABI/API */ _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. * A metadata element.
* *
@ -190,12 +183,7 @@ struct spa_meta_videotransform {
* this metadata as SPA_PARAM_BUFFERS_metaType when negotiating a buffer * this metadata as SPA_PARAM_BUFFERS_metaType when negotiating a buffer
* layout with 2 extra fds. * layout with 2 extra fds.
*/ */
#define SPA_META_FEATURE_SYNC_TIMELINE_RELEASE (1<<0) /**< metadata supports RELEASE */
struct spa_meta_sync_timeline { 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 flags;
uint32_t padding; uint32_t padding;
uint64_t acquire_point; /**< the timeline acquire point, this is when the data uint64_t acquire_point; /**< the timeline acquire point, this is when the data

View file

@ -5,10 +5,6 @@
#ifndef SPA_BUFFER_TYPES_H #ifndef SPA_BUFFER_TYPES_H
#define 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 * \addtogroup spa_buffer
* \{ * \{
@ -18,6 +14,10 @@
extern "C" { extern "C" {
#endif #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 SPA_TYPE_INFO_POINTER_BASE "Buffer"
#define SPA_TYPE_INFO_BUFFER_BASE SPA_TYPE_INFO_Buffer ":" #define SPA_TYPE_INFO_BUFFER_BASE SPA_TYPE_INFO_Buffer ":"

View file

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

View file

@ -5,10 +5,6 @@
#ifndef SPA_CONTROL_TYPES_H #ifndef SPA_CONTROL_TYPES_H
#define 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 #ifdef __cplusplus
extern "C" { extern "C" {
#endif #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 */ /* base for parameter object enumerations */
#define SPA_TYPE_INFO_Control SPA_TYPE_INFO_ENUM_BASE "Control" #define SPA_TYPE_INFO_Control SPA_TYPE_INFO_ENUM_BASE "Control"
#define SPA_TYPE_INFO_CONTROL_BASE SPA_TYPE_INFO_Control ":" #define SPA_TYPE_INFO_CONTROL_BASE SPA_TYPE_INFO_Control ":"

View file

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

View file

@ -5,11 +5,6 @@
#ifndef SPA_DEBUG_BUFFER_H #ifndef SPA_DEBUG_BUFFER_H
#define 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 #ifdef __cplusplus
extern "C" { extern "C" {
#endif #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 #ifndef SPA_API_DEBUG_BUFFER
#ifdef SPA_API_IMPL #ifdef SPA_API_IMPL
#define SPA_API_DEBUG_BUFFER SPA_API_IMPL #define SPA_API_DEBUG_BUFFER SPA_API_IMPL

View file

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

View file

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

View file

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

View file

@ -5,15 +5,6 @@
#ifndef SPA_DEBUG_FORMAT_H #ifndef SPA_DEBUG_FORMAT_H
#define 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 #ifdef __cplusplus
extern "C" { extern "C" {
#endif #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 #ifndef SPA_API_DEBUG_FORMAT
#ifdef SPA_API_IMPL #ifdef SPA_API_IMPL
#define SPA_API_DEBUG_FORMAT 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; break;
case SPA_TYPE_Id: case SPA_TYPE_Id:
{ {
uint32_t value = *(uint32_t *) body; const char *str = spa_debug_type_find_short_name(info, *(int32_t *) body);
const char *str = spa_debug_type_find_short_name(info, value);
char tmp[64]; char tmp[64];
if (str == NULL) { if (str == NULL) {
snprintf(tmp, sizeof(tmp), "%" PRIu32, value); snprintf(tmp, sizeof(tmp), "%d", *(int32_t*)body);
str = tmp; str = tmp;
} }
spa_strbuf_append(buffer, "%s", str); 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); spa_strbuf_append(buffer, "%f", *(double *) body);
break; break;
case SPA_TYPE_String: case SPA_TYPE_String:
spa_strbuf_append(buffer, "%-*s", size, (char *) body); spa_strbuf_append(buffer, "%s", (char *) body);
break; break;
case SPA_TYPE_Rectangle: case SPA_TYPE_Rectangle:
{ {
@ -93,12 +90,10 @@ spa_debug_strbuf_format_value(struct spa_strbuf *buffer, const struct spa_type_i
int i = 0; int i = 0;
info = info && info->values ? info->values : info; info = info && info->values ? info->values : info;
spa_strbuf_append(buffer, "< "); spa_strbuf_append(buffer, "< ");
if (b->child.size >= spa_pod_type_size(b->child.type)) { SPA_POD_ARRAY_BODY_FOREACH(b, size, p) {
SPA_POD_ARRAY_BODY_FOREACH(b, size, p) { if (i++ > 0)
if (i++ > 0) spa_strbuf_append(buffer, ", ");
spa_strbuf_append(buffer, ", "); spa_debug_strbuf_format_value(buffer, info, b->child.type, p, b->child.size);
spa_debug_strbuf_format_value(buffer, info, b->child.type, p, b->child.size);
}
} }
spa_strbuf_append(buffer, " >"); spa_strbuf_append(buffer, " >");
break; break;
@ -133,7 +128,7 @@ SPA_API_DEBUG_FORMAT int spa_debugc_format(struct spa_debug_context *ctx, int in
if (info == NULL) if (info == NULL)
info = spa_type_format; info = spa_type_format;
if (format == NULL || format->type != SPA_TYPE_Object) if (format == NULL || SPA_POD_TYPE(format) != SPA_TYPE_Object)
return -EINVAL; return -EINVAL;
if (spa_format_parse(format, &mtype, &mstype) < 0) 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; type = val->type;
size = val->size; 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; continue;
vals = SPA_POD_BODY(val);
ti = spa_debug_type_find(info, prop->key); ti = spa_debug_type_find(info, prop->key);
key = ti ? ti->name : NULL; key = ti ? ti->name : NULL;

View file

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

View file

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

View file

@ -5,10 +5,6 @@
#ifndef SPA_DEBUG_NODE_H #ifndef SPA_DEBUG_NODE_H
#define 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 #ifdef __cplusplus
extern "C" { extern "C" {
#endif #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 #ifndef SPA_API_DEBUG_NODE
#ifdef SPA_API_IMPL #ifdef SPA_API_IMPL
#define SPA_API_DEBUG_NODE SPA_API_IMPL #define SPA_API_DEBUG_NODE SPA_API_IMPL

View file

@ -5,14 +5,6 @@
#ifndef SPA_DEBUG_POD_H #ifndef SPA_DEBUG_POD_H
#define 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 #ifdef __cplusplus
extern "C" { extern "C" {
#endif #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 #ifndef SPA_API_DEBUG_POD
#ifdef SPA_API_IMPL #ifdef SPA_API_IMPL
#define SPA_API_DEBUG_POD 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"); spa_debugc(ctx, "%*s" "Bool %s", indent, "", (*(int32_t *) body) ? "true" : "false");
break; break;
case SPA_TYPE_Id: case SPA_TYPE_Id:
spa_debugc(ctx, "%*s" "Id %-8" PRIu32 " (%s)", indent, "", *(uint32_t *) body, spa_debugc(ctx, "%*s" "Id %-8d (%s)", indent, "", *(int32_t *) body,
spa_debug_type_find_name(info, *(uint32_t *) body)); spa_debug_type_find_name(info, *(int32_t *) body));
break; break;
case SPA_TYPE_Int: 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; break;
case SPA_TYPE_Long: case SPA_TYPE_Long:
spa_debugc(ctx, "%*s" "Long %" PRIi64 "", indent, "", *(int64_t *) body); 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; struct spa_pod_array_body *b = (struct spa_pod_array_body *)body;
void *p; void *p;
const struct spa_type_info *ti = spa_debug_type_find(SPA_TYPE_ROOT, b->child.type); 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"); b->child.size, ti ? ti->name : "unknown");
if (b->child.size < min_size) { info = info && info->values ? info->values : info;
spa_debugc(ctx, "%*s" " INVALID child.size < %" PRIu32, indent, "", min_size); SPA_POD_ARRAY_BODY_FOREACH(b, size, p)
} else { spa_debugc_pod_value(ctx, indent + 2, info, b->child.type, p, b->child.size);
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; break;
} }
case SPA_TYPE_Choice: 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; struct spa_pod_choice_body *b = (struct spa_pod_choice_body *)body;
void *p; void *p;
const struct spa_type_info *ti = spa_debug_type_find(spa_type_choice, b->type); 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); ti ? ti->name : "unknown", b->flags, size, b->child.size);
if (b->child.size < min_size) { SPA_POD_CHOICE_BODY_FOREACH(b, size, p)
spa_debugc(ctx, "%*s" "INVALID child.size < %" PRIu32, indent, "", min_size); spa_debugc_pod_value(ctx, indent + 2, info, b->child.type, p, b->child.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; break;
} }
case SPA_TYPE_Struct: case SPA_TYPE_Struct:
{ {
struct spa_pod *b = (struct spa_pod *)body, *p; struct spa_pod *b = (struct spa_pod *)body, *p;
spa_debugc(ctx, "%*s" "Struct: size %" PRIu32, indent, "", size); spa_debugc(ctx, "%*s" "Struct: size %d", indent, "", size);
SPA_POD_FOREACH(b, size, p) { SPA_POD_FOREACH(b, size, p)
uint32_t min_size = spa_pod_type_size(p->type); spa_debugc_pod_value(ctx, indent + 2, info, p->type, SPA_POD_BODY(p), p->size);
if (p->size < min_size) {
spa_debugc(ctx, "%*s" "INVALID child.size < %" PRIu32, indent, "", min_size);
} else {
spa_debugc_pod_value(ctx, indent + 2, info, p->type, SPA_POD_BODY(p), p->size);
}
}
break; break;
} }
case SPA_TYPE_Object: case SPA_TYPE_Object:
@ -143,37 +125,21 @@ 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 = ti ? spa_debug_type_find(ti->values, 0) : NULL;
ii = ii ? spa_debug_type_find(ii->values, b->id) : 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 ")", spa_debugc(ctx, "%*s" "Object: size %d, type %s (%d), id %s (%d)", indent, "", size,
indent, "", size, ti ? ti->name : "unknown", b->type, ii ? ii->name : "unknown", b->id); ti ? ti->name : "unknown", b->type, ii ? ii->name : "unknown", b->id);
info = ti ? ti->values : info; info = ti ? ti->values : info;
SPA_POD_OBJECT_BODY_FOREACH(b, size, p) { 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); 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, spa_debugc(ctx, "%*s" "Prop: key %s (%d), flags %08x", indent+2, "",
indent+2, "", name, p->key, p->flags); ii ? ii->name : "unknown", p->key, p->flags);
if (p->value.size < min_size) { spa_debugc_pod_value(ctx, indent + 4, ii ? ii->values : NULL,
spa_debugc(ctx, "%*s" "INVALID value.size < %" PRIu32, indent, "", min_size); p->value.type,
} else { SPA_POD_CONTENTS(struct spa_pod_prop, p),
spa_debugc_pod_value(ctx, indent + 4, ii ? ii->values : NULL, p->value.size);
p->value.type,
SPA_POD_CONTENTS(struct spa_pod_prop, p),
p->value.size);
}
} }
break; break;
} }
@ -185,25 +151,19 @@ spa_debugc_pod_value(struct spa_debug_context *ctx, int indent, const struct spa
ti = spa_debug_type_find(info, b->unit); 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"); ti ? ti->name : "unknown");
SPA_POD_SEQUENCE_BODY_FOREACH(b, size, c) { 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); 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"); c->offset, ii ? ii->name : "unknown");
if (c->value.size < min_size) { spa_debugc_pod_value(ctx, indent + 4, ii ? ii->values : NULL,
spa_debugc(ctx, "%*s" "INVALID value.size < %" PRIu32, indent, "", min_size); c->value.type,
} else { SPA_POD_CONTENTS(struct spa_pod_control, c),
spa_debugc_pod_value(ctx, indent + 4, ii ? ii->values : NULL, c->value.size);
c->value.type,
SPA_POD_CONTENTS(struct spa_pod_control, c),
c->value.size);
}
} }
break; break;
} }
@ -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); spa_debugc_mem(ctx, indent + 2, body, size);
break; break;
default: default:
spa_debugc(ctx, "%*s" "unhandled POD type %" PRIu32, indent, "", type); spa_debugc(ctx, "%*s" "unhandled POD type %d", indent, "", type);
break; break;
} }
return 0; 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, 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) 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, 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 SPA_API_DEBUG_POD int

View file

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

View file

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

View file

@ -5,13 +5,6 @@
#ifndef SPA_GRAPH_H #ifndef SPA_GRAPH_H
#define 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 #ifdef __cplusplus
extern "C" { extern "C" {
#endif #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 #ifndef SPA_API_GRAPH
#ifdef SPA_API_IMPL #ifdef SPA_API_IMPL
#define SPA_API_GRAPH SPA_API_IMPL #define SPA_API_GRAPH SPA_API_IMPL

View file

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

View file

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

View file

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

View file

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

View file

@ -5,8 +5,6 @@
#ifndef SPA_COMMAND_NODE_H #ifndef SPA_COMMAND_NODE_H
#define SPA_COMMAND_NODE_H #define SPA_COMMAND_NODE_H
#include <spa/pod/command.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -16,6 +14,8 @@ extern "C" {
* \{ * \{
*/ */
#include <spa/pod/command.h>
/* object id of SPA_TYPE_COMMAND_Node */ /* object id of SPA_TYPE_COMMAND_Node */
enum spa_node_command { enum spa_node_command {
SPA_NODE_COMMAND_Suspend, /**< suspend a node, this removes all configured 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_ParamEnd, /**< end a transaction */
SPA_NODE_COMMAND_RequestProcess,/**< Sent to a driver when some other node emitted SPA_NODE_COMMAND_RequestProcess,/**< Sent to a driver when some other node emitted
* the RequestProcess event. */ * 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_ID(cmd) SPA_COMMAND_ID(cmd, SPA_TYPE_COMMAND_Node)
#define SPA_NODE_COMMAND_INIT(id) SPA_COMMAND_INIT(SPA_TYPE_COMMAND_Node, id) #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 #ifndef SPA_EVENT_NODE_H
#define SPA_EVENT_NODE_H #define SPA_EVENT_NODE_H
#include <spa/pod/event.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -16,6 +14,8 @@ extern "C" {
* \{ * \{
*/ */
#include <spa/pod/event.h>
/* object id of SPA_TYPE_EVENT_Node */ /* object id of SPA_TYPE_EVENT_Node */
enum spa_node_event { enum spa_node_event {
SPA_NODE_EVENT_Error, SPA_NODE_EVENT_Error,
@ -23,7 +23,6 @@ enum spa_node_event {
SPA_NODE_EVENT_RequestRefresh, SPA_NODE_EVENT_RequestRefresh,
SPA_NODE_EVENT_RequestProcess, /*< Ask the driver to start processing SPA_NODE_EVENT_RequestProcess, /*< Ask the driver to start processing
* the graph */ * the graph */
SPA_NODE_EVENT_User, /* User defined event */
}; };
#define SPA_NODE_EVENT_ID(ev) SPA_EVENT_ID(ev, SPA_TYPE_EVENT_Node) #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 */ /* properties for SPA_TYPE_EVENT_Node */
enum spa_event_node { enum spa_event_node {
SPA_EVENT_NODE_START, 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 #ifndef SPA_IO_H
#define SPA_IO_H #define SPA_IO_H
#include <spa/utils/defs.h>
#include <spa/pod/pod.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -17,6 +14,9 @@ extern "C" {
* \{ * \{
*/ */
#include <spa/utils/defs.h>
#include <spa/pod/pod.h>
/** IO areas /** IO areas
* *
* IO information for a port on a node. This is allocated * 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 * 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 * 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 * 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 * not need to update the contents of their \ref SPA_IO_Clock.
* see \ref page_driver for further details.
* *
* The host generally gives each node a separate \ref spa_io_clock in \ref * 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 * 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 * contents of \ref SPA_IO_Clock of other nodes. Instead, \ref SPA_IO_Position
* is used to look up the current graph time. * is used to look up the current graph time.
* *
* A node is a driver when \ref spa_io_clock::id and the ID in * A node is a driver when \ref spa_io_clock.id in \ref SPA_IO_Clock and
* \ref spa_io_position.clock in \ref SPA_IO_Position are the same. * \ref spa_io_position.clock.id in \ref SPA_IO_Position are the same.
*
* The flags are set by the graph driver at the start of each cycle.
*/ */
struct spa_io_clock { struct spa_io_clock {
#define SPA_IO_CLOCK_FLAG_FREEWHEEL (1u<<0) /**< Graph is freewheeling. It runs at the maximum #define SPA_IO_CLOCK_FLAG_FREEWHEEL (1u<<0) /* graph is freewheeling */
* possible rate, only constrained by the processing #define SPA_IO_CLOCK_FLAG_XRUN_RECOVER (1u<<1) /* recovering from xrun */
* power of the machine it runs on. This can be useful #define SPA_IO_CLOCK_FLAG_LAZY (1u<<2) /* lazy scheduling */
* for offline processing, where processing in real #define SPA_IO_CLOCK_FLAG_NO_RATE (1u<<3) /* the rate of the clock is only approximately.
* time is not desired. */ * it is recommended to use the nsec as a clock source.
#define SPA_IO_CLOCK_FLAG_XRUN_RECOVER (1u<<1) /**< A node's process callback did not complete within * The rate_diff contains the measured inaccuracy. */
* 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.
* 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 flags; /**< Clock flags */
uint32_t id; /**< Unique clock id, set by host application */ uint32_t id; /**< Unique clock id, set by host application */
char name[64]; /**< Clock name prefixed with API, set by node when it receives 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. */ * can be used to check if nodes share the same clock. */
uint64_t nsec; /**< Time in nanoseconds against monotonic clock uint64_t nsec; /**< Time in nanoseconds against monotonic clock
* (CLOCK_MONOTONIC). This fields reflects a real time instant * (CLOCK_MONOTONIC). This fields reflects a real time instant
* in the past, when the current cycle started. The value may * in the past. The value may have jitter. */
* have jitter. */
struct spa_fraction rate; /**< Rate for position/duration/delay/xrun */ struct spa_fraction rate; /**< Rate for position/duration/delay/xrun */
uint64_t position; /**< Current position, in samples @ \ref rate */ uint64_t position; /**< Current position, in samples @ \ref rate */
uint64_t duration; /**< Duration of current cycle, 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 */ 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 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 * clock speeds. */
* internal clock is faster than the monotonic clock (by that
* factor), and vice versa. */
uint64_t next_nsec; /**< Estimated next wakeup time in nanoseconds. uint64_t next_nsec; /**< Estimated next wakeup time in nanoseconds.
* This time is a logical start time of the next cycle, and * This time is a logical start time of the next cycle, and
* is not necessarily in the future. * 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 * 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 * 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 * the graph in its \ref SPA_IO_Clock. Also, \ref spa_io_position.clock.id
* will be the clock id of the driving node in the graph. * will contain the clock id of the driving node in the graph.
* *
* The position clock indicates the logical start time of the current graph * The position clock indicates the logical start time of the current graph
* cycle. * 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. * 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 * 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 * 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. * e.g. drives the node buffer fill level toward a specific value.
* *

View file

@ -5,14 +5,6 @@
#ifndef SPA_NODE_H #ifndef SPA_NODE_H
#define 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 #ifdef __cplusplus
extern "C" { extern "C" {
#endif #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 #ifndef SPA_API_NODE
#ifdef SPA_API_IMPL #ifdef SPA_API_IMPL
#define SPA_API_NODE SPA_API_IMPL #define SPA_API_NODE SPA_API_IMPL

View file

@ -5,12 +5,6 @@
#ifndef SPA_NODE_TYPES_H #ifndef SPA_NODE_TYPES_H
#define 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 #ifdef __cplusplus
extern "C" { extern "C" {
#endif #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 SPA_TYPE_INFO_ENUM_BASE "IO"
#define SPA_TYPE_INFO_IO_BASE SPA_TYPE_INFO_IO ":" #define SPA_TYPE_INFO_IO_BASE SPA_TYPE_INFO_IO ":"
@ -46,20 +46,16 @@ 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_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_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_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 }, { 0, 0, NULL, NULL },
}; };
static const struct spa_type_info spa_type_node_event[] = { 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_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 }, { 0, 0, NULL, NULL },
}; };
#define SPA_TYPE_INFO_NodeCommand SPA_TYPE_INFO_COMMAND_BASE "Node" #define SPA_TYPE_INFO_NodeCommand SPA_TYPE_INFO_COMMAND_BASE "Node"
#define SPA_TYPE_INFO_NODE_COMMAND_BASE SPA_TYPE_INFO_NodeCommand ":" #define SPA_TYPE_INFO_NODE_COMMAND_BASE SPA_TYPE_INFO_NodeCommand ":"
static const struct spa_type_info spa_type_node_command_id[] = { static const struct spa_type_info spa_type_node_command_id[] = {
{ SPA_NODE_COMMAND_Suspend, SPA_TYPE_COMMAND_Node, SPA_TYPE_INFO_NODE_COMMAND_BASE "Suspend", NULL }, { SPA_NODE_COMMAND_Suspend, SPA_TYPE_COMMAND_Node, SPA_TYPE_INFO_NODE_COMMAND_BASE "Suspend", 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_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_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_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 }, { 0, 0, NULL, NULL },
}; };
static const struct spa_type_info spa_type_node_command[] = { 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 }, { 0, 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, 0, NULL, NULL }, { 0, 0, NULL, NULL },
}; };

View file

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

View file

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

View file

@ -5,11 +5,6 @@
#ifndef SPA_AUDIO_AAC_UTILS_H #ifndef SPA_AUDIO_AAC_UTILS_H
#define 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 #ifdef __cplusplus
extern "C" { extern "C" {
#endif #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 #ifndef SPA_API_AUDIO_AAC_UTILS
#ifdef SPA_API_IMPL #ifdef SPA_API_IMPL
#define SPA_API_AUDIO_AAC_UTILS SPA_API_IMPL #define SPA_API_AUDIO_AAC_UTILS SPA_API_IMPL

View file

@ -5,12 +5,12 @@
#ifndef SPA_AUDIO_AAC_H #ifndef SPA_AUDIO_AAC_H
#define SPA_AUDIO_AAC_H #define SPA_AUDIO_AAC_H
#include <spa/param/audio/raw.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#include <spa/param/audio/raw.h>
/** /**
* \addtogroup spa_param * \addtogroup spa_param
* \{ * \{
@ -18,19 +18,19 @@ extern "C" {
enum spa_audio_aac_stream_format { enum spa_audio_aac_stream_format {
SPA_AUDIO_AAC_STREAM_FORMAT_UNKNOWN, SPA_AUDIO_AAC_STREAM_FORMAT_UNKNOWN,
/** Raw AAC frames */ /* Raw AAC frames */
SPA_AUDIO_AAC_STREAM_FORMAT_RAW, 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, 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, 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, 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, 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, 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_MP4FF,
SPA_AUDIO_AAC_STREAM_FORMAT_CUSTOM = 0x10000, 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 #ifndef SPA_AUDIO_ALAC_UTILS_H
#define 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 #ifdef __cplusplus
extern "C" { extern "C" {
#endif #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 #ifndef SPA_API_AUDIO_ALAC_UTILS
#ifdef SPA_API_IMPL #ifdef SPA_API_IMPL
#define SPA_API_AUDIO_ALAC_UTILS SPA_API_IMPL #define SPA_API_AUDIO_ALAC_UTILS SPA_API_IMPL

View file

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

View file

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

View file

@ -5,11 +5,6 @@
#ifndef SPA_AUDIO_AMR_UTILS_H #ifndef SPA_AUDIO_AMR_UTILS_H
#define 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 #ifdef __cplusplus
extern "C" { extern "C" {
#endif #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 #ifndef SPA_API_AUDIO_AMR_UTILS
#ifdef SPA_API_IMPL #ifdef SPA_API_IMPL
#define SPA_API_AUDIO_AMR_UTILS SPA_API_IMPL #define SPA_API_AUDIO_AMR_UTILS SPA_API_IMPL

View file

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

View file

@ -5,11 +5,6 @@
#ifndef SPA_AUDIO_APE_UTILS_H #ifndef SPA_AUDIO_APE_UTILS_H
#define 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 #ifdef __cplusplus
extern "C" { extern "C" {
#endif #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 #ifndef SPA_API_AUDIO_APE_UTILS
#ifdef SPA_API_IMPL #ifdef SPA_API_IMPL
#define SPA_API_AUDIO_APE_UTILS SPA_API_IMPL #define SPA_API_AUDIO_APE_UTILS SPA_API_IMPL

View file

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

View file

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

View file

@ -5,12 +5,6 @@
#ifndef SPA_AUDIO_DSD_UTILS_H #ifndef SPA_AUDIO_DSD_UTILS_H
#define 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 #ifdef __cplusplus
extern "C" { extern "C" {
#endif #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 #ifndef SPA_API_AUDIO_DSD_UTILS
#ifdef SPA_API_IMPL #ifdef SPA_API_IMPL
#define SPA_API_AUDIO_DSD_UTILS 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_channels, SPA_POD_OPT_Int(&info->channels),
SPA_FORMAT_AUDIO_position, SPA_POD_OPT_Pod(&position)); SPA_FORMAT_AUDIO_position, SPA_POD_OPT_Pod(&position));
if (position == NULL || 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); SPA_FLAG_SET(info->flags, SPA_AUDIO_FLAG_UNPOSITIONED);
return res; return res;

View file

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

View file

@ -5,11 +5,6 @@
#ifndef SPA_AUDIO_DSP_UTILS_H #ifndef SPA_AUDIO_DSP_UTILS_H
#define 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 #ifdef __cplusplus
extern "C" { extern "C" {
#endif #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 #ifndef SPA_API_AUDIO_DSP_UTILS
#ifdef SPA_API_IMPL #ifdef SPA_API_IMPL
#define SPA_API_AUDIO_DSP_UTILS SPA_API_IMPL #define SPA_API_AUDIO_DSP_UTILS SPA_API_IMPL

View file

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