<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="/styles/rss-styles.xsl"?>
<rss version="2.0" 
    xmlns:atom="http://www.w3.org/2005/Atom"
    xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:source="https://source.scripting.com/"
    >
  <channel>
    <title>Reilly Spitzfaden | All</title>
    <link>https://reillyspitzfaden.com/</link>
    <description>All blog posts, notes, likes, and photos on my site</description>
    <language>en-us</language>
    <pubDate>Sat, 9 Mar 2024 00:00:00 GMT</pubDate>
    <lastBuildDate>Tue, 17 Mar 2026 16:06:02 GMT</lastBuildDate>
    <docs>https://www.rssboard.org/rss-specification</docs>
    <managingEditor>reillypascal@gmail.com (Reilly Spitzfaden)</managingEditor>
    <webMaster>reillypascal@gmail.com (Reilly Spitzfaden)</webMaster>
    <atom:link href="https://reillyspitzfaden.com/feed.xml" rel="self" type="application/rss+xml"/>
    <source:blogroll>https://reillyspitzfaden.com/blogroll.opml</source:blogroll>
    
        <item>
            <title>The Antique Telecommunications Museum</title>
            <author>reillypascal@gmail.com (Reilly Spitzfaden)</author>
            <link>https://reillyspitzfaden.com/posts/2026/03/the-antique-telecommunications-museum/</link>
            <guid>https://reillyspitzfaden.com/posts/2026/03/the-antique-telecommunications-museum/</guid>
            <pubDate>Tue, 17 Mar 2026 16:06:02 GMT</pubDate>
            <description>Remembering my partner taking me to see a museum on one of my favorite topics</description>
            <content:encoded>
            
            

          
          
          &lt;p&gt;James is hosting &lt;a href=&quot;https://jamesg.blog/2026/03/01/indieweb-carnival-museum-memories&quot;&gt;this month&#39;s IndieWeb blog carnival&lt;/a&gt; on the topic “museum memories.”&lt;/p&gt;
&lt;p&gt;One of my favorite museum trips was when my spouse took me to see the Antique Wireless Association&#39;s &lt;a href=&quot;https://www.antiquewireless.org/homepage/museum/&quot;&gt;Communication Technologies Museum&lt;/a&gt; for my birthday a few years ago. I didn&#39;t know about this museum before we went — my spouse had come up with the idea to take me there on their own, and the thoughtfulness made it extra nice. It&#39;s a small museum, and a tour guide walked us and one other couple through the museum, and for several of the exhibits, showed us the devices in action.&lt;/p&gt;
&lt;p&gt;One of my favorite exhibits was a set of &lt;a href=&quot;https://en.wikipedia.org/wiki/Teleprinter&quot;&gt;teletype&lt;/a&gt; machines, all linked together. A teletype is similar to a typewriter, but keypresses can be transmitted and received. Typing on one of these machines sends a code for each character — traditionally the 5-bit &lt;a href=&quot;https://en.wikipedia.org/wiki/Baudot_code&quot;&gt;Baudot code&lt;/a&gt;. When a teletype on the other end of the line receives Baudot code, it types out the same character as the unit sending the code. The museum was kind enough to let visitors type on one of the teletypes, and it was extremely cool to see them communicate with each other, with another unit duplicating what we typed.&lt;/p&gt;
&lt;p&gt;I love mechanical keyboards/typewriters and computer history, and teletypes were one of the earliest ways of interacting with computers. As &lt;a href=&quot;https://reillyspitzfaden.com/posts/2024/12/radio-listening-musically/&quot;&gt;I wrote about previously&lt;/a&gt;, the feeling of transmitting information over a distance also has a strange pull for me. I think there are a few reasons why things like teletypes create this feeling so much more than e.g., the internet. First, they aren&#39;t nearly as mundane, and the unfamiliarity makes me think more about what&#39;s actually happening. Second, the protocol is much simpler, and it&#39;s easier to visualize what&#39;s happening over the wire and how that connects to what I&#39;m typing. It feels more real and immediate, and more tied to the physical realm.&lt;/p&gt;
&lt;p&gt;Another stand-out exhibit was an early arc transmitter that we got to see in action. Kathy Loves Physics has &lt;a href=&quot;https://www.youtube.com/watch?v=hrmx_TKNvyc&quot;&gt;a good video on YouTube&lt;/a&gt; explaining these, but in short, high voltage arcs are generated in rapid succession across a small gap, and this creates oscillating radio-frequency emissions. These were some of the earliest wireless devices, and the museum had a working unit on display. The guide demonstrated running the generator for this transmitter, and it was impressive to watch the powerful arc and hear the immense noise it makes.&lt;/p&gt;
&lt;p&gt;Other exhibits included replicas of radio broadcast and communications rooms from various eras of civilian and military history, and we got to look up close at all the transmitters, receivers, and audio gear for these studios. The biggest was a control room from a &lt;a href=&quot;https://en.wikipedia.org/wiki/Voice_of_America&quot;&gt;Voice of America&lt;/a&gt; station. This exhibit had a large arc of control panels filled with dials, gauges, and screens, and a row of cabinets containing the transmitters and other hardware. Across from this was a section in the back with rows of shelves containing lovingly catalogued receivers and transmitters that hadn&#39;t fit elsewhere in the museum.&lt;/p&gt;
&lt;h2 id=&quot;postscript&quot;&gt;Postscript&lt;/h2&gt;
&lt;p&gt;Thanks to James for hosting this month! This was a fun trip to remember, and I appreciated the chance to think over what made it so interesting and enjoyable. Until next time!&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;mailto:reillypascal@gmail.com?subject=Re:%20&#39;The%20Antique%20Telecommunications%20Museum&#39;&quot;&gt;Reply via email&lt;/a&gt; :: &lt;a href=&quot;https://reillyspitzfaden.com/feeds/&quot;&gt;Subscribe to my other feeds&lt;/a&gt; :: &lt;a href=&quot;https://ko-fi.com/reillyspitzfaden&quot;&gt;Buy me a coffee&lt;/a&gt;&lt;/p&gt;
            </content:encoded>
          </item>
        <item>
            <title>Tidal Cycles/Neovim: No Plugins, 24 Lines of Lua</title>
            <author>reillypascal@gmail.com (Reilly Spitzfaden)</author>
            <link>https://reillyspitzfaden.com/posts/2026/03/tidal-cycles-neovim-no-plugins-24-lines-of-lua/</link>
            <guid>https://reillyspitzfaden.com/posts/2026/03/tidal-cycles-neovim-no-plugins-24-lines-of-lua/</guid>
            <pubDate>Fri, 06 Mar 2026 17:30:00 GMT</pubDate>
            <description>I made a simple, easy-to-maintain way to do “algorave” musical live-coding from Neovim, without needing to depend on other people&#39;s plugins staying updated.</description>
            <content:encoded>
            
            

          
          
          &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://reillyspitzfaden.com/styles/code/prism-perf-custom.css&quot; /&gt;
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://reillyspitzfaden.com/styles/code/code-tweaks.css&quot; /&gt;
&lt;p&gt;I&#39;ve been enjoying writing music using code in Neovim — I &lt;a href=&quot;https://reillyspitzfaden.com/posts/2026/02/friendly-lilypond-with-neovim-audacity/&quot;&gt;recently talked about using Lilypond to write sheet music this way, for example&lt;/a&gt;. Another way of writing music with code is &lt;a href=&quot;https://tidalcycles.org/&quot;&gt;Tidal Cycles&lt;/a&gt;. This is a set of pattern-sequencing tools that talk to the &lt;a href=&quot;https://supercollider.github.io/&quot;&gt;SuperCollider&lt;/a&gt; synthesizer. Tidal Cycles allows a highly compact way of notating musical patterns, and one aimed at &lt;a href=&quot;https://www.youtube.com/watch?v=Db0QJo1eaoI&quot;&gt;live-coding&lt;/a&gt; or “algorave” events, where performers&#39; screens are projected, showing code being typed in real time.&lt;/p&gt;
&lt;p&gt;Today, let&#39;s look at how I bypassed the need for plugins when writing Tidal Cycles code, and created something simple and self-sufficient that also gave me more understanding of my tools!&lt;/p&gt;
&lt;h2 id=&quot;existing-tidal-cycles-tools&quot;&gt;Existing Tidal Cycles Tools&lt;/h2&gt;
&lt;p&gt;The officially-recommended plugin &lt;a href=&quot;https://github.com/tidalcycles/vim-tidal&quot;&gt;vim-tidal&lt;/a&gt; hasn&#39;t been updated since 2020, and whenever I quit the Tidal interpreter in this plugin, I wasn&#39;t able to start it again without quitting and re-opening my terminal. &lt;a href=&quot;https://github.com/grddavies/tidal.nvim&quot;&gt;tidal.nvim&lt;/a&gt; was pretty nice and somewhat newer, but development doesn&#39;t seem to be particularly active, and my next experience made me question if I even needed that.&lt;/p&gt;
&lt;p&gt;I was playing with the &lt;a href=&quot;https://github.com/Olical/conjure&quot;&gt;conjure&lt;/a&gt; plugin, &lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://reillyspitzfaden.com/posts/2026/03/tidal-cycles-neovim-no-plugins-24-lines-of-lua/#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt; which provides interactive &lt;a href=&quot;https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop&quot;&gt;REPL&lt;/a&gt; support for many languages, including Scheme, which I&#39;ve been using with Lilypond. I saw that it was pretty easy to set this up with the &lt;a href=&quot;https://lilypond.org/doc/v2.24/Documentation/extending/scheme-sandbox&quot;&gt;&lt;code&gt;lilypond scheme-sandbox&lt;/code&gt;&lt;/a&gt; command, instead of the suggested MIT Scheme or GNU Guile REPLs — you can &lt;a href=&quot;https://github.com/reillypascal/nvim/blob/d84f72ada230811b0879cba3e2e92b4e8c5f4ca4/lua/plugins/conjure.lua#L14-L15&quot;&gt;see my Neovim configuration for this here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This got me thinking: how hard could it be to set something like this up myself for Tidal Cycles? It turned out that I only needed a little bit of Lua! I always prefer small, simple scripts that I wrote and understand, since I know I can keep these maintained without relying on someone else to write a plugin (or having to dig through a plugin&#39;s worth of code myself in order to fork/maintain it).&lt;/p&gt;
&lt;p&gt;Additionally, it&#39;s extremely easy to stop/start the Tidal interpreter with this configuration, and even more so than in the more recent tidal.nvim plugin. Tidal Cycles just uses Haskell&#39;s &lt;a href=&quot;https://wiki.haskell.org/GHC/GHCi&quot;&gt;GHCi&lt;/a&gt; environment started with a custom file titled &lt;code&gt;BootTidal.hs&lt;/code&gt;. GHCi is the interactive version of the Glasgow Haskell Compiler (GHC). You can enter Haskell expressions at the prompt, and they will be evaluated on the fly. The standard way to quit GHCi is ctrl + D, and since we will just be running GHCi in a Neovim terminal pane, this works great here.&lt;/p&gt;
&lt;h2 id=&quot;my-neovim-configuration&quot;&gt;My Neovim Configuration&lt;/h2&gt;
&lt;p&gt;First, we want Neovim to recognize “.tidal” as a file type. We can add a &lt;code&gt;tidal.lua&lt;/code&gt; file in the &lt;code&gt;ftdetect/&lt;/code&gt; folder with the following code, which lets Neovim know about that file type.&lt;/p&gt;
&lt;span class=&quot;code-file&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/reillypascal/nvim/blob/main/ftdetect/tidal.lua&quot;&gt;ftdetect/tidal.lua&lt;/a&gt;&lt;/p&gt;
&lt;/span&gt;
&lt;pre class=&quot;language-lua&quot;&gt;&lt;code class=&quot;language-lua&quot;&gt;vim&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;filetype&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	extension &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		tidal &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;tidal&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, as mentioned previously, Tidal Cycles uses Haskell&#39;s GHCi. All we need to do is start GHCi in a Neovim terminal window using the correct boot file, and then enter the code at the prompt, followed by a &lt;code&gt;&amp;lt;CR&amp;gt;&lt;/code&gt; character (the “Enter”/“Return” key). We can add keymaps that only apply to a buffer with a .tidal file by putting them in &lt;code&gt;ftplugin/tidal.lua&lt;/code&gt; and adding the &lt;code&gt;buffer = true&lt;/code&gt; option as shown below.&lt;/p&gt;
&lt;span class=&quot;code-file&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/reillypascal/nvim/blob/main/ftplugin/tidal.lua&quot;&gt;ftplugin/tidal.lua&lt;/a&gt;&lt;/p&gt;
&lt;/span&gt;
&lt;pre class=&quot;language-lua&quot;&gt;&lt;code class=&quot;language-lua&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;-- open GHCi REPL in term split using Tidal boot file&lt;/span&gt;
vim&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;keymap&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
	&lt;span class=&quot;token string&quot;&gt;&quot;n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token string&quot;&gt;&quot;&amp;lt;localleader&gt;b&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token string&quot;&gt;&quot;&amp;lt;cmd&gt;10 split term://ghci -ghci-script=$TIDAL_BOOT_PATH/BootTidal.hs %&amp;lt;cr&gt;:startinsert&amp;lt;cr&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; desc &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Boot Tidal interpreter and open in terminal split&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; noremap &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; buffer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since this keymap is local to the buffer, we use the &lt;code&gt;&amp;lt;localleader&amp;gt;&lt;/code&gt; key, which I have mapped to “,“. The command that this keymap runs enters command mode (&lt;code&gt;:&lt;/code&gt;); creates a terminal split that&#39;s 10 characters high; runs GHCi with the Tidal boot file; and then switches to insert mode (Neovim&#39;s terminal defaults to normal mode).&lt;/p&gt;
&lt;p&gt;&lt;code&gt;$TIDAL_BOOT_PATH&lt;/code&gt; here could be replaced with a hardcoded path to the Tidal boot file, but using an environment variable like this lets me use my configuration on multiple computers/OSes. You can set this variable with the following line in your .bashrc or .zshrc file. Note that this is under &lt;code&gt;~/.cabal/share/&lt;/code&gt; (at least on my setup), but contains install-specific details, so you will need to locate the &lt;code&gt;BootTidal.hs&lt;/code&gt; file for your installation. If you want or need, you can manually copy &lt;a href=&quot;https://tidalcycles.org/docs/configuration/boot-tidal/&quot;&gt;the code for &lt;code&gt;BootTidal.hs&lt;/code&gt;&lt;/a&gt; into a file and use the directory where you store that file.&lt;/p&gt;
&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;TIDAL_BOOT_PATH&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/.cabal/share/aarch64-osx-ghc-9.12.2-ea3d/tidal-1.10.1&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, I added two keymaps to let me run the current line and the current block. For the first one:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;yy&lt;/code&gt; “yanks” the current line.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Control-w&lt;/code&gt; accesses window-related commands, and from here, &lt;code&gt;j&lt;/code&gt; will go down a window.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;p&lt;/code&gt; pastes the yanked line, &lt;code&gt;a&lt;/code&gt; enters insert mode &lt;em&gt;after&lt;/em&gt; the line (“append”), and &lt;code&gt;&amp;lt;CR&amp;gt;&lt;/code&gt; sends the line to GHCi.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Control-&#92;&lt;/code&gt; and &lt;code&gt;Control-n&lt;/code&gt; are needed together to exit insert mode in the terminal.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Control-w p&lt;/code&gt; goes to the previous window location.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Running all this from one keymap smoothly takes the current line and runs it in the terminal split.&lt;/p&gt;
&lt;p&gt;Next, we want to do a similar thing for a block of text, potentially including line breaks. (Neo)vim has the concept of &lt;a href=&quot;https://martinlwx.github.io/en/learn-to-use-text-objects-in-vim/&quot;&gt;text objects&lt;/a&gt;, and a block of text with blank lines before and after is a “paragraph” object. &lt;code&gt;yip&lt;/code&gt; (“yank inner paragraph“) will copy the required type of text block. I precede it with &lt;code&gt;&amp;quot;*&lt;/code&gt; to copy to the system clipboard instead of the unnamed &lt;a href=&quot;https://www.brianstorti.com/vim-registers/&quot;&gt;register&lt;/a&gt; used by default. This makes it easier for me to edit the contents of the register before pasting them.&lt;/p&gt;
&lt;p&gt;In order for GCHi/Tidal to accept a block with line breaks, the block needs to be preceded by &lt;code&gt;:{&lt;/code&gt; and followed by &lt;code&gt;:}&lt;/code&gt;, both on separate lines from the block. We can assign things to a register with e.g., &lt;code&gt;:let @* =&lt;/code&gt;, and I chain the required strings together with the existing contents of the register (represented with &lt;code&gt;@*&lt;/code&gt;). Vimscript uses the dot (&lt;code&gt;.&lt;/code&gt;) to chain text together. All told, here are the differences:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We use &lt;code&gt;yip&lt;/code&gt; instead of &lt;code&gt;yy&lt;/code&gt; to yank the paragraph.&lt;/li&gt;
&lt;li&gt;We yank it to/paste it from the &lt;code&gt;&amp;quot;*&lt;/code&gt; register, rather than the default.&lt;/li&gt;
&lt;li&gt;We use &lt;code&gt;:let&lt;/code&gt; to edit the contents of the register.&lt;/li&gt;
&lt;/ul&gt;
&lt;span class=&quot;code-file&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/reillypascal/nvim/blob/main/ftplugin/tidal.lua&quot;&gt;ftplugin/tidal.lua&lt;/a&gt;&lt;/p&gt;
&lt;/span&gt;
&lt;pre class=&quot;language-lua&quot;&gt;&lt;code class=&quot;language-lua&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;-- yank current line; move to term; paste, enter append mode, &amp;lt;CR&gt;; back to normal mode; return to previous location&lt;/span&gt;
vim&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;keymap&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
	&lt;span class=&quot;token string&quot;&gt;&quot;n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token string&quot;&gt;&quot;&amp;lt;localleader&gt;ee&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token string&quot;&gt;[[ yy&amp;lt;C-w&gt;jpa&amp;lt;CR&gt;&amp;lt;C-&#92;&gt;&amp;lt;C-n&gt;&amp;lt;C-w&gt;p ]]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; desc &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Evaluate current line&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; noremap &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; buffer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;-- yank current block to &quot;*; wrap in :{/:}; move to term; paste from &quot;*, enter append mode, &amp;lt;CR&gt;; back to normal mode; return to previous location&lt;/span&gt;
vim&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;keymap&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
	&lt;span class=&quot;token string&quot;&gt;&quot;n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token string&quot;&gt;&quot;&amp;lt;localleader&gt;er&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token string&quot;&gt;[[ &quot;*yip &amp;lt;cmd&gt;let @* = &quot;&#92;:&#92;{&#92;n&quot; . @* . &quot;&#92;:&#92;}&quot;&amp;lt;cr&gt; &amp;lt;C-w&gt;j&quot;*pa&amp;lt;CR&gt;&amp;lt;C-&#92;&gt;&amp;lt;C-n&gt;&amp;lt;C-w&gt;p ]]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; desc &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Evaluate current block&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; noremap &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; buffer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, I add the following line to associate .tidal files with Haskell syntax. This works well, but note that the Haskell Language Server (HLS) may throw a fit on Tidal files — this has been an issue with some Vim/Neovim plugins, but weirdly not others. HLS is not needed for Tidal Cycles itself, but if you also want to write vanilla Haskell, be aware of this. I ended up using &lt;a href=&quot;https://github.com/reillypascal/nvim/blob/d84f72ada230811b0879cba3e2e92b4e8c5f4ca4/lua/config/lsp.lua#L12-L16&quot;&gt;this function&lt;/a&gt; and &lt;a href=&quot;https://github.com/reillypascal/nvim/blob/d84f72ada230811b0879cba3e2e92b4e8c5f4ca4/lua/config/lsp.lua#L29&quot;&gt;this line&lt;/a&gt; in my LSP configuration to prevent HLS from loading unless there is at least one Haskell project root marker in the folder. A bit of a hack, but it works for now.&lt;/p&gt;
&lt;span class=&quot;code-file&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/reillypascal/nvim/blob/main/ftplugin/tidal.lua&quot;&gt;ftplugin/tidal.lua&lt;/a&gt;&lt;/p&gt;
&lt;/span&gt;
&lt;pre class=&quot;language-lua&quot;&gt;&lt;code class=&quot;language-lua&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;-- enables highlighting&lt;/span&gt;
vim&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cmd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;set ft=haskell&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;postscript&quot;&gt;Postscript&lt;/h2&gt;
&lt;p&gt;The tidal.nvim plugin is certainly still quite nice, and may be more your taste. The benefits I found from this project are 1) more flexibility over the default terminal split size, 2) direct access to the GHCi Tidal process in the resulting terminal, 3) a better understanding of my tools in general, and 4) the knowledge that all my setup depends on is the &lt;a href=&quot;https://codeberg.org/uzu/tidal&quot;&gt;base Tidal code&lt;/a&gt; staying maintained. In general, I find it fun and reassuring to make minimalist scripts to accomplish tasks, and this project was similarly satisfying.&lt;/p&gt;
&lt;p&gt;I plan to keep tinkering and writing about Tidal Cycles/Neovim, as well as Lilypond (which I mentioned at the beginning). I hope to see you then — until next time!&lt;/p&gt;
&lt;hr class=&quot;footnotes-sep&quot; /&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;In addition to the Conjure plugin, &lt;a href=&quot;https://github.com/Vigemus/iron.nvim&quot;&gt;iron.nvim&lt;/a&gt; is another general-purpose REPL plugin you could try. &lt;a href=&quot;https://reillyspitzfaden.com/posts/2026/03/tidal-cycles-neovim-no-plugins-24-lines-of-lua/#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;p&gt;&lt;a href=&quot;mailto:reillypascal@gmail.com?subject=Re:%20&#39;Tidal%20Cycles/Neovim:%20No%20Plugins,%2024%20Lines%20of%20Lua&#39;&quot;&gt;Reply via email&lt;/a&gt; :: &lt;a href=&quot;https://reillyspitzfaden.com/feeds/&quot;&gt;Subscribe to my other feeds&lt;/a&gt; :: &lt;a href=&quot;https://ko-fi.com/reillyspitzfaden&quot;&gt;Buy me a coffee&lt;/a&gt;&lt;/p&gt;
            </content:encoded>
          </item>
        <item>
            <title>Friendly Lilypond with Neovim &amp; Audacity</title>
            <author>reillypascal@gmail.com (Reilly Spitzfaden)</author>
            <link>https://reillyspitzfaden.com/posts/2026/02/friendly-lilypond-with-neovim-audacity/</link>
            <guid>https://reillyspitzfaden.com/posts/2026/02/friendly-lilypond-with-neovim-audacity/</guid>
            <pubDate>Fri, 27 Feb 2026 17:35:05 GMT</pubDate>
            <description>I made a nice setup to write Lilypond scores in Neovim, while still being able to conveniently view and listen to them</description>
            <content:encoded>
            
            

          
          
          &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://reillyspitzfaden.com/styles/code/prism-perf-custom.css&quot; /&gt;
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://reillyspitzfaden.com/styles/code/code-tweaks.css&quot; /&gt;
&lt;p&gt;&lt;a href=&quot;https://lilypond.org/&quot;&gt;Lilypond&lt;/a&gt; is a program and language for writing musical scores using only text. The syntax is similar to &lt;a href=&quot;https://en.wikipedia.org/wiki/LaTeX&quot;&gt;LaTeX&lt;/a&gt;, and this can be easily converted to nice-looking PDF scores, as well as MIDI files for previewing/making mockups. In addition, there are e.g., Python libraries such as &lt;a href=&quot;https://abjad.github.io/&quot;&gt;Abjad&lt;/a&gt; that allow for algorithmic manipulation of musical notation. &lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://reillyspitzfaden.com/posts/2026/02/friendly-lilypond-with-neovim-audacity/#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt; I&#39;ve found that I enjoy writing text files more than I enjoy using graphical programs such as Dorico/Sibelius/the late Finale, so I&#39;ve recently been trying out Lilypond.&lt;/p&gt;
&lt;p&gt;Part of what I&#39;ve been enjoying about text files is that I&#39;ve gotten &lt;a href=&quot;https://github.com/reillypascal/nvim&quot;&gt;my Neovim setup&lt;/a&gt; to a place that&#39;s very pleasant and smooth to work with. Additionally, I&#39;ve developed joint issues, and even with a nice vertical mouse, typing exacerbates the joint issues much less.&lt;/p&gt;
&lt;p&gt;For writing Lilypond, the IDE-like program &lt;a href=&quot;https://www.frescobaldi.org/&quot;&gt;Frescobaldi&lt;/a&gt; is popular. It bundles a text editor with tools for handling boilerplate code, transposing and other musical tasks, and a MIDI player and score viewer that make it easy to see and hear the results of the code. Since I prefer using my own Neovim setup, I decided to try getting as much of the convenience of Frescobaldi as possible with the tools I prefer. I think it turned out pretty well! Let&#39;s have a look at how it works.&lt;/p&gt;
&lt;h2 id=&quot;neovim-setup&quot;&gt;Neovim Setup&lt;/h2&gt;
&lt;p&gt;First (and easiest), there is a nice Neovim plugin &lt;a href=&quot;https://github.com/martineausimon/nvim-lilypond-suite&quot;&gt;nvim-lilypond-suite&lt;/a&gt;. This adds syntax highlighting and PDF/playback keyboard shortcuts. I also use the &lt;a href=&quot;https://github.com/stevearc/conform.nvim&quot;&gt;conform.nvim&lt;/a&gt; plugin to perform automatic formatting (e.g., line breaks, spacing, etc.). This plugin communicates with existing formatting tools, and here I used the &lt;a href=&quot;https://python-ly.readthedocs.io/en/latest/&quot;&gt;python-ly&lt;/a&gt; command-line program. It has indentation/formatting options, and I made conform.nvim aware of these commands using &lt;a href=&quot;https://github.com/reillypascal/nvim/blob/0efaa3262aa483d052bbab00c2219893e2a2d8a1/lua/plugins/conform.lua#L72-L81&quot;&gt;this configuration here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This covers most of what Frescobaldi does, but for audio playback, there is one wrinkle that&#39;s specific to my needs that makes the provided playback not work. The nvim-lilypond-suite plugin uses &lt;a href=&quot;https://timidity.sourceforge.net/&quot;&gt;timidity&lt;/a&gt; or &lt;a href=&quot;https://www.fluidsynth.org/&quot;&gt;fluidsynth&lt;/a&gt; to convert MIDI files (which are just instructions to a synthesizer on the notes to play) to audio files. These two programs use a &lt;a href=&quot;https://en.wikipedia.org/wiki/SoundFont&quot;&gt;SoundFont&lt;/a&gt; — a predetermined collection of synthesizers — to convert the MIDI file to audio. In my compositions, I often like to have a &lt;a href=&quot;https://en.wikipedia.org/wiki/Max_(software)&quot;&gt;Max/MSP&lt;/a&gt; patch being controlled by e.g., a live MIDI keyboardist, and played alongside live instruments. This is unfortunately not compatible with timidity/fluidsynth.&lt;/p&gt;
&lt;h2 id=&quot;midi-playback&quot;&gt;MIDI Playback&lt;/h2&gt;
&lt;p&gt;macOS provides the &lt;a href=&quot;https://help.ableton.com/hc/en-us/articles/209774225-Setting-up-a-virtual-MIDI-bus&quot;&gt;IAC&lt;/a&gt; virtual MIDI connection, which allows me to send MIDI data between programs, including sending it to Max. &lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://reillyspitzfaden.com/posts/2026/02/friendly-lilypond-with-neovim-audacity/#fn2&quot; id=&quot;fnref2&quot;&gt;[2]&lt;/a&gt;&lt;/sup&gt; This means I just needed to find a program that can play the MIDI file that Lilypond generates into the IAC bus in order to hear my Max patches played as the keyboardist would play them.&lt;/p&gt;
&lt;p&gt;I looked for a surprisingly long time before realizing that Audacity &lt;a href=&quot;https://manual.audacityteam.org/man/note_tracks.html&quot;&gt;can load MIDI files&lt;/a&gt; and can play them back over IAC. It would work OK to drag and drop the files in, but I would miss the convenience of Frescobaldi automatically updating the MIDI file, and having to manually load the file and delete the previous ones would partly defeat the purpose of using Neovim to get away from the mouse.&lt;/p&gt;
&lt;p&gt;Fortunately, it turns out &lt;a href=&quot;https://manual.audacityteam.org/man/scripting.html&quot;&gt;Audacity can be scripted&lt;/a&gt;! First, go to Audacity &amp;gt; Preferences &amp;gt; Modules (Mac) or Edit &amp;gt; Preferences &amp;gt; Modules (Win), and make sure that “mod-script-pipe” is set to “Enabled.” The Audacity manual gives an &lt;a href=&quot;https://github.com/audacity/audacity/blob/master/au3/scripts/piped-work/pipe_test.py&quot;&gt;example Python script&lt;/a&gt; to confirm that the connection is now working. At the end of this file, note the line &lt;code&gt;do_command(&#39;Help: Command=Help&#39;)&lt;/code&gt;. This sends the message &lt;code&gt;Help: Command=Help&lt;/code&gt; to Audacity, and is a good template of how to send commands more generally.&lt;/p&gt;
&lt;p&gt;What I wanted to accomplish was have my script select any previously-opened tracks, delete them, and then open the latest version of my MIDI file. From looking at the &lt;a href=&quot;https://manual.audacityteam.org/man/scripting_reference.html&quot;&gt;scripting reference page&lt;/a&gt;, I concluded I would need the &lt;code&gt;SelAllTracks:&lt;/code&gt;, &lt;code&gt;RemoveTracks:&lt;/code&gt;, and &lt;code&gt;Import2:&lt;/code&gt; commands. You can see my use of them below:&lt;/p&gt;
&lt;span class=&quot;code-file&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://codeberg.org/reillypascal/forget/src/branch/main/pipe.py&quot;&gt;pipe.py&lt;/a&gt;&lt;/p&gt;
&lt;/span&gt;
&lt;pre class=&quot;language-py&quot;&gt;&lt;code class=&quot;language-py&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;#!/usr/bin/env python3&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; argparse
&lt;span class=&quot;token comment&quot;&gt;# ...&lt;/span&gt;

parser &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; argparse&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ArgumentParser&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
parser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;add_argument&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;input&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;help&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;.mid file to open&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

args &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; parser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;parse_args&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# ...&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;reload_file&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    do_command&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;SelAllTracks:&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    do_command&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;RemoveTracks:&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    do_command&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&#39;Import2: Filename=&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;args&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

reload_file&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I&#39;ve excerpted the sections that I needed to change from the example. I used the &lt;a href=&quot;https://docs.python.org/3/library/argparse.html&quot;&gt;argparse&lt;/a&gt; library to handle command-line arguments — in this case, the MIDI file name — which is stored in &lt;code&gt;args.input&lt;/code&gt;. After that, I run the required Audacity scripting commands, and use a format string to send the name of the MIDI file to Audacity. Because of the “shebang” in the first line of the Python file, the script can be run like this: &lt;code&gt;./pipe.py &amp;lt;my-score&amp;gt;.midi&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&quot;automatically-reloading-midi%2Fpdfs&quot;&gt;Automatically Reloading MIDI/PDFs&lt;/h2&gt;
&lt;p&gt;This is already nice, but I had also seen the utility &lt;a href=&quot;https://eradman.com/entrproject/&quot;&gt;&lt;code&gt;entr&lt;/code&gt;&lt;/a&gt;, which will run commands whenever a given file changes. The Bash script below runs two copies of &lt;code&gt;entr&lt;/code&gt; to watch the PDF and MIDI files for changes, and then open each file when it changes.&lt;/p&gt;
&lt;span class=&quot;code-file&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://codeberg.org/reillypascal/forget/src/branch/main/watch&quot;&gt;watch&lt;/a&gt;&lt;/p&gt;
&lt;/span&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token shebang important&quot;&gt;#!/usr/bin/env bash&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# run lilypond on score file to ensure MIDI/PDF are made&lt;/span&gt;
lilypond &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;realpath &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$1&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;# need to run `realpath` *after* MIDI/PDF generated&lt;/span&gt;
	&lt;span class=&quot;token assign-left variable&quot;&gt;midipath&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;realpath &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;${1&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;.ly}&lt;/span&gt;.midi&quot;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;
	&lt;span class=&quot;token assign-left variable&quot;&gt;pdfpath&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;realpath &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;${1&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;.ly}&lt;/span&gt;.pdf&quot;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;# run two separate `entr` processes, one each to watch &amp;amp; open MIDI/PDF&lt;/span&gt;
	&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$midipath&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; entr ./pipe.py &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$midipath&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;# different OSes need different actions to open PDF&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$OSTYPE&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;linux-gnu&quot;&lt;/span&gt;* &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt;
		&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$pdfpath&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; entr evince &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$pdfpath&lt;/span&gt;&quot;&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$OSTYPE&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;darwin&quot;&lt;/span&gt;* &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt;
		&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$pdfpath&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; entr &lt;span class=&quot;token function&quot;&gt;open&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$pdfpath&lt;/span&gt;&quot;&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$OSTYPE&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;cygwin&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;# POSIX compatibility layer and Linux environment emulation for Windows&lt;/span&gt;
		&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$pdfpath&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; entr start &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt; /max &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$pdfpath&lt;/span&gt;&quot;&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$OSTYPE&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;msys&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;# Lightweight shell and GNU utilities compiled for Windows (part of MinGW)&lt;/span&gt;
		&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$pdfpath&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; entr start &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt; /max &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$pdfpath&lt;/span&gt;&quot;&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;
		&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Unknown OS: PDF not opened&quot;&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;fi&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can run the script with &lt;code&gt;./watch &amp;lt;scorename&amp;gt;.ly&lt;/code&gt;. First, the script runs &lt;code&gt;lilypond &amp;lt;scorename&amp;gt;.ly&lt;/code&gt; to ensure that the required MIDI/PDF exist, even if I haven&#39;t remembered to generate them yet. I use &lt;code&gt;realpath&lt;/code&gt; to get the full path of the files and avoid any potential issues loading them (Audacity was the main source of trouble with this).&lt;/p&gt;
&lt;p&gt;The next block runs two copies of &lt;code&gt;entr&lt;/code&gt;. In both cases we use the command format &lt;code&gt;echo &amp;lt;file-to-watch&amp;gt; | entr &amp;lt;run-on-file-change&amp;gt;&lt;/code&gt;. For the PDF, we check the &lt;code&gt;$OSTYPE&lt;/code&gt; variable, since different operating systems have different PDF viewers. On Linux, Evince is common; macOS provides the &lt;code&gt;open&lt;/code&gt; command to open any file in the default program; and the Windows options are based on poking around the internet (note that I don&#39;t have a Windows machine to test them, so please check before using!)&lt;/p&gt;
&lt;h2 id=&quot;listening-in-max&quot;&gt;Listening in Max&lt;/h2&gt;
&lt;p&gt;Now that I can send MIDI messages between programs over a virtual MIDI device, it&#39;s pretty straightforward to use them in Max. Max has the &lt;code&gt;[notein]&lt;/code&gt;, &lt;code&gt;[ctlin]&lt;/code&gt; and &lt;code&gt;[bendin]&lt;/code&gt; objects for note, CC, and pitch bend data respectively. MIDI files generated by Lilypond send MIDI data over different channels for each instrument, and these objects can take arguments to listen to only one specific channel. The &lt;a href=&quot;https://www.snoize.com/MIDIMonitor/&quot;&gt;MIDI Monitor&lt;/a&gt; app is useful to see which channels are which, but Lilypond seems to assign increasing channel numbers from top to bottom in the score.&lt;/p&gt;
&lt;p&gt;In addition to running the Max patch for the keyboardist, Max is useful for hosting VST plugins to handle mockups for the other instruments. I found the &lt;code&gt;[midiselect]&lt;/code&gt; object useful for handling MIDI input, then send that into &lt;code&gt;[midiformat]&lt;/code&gt;. You can connect the right outlet of &lt;code&gt;[midiformat]&lt;/code&gt; to the &lt;code&gt;[vst~]&lt;/code&gt; object — this will give &lt;code&gt;[vst~]&lt;/code&gt; the “midievent” message format it needs. Also note that &lt;code&gt;[vst~]&lt;/code&gt; should have the &lt;code&gt;@autosave 1&lt;/code&gt; attribute set — this will ensure your VST settings are saved.&lt;/p&gt;
&lt;p&gt;If you don&#39;t use Max, note that most DAWs and other programs that can host virtual instruments (e.g., I&#39;ve tried this with Logic Pro, REAPER, and Mainstage) can also take input over a virtual MIDI bus. You could also connect to SuperCollider, Pure Data, VCV Rack, and many others.&lt;/p&gt;
&lt;h2 id=&quot;postscript&quot;&gt;Postscript&lt;/h2&gt;
&lt;p&gt;I&#39;ve been having a ton of fun with Lilypond, including &lt;a href=&quot;https://en.wikipedia.org/wiki/Microtonality&quot;&gt;microtones&lt;/a&gt;, algorithmic composition with Python/Abjad, and more. There&#39;s a lot of interesting stuff to discuss there, and I&#39;m planning to write a few more posts about these topics sometime soon. I hope to see you then — until next time!&lt;/p&gt;
&lt;hr class=&quot;footnotes-sep&quot; /&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;I use “algorithmic” here in the sense of Iannis Xenakis&#39; &lt;a href=&quot;https://en.wikipedia.org/wiki/Formalized_Music&quot;&gt;&lt;em&gt;Formalized Music&lt;/em&gt;&lt;/a&gt; — i.e., handwritten algorithms without large, unethical datasets — not in the LLM sense. &lt;a href=&quot;https://reillyspitzfaden.com/posts/2026/02/friendly-lilypond-with-neovim-audacity/#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;While I haven&#39;t tried this on Linux yet, &lt;a href=&quot;https://qjackctl.sourceforge.io/qjackctl-screenshots.html&quot;&gt;QJackCtl&lt;/a&gt; and &lt;a href=&quot;https://wiki.archlinux.org/title/JACK_Audio_Connection_Kit&quot;&gt;JACK&lt;/a&gt; should allow routing MIDI between programs. &lt;a href=&quot;https://wiki.archlinux.org/title/PulseAudio/Examples#PulseAudio_through_JACK&quot;&gt;This page section&lt;/a&gt; also discusses getting JACK to play nice with PulseAudio. &lt;a href=&quot;https://www.nerds.de/en/loopbe1.html&quot;&gt;LoopBe1&lt;/a&gt; looks like a possibility for Windows, but I haven&#39;t tried it. &lt;a href=&quot;https://reillyspitzfaden.com/posts/2026/02/friendly-lilypond-with-neovim-audacity/#fnref2&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;p&gt;&lt;a href=&quot;mailto:reillypascal@gmail.com?subject=Re:%20&#39;Friendly%20Lilypond%20with%20Neovim%20&amp;amp;%20Audacity&#39;&quot;&gt;Reply via email&lt;/a&gt; :: &lt;a href=&quot;https://reillyspitzfaden.com/feeds/&quot;&gt;Subscribe to my other feeds&lt;/a&gt; :: &lt;a href=&quot;https://ko-fi.com/reillyspitzfaden&quot;&gt;Buy me a coffee&lt;/a&gt;&lt;/p&gt;
            </content:encoded>
          </item>
        <item>
            <title>Caw</title>
            <author>reillypascal@gmail.com (Reilly Spitzfaden)</author>
            <link>https://reillyspitzfaden.com/caw/</link>
            <guid>https://reillyspitzfaden.com/caw/</guid>
            <pubDate>Sat, 07 Feb 2026 00:00:00 GMT</pubDate>
            <description>Caw</description>
            <content:encoded>
            
            

          
          
          &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://reillyspitzfaden.com/styles/onecolumn.css&quot; /&gt;
&lt;style&gt;
    .img {
        max-width: 100%;
    }
&lt;/style&gt;
&lt;h1 class=&quot;sectionHeader&quot;&gt;Caw&lt;/h1&gt;
&lt;p&gt;It is a “caw”&lt;/p&gt;
&lt;p&gt;&lt;audio controls=&quot;&quot; src=&quot;https://reillyspitzfaden.com/media/audio/caw.mp3&quot; title=&quot;caw&quot;&gt;&lt;/audio&gt;&lt;/p&gt;
&lt;section&gt;
&lt;p&gt;&lt;img src=&quot;https://reillyspitzfaden.com/media/images/caw-floppy.webp&quot; alt=&quot;A digital drawing of a rust-brown crow cawing on top of a teal pixel-art floppy disk — the same floppy design as in the banner art on my website&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Thanks to &lt;a href=&quot;https://banjomagpi.com/&quot;&gt;Sophia&lt;/a&gt; for the caw-related art&lt;/p&gt;
&lt;/section&gt;
&lt;p&gt;More caw: &lt;a href=&quot;https://banjomagpi.com/caw/&quot;&gt;Sophia&lt;/a&gt;, &lt;a href=&quot;https://jamesg.blog/caw&quot;&gt;James&lt;/a&gt;, &lt;a href=&quot;https://artlung.com/caw/&quot;&gt;Joe&lt;/a&gt;, &lt;a href=&quot;https://gregorlove.com/caw/&quot;&gt;gRegor&lt;/a&gt;, &lt;a href=&quot;https://www.vanderwal.net/random/entrysel.php?blog=2135&quot;&gt;Thomas&lt;/a&gt;, &lt;a href=&quot;https://burgeonlab.com/caw/&quot;&gt;Naty&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;mailto:reillypascal@gmail.com?subject=Re:%20&#39;Caw&#39;&quot;&gt;Reply via email&lt;/a&gt; :: &lt;a href=&quot;https://reillyspitzfaden.com/feeds/&quot;&gt;Subscribe to my other feeds&lt;/a&gt; :: &lt;a href=&quot;https://ko-fi.com/reillyspitzfaden&quot;&gt;Buy me a coffee&lt;/a&gt;&lt;/p&gt;
            </content:encoded>
          </item>
        <item>
            <title>IndieWeb Movie Club: “Alien”</title>
            <author>reillypascal@gmail.com (Reilly Spitzfaden)</author>
            <link>https://reillyspitzfaden.com/posts/2026/01/indieweb-movie-club-alien/</link>
            <guid>https://reillyspitzfaden.com/posts/2026/01/indieweb-movie-club-alien/</guid>
            <pubDate>Sat, 31 Jan 2026 23:53:51 GMT</pubDate>
            <description>Re-watching a sci-fi classic to discuss with IndieWeb friends, and thinking about the music and sound design</description>
            <content:encoded>
            
            

          
          
          &lt;p&gt;January&#39;s IndieWeb movie club is &lt;em&gt;Alien&lt;/em&gt; (1979), and it&#39;s hosted by Al Abut — &lt;a href=&quot;https://alabut.com/writing/alien1979/&quot;&gt;here is his introduction post for the month&lt;/a&gt;. I&#39;ve been in the mood to see some space horror lately. I saw a promotion for &lt;em&gt;Ash&lt;/em&gt; (2025), which looks like a solid B-movie, and that reminded me to add &lt;em&gt;Sunshine&lt;/em&gt; (2007) and &lt;em&gt;Event Horizon&lt;/em&gt; to my watch list. I&#39;ve also been wanting to watch more movies with my husband, so &lt;em&gt;Alien&lt;/em&gt; is perfect for all of that. This is a re-watch for both of us — we&#39;ve seen it (and &lt;em&gt;Aliens&lt;/em&gt;) before, and liked them a lot.&lt;/p&gt;
&lt;h2 id=&quot;sound-design&quot;&gt;Sound Design&lt;/h2&gt;
&lt;p&gt;A few things stood out to me about the sound design of the film. The first happens a few times throughout. When the initial exploration party leaves the ship, the sound environments inside/outside the vessel have a stark contrast, and the cuts between them are immediate. Later, as the face hugger first attacks Kane, the camera cuts rapidly from attack, only allowing the sudden noise to sound for an instant.&lt;/p&gt;
&lt;p&gt;A similar contrast happens when Lambert and Parker are loading coolant into an escape ship while Ripley gets the escape shuttle ready. Ripley&#39;s surroundings are well-lit and quiet, while Lambert and Parker work noisily, loading the coolant, with Lambert being audibly agitated as well. Here as well, the cuts between the sound environments are immediate and jarring.&lt;/p&gt;
&lt;p&gt;To my ear, these contrasting sound environments emphasize the otherness of the alien, with the suddenness of the cuts exaggerating the difference between the sound environments. This also intensifies the harshness of the environment where the alien will appear, and heightens the sense of impending danger. Especially in the second example above, the time between the cuts speeds up slightly as the alien nears, and finally the loudness of Lambert and Parker&#39;s environment intrudes on Ripley&#39;s part of the ship as she receives their distress call and runs down the halls to help. In both cases, I got a sense from the cuts and their pacing of two narrative strands converging and joining.&lt;/p&gt;
&lt;h2 id=&quot;bart%C3%B3k-reference&quot;&gt;Bartók Reference&lt;/h2&gt;
&lt;p&gt;Jerry Goldsmith&#39;s score includes a passage (from about 1:11:55 to 1:12:30 in the film, or in &lt;a href=&quot;https://reillyspitzfaden.com/posts/2026/01/indieweb-movie-club-alien/www.youtube.com/watch?v=9PGvL2L2irw&amp;amp;t=25s&quot;&gt;this clip&lt;/a&gt;) that reminds me very strongly of &lt;a href=&quot;https://www.youtube.com/watch?v=QElT9KD4uX8&amp;amp;t=974s&quot;&gt;another passage&lt;/a&gt; from Béla Bartók&#39;s &lt;em&gt;Music for Strings, Percussion and Celesta&lt;/em&gt; (1936), movement III.&lt;/p&gt;
&lt;p&gt;I initially wondered if this was the actual Bartók piece and had to look up the soundtrack on Wikipedia to confirm that it wasn&#39;t. I also remembered that the actual Bartók piece appeared in the score for Stanley Kubrick&#39;s &lt;em&gt;The Shining&lt;/em&gt; as the boy Danny rides his tricycle through the endless halls of the hotel. While my first thought was that Goldsmith and/or director Ridley Scott were inspired by Kubrick, since &lt;em&gt;The Shining&lt;/em&gt; came out a year later (1980), that&#39;s of course not possible.&lt;/p&gt;
&lt;p&gt;At any rate, the sinuously winding melody in the high strings, and especially the piano octaves ascending and descending chromatically sound similar enough that I imagine Goldsmith was influenced by the earlier piece. It seems that someone else also had the same thought — I was able to find &lt;a href=&quot;https://www.reddit.com/r/StanleyKubrick/comments/12mh72d/is_it_just_me_or_are_these_two_songs_from_the/&quot;&gt;this thread on Reddit&lt;/a&gt;, asking if others thought the passages sounded similar.&lt;/p&gt;
&lt;p&gt;Interestingly, this music does not appear to have been written for the film. According to &lt;a href=&quot;https://www.filmtracks.com/titles/alien.html&quot;&gt;this review&lt;/a&gt;, Scott and Rawlings borrowed significantly from Goldsmith&#39;s earlier score to &lt;em&gt;Freud&lt;/em&gt; (1962), and &lt;a href=&quot;https://www.youtube.com/watch?v=4902R56BXCY&amp;amp;t=27s&quot;&gt;this title from &lt;em&gt;Freud&lt;/em&gt;&lt;/a&gt; appears to be the same music as the scene in &lt;em&gt;Alien&lt;/em&gt;.&lt;/p&gt;
&lt;h2 id=&quot;final-thoughts&quot;&gt;Final Thoughts&lt;/h2&gt;
&lt;p&gt;I appreciated that this month, there was &lt;a href=&quot;https://events.indieweb.org/2026/01/january-movie-club-DvPcQUkN8eBo&quot;&gt;an event&lt;/a&gt; where people got together on a call and discussed the movies in real time. This both got me to watch the film earlier in the month than I would have otherwise, and was a fun addition to the written discussions. I liked this film choice a lot, and I&#39;m definitely planning to participate in future movie clubs.&lt;/p&gt;
&lt;p&gt;Until next time!&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;mailto:reillypascal@gmail.com?subject=Re:%20&#39;IndieWeb%20Movie%20Club:%20%E2%80%9CAlien%E2%80%9D&#39;&quot;&gt;Reply via email&lt;/a&gt; :: &lt;a href=&quot;https://reillyspitzfaden.com/feeds/&quot;&gt;Subscribe to my other feeds&lt;/a&gt; :: &lt;a href=&quot;https://ko-fi.com/reillyspitzfaden&quot;&gt;Buy me a coffee&lt;/a&gt;&lt;/p&gt;
            </content:encoded>
          </item>
        <item>
            <title>Sending Webmentions with a Simple Shell Script</title>
            <author>reillypascal@gmail.com (Reilly Spitzfaden)</author>
            <link>https://reillyspitzfaden.com/posts/2026/01/sending-webmentions-with-a-simple-shell-script/</link>
            <guid>https://reillyspitzfaden.com/posts/2026/01/sending-webmentions-with-a-simple-shell-script/</guid>
            <pubDate>Wed, 07 Jan 2026 18:25:04 GMT</pubDate>
            <description>I came across a convenient way to send webmentions from my terminal using a simple Bash script.</description>
            <content:encoded>
            
            

          
          
          &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://reillyspitzfaden.com/styles/code/prism-perf-custom.css&quot; /&gt;
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://reillyspitzfaden.com/styles/code/code-tweaks.css&quot; /&gt;
&lt;p&gt;I came across a convenient way to send webmentions from my terminal using a simple Bash script. &lt;a href=&quot;https://indieweb.org/webmention-implementation-guide#One-liner_webmentions&quot;&gt;This page on the IndieWeb wiki&lt;/a&gt; includes a shell script one-liner. It references an older version of the webmention standard, but I was able to figure it out and get it working with my setup. I have the following in &lt;a href=&quot;https://github.com/reillypascal/personalsite-ssg/blob/70701a0af5980082df23f2c89651af6fb7be6d7f/send-wm&quot;&gt;a file titled &lt;code&gt;send-wm&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token shebang important&quot;&gt;#!/usr/bin/env bash&lt;/span&gt;

&lt;span class=&quot;token assign-left variable&quot;&gt;my_url&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$1&lt;/span&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;target_url&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$2&lt;/span&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-i&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;source=&lt;span class=&quot;token variable&quot;&gt;$my_url&lt;/span&gt;&amp;amp;target=&lt;span class=&quot;token variable&quot;&gt;$target_url&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-i&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-s&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$target_url&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;rel=&quot;webmention&quot;&#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-o&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-E&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;https?://[^ &quot;&gt;]+&#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;uniq&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The example had &lt;code&gt;rel=&amp;quot;http://webmention.org/&amp;quot;&lt;/code&gt; instead of &lt;code&gt;rel=&amp;quot;webmention&amp;quot;&lt;/code&gt;, which is the current standard. It also included an extra step — &lt;code&gt;sed &#39;s/rel=&amp;quot;webmention&amp;quot;//&#39;&lt;/code&gt;. I assume this was originally supposed to read something like &lt;code&gt;sed &#39;s/rel=&amp;quot;http:&#92;/&#92;/webmention.org&#92;/&amp;quot;//&#39;&lt;/code&gt;, which would be necessary to make sure there is only one &amp;quot;http(s)&amp;quot; to &lt;code&gt;grep&lt;/code&gt; for. At any rate, that part doesn&#39;t appear to be currently necessary. (UPDATE: I edited the IndieWeb wiki to reflect the current version of this script!)&lt;/p&gt;
&lt;p&gt;This script can be used as follows. Note that to do this, you will first need to run &lt;code&gt;sudo chmod +x send-wm&lt;/code&gt; to make the script executable:&lt;/p&gt;
&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;./send-wm &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;your_url&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;target_url&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The basic command to send a webmention using cURL looks like this:&lt;/p&gt;
&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-i&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;source=&lt;span class=&quot;token variable&quot;&gt;$your_url&lt;/span&gt;&amp;amp;target=&lt;span class=&quot;token variable&quot;&gt;$target_url&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$targets_webmention_endpoint&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This script inserts the provided source/target URLs into the statement, and the part inside the parentheses evaluates to the webmention endpoint from the target page.&lt;/p&gt;
&lt;p&gt;I also added this to &lt;a href=&quot;https://reillyspitzfaden.com/wiki/tutorials/webmention-tutorial/#sending-webmentions-(command-line)&quot;&gt;my webmentions tutorial&lt;/a&gt; — I like to do that so all my webmention info is in one place. I regularly update this, and there&#39;s a table of contents to jump to specific sections.&lt;/p&gt;
&lt;h2 id=&quot;future-plans&quot;&gt;Future Plans&lt;/h2&gt;
&lt;p&gt;I imagine it&#39;s possible to make a version of this that only needs the URL for the post sending the mention, and can parse out a list of URLs linked from that page and try sending webmentions to each, handling any failure gracefully. If I get around to doing that, I&#39;ll write another post and add it to the tutorial. Until next time!&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;mailto:reillypascal@gmail.com?subject=Re:%20&#39;Sending%20Webmentions%20with%20a%20Simple%20Shell%20Script&#39;&quot;&gt;Reply via email&lt;/a&gt; :: &lt;a href=&quot;https://reillyspitzfaden.com/feeds/&quot;&gt;Subscribe to my other feeds&lt;/a&gt; :: &lt;a href=&quot;https://ko-fi.com/reillyspitzfaden&quot;&gt;Buy me a coffee&lt;/a&gt;&lt;/p&gt;
            </content:encoded>
          </item>
        <item>
            <title>App Defaults at the End of 2025</title>
            <author>reillypascal@gmail.com (Reilly Spitzfaden)</author>
            <link>https://reillyspitzfaden.com/notes/2026/01/app-defaults-2025/</link>
            <guid>https://reillyspitzfaden.com/notes/2026/01/app-defaults-2025/</guid>
            <pubDate>Wed, 07 Jan 2026 15:11:17 GMT</pubDate>
            <description></description>
            <content:encoded>
            
            

          
          
          &lt;p&gt;Robb Knight has &lt;a href=&quot;https://defaults.rknight.me/&quot;&gt;a page listing people&#39;s descriptions of their default app choices&lt;/a&gt;, and he just did &lt;a href=&quot;https://rknight.me/blog/app-defaults-2026/&quot;&gt;an update for this year&lt;/a&gt;. I thought it sounded fun, so here are some of mine as of the end of 2025:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Adblocker: uBlockOrigin&lt;/li&gt;
&lt;li&gt;Browser: Firefox; FFUpdater to keep vanilla Firefox for Android updated without the Play Store&lt;/li&gt;
&lt;li&gt;Calendar: Fossify Calendar, DAVx&lt;sup&gt;5&lt;/sup&gt;, macOS Calendar.app&lt;/li&gt;
&lt;li&gt;Chat: Signal&lt;/li&gt;
&lt;li&gt;Cloud File Storage: Mega&lt;/li&gt;
&lt;li&gt;Contacts: GrapheneOS Contacts app&lt;/li&gt;
&lt;li&gt;E-Books: Readest&lt;/li&gt;
&lt;li&gt;File Sharing: LocalSend, OpenMTP, Syncthing&lt;/li&gt;
&lt;li&gt;Local Backups: FreeFileSync&lt;/li&gt;
&lt;li&gt;Mail Client: Mailspring on desktop, Thunderbird on mobile&lt;/li&gt;
&lt;li&gt;Maps: Organic Maps&lt;/li&gt;
&lt;li&gt;Music: Auxio, Lollypop, Music.app&lt;/li&gt;
&lt;li&gt;Notes: Obsidian and Markdown-Oxide/Neovim&lt;/li&gt;
&lt;li&gt;Password Management: Bitwarden&lt;/li&gt;
&lt;li&gt;Podcasts: AntennaPod&lt;/li&gt;
&lt;li&gt;RSS: NetNewsWire, Capy Reader&lt;/li&gt;
&lt;li&gt;To-Do: Same as notes for writing the lists; &lt;a href=&quot;https://codeberg.org/kdwarn/taskfinder&quot;&gt;taskfinder&lt;/a&gt; for tracking/organizing&lt;/li&gt;
&lt;li&gt;Two-Factor Authentication: Aegis&lt;/li&gt;
&lt;li&gt;Weather: Breezy Weather&lt;/li&gt;
&lt;li&gt;Word Processing, Presentations, and Spreadsheets: LibreOffice&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;mailto:reillypascal@gmail.com?subject=Re:%20&#39;App%20Defaults%20at%20the%20End%20of%202025&#39;&quot;&gt;Reply via email&lt;/a&gt; :: &lt;a href=&quot;https://reillyspitzfaden.com/feeds/&quot;&gt;Subscribe to my other feeds&lt;/a&gt; :: &lt;a href=&quot;https://ko-fi.com/reillyspitzfaden&quot;&gt;Buy me a coffee&lt;/a&gt;&lt;/p&gt;
            </content:encoded>
          </item>
        <item>
            <title>Music Listened in 2025</title>
            <author>reillypascal@gmail.com (Reilly Spitzfaden)</author>
            <link>https://reillyspitzfaden.com/posts/2026/01/music-listened-in-2025/</link>
            <guid>https://reillyspitzfaden.com/posts/2026/01/music-listened-in-2025/</guid>
            <pubDate>Mon, 05 Jan 2026 15:41:00 GMT</pubDate>
            <description>Artists, albums, and songs I discovered, revisited, and otherwise enjoyed in 2025</description>
            <content:encoded>
            
            

          
          
          &lt;p&gt;Here&#39;s some of the music I&#39;ve listened to in 2025 — things in regular rotation, things from a while ago that I&#39;ve revisited, and new (or new-to-me) music I&#39;ve added to my library of digital downloads/CDs.&lt;/p&gt;
&lt;h2 id=&quot;new-listens&quot;&gt;New Listens&lt;/h2&gt;
&lt;h3 id=&quot;charli-xcx&quot;&gt;Charli XCX&lt;/h3&gt;
&lt;p&gt;I&#39;ve listened to Charli XCX since before &lt;em&gt;Vroom Vroom&lt;/em&gt; came out, but as is often the case with artists I like, I&#39;ve been moving quite slowly through her discography. I hadn&#39;t given &lt;em&gt;Number 1 Angel&lt;/em&gt; a proper listen, but I currently have “Lipgloss” on repeat. I love the over-the-top, scratchy synth design, and I actually tried my hand at recreating the lead part, to some success. Looks like the key is something that has a bright, buzzy formant — I tried using a kick drum-based wavetable, and some oscillator sync.&lt;/p&gt;
&lt;h3 id=&quot;fire-toolz&quot;&gt;Fire-Toolz&lt;/h3&gt;
&lt;p&gt;Fire-Toolz&#39; first album, &lt;em&gt;Interbeing&lt;/em&gt; came out in 2017. I first heard of her with 2018&#39;s &lt;em&gt;Skinless X-1&lt;/em&gt;, and while I bought &lt;em&gt;Interbeing&lt;/em&gt; shortly after, I never really got into it until this year. This is common with me — Autechre, for example is pretty much my favorite group, but it took me a long time to get into albums other than &lt;em&gt;Confield&lt;/em&gt; and &lt;em&gt;Draft 7.30&lt;/em&gt;. This year I found that I actually really like the first track on &lt;em&gt;Interbeing&lt;/em&gt;, “Yellow Rose-Fire.”&lt;/p&gt;
&lt;p&gt;She also released a new mini-EP &lt;a href=&quot;https://fire-toolz.bandcamp.com/album/private-angel-message&quot;&gt;&lt;em&gt;Private Angel Message&lt;/em&gt;&lt;/a&gt; “to hold us over until the next album.” Track 1 mixes a pounding disco beat, sparkly synths, chugging guitars, and metal screams. Track 2 is a metal-infused cover of a Trammell Starks song originally written for the Weather Channel — I remember reading an article where Angel Marcloid listed some of his work among her favorite music. Track 3 is an ambient electronic collage including acoustic guitar/voice recordings with lyrics no longer remembered by the artist.&lt;/p&gt;
&lt;h3 id=&quot;william-fields&quot;&gt;William Fields&lt;/h3&gt;
&lt;p&gt;I got to see William Fields live with Autechre in Philadelphia this October, and this next one is actually a live recording of that concert! It was very cool to see live, and I&#39;m glad he decided to release the set. It&#39;s available &lt;a href=&quot;https://williamfields.bandcamp.com/album/opening-for-autechre-in-philadelphia&quot;&gt;here on Bandcamp&lt;/a&gt;. William Fields &lt;a href=&quot;https://arstechnica.com/gaming/2020/09/turning-code-into-music-anagrams-open-source-marxism-and-vr-raves/&quot;&gt;uses REAPER&#39;s JSFX scripting tools&lt;/a&gt; to create custom interfaces for glitchy, rhythmically uneasy algorithmic music. &lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://reillyspitzfaden.com/posts/2026/01/music-listened-in-2025/#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h3 id=&quot;autechre&quot;&gt;Autechre&lt;/h3&gt;
&lt;p&gt;At the very end of 2025, I got Autechre&#39;s most recent live album, &lt;em&gt;AE_2022–&lt;/em&gt;. It&#39;s taken me the longest to get into their live albums. The sets tend to be a long, monolithic performance that slowly morphs from one idea to the next over the course of an hour or more. Both in my composition and listening, I tend to prefer short and succinct, but after experiencing such a set live, I have a greater appreciation for the duo&#39;s live work — it feels more familiar now, and takes me back to a good experience I had.&lt;/p&gt;
&lt;p&gt;Another reason I hadn&#39;t gotten this particular album is that (at 19 tracks of around an hour each) it&#39;s usually fairly expensive. It turned out that at the end of December/beginning of January, the &lt;a href=&quot;https://bleep.com/release/483225-autechre-ae2022&quot;&gt;Bleep listing of the album&lt;/a&gt; was on sale for half price, and I ended up buying and enjoying it. It has me interested in re-listening to the Philadelphia set I attended, or hearing some other sets from their 2025 North America tour — would be cool if they release those.&lt;/p&gt;
&lt;h3 id=&quot;kelley-sheehan&quot;&gt;Kelley Sheehan&lt;/h3&gt;
&lt;p&gt;Kelley Sheehan is a composer whose work I&#39;ve admired for a while. She pulls from a mix of underground noise music and contemporary classical performance practices, and her music has a wild riot of colors and strange sounds. I actually wrote about her composition “&lt;a href=&quot;https://www.youtube.com/watch?v=gH3kxga4_JY&quot;&gt;Talk Circus&lt;/a&gt;” for no-input mixer and percussion in my composition dissertation, along with a few other pieces that use audio equipment as instruments. I&#39;d been wanting to have a release of hers I could buy from e.g., Bandcamp, so I was excited to see her release &lt;em&gt;new ears&lt;/em&gt; with the Hoodwink Duo.&lt;/p&gt;
&lt;h3 id=&quot;meljoann&quot;&gt;Meljoann&lt;/h3&gt;
&lt;p&gt;Meljoann describes their music as “hyperjack” — i.e., a hyperpop-like cousin of new jack swing. They released &lt;a href=&quot;https://meljoann.com/posts/status/&quot;&gt;&lt;em&gt;Status&lt;/em&gt;&lt;/a&gt; early this year, and I&#39;ve been enjoying it a lot. “Translate Me” has a thick, detuned bass against floating synths and vocals, and a reggaeton-like beat. “Data Ghost” has trap hi-hats, a funky synth bassline, and an 80s power pop-like guitar solo in the middle. It&#39;s all very fun and danceable, with a healthy dose of chaos and genre-bending. Note that in addition to more well-known platforms, including Bandcamp, you can buy this album directly from the artist, via their &lt;a href=&quot;https://faircamp.meljoann.com/status/&quot;&gt;Faircamp page&lt;/a&gt;! &lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://reillyspitzfaden.com/posts/2026/01/music-listened-in-2025/#fn2&quot; id=&quot;fnref2&quot;&gt;[2]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h2 id=&quot;regular-rotation&quot;&gt;Regular Rotation&lt;/h2&gt;
&lt;p&gt;While I did listen to some new music this year, most of my listening has been familiar, comfortable things. Some of those tracks:&lt;/p&gt;
&lt;h3 id=&quot;autechre-1&quot;&gt;Autechre&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;“Dropp”&lt;/li&gt;
&lt;li&gt;“VL AL 5”&lt;/li&gt;
&lt;li&gt;“Tapr”&lt;/li&gt;
&lt;li&gt;“Gantz Graf”&lt;/li&gt;
&lt;li&gt;“qplay”&lt;/li&gt;
&lt;li&gt;“Altibzz”&lt;/li&gt;
&lt;li&gt;“V-Proc”&lt;/li&gt;
&lt;li&gt;“plyPhon”&lt;/li&gt;
&lt;li&gt;“Fol3”&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;fire-toolz-1&quot;&gt;Fire-Toolz&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;“Soaked: Another Name for Everything”&lt;/li&gt;
&lt;li&gt;“✓ iNTERBEiNG”&lt;/li&gt;
&lt;li&gt;“Experience ☆ Slips ☆ Away”&lt;/li&gt;
&lt;li&gt;“Screamography”&lt;/li&gt;
&lt;li&gt;“Second Life”&lt;/li&gt;
&lt;li&gt;“Response To Subdivisions ☾”&lt;/li&gt;
&lt;li&gt;“✓ BEiNG”&lt;/li&gt;
&lt;li&gt;“Clear Light”&lt;/li&gt;
&lt;li&gt;“觀音 Prayer For The Abuser (abridged)”&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;william-fields-1&quot;&gt;William Fields&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;“Doquado”&lt;/li&gt;
&lt;li&gt;“Athal”&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A fun note on this list is that my spouse and I used ”Altibzz” as background music in a video we showed at our wedding! My spouse told me they just wanted something that wasn&#39;t too cheesy, and I find this track to be hauntingly beautiful, and was happy with how it turned out.&lt;/p&gt;
&lt;h2 id=&quot;revisited&quot;&gt;Revisited&lt;/h2&gt;
&lt;h3 id=&quot;subtle%2F13-%26-god&quot;&gt;Subtle/13 &amp;amp; God&lt;/h3&gt;
&lt;p&gt;Subtle and 13 &amp;amp; God are both groups I loved in high school, and I&#39;ve been listening to them again this year. Both groups are related: 13 &amp;amp; God is a collaboration between Doseone and Jel of Themselves and Subtle (and of other groups from the Anticon experimental hip-hop collective), and members of The Notwist. Both Subtle and 13 &amp;amp; God perform a mix of early 2000s alternative hip hop, trip hop, and indie rock, with rapper Doseone performing in a strange, dense style with dreamlike, abstract lyrics. I&#39;ve been mostly listening to 13 &amp;amp; God&#39;s self-titled debut, and Subtle&#39;s &lt;em&gt;For Hero: For Fool&lt;/em&gt;.&lt;/p&gt;
&lt;h2 id=&quot;postscript&quot;&gt;Postscript&lt;/h2&gt;
&lt;p&gt;Thanks for reading! If you also listen to any of the artists on this list (or similar ones you think I might like) I would love to hear about it — I have comments, email, and a webmention field below. Until next time!&lt;/p&gt;
&lt;hr class=&quot;footnotes-sep&quot; /&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Here, by “algorithmic,” I&#39;m not referring to LLMs or related technology. Rather, as far as I understand, Fields uses probability and more ”classic” algorithms such as Markov chains — algorithms he has set up, rather than tools trained on others&#39; work. &lt;a href=&quot;https://reillyspitzfaden.com/posts/2026/01/music-listened-in-2025/#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;&lt;a href=&quot;https://simonrepp.com/faircamp/&quot;&gt;Faircamp&lt;/a&gt; is a tool for creating a music streaming/download sales page directly on the artist&#39;s website, allowing listeners to pay the artist directly. &lt;a href=&quot;https://reillyspitzfaden.com/posts/2026/01/music-listened-in-2025/#fnref2&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;p&gt;&lt;a href=&quot;mailto:reillypascal@gmail.com?subject=Re:%20&#39;Music%20Listened%20in%202025&#39;&quot;&gt;Reply via email&lt;/a&gt; :: &lt;a href=&quot;https://reillyspitzfaden.com/feeds/&quot;&gt;Subscribe to my other feeds&lt;/a&gt; :: &lt;a href=&quot;https://ko-fi.com/reillyspitzfaden&quot;&gt;Buy me a coffee&lt;/a&gt;&lt;/p&gt;
            </content:encoded>
          </item>
        <item>
            <title>On a Knife-Edge</title>
            <author>reillypascal@gmail.com (Reilly Spitzfaden)</author>
            <link>https://reillyspitzfaden.com/fiction/on-a-knife-edge/</link>
            <guid>https://reillyspitzfaden.com/fiction/on-a-knife-edge/</guid>
            <pubDate>Tue, 09 Dec 2025 20:13:14 GMT</pubDate>
            <description>&lt;i&gt;The clouds cascade above you in incredible detail. In places, their bases form an impenetrable ceiling, but that ceiling is temporary. Wisps of shadow float against glowing shards of the sun, illuminating another layer behind…&lt;/i&gt;</description>
            <content:encoded>
            
            

          
          
          &lt;p&gt;The clouds cascade above you in incredible detail. In places, their bases form an impenetrable ceiling, but that ceiling is temporary. Wisps of shadow float against glowing shards of the sun, illuminating another layer behind. The effect continues below the clouds. As you move forward, you can see the boundaries between light and dark projected on the ground. The changing brightness pulsates as it sweeps over you.&lt;/p&gt;
&lt;p&gt;As you learn the contours above you, the scale of things shifts. The sky is closer now: close enough to visit, it seems, and its vault looks comfortable, as if you could live inside. You are much larger than before. Your body warps — for the moment, more spirit than matter — and your extremities flow up to nestle between the darkened floors, in the space of light between. You feel your heart rate slow, coming to rest after the day.&lt;/p&gt;
&lt;p&gt;Remember when you would stir a giant basin of treacle in your mind&#39;s eye? Remember how the thoughts would catch on the circling waves, tearing and smearing, disappearing into the uniform surface? This feels kind of like then.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Eyes on the road&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The violence of collision drifts into your thoughts. It seems to you now as if even its specter transforms your flesh into something new and strange.&lt;/p&gt;
&lt;p&gt;Your flesh remembers the &lt;em&gt;slam&lt;/em&gt; of impact, mere inches from your left arm, only the door&#39;s thin layer of metal and plastic separating you. It&#39;s as if those materials have punched an imprint into your skin and bone, staying there ever since. The acrid smell lingers in your nostrils, a mix of spent propellant and that strange harshness that sprang from within your head.&lt;/p&gt;
&lt;p&gt;You&#39;ve heard it said that if a machine never leaves your side, how different is it from an implant? You wonder where your body ends. You wonder what you would have to remove to become yourself again.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Eyes on the road&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;You glide along a knife-edge. All around is peaceful. It would be so easy to float into someone else, into something stable and fixed. How can you be flying and yet still at the same time?&lt;/p&gt;
&lt;div class=&quot;dinkus&quot;&gt;***&lt;/div&gt;
&lt;p&gt;You return your eyes to the clouds. They have blended together into a murky gray while you weren&#39;t looking.&lt;/p&gt;
&lt;div class=&quot;centered asterism&quot;&gt;⁂&lt;/div&gt;
&lt;p&gt;&lt;a href=&quot;mailto:reillypascal@gmail.com?subject=Re:%20&#39;On%20a%20Knife-Edge&#39;&quot;&gt;Reply via email&lt;/a&gt; :: &lt;a href=&quot;https://reillyspitzfaden.com/feeds/&quot;&gt;Subscribe to my other feeds&lt;/a&gt; :: &lt;a href=&quot;https://ko-fi.com/reillyspitzfaden&quot;&gt;Buy me a coffee&lt;/a&gt;&lt;/p&gt;
            </content:encoded>
          </item>
        <item>
            <title>Reverb Part 2—Natural Rooms with Allpass Rings</title>
            <author>reillypascal@gmail.com (Reilly Spitzfaden)</author>
            <link>https://reillyspitzfaden.com/posts/2025/09/reverb-part-2/</link>
            <guid>https://reillyspitzfaden.com/posts/2025/09/reverb-part-2/</guid>
            <pubDate>Sun, 28 Sep 2025 16:16:34 GMT</pubDate>
            <description>I discuss some lovely-sounding reverbs that make echo densities build up over time, as in a real room. They&#39;re available in my VST/AU plugin, and I link to Max/MSP versions as well.</description>
            <content:encoded>
            
            

          
          
          &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://reillyspitzfaden.com/styles/notes-photos.css&quot; /&gt;
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://reillyspitzfaden.com/styles/code/prism-perf-custom.css&quot; /&gt;
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://reillyspitzfaden.com/styles/code/code-tweaks.css&quot; /&gt;
&lt;p&gt;Continuing from &lt;a href=&quot;https://reillyspitzfaden.com/posts/2025/06/reverb-part-1&quot;&gt;a previous post&lt;/a&gt;, today we&#39;ll be looking at another collection of reverb algorithms that I&#39;ve implemented in my &lt;a href=&quot;https://github.com/reillypascal/RSAlgorithmicVerb/releases&quot;&gt;reverb plugin&lt;/a&gt;. With only a small increase in complexity over last time, we can get a reverb that grows in density over its duration, much as a real room would, and that sounds smoother and less metallic.&lt;/p&gt;
&lt;p&gt;There are two key differences between the designs here and &lt;a href=&quot;https://reillyspitzfaden.com/posts/2025/06/reverb-part-1/#the-classic-schroeder-reverberator&quot;&gt;the Schroeder reverb I discussed previously&lt;/a&gt;: 1) in this design we will “nest” an allpass filter within another allpass filter, causing the echo density to grow over time, and 2) we will connect the ends of a chain of allpasses into one large “ring,” smoothing out the sound. Let&#39;s discuss how this all works!&lt;/p&gt;
&lt;h2 id=&quot;nested-allpass-filters&quot;&gt;Nested Allpass Filters&lt;/h2&gt;
&lt;p&gt;As we &lt;a href=&quot;https://reillyspitzfaden.com/posts/2025/06/reverb-part-1/#allpass-filters&quot;&gt;previously discussed&lt;/a&gt;, an allpass filter is created by a feedforward and feedback delay in series, with the gain of one of them being negative. This lets all frequencies through at equal amplitude, but delays different frequencies by different amounts, “smearing” or “blurring” the rhythmic attacks of an incoming sound, which is excellent for simulating reverberation. For the diagrams below, note that both the feedforward and feedback can use the same delay line — the design we&#39;re using is equivalent to two separate delays in series.&lt;/p&gt;
&lt;p&gt;Schroeder found that the “smearing” from allpass filters multiplies the number of echoes about threefold. &lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://reillyspitzfaden.com/posts/2025/09/reverb-part-2/#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt; However, the number of echoes is roughly constant over the duration of the reverberation. In a real room, echoes continually build up over the course of a reverb tail. To achieve this buildup, Barry Vercoe and Miller Puckette propose replacing the delay in an allpass filter with another allpass filter creating a “nested” structure. &lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://reillyspitzfaden.com/posts/2025/09/reverb-part-2/#fn2&quot; id=&quot;fnref2&quot;&gt;[2]&lt;/a&gt;&lt;/sup&gt; Since an allpass filter will multiply the echoes that pass through it, taking the output of the inner allpass and feeding it back to the input will cause that multiplication to compound, increasing the number of echoes over time.&lt;/p&gt;
&lt;p&gt;Below are diagrams of this design. Note that in addition to using a single allpass filter as the delay, we can use multiple allpasses in series, as well as combining them with simple delays. Gardner uses both options depicted below in the reverb algorithms we&#39;ll discuss today. &lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://reillyspitzfaden.com/posts/2025/09/reverb-part-2/#fn3&quot; id=&quot;fnref3&quot;&gt;[3]&lt;/a&gt;&lt;/sup&gt; In the diagrams, &lt;mjx-container class=&quot;MathJax&quot; jax=&quot;CHTML&quot; style=&quot;position: relative;&quot;&gt;&lt;mjx-math class=&quot; MJX-TEX&quot; aria-hidden=&quot;true&quot;&gt;&lt;mjx-mi class=&quot;mjx-i&quot;&gt;&lt;mjx-c class=&quot;mjx-c1D44E TEX-I&quot;&gt;&lt;/mjx-c&gt;&lt;/mjx-mi&gt;&lt;mjx-mi class=&quot;mjx-i&quot;&gt;&lt;mjx-c class=&quot;mjx-c1D456 TEX-I&quot;&gt;&lt;/mjx-c&gt;&lt;/mjx-mi&gt;&lt;mjx-mi class=&quot;mjx-i&quot;&gt;&lt;mjx-c class=&quot;mjx-c1D45B TEX-I&quot;&gt;&lt;/mjx-c&gt;&lt;/mjx-mi&gt;&lt;/mjx-math&gt;&lt;mjx-assistive-mml unselectable=&quot;on&quot; display=&quot;inline&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/math&gt;&lt;/mjx-assistive-mml&gt;&lt;/mjx-container&gt; and &lt;mjx-container class=&quot;MathJax&quot; jax=&quot;CHTML&quot; style=&quot;position: relative;&quot;&gt;&lt;mjx-math class=&quot; MJX-TEX&quot; aria-hidden=&quot;true&quot;&gt;&lt;mjx-mi class=&quot;mjx-i&quot;&gt;&lt;mjx-c class=&quot;mjx-c1D44E TEX-I&quot;&gt;&lt;/mjx-c&gt;&lt;/mjx-mi&gt;&lt;mjx-mi class=&quot;mjx-i&quot;&gt;&lt;mjx-c class=&quot;mjx-c1D45C TEX-I&quot;&gt;&lt;/mjx-c&gt;&lt;/mjx-mi&gt;&lt;mjx-mi class=&quot;mjx-i&quot;&gt;&lt;mjx-c class=&quot;mjx-c1D462 TEX-I&quot;&gt;&lt;/mjx-c&gt;&lt;/mjx-mi&gt;&lt;mjx-mi class=&quot;mjx-i&quot;&gt;&lt;mjx-c class=&quot;mjx-c1D461 TEX-I&quot;&gt;&lt;/mjx-c&gt;&lt;/mjx-mi&gt;&lt;/mjx-math&gt;&lt;mjx-assistive-mml unselectable=&quot;on&quot; display=&quot;inline&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;mi&gt;o&lt;/mi&gt;&lt;mi&gt;u&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;/math&gt;&lt;/mjx-assistive-mml&gt;&lt;/mjx-container&gt; are the input and output; the &lt;mjx-container class=&quot;MathJax&quot; jax=&quot;CHTML&quot; style=&quot;position: relative;&quot;&gt;&lt;mjx-math class=&quot; MJX-TEX&quot; aria-hidden=&quot;true&quot;&gt;&lt;mjx-mo class=&quot;mjx-n&quot;&gt;&lt;mjx-c class=&quot;mjx-c2295&quot;&gt;&lt;/mjx-c&gt;&lt;/mjx-mo&gt;&lt;/mjx-math&gt;&lt;mjx-assistive-mml unselectable=&quot;on&quot; display=&quot;inline&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;mo&gt;⊕&lt;/mo&gt;&lt;/math&gt;&lt;/mjx-assistive-mml&gt;&lt;/mjx-container&gt; symbol means the sum of two signals; and &lt;mjx-container class=&quot;MathJax&quot; jax=&quot;CHTML&quot; style=&quot;position: relative;&quot;&gt;&lt;mjx-math class=&quot; MJX-TEX&quot; aria-hidden=&quot;true&quot;&gt;&lt;mjx-mi class=&quot;mjx-i&quot;&gt;&lt;mjx-c class=&quot;mjx-c1D454 TEX-I&quot;&gt;&lt;/mjx-c&gt;&lt;/mjx-mi&gt;&lt;mjx-mn class=&quot;mjx-n&quot;&gt;&lt;mjx-c class=&quot;mjx-c31&quot;&gt;&lt;/mjx-c&gt;&lt;/mjx-mn&gt;&lt;/mjx-math&gt;&lt;mjx-assistive-mml unselectable=&quot;on&quot; display=&quot;inline&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;mi&gt;g&lt;/mi&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/math&gt;&lt;/mjx-assistive-mml&gt;&lt;/mjx-container&gt;, &lt;mjx-container class=&quot;MathJax&quot; jax=&quot;CHTML&quot; style=&quot;position: relative;&quot;&gt;&lt;mjx-math class=&quot; MJX-TEX&quot; aria-hidden=&quot;true&quot;&gt;&lt;mjx-mi class=&quot;mjx-i&quot;&gt;&lt;mjx-c class=&quot;mjx-c1D454 TEX-I&quot;&gt;&lt;/mjx-c&gt;&lt;/mjx-mi&gt;&lt;mjx-mn class=&quot;mjx-n&quot;&gt;&lt;mjx-c class=&quot;mjx-c32&quot;&gt;&lt;/mjx-c&gt;&lt;/mjx-mn&gt;&lt;/mjx-math&gt;&lt;mjx-assistive-mml unselectable=&quot;on&quot; display=&quot;inline&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;mi&gt;g&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/math&gt;&lt;/mjx-assistive-mml&gt;&lt;/mjx-container&gt;, and &lt;mjx-container class=&quot;MathJax&quot; jax=&quot;CHTML&quot; style=&quot;position: relative;&quot;&gt;&lt;mjx-math class=&quot; MJX-TEX&quot; aria-hidden=&quot;true&quot;&gt;&lt;mjx-mi class=&quot;mjx-i&quot;&gt;&lt;mjx-c class=&quot;mjx-c1D454 TEX-I&quot;&gt;&lt;/mjx-c&gt;&lt;/mjx-mi&gt;&lt;mjx-mn class=&quot;mjx-n&quot;&gt;&lt;mjx-c class=&quot;mjx-c33&quot;&gt;&lt;/mjx-c&gt;&lt;/mjx-mn&gt;&lt;/mjx-math&gt;&lt;mjx-assistive-mml unselectable=&quot;on&quot; display=&quot;inline&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;mi&gt;g&lt;/mi&gt;&lt;mn&gt;3&lt;/mn&gt;&lt;/math&gt;&lt;/mjx-assistive-mml&gt;&lt;/mjx-container&gt; are separate gain values, with these values made negative for feedforward signals.&lt;/p&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;https://reillyspitzfaden.com/media/blog/2025/09/reverb_2/single-nested-allpass.webp&quot; alt=&quot;A DSP block diagram. Delay 1 and delay 2 are in series. There are feedforward and feedback values around delay 2, as well as around the entire chain of delays.&quot; /&gt;&lt;/p&gt;
&lt;figcaption&gt;
&lt;p&gt;A block diagram of a nested allpass filter &lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://reillyspitzfaden.com/posts/2025/09/reverb-part-2/#fn4&quot; id=&quot;fnref4&quot;&gt;[4]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;https://reillyspitzfaden.com/media/blog/2025/09/reverb_2/double-nested-allpass.webp&quot; alt=&quot;A DSP block diagram. Delay 1, delay 2, and delay 3 are in series. There are feedforward and feedback values around delay 2 and another set around delay 3, as well as around the entire chain of delays.&quot; /&gt;&lt;/p&gt;
&lt;figcaption&gt;
&lt;p&gt;A block diagram of a double nested allpass filter &lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://reillyspitzfaden.com/posts/2025/09/reverb-part-2/#fn4&quot; id=&quot;fnref4:1&quot;&gt;[4:1]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;allpass-rings&quot;&gt;Allpass Rings&lt;/h2&gt;
&lt;p&gt;To multiply the echoes even further, Gardner chains a mix of standard and nested allpass filters in series, and then feeds the end of that chain into the chain&#39;s input. &lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://reillyspitzfaden.com/posts/2025/09/reverb-part-2/#fn3&quot; id=&quot;fnref3:1&quot;&gt;[3:1]&lt;/a&gt;&lt;/sup&gt; Last time, we placed a low-pass filter in the feedback path of individual comb filters. This time, Gardner suggests placing a single low-pass filter in the feedback path for the entire chain. In both contexts, the purpose is to cause higher frequencies to decay faster, similar to the effect of the atmosphere in a real room.&lt;/p&gt;
&lt;p&gt;Gardner also suggests taking the output sound from multiple points along the allpass chain. These must be &lt;em&gt;between&lt;/em&gt; allpass filters, rather than inside an allpass — taking it from inside an allpass will transform the allpass into a comb, producing an undesirable metallic quality. The output signals can be scaled in different proportions to customize the decay profile of the reverb, and the gain in the global feedback path can be used to scale the decay time overall.&lt;/p&gt;
&lt;p&gt;Both the multiple outputs and the ring structure prevent this reverberator from being allpass. The ring structure in particular is a comb filter, which (&lt;a href=&quot;https://reillyspitzfaden.com/posts/2025/06/reverb-part-1/#feedforward-and-feedback-delays&quot;&gt;as we discussed previously&lt;/a&gt;) introduces comb tooth-like peaks and valleys in the frequency spectrum. While Gardner does not go into depth about why the comb filtering is acceptable, my best understanding is that it&#39;s because the series allpasses add together to create a long delay time.&lt;/p&gt;
&lt;p&gt;As I discussed &lt;a href=&quot;https://reillyspitzfaden.com/posts/2025/06/reverb-part-1/#series-allpasses&quot;&gt;here&lt;/a&gt;, and as the audio example below demonstrates, feedback combs with longer delay times create an audible “flutter,” and shorter times create a metallic sound. The long time in the allpass ring means no metallic sounds, and because the chain of nested allpasses multiplies the echo density so much, the flutter isn&#39;t meaningfully audible.&lt;/p&gt;
&lt;p&gt;&lt;audio controls=&quot;&quot; src=&quot;https://reillyspitzfaden.com/media/blog/2025/09/reverb_2/clap_comb_demo.mp3&quot; title=&quot;feedback comb-filtered clap&quot;&gt;&lt;/audio&gt;&lt;/p&gt;
&lt;h3 id=&quot;gardner&#39;s-reverb-designs&quot;&gt;Gardner&#39;s Reverb Designs&lt;/h3&gt;
&lt;p&gt;Below are the three designs Gardner gives. The small one is good for decay times between 0.38–0.57 seconds; the medium for 0.58–1.29 seconds; and the large for 1.30 seconds and above. Gardner does not find any particular rule for choosing decay times, noting that the process for designing the three topologies he describes was “purely empirical.” &lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://reillyspitzfaden.com/posts/2025/09/reverb-part-2/#fn3&quot; id=&quot;fnref3:2&quot;&gt;[3:2]&lt;/a&gt;&lt;/sup&gt; As with designing Schroeder reverbs, a good starting point seems to be to avoid delay times that easily divide into each other; this ensures the delays do not rhythmically align. The first number next to a delay is the time in milliseconds, and the float value in parentheses is the gain.&lt;/p&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;https://reillyspitzfaden.com/media/blog/2025/09/reverb_2/small-room.webp&quot; alt=&quot;A DSP block diagram. There is a chain of delays and nested allpasses with two outputs taken between the delays, and a 4.2 kHz low pass filter in the feedback loop for the whole chain. Delay list: delay (24 ms); double nested allpass (outer: 35 ms &amp;amp; 0.3, inner: 22 ms &amp;amp; 0.4, 8.3 ms &amp;amp; 0.6); output (0.5 gain); nested allpass (outer: 66 ms &amp;amp; 0.1, inner: 30 ms &amp;amp; 0.4); output (0.5 gain)&quot; /&gt;&lt;/p&gt;
&lt;figcaption&gt;
&lt;p&gt;Small room reverberator &lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://reillyspitzfaden.com/posts/2025/09/reverb-part-2/#fn3&quot; id=&quot;fnref3:3&quot;&gt;[3:3]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;https://reillyspitzfaden.com/media/blog/2025/09/reverb_2/medium-room.webp&quot; alt=&quot;A DSP block diagram. There is a chain of delays and nested allpasses with three outputs taken between the delays, and a 2.5 kHz low pass filter in the feedback loop for the whole chain. Delay list: double nested allpass (outer: 35 ms &amp;amp; 0.3, inner: 8.3 ms &amp;amp; 0.7, 22 ms &amp;amp; 0.5); output (0.5 gain); delay (5 ms); allpass (30 ms &amp;amp; 0.5); delay (67 ms); output (0.5 gain); delay (15 ms); gain; input; nested allpass (outer: 39 ms &amp;amp; 0.3, inner: 9.8 ms &amp;amp; 0.6); output (0.5 gain); delay (108 ms)&quot; /&gt;&lt;/p&gt;
&lt;figcaption&gt;
&lt;p&gt;Medium room reverberator &lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://reillyspitzfaden.com/posts/2025/09/reverb-part-2/#fn3&quot; id=&quot;fnref3:4&quot;&gt;[3:4]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;https://reillyspitzfaden.com/media/blog/2025/09/reverb_2/large-room.webp&quot; alt=&quot;A DSP block diagram. There is a chain of delays and nested allpasses with two outputs taken between the delays, and a 2.6 kHz low pass filter in the feedback loop for the whole chain. Delay list: allpass (8 ms &amp;amp; 0.3); allpass (12 ms &amp;amp; 0.3); delay (4 ms); output (0.34 gain); delay (17 ms); nested allpass (outer: 87 ms &amp;amp; 0.5, inner: 62 ms &amp;amp; 0.25); delay (31 ms); output (0.14 gain); delay (3 ms) double nested allpass (outer: 120 ms &amp;amp; 0.5, inner: 76 ms &amp;amp; 0.25, 30 ms &amp;amp; 0.25); output (0.14 gain)&quot; /&gt;&lt;/p&gt;
&lt;figcaption&gt;
&lt;p&gt;Large room reverberator &lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://reillyspitzfaden.com/posts/2025/09/reverb-part-2/#fn3&quot; id=&quot;fnref3:5&quot;&gt;[3:5]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Note that these designs have a mix of delays, allpasses, nested allpasses, and double nested allpasses. The medium reverberator also has two inputs, and applies the gain both in the feedback loop and in the middle of the allpass chain, directly before the second input.&lt;/p&gt;
&lt;h2 id=&quot;reverb-characteristics&quot;&gt;Reverb Characteristics&lt;/h2&gt;
&lt;p&gt;Gardner describes these as “room” reverbs. While they are synthesized, not real rooms, it&#39;s still useful to look at the characteristics of the types of reverbs Gardner is emulating. First off, &lt;a href=&quot;https://valhalladsp.com/2018/05/14/effect-o-pedia-reverb-types/&quot;&gt;Sean Costello of Valhalla DSP describes&lt;/a&gt; room reverbs as having prominent early reflections.&lt;/p&gt;
&lt;p&gt;Early reflections refer to sounds within the first 80 ms or so, followed by late reflections. Summarizing psychoacoustic research on the matter, Rungta et al. note that early reflections positively correlate with “the perception of auditory spaciousness,” are “very important in concert halls,” and can “improve speech clarity in rooms.” &lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://reillyspitzfaden.com/posts/2025/09/reverb-part-2/#fn5&quot; id=&quot;fnref5&quot;&gt;[5]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Rungta et al. also note that these early reflections help the listener hear the shape of the room. My best guess for why is because these reflections have traveled a short distance to the listener, maybe only reflecting a single time. This implies for “room”-type reverbs that we get a particularly strong sense of the room&#39;s dimensions. In my next post, I&#39;ll describe Dattorro&#39;s 1997 “plate”-style allpass ring, and we&#39;ll hear how that reverb sounds more amorphous, with less sense of space.&lt;/p&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;https://reillyspitzfaden.com/media/blog/2025/09/reverb_2/early-late-reflections.webp&quot; alt=&quot;A list of vertical lines representing echoes that decay as we move toward the right. There is a gap between direct sound and early reflections, early reflections are sparse, and reverberation at the end is dense.&quot; /&gt;&lt;/p&gt;
&lt;figcaption&gt;
&lt;p&gt;Direct sound, early reflections, and late reflections/reverberation; horizontal axis is time and vertical is amplitude &lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://reillyspitzfaden.com/posts/2025/09/reverb-part-2/#fn5&quot; id=&quot;fnref5:1&quot;&gt;[5:1]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;In addition to these early reflections, Costello describes a dense sound and a short decay — these are usually smaller rooms than the &lt;a href=&quot;https://en.wikipedia.org/wiki/Reverberation_room&quot;&gt;reverb chambers&lt;/a&gt; in recording studios. Rooms also quickly build up echo density (here accomplished with the nested allpasses) and tend to be “colored,” i.e., they emphasize some frequencies over others. You may want to use an EQ on your reverb send track to reduce low frequencies on these algorithms, depending on your application. Costello suggests these may be useful for adding body to drums and acoustic instruments.&lt;/p&gt;
&lt;h2 id=&quot;postscript&quot;&gt;Postscript&lt;/h2&gt;
&lt;p&gt;These algorithms are all available in &lt;a href=&quot;https://github.com/reillypascal/RSAlgorithmicVerb/releases&quot;&gt;my algorithmic reverb plugin&lt;/a&gt; via the dropdown menu at the bottom. I also have Max/MSP abstractions of them &lt;a href=&quot;https://codeberg.org/reillypascal/rs.reverb&quot;&gt;available on my Codeberg&lt;/a&gt;. I would love to hear if you try them out!&lt;/p&gt;
&lt;p&gt;As I mentioned, in my next post I&#39;ll cover the famous 1997 Dattorro plate algorithm that also uses an allpass ring structure. This is in Max/MSP as the [yafr2] abstraction, and in the &lt;a href=&quot;https://library.vcvrack.com/Valley/Plateau&quot;&gt;Valley Audio “Plateau” module&lt;/a&gt; for VCV Rack, among numerous other places, and is likely based on an algorithm from the Lexicon 224/480 reverb units. I hope to see you then!&lt;/p&gt;
&lt;hr class=&quot;footnotes-sep&quot; /&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;M. R. Schroeder, “Natural sounding artificial reverberation,” in Audio Engineering Society Convention 13, Audio Engineering Society, 1961. Accessed: Dec. 29, 2024. [Online]. Available: &lt;a href=&quot;https://www.aes.org/e-lib/download.cfm?ID=343&quot;&gt;https://www.aes.org/e-lib/download.cfm?ID=343&lt;/a&gt; &lt;a href=&quot;https://reillyspitzfaden.com/posts/2025/09/reverb-part-2/#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt; &lt;a href=&quot;https://reillyspitzfaden.com/posts/2025/09/reverb-part-2/#fnref1:1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Unfortunately this paper is unpublished, and I was only able to find William Gardner&#39;s description of it, &lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://reillyspitzfaden.com/posts/2025/09/reverb-part-2/#fn1&quot; id=&quot;fnref1:1&quot;&gt;[1:1]&lt;/a&gt;&lt;/sup&gt; but here is the citation:&lt;/p&gt;
&lt;p&gt;B. Vercoe and M. Puckette, “Synthetic Spaces — Artificial Acoustic Ambiance from Active Boundary Computation,” 1985, &lt;em&gt;Music and Cognition Office at MIT Media Lab, Boston, MA&lt;/em&gt;. &lt;a href=&quot;https://reillyspitzfaden.com/posts/2025/09/reverb-part-2/#fnref2&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn3&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;W. G. Gardner, “A realtime multichannel room simulator,” &lt;em&gt;J. Acoust. Soc. Am&lt;/em&gt;, vol. 92, no. 4, p. 2395, 1992. Available: &lt;a href=&quot;https://pubs.aip.org/asa/jasa/article/92/4_Supplement/2395/646024/A-real-time-multichannel-room-simulator&quot;&gt;https://pubs.aip.org/asa/jasa/article/92/4_Supplement/2395/646024/A-real-time-multichannel-room-simulator&lt;/a&gt; &lt;a href=&quot;https://reillyspitzfaden.com/posts/2025/09/reverb-part-2/#fnref3&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt; &lt;a href=&quot;https://reillyspitzfaden.com/posts/2025/09/reverb-part-2/#fnref3:1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt; &lt;a href=&quot;https://reillyspitzfaden.com/posts/2025/09/reverb-part-2/#fnref3:2&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt; &lt;a href=&quot;https://reillyspitzfaden.com/posts/2025/09/reverb-part-2/#fnref3:3&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt; &lt;a href=&quot;https://reillyspitzfaden.com/posts/2025/09/reverb-part-2/#fnref3:4&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt; &lt;a href=&quot;https://reillyspitzfaden.com/posts/2025/09/reverb-part-2/#fnref3:5&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn4&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;H. Mikelson, “A Csound Multi-Effects Processor.” Accessed: Sept. 26, 2025. [Online]. Available: &lt;a href=&quot;https://www.eumus.edu.uy/eme/ensenanza/electivas/csound/materiales/book_chapters/24mikelson/24mikelson.html&quot;&gt;https://www.eumus.edu.uy/eme/ensenanza/electivas/csound/materiales/book_chapters/24mikelson/24mikelson.html&lt;/a&gt; &lt;a href=&quot;https://reillyspitzfaden.com/posts/2025/09/reverb-part-2/#fnref4&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt; &lt;a href=&quot;https://reillyspitzfaden.com/posts/2025/09/reverb-part-2/#fnref4:1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn5&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;A. Rungta, N. Rewkowski, R. Klatzky, and D. Manocha, “P-Reverb: Perceptual Characterization of Early and Late Reflections for Auditory Displays,” in 2019 IEEE Conference on Virtual Reality and 3D User Interfaces (VR), Mar. 2019, pp. 455–463. doi: 10.1109/VR.2019.8797914. Available: &lt;a href=&quot;https://arxiv.org/pdf/1902.06880&quot;&gt;https://arxiv.org/pdf/1902.06880&lt;/a&gt; &lt;a href=&quot;https://reillyspitzfaden.com/posts/2025/09/reverb-part-2/#fnref5&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt; &lt;a href=&quot;https://reillyspitzfaden.com/posts/2025/09/reverb-part-2/#fnref5:1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;p&gt;&lt;a href=&quot;mailto:reillypascal@gmail.com?subject=Re:%20&#39;Reverb%20Part%202%E2%80%94Natural%20Rooms%20with%20Allpass%20Rings&#39;&quot;&gt;Reply via email&lt;/a&gt; :: &lt;a href=&quot;https://reillyspitzfaden.com/feeds/&quot;&gt;Subscribe to my other feeds&lt;/a&gt; :: &lt;a href=&quot;https://ko-fi.com/reillyspitzfaden&quot;&gt;Buy me a coffee&lt;/a&gt;&lt;/p&gt;
            </content:encoded>
          </item>
        <item>
            <title>A Certain Sickness</title>
            <author>reillypascal@gmail.com (Reilly Spitzfaden)</author>
            <link>https://reillyspitzfaden.com/posts/2025/09/september-indieweb-carnival/</link>
            <guid>https://reillyspitzfaden.com/posts/2025/09/september-indieweb-carnival/</guid>
            <pubDate>Thu, 25 Sep 2025 12:38:00 GMT</pubDate>
            <description>&lt;i&gt;You feel that a certain sickness has been pervading your life. It&#39;s a dull ache that suffuses subtly through many unrelated things, a background radiation to your everyday…&lt;/i&gt;</description>
            <content:encoded>
            
            

          
          
          &lt;p&gt;You feel that a certain sickness has been pervading your life. It&#39;s a dull ache that suffuses subtly through many unrelated things, a background radiation to your everyday. You have tried removing possible sources, one by one, but in the wake of each, there is less to distract you, and the sickness only changes its form.&lt;/p&gt;
&lt;p&gt;One day, you are walking back from your lunch and you cast your eyes on the ground. Even amid the concrete, asphalt, and stones stretching on forever, there is life. Shoots of green dart out from cracks. In a few patches the architects have left open, small trees. Further down your walk, someone has kept a small patch of woodchips and soil, holding a collection of flowers and bushes. Even the loose clippings and leaves on the concrete have a depth to them.&lt;/p&gt;
&lt;p&gt;You feel the acceleration of the earth below you, its wide surface supporting you, its pull keeping you from falling into space forever. You note that you haven&#39;t thought of the sickness in several minutes.&lt;/p&gt;
&lt;div class=&quot;centered&quot;&gt;*&amp;nbsp;*&amp;nbsp;*&lt;/div&gt;
&lt;p&gt;Late that evening, as you take out the recycling, you hear birds. Their calls trace out the space around you — the city filtering and reverberating the calls more or less, and in different ways, depending on distance and location. You hear them (for once) without the filter of your thoughts overlaid. Their calls do not mean anything in particular, at least to you, and for that, you are grateful.&lt;/p&gt;
&lt;p&gt;As your eyes pass over a patch of ground you see every day on returning home, you feel less real for a moment, but the patch is realer than it&#39;s been before. There are many others almost (but not quite) like it, and although your view is obstructed, you can sense them faintly beyond it.&lt;/p&gt;
&lt;p&gt;On hearing the crickets in the distance, you decide to linger a moment longer. One sound is a continuous wave of trilling, many voices blending into one. In front of that (you can feel the depth of sound now), individual scratches are much clearer, less blurred by the air between you.&lt;/p&gt;
&lt;p&gt;You recall that air functions roughly as a low-pass filter. You are at the bottom of a great ocean. It&#39;s really not that different from an ocean made of water, is it?&lt;/p&gt;
&lt;p&gt;The waters pulsate around you. It feels peaceful though.&lt;/p&gt;
&lt;p&gt;You continue back indoors.&lt;/p&gt;
&lt;h2 id=&quot;postscript&quot;&gt;Postscript&lt;/h2&gt;
&lt;p&gt;This was written for the September 2025 &lt;a href=&quot;https://indieweb.org/IndieWeb_Carnival&quot;&gt;IndieWeb blog carnival&lt;/a&gt;. &lt;a href=&quot;https://toground.link/second-person-birds/&quot;&gt;Sophia is hosting this month&lt;/a&gt;, and the theme is “second-person birds.” On her blog &lt;a href=&quot;https://toground.link/&quot;&gt;to ground&lt;/a&gt;, she writes about nature in the second person.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;mailto:reillypascal@gmail.com?subject=Re:%20&#39;A%20Certain%20Sickness&#39;&quot;&gt;Reply via email&lt;/a&gt; :: &lt;a href=&quot;https://reillyspitzfaden.com/feeds/&quot;&gt;Subscribe to my other feeds&lt;/a&gt; :: &lt;a href=&quot;https://ko-fi.com/reillyspitzfaden&quot;&gt;Buy me a coffee&lt;/a&gt;&lt;/p&gt;
            </content:encoded>
          </item>
        <item>
            <title>TTRPGs at the Library</title>
            <author>reillypascal@gmail.com (Reilly Spitzfaden)</author>
            <link>https://reillyspitzfaden.com/notes/2025/08/ttrpgs-at-the-library/</link>
            <guid>https://reillyspitzfaden.com/notes/2025/08/ttrpgs-at-the-library/</guid>
            <pubDate>Sun, 31 Aug 2025 00:00:00 GMT</pubDate>
            <description>I&#39;m finally getting into TTRPGs!</description>
            <content:encoded>
            
            

          
          
          &lt;p&gt;My local library has a TTRPG group (currently playing Pathfinder 2e). I sat in on a campaign today, the group was very welcoming, and I&#39;m excited about it. I&#39;ve wanted to get into D&amp;amp;D/TTRPGs for a while, but didn&#39;t have a group to do it with. While I hear Pathfinder is a bit more involved than some, I was able to get a copy of the rulebook to take home, and I&#39;m invited to give it a go with making my own character and joining the party next weekend. It&#39;s especially nice because the library is right at the end of my street!&lt;/p&gt;
&lt;p&gt;I enjoyed how it felt like manually stepping through a computer simulation — the whole time I was thinking of &lt;a href=&quot;https://www.youtube.com/watch?v=LnzuMJLZRdU&amp;amp;list=PLowKtXNTBypFbtuVMUVXNR0z1mu7dp7eH&amp;amp;index=2&amp;amp;t=1300s&quot;&gt;Ben Eater&#39;s videos about building a 6502 computer on a breadboard&lt;/a&gt;, in which he uses a pushbutton for a clock pulse at some points to manually step through things.&lt;/p&gt;
&lt;p&gt;Lately I&#39;ve been looking for 1) &lt;a href=&quot;https://reillyspitzfaden.com/notes/2025/08/re-turning-towards-the-positive/&quot;&gt;more things to do off the internet&lt;/a&gt; and 2) ways to make friends in my area. I made a lot of good friends in grad school, but now most of them have moved; the scarcity of academic jobs means a lot of moving around T-T. I&#39;ve never been great at putting myself out there, so most of my friendships have developed from being in proximity to a lot of people, which doesn&#39;t work the same way out of school. This group seems lovely though, and I&#39;m glad I pushed myself to give it a try.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;mailto:reillypascal@gmail.com?subject=Re:%20&#39;TTRPGs%20at%20the%20Library&#39;&quot;&gt;Reply via email&lt;/a&gt; :: &lt;a href=&quot;https://reillyspitzfaden.com/feeds/&quot;&gt;Subscribe to my other feeds&lt;/a&gt; :: &lt;a href=&quot;https://ko-fi.com/reillyspitzfaden&quot;&gt;Buy me a coffee&lt;/a&gt;&lt;/p&gt;
            </content:encoded>
          </item>
        <item>
            <title>Re: Turning towards the positive</title>
            <author>reillypascal@gmail.com (Reilly Spitzfaden)</author>
            <link>https://reillyspitzfaden.com/notes/2025/08/re-turning-towards-the-positive/</link>
            <guid>https://reillyspitzfaden.com/notes/2025/08/re-turning-towards-the-positive/</guid>
            <pubDate>Wed, 27 Aug 2025 18:00:00 GMT</pubDate>
            <description></description>
            <content:encoded>
            
            

          
          
          &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://reillyspitzfaden.com/styles/notes-photos.css&quot; /&gt;
&lt;p&gt;&lt;a href=&quot;https://tracydurnell.com/2025/08/27/turning-towards-the-positive/&quot;&gt;Tracy Durnell&#39;s recent post&lt;/a&gt; resonates with what I&#39;ve been doing lately to make my computer usage more pleasant.&lt;/p&gt;
&lt;p&gt;I&#39;ve been in the habit of compulsively checking notifications (Mastodon, RSS, YouTube subscriptions, etc.), and I figured out that staying away from that, and using my computer for local things is much nicer. A few specific local things I&#39;ve been enjoying:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;I&#39;ve wanted to learn the live-coding tool &lt;a href=&quot;https://tidalcycles.org/&quot;&gt;Tidal Cycles&lt;/a&gt; for a while now, and I&#39;m finally doing that. &lt;a href=&quot;https://www.youtube.com/watch?v=Db0QJo1eaoI&quot;&gt;Here&#39;s a Tidal Cycles performance by Lil Data&lt;/a&gt;, and &lt;a href=&quot;https://www.youtube.com/watch?v=Tjf-NJNfOP4&quot;&gt;here&#39;s one by Moxus&lt;/a&gt; (super glitchy and noisy!). This tool is nice because I can code &lt;em&gt;and&lt;/em&gt; have my coding be immediately musical.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I&#39;ve started knitting, and my goal is that once I&#39;m comfortable with some basic stitches, I can use code to generate patterns. I was inspired to do this by &lt;a href=&quot;https://www.fractalkitty.com/w/&quot;&gt;Sophia&#39;s project using p5.js to generate knit beanie patterns&lt;/a&gt;. This is a nice way to feel connected to my programming/computer interests without actually needing to be online or even use a computer for the full project.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;mailto:reillypascal@gmail.com?subject=Re:%20&#39;Re:%20Turning%20towards%20the%20positive&#39;&quot;&gt;Reply via email&lt;/a&gt; :: &lt;a href=&quot;https://reillyspitzfaden.com/feeds/&quot;&gt;Subscribe to my other feeds&lt;/a&gt; :: &lt;a href=&quot;https://ko-fi.com/reillyspitzfaden&quot;&gt;Buy me a coffee&lt;/a&gt;&lt;/p&gt;
            </content:encoded>
          </item>
        <item>
            <title>ルビとHTML</title>
            <author>reillypascal@gmail.com (Reilly Spitzfaden)</author>
            <link>https://reillyspitzfaden.com/posts/2025/08/ruby-html/</link>
            <guid>https://reillyspitzfaden.com/posts/2025/08/ruby-html/</guid>
            <pubDate>Tue, 19 Aug 2025 21:14:00 GMT</pubDate>
            <description>I took a few years of Japanese classes in undergrad, and today I&#39;m returning to that and discussing some HTML markup for Japanese and other East Asian languages.</description>
            <content:encoded>
            
            

          
          
          &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://reillyspitzfaden.com/styles/code/prism-perf-custom.css&quot; /&gt;
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://reillyspitzfaden.com/styles/code/code-tweaks.css&quot; /&gt;
&lt;p&gt;&lt;ruby&gt;最近&lt;rp&gt;(&lt;/rp&gt;&lt;rt&gt;さいきん&lt;/rt&gt;&lt;rp&gt;)&lt;/rp&gt;&lt;/ruby&gt;HTMLでルビを&lt;ruby&gt;振&lt;rp&gt;(&lt;/rp&gt;&lt;rt&gt;ふ&lt;/rt&gt;&lt;rp&gt;)&lt;/rp&gt;&lt;/ruby&gt;ることのやり&lt;ruby&gt;方&lt;rp&gt;(&lt;/rp&gt;&lt;rt&gt;かた&lt;/rt&gt;&lt;rp&gt;)&lt;/rp&gt;&lt;/ruby&gt;を&lt;ruby&gt;知&lt;rp&gt;(&lt;/rp&gt;&lt;rt&gt;し&lt;/rt&gt;&lt;rp&gt;)&lt;/rp&gt;&lt;/ruby&gt;た!&lt;/p&gt;
&lt;p&gt;Or in English, “I recently learned how to write &lt;a href=&quot;https://en.wikipedia.org/wiki/Ruby_character&quot;&gt;ruby characters&lt;/a&gt; in HTML!”&lt;/p&gt;
&lt;p&gt;Japanese writing uses multiple different sets of characters. Chinese &lt;a href=&quot;https://en.wikipedia.org/wiki/Ideogram&quot;&gt;ideographic&lt;/a&gt; characters (called “&lt;a href=&quot;https://en.wikipedia.org/wiki/Kanji&quot;&gt;kanji&lt;/a&gt;”) encode an idea rather than a sound and can have multiple pronunciations. &lt;a href=&quot;https://en.wikipedia.org/wiki/Kana&quot;&gt;Kana&lt;/a&gt; are phonetic characters that each represent one syllable.&lt;/p&gt;
&lt;p&gt;Ruby characters are kana placed above kanji to indicate the pronunciation — these are common in educational materials, children&#39;s/YA books, or for kanji outside the list of &lt;a href=&quot;https://en.wikipedia.org/wiki/J%C5%8Dy%C5%8D_kanji&quot;&gt;jōyō (“regular-use”) kanji&lt;/a&gt;, among other uses. Because there are many more kanji than kana, and their pronunciation can be complicated to learn, the ruby characters make reading easier.&lt;/p&gt;
&lt;p&gt;I took some Japanese classes in undergrad, and while I haven&#39;t kept up with it, I recently stumbled across the &lt;a href=&quot;https://html.spec.whatwg.org/multipage/text-level-semantics.html#the-ruby-element&quot;&gt;HTML markup&lt;/a&gt; for ruby and thought it was a cool thing to know. The markup for the first word from the above example, “saikin” (“recently”) is shown below. The whole thing is enclosed in &lt;code&gt;&amp;lt;ruby&amp;gt;&lt;/code&gt; tags; the &lt;code&gt;&amp;lt;rp&amp;gt;&lt;/code&gt; tag surrounds parentheses for the pronunciation; and &lt;code&gt;&amp;lt;rt&amp;gt;&lt;/code&gt; surrounds the phonetic gloss. This gives a fallback of placing the pronunciation in parentheses after the kanji — i.e., as 最近 (さいきん) — if a browser doesn&#39;t support rendering ruby characters, while allowing the parentheses to be hidden and the phonetic gloss placed above on browsers that do support this.&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ruby&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;最近&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;rp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;(&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;rp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;rt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;さいきん&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;rt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;rp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;)&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;rp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;ruby&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This all has gotten me a bit nostalgic for learning Japanese, and I think I&#39;ll try tracking down my old textbooks. Because I love typography and web standards in general, it would also give me more typographic practices to try out on my blog — depending on how returning to Japanese goes, it would be cool to try writing some posts in Japanese.&lt;/p&gt;
&lt;p&gt;This also might give me the chance to get internet feedback on my Japanese. One of the reasons I never stuck with it is that even when I was decent at it, I had a lot of anxiety seeking out conversation partners with whom to practice. Writing online doesn&#39;t feel as intense though, so that could be a good way to get feedback. We&#39;ll see how it goes!&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;mailto:reillypascal@gmail.com?subject=Re:%20&#39;%E3%83%AB%E3%83%93%E3%81%A8HTML&#39;&quot;&gt;Reply via email&lt;/a&gt; :: &lt;a href=&quot;https://reillyspitzfaden.com/feeds/&quot;&gt;Subscribe to my other feeds&lt;/a&gt; :: &lt;a href=&quot;https://ko-fi.com/reillyspitzfaden&quot;&gt;Buy me a coffee&lt;/a&gt;&lt;/p&gt;
            </content:encoded>
          </item>
        <item>
            <title>Location Test</title>
            <author>reillypascal@gmail.com (Reilly Spitzfaden)</author>
            <link>https://reillyspitzfaden.com/notes/2025/08/location-test/</link>
            <guid>https://reillyspitzfaden.com/notes/2025/08/location-test/</guid>
            <pubDate>Tue, 19 Aug 2025 18:45:00 GMT</pubDate>
            <description></description>
            <content:encoded>
            
            

          
          
          &lt;p&gt;Jo has been using &lt;a href=&quot;https://github.com/reillypascal/personalsite-ssg/blob/fcec4c251b343b0e53f9f8d0dd2689f27c9cbf9c/status#L5&quot;&gt;the code I use to get post locations&lt;/a&gt; for &lt;a href=&quot;https://reillyspitzfaden.com/now&quot;&gt;my /now page statuslog section&lt;/a&gt; to &lt;a href=&quot;https://dead.garden/notes/&quot;&gt;add locations to her notes&lt;/a&gt;. I realized it would be nice to add it to &lt;a href=&quot;https://github.com/reillypascal/personalsite-ssg/blob/main/note&quot;&gt;the script I use to generate note templates&lt;/a&gt; as well!&lt;/p&gt;
&lt;p&gt;While most of my blog posts are written from home and not associated with a place, I have a &lt;a href=&quot;https://reillyspitzfaden.com/notes/2025/07/photoblog-natural-stone-bridge-caves/&quot;&gt;number&lt;/a&gt; of &lt;a href=&quot;https://reillyspitzfaden.com/notes/2025/07/powder-mills-usgs-gaging-station/&quot;&gt;notes&lt;/a&gt; from trips with my partner that aren&#39;t just in Rochester.&lt;/p&gt;
&lt;p&gt;I like the “vibe” of connecting things on my site to a physical place, so this should be nice to add.&lt;/p&gt;
&lt;aside&gt;
&lt;p&gt;For fellow Eleventy users who are interested in more setup information: I don&#39;t want to go back and add dates to every note, and since I use the same partial for notes/blog posts/etc. metadata, I have the Eleventy templates for the &lt;a href=&quot;https://github.com/reillypascal/personalsite-ssg/blob/3fe553d4a95abc48b8698ced35e4426510c84c3f/pages/_includes/partials/post-meta.liquid#L21&quot;&gt;post metadata&lt;/a&gt; and the &lt;a href=&quot;https://github.com/reillypascal/personalsite-ssg/blob/3fe553d4a95abc48b8698ced35e4426510c84c3f/pages/notes.liquid#L40&quot;&gt;notes page&lt;/a&gt; set up so the location section is only included if there&#39;s a “location” tag in the header and that tag has a value.&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;&lt;a href=&quot;mailto:reillypascal@gmail.com?subject=Re:%20&#39;Location%20Test&#39;&quot;&gt;Reply via email&lt;/a&gt; :: &lt;a href=&quot;https://reillyspitzfaden.com/feeds/&quot;&gt;Subscribe to my other feeds&lt;/a&gt; :: &lt;a href=&quot;https://ko-fi.com/reillyspitzfaden&quot;&gt;Buy me a coffee&lt;/a&gt;&lt;/p&gt;
            </content:encoded>
          </item>
        <item>
            <title>We&#39;re Getting Married!</title>
            <author>reillypascal@gmail.com (Reilly Spitzfaden)</author>
            <link>https://reillyspitzfaden.com/posts/2025/08/were-getting-married/</link>
            <guid>https://reillyspitzfaden.com/posts/2025/08/were-getting-married/</guid>
            <pubDate>Sat, 16 Aug 2025 23:18:00 GMT</pubDate>
            <description>Eli and I are engaged, and we&#39;re getting married later this year!</description>
            <content:encoded>
            
            

          
          
          &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://reillyspitzfaden.com/styles/notes-photos.css&quot; /&gt;
&lt;p&gt;Eli and I are engaged, and we&#39;re getting married later this year! I&#39;m really excited to spend the rest of my life with them. We didn&#39;t feel like doing an engagement photoshoot, but here are some nice photos from some of the hikes and other outdoor trips we like to do together.&lt;/p&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;https://reillyspitzfaden.com/media/blog/2025/07/eli-bday/IMG_2509.webp&quot; alt=&quot;My partner and me, with a walkway handrail and a marble cave entrance visible in the background&quot; class=&quot;img-vertical&quot; /&gt;&lt;/p&gt;
&lt;figcaption&gt;In front of a marble cave at the Natural Stone Bridge &amp; Caves park in the Adirondacks&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;https://reillyspitzfaden.com/media/blog/2025/08/IMG_3820.webp&quot; alt=&quot;Me and my partner smiling at the camera, with stromatolite fossils visible below us on the ground.&quot; class=&quot;img-vertical&quot; /&gt;&lt;/p&gt;
&lt;figcaption&gt;This is at Lester Park in Saratoga Springs, NY and the ground below us is a 490 million year-old lake bed covered in &lt;a href=&quot;https://en.wikipedia.org/wiki/Stromatolite&quot;&gt;stromatolite&lt;/a&gt; fossils!&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;https://reillyspitzfaden.com/media/blog/2025/08/IMG_3804.webp&quot; alt=&quot;My partner gesturing down at some stromatolite fossils and looking very excited.&quot; class=&quot;img-vertical&quot; /&gt;&lt;/p&gt;
&lt;figcaption&gt;More of the stromatolite fossils. It makes me happy looking at this photo and seeing Eli so excited.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&quot;mailto:reillypascal@gmail.com?subject=Re:%20&#39;We&amp;#39;re%20Getting%20Married!&#39;&quot;&gt;Reply via email&lt;/a&gt; :: &lt;a href=&quot;https://reillyspitzfaden.com/feeds/&quot;&gt;Subscribe to my other feeds&lt;/a&gt; :: &lt;a href=&quot;https://ko-fi.com/reillyspitzfaden&quot;&gt;Buy me a coffee&lt;/a&gt;&lt;/p&gt;
            </content:encoded>
          </item>
        <item>
            <title>IndieWeb Carnival: Tone Colors</title>
            <author>reillypascal@gmail.com (Reilly Spitzfaden)</author>
            <link>https://reillyspitzfaden.com/posts/2025/08/indieweb-carnival-tone-colors/</link>
            <guid>https://reillyspitzfaden.com/posts/2025/08/indieweb-carnival-tone-colors/</guid>
            <pubDate>Mon, 11 Aug 2025 22:05:00 GMT</pubDate>
            <description>For this month&#39;s IndieWeb Carnival, I&#39;m writing about music that emphasizes timbre or “tone-color,” and how I use this kind of approach in my own composition.</description>
            <content:encoded>
            
            

          
          
          &lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=8AQx0V2lZs8&amp;amp;t=496s&quot;&gt;Movement III, “Farben” (“Colors”)&lt;/a&gt; from Arnold Schoenberg&#39;s &lt;em&gt;Five Pieces for Orchestra, Op. 16&lt;/em&gt; begins very subtly. Two different groups in the orchestra alternate on the same hushed, eerie chord. As this slow, regular pulsation continues, some notes in the chord move up or down very slightly while others remain the same, gradually transforming the harmony.&lt;/p&gt;
&lt;p&gt;Throughout the movement, there is almost no melody in the traditional sense. Rather, by keeping the pitch material nearly static while alternating different instruments (or combinations of instruments), Schoenberg foregrounds the &lt;a href=&quot;https://en.wikipedia.org/wiki/Timbre&quot;&gt;timbre&lt;/a&gt; or “tone-colors” of the orchestra — the aspects of sound by which we can tell, for example, a trumpet from a violin.&lt;/p&gt;
&lt;p&gt;He describes what he is doing as &lt;a href=&quot;https://en.wikipedia.org/wiki/Klangfarbenmelodie&quot;&gt;&lt;em&gt;klangfarbenmelodie&lt;/em&gt;&lt;/a&gt; or “tone-color melody.” By composing this way, he seeks to have the listener perceive this changing of “tone-colors” with “a kind of logic entirely equivalent to that logic which satisfies us in the melody of pitches.” &lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://reillyspitzfaden.com/posts/2025/08/indieweb-carnival-tone-colors/#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt; In other words, just as a more traditional melody might have a distinctive sequence of pitches (often associated with a similarly distinctive rhythm), we can apply the same type of listening to a sequence of &lt;em&gt;timbres&lt;/em&gt;, as well as writing music that encourages this type of listening.&lt;/p&gt;
&lt;h2 id=&quot;color-in-my-earlier-music&quot;&gt;Color in My Earlier Music&lt;/h2&gt;
&lt;p&gt;In my first year of college, I stumbled across a score page for Anton Webern&#39;s &lt;a href=&quot;https://www.youtube.com/watch?v=pVQambrIKNo&quot;&gt;&lt;em&gt;Concerto for Nine Instruments, Op. 24&lt;/em&gt;&lt;/a&gt; discarded in a practice room — likely homework from some classmate&#39;s &lt;a href=&quot;https://en.wikipedia.org/wiki/20th-century_classical_music&quot;&gt;20th-century music theory&lt;/a&gt; class. Webern was one of Schoenberg&#39;s students and someone who also made use of &lt;em&gt;klangfarbenmelodie&lt;/em&gt;, and this piece was my entry point to that idea, among many other musical concepts. My &lt;em&gt;Nonet&lt;/em&gt; from 2014, and &lt;a href=&quot;https://soundcloud.com/reilly-spitzfaden/nonet-iii?in=reilly-spitzfaden/sets/nonet-premiere&quot;&gt;movement III in particular&lt;/a&gt; is a good example of my use of this technique.&lt;/p&gt;
&lt;p&gt;Where Schoenberg&#39;s prototype of &lt;em&gt;klangfarbenmelodie&lt;/em&gt; in his “Farben” movement uses slowly morphing chords, the opening of movement III of my &lt;em&gt;Nonet&lt;/em&gt; is highly pointillistic — more like how Webern tended to write. In the first two measures, the horn, bass clarinet, and cello each play a short &lt;a href=&quot;https://en.wikipedia.org/wiki/Motif_(music)&quot;&gt;motive&lt;/a&gt;, transposing and manipulating it each time, with each instrument just barely overlapping with the end of the previous one. This rapid passing of short ideas between instruments sets the tone for the rest of the composition.&lt;/p&gt;
&lt;p&gt;We can listen to this pointillistic call-and-response in a similar way to how we did in the Schoenberg example. While the musical material is much more active in my piece, the shifts in tone color also occur in quicker succession, and are often accompanied by large &lt;a href=&quot;https://en.wikipedia.org/wiki/Register_(music)&quot;&gt;register&lt;/a&gt; jumps. In addition, almost all of the material derives from that 5-note motive from the first measure. While the melody is quite dissonant, angular, and chromatic, deriving most things from this one short motive gives a consistent overall character or “vibe” to the piece.&lt;/p&gt;
&lt;p&gt;The combination of a consistent character to the melody with large contrasts in timbre and register encourages the listener to focus on the overall quality and color of the sound, rather than trying to follow the specifics of the melody. When I listen like this, the rapid &lt;em&gt;klangfarbenmelodie&lt;/em&gt; shifts in tone color become particularly clear.&lt;/p&gt;
&lt;p&gt;This pointillistic approach of rapidly passing ideas between instruments appeared regularly in many other compositions of mine around this time, and as I wrote this way, I took particular interest in the shifting timbres that resulted.&lt;/p&gt;
&lt;h2 id=&quot;color-in-my-recent-composition&quot;&gt;Color in My Recent Composition&lt;/h2&gt;
&lt;p&gt;Some 13 years after my &lt;em&gt;Nonet&lt;/em&gt;, it&#39;s interesting to look back on what has changed and what has stayed the same in how I use color in my music. I composed &lt;a href=&quot;https://applytriangle.bandcamp.com/track/if-this-reaches-you&quot;&gt;&lt;em&gt;If this reaches you&lt;/em&gt;&lt;/a&gt; in 2021, and &lt;a href=&quot;https://reillyspitzfaden.com/posts/2024/04/new-album-announcement/&quot;&gt;it was recorded in 2024&lt;/a&gt;. The details of my approach are very different, but the emphasis on sound and timbre, and the pointillistic, thin textures are still there. This piece is for MIDI keyboard (controlling a custom software setup in &lt;a href=&quot;https://en.wikipedia.org/wiki/Max_(software)&quot;&gt;Max/MSP&lt;/a&gt;), flute, and clarinet. The flutist briefly uses a bass bow on a cardboard box in the middle, as well. The MIDI keyboard plays a combination of electric piano and sampled amateur radio sounds — &lt;a href=&quot;https://reillyspitzfaden.com/posts/2024/12/radio-listening-musically/&quot;&gt;I wrote about using radio transmissions in my compositions in another post&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Where the things that made the &lt;em&gt;Nonet&lt;/em&gt; sound unusual were the choice of pitches and rhythms, in &lt;em&gt;If this reaches you&lt;/em&gt;, the focus is a bit more on &lt;em&gt;sound&lt;/em&gt; than pitch. In addition to the “non-musical” radio samples, I also use a number of so-called “extended techniques,” particularly in the clarinet. &lt;a href=&quot;http://www.heatherroche.net/&quot;&gt;Clarinetist Heather Roche&#39;s blog&lt;/a&gt; is a great source of information on how these work, and I use &lt;a href=&quot;https://heatherroche.net/2018/09/13/27-easy-bb-clarinet-multiphonics/&quot;&gt;various&lt;/a&gt; different &lt;a href=&quot;https://heatherroche.net/2019/11/05/underblown-bb-clarinet-multiphonics/&quot;&gt;multiphonics&lt;/a&gt;, &lt;a href=&quot;https://heatherroche.net/2014/05/11/on-double-trills-for-bb-clarinet/&quot;&gt;double trills&lt;/a&gt;, and other unusual sounds. At the same time, the way I combine these sounds is still quite pointillistic, and emphasizes rapid shifts between the different kinds of noise.&lt;/p&gt;
&lt;p&gt;When I do use clearly pitched material, my more recent compositions tend to be a bit more “tonal” than the &lt;em&gt;Nonet&lt;/em&gt; — less chromatic, and leaning more toward “cheesy” 80s pop, lounge music, or electronic dance music sounds. For example, the piano chords — both notes and instrument sound — in &lt;a href=&quot;https://applytriangle.bandcamp.com/track/if-this-reaches-you&quot;&gt;&lt;em&gt;If this reaches you&lt;/em&gt;&lt;/a&gt; starting at around 0:58 sound like lounge/elevator music mixed in amid the noisy samples and flute/clarinet sounds. The synth chords and scooping accents in the sax melody in &lt;a href=&quot;https://www.youtube.com/watch?v=2dz0iKwHrkI&quot;&gt;the opening of &lt;em&gt;Outlive everything you know&lt;/em&gt;&lt;/a&gt; sound reminiscent of house music, again mixed in with a kaleidoscope of strange glitches and multiphonics.&lt;/p&gt;
&lt;p&gt;Someone I admire who manages to pull together “cheesy” synth sounds with experimental electronics (as well as metal and many other things!) is Fire-Toolz. Listen how the opening of &lt;a href=&quot;https://fire-toolz.bandcamp.com/track/soaked-another-name-for-everything&quot;&gt;&lt;em&gt;Soaked: Another Name for Everything&lt;/em&gt;&lt;/a&gt; moves from acoustic guitar to 80s power ballad to glitchy sound collage, to some sort of prog-rock/elevator music hybrid at the end. Extremely colorful, and while her music is very different from Schoenberg, the quick movement between different tone colors is an integral part of her work too.&lt;/p&gt;
&lt;h2 id=&quot;wrapping-up&quot;&gt;Wrapping Up&lt;/h2&gt;
&lt;p&gt;Marisabel is hosting &lt;a href=&quot;https://marisabel.nl/public/blog/IndieWeb_Carnival_August_2025_:_Colors&quot;&gt;this month&#39;s IndieWeb carnival on the topic of colors&lt;/a&gt;, and this is my contribution. I had been looking forward to writing on this topic since I saw it on &lt;a href=&quot;https://indieweb.org/IndieWeb_Carnival&quot;&gt;the list of upcoming events&lt;/a&gt;. I&#39;ve been enjoying other people&#39;s entries, and thanks to Marisabel for hosting! I&#39;ve particularly enjoyed this exercise of looking at my past work because it has given me some ideas for a current composition project — more info on that as I compose. Until next time!&lt;/p&gt;
&lt;hr class=&quot;footnotes-sep&quot; /&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Schoenberg, Arnold. &lt;em&gt;Theory of Harmony&lt;/em&gt;. Translated by Roy E. Carter. University of California Press, 1978. &lt;a href=&quot;https://reillyspitzfaden.com/posts/2025/08/indieweb-carnival-tone-colors/#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;p&gt;&lt;a href=&quot;mailto:reillypascal@gmail.com?subject=Re:%20&#39;IndieWeb%20Carnival:%20Tone%20Colors&#39;&quot;&gt;Reply via email&lt;/a&gt; :: &lt;a href=&quot;https://reillyspitzfaden.com/feeds/&quot;&gt;Subscribe to my other feeds&lt;/a&gt; :: &lt;a href=&quot;https://ko-fi.com/reillyspitzfaden&quot;&gt;Buy me a coffee&lt;/a&gt;&lt;/p&gt;
            </content:encoded>
          </item>
        <item>
            <title>Plugins for Everyone! Cross-Platform JUCE with CMake &amp; GitHub Actions</title>
            <author>reillypascal@gmail.com (Reilly Spitzfaden)</author>
            <link>https://reillyspitzfaden.com/posts/2025/08/plugins-for-everyone-crossplatform-juce-with-cmake-github-actions/</link>
            <guid>https://reillyspitzfaden.com/posts/2025/08/plugins-for-everyone-crossplatform-juce-with-cmake-github-actions/</guid>
            <pubDate>Fri, 01 Aug 2025 18:31:00 GMT</pubDate>
            <description>My C++ reverb plugin is finally available for macOS, Windows, and Linux! Here&#39;s how I&#39;m using JUCE&#39;s CMake API and GitHub actions to make that possible.</description>
            <content:encoded>
            
            

          
          
          &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://reillyspitzfaden.com/styles/code/prism-perf-custom.css&quot; /&gt;
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://reillyspitzfaden.com/styles/code/code-tweaks.css&quot; /&gt;
&lt;p&gt;I have &lt;a href=&quot;https://github.com/reillypascal/RSBrokenMedia&quot;&gt;a few&lt;/a&gt; &lt;a href=&quot;https://github.com/reillypascal/RSAlgorithmicVerb&quot;&gt;C++/JUCE&lt;/a&gt; &lt;a href=&quot;https://github.com/reillypascal/RSTelecom&quot;&gt;audio plugins&lt;/a&gt; I&#39;ve worked on off and on over the last couple of years. I&#39;ve wanted them to be available to anyone who&#39;s interested, but I previously wasn&#39;t able to get them compiled for Windows (and Linux was very inconvenient).&lt;/p&gt;
&lt;p&gt;I&#39;m now able to easily compile them for Linux, macOS, and Windows using the &lt;a href=&quot;https://github.com/juce-framework/JUCE/blob/d6181bde38d858c283c3b7bf699ce6340c050b5d/docs/CMake%20API.md#L4&quot;&gt;JUCE CMake API&lt;/a&gt; and GitHub actions. Let&#39;s look at how that works!&lt;/p&gt;
&lt;h2 id=&quot;my-starting-point&quot;&gt;My Starting Point&lt;/h2&gt;
&lt;p&gt;The JUCE C++ framework is a popular way to build audio plugins. When you first learn it, the &lt;a href=&quot;https://juce.com/tutorials/tutorial_new_projucer_project/&quot;&gt;tutorials show how to build projects using the “Projucer” GUI tool&lt;/a&gt;. This generates project files for Visual Studio, Xcode, and Linux Makefiles. It&#39;s a convenient and well-documented way to work if you&#39;re only building for one platform, but if you want to compile for multiple OSes, you need to have each OS available to work with (in order to run the appropriate GUI program for which the Projucer generates files). Since my primary computer is a MacBook, I&#39;ve only had compiled releases for macOS. This was where I was when I started learning the CMake API.&lt;/p&gt;
&lt;h2 id=&quot;cmake-and-juce&quot;&gt;CMake and JUCE&lt;/h2&gt;
&lt;p&gt;When I started on the &lt;a href=&quot;https://github.com/juce-framework/JUCE/blob/d6181bde38d858c283c3b7bf699ce6340c050b5d/docs/CMake%20API.md#L4&quot;&gt;JUCE CMake API&lt;/a&gt;, I had next to no experience with CMake. The official website has this nice web book &lt;a href=&quot;https://cmake.org/cmake/help/book/mastering-cmake/index.html&quot;&gt;&lt;em&gt;Mastering CMake&lt;/em&gt;&lt;/a&gt;. Among other things, it has &lt;a href=&quot;https://cmake.org/cmake/help/book/mastering-cmake/cmake/Help/guide/tutorial/index.html&quot;&gt;a step-by-step tutorial&lt;/a&gt; and &lt;a href=&quot;https://cmake.org/cmake/help/latest/manual/cmake.1.html#manual:cmake(1)&quot;&gt;documentation for the &lt;code&gt;cmake&lt;/code&gt; CLI command&lt;/a&gt;, which were particularly helpful. You can also look at the examples in the JUCE &lt;a href=&quot;https://github.com/juce-framework/JUCE/tree/master/examples/CMake&quot;&gt;examples/CMake folder&lt;/a&gt; for reference on the JUCE end of things.&lt;/p&gt;
&lt;p&gt;Below is the CMakeLists.txt file for my &lt;a href=&quot;https://github.com/reillypascal/RSAlgorithmicVerb&quot;&gt;algorithmic reverb plugin&lt;/a&gt;—this goes in the root directory. Let&#39;s go through line by line:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;a href=&quot;https://cmake.org/cmake/help/latest/command/cmake_minimum_required.html&quot;&gt;&lt;code&gt;cmake_minimum_required&lt;/code&gt;&lt;/a&gt; statement should be the first line in any CMakeLists.txt file.&lt;/li&gt;
&lt;li&gt;Without &lt;a href=&quot;https://cmake.org/cmake/help/latest/command/set.html&quot;&gt;&lt;code&gt;set(CMAKE_EXPORT_COMPILE_COMMANDS ON)&lt;/code&gt;&lt;/a&gt;, my text editor (currently using Zed and Neovim) can&#39;t find the JUCE imports it needs.&lt;/li&gt;
&lt;li&gt;The &lt;a href=&quot;https://cmake.org/cmake/help/latest/command/project.html&quot;&gt;&lt;code&gt;project&lt;/code&gt;&lt;/a&gt; statement gives the name/version.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://cmake.org/cmake/help/latest/command/add_subdirectory.html&quot;&gt;&lt;code&gt;add_subdirectory(JUCE)&lt;/code&gt;&lt;/a&gt;: if you clone the &lt;a href=&quot;https://github.com/juce-framework/JUCE&quot;&gt;JUCE framework&lt;/a&gt; into the working directory (&lt;code&gt;git clone https://github.com/juce-framework/JUCE.git&lt;/code&gt;), this statement will make the resulting folder available.
&lt;ul&gt;
&lt;li&gt;I&#39;ve seen the &lt;a href=&quot;https://github.com/cpm-cmake/CPM.cmake&quot;&gt;CPM&lt;/a&gt; package manager used (e.g., in &lt;a href=&quot;https://www.youtube.com/watch?v=Uq7Hwt18s3s&quot;&gt;this video from WolfSound&lt;/a&gt;) to bring in these dependencies, but I was having some kind of issue with dependencies being included twice and decided to figure that out later.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The &lt;a href=&quot;https://github.com/juce-framework/JUCE/blob/d6181bde38d858c283c3b7bf699ce6340c050b5d/docs/CMake%20API.md#juce_add_target&quot;&gt;&lt;code&gt;juce_add_plugin&lt;/code&gt;&lt;/a&gt; line is from the JUCE API. This contains a list of options and metadata for the plugin.
&lt;ul&gt;
&lt;li&gt;Note in particular &lt;code&gt;COPY_PLUGIN_AFTER_BUILD TRUE&lt;/code&gt;, and the following two lines &lt;code&gt;VST3_COPY_DIR &amp;quot;/Library/Audio/Plug-Ins/VST3&amp;quot;&lt;/code&gt; and &lt;code&gt;AU_COPY_DIR &amp;quot;/Library/Audio/Plug-Ins/Components&amp;quot;&lt;/code&gt;. If you uncomment these, CMake will copy the plugin files to the given directories after building. You &lt;em&gt;don&#39;t&lt;/em&gt; want this for the GitHub actions,&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/juce-framework/JUCE/blob/d6181bde38d858c283c3b7bf699ce6340c050b5d/docs/CMake%20API.md#juce_generate_juce_header&quot;&gt;&lt;code&gt;juce_generate_juce_header&lt;/code&gt;&lt;/a&gt; generates the &lt;code&gt;JuceHeader.h&lt;/code&gt; file. As the link above describes and &lt;a href=&quot;https://melatonin.dev/manuals/pamplejuce/juce/juceheader-h/&quot;&gt;Sudara demonstrates&lt;/a&gt;, if you&#39;re not using the Projucer you can include the JUCE module(s) you need directly.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://cmake.org/cmake/help/latest/command/target_sources.html&quot;&gt;&lt;code&gt;target_sources&lt;/code&gt;&lt;/a&gt; lists the .cpp that need to be included in the project.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://cmake.org/cmake/help/latest/command/target_compile_definitions.html&quot;&gt;&lt;code&gt;target_compile_definitions&lt;/code&gt;&lt;/a&gt; adds preprocessor definitions to the target—see the options used below.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://cmake.org/cmake/help/latest/command/target_link_libraries.html&quot;&gt;&lt;code&gt;target_link_libraries&lt;/code&gt;&lt;/a&gt;: in the &lt;code&gt;PRIVATE&lt;/code&gt; field, we include the JUCE modules we&#39;re using in this project. In the &lt;code&gt;PUBLIC&lt;/code&gt; field, we include some recommended flags.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;language-cmake&quot;&gt;&lt;code class=&quot;language-cmake&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;cmake_minimum_required&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;VERSION&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3.22&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;CMAKE_EXPORT_COMPILE_COMMANDS&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;ON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;RSAlgorithmicVerb &lt;span class=&quot;token property&quot;&gt;VERSION&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.5.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;add_subdirectory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;JUCE&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;                    &lt;span class=&quot;token comment&quot;&gt;# If you&#39;ve put JUCE in a subdirectory called JUCE&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;juce_add_plugin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;PROJECT_NAME&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# VERSION ...                               # Set this if the plugin version is different to the project version&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# ICON_BIG ...                              # ICON_* arguments specify a path to an image file to use as an icon for the Standalone&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# ICON_SMALL ...&lt;/span&gt;
    COMPANY_NAME &lt;span class=&quot;token string&quot;&gt;&quot;Reilly Spitzfaden&quot;&lt;/span&gt;                          &lt;span class=&quot;token comment&quot;&gt;# Specify the name of the plugin&#39;s author&lt;/span&gt;
    BUNDLE_ID &lt;span class=&quot;token string&quot;&gt;&quot;com.reillyspitzfaden.RSAlgorithmicVerb&quot;&lt;/span&gt;
    IS_SYNTH &lt;span class=&quot;token boolean&quot;&gt;FALSE&lt;/span&gt;                       &lt;span class=&quot;token comment&quot;&gt;# Is this a synth or an effect?&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# NEEDS_MIDI_INPUT TRUE/FALSE               # Does the plugin need midi input?&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# NEEDS_MIDI_OUTPUT TRUE/FALSE              # Does the plugin need midi output?&lt;/span&gt;
    IS_MIDI_EFFECT &lt;span class=&quot;token boolean&quot;&gt;FALSE&lt;/span&gt;                 &lt;span class=&quot;token comment&quot;&gt;# Is this plugin a MIDI effect?&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# EDITOR_WANTS_KEYBOARD_FOCUS TRUE/FALSE    # Does the editor need keyboard focus?&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# Should the plugin be installed to a default location after building?&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# COPY_PLUGIN_AFTER_BUILD TRUE&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# VST3_COPY_DIR &quot;/Library/Audio/Plug-Ins/VST3&quot;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# AU_COPY_DIR &quot;/Library/Audio/Plug-Ins/Components&quot;&lt;/span&gt;
    PLUGIN_MANUFACTURER_CODE Rspi               &lt;span class=&quot;token comment&quot;&gt;# A four-character manufacturer id with at least one upper-case character&lt;/span&gt;
    PLUGIN_CODE Rsav                            &lt;span class=&quot;token comment&quot;&gt;# A unique four-character plugin id with exactly one upper-case character&lt;/span&gt;
                                                &lt;span class=&quot;token comment&quot;&gt;# GarageBand 10.3 requires the first letter to be upper-case, and the remaining letters to be lower-case&lt;/span&gt;
    FORMATS AU VST3                  &lt;span class=&quot;token comment&quot;&gt;# The formats to build. Other valid formats are: AAX Unity VST AU AUv3 Standalone&lt;/span&gt;
    PRODUCT_NAME &lt;span class=&quot;token string&quot;&gt;&quot;RSAlgorithmicVerb&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;        &lt;span class=&quot;token comment&quot;&gt;# The name of the final executable, which can differ from the target name&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;juce_generate_juce_header&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;PROJECT_NAME&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;target_sources&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;PROJECT_NAME&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token namespace&quot;&gt;PRIVATE&lt;/span&gt;
        Source/ConcertHallB.cpp
        Source/CustomDelays.cpp
        Source/DattorroVerb.cpp
        Source/EarlyReflections.cpp
        Source/FDNs.cpp
        Source/Freeverb.cpp
        Source/GardnerRooms.cpp
        Source/LFO.cpp
        Source/SpecialFX.cpp
        Source/PluginEditor.cpp
        Source/PluginProcessor.cpp&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;target_compile_definitions&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;PROJECT_NAME&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token namespace&quot;&gt;PUBLIC&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;# JUCE_WEB_BROWSER and JUCE_USE_CURL would be on by default, but you might not need them.&lt;/span&gt;
        JUCE_WEB_BROWSER=&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# If you remove this, add `NEEDS_WEB_BROWSER TRUE` to the `juce_add_plugin` call&lt;/span&gt;
        JUCE_USE_CURL=&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;     &lt;span class=&quot;token comment&quot;&gt;# If you remove this, add `NEEDS_CURL TRUE` to the `juce_add_plugin` call&lt;/span&gt;
        JUCE_VST3_CAN_REPLACE_VST2=&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;target_link_libraries&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;PROJECT_NAME&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token namespace&quot;&gt;PRIVATE&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;# AudioPluginData           # If we&#39;d created a binary data target, we&#39;d link to it here&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;# juce::juce_analytics&lt;/span&gt;
        &lt;span class=&quot;token inserted class-name&quot;&gt;juce::juce_audio_basics&lt;/span&gt;
        &lt;span class=&quot;token inserted class-name&quot;&gt;juce::juce_audio_devices&lt;/span&gt;
        &lt;span class=&quot;token inserted class-name&quot;&gt;juce::juce_audio_formats&lt;/span&gt;
        &lt;span class=&quot;token inserted class-name&quot;&gt;juce::juce_audio_processors&lt;/span&gt;
        &lt;span class=&quot;token inserted class-name&quot;&gt;juce::juce_audio_utils&lt;/span&gt;
        &lt;span class=&quot;token inserted class-name&quot;&gt;juce::juce_core&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;# juce::juce_cryptography&lt;/span&gt;
        &lt;span class=&quot;token inserted class-name&quot;&gt;juce::juce_data_structures&lt;/span&gt;
        &lt;span class=&quot;token inserted class-name&quot;&gt;juce::juce_dsp&lt;/span&gt;
        &lt;span class=&quot;token inserted class-name&quot;&gt;juce::juce_events&lt;/span&gt;
        &lt;span class=&quot;token inserted class-name&quot;&gt;juce::juce_graphics&lt;/span&gt;
        &lt;span class=&quot;token inserted class-name&quot;&gt;juce::juce_gui_basics&lt;/span&gt;
        &lt;span class=&quot;token inserted class-name&quot;&gt;juce::juce_gui_extra&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;# juce::juce_opengl&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;# juce::juce_osc&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;# juce::juce_video&lt;/span&gt;
    &lt;span class=&quot;token namespace&quot;&gt;PUBLIC&lt;/span&gt;
        &lt;span class=&quot;token inserted class-name&quot;&gt;juce::juce_recommended_config_flags&lt;/span&gt;
        &lt;span class=&quot;token inserted class-name&quot;&gt;juce::juce_recommended_lto_flags&lt;/span&gt;
        &lt;span class=&quot;token inserted class-name&quot;&gt;juce::juce_recommended_warning_flags&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With this &lt;code&gt;CMakeLists.txt&lt;/code&gt;, you can run &lt;code&gt;cmake -S . -B build&lt;/code&gt; in the root directory to create the build environment. This means the source is the root directory, and &lt;code&gt;build&lt;/code&gt; is the build directory. You can add the flags &lt;code&gt;-D CMAKE_BUILD_TYPE=Debug&lt;/code&gt; or &lt;code&gt;-D CMAKE_BUILD_TYPE=Release&lt;/code&gt; to specify debug/release builds. After that, run &lt;code&gt;cmake --build build&lt;/code&gt; to compile. Note that if you have the &lt;code&gt;COPY_PLUGIN_AFTER_BUILD TRUE&lt;/code&gt; option in &lt;code&gt;juce_add_plugin&lt;/code&gt;, you will likely need to add &lt;code&gt;sudo&lt;/code&gt; to both of the build commands since my installation directories above are system ones.&lt;/p&gt;
&lt;h2 id=&quot;compiling-with-github-actions&quot;&gt;Compiling with GitHub Actions&lt;/h2&gt;
&lt;p&gt;The nice thing about using CMake is that it doesn&#39;t require a desktop GUI program like Xcode or Visual Studio, meaning that it&#39;s possible to use something like &lt;a href=&quot;https://docs.github.com/en/actions&quot;&gt;GitHub actions&lt;/a&gt; to compile in the terminal on virtual versions of the target OSes. For my build action, I referenced &lt;a href=&quot;https://github.com/sudara/pamplejuce/blob/main/.github/workflows/build_and_test.yml&quot;&gt;Sudara&#39;s Pamplejuce template&lt;/a&gt;. This is the file &lt;code&gt;.github/workflows/cmake.yml&lt;/code&gt;. I have this set to manually trigger, and if you go to the “Actions” tab for your project, you can trigger a build using the GUI.&lt;/p&gt;
&lt;p&gt;The file is fairly straightforward, but I&#39;ll point out some specifics. &lt;a href=&quot;https://docs.github.com/en/actions/how-tos/manage-workflow-runs/manually-run-a-workflow&quot;&gt;&lt;code&gt;on: [workflow_dispatch]&lt;/code&gt;&lt;/a&gt; means that you manually trigger the build. The &lt;a href=&quot;https://docs.github.com/en/actions/how-tos/write-workflows/choose-what-workflows-do/run-job-variations&quot;&gt;&lt;code&gt;matrix&lt;/code&gt; strategy&lt;/a&gt; allows for running multiple copies of the job, in this case, on macOS, Ubuntu, and Windows.&lt;/p&gt;
&lt;p&gt;The first two steps, which only run on Linux, are taken directly from Pamplejuce&#39;s example .yml file. Note however that the &lt;a href=&quot;https://github.com/juce-framework/JUCE/blob/develop/docs/Linux%20Dependencies.md&quot;&gt;current version of the Linux dependencies&lt;/a&gt; is slightly different, and I had to adjust accordingly.&lt;/p&gt;
&lt;p&gt;After this, we check out the project repo, clone the JUCE repo, and run (almost) the same CMake commands as above. Note that we specify the &lt;code&gt;Release&lt;/code&gt; build when we actually build, rather than when we set up the build, and that the syntax is a bit different: &lt;code&gt;--config Release&lt;/code&gt;. &lt;code&gt;-D CMAKE_BUILD_TYPE&lt;/code&gt; only seems to work on *nix OSes, not on Windows.&lt;/p&gt;
&lt;p&gt;Finally, we archive the build artifacts (i.e., the compiled files). Note that I append &lt;code&gt;${{ runner.os }}&lt;/code&gt; to the end of the artifact name. This is important—without it, the artifacts for each OS will all be named the same thing, and the process will fail due to path conflicts.&lt;/p&gt;
&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; rsav&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;compile

&lt;span class=&quot;token key atrule&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;workflow_dispatch&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;token key atrule&quot;&gt;jobs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;runs-on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;matrix.os&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;strategy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;matrix&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;macos&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;latest&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ubuntu&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;latest&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; windows&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;latest&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

    &lt;span class=&quot;token key atrule&quot;&gt;steps&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;# Use clang on Linux so we don&#39;t introduce a 3rd compiler (Windows and macOS use MSVC and Clang)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Set up Clang
        &lt;span class=&quot;token key atrule&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; runner.os == &#39;Linux&#39;
        &lt;span class=&quot;token key atrule&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; egor&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;tensin/setup&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;clang@v1

      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Install JUCE&#39;s Linux Deps
        &lt;span class=&quot;token key atrule&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; runner.os == &#39;Linux&#39;
        &lt;span class=&quot;token comment&quot;&gt;# Official list of Linux deps: https://github.com/juce-framework/JUCE/blob/develop/docs/Linux%20Dependencies.md&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;token scalar string&quot;&gt;
          sudo apt-get update &amp;amp;&amp;amp; sudo apt install libasound2-dev libjack-jackd2-dev &#92;
              ladspa-sdk &#92;
              libcurl4-openssl-dev  &#92;
              libfreetype-dev libfontconfig1-dev &#92;
              libx11-dev libxcomposite-dev libxcursor-dev libxext-dev libxinerama-dev libxrandr-dev libxrender-dev &#92;
              libwebkit2gtk-4.1-dev &#92;
              libglu1-mesa-dev mesa-common-dev&lt;/span&gt;

      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Preparation&quot;&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; actions/checkout@v2

      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;(JUCE) Clone Repository&quot;&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; actions/checkout@v2
        &lt;span class=&quot;token key atrule&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;repository&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; juce&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;framework/JUCE
          &lt;span class=&quot;token key atrule&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;runner.workspace&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;/RSAlgorithmicVerb/JUCE

      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Create Build Environment&quot;&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;working-directory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;runner.workspace&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;/RSAlgorithmicVerb
        &lt;span class=&quot;token key atrule&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; cmake &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;S . &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;B build

      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Build&quot;&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;working-directory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;runner.workspace&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;/RSAlgorithmicVerb
        &lt;span class=&quot;token key atrule&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; cmake &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;build build &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;config Release

      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Archive build artifacts
        &lt;span class=&quot;token key atrule&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; actions/upload&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;artifact@v4
        &lt;span class=&quot;token key atrule&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;RSAlgorithmicVerb_${{ runner.os }}&quot;&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;runner.workspace&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;/RSAlgorithmicVerb/build/RSAlgorithmicVerb_artefacts/&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;linux-build-issues&quot;&gt;Linux Build Issues&lt;/h2&gt;
&lt;p&gt;Frustratingly, this all works perfectly for Mac and Windows, but gives me a perplexing issue on Linux. The GitHub action works without issue on all OSes. However, when I use &lt;a href=&quot;https://github.com/Tracktion/pluginval&quot;&gt;pluginval&lt;/a&gt; to validate the Linux build on Debian 12.11, I get the following error for both the “open plugin (cold)” and “open plugin (warm)” tests:&lt;/p&gt;
&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt; Test &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; failed: Expected value: , Actual value: Unable to load VST-3 plug-in &lt;span class=&quot;token function&quot;&gt;file&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt; Test &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; failed: Unable to create juce::AudioPluginInstance&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When I try to load the plugin in REAPER (same distro/version), the DAW detects that the plugin exists but won&#39;t load it. However, if I manually compile on my Debian laptop using CMake, everything works fine! The only other clue I&#39;ve been able to find is that the VST3 &lt;code&gt;RSAlgorithmicVerb.so&lt;/code&gt; file is significantly bigger when I use the GitHub action than when I manually compile it—31.9 MB, instead of 5.1 MB. At this point, I&#39;ve decided to manually compile the Linux version, although I would very much like to figure this issue out, if anyone has any idea!&lt;/p&gt;
&lt;h2 id=&quot;wrapping-up&quot;&gt;Wrapping Up&lt;/h2&gt;
&lt;p&gt;Please check out the &lt;a href=&quot;https://github.com/reillypascal/RSAlgorithmicVerb/releases&quot;&gt;releases for my reverb plugin&lt;/a&gt;—it&#39;s available for Linux, Mac, and Windows! This is the only one for which I&#39;ve set up this workflow, but next on my list is &lt;a href=&quot;https://github.com/reillypascal/RSTelecom&quot;&gt;my telecom codec plugin&lt;/a&gt;—I want to to add a C++ version of the &lt;a href=&quot;https://reillyspitzfaden.com/posts/2025/05/databending-part-5/&quot;&gt;Rust ADPCM codec I wrote about previously&lt;/a&gt;, for example.&lt;/p&gt;
&lt;p&gt;For the time being, I don&#39;t have the full release and validation process automated. I decided to leave it as is since the main reason I want to do this is so I have easy access to Windows/Linux compilers. As a next step, I would like to reference &lt;a href=&quot;https://github.com/sudara/pamplejuce/blob/main/.github/workflows/build_and_test.yml&quot;&gt;the Pamplejuce workflow file&lt;/a&gt; and finish automating that. The example uses &lt;a href=&quot;https://keith.github.io/xcode-man-pages/pkgbuild.1.html&quot;&gt;the Xcode &lt;code&gt;pkgbuild&lt;/code&gt; utility&lt;/a&gt; and &lt;a href=&quot;https://github.com/Tracktion/pluginval&quot;&gt;Tracktion&#39;s &lt;code&gt;pluginval&lt;/code&gt; validator&lt;/a&gt;, and it would be very convenient. Until next time!&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;mailto:reillypascal@gmail.com?subject=Re:%20&#39;Plugins%20for%20Everyone!%20Cross-Platform%20JUCE%20with%20CMake%20&amp;amp;%20GitHub%20Actions&#39;&quot;&gt;Reply via email&lt;/a&gt; :: &lt;a href=&quot;https://reillyspitzfaden.com/feeds/&quot;&gt;Subscribe to my other feeds&lt;/a&gt; :: &lt;a href=&quot;https://ko-fi.com/reillyspitzfaden&quot;&gt;Buy me a coffee&lt;/a&gt;&lt;/p&gt;
            </content:encoded>
          </item>
        <item>
            <title>Powder Mills USGS Gaging Station</title>
            <author>reillypascal@gmail.com (Reilly Spitzfaden)</author>
            <link>https://reillyspitzfaden.com/notes/2025/07/powder-mills-usgs-gaging-station/</link>
            <guid>https://reillyspitzfaden.com/notes/2025/07/powder-mills-usgs-gaging-station/</guid>
            <pubDate>Sun, 20 Jul 2025 19:07:10 GMT</pubDate>
            <description></description>
            <content:encoded>
            
            

          
          
          &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://reillyspitzfaden.com/styles/notes-photos.css&quot; /&gt;
&lt;p&gt;My partner and I took a walk at Powder Mill Park in upstate NY to look at the mushrooms and fish hatchery. While we were there, I came across the transmitter for a &lt;a href=&quot;https://waterdata.usgs.gov/monitoring-location/USGS-430252077283402/&quot;&gt;United States Geological Survey (USGS) stream gaging station&lt;/a&gt;—you can go to the link and see the data from this station.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://reillyspitzfaden.com/media/notes/2025/usgs-powder-mill-graph.webp&quot; alt=&quot;A graph of water levels from Jul. 13-20 showing feet below ground level. There is a peak of around 9.25 ft. on the 15th, a smaller one on the 18th, and the level drops to around 9.75 ft. below the ground by the end&quot; class=&quot;img-horizontal&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I&#39;ve been interested in cataloging the stations I see since I saw Sarah from Signals Everywhere&#39;s &lt;a href=&quot;https://www.youtube.com/watch?v=TT8AIp-DlrM&quot;&gt;video on the transmitters for these stations&lt;/a&gt;. I previously &lt;a href=&quot;https://hachyderm.io/@reillypascal/111915520145252626&quot;&gt;found one&lt;/a&gt; at Ellison Park and got some pictures of both the transmitter and what I believe is the sensor. According to Sarah, the stations uplink the data in the UHF band (~401 MHz) to the &lt;a href=&quot;https://www.star.nesdis.noaa.gov/goes/index.php&quot;&gt;GOES weather satellites&lt;/a&gt;, which relay the data back down for processing by the &lt;a href=&quot;https://www.nesdis.noaa.gov/&quot;&gt;National Environmental Satellite, Data, and Information Service (NESDIS)&lt;/a&gt;. My photos from today are below:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://reillyspitzfaden.com/media/notes/2025/usgs-gaging-station-powder-mill.webp&quot; alt=&quot;A circularly-polarized Yagi antenna on top of a pole with a box in the middle from the US Geological Survey&quot; class=&quot;img-vertical&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://reillyspitzfaden.com/media/notes/2025/usgs-gaging-station-powder-mill-box.webp&quot; alt=&quot;A close up of a rusty gray metal box with a white/green label reading &amp;quot;USGS science for a changing world OBSERVATION WELL Operated by U.S. GEOLOGICAL SURVEY IN COOPERATION WITH FEDERAL, STATE, AND LOCAL AGENCIES This station is part of a national network for obtaining water-resources information. The recorded water levels are used for flood forecasting, reservoir operations, design of bridges and culverts, interstate and intrastate water-rights claims, and many other hydrologic projects. For information contact:&amp;quot;&quot; class=&quot;img-horizontal&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I&#39;ve long thought it would be cool to connect the data from these to some sort of musical result, but I haven&#39;t figured out a satisfying way to do that—a way to both make the data meaningfully present in the music &lt;em&gt;and&lt;/em&gt; make interesting music, rather than something blandly demonstrative of the data.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;mailto:reillypascal@gmail.com?subject=Re:%20&#39;Powder%20Mills%20USGS%20Gaging%20Station&#39;&quot;&gt;Reply via email&lt;/a&gt; :: &lt;a href=&quot;https://reillyspitzfaden.com/feeds/&quot;&gt;Subscribe to my other feeds&lt;/a&gt; :: &lt;a href=&quot;https://ko-fi.com/reillyspitzfaden&quot;&gt;Buy me a coffee&lt;/a&gt;&lt;/p&gt;
            </content:encoded>
          </item>
        <item>
            <title>Photoblog: Natural Stone Bridge &amp; Caves</title>
            <author>reillypascal@gmail.com (Reilly Spitzfaden)</author>
            <link>https://reillyspitzfaden.com/notes/2025/07/photoblog-natural-stone-bridge-caves/</link>
            <guid>https://reillyspitzfaden.com/notes/2025/07/photoblog-natural-stone-bridge-caves/</guid>
            <pubDate>Wed, 02 Jul 2025 02:41:29 GMT</pubDate>
            <description></description>
            <content:encoded>
            
            

          
          
          &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://reillyspitzfaden.com/styles/notes-photos.css&quot; /&gt;
&lt;p&gt;I went with my partner to the Natural Stone Bridge &amp;amp; Caves park in the Adirondacks for their birthday. They love rocks and geology, and really wanted to go here.&lt;/p&gt;
&lt;p&gt;From what they told me, this park was originally gifted to a family as thanks for their efforts in the American Revolutionary War, and after a long time as a sawmill, later members of the family converted it to a park.&lt;/p&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;https://reillyspitzfaden.com/media/blog/2025/07/eli-bday/IMG_2509.webp&quot; alt=&quot;My partner and me, with a walkway handrail and a marble cave entrance visible in the background&quot; class=&quot;img-vertical&quot; /&gt;&lt;/p&gt;
&lt;figcaption&gt;The cave behind us is made of marble, and was formed from a collapse several decades ago—I think in the 90s.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;https://reillyspitzfaden.com/media/blog/2025/07/eli-bday/IMG_20250701_134137_818.webp&quot; alt=&quot;A person in a black T-shirt, sweats, and glasses (my partner) making a “rock-n-roll” hand gesture and sticking out their tongue&quot; class=&quot;img-vertical&quot; /&gt;&lt;/p&gt;
&lt;figcaption&gt;My partner standing in the aptly-named “Noisy Cave,” which resounded with rushing water.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;https://reillyspitzfaden.com/media/blog/2025/07/eli-bday/IMG_20250701_134225_296.webp&quot; alt=&quot;The view out of a rocky cave, with stair steps cut into the ascent and sunlight peeking through the entrance&quot; class=&quot;img-vertical&quot; /&gt;&lt;/p&gt;
&lt;figcaption&gt;The view out of “Noisy Cave”&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;p&gt;&lt;img src=&quot;https://reillyspitzfaden.com/media/blog/2025/07/eli-bday/IMG_20250701_142237_732.webp&quot; alt=&quot;My partner standing on a flat, rocky surface under a brown and tan striped rock overhang&quot; class=&quot;img-vertical&quot; /&gt;&lt;/p&gt;
&lt;figcaption&gt;This area was down in a gorge between two banks. Everything around us was rocks.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&quot;mailto:reillypascal@gmail.com?subject=Re:%20&#39;Photoblog:%20Natural%20Stone%20Bridge%20&amp;amp;%20Caves&#39;&quot;&gt;Reply via email&lt;/a&gt; :: &lt;a href=&quot;https://reillyspitzfaden.com/feeds/&quot;&gt;Subscribe to my other feeds&lt;/a&gt; :: &lt;a href=&quot;https://ko-fi.com/reillyspitzfaden&quot;&gt;Buy me a coffee&lt;/a&gt;&lt;/p&gt;
            </content:encoded>
          </item></channel>
</rss>