<?xml version="1.0"?>
<!-- name="generator" content="blosxom/2.0" -->
<!DOCTYPE rss PUBLIC "-//Netscape Communications//DTD RSS 0.91//EN" "http://my.netscape.com/publish/formats/rss-0.91.dtd">

<rss version="0.91">
  <channel>
    <title>e dot dot dot   </title>
    <link>http://www.jamesraposa.com/index</link>
    <description>e dot dot dot - a mostly about the Internet weblog by James Raposa</description>
    <language>en</language>

  <item>
    <title>Making an Asynchronous Clocking Drum Machine App in Perl</title>
    <link>http://www.jamesraposa.com/index/2026/04/15#auto___making_an_asynchronous_clocking_drum_machine_app_in_perl</link>
    <description>Furnished content.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Let&amp;rsquo;s Make a Drum Machine application! Yeah! :DThere are basically two important things to handle: A MIDI &amp;ldquo;clock&amp;rdquo; and a groove to play.Why asynchronous? Well, a simple &lt;code&gt;while (1) { Time::HiRes::sleep(); ... }&lt;/code&gt; will not do because the time between ticks will fluctuate, often dramatically. &lt;code&gt;IO::Async::Timer::Periodic&lt;/code&gt; is a great timer for this purpose. Its default scheduler uses system time, so intervals happen as close to the correct real-world time as possible.&lt;h2 id=&quot;clocks&quot;&gt;Clocks&lt;/h2&gt;A MIDI clock tells a MIDI device about the tempo. This can be handed to a drum machine or a sequencer. Each clock tick tells the device to advance a step of a measured interval. Usually this is very short, and is often 24 pulses per quarter-note (four quarter-notes to a measure of four beats).Here is code to do that, followed by an explanation of the parts:&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot; style=&quot;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&quot;&gt;&lt;code class=&quot;language-perl&quot; data-lang=&quot;perl&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#75715e&quot;&gt;#!/usr/bin/env perl&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;use&lt;/span&gt; v5&lt;span style=&quot;color:#ae81ff&quot;&gt;.36&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;use&lt;/span&gt; feature &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;try&amp;#39;&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;use&lt;/span&gt; IO::Async::Loop ();&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;use&lt;/span&gt; IO::Async::Timer::Periodic ();&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;use&lt;/span&gt; MIDI::RtMidi::FFI::Device ();&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; shift &lt;span style=&quot;color:#f92672&quot;&gt;||&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;usb&amp;#39;&lt;/span&gt;; &lt;span style=&quot;color:#75715e&quot;&gt;# MIDI sequencer device&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;   &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; shift &lt;span style=&quot;color:#f92672&quot;&gt;||&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;120&lt;/span&gt;; &lt;span style=&quot;color:#75715e&quot;&gt;# beats per minute&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;60&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;/  /&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;24&lt;/span&gt;; &lt;span style=&quot;color:#75715e&quot;&gt;# time / bpm / clocks-per-beat&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#75715e&quot;&gt;# open the named midi device for output&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; RtMidiOut&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;new&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;try { &lt;span style=&quot;color:#75715e&quot;&gt;# this will die on Windows but is needed for Mac&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;open_virtual_port(&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;RtMidiOut&amp;#39;&lt;/span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;catch ($e) {}&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;open_port_by_name(&lt;span style=&quot;color:#e6db74&quot;&gt;qr/\Q/&lt;/span&gt;i);&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;start; &lt;span style=&quot;color:#75715e&quot;&gt;# start the sequencer&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;{INT} &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;sub&lt;/span&gt; { &lt;span style=&quot;color:#75715e&quot;&gt;# halt gracefully&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    say &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;\nStop&amp;#34;&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    try {&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;stop; &lt;span style=&quot;color:#75715e&quot;&gt;# stop the sequencer&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;panic; &lt;span style=&quot;color:#75715e&quot;&gt;# make sure all notes are off&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    catch ($e) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        warn &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;Can&amp;#39;t halt the MIDI out device: $e\n&amp;#34;&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    exit;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;};&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; IO::Async::Loop&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;new&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; IO::Async::Timer::Periodic&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;new&lt;/span&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;   interval &lt;span style=&quot;color:#f92672&quot;&gt;=&amp;gt;&lt;/span&gt; ,&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;   on_tick  &lt;span style=&quot;color:#f92672&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;sub&lt;/span&gt; { &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;clock }, &lt;span style=&quot;color:#75715e&quot;&gt;# send a clock tick!&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;start;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;add();&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;run;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;The above code does a few things. First it uses modern Perl, then the modules that will make execution asynchronous, and finally the module that makes real-time MIDI possible.Next up, a &lt;code&gt;&lt;/code&gt; variable is captured for a unique MIDI device. (And to see what the names of MIDI devices on the system are, use &lt;a href=&quot;https://metacpan.org/author/JBARRETT&quot;&gt;JBARRETT&lt;/a&gt;&amp;rsquo;s little &lt;a href=&quot;https://metacpan.org/release/JBARRETT/MIDI-RtMidi-FFI-0.10/source/examples/list_devices.pl&quot;&gt;list_devices&lt;/a&gt; script.) Also, the beats per minute is taken from the command-line. If neither is given, &lt;code&gt;usb&lt;/code&gt; is used for the name, and the BPM is set to &amp;ldquo;dance tempo.&amp;rdquo;The clock needs a time interval to tick off. For us, this is a fraction of a second based on the beats per minute, and is assigned to the &lt;code&gt;&lt;/code&gt; variable.To get the job done, we will need to open the named MIDI device for sending output messages to. This is done with the &lt;code&gt;&lt;/code&gt; provided.In order to not just die when we want to stop, &lt;code&gt;{INT}&lt;/code&gt; is redefined to gracefully halt. This also sends a &lt;code&gt;stop&lt;/code&gt; message to the open MIDI device. This stops the sequencer from playing.Now for the meat and potatoes: The asynchronous loop and periodic timer. These tell the program to do its thing, in a non-blocking and event-driven manner. The periodic timer ticks off a clock message every &lt;code&gt;&lt;/code&gt;. Pretty simple!As an example, here is the above code controlling my &lt;a href=&quot;https://www.korg.com/us/products/dj/volca_drum/&quot;&gt;Volca Drum&lt;/a&gt; drum machine on a stock, funky groove. We invoke it on the command-line like this:&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot; style=&quot;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;perl clock-gen-async.pl&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;audio controls&gt;  &lt;source src=&quot;https://www.perl.com/media/making-an-asynchronous-clocking-drum-machine-in-perl/clocked-sequence.mp3&quot; type=&quot;audio/mpeg&quot;&gt;  Your browser does not support the audio element.&lt;/audio&gt;&lt;h2 id=&quot;grooves&quot;&gt;Grooves&lt;/h2&gt;What we really want is to make our drum machine actually play something of our own making. So it&amp;rsquo;s refactor time&amp;hellip; Let&amp;rsquo;s make a 4/4 time groove, with 16th-note resolution, that alternates between two different parts. &amp;ldquo;4/4&amp;rdquo; is a &amp;ldquo;time signature&amp;rdquo; in music jargon and means that there are four beats per measure (numerator), and a quarter note equals one beat (denominator). Other time signatures like the waltz&amp;rsquo;s 3/4 are simple, while odd meters like 7/8 are not.In order to generate syncopated patterns, &lt;a href=&quot;https://metacpan.org/pod/Math::Prime::XS&quot;&gt;Math::Prime::XS&lt;/a&gt; and &lt;a href=&quot;https://metacpan.org/pod/Music::CreatingRhythms&quot;&gt;Music::CreatingRhythms&lt;/a&gt; are added to the &lt;code&gt;use&lt;/code&gt; statements. &amp;ldquo;What are syncopated patterns?&amp;rdquo;, you may ask. Good question! &amp;ldquo;Syncopated&amp;rdquo; means, &amp;ldquo;characterized by displaced beats.&amp;rdquo; That is, every beat does not happen evenly, at exactly the same time. Instead, some are displaced. For example, a repeated &lt;code&gt;[1 1 1 1]&lt;/code&gt; is even and boring. But when it becomes a repeated &lt;code&gt;[1 1 0 1]&lt;/code&gt; things get spicier and more syncopated.The desired MIDI channel is added to the command-line inputs. Most commonly, this will be channel &lt;code&gt;9&lt;/code&gt; (in zero-based numbering). But some drum machines and sequencers are &amp;ldquo;multi-timbral&amp;rdquo; and use multiple channels simultaneously for individual sounds.Next we define the drums to use. This is a hash-reference that includes the MIDI patch number, the channel it&amp;rsquo;s on, and the pattern to play. The combined patterns of all the drums, when played together at tempo, make a groove.Now we compute intervals and friends. Previously, there was one &lt;code&gt;&lt;/code&gt;. Now there are a whole host of measurements to make before sending MIDI messages.Then, as before, a named MIDI output device is opened, and a graceful stop is defined.Next, a &lt;a href=&quot;https://metacpan.org/pod/Music::CreatingRhythms&quot;&gt;Music::CreatingRhythms&lt;/a&gt; object is created. And then, again as before, an asynchronous loop and periodic timer are instantiated and set in motion.The meaty bits are in the timer&amp;rsquo;s &lt;code&gt;on_tick&lt;/code&gt; callback. This contains all the logic needed to trigger our drum grooves.As was done in the previous clock code, a clock message is sent, but also we keep track of the number of clock ticks that have passed. This number of ticks is used to trigger the drums. We care about 16 beats. So every 16th beat, we construct and play a queue of events.Adjusting the drum patterns is where &lt;a href=&quot;https://metacpan.org/pod/Math::Prime::XS&quot;&gt;Math::Prime::XS&lt;/a&gt; and &lt;a href=&quot;https://metacpan.org/pod/Music::CreatingRhythms&quot;&gt;Music::CreatingRhythms&lt;/a&gt; come into play. The subroutine that does that is &lt;code&gt;adjust_drums()&lt;/code&gt; and is fired every 4th measure. A measure is equal to four quarter-notes, and we use four pulses for each, to make 16 beats per measure. This routine reassigns either Euclidean or manual patterns of 16 beats to each drum pattern.Managing the queue is next. If a drum is to be played at the current beat (as tallied by the &lt;code&gt;&lt;/code&gt; variable), it is added to the queue at full velocity (&lt;code&gt;127&lt;/code&gt;). Then, after all the drums have been accounted for, the queue is played with &lt;code&gt;-&amp;gt;note_on()&lt;/code&gt; messages. Lastly, the queue is &amp;ldquo;drained&amp;rdquo; by sending &lt;code&gt;-&amp;gt;note_off()&lt;/code&gt; messages.&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot; style=&quot;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&quot;&gt;&lt;code class=&quot;language-perl&quot; data-lang=&quot;perl&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#75715e&quot;&gt;#!/usr/bin/env perl&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;use&lt;/span&gt; v5&lt;span style=&quot;color:#ae81ff&quot;&gt;.36&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;use&lt;/span&gt; feature &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;try&amp;#39;&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;use&lt;/span&gt; IO::Async::Loop ();&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;use&lt;/span&gt; IO::Async::Timer::Periodic ();&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;use&lt;/span&gt; Math::Prime::XS &lt;span style=&quot;color:#e6db74&quot;&gt;qw(primes)&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;use&lt;/span&gt; MIDI::RtMidi::FFI::Device ();&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;use&lt;/span&gt; Music::CreatingRhythms ();&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; shift &lt;span style=&quot;color:#f92672&quot;&gt;||&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;usb&amp;#39;&lt;/span&gt;; &lt;span style=&quot;color:#75715e&quot;&gt;# MIDI sequencer device&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;   &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; shift &lt;span style=&quot;color:#f92672&quot;&gt;||&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;120&lt;/span&gt;; &lt;span style=&quot;color:#75715e&quot;&gt;# beats-per-minute&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; shift &lt;span style=&quot;color:#e6db74&quot;&gt;//&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;9&lt;/span&gt;; &lt;span style=&quot;color:#75715e&quot;&gt;# 0-15, 9=percussion, -1=multi-timbral&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; {&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    kick  &lt;span style=&quot;color:#f92672&quot;&gt;=&amp;gt;&lt;/span&gt; { num &lt;span style=&quot;color:#f92672&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;36&lt;/span&gt;, chan &lt;span style=&quot;color:#f92672&quot;&gt;=&amp;gt;&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;0&lt;/span&gt; ? &lt;span style=&quot;color:#ae81ff&quot;&gt;0&lt;/span&gt; : , pat &lt;span style=&quot;color:#f92672&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;[]&lt;/span&gt; },&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    snare &lt;span style=&quot;color:#f92672&quot;&gt;=&amp;gt;&lt;/span&gt; { num &lt;span style=&quot;color:#f92672&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;38&lt;/span&gt;, chan &lt;span style=&quot;color:#f92672&quot;&gt;=&amp;gt;&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;0&lt;/span&gt; ? &lt;span style=&quot;color:#ae81ff&quot;&gt;1&lt;/span&gt; : , pat &lt;span style=&quot;color:#f92672&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;[]&lt;/span&gt; },&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    hihat &lt;span style=&quot;color:#f92672&quot;&gt;=&amp;gt;&lt;/span&gt; { num &lt;span style=&quot;color:#f92672&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;42&lt;/span&gt;, chan &lt;span style=&quot;color:#f92672&quot;&gt;=&amp;gt;&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;0&lt;/span&gt; ? &lt;span style=&quot;color:#ae81ff&quot;&gt;2&lt;/span&gt; : , pat &lt;span style=&quot;color:#f92672&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;[]&lt;/span&gt; },&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;};&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;16&lt;/span&gt;; &lt;span style=&quot;color:#75715e&quot;&gt;# beats in a measure&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;4&lt;/span&gt;; &lt;span style=&quot;color:#75715e&quot;&gt;# divisions of a quarter-note into 16ths&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;24&lt;/span&gt;; &lt;span style=&quot;color:#75715e&quot;&gt;# PPQN&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;60&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;/  /&lt;/span&gt; ; &lt;span style=&quot;color:#75715e&quot;&gt;# time / bpm / ppqn&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;/&lt;/span&gt; ; &lt;span style=&quot;color:#75715e&quot;&gt;# clocks per 16th-note&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt; %primes &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; ( &lt;span style=&quot;color:#75715e&quot;&gt;# for computing the pattern&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    all  &lt;span style=&quot;color:#f92672&quot;&gt;=&amp;gt;&lt;/span&gt; [ primes() ],&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    to_5 &lt;span style=&quot;color:#f92672&quot;&gt;=&amp;gt;&lt;/span&gt; [ primes(&lt;span style=&quot;color:#ae81ff&quot;&gt;5&lt;/span&gt;) ],&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    to_7 &lt;span style=&quot;color:#f92672&quot;&gt;=&amp;gt;&lt;/span&gt; [ primes(&lt;span style=&quot;color:#ae81ff&quot;&gt;7&lt;/span&gt;) ],&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;0&lt;/span&gt;; &lt;span style=&quot;color:#75715e&quot;&gt;# clock ticks&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;0&lt;/span&gt;; &lt;span style=&quot;color:#75715e&quot;&gt;# how many beats?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;0&lt;/span&gt;; &lt;span style=&quot;color:#75715e&quot;&gt;# part A or B?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt; @queue; &lt;span style=&quot;color:#75715e&quot;&gt;# priority queue for note_on/off messages&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#75715e&quot;&gt;# open the named midi output device&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; RtMidiOut&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;new&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;try { &lt;span style=&quot;color:#75715e&quot;&gt;# this will die on Windows but is needed for Mac&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;open_virtual_port(&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;RtMidiOut&amp;#39;&lt;/span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;catch ($e) {}&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;open_port_by_name(&lt;span style=&quot;color:#e6db74&quot;&gt;qr/\Q/&lt;/span&gt;i);&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;{INT} &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;sub&lt;/span&gt; { &lt;span style=&quot;color:#75715e&quot;&gt;# halt gracefully&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    say &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;\nStop&amp;#34;&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    try {&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;stop; &lt;span style=&quot;color:#75715e&quot;&gt;# stop the sequencer&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;panic; &lt;span style=&quot;color:#75715e&quot;&gt;# make sure all notes are off&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    catch ($e) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        warn &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;Can&amp;#39;t halt the MIDI out device: $e\n&amp;#34;&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    exit;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;};&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#75715e&quot;&gt;# for computing the pattern&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; Music::CreatingRhythms&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;new&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; IO::Async::Loop&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;new&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; IO::Async::Timer::Periodic&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;new&lt;/span&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    interval &lt;span style=&quot;color:#f92672&quot;&gt;=&amp;gt;&lt;/span&gt; ,&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    on_tick  &lt;span style=&quot;color:#f92672&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;sub&lt;/span&gt; {&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;clock;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        &lt;span style=&quot;color:#f92672&quot;&gt;++&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        &lt;span style=&quot;color:#66d9ef&quot;&gt;if&lt;/span&gt; ( % &lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;$&lt;/span&gt;sixteenth &lt;span style=&quot;color:#f92672&quot;&gt;==&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;0&lt;/span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;            &lt;span style=&quot;color:#75715e&quot;&gt;# adjust the drum pattern every 4th measure&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;            &lt;span style=&quot;color:#66d9ef&quot;&gt;if&lt;/span&gt; ( % &lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;($&lt;/span&gt;beats &lt;span style=&quot;color:#f92672&quot;&gt;*&lt;/span&gt; ) &lt;span style=&quot;color:#f92672&quot;&gt;==&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;0&lt;/span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;                adjust_drums(, , &lt;span style=&quot;color:#f92672&quot;&gt;\&lt;/span&gt;%primes, &lt;span style=&quot;color:#f92672&quot;&gt;\&lt;/span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;            }&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;            &lt;span style=&quot;color:#75715e&quot;&gt;# add simultaneous drums to the queue&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;            &lt;span style=&quot;color:#66d9ef&quot;&gt;for&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  (keys %) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;                &lt;span style=&quot;color:#66d9ef&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;{}{pat}[  % &lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;$&lt;/span&gt;beats ]) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;                    push @queue, { drum &lt;span style=&quot;color:#f92672&quot;&gt;=&amp;gt;&lt;/span&gt; , velocity &lt;span style=&quot;color:#f92672&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;127&lt;/span&gt; };&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;                }&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;            }&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;            &lt;span style=&quot;color:#75715e&quot;&gt;# play the queue&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;            &lt;span style=&quot;color:#66d9ef&quot;&gt;for&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  (@queue) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;                &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;note_on(&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;                    &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;{ &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;{drum} }{chan},&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;                    &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;{ &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;{drum} }{num},&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;                    &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;{velocity}&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;                );&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;            }&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;            &lt;span style=&quot;color:#f92672&quot;&gt;++&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        &lt;span style=&quot;color:#66d9ef&quot;&gt;else&lt;/span&gt; {&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;            &lt;span style=&quot;color:#75715e&quot;&gt;# drain the queue with note_off messages&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;            &lt;span style=&quot;color:#66d9ef&quot;&gt;while&lt;/span&gt; (&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; pop @queue) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;                &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;note_off(&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;                    &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;{ &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;{drum} }{chan},&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;                    &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;{ &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;{drum} }{num},&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;                    &lt;span style=&quot;color:#ae81ff&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;                );&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;            }&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;            @queue &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; (); &lt;span style=&quot;color:#75715e&quot;&gt;# ensure the queue is empty&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    },&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;start;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;add();&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;run;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;sub&lt;/span&gt; &lt;span style=&quot;color:#a6e22e&quot;&gt;adjust_drums&lt;/span&gt;(, , , ) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    &lt;span style=&quot;color:#75715e&quot;&gt;# choose random primes to use by the hihat, kick, and snare&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    &lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt; ($p, $q, $r) &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; map { &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;{$_}[ int rand &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;{$_}&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;@&lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;*&lt;/span&gt; &lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;}&lt;/span&gt; sort keys %;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    &lt;span style=&quot;color:#66d9ef&quot;&gt;if&lt;/span&gt; ($ &lt;span style=&quot;color:#f92672&quot;&gt;==&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;0&lt;/span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        say &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;part A&amp;#39;&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;{hihat}{pat} &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;euclid($p, );&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;{kick}{pat}  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;euclid($q, );&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;{snare}{pat} &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;rotate_n($r, &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;euclid(&lt;span style=&quot;color:#ae81ff&quot;&gt;2&lt;/span&gt;, ));&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        $ &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;1&lt;/span&gt;; &lt;span style=&quot;color:#75715e&quot;&gt;# set to part B&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    &lt;span style=&quot;color:#66d9ef&quot;&gt;else&lt;/span&gt; {&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        say &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;part B&amp;#39;&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;{hihat}{pat} &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;euclid($p, );&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;{kick}{pat}  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; [&lt;span style=&quot;color:#e6db74&quot;&gt;qw(1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1)&lt;/span&gt;];&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;{snare}{pat} &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; [&lt;span style=&quot;color:#e6db74&quot;&gt;qw(0 0 0 0 1 0 0 0 0 0 0 0 1 0 1 0)&lt;/span&gt;];&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        $ &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;0&lt;/span&gt;; &lt;span style=&quot;color:#75715e&quot;&gt;# set to part A&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;(You may notice the inefficiency of attempting to drain an empty queue 23 times every 16th note. Oof! Fortunately, this doesn&amp;rsquo;t fire anything other than a single while loop condition. A more efficient solution would be to only drain the queue once, but this requires a bit more complexity that we won&amp;rsquo;t be adding, for brevity&amp;rsquo;s sake.)On Windows, this works fine:&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot; style=&quot;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;perl clocked-euclidean-drums.pl &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;gs wavetable&amp;#34;&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;90&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;To run with &lt;code&gt;fluidsynth&lt;/code&gt; and hear the General MIDI percussion sounds, open a fresh new terminal session, and start up &lt;code&gt;fluidsynth&lt;/code&gt; like so (mac syntax):&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot; style=&quot;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;fluidsynth -a coreaudio -m coremidi -g 2.0 ~/Music/soundfont/FluidR3_GM.sf2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;The &lt;code&gt;FluidR3_GM.sf2&lt;/code&gt; is a MIDI &amp;ldquo;soundfont&amp;rdquo; file and can be downloaded for free.Next, enter this on the command-line (back in the &lt;strong&gt;previous&lt;/strong&gt; terminal session):&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot; style=&quot;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;perl clocked-euclidean-drums.pl fluid &lt;span style=&quot;color:#ae81ff&quot;&gt;90&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;You will hear standard kick, snare, and closed hihat cymbal. And here is a poor recording of this with my phone:&lt;audio controls&gt;  &lt;source src=&quot;https://www.perl.com/media/making-an-asynchronous-clocking-drum-machine-in-perl/clocked-euclidean-drums-GM.mp3&quot; type=&quot;audio/mpeg&quot;&gt;  Your browser does not support the audio element.&lt;/audio&gt;To run the code with my multi-timbral drum machine, I enter this on the command-line:&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot; style=&quot;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;perl clocked-euclidean-drums.pl usb &lt;span style=&quot;color:#ae81ff&quot;&gt;90&lt;/span&gt; -1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;And here is what that sounds like:&lt;audio controls&gt;  &lt;source src=&quot;https://www.perl.com/media/making-an-asynchronous-clocking-drum-machine-in-perl/clocked-euclidean-drums.mp3&quot; type=&quot;audio/mpeg&quot;&gt;  Your browser does not support the audio element.&lt;/audio&gt;&lt;h2 id=&quot;the-module&quot;&gt;The Module&lt;/h2&gt;I have coded this logic, and a bit more, into a friendly &lt;a href=&quot;https://metacpan.org/pod/Music::SimpleDrumMachine&quot;&gt;CPAN module&lt;/a&gt;. Check out the &lt;code&gt;eg/euclidean.pl&lt;/code&gt; example program in the distribution. It is a work in progress. YMMV.&lt;h2 id=&quot;credits&quot;&gt;Credits&lt;/h2&gt;Thank you to Andrew Rodland (hobbs), who helped me wrap my head around the &amp;ldquo;no-sleeping asynchronous&amp;rdquo; algorithm.&lt;h2 id=&quot;to-do-challenges&quot;&gt;To-do Challenges&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;Make patterns other than prime number based Euclidean phrases.&lt;/li&gt;&lt;li&gt;Toggle more than two groove parts.&lt;/li&gt;&lt;li&gt;Add snare fills to the (end of the) 4th bars. (&lt;a href=&quot;https://github.com/ology/Music/blob/master/clocked-euclidean-drum-fills.pl&quot;&gt;here&amp;rsquo;s my version&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;Make this code handle odd meter grooves.&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;The &lt;a href=&quot;https://metacpan.org/pod/IO::Async::Loop&quot;&gt;IO::Async::Loop&lt;/a&gt; module&lt;/li&gt;&lt;li&gt;The &lt;a href=&quot;https://metacpan.org/pod/IO::Async::Timer::Periodic&quot;&gt;IO::Async::Timer::Periodic&lt;/a&gt; module&lt;/li&gt;&lt;li&gt;The &lt;a href=&quot;https://metacpan.org/pod/Math::Prime::XS&quot;&gt;Math::Prime::XS&lt;/a&gt; module&lt;/li&gt;&lt;li&gt;The &lt;a href=&quot;https://metacpan.org/pod/MIDI::RtMidi::FFI::Device&quot;&gt;MIDI::RtMidi::FFI::Device&lt;/a&gt; module&lt;/li&gt;&lt;li&gt;The &lt;a href=&quot;https://metacpan.org/pod/Music::CreatingRhythms&quot;&gt;Music::CreatingRhythms&lt;/a&gt; module&lt;/li&gt;&lt;li&gt;The &lt;a href=&quot;https://metacpan.org/pod/Music::SimpleDrumMachine&quot;&gt;Music::SimpleDrumMachine&lt;/a&gt; WIP module based on this logic&lt;/li&gt;&lt;li&gt;The cross-platform &lt;a href=&quot;https://www.fluidsynth.org/&quot;&gt;fluidsynth&lt;/a&gt; application&lt;/li&gt;&lt;li&gt;My original music: &lt;a href=&quot;https://www.youtube.com/@GeneBoggs&quot;&gt;https://www.youtube.com/@GeneBoggs&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Read more &lt;a class=&quot;sw_sl&quot; href=&quot;https://www.perl.com/article/making-an-asynchronous-clocking-drum-machine-in-perl/&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;</description>
  </item>
  <item>
    <title>Musical Rhythms with Math in Perl</title>
    <link>http://www.jamesraposa.com/index/2026/03/16#auto___musical_rhythms_with_math_in_perl</link>
    <description>Furnished content.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Let&amp;rsquo;s talk about music programming! There are a million aspects to this subject, but today, we&amp;rsquo;ll touch on generating rhythmic patterns with mathematical and combinatorial techniques. These include the generation of partitions, necklaces, and Euclidean patterns.Stefan and J. Richard Hollos wrote an &lt;a href=&quot;https://abrazol.com/books/rhythm1/&quot;&gt;excellent little book&lt;/a&gt; called &amp;ldquo;Creating Rhythms&amp;rdquo; that has been turned into &lt;a href=&quot;https://abrazol.com/books/rhythm1/software.html&quot;&gt;C, Perl, and Python&lt;/a&gt;. It features a number of algorithms that produce or modify lists of numbers or bit-vectors (of ones and zeroes). These can be beat onsets (the ones) and rests (the zeroes) of a rhythm. We&amp;rsquo;ll check out these concepts with Perl.For each example, we&amp;rsquo;ll save the MIDI with the &lt;a href=&quot;https://metacpan.org/pod/MIDI::Util&quot;&gt;MIDI::Util&lt;/a&gt; module. Also, in order to actually &lt;em&gt;hear&lt;/em&gt; the rhythms, we will need a MIDI synthesizer. For these illustrations, &lt;a href=&quot;https://www.fluidsynth.org/&quot;&gt;fluidsynth&lt;/a&gt; will work. Of course, any MIDI capable synth will do! I often control my eurorack analog synthesizer with code (and a MIDI interface module).Here&amp;rsquo;s how I start &lt;code&gt;fluidsynth&lt;/code&gt; on my mac in the terminal, in a &lt;em&gt;separate&lt;/em&gt; session. It uses a generic soundfont file (&lt;code&gt;sf2&lt;/code&gt;) that can be downloaded &lt;a href=&quot;https://keymusician01.s3.amazonaws.com/FluidR3_GM.zip&quot;&gt;here&lt;/a&gt; (124MB zip).&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot; style=&quot;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;fluidsynth -a coreaudio -m coremidi -g 2.0 ~/Music/soundfont/FluidR3_GM.sf2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;So, how does Perl know what output port to use? There are a few ways, but with &lt;a href=&quot;https://metacpan.org/author/JBARRETT&quot;&gt;JBARRETT&lt;/a&gt;&amp;rsquo;s &lt;a href=&quot;https://metacpan.org/pod/MIDI::RtMidi::FFI::Device&quot;&gt;MIDI::RtMidi::FFI::Device&lt;/a&gt;, you can do this:&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot; style=&quot;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&quot;&gt;&lt;code class=&quot;language-perl&quot; data-lang=&quot;perl&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;use&lt;/span&gt; MIDI::RtMidi::FFI::Device ();&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; RtMidiIn&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;new&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; RtMidiOut&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;new&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;print&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;Input devices:\n&amp;#34;&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;print_ports;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;print&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;\n&amp;#34;&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;print&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;Output devices:\n&amp;#34;&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;print_ports;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;print&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;\n&amp;#34;&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;This shows that &lt;code&gt;fluidsynth&lt;/code&gt; is alive and ready for interaction.Okay, on with the show!First-up, let&amp;rsquo;s look at partition algorithms. With the &lt;code&gt;part()&lt;/code&gt; function, we can generate all partitions of &lt;code&gt;n&lt;/code&gt;, where &lt;code&gt;n&lt;/code&gt; is &lt;code&gt;5&lt;/code&gt;, and the &amp;ldquo;parts&amp;rdquo; all add up to &lt;code&gt;5&lt;/code&gt;. Then taking one of these (say, the third element), we convert it to a binary sequence that can be interpreted as a rhythmic phrase, and play it 4 times.&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot; style=&quot;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&quot;&gt;&lt;code class=&quot;language-perl&quot; data-lang=&quot;perl&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#75715e&quot;&gt;#!/usr/bin/env perl&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;use&lt;/span&gt; strict;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;use&lt;/span&gt; warnings;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;use&lt;/span&gt; Music::CreatingRhythms ();&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; Music::CreatingRhythms&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;new&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;part(&lt;span style=&quot;color:#ae81ff&quot;&gt;5&lt;/span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#75715e&quot;&gt;# [ [ 1, 1, 1, 1, 1 ], [ 1, 1, 1, 2 ], [ 1, 2, 2 ], [ 1, 1, 3 ], [ 2, 3 ], [ 1, 4 ], [ 5 ] ]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt; $p &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;[&lt;span style=&quot;color:#ae81ff&quot;&gt;2&lt;/span&gt;]; &lt;span style=&quot;color:#75715e&quot;&gt;# [ 1, 2, 2 ]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;int2b([$p]); &lt;span style=&quot;color:#75715e&quot;&gt;# [ [ 1, 1, 0, 1, 0 ] ]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;Now we render and save the rhythm:&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot; style=&quot;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&quot;&gt;&lt;code class=&quot;language-perl&quot; data-lang=&quot;perl&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;use&lt;/span&gt; MIDI::Util &lt;span style=&quot;color:#e6db74&quot;&gt;qw(setup_score)&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; setup_score(bpm &lt;span style=&quot;color:#f92672&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;120&lt;/span&gt;, channel &lt;span style=&quot;color:#f92672&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;9&lt;/span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;for&lt;/span&gt; (&lt;span style=&quot;color:#ae81ff&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;..&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;4&lt;/span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    &lt;span style=&quot;color:#66d9ef&quot;&gt;for&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  (&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;[&lt;span style=&quot;color:#ae81ff&quot;&gt;0&lt;/span&gt;]&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;@&lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;*&lt;/span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        &lt;span style=&quot;color:#66d9ef&quot;&gt;if&lt;/span&gt; () {&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;            &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;n(&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;en&amp;#39;&lt;/span&gt;, &lt;span style=&quot;color:#ae81ff&quot;&gt;40&lt;/span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        &lt;span style=&quot;color:#66d9ef&quot;&gt;else&lt;/span&gt; {&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;            &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;r(&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;en&amp;#39;&lt;/span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;write_score(&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;perldotcom-1.mid&amp;#39;&lt;/span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;In order to play the MIDI file that is produced, we can use &lt;code&gt;fluidsynth&lt;/code&gt; like this:&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot; style=&quot;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;fluidsynth -i ~/Music/soundfont/FluidR3_GM.sf2 perldotcom-1.mid&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;audio controls&gt;  &lt;source src=&quot;https://www.perl.com/media/musical-rhythms-with-math-in-perl/perldotcom-1.mp3&quot; type=&quot;audio/mpeg&quot;&gt;  Your browser does not support the audio element.&lt;/audio&gt;Not terribly exciting yet.Let&amp;rsquo;s see what the &amp;ldquo;compositions&amp;rdquo; of a number reveal. According to the &lt;a href=&quot;https://metacpan.org/pod/Music::CreatingRhythms&quot;&gt;Music::CreatingRhythms&lt;/a&gt; docs, a composition of a number is &amp;ldquo;the set of combinatorial variations of the partitions of &lt;code&gt;n&lt;/code&gt; with the duplicates removed.&amp;rdquo;Okay. Well, the 7 partitions of &lt;code&gt;5&lt;/code&gt; are:&lt;pre tabindex=&quot;0&quot;&gt;&lt;code&gt;[[1, 1, 1, 1, 1], [1, 1, 1, 2], [1, 1, 3], [1, 2, 2], [1, 4], [2, 3], [5]]&lt;/code&gt;&lt;/pre&gt;And the 16 compositions of &lt;code&gt;5&lt;/code&gt; are:&lt;pre tabindex=&quot;0&quot;&gt;&lt;code&gt;[[1, 1, 1, 1, 1], [1, 1, 1, 2], [1, 1, 2, 1], [1, 1, 3], [1, 2, 1, 1], [1, 2, 2], [1, 3, 1], [1, 4], [2, 1, 1, 1], [2, 1, 2], [2, 2, 1], [2, 3], [3, 1, 1], [3, 2], [4, 1], [5]]&lt;/code&gt;&lt;/pre&gt;That is, the list of compositions has, not only the partition &lt;code&gt;[1, 2, 2]&lt;/code&gt;, but also its variations: &lt;code&gt;[2, 1, 2]&lt;/code&gt; and &lt;code&gt;[2, 2, 1]&lt;/code&gt;. Same with the other partitions. Selections from this list will produce possibly cool rhythms.Here are the compositions of &lt;code&gt;5&lt;/code&gt; turned into sequences, played by a snare drum, and written to the disk:&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot; style=&quot;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&quot;&gt;&lt;code class=&quot;language-perl&quot; data-lang=&quot;perl&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;use&lt;/span&gt; Music::CreatingRhythms ();&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;use&lt;/span&gt; MIDI::Util &lt;span style=&quot;color:#e6db74&quot;&gt;qw(setup_score)&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; Music::CreatingRhythms&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;new&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;compm(&lt;span style=&quot;color:#ae81ff&quot;&gt;5&lt;/span&gt;, &lt;span style=&quot;color:#ae81ff&quot;&gt;3&lt;/span&gt;); &lt;span style=&quot;color:#75715e&quot;&gt;# compositions of 5 with 3 elements&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;int2b();&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; setup_score(bpm &lt;span style=&quot;color:#f92672&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;120&lt;/span&gt;, channel &lt;span style=&quot;color:#f92672&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;9&lt;/span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;for&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  (&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;@&lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;*&lt;/span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    &lt;span style=&quot;color:#66d9ef&quot;&gt;for&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  (@) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        &lt;span style=&quot;color:#66d9ef&quot;&gt;if&lt;/span&gt; () {&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;            &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;n(&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;en&amp;#39;&lt;/span&gt;, &lt;span style=&quot;color:#ae81ff&quot;&gt;40&lt;/span&gt;); &lt;span style=&quot;color:#75715e&quot;&gt;# snare patch&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        &lt;span style=&quot;color:#66d9ef&quot;&gt;else&lt;/span&gt; {&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;            &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;r(&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;en&amp;#39;&lt;/span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;write_score(&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;perldotcom-2.mid&amp;#39;&lt;/span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;audio controls&gt;  &lt;source src=&quot;https://www.perl.com/media/musical-rhythms-with-math-in-perl/perldotcom-2.mp3&quot; type=&quot;audio/mpeg&quot;&gt;  Your browser does not support the audio element.&lt;/audio&gt;A little better. Like a syncopated snare solo.&lt;h2 id=&quot;sidebar&quot;&gt;Sidebar&lt;/h2&gt;Another way to play the MIDI file is to use &lt;a href=&quot;https://wiki.archlinux.org/title/Timidity++&quot;&gt;timidity&lt;/a&gt;. On my mac, with the soundfont specified in the &lt;code&gt;timidity.cfg&lt;/code&gt; configuration file, this would be:&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot; style=&quot;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;timidity -c ~/timidity.cfg -Od perldotcom-2.mid&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;To convert a MIDI file to an mp3 (or other audio formats), I do this:&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot; style=&quot;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&quot;&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;timidity -c ~/timidity.cfg perldotcom-2.mid -Ow -o - | ffmpeg -i - -acodec libmp3lame -ab 64k perldotcom-2.mp3&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;Okay. Enough technical details! What if we want a kick bass drum and hi-hat cymbals, too? Refactor time&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot; style=&quot;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&quot;&gt;&lt;code class=&quot;language-perl&quot; data-lang=&quot;perl&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;use&lt;/span&gt; MIDI::Util &lt;span style=&quot;color:#e6db74&quot;&gt;qw(setup_score)&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;use&lt;/span&gt; Music::CreatingRhythms ();&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; Music::CreatingRhythms&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;new&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;compm(&lt;span style=&quot;color:#ae81ff&quot;&gt;4&lt;/span&gt;, &lt;span style=&quot;color:#ae81ff&quot;&gt;2&lt;/span&gt;); &lt;span style=&quot;color:#75715e&quot;&gt;# snare&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;int2b();&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;compm(&lt;span style=&quot;color:#ae81ff&quot;&gt;4&lt;/span&gt;, &lt;span style=&quot;color:#ae81ff&quot;&gt;3&lt;/span&gt;); &lt;span style=&quot;color:#75715e&quot;&gt;# kick&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;int2b();&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; setup_score(bpm &lt;span style=&quot;color:#f92672&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;120&lt;/span&gt;, channel &lt;span style=&quot;color:#f92672&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;9&lt;/span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;for&lt;/span&gt; (&lt;span style=&quot;color:#ae81ff&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;..&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;8&lt;/span&gt;) { &lt;span style=&quot;color:#75715e&quot;&gt;# repeats&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    &lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;[ int rand @ ];&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    &lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;[ int rand @ ];&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    &lt;span style=&quot;color:#66d9ef&quot;&gt;for&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt; $i (&lt;span style=&quot;color:#ae81ff&quot;&gt;0&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;..&lt;/span&gt; $#) { &lt;span style=&quot;color:#75715e&quot;&gt;# pattern position&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        &lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt; @notes &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; (&lt;span style=&quot;color:#ae81ff&quot;&gt;42&lt;/span&gt;); &lt;span style=&quot;color:#75715e&quot;&gt;# hi-hat every time&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        &lt;span style=&quot;color:#66d9ef&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;[$i]) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;            push @notes, &lt;span style=&quot;color:#ae81ff&quot;&gt;40&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        &lt;span style=&quot;color:#66d9ef&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;[$i]) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;            push @notes, &lt;span style=&quot;color:#ae81ff&quot;&gt;36&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;n(&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;en&amp;#39;&lt;/span&gt;, @notes);&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;write_score(&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;perldotcom-3.mid&amp;#39;&lt;/span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;audio controls&gt;  &lt;source src=&quot;https://www.perl.com/media/musical-rhythms-with-math-in-perl/perldotcom-3.mp3&quot; type=&quot;audio/mpeg&quot;&gt;  Your browser does not support the audio element.&lt;/audio&gt;Here we play generated kick and snare patterns, along with a steady hi-hat.Next up, let&amp;rsquo;s look at rhythmic &amp;ldquo;necklaces.&amp;rdquo; Here we find many grooves of the world.&lt;img height=400 width=500 src=&quot;https://www.perl.com/images/musical-rhythms-with-math-in-perl/rhythm-necklaces.png&quot; alt=&quot;World rhythms&quot;&gt;Image from &lt;a href=&quot;https://cgm.cs.mcgill.ca/~godfried/publications/geometry-of-rhythm.pdf&quot;&gt;The Geometry of Musical Rhythm&lt;/a&gt;Rhythm necklaces are circular diagrams of equally spaced, connected nodes. A necklace is a lexicographical ordering with no rotational duplicates. For instance, the necklaces of &lt;code&gt;3&lt;/code&gt; beats are &lt;code&gt;[[1, 1, 1], [1, 1, 0], [1, 0, 0], [0, 0, 0]]&lt;/code&gt;. Notice that there is no &lt;code&gt;[1, 0, 1]&lt;/code&gt; or &lt;code&gt;[0, 1, 1]&lt;/code&gt;. Also, there are no rotated versions of &lt;code&gt;[1, 0, 0]&lt;/code&gt;, either.So, how many 16 beat rhythm necklaces are there?&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot; style=&quot;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&quot;&gt;&lt;code class=&quot;language-perl&quot; data-lang=&quot;perl&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;neck(&lt;span style=&quot;color:#ae81ff&quot;&gt;16&lt;/span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;print&lt;/span&gt; scalar @, &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;\n&amp;#34;&lt;/span&gt;; &lt;span style=&quot;color:#75715e&quot;&gt;# 4116 of &amp;#39;em!&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;Okay. Let&amp;rsquo;s generate necklaces of &lt;code&gt;8&lt;/code&gt; instead, pull a random choice, and play the pattern with a percussion instrument.&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot; style=&quot;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&quot;&gt;&lt;code class=&quot;language-perl&quot; data-lang=&quot;perl&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;use&lt;/span&gt; MIDI::Util &lt;span style=&quot;color:#e6db74&quot;&gt;qw(setup_score)&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;use&lt;/span&gt; Music::CreatingRhythms ();&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; shift &lt;span style=&quot;color:#f92672&quot;&gt;||&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;75&lt;/span&gt;; &lt;span style=&quot;color:#75715e&quot;&gt;# claves&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; Music::CreatingRhythms&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;new&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;neck(&lt;span style=&quot;color:#ae81ff&quot;&gt;8&lt;/span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;[ int rand @ ];&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; setup_score(bpm &lt;span style=&quot;color:#f92672&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;120&lt;/span&gt;, channel &lt;span style=&quot;color:#f92672&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;9&lt;/span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;for&lt;/span&gt; (&lt;span style=&quot;color:#ae81ff&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;..&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;4&lt;/span&gt;) { &lt;span style=&quot;color:#75715e&quot;&gt;# repeats&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    &lt;span style=&quot;color:#66d9ef&quot;&gt;for&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  (@) { &lt;span style=&quot;color:#75715e&quot;&gt;# pattern position&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        &lt;span style=&quot;color:#66d9ef&quot;&gt;if&lt;/span&gt; () {&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;            &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;n(&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;en&amp;#39;&lt;/span&gt;, );&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        &lt;span style=&quot;color:#66d9ef&quot;&gt;else&lt;/span&gt; {&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;            &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;r(&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;en&amp;#39;&lt;/span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;write_score(&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;perldotcom-4.mid&amp;#39;&lt;/span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;audio controls&gt;  &lt;source src=&quot;https://www.perl.com/media/musical-rhythms-with-math-in-perl/perldotcom-4.mp3&quot; type=&quot;audio/mpeg&quot;&gt;  Your browser does not support the audio element.&lt;/audio&gt;Here we choose from &lt;strong&gt;all&lt;/strong&gt; necklaces. But note that this also includes the sequence with all ones and the sequence with all zeroes. More sophisticated code might skip these.More interesting would be playing simultaneous beats.&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot; style=&quot;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&quot;&gt;&lt;code class=&quot;language-perl&quot; data-lang=&quot;perl&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;use&lt;/span&gt; MIDI::Util &lt;span style=&quot;color:#e6db74&quot;&gt;qw(setup_score)&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;use&lt;/span&gt; Music::CreatingRhythms ();&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; Music::CreatingRhythms&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;new&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;neck(&lt;span style=&quot;color:#ae81ff&quot;&gt;8&lt;/span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;[ int rand @ ];&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;[ int rand @ ];&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;[ int rand @ ];&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; setup_score(bpm &lt;span style=&quot;color:#f92672&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;120&lt;/span&gt;, channel &lt;span style=&quot;color:#f92672&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;9&lt;/span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;for&lt;/span&gt; (&lt;span style=&quot;color:#ae81ff&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;..&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;4&lt;/span&gt;) { &lt;span style=&quot;color:#75715e&quot;&gt;# repeats&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    &lt;span style=&quot;color:#66d9ef&quot;&gt;for&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt; $i (&lt;span style=&quot;color:#ae81ff&quot;&gt;0&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;..&lt;/span&gt; $#) { &lt;span style=&quot;color:#75715e&quot;&gt;# pattern position&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        &lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt; @notes;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        &lt;span style=&quot;color:#66d9ef&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;[$i]) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;            push @notes, &lt;span style=&quot;color:#ae81ff&quot;&gt;75&lt;/span&gt;; &lt;span style=&quot;color:#75715e&quot;&gt;# claves&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        &lt;span style=&quot;color:#66d9ef&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;[$i]) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;            push @notes, &lt;span style=&quot;color:#ae81ff&quot;&gt;63&lt;/span&gt;; &lt;span style=&quot;color:#75715e&quot;&gt;# hi_conga&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        &lt;span style=&quot;color:#66d9ef&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;[$i]) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;            push @notes, &lt;span style=&quot;color:#ae81ff&quot;&gt;64&lt;/span&gt;; &lt;span style=&quot;color:#75715e&quot;&gt;# low_conga&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;n(&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;en&amp;#39;&lt;/span&gt;, @notes);&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;write_score(&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;perldotcom-5.mid&amp;#39;&lt;/span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;And that sounds like:&lt;audio controls&gt;  &lt;source src=&quot;https://www.perl.com/media/musical-rhythms-with-math-in-perl/perldotcom-5.mp3&quot; type=&quot;audio/mpeg&quot;&gt;  Your browser does not support the audio element.&lt;/audio&gt;How about Euclidean patterns? What are they, and why are they named for a geometer?Euclidean patterns are a set number of positions &lt;code&gt;P&lt;/code&gt; that are filled with a number of beats &lt;code&gt;Q&lt;/code&gt; that is less than or equal to &lt;code&gt;P&lt;/code&gt;. They are named for Euclid because they are generated by applying the &amp;ldquo;Euclidean algorithm,&amp;rdquo; which was originally designed to find the greatest common divisor (GCD) of two numbers, to distribute musical beats as evenly as possible.&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot; style=&quot;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&quot;&gt;&lt;code class=&quot;language-perl&quot; data-lang=&quot;perl&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;use&lt;/span&gt; MIDI::Util &lt;span style=&quot;color:#e6db74&quot;&gt;qw(setup_score)&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;use&lt;/span&gt; Music::CreatingRhythms ();&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; Music::CreatingRhythms&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;new&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;16&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;rotate_n(&lt;span style=&quot;color:#ae81ff&quot;&gt;4&lt;/span&gt;, &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;euclid(&lt;span style=&quot;color:#ae81ff&quot;&gt;2&lt;/span&gt;, )); &lt;span style=&quot;color:#75715e&quot;&gt;# snare&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;euclid(&lt;span style=&quot;color:#ae81ff&quot;&gt;2&lt;/span&gt;, ); &lt;span style=&quot;color:#75715e&quot;&gt;# kick&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;euclid(&lt;span style=&quot;color:#ae81ff&quot;&gt;11&lt;/span&gt;, ); &lt;span style=&quot;color:#75715e&quot;&gt;# hi-hats&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; setup_score(bpm &lt;span style=&quot;color:#f92672&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;120&lt;/span&gt;, channel &lt;span style=&quot;color:#f92672&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;9&lt;/span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;for&lt;/span&gt; (&lt;span style=&quot;color:#ae81ff&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;..&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;4&lt;/span&gt;) { &lt;span style=&quot;color:#75715e&quot;&gt;# repeats&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    &lt;span style=&quot;color:#66d9ef&quot;&gt;for&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt; $i (&lt;span style=&quot;color:#ae81ff&quot;&gt;0&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;..&lt;/span&gt;  &lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;1&lt;/span&gt;) { &lt;span style=&quot;color:#75715e&quot;&gt;# pattern position&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        &lt;span style=&quot;color:#66d9ef&quot;&gt;my&lt;/span&gt; @notes;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        &lt;span style=&quot;color:#66d9ef&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;[$i]) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;            push @notes, &lt;span style=&quot;color:#ae81ff&quot;&gt;40&lt;/span&gt;; &lt;span style=&quot;color:#75715e&quot;&gt;# snare&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        &lt;span style=&quot;color:#66d9ef&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;[$i]) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;            push @notes, &lt;span style=&quot;color:#ae81ff&quot;&gt;36&lt;/span&gt;; &lt;span style=&quot;color:#75715e&quot;&gt;# kick&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        &lt;span style=&quot;color:#66d9ef&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;[$i]) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;            push @notes, &lt;span style=&quot;color:#ae81ff&quot;&gt;42&lt;/span&gt;; &lt;span style=&quot;color:#75715e&quot;&gt;# hi-hats&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        &lt;span style=&quot;color:#66d9ef&quot;&gt;if&lt;/span&gt; (@notes) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;            &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;n(&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;en&amp;#39;&lt;/span&gt;, @notes);&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        &lt;span style=&quot;color:#66d9ef&quot;&gt;else&lt;/span&gt; {&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;            &lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;r(&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;en&amp;#39;&lt;/span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&amp;gt;&lt;/span&gt;write_score(&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#39;perldotcom-6.mid&amp;#39;&lt;/span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;audio controls&gt;  &lt;source src=&quot;https://www.perl.com/media/musical-rhythms-with-math-in-perl/perldotcom-6.mp3&quot; type=&quot;audio/mpeg&quot;&gt;  Your browser does not support the audio element.&lt;/audio&gt;Now we&amp;rsquo;re talkin&amp;rsquo; - an actual drum groove! To reiterate, the &lt;code&gt;euclid()&lt;/code&gt; method distributes a number of beats, like &lt;code&gt;2&lt;/code&gt; or &lt;code&gt;11&lt;/code&gt;, over the number of beats, &lt;code&gt;16&lt;/code&gt;. The kick and snare use the same arguments, but the snare pattern is rotated by 4 beats, so that they alternate.&lt;h2 id=&quot;so-what-have-we-learned-today&quot;&gt;So what have we learned today?&lt;/h2&gt;&lt;ol&gt;&lt;li&gt;That you can use mathematical functions to generate sequences to represent rhythmic patterns.&lt;/li&gt;&lt;li&gt;That you can play an entire sequence or simultaneous notes with MIDI.&lt;/li&gt;&lt;/ol&gt;&lt;h2 id=&quot;references&quot;&gt;References:&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://github.com/ology/Music/tree/master/mrwmip/&quot;&gt;Article repository&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://abrazol.com/books/rhythm1/&quot;&gt;Creating Rhythms book&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://metacpan.org/pod/MIDI::RtMidi::FFI::Device&quot;&gt;MIDI::RtMidi::FFI::Device&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://metacpan.org/pod/MIDI::Util&quot;&gt;MIDI::Util&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://metacpan.org/pod/Music::CreatingRhythms&quot;&gt;Music::CreatingRhythms&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.fluidsynth.org/&quot;&gt;fluidsynth&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://wiki.archlinux.org/title/Timidity++&quot;&gt;timidity&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Read more &lt;a class=&quot;sw_sl&quot; href=&quot;https://www.perl.com/article/musical-rhythms-with-math-in-perl/&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;</description>
  </item>
  <item>
    <title>Fastmail Donates USD 10,000 to The Perl and Raku Foundation</title>
    <link>http://www.jamesraposa.com/index/2026/02/05#auto___fastmail_donates_usd_10_000_to_the_perl_and_raku_foundation</link>
    <description>Furnished content.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;2025 was a tough year for &lt;a href=&quot;https://perlfoundation.org/&quot;&gt;The Perl and Raku Foundation&lt;/a&gt; (TPRF). Funds were sorely needed. The community grants program had been paused due to budget constraints and we were in danger of needing to pause the Perl 5 core maintenance grants. &lt;a href=&quot;https://www.fastmail.com/&quot;&gt;Fastmail&lt;/a&gt; stepped up with a USD 10,000 donation and helped TPRF to continue to support Perl 5 core maintenance. Ricardo Signes explains why Fastmail helped keep this very important work on track.&lt;blockquote&gt;Perl has served us quite well since Fastmail&amp;rsquo;s inception.  We&amp;rsquo;ve built up a large code base that has continued to work, grow, and improve over twenty years.  We&amp;rsquo;ve stuck with Perl because Perl stuck with us:  it kept working and growing and improving, and very rarely did those improvements require us to stop the world and adapt to onerous changes.  We know that kind of stability is, in part, a function of the developers of Perl, whose time is spent figuring out how to make Perl better without also making it worse.  The money we give toward those efforts is well-spent, because it keeps the improvements coming and the language reliable. Ricardo Signes, Director &amp;amp; Chief Developer Experience Officer, Fastmail&lt;/blockquote&gt;One of the reasons that you don&amp;rsquo;t hear about Perl in the headlines is its reliability. Upgrading your Perl from one version to the next? That can be a very boring deployment. You code worked before and it continues to &amp;ldquo;just work&amp;rdquo; after the upgrade. You don&amp;rsquo;t need to rant about short deprecation cycles, performance degradation or dependencies which no longer install. The Perl 5 core maintainers take great care to ensure that you don&amp;rsquo;t have to care very much about upgrading your Perl. Backwards compatibility is top of mind. If your deployment is boring, it&amp;rsquo;s because a lot of care and attention has been given to this matter by the people who love Perl and love to work on it.As we moved to secure TPRF&amp;rsquo;s 2025 budget, we reached out to organizations which rely on Perl. A number of these companies immediately offered to help. Fastmail has already been a supporter of TPRF for quite some time. In addition to this much needed donation, Fastmail has been providing rock solid free email hosting to the foundation for many years.While Fastmail&amp;rsquo;s donation has been allocated towards Perl 5 Core maintenance, TPRF is now in the position to re-open &lt;a href=&quot;https://perlfoundation.org/grants.html&quot;&gt;the community grants program&lt;/a&gt;, funding it with USD 10,000 for 2026. There is also an opportunity to increase the community grants funding if sponsor participation increases. As we begin our 2026 fundraising, we are looking to cast a wider net and bring more sponsor organizations on board to help support healthy Perl and Raku ecosystems.Maybe your organization will be the one to help us double our community grants budget in 2026. To &lt;a href=&quot;https://perlfoundation.org/how-do-sponsors-benefit.html&quot;&gt;become a sponsor&lt;/a&gt;, contact:&lt;a href=&quot;mailto:olaf@perlfoundation.org&quot;&gt;olaf@perlfoundation.org&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Read more &lt;a class=&quot;sw_sl&quot; href=&quot;https://www.perl.com/article/fastmail-donates-usd-10-000-to-the-perl-and-raku-foundation/&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;</description>
  </item>
  <item>
    <title>Cast-Iron Community: Your Chance to Sponsor TPRC 2026</title>
    <link>http://www.jamesraposa.com/index/2026/02/04#auto___cast_iron_community__your_chance_to_sponsor_tprc_2026</link>
    <description>Furnished content.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;ldquo;Perl is my cast-iron pan - reliable, versatile, durable, and continues to beever so useful.&amp;rdquo; &lt;a href=&quot;https://tprc.us/tprc-2026-gsp/&quot;&gt;TPRC 2026&lt;/a&gt; brings together acommunity that embodies all of these qualities, and we&amp;rsquo;re looking for sponsorsto help make this special gathering possible.&lt;h3 id=&quot;about-the-conference&quot;&gt;About the Conference&lt;/h3&gt;&lt;a href=&quot;https://tprc.us/tprc-2026-gsp/&quot;&gt;The Perl and Raku Conference 2026&lt;/a&gt; is acommunity-organized gathering of developers, enthusiasts, and industryprofessionals. It takes place from June 26-28, 2026, in Greenville, South Carolina.The conference will feature an intimate, single-track format that promises high sponsor visibility.We look forward to approximately 80 participants with some of those staying in town for the shoulder days (June 25-29) and a Mondayworkshop.&lt;h3 id=&quot;why-sponsor&quot;&gt;Why Sponsor?&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;Give back to the language and communities which have already given so much to you&lt;/li&gt;&lt;li&gt;Connect with the developers and craftspeople who build your tools &amp;ndash; the ones that are built to last&lt;/li&gt;&lt;li&gt;Help to ensure that The Perl and Raku Foundation can continue to fund Perl 5 core maintenance and Community Grants&lt;/li&gt;&lt;/ul&gt;&lt;h3 id=&quot;sponsorship-tiers&quot;&gt;Sponsorship Tiers&lt;/h3&gt;&lt;h4 id=&quot;platinum-sponsor-6000&quot;&gt;Platinum Sponsor ($6,000)&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;Only 1 sponsorship is available at this level&lt;/li&gt;&lt;li&gt;Premium logo placement on conference website&lt;/li&gt;&lt;li&gt;This donation qualifies your organization to be a Bronze Level Sponsor of The Perl and Raku Foundation&lt;/li&gt;&lt;li&gt;5-minute speaking slot during opening ceremony&lt;/li&gt;&lt;li&gt;2 complimentary conference passes&lt;/li&gt;&lt;li&gt;Priority choice of rollup banner placement&lt;/li&gt;&lt;li&gt;Logo prominently displayed on conference badges&lt;/li&gt;&lt;li&gt;First choice of major named sponsorship (Conference Dinner, T-shirts, or Swag Bags)&lt;/li&gt;&lt;li&gt;Logo on main stage backdrop and conference banners&lt;/li&gt;&lt;li&gt;Social media promotion&lt;/li&gt;&lt;li&gt;All benefits of lower tiers&lt;/li&gt;&lt;/ul&gt;&lt;h4 id=&quot;gold-sponsor-4000&quot;&gt;Gold Sponsor ($4,000)&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;Logo on all conference materials&lt;/li&gt;&lt;li&gt;One complimentary conference pass&lt;/li&gt;&lt;li&gt;Rollup banner on display&lt;/li&gt;&lt;li&gt;Choice of named sponsorship (Lunch or Snacks)&lt;/li&gt;&lt;li&gt;Logo on backdrop and banners&lt;/li&gt;&lt;li&gt;Dedicated social media recognition&lt;/li&gt;&lt;li&gt;All benefits of lower tiers&lt;/li&gt;&lt;/ul&gt;&lt;h4 id=&quot;silver-sponsor-2000&quot;&gt;Silver Sponsor ($2,000)&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;Logo on conference website&lt;/li&gt;&lt;li&gt;Logo on backdrop and banners&lt;/li&gt;&lt;li&gt;Choice of smaller named sponsorship (Beverage Bars)&lt;/li&gt;&lt;li&gt;Social media mention&lt;/li&gt;&lt;li&gt;All benefits of lower tier&lt;/li&gt;&lt;/ul&gt;&lt;h4 id=&quot;bronze-sponsor-1000&quot;&gt;Bronze Sponsor ($1,000)&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;Name/logo on conference website&lt;/li&gt;&lt;li&gt;Name/logo on backdrop and banners&lt;/li&gt;&lt;/ul&gt;&lt;h3 id=&quot;all-sponsors-receive&quot;&gt;All Sponsors Receive&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;Logo/name in Update::Daily conference newsletter sidebar&lt;/li&gt;&lt;li&gt;Opportunity to provide materials for conference swag bags&lt;/li&gt;&lt;li&gt;Recognition during opening and closing ceremonies&lt;/li&gt;&lt;li&gt;Listed on conference website sponsor page&lt;/li&gt;&lt;li&gt;Mentioned in conference social media&lt;/li&gt;&lt;/ul&gt;&lt;h3 id=&quot;named-sponsorship-opportunities&quot;&gt;Named Sponsorship Opportunities&lt;/h3&gt;Exclusive naming rights available for:&lt;ul&gt;&lt;li&gt;Conference Dinner ($2,000) - Signage on tables and buffet&lt;/li&gt;&lt;li&gt;Conference Swag Bags ($1,500) - Logo on bags&lt;/li&gt;&lt;li&gt;Conference T-Shirts ($1,500) - Logo on sleeve&lt;/li&gt;&lt;li&gt;Lunches ($1,500) - Signage at pickup and on menu tickets&lt;/li&gt;&lt;li&gt;Snacks ($1,000) - Signage at snack bar&lt;/li&gt;&lt;li&gt;Update::Daily Printing ($200) - Logo on masthead&lt;/li&gt;&lt;/ul&gt;&lt;h3 id=&quot;about-the-perl-and-raku-foundation&quot;&gt;About The Perl and Raku Foundation&lt;/h3&gt;Proceeds beyond conference expenses support The Perl and Raku Foundation, a non-profit organization dedicated to advancing the Perl and Raku programming languages through open source development, education, and community building.&lt;h3 id=&quot;contact-information&quot;&gt;Contact Information&lt;/h3&gt;For more information on how to become a sponsor, please contact:&lt;a href=&quot;mailto:olaf@perlfoundation.org&quot;&gt;olaf@perlfoundation.org&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Read more &lt;a class=&quot;sw_sl&quot; href=&quot;https://www.perl.com/article/cast-iron-community-your-chance-to-sponsor-tprc-2026/&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;</description>
  </item>
  <item>
    <title>Podlite comes to Perl: a lightweight block-based markup language for everyday use</title>
    <link>http://www.jamesraposa.com/index/2026/01/28#auto___podlite_comes_to_perl__a_lightweight_block_based_markup_language_for_everyday_use</link>
    <description>Furnished content.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;My name is Alex. Over the last years I've implemented several versions of the Raku&amp;rsquo;s documentation format (Synopsys 26 / Raku&amp;rsquo;s Pod) in Perl and JavaScript.At an early stage, I shared the idea of creating a lightweight version of Raku&amp;rsquo;s Pod, with Damian Conway, the original author of the Synopsys 26 Documentation specification (S26).He was supportive of the concept and offered several valuable insights that helped shape the vision of what later became Podlite.Today, Podlite is a small block-based markup language that is easy to read as plain text, simple to parse, and flexible enough to be used everywhere  in code, notes, technical documents, long-form writing, and even full documentation systems.This article is an introduction for the Perl community  what Podlite is, how it looks, how you can already use it in Perl via a source filter, and what's coming next.&lt;h2 id=&quot;the-block-structure-of-podlite&quot;&gt;The Block Structure of Podlite&lt;/h2&gt;One of the core ideas behind Podlite is its consistent block-based structure.Every meaningful element of a document  a heading, a paragraph, a list item, a table, a code block, a callout  is represented as a block. This makes documents both readable for humans and predictable for tools.Podlite supports three interchangeable block styles: &lt;code&gt;delimited&lt;/code&gt;, &lt;code&gt;paragraph&lt;/code&gt;, and &lt;code&gt;abbreviated&lt;/code&gt;.&lt;h3 id=&quot;abbreviated-blocks-block&quot;&gt;Abbreviated blocks (&lt;code&gt;=BLOCK&lt;/code&gt;)&lt;/h3&gt;This is the most compact form.A block starts with &lt;code&gt;=&lt;/code&gt; followed by the block name.&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot; style=&quot;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&quot;&gt;&lt;code class=&quot;language-perl&quot; data-lang=&quot;perl&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt;head1 Installation Guide&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt;item Perl &lt;span style=&quot;color:#ae81ff&quot;&gt;5.8&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;or&lt;/span&gt; newer&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt;para This tool automates the process&lt;span style=&quot;color:#f92672&quot;&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;ends on the next directive or a blank line&lt;/li&gt;&lt;li&gt;best used for simple one-line blocks&lt;/li&gt;&lt;li&gt;cannot include configuration options (attributes)&lt;/li&gt;&lt;/ul&gt;&lt;h3 id=&quot;paragraph-blocks-for-block&quot;&gt;Paragraph blocks (&lt;code&gt;=for BLOCK&lt;/code&gt;)&lt;/h3&gt;Use this form when you want a multi-line block or need attributes.&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot; style=&quot;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&quot;&gt;&lt;code class=&quot;language-perl&quot; data-lang=&quot;perl&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;for&lt;/span&gt; code :lang&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;lt;perl&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;say &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;Hello from Podlite!&amp;#34;&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;ends when a blank line appears&lt;/li&gt;&lt;li&gt;can include complex content&lt;/li&gt;&lt;li&gt;allows attributes such as &lt;code&gt;:lang&lt;/code&gt;, &lt;code&gt;:id&lt;/code&gt;, &lt;code&gt;:caption&lt;/code&gt;, &lt;code&gt;:nested&lt;/code&gt;, &lt;/li&gt;&lt;/ul&gt;&lt;h3 id=&quot;delimited-blocks-begin-block--end-block&quot;&gt;Delimited blocks (&lt;code&gt;=begin BLOCK&lt;/code&gt;  &lt;code&gt;=end BLOCK&lt;/code&gt;)&lt;/h3&gt;The most expressive form. Useful for large sections, nested blocks, or structures that require clarity.&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot; style=&quot;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&quot;&gt;&lt;code class=&quot;language-perl&quot; data-lang=&quot;perl&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt;begin nested :notify&lt;span style=&quot;color:#e6db74&quot;&gt;&amp;lt;important&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;Make sure you have administrator privileges&lt;span style=&quot;color:#f92672&quot;&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt;end nested&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;explicit start and end markers&lt;/li&gt;&lt;li&gt;perfect for code, lists, tables, notifications, markdown, formulas&lt;/li&gt;&lt;li&gt;can contain other blocks, including nested ones&lt;/li&gt;&lt;/ul&gt;These block styles differ in syntax convenience, but all produce the same internal structure.&lt;img height=400 width=500 src=&quot;https://www.perl.com/images/podlite-comes-to-perl-a-lightweight-block-based-markup-language-for-everyday-use/podlite-blocktypes.png&quot; alt=&quot;diagram here showing the three block styles and how they map to the same internal structure&quot;&gt;Regardless of which syntax you choose:&lt;ul&gt;&lt;li&gt;all three forms represent the same &lt;strong&gt;block type&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;attributes apply the same way (&lt;code&gt;:lang&lt;/code&gt;, &lt;code&gt;:caption&lt;/code&gt;, &lt;code&gt;:id&lt;/code&gt;, )&lt;/li&gt;&lt;li&gt;tools and renderers treat them uniformly&lt;/li&gt;&lt;li&gt;nested blocks work identically&lt;/li&gt;&lt;li&gt;you can freely mix styles inside a document&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;example-comparing-pod-and-podlite&quot;&gt;Example: Comparing POD and Podlite&lt;/h2&gt;Let&amp;rsquo;s see how the same document looks in traditional POD versus Podlite:&lt;img height=400 width=500 src=&quot;https://www.perl.com/images/podlite-comes-to-perl-a-lightweight-block-based-markup-language-for-everyday-use/pod-podlite.png&quot; alt=&quot;POD vs Podlite&quot;&gt;Each block has clear boundaries, so you don&amp;rsquo;t need blank lines between them. This makes your documentation more compact and easier to read.This is one of the reasons Podlite remains compact yet powerful:the syntax stays flexible, while the underlying document model stays clean and consistent.This Podlite example rendered as on the following screen:&lt;img height=400 width=500 src=&quot;https://www.perl.com/images/podlite-comes-to-perl-a-lightweight-block-based-markup-language-for-everyday-use/podlite-renderexample.png&quot; alt=&quot;Podlite example&quot;&gt;&lt;h2 id=&quot;inside-the-podlite-specification-10&quot;&gt;Inside the Podlite Specification 1.0&lt;/h2&gt;One important point about Podlite is that it is first and foremost a specification.It does not belong to any particular programming language, platform, or tooling ecosystem.The specification defines the document model, syntax rules, and semantics.From the Podlite 1.0 specification, notable features include:&lt;ul&gt;&lt;li&gt;headings (&lt;code&gt;=head1&lt;/code&gt;, &lt;code&gt;=head2&lt;/code&gt;, )&lt;/li&gt;&lt;li&gt;lists and definition lists, and including task lists&lt;/li&gt;&lt;li&gt;tables (simple and advanced)&lt;/li&gt;&lt;li&gt;CSV-backed tables&lt;/li&gt;&lt;li&gt;callouts / notifications (&lt;code&gt;=nested :notify&amp;lt;tip|warning|important|note|caution&amp;gt;&lt;/code&gt;)&lt;/li&gt;&lt;li&gt;table of contents (&lt;code&gt;=toc&lt;/code&gt;)&lt;/li&gt;&lt;li&gt;includes (&lt;code&gt;=include&lt;/code&gt;)&lt;/li&gt;&lt;li&gt;embedded data (&lt;code&gt;=data&lt;/code&gt;)&lt;/li&gt;&lt;li&gt;pictures (&lt;code&gt;=picture&lt;/code&gt; and inline &lt;code&gt;P&amp;lt;&amp;gt;&lt;/code&gt;)&lt;/li&gt;&lt;li&gt;formulas (&lt;code&gt;=formula&lt;/code&gt; and inline &lt;code&gt;F&amp;lt;&amp;gt;&lt;/code&gt;)&lt;/li&gt;&lt;li&gt;user defined blocks and markup codes&lt;/li&gt;&lt;li&gt;Markdown integration&lt;/li&gt;&lt;/ul&gt;The &lt;code&gt;=markdown&lt;/code&gt; block is part of the standard block set defined by the Podlite Specification 1.0.This means Markdown is not an add-on or optional plugin  it is a fully integrated, first-class component of the language.Markdown content becomes part of Podlite's unified document structure, and its headings merge naturally with Podlite headings inside the TOC and document outline.Below is a screenshot showing how Markdown inside Perl is rendered in the in-development VS Code extension, demonstrating both the block structure and live preview:&lt;img height=400 width=500 src=&quot;https://www.perl.com/images/podlite-comes-to-perl-a-lightweight-block-based-markup-language-for-everyday-use/podlite_for_perl.png&quot; alt=&quot;Podlite source, including =markdown block&quot;&gt;&lt;h2 id=&quot;using-podlite-in-perl-via-the-source-filter&quot;&gt;Using Podlite in Perl via the source filter&lt;/h2&gt;To make Podlite directly usable in Perl code, there is a module on CPAN:&lt;a href=&quot;https://metacpan.org/pod/Podlite&quot;&gt;Podlite&lt;/a&gt;   Use Podlite markup language in Perl programsA minimal example could look like this:&lt;div class=&quot;highlight&quot;&gt;&lt;pre tabindex=&quot;0&quot; style=&quot;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&quot;&gt;&lt;code class=&quot;language-perl&quot; data-lang=&quot;perl&quot;&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;use&lt;/span&gt; Podlite; &lt;span style=&quot;color:#75715e&quot;&gt;# enable Podlite blocks inside Perl&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt;head1 Quick Example&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt;begin markdown&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;Podlite can live inside your Perl programs&lt;span style=&quot;color:#f92672&quot;&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt;end markdown&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;print&lt;/span&gt; &lt;span style=&quot;color:#e6db74&quot;&gt;&amp;#34;Podlite active\n&amp;#34;&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&quot;roadmap-whats-next-for-podlite&quot;&gt;Roadmap: what&amp;rsquo;s next for Podlite&lt;/h2&gt;Podlite continues to grow, and the Specification 1.0 is only the beginning.Several areas are already in active development, and more will evolve with community feedback.Some of the things currently planned or in progress:&lt;ul&gt;&lt;li&gt;CLI tools&lt;ul&gt;&lt;li&gt;command-line utilities for converting Podlite to HTML, PDF, man pages, etc.&lt;/li&gt;&lt;li&gt;improve pipelines for building documentation sites from Podlite sources&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;VS Code integration&lt;/li&gt;&lt;li&gt;Ecosystem growth&lt;ul&gt;&lt;li&gt;develop comprehensive documentation and tutorials&lt;/li&gt;&lt;li&gt;community-driven block types and conventions&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;try-podlite-and-share-feedback&quot;&gt;Try Podlite and share feedback&lt;/h2&gt;If this resonates with you, I'd be very happy to hear from you:&lt;ul&gt;&lt;li&gt;ideas for useful block types&lt;/li&gt;&lt;li&gt;suggestions for tools or integrations&lt;/li&gt;&lt;li&gt;feedback on the syntax and specification&lt;/li&gt;&lt;/ul&gt;&lt;a href=&quot;https://github.com/podlite/podlite-specs/discussions&quot;&gt;https://github.com/podlite/podlite-specs/discussions&lt;/a&gt;Even small contributions  a comment, a GitHub star, or trying an early tool  help shape the future of the specification and encourage further development.Useful links:&lt;ul&gt;&lt;li&gt;CPAN: &lt;a href=&quot;https://metacpan.org/pod/Podlite&quot;&gt;https://metacpan.org/pod/Podlite&lt;/a&gt;&lt;/li&gt;&lt;li&gt;GitHub:&lt;a href=&quot;https://github.com/podlite&quot;&gt;https://github.com/podlite&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Specification&lt;ul&gt;&lt;li&gt;(HTML): &lt;a href=&quot;https://podlite.org/specification&quot;&gt;https://podlite.org/specification&lt;/a&gt;&lt;/li&gt;&lt;li&gt;source: &lt;a href=&quot;https://github.com/podlite/podlite-specs&quot;&gt;https://github.com/podlite/podlite-specs&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Project site: &lt;a href=&quot;https://podlite.org&quot;&gt;https://podlite.org&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Roadmap: &lt;a href=&quot;https://podlite.org/#Roadmap&quot;&gt;https://podlite.org/#Roadmap&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;Thanks for reading,&lt;strong&gt;Alex&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Read more &lt;a class=&quot;sw_sl&quot; href=&quot;https://www.perl.com/article/podlite-comes-to-perl-a-lightweight-block-based-markup-language-for-everyday-use/&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;</description>
  </item>
  <item>
    <title>DuckDuckGo Donates $25,000 to The Perl and Raku Foundation v2025</title>
    <link>http://www.jamesraposa.com/index/2026/01/26#auto___duckduckgo_donates__25_000_to_the_perl_and_raku_foundation_v2025</link>
    <description>Furnished content.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;For the second consecutive year, The Perl and Raku Foundation (TPRF) isoverjoyed to announce &lt;a href=&quot;https://spreadprivacy.com/2025-duckduckgo-charitable-donations/&quot;&gt;a donation of USD 25,000 fromDuckDuckGo&lt;/a&gt;.&lt;blockquote&gt;DuckDuckGo has demonstrated how Perl and its ecosystem can deliver power andscale to drive the DuckDuckGo core systems, plug-in framework and InstantAnswers. The Foundation is grateful that DuckDuckGo recognises the importanceof Perl, and for their generous funding support for a second year throughtheir charitable donations programme.&lt;/blockquote&gt; Stuart J Mackintosh, President of The Perl and Raku Foundation&lt;a href=&quot;https://www.perl.com/article/duckduckgo-donates-25-000-to-the-perl-and-raku-foundation/&quot;&gt;Last years donation of USD 25,000 fromDuckDuckGo&lt;/a&gt;was instrumental in helping to fund the foundations Core Perl Maintenance Fundand this years donation will help to fund more of the same crucial work thatkeeps the Perl language moving forward.&lt;img height=400 width=500 src=&quot;https://www.perl.com/images/duck-duck-go/fireworks.jpg&quot; alt=&quot;Fireworks celebration&quot;&gt;&lt;br /&gt;&lt;a href=&quot;https://metacpan.org/author/PEVANS&quot;&gt;Paul LeoNerd Evans&lt;/a&gt; is one of thedevelopers who gets regular funding from the Perl Core Maintenance Fund. Hereis a short list of just some of the many contributions which Paul has made tocore Perl as part of the maintenance fund work:&lt;hr&gt;&lt;ul&gt;&lt;li&gt;The &lt;a href=&quot;https://perldoc.perl.org/builtin&quot;&gt;builtin&lt;/a&gt; module (5.36), makingavailable many new useful language-level utilities that were previouslyloaded from modules like &lt;a href=&quot;https://metacpan.org/pod/Scalar::Util&quot;&gt;Scalar::Util&lt;/a&gt;&lt;/li&gt;&lt;li&gt;The complete &lt;a href=&quot;https://perldoc.perl.org/feature#The-'class'-feature&quot;&gt;featureclass&lt;/a&gt; system(5.38), adding proper object-orientation syntax and abilities&lt;/li&gt;&lt;li&gt;Lexical method support (5.42), adding &lt;code&gt;my method&lt;/code&gt; andthe &lt;code&gt;-&gt;&amp;method&lt;/code&gt; invocation syntax for better object encapsulation&lt;/li&gt;&lt;li&gt;Stabilising some of the recent experiments - signatures (5.36),try/catch (5.40), foreach on multiple vars (5.40)&lt;/li&gt;&lt;li&gt;Ability to use the //= and ||= operators in signatures (5.38),performance improvements and named parameters (upcoming in nextrelease)&lt;/li&gt;&lt;li&gt;The new &lt;a href=&quot;https://perldoc.perl.org/functions/any&quot;&gt;any&lt;/a&gt; and&lt;a href=&quot;https://perldoc.perl.org/functions/all&quot;&gt;all&lt;/a&gt; keywords (5.42)&lt;/li&gt;&lt;/ul&gt;&lt;hr&gt;We look forward to many more innovative contributions from Paul over the comingyear.While TPRF never takes continued support for granted, when it does arrive, itallows the foundation to plan for the future with much greater confidence.Multi-year partnerships with our sponsors allow us to continue to prioritizeimportant work, knowing that we will have the runway that we need to fund thework which helps to sustain the Perl Language and its associated communities.For more information on how to become a sponsor, please contact:&lt;a href=&quot;mailto:olaf@perlfoundation.org&quot;&gt;olaf@perlfoundation.org&lt;/a&gt;&lt;hr&gt;&lt;em&gt;&quot;&lt;a href=&quot;https://www.flickr.com/photos/67458569@N00/7722577066&quot;&gt;Fireworks&lt;/a&gt;&quot; by &lt;a href=&quot;https://www.flickr.com/photos/67458569@N00&quot;&gt;colink.&lt;/a&gt; is licensed under &lt;a href=&quot;https://creativecommons.org/licenses/by-sa/2.0/?ref=openverse&quot;&gt;CC BY-SA 2.0&lt;/a&gt;.&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;Read more &lt;a class=&quot;sw_sl&quot; href=&quot;https://www.perl.com/article/duckduckgo-donates-25-000-to-the-perl-and-raku-foundation-v2025/&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;</description>
  </item>
  <item>
    <title>Announcing the Perl Toolchain Summit 2026</title>
    <link>http://www.jamesraposa.com/index/2026/01/26#auto___announcing_the_perl_toolchain_summit_2026</link>
    <description>Furnished content.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h1 id=&quot;announcing-the-perl-toolchain-summit-2026&quot;&gt;Announcing the Perl Toolchain Summit 2026!&lt;/h1&gt;The organizers have been working behind the scenes since last September,and today Im happy to announce that the 16th Perl Toolchain Summit willbe held in Vienna, Austria, from Thursday April 23rd till Sunday April26th, 2026.This post is brought to you by &lt;a href=&quot;https://www.simplelists.com/&quot;&gt;Simplelists&lt;/a&gt;, a group email andmailing list service provider, and a recurring sponsor of the PerlToolchain Summit.&lt;img height=400 width=500 src=&quot;https://www.perl.com/images/announcing-the-perl-toolchain-summit-2026/simplelists-logo.png&quot; alt=&quot;Simplelists logo&quot;&gt;&lt;hr&gt;Started in 2008 as the Perl QA Hackathon in Oslo, the Perl ToolchainSummit is an annual event that brings together the key developersworking on the Perl toolchain. Each year (except for 2020-2022), theevent moves from country to country all over Europe, organised by localteams of volunteers. The surplus money from previous summits helps fundthe next one.Since 2023, the organizing team is formally split between a globalteam and a local team (although this setup has been informallyused before).The global team is made up of veteran PTS organizers, who deal withinvitations, finding sponsors, paying bills and communications. They areLaurent Boivin (&lt;a href=&quot;https://metacpan.org/author/ELBEHO&quot;&gt;ELBEHO&lt;/a&gt;), PhilippeBruhat (&lt;a href=&quot;https://metacpan.org/author/BOOK&quot;&gt;BOOK&lt;/a&gt;), Thibault Duponchelle(&lt;a href=&quot;https://metacpan.org/author/CONTRA&quot;&gt;CONTRA&lt;/a&gt;), Tina Mller(&lt;a href=&quot;https://metacpan.org/author/TINITA&quot;&gt;TINITA&lt;/a&gt;) and Breno de Oliveira(&lt;a href=&quot;https://metacpan.org/author/GARU&quot;&gt;GARU&lt;/a&gt;), supported by &lt;a href=&quot;https://www.mongueurs.net/&quot;&gt;Les Mongueursde Perl&lt;/a&gt;s bank account.The local team members for this year have organized several events inVienna (including the Perl QA Hackathon 2010!) and deal with finding thevenue, the hotel, the catering and welcoming our attendees in Vienna inApril. They are Alexander Hartmaier(&lt;a href=&quot;https://metacpan.org/author/ABRAXXA&quot;&gt;ABRAXXA&lt;/a&gt;), Thomas Klausner(&lt;a href=&quot;https://metacpan.org/author/DOMM&quot;&gt;DOMM&lt;/a&gt;), Maro Kollr(&lt;a href=&quot;https://metacpan.org/author/MAROS&quot;&gt;MAROS&lt;/a&gt;), Michael Krll and HelmutWollmersdorfer (&lt;a href=&quot;https://metacpan.org/author/WOLLMERS&quot;&gt;WOLLMERS&lt;/a&gt;).The developers who maintain CPAN and associated tools and services areall volunteers, scattered across the globe. This event is the one timein the year when they can get together.The summit provides dedicated time to work on the critical systems andtools, with all the right people in the same room. The attendees hammerout solutions to thorny problems and discuss new ideas to keep thetoolchain moving forward. This year, about 40 people have been invited,with 35 participants expected to join us in Vienna.If you want to find out more about the work being done at the ToolchainSummit, and hear the teams and people involved, you can listen toseveral episodes of &lt;a href=&quot;https://underbar.cpan.io/&quot;&gt;The Underbar&lt;/a&gt; podcast,which were recorded during the 2025 edition in Leipzig, Germany:&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://underbar.cpan.io/episodes/3/&quot;&gt;MetaCPAN&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://underbar.cpan.io/episodes/5/&quot;&gt;Test::Smoke&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://underbar.cpan.io/episodes/6/&quot;&gt;CPAN Testers&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://underbar.cpan.io/episodes/7/&quot;&gt;CPAN Security Group&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://underbar.cpan.io/episodes/8/&quot;&gt;A tangent about the Perl Toolchain Summit&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;Given the important nature of the attendees work and their volunteerstatus, we try to pay for most expenses (travel, lodging, food, etc.)through sponsorship. If youre interested in helping sponsor the summit,please get in touch with the global team at&lt;a href=&quot;mailto:pts2026@perltoolchainsummit.org&quot;&gt;pts2026@perltoolchainsummit.org&lt;/a&gt;.&lt;a href=&quot;https://www.simplelists.com/&quot;&gt;Simplelists&lt;/a&gt; has been sponsoring the Perl Toolchain Summit for severalyears now. We are very grateful for their continued support.&lt;blockquote&gt;Simplelists is proud to sponsor the 2026 Perl Toolchain Summit, as Perlforms the core of our technology stack. We are grateful that we can relyon the robust and comprehensive Perl ecosystem, from the core of Perlitself to a whole myriad of CPAN modules. We are glad that the PTScontinues its unsung work, ensuring that Simplelists can continue torely on these many tools.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Read more &lt;a class=&quot;sw_sl&quot; href=&quot;https://www.perl.com/article/announcing-the-perl-toolchain-summit-2026/&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;</description>
  </item>
  <item>
    <title>Geizhals Preisvergleich Donates USD 10,000 to The Perl and Raku Foundation</title>
    <link>http://www.jamesraposa.com/index/2026/01/25#auto___geizhals_preisvergleich_donates_usd_10_000_to_the_perl_and_raku_foundation</link>
    <description>Furnished content.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Today The Perl and Raku Foundation is thrilled to announce a donation of USD10,000 from &lt;a href=&quot;https://geizhals.at&quot;&gt;Geizhals Preisvergleich&lt;/a&gt;. This gift helps tosecure the future of The Perl 5 Core Maintenance Fund.&lt;blockquote&gt;Perl has been an integral part of our product price comparison platformfrom the start of the company 25 years ago. Supporting the Perl 5 CoreMaintenance Fund means supporting both present and future of asubstantial pillar of Modern Open Source Computing, for us and othercurrent or prospective users.&lt;/blockquote&gt;&amp;ndash; Michael Krll of Geizhals Preisvergleich&lt;blockquote&gt;Geizhals is not only providing core funding for the Perl ecosystem, but alsosupporting developers, actively contributing to European conferences, andemploying Perl coders. Their interest in the strategic maintenance anddevelopment of Perl and CPAN is of great value to us all, and theirinvestment is very much appreciated.&lt;/blockquote&gt;&amp;ndash; Stuart J Mackintosh, President of The Perl and Raku FoundationBut who exactly is Geizhals, and why does their support matter so much to thePerl community?Geizhals Preisvergleich began in July of 1997 as a hobby projectand yes,&amp;ldquo;Geizhals&amp;rdquo; literally translates to &amp;ldquo;skinflint&amp;rdquo; in English (they even operate&lt;a href=&quot;https://skinflint.co.uk/&quot;&gt;skinflint.co.uk&lt;/a&gt; for UK users!). From those humblebeginnings, they&amp;rsquo;ve leveraged the power of Perl to scale up to serving &lt;a href=&quot;https://unternehmen.geizhals.at/&quot;&gt;4.3million monthly users&lt;/a&gt;. With Perl being a keypart of their infrastructure, they have generously decided to support the Perl5 Core Maintenance Fund.While many of us know about the Core Maintenance Fund, the specific problems itaddresses often remain invisible to users. I reached out to the maintainerswhose work is supported by this fund. This is what core maintainer Tony Cookhad to say:&lt;blockquote&gt;My work tends to be little things, I review other people&amp;rsquo;s work which I thinkimproves quality and velocity, and fix more minor issues, some examples wouldbe:&lt;ul&gt;&lt;li&gt;a fix to signal handling where perl could crash where an external librarycreated threads (&lt;a href=&quot;https://github.com/perl/perl5/issues/22487&quot;&gt;#22487&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;fix a segmentation fault in smartmatch against a sub if the sub exited via aloop exit op (such as last)(&lt;a href=&quot;https://github.com/perl/perl5/issues/16608&quot;&gt;#16608&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;fixed a bug where a regexp warning could leak memory.&lt;/li&gt;&lt;li&gt;prevent a confusing undefined warning message when accessing a subparameter that was placeholder for a hash element indexed by anundef key (&lt;a href=&quot;https://github.com/perl/perl5/issues/22423&quot;&gt;#22423&lt;/a&gt;)&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;What Tony has highlighted are the kinds of bug fixes which collectively help toensure that Perl remains stable, secure and reliable for the many organisationsand individuals who depend on it.With organizations like Geizhals Preisvergleich funding the work which Tony andothers put into maintaining the Perl 5 core, we can work together to ensure thatthe Perl core continues to receive the maintenance which it deserves, for manyyears to come. Whether you&amp;rsquo;re a startup using Perl for rapid prototyping or anenterprise running mission-critical systems, your support helps ensure Perlremains reliable for everyone. Please join us on this journey.For more information on how to become a sponsor, please contact:&lt;a href=&quot;mailto:olaf@perlfoundation.org&quot;&gt;olaf@perlfoundation.org&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Read more &lt;a class=&quot;sw_sl&quot; href=&quot;https://www.perl.com/article/geizhals-donates-to-tprf/&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;</description>
  </item>
  <item>
    <title>Beginner's Introduction to Perl 5.10, Part 2</title>
    <link>http://www.jamesraposa.com/index/2008/05/08#auto___beginner_s_introduction_to_perl_5_10__part_2</link>
    <description>&lt;a href='http://www.perl.com/pub/a/2008/05/07/beginners-introduction-to-perl-510-part-2.html?CMP=OTC-BD0016219291&amp;amp;ATT=Beginner+s+Introduction+to+Perl+5+10+Part+2'&gt;&lt;img src='http://www.perl.com/standard-tiles/perl/111-camel.jpg' width='111px' height='91px' alt='tile image' align='left' border='0' style='padding-right:5px;' /&gt;&lt;/a&gt;Perl 5 has come a long way in the past few years. The newest version, Perl 5.10, added several new features to make your programs shorter, easier to maintain, easier to write, and more powerful. Here's how to start using files and strings in modern Perl.&lt;br /&gt;&lt;br /&gt;Read more &lt;a class=&quot;sw_sl&quot; href=&quot;http://www.perl.com/pub/a/2008/05/07/beginners-introduction-to-perl-510-part-2.html?CMP=OTC-BD0016219291&amp;ATT=Beginner+s+Introduction+to+Perl+5+10+Part+2&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;&lt;br /&gt;&lt;!--ttag:perl, programming, scripting--&gt;</description>
  </item>
  <item>
    <title>A Beginner's Introduction to Perl 5.10</title>
    <link>http://www.jamesraposa.com/index/2008/04/24#auto___a_beginner_s_introduction_to_perl_5_10</link>
    <description>&lt;a href='http://www.perl.com/pub/a/2008/04/23/a-beginners-introduction-to-perl-510.html?CMP=OTC-BD0016219291&amp;amp;ATT=A+Beginner+s+Introduction+to+Perl+5+10'&gt;&lt;img src='http://www.perl.com/standard-tiles/perl/111-camel.jpg' width='111px' height='91px' alt='tile image' align='left' border='0' style='padding-right:5px;' /&gt;&lt;/a&gt;Perl 5 has come a long way in the past few years. The newest version, Perl 5.10, added several new features to make your programs shorter, easier to maintain, easier to write, and more powerful. Here's how to start using modern Perl productively.&lt;br /&gt;&lt;br /&gt;Read more &lt;a class=&quot;sw_sl&quot; href=&quot;http://www.perl.com/pub/a/2008/04/23/a-beginners-introduction-to-perl-510.html?CMP=OTC-BD0016219291&amp;ATT=A+Beginner+s+Introduction+to+Perl+5+10&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;&lt;br /&gt;&lt;!--ttag:perl, programming, scripting--&gt;</description>
  </item>
  </channel>
</rss>