https://nick-black.com/dankwiki/index.php?title=Special:NewPages&feed=atom&hideredirs=1&limit=50&offset=&namespace=0&username=&tagfilter=&size-mode=max&size=0dankwiki - New pages [en]2024-03-28T10:27:08ZFrom dankwikiMediaWiki 1.41.0https://nick-black.com/dankwiki/index.php/TRIMTRIM2024-03-20T01:55:17Z<p>Dank: </p>
<hr />
<div>SSDs generally need to have the blocks belonging to a file explicitly deallocated. This is done with the ATA TRIM command. Unfortunately, regular use of TRIM can have negative effects on performance (TRIM cannot be queued on some devices) and lifetime. It is thus not generally recommended to trim after every delete operation, though this can be configured ("online mode"). Note that trimming generally requires the filesystem to be mounted, unlike e.g. <tt>fsck</tt>. Note also that TRIM can have negative impacts on the security of encrypted filesystems.<br />
<br />
A device which doesn't support TRIM will be rejected by <tt>fstrim</tt> with an error, so it's safe to run on arbitrary filesystems.<br />
<br />
TRIM is engaged from userspace using the FITRIM ioctl.<br />
<br />
==Online mode==<br />
* Use the <tt>discard</tt> option when <tt>mount</tt>ing<br />
* On [[ZFS]], set the <tt>autotrim</tt> pool option<br />
<br />
==Explicit==<br />
* <tt>fstrim -v</tt> <i>filesystem</i><br />
* On [[ZFS]], <tt>zpool trim</tt> <i>poolname</i><br />
* On md or DM, all devices in the pool must support TRIM, or it will be rejected<br />
<br />
==Periodic==<br />
* <tt>systemctl enable fstrim.timer</tt></div>Dankhttps://nick-black.com/dankwiki/index.php/Rescuing_LinuxRescuing Linux2024-03-08T06:10:32Z<p>Dank: </p>
<hr />
<div>Sometimes you need perform irregular, unpleasant tasks involving a Linux box. One generally picks up the techniques via experience. This kind of thing tends to become less necessary as one learns Linux better, and thus it's easy to lose currency. The introduction of [[systemd]], for instance, changed almost all of this shit up. Almost everything here requires access to the console, relevant only long before sshd is running (though take a look at e.g. [https://wiki.debian.org/RescueInitramfs RescueInitramfs]).<br />
<br />
==grub==<br />
If there is no boot delay, but you need interactive control, try holding down space when grub comes up.<br />
<br />
Don't go editing grub's configuration files directly if at all possible. Edit <tt>/etc/default/grub</tt> and rebuild them with <tt>update-grub</tt>. Note that <tt>update-grub2</tt> is these days just a symlink to <tt>update-grub</tt>. If what you want to change isn't available via <tt>/etc/default/grub</tt>, try to do it via <tt>/etc/grub.d</tt>. If you're directly editing <tt>grub.cfg</tt>, you're gonna have a bad time (and your changes will be blown away the next time someone runs <tt>update-grub</tt>).<br />
<br />
Do yourself a favor and install [https://packages.debian.org/sid/memtest86+ memtest86+], which will be automatically added to your grub menu on [[UEFI]] machines.<br />
<br />
==kernel command line==<br />
The bootloader can provide command line parameters to the kernel (they can also be specified at build time, see <tt>CONFIG_CMDLINE</tt>). [[systemd]] can take many parameters off of the kernel command line.<br />
<br />
For more output, ensure "quiet" is not present. For still more output, add "debug=vc" (by default, <tt>debug</tt> writes to <tt>/run/initramfs/initramfs.debug</tt>; this sends it to the console).<br />
<br />
The root process can be specified using <tt>init=</tt> (this can also be specified at build time with <tt>CONFIG_DEFAULT_INIT</tt>).<br />
<br />
Note that the kernel does not by default reboot following a panic. This can be undesirable on remote machines. <tt>panic=N</tt> will reboot N seconds after a panic, if N is positive. <tt>/proc/sys/kernel/panic</tt> exposes this.<br />
<br />
===my video is borked===<br />
If you can't get output to the display, [https://www.kernel.org/doc/html/latest/networking/netconsole.html netconsole] is a pretty decent method for quickly getting console output sent to another machine. You won't have ARP or routing, so the target will need be on the local broadcast domain. Specify the target MAC if you can to avoid broadcasting.<br />
<br />
==initramfs==<br />
Almost all distributions ship kernels making use of initramfs these days. An initramfs can be embedded directly into the kernel image (see kernel config entry <tt>CONFIG_INITRAMFS_SOURCE</tt>), but it is usually shipped as its own file instead, and specified by the bootloader. An initramfs is a (possibly compressed) <tt>cpio</tt> archive. On boot, it is unpacked into a tmpfs. The compelling advantage of initramfs is the ability to mount the true root filesystem (which might be on [[NFS]], or encrypted, etc.) from userspace, with a minimal filesystem such as userspace expects. Over time, presence of an initramfs has become more or less assumed, and is is thus now required for all manner of things (i.e. persistent block device names when specifying the root filesystem). In the absence of an initramfs, all code necessary for mounting root must be built into the kernel (i.e. not as modules).<br />
<br />
The [https://packages.debian.org/sid/initramfs-tools initramfs-tools-core] package ships <tt>lsinitramfs</tt> and <tt>unmkinitramfs</tt> to easily list or extract the contents of an initramfs file.<br />
<br />
You're unlikely to run into initrd these days, but it can be unpacked the same way (the difference is in how it's mounted during boot). Initramfs on Debian are named <tt>initrd-*</tt>.<br />
<br />
If built into the kernel, there are no extra considerations for the initramfs. If it's a distinct file, it needs to live somewhere visible to the bootloader. If booting directly from [[UEFI]], it needs live in the ESP. So long as it's kept in the same directory as the kernel image, you ought be fine. Be sure to copy the initramfs along with the kernel image if you're ever backing up the kernel, or moving it to another machine, etc.<br />
<br />
The initramfs often has copies of various kernel modules, so most changes to modules require an initramfs rebuild.<br />
<br />
===writing an initramfs===<br />
<tt>mkinitramfs</tt> is a lower-level tool usually called via <tt>update-initramfs</tt>, controlled by the many configuration files in <tt>/etc/initramfs-tools/</tt>.<br />
<br />
===initramfs can't mount root===<br />
An unpleasant situation is one where initramfs fails to mount the root partition, in which case you will be dumped to the dreaded BusyBox or klibc shells (ash, as in "a shitty shell"). A day when one sees BusyBox is never a good day. If the machine is remote, you are fucked without server-style out of band access (e.g. Dell iDRAC, BMC, KVM-over-IP). Otherwise, if you have a valid root partition somewhere, you can manually continue the boot by mounting that partition to <tt>/mnt/root</tt> and running <tt>exec switch_root /mnt/root /sbin/init</tt> or its non-union equivalent. Usually this means you've specified the wrong root partition in your bootloader; check the <tt>root</tt> command line option to the kernel.<br />
<br />
==fsck on boot==<br />
<br />
==access sans password==<br />
Ideally, you can just provide <tt>init=/bin/sh</tt> on the kernel command line using grub's interactive mode. This will go through the end of the initramfs and invoke <tt>/bin/sh</tt> within the root filesystem.<br />
<br />
<b>what if we can't use interactive mode?</b><br />
===systemd emergency mode with a locked root account===<br />
If you've locked the root account with <tt>passwd -l</tt>, systemd's <tt>sulogin</tt> won't let you enter rescue mode. Use the instructions from "access sans password" above to get a shell if possible, and enable root with <tt>passwd</tt>. Reboot, and <tt>sulogin</tt> will admit you using the new passwork.<br />
<br />
==all my binaries are gone==<br />
The situation can arise that one has an active process context (we'll assume a shell) on a machine where the standard POSIX binaries are unavailable. This can happen due to e.g. a network error, a disk error, memory error, wayward <tt>rm -rf /</tt>, misadventures in package management. What can be done in such a case? Shell builtins, [[sysfs]], <tt>/dev</tt> entries, and [[proc]] usually continue to be available.<br />
===cat without cat===<br />
The bash shell's <tt>echo</tt> or <tt>printf</tt> builtin can be used:<br />
<pre><br />
[freebird](0) $ dmesg<br />
-bash: /usr/bin/dmesg: Input/output error<br />
[freebird](126) $ printf "%s" "$(</proc/kmsg)"<br />
.....<br />
[freebird](0) $ echo "$(</proc/kmsg)"<br />
.....<br />
[freebird](0) $<br />
</pre><br />
===reboot without reboot===<br />
Enable and apply sysrq reboot:<br />
<pre>echo 128 > /proc/sys/kernel/sysrq<br />
echo b > /proc/sysrq-trigger</pre><br />
Alt+SysRq+B will accomplish this at the terminal if sysrq reboot is enabled. Unlike <tt>reboot</tt>, there will be no syncing and unmounting of disks.<br />
<br />
==moving a root filesystem + bootloader==<br />
Ideally, mount the source filesystem <tt>ro</tt>, so it's not being modified while you copy. Start assuming a clean destination filesystem (otherwise, wipe it). Using the <tt>-a</tt> flag, <tt>cp</tt> basic toplevel directories *but do not cross filesystem boundaries on the source* (i.e. if <tt>/home</tt> is on its own filesystem, do not include it below; this includes <tt>/boot/efi</tt>). Any that you skip in this fashion ought have their mountpoints created; add them to the <tt>mkdir</tt> below:<br />
<br />
<pre><br />
cp -a SOURCE/{bin,boot,etc,home,lib*,root,sbin,usr} DEST/<br />
mkdir -p DEST/{dev,proc,var/tmp,tmp}<br />
ln -s /run DEST/var/run<br />
ln -s /lock DEST/var/lock<br />
chmod 1777 DEST/{var/tmp,tmp}<br />
</pre><br />
<br />
<b>ESP, bootloader, initramfs...</b><br />
<br />
==External links==<br />
* Debian wiki page for [https://wiki.debian.org/initramfs initramfs]<br />
* Kernel documentation for [https://www.kernel.org/doc/html/latest/filesystems/ramfs-rootfs-initramfs.html Ramfs, Rootfs, and Initramfs]</div>Dankhttps://nick-black.com/dankwiki/index.php/Io_uring_and_xdp_enter_2024Io uring and xdp enter 20242024-02-14T02:41:15Z<p>Dank: /* io_uring */</p>
<hr />
<div>'''[[Dankblog|dankblog!]] 2024-02-15, 1452 EST, at [[Viewpoint|the danktower]]'''<br />
<br />
Last year (2023), I spent significant time writing code using [[XDP]] and [[io_uring]]. The latter was delightful, the former less so. Work on these technologies has progressed, and it seems time for an update.<br />
<br />
==XDP==<br />
One of the big problems I had with <tt>AF_XDP</tt> sockets was the lack of support for large packets. One could typically only use an MTU of 3KB and some change, putting XDP at a disadvantage relative to systems which happily process 8KB frames. One must supply <tt>XDP_USE_SG</tt>, and supply <tt>xdp.frags</tt> as the program's section name. A single RXring frame might not hold the entire packet, in which case it will be written across several ring frames (with attendant multiple RXring descriptors). The <tt>XDP_PKT_CONTD</tt> flag is set in the <tt>options</tt> field if there are more frames. They will always be written in order, and if there are insufficient frames to write all data, none will be written.<br />
<br />
==io_uring==<br />
Easily the most exciting development is integration of futexes (Jens Axboe 2023-07-20 [https://lwn.net/Articles/938800/ "Add io_uring futex/futexv support"]).<br />
Multiple futexes ("vectored wait") can be supplied at once using <tt>IORING_OP_FUTEX_WAITV</tt> (Jens Axboe 2023-09-29 [https://git.kernel.dk/cgit/linux/commit/?h=io_uring-futex&id=8f350194d5cfd7016d4cd44e433df0faa4d4a703 "add support for vectored futex waits"]).<br />
I used to have the following on my io_uring page:<br />
<br />
<q>It would be nice to have tight integration with condition variables or even mutex/futex (allow me to submit a request to get a lock, and when i get the CQE, i have that lock). Bonus points if the fast (uncontended) path never needs a system call (like mutexes built atop futexes today).</q><br />
<br />
The new API appears to satisfy all my desires!<br />
<br />
Also new is <tt>IORING_OP_WAITID</tt> for working with process state changes (though I would recommend use of [[pidfd|pidfds]] for this kind of thing in new code).<br />
<br />
[https://git.kernel.dk/cgit/linux/commit/?h=io_uring-send-queue&id=060845d3788f20b427631b64a6dbdbd249a0309b Kernel 6.8] introduces <tt>IORING_SEND_MULTISHOT</tt>, bringing the multishot pattern to the TX (<tt>send</tt> and <tt>sendmsg</tt>) side. See Axboe's "[https://lore.kernel.org/io-uring/20240308235045.1014125-1-axboe@kernel.dk/ Send and receive bundles]" post for further optimization using "bundles" (these require registered buffers).<br />
<br />
<tt>IORING_SETUP_REGISTERED_FD_ONLY</tt> registers the ring fd for use with <tt>IORING_REGISTER_USE_REGISTERED_RING</tt>.<br />
<br />
<tt>io_uring_prep_cmd_sock(2)</tt> configures <tt>IORING_OP_URING_CMD</tt> SQEs to perform <tt>setsockopt(2)</tt> operations.<br />
<br />
<tt>io_uring_prep_getxattr(2)</tt> and <tt>io_uring_prep_setxattr(2)</tt> prep SQEs for <tt>getxattr(2)</tt> and <tt>setxattr(2)</tt> operations; <tt>io_uring_prep_fgetxattr(2)</tt> and <tt>io_uring_prep_fsetxattr(2)</tt> do exactly what you'd think.<br />
<br />
Making huge pages as unpleasant as possible to use is a central tenet (perhaps <i>the</i> central tenet) underpinning the entire Linux mission, but <tt>IORING_SETUP_NO_MMAP</tt> was [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=03d89a2de25b added in 6.5], huzzah!<br />
<br />
==See also==<br />
* [https://elixir.bootlin.com/linux/latest/source/Documentation/networking/af_xdp.rst AF_XDP] kernel documentation<br />
<br />
<br />
'''previously: "[[Ebooks_are_hot_garbage|ebooks are hot garbage]]" 2024-02-11'''<br />
<br />
[[Category:Blog]]</div>Dankhttps://nick-black.com/dankwiki/index.php/Ebooks_are_hot_garbageEbooks are hot garbage2024-02-11T08:50:03Z<p>Dank: </p>
<hr />
<div>'''[[Dankblog|dankblog!]] 2024-02-11, 0349 EST, at [[Viewpoint|the danktower]]'''<br />
<br />
Pretty much exactly what the title says.<br />
<br />
I did not consider ebooks when writing <i>[https://midnightssimulacra midnight's simulacra]</i>. This was both fortunate and unfortunate: unfortunate because it's proven difficult to make an acceptable ebook after the fact, fortunate because I really like the print version, and it's more important to me than the ebook, and properly designing for an ebook would have delayed or weakened the print version.<br />
<br />
But goddamn, a lot of people seem to have suddenly developed allergies to a format that worked just fine for 570 years. And I get it. The last time I moved, it required sixty-plus boxes to move the books. I've now got about [[bookshelves|twice as many]]. They cover every surface in my condo along with the majority of the walls. When I travel, they eat precious volume and mass in my bags (then again, I barely own anything besides books, and I hate traveling). The ability to search is admittedly a huge win, as is click-to-define (though the dictionary in my Kindle Paperwhite is trash). That Amazon can reach out and fuck with your shit is completely unacceptable (btw, I know of only one book that Amazon-US refuses to stock, and can thus plausibly be considered a "banned book" in America: <i>[https://en.wikipedia.org/wiki/The_Turner_Diaries The Turner Diaries].</i> No sales from Amazon, and searching for it on subsidiary Goodreads gets "NOTABOOK". This started in 2020, and is some cowardly bullshit). Kindle still can't display characters from certain languages, <i>even if you supply and specify a font that includes the necessary glyphs,</i> which blows my fucking mind.<br />
<br />
Anyway, if you want to sell to these people, you need an ebook. And here begins the shit.<br />
<br />
If you have any page-oriented material, that has no meaning in a world of reflowable text. If you have footnotes, this means:<br />
* get rid of them<br />
* put them at the end of chapter/book, link to them, provide backlink<br />
* use the necessary incantation to get a popup<br />
<br />
of these options, the last seems to me pretty obviously the best. Guess what? Every vendor took the EPUB3 standard, furrowed their brow, and wiped their ass with it. Apple, Amazon, whatever the fuck a Kobo is, even Calibre all went their own way on this issue, leading to [[EPUB#EPUB-specific_markup|monstrosities such as this]] and gigantic wastes of my time. Even this godawful "solution" doesn't necessarily work, because Amazon insists on heuristics based off a link cycle.<br />
<br />
Speaking of Calibre. You tell people, "I wrote a book, now I need an ebook and it's cost me a hundred hours thus far and it totally sucks." They put their hand on their hip, look at you like an idiot, and say "just put your PDF through Calibre," and think they've taught you something. I don't know who's reading this, but unless you're Kovid Goyal, I was using Calibre before your balls dropped. I have code in Calibre. I personally know Kovid, or at least have exchanged hundreds of emails with him. We've discussed his poetry. You don't need to tell me about Calibre.<br />
<br />
Not to blame Kovid, who's written a tremendous piece of software in Calibre (and an even better one IMHO in kitty), but putting my PDF through Calibre to generate anything else churns it into complete shit. This is better than pandoc or tex4ht did, because tex4ht crashed and pandoc pegged a core for several hours, producing nothing. Whether this was an infinite loop or just Haskell being Haskell is not for me to know. Now, you can endlessly fuck with the conversion parameters in Calibre, but at some point you're like, "I'll just build the EPUB up by hand, fuck it." EPUB3 is supposedly the future, with support for MathML and HTML5 and CSS and even multimedia and you can probably watch VR porn in an EPUB3 if you can fit it on your Kobo.<br />
<br />
You will do this not because it is easy, but because you thought it would be easy. And for most straight fiction it probably is. But imagine, say, <i>[https://en.wikipedia.org/wiki/House_of_Leaves House of Leaves]</i>. You're going to be moving the field forward.<br />
<br />
All the current devices support EPUB3, you gather. There are worrying notes about buggy MathML support, and some older devices don't support EPUB3 at all, and the markup is kinda ass, and you're not quite sure how you'd watch <i>Follow that Bird</i> on a Kindle Paperwhite that has neither speakers nor color and is capable of something like 4 FLOPs on a good day, but you're a game little author and you set out.<br />
<br />
Guess what? Kindle <b>does not</b> natively support EPUB3. It "supports" it in that you can upload EPUB3 to KDP, and it'll be converted to AZW3 or MOBI. But stick a raw EPUB3 on your Kindle, and it will not be readable. Does the EPUB3 get converted cleanly to AZW3/MOBI? Who fucking knows? It totally depends on your content. So the largest vendor is still getting a lossy, automated conversion, despite your EPUBbing. It totally sucks. You people killed Jesus.<br />
<br />
'''previously: "[[Writing_a_book_in_LaTeX_in_2023|writing a book in LaTeX in 2023]]" 2023-11-29'''<br />
<br />
[[Category:Blog]]</div>Dankhttps://nick-black.com/dankwiki/index.php/EPUBEPUB2024-01-21T18:51:35Z<p>Dank: /* EPUB-specific markup */</p>
<hr />
<div>EPUB (in version 3.3 as of 2023-12-21) is a container for ebooks using ZIP for its archive and compression. Most of the content is XHTML or media (usually graphics).<br />
<br />
==Contents==<br />
* There must be a file <tt>mimetype</tt> in the toplevel containing the string <tt>application/epub+zip</tt><br />
* There must be a directory <tt>META-INF</tt> in the toplevel containing:<br />
** <tt>container.xml</tt> specifies one or more ''rootfiles'', using their locations relative to the toplevel:<br />
<pre><br />
<?xml version="1.0"?><br />
<container xmlns="urn:oasis:names:tc:opendocument:xmlns:container" version="1.0"><br />
<rootfiles><br />
<rootfile full-path="PATHPATHPATH" media-type="application/oebps-package+xml"/><br />
</rootfiles><br />
</container><br />
</pre><br />
<br />
==EPUB-specific markup==<br />
Ensure you've referenced <tt>xmlns:epub="http://www.idpf.org/2007/ops</tt> in your <tt>html</tt> tag.<br />
<br />
When using reflowable EPUB, there's no real concept of a page, and thus no real concept of footnotes. One can move them to the end of a chapter, but an arguably better solution is a popup. Enclose the footnote text in an <tt>aside</tt> tag ala:<br />
<syntaxhighlight lang="html"><br />
<aside hidden="hidden" epub:type="footnote" id="SOMEID"><br />
<div class="footnote"><a href="#CALLSITE">*</a> Footnote text.</div><br />
</aside><br />
</syntaxhighlight><br />
Use of <tt>epub:type="footnote"</tt> ought result in the text being hidden, but you might need <tt>hidden="hidden"</tt> in your <tt>aside</tt> tag. Unfortunately, this latter causes problems with the popup text in Calibre (at least version 7.4).<br />
Wrap the callsite with an <tt>a</tt> tag:<br />
<syntaxhighlight lang="html"><br />
<a role="doc-noteref" epub:type="noteref" href="#SOMEID" id>Callsite text.</a><br />
</syntaxhighlight><br />
Without <tt>role="doc-noteref"</tt>, you will not get a popup in Calibre.<br />
===Entities===<br />
EPUB3 eliminates all but a few HTML entitites.<br />
* &amp;nbsp; ↦ &amp;#160;<br />
<br />
==See also==<br />
* [https://kindlegen.s3.amazonaws.com/AmazonKindlePublishingGuidelines.pdf Kindle Publishing Guidelines] from Amazon</div>Dankhttps://nick-black.com/dankwiki/index.php/KEF_LS60KEF LS602024-01-19T04:48:42Z<p>Dank: </p>
<hr />
<div>I acquired a pair of [https://us.kef.com/products/ls60-wireless KEF LS60] active wireless speakers in January 2024. The speakers are awesome, but getting them working well with Linux was not completely trivial, and is not quite complete.<br />
<br />
At the time, I had the following versions of crap:<br />
* Linux 6.7<br />
* Pipewire 1.0.1<br />
* Pulseaudio 16.1<br />
* KEF firmware 2.0<br />
<br />
As a first observation, setting up an EQ profile for my small office seemed to <i>substantially</i> improve listening experience. I used Normal Mode (as opposed to expert).<br />
<br />
==Requirements==<br />
I was using [[Mpd|MPD]] 0.23.14 for my music, but I needed a solution at the audio device level, so that video, system sounds, and everything else would use the speakers. So I was looking at pulseaudio or pipewire. I wanted to create a virtual device into which I could dump digital data (probably PWM). The speakers have a line in, but I <i>did not</i> want to do the digital-to-analog conversion on my machine, but rather to use the DAC of the $7,000 speakers. They also have an HDMI input, which could happily accept stereo PCM at up to 24 bits at 192 kHz, but I wanted wireless.<br />
<br />
I might end up using the HDMI if I can't eliminate the latency of my wireless solution.<br />
<br />
An ideal solution would involve:<br />
* no cables between computer and speakers<br />
* lossless transfer to speakers (either as unpacked PCM or packed FLAC/AAC/etc.)<br />
* DAC at speakers<br />
* minimal latency<br />
* output automatically waking the speakers from standby mode<br />
<br />
==Wireless==<br />
Using the app, set the input to "Wi-Fi".<br />
The specs list the following "wireless streaming features":<br />
* AirPlay 2<br />
* Google Chromecast<br />
* Roon Ready<br />
* UPnP Compatible<br />
* Bluetooth 4.2<br />
As far as I'm aware, [[Bluetooth]] audio is always going to involve a lossy compression, so I won't be using it. I did set up Bluetooth just to see that it worked, which it did. You'll have to pair the devices, and connect them.<br />
<br />
Running <tt>avahi-browse -a -t</tt> showed numerous zeroconf services:<br />
* ax200 IPv6 ls60w-eb17fe57-5688-4f03-b2a9-4ef78be95abf _spotify-connect._tcp local<br />
* ax200 IPv6 8417151A1273@lilypad speaker AirTunes Remote Audio local<br />
* ax200 IPv6 lilypad speaker AirPlay Remote Video local<br />
* ax200 IPv6 ls60w-eb17fe57-5688-4f03-b2a9-4ef78be95abf _suegrouping._tcp local<br />
* ax200 IPv6 LS60 Wireless-490b3a50ff76a5f16a56b25fa9ca18fe _tidalconnect._tcp local<br />
* ax200 IPv6 8417151A1273@LS60W _kef-info._tcp local<br />
* ax200 IPv6 ls60w-eb17fe57-5688-4f03-b2a9-4ef78be95abf _sues800device._tcp local<br />
* ax200 IPv6 lilypad speaker Web Site local<br />
<br />
adding <tt>-r</tt> for resolution generated more details:<br />
<pre><br />
= ax200 IPv6 ls60w-xxx _spotify-connect._tcp local<br />
hostname = [ls60w-xxx.local]<br />
address = [192.168.88.77]<br />
port = [80]<br />
txt = ["VERSION=2.9.0" "CPath=/api/stream/spotify:zeroconf"]<br />
= ax200 IPv6 8417151A1273@lilypad speaker AirTunes Remote Audio local<br />
hostname = [ls60w-xxxx.local]<br />
address = [192.168.88.77]<br />
port = [7000]<br />
txt = ["pk=xxx" "vs=366.0" "vn=65537" "tp=UDP" "sf=0x4" "am=LS60 Wireless" "md=0,1,2" "fv=p20.2.0.66.0x187653b" "ft=0x445F8A00,0x1C340" "et=0,4" "da=true" "cn=0,1"]<br />
= ax200 IPv6 lilypad speaker AirPlay Remote Video local<br />
hostname = [ls60w-xxx.local]<br />
address = [192.168.88.77]<br />
port = [7000]<br />
txt = ["pk=xxx" "gcgl=0" "gid=xxx" "pi=xxx" "srcvers=366.0" "protovers=1.1" "serialNumber=xxx" "manufacturer=KEF" "model=LS60 Wireless" "flags=0x4" "fv=p20.2.0.66.0x187653b" "rsf=0x0" "features=0x445F8A00,0x1C340" "deviceid=xxx" "acl=0"]<br />
= ax200 IPv6 ls60w-xxx _suegrouping._tcp local<br />
hostname = [ls60w-xxx.local]<br />
address = [192.168.88.77]<br />
port = [80]<br />
txt = ["ip=192.168.88.77" "groupTimestamp=0" "groupName=" "groupMembers=0" "spotify=true" "transcoder=true" "manufacturer=KEF" "uuid=ls60w-xxx" "name=lilypad speaker"]<br />
= ax200 IPv6 LS60 Wireless-xxx _tidalconnect._tcp local<br />
hostname = [ls60w-xxx.local]<br />
address = [192.168.88.77]<br />
port = [2019]<br />
txt = ["fn=lilypad speaker" "ve=1" "id=xxx" "ca=2" "mn=LS60 Wireless"]<br />
= ax200 IPv6 xxx@LS60W _kef-info._tcp local<br />
hostname = [ls60w-xxx.local]<br />
address = [192.168.88.77]<br />
port = [80]<br />
txt = ["groupRole=N/A" "groupName=N/A" "groupId=N/A" "kefId=xxx" "version=2.0.66.0x187653b" "serialNumberSlave=" "serialNumber=xxx" "manufacturer=KEF" "modelName=LS60 Wireless" "model=SP4017" "mac=xxx" "name=lilypad speaker"]<br />
= ax200 IPv6 ls60w-xxx _sues800device._tcp local<br />
hostname = [ls60w-xxx.local]<br />
address = [192.168.88.77]<br />
port = [80]<br />
txt = ["ip=192.168.88.77" "manufacturer=KEF" "uuid=ls60w-xxx" "serial=xxx" "name=lilypad speaker"]<br />
= ax200 IPv6 lilypad speaker Web Site local<br />
hostname = [ls60w-xxx.local]<br />
address = [192.168.88.77]<br />
port = [80]<br />
txt = []<br />
</pre><br />
<br />
I first tried pipewire+AirPlay using the [https://docs.pipewire.org/page_module_raop_discover.html raop-discover] module. This was able to find the speakers, and created a device visible in <tt>pavucontrol</tt>, but I was unable to produce any audible output using it. The monitor showed signal going to the sink, but I heard nothing.<br />
<br />
I disabled pipewire and pipewire-pulse, and brought up true pulseaudio. Using <tt>pulseaudio-dlna</tt>, I got a working sink that generated sound:<br />
<br />
<pre><br />
Sink #2<br />
State: RUNNING<br />
Name: lilypadspeaker_dlna<br />
Description: lilypad speaker (DLNA)<br />
Driver: module-null-sink.c<br />
Sample Specification: s16le 2ch 44100Hz<br />
Channel Map: front-left,front-right<br />
Owner Module: 25<br />
Mute: no<br />
Volume: front-left: 65536 / 100% / 0.00 dB, front-right: 65536 / 100% / 0.00 dB<br />
balance 0.00<br />
Base Volume: 65536 / 100% / 0.00 dB<br />
Monitor Source: lilypadspeaker_dlna.monitor<br />
Latency: 26367 usec, configured 40000 usec<br />
Flags: DECIBEL_VOLUME LATENCY SET_FORMATS <br />
Properties:<br />
device.description = "lilypad speaker (DLNA)"<br />
device.class = "abstract"<br />
device.icon_name = "audio-card"<br />
Formats:<br />
pcm<br />
</pre><br />
<br />
The first number reported for <b>Latency:</b> changed with each run.</div>Dankhttps://nick-black.com/dankwiki/index.php/Unicode_MathUnicode Math2024-01-13T10:34:52Z<p>Dank: /* Math zones */</p>
<hr />
<div>[[Using_Unicode|Unicode]] admits a plaintext encoding of mathematics approaching that of MathML or [[LaTeX]]. This encoding, [https://unicodemath.org/ UnicodeMath], is Unicode [https://www.unicode.org/notes/tn28/ Technical Note 28]. This ought not be confused with the CTAN [https://ctan.org/pkg/unicode-math?lang=en unicode-math] package.<br />
<br />
As of 2024-01, the current revision is 3.2, last updated 2023-04-13.<br />
<br />
It is intended that word processors and other tools render Unicode Math in a "builtup" format (this requires symbols with different baselines, stretched grouping operators, etc.). It ought be possible to roundtrip from Unicode Math to builtup format and back to Unicode Math without loss of meaningful content.<br />
<br />
==Delimiters==<br />
Known as fences in MathML, brackets (<tt>[]</tt>) braces (<tt>{}</tt>) and parens (<tt>()</tt>) are delimiters. In builtup display, they ought be at least as large as their contents. Pairs of delimiters, even when nested, needn't match up--any closing delimiter works with any opening delimiter. A closing delimiter may have a subscript and/or exponent.<br />
<br />
===Math zones===<br />
Regions/zones of Unicode Math can be set off with quilled brackets (<tt>⁅⁆</tt>).<br />
A "display region" fills a paragraph in the source text; the region is otherwise considered an "inline region", and ought be rendered more compactly. Adjacent math zones are automatically merged.<br />
<br />
Display regions are roughly equivalent to LaTeX's <tt>$$…$$</tt> and <tt>\[…\]</tt>. Inline regions correspond to LaTeX's <tt>$…$</tt> and <tt>\(…\)</tt>.</div>Dank