e dot dot dot
a mostly about the Internet blog by

home << Programming << Perl
September 2026
Sun Mon Tue Wed Thu Fri Sat
   
     

  Basic Search
Search:
Entire Site This Topic Only
Match:
Any All
Partial Whole Words only


Making an Asynchronous Clocking Drum Machine App in Perl

Furnished content.


Let’s Make a Drum Machine application! Yeah! :DThere are basically two important things to handle: A MIDI “clock” and a groove to play.Why asynchronous? Well, a simple while (1) { Time::HiRes::sleep(); ... } will not do because the time between ticks will fluctuate, often dramatically. IO::Async::Timer::Periodic 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.

Clocks

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:
#!/usr/bin/env perluse v5.36;use feature 'try';use IO::Async::Loop ();use IO::Async::Timer::Periodic ();use MIDI::RtMidi::FFI::Device ();my  = shift || 'usb'; # MIDI sequencer devicemy   = shift || 120; # beats per minutemy  = 60 /  / 24; # time / bpm / clocks-per-beat# open the named midi device for outputmy  = RtMidiOut->new;try { # this will die on Windows but is needed for Mac    ->open_virtual_port('RtMidiOut');}catch ($e) {}->open_port_by_name(qr/\Q/i);->start; # start the sequencer{INT} = sub { # halt gracefully    say "\nStop";    try {        ->stop; # stop the sequencer        ->panic; # make sure all notes are off    }    catch ($e) {        warn "Can't halt the MIDI out device: $e\n";    }    exit;};my  = IO::Async::Loop->new;my  = IO::Async::Timer::Periodic->new(   interval => ,   on_tick  => sub { ->clock }, # send a clock tick!);->start;->add();->run;
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 variable is captured for a unique MIDI device. (And to see what the names of MIDI devices on the system are, use JBARRETT’s little list_devices script.) Also, the beats per minute is taken from the command-line. If neither is given, usb is used for the name, and the BPM is set to “dance tempo.”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 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 provided.In order to not just die when we want to stop, {INT} is redefined to gracefully halt. This also sends a stop 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 . Pretty simple!As an example, here is the above code controlling my Volca Drum drum machine on a stock, funky groove. We invoke it on the command-line like this:
perl clock-gen-async.pl

Grooves

What we really want is to make our drum machine actually play something of our own making. So it’s refactor time… Let’s make a 4/4 time groove, with 16th-note resolution, that alternates between two different parts. “4/4” is a “time signature” 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’s 3/4 are simple, while odd meters like 7/8 are not.In order to generate syncopated patterns, Math::Prime::XS and Music::CreatingRhythms are added to the use statements. “What are syncopated patterns?”, you may ask. Good question! “Syncopated” means, “characterized by displaced beats.” That is, every beat does not happen evenly, at exactly the same time. Instead, some are displaced. For example, a repeated [1 1 1 1] is even and boring. But when it becomes a repeated [1 1 0 1] things get spicier and more syncopated.The desired MIDI channel is added to the command-line inputs. Most commonly, this will be channel 9 (in zero-based numbering). But some drum machines and sequencers are “multi-timbral” 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’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 . 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 Music::CreatingRhythms 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’s on_tick 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 Math::Prime::XS and Music::CreatingRhythms come into play. The subroutine that does that is adjust_drums() 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 variable), it is added to the queue at full velocity (127). Then, after all the drums have been accounted for, the queue is played with ->note_on() messages. Lastly, the queue is “drained” by sending ->note_off() messages.
#!/usr/bin/env perluse v5.36;use feature 'try';use IO::Async::Loop ();use IO::Async::Timer::Periodic ();use Math::Prime::XS qw(primes);use MIDI::RtMidi::FFI::Device ();use Music::CreatingRhythms ();my  = shift || 'usb'; # MIDI sequencer devicemy   = shift || 120; # beats-per-minutemy  = shift // 9; # 0-15, 9=percussion, -1=multi-timbralmy  = {    kick  => { num => 36, chan =>  < 0 ? 0 : , pat => [] },    snare => { num => 38, chan =>  < 0 ? 1 : , pat => [] },    hihat => { num => 42, chan =>  < 0 ? 2 : , pat => [] },};my  = 16; # beats in a measuremy  = 4; # divisions of a quarter-note into 16thsmy  = 24; # PPQNmy  = 60 /  / ; # time / bpm / ppqnmy  =  / ; # clocks per 16th-notemy %primes = ( # for computing the pattern    all  => [ primes() ],    to_5 => [ primes(5) ],    to_7 => [ primes(7) ],);my  = 0; # clock ticksmy  = 0; # how many beats?my  = 0; # part A or B?my @queue; # priority queue for note_on/off messages# open the named midi output devicemy  = RtMidiOut->new;try { # this will die on Windows but is needed for Mac    ->open_virtual_port('RtMidiOut');}catch ($e) {}->open_port_by_name(qr/\Q/i);{INT} = sub { # halt gracefully    say "\nStop";    try {        ->stop; # stop the sequencer        ->panic; # make sure all notes are off    }    catch ($e) {        warn "Can't halt the MIDI out device: $e\n";    }    exit;};# for computing the patternmy  = Music::CreatingRhythms->new;my  = IO::Async::Loop->new;my  = IO::Async::Timer::Periodic->new(    interval => ,    on_tick  => sub {        ->clock;        ++;        if ( % $sixteenth == 0) {            # adjust the drum pattern every 4th measure            if ( % ($beats * ) == 0) {                adjust_drums(, , \%primes, \);            }            # add simultaneous drums to the queue            for my  (keys %) {                if (->{}{pat}[  % $beats ]) {                    push @queue, { drum => , velocity => 127 };                }            }            # play the queue            for my  (@queue) {                ->note_on(                    ->{ ->{drum} }{chan},                    ->{ ->{drum} }{num},                    ->{velocity}                );            }            ++;        }        else {            # drain the queue with note_off messages            while (my  = pop @queue) {                ->note_off(                    ->{ ->{drum} }{chan},                    ->{ ->{drum} }{num},                    0                );            }            @queue = (); # ensure the queue is empty        }    },);->start;->add();->run;sub adjust_drums(, , , ) {    # choose random primes to use by the hihat, kick, and snare    my ($p, $q, $r) = map { ->{$_}[ int rand ->{$_}->@* ] } sort keys %;    if ($ == 0) {        say 'part A';        ->{hihat}{pat} = ->euclid($p, );        ->{kick}{pat}  = ->euclid($q, );        ->{snare}{pat} = ->rotate_n($r, ->euclid(2, ));        $ = 1; # set to part B    }    else {        say 'part B';        ->{hihat}{pat} = ->euclid($p, );        ->{kick}{pat}  = [qw(1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1)];        ->{snare}{pat} = [qw(0 0 0 0 1 0 0 0 0 0 0 0 1 0 1 0)];        $ = 0; # set to part A    }}
(You may notice the inefficiency of attempting to drain an empty queue 23 times every 16th note. Oof! Fortunately, this doesn’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’t be adding, for brevity’s sake.)On Windows, this works fine:
perl clocked-euclidean-drums.pl "gs wavetable" 90
To run with fluidsynth and hear the General MIDI percussion sounds, open a fresh new terminal session, and start up fluidsynth like so (mac syntax):
fluidsynth -a coreaudio -m coremidi -g 2.0 ~/Music/soundfont/FluidR3_GM.sf2
The FluidR3_GM.sf2 is a MIDI “soundfont” file and can be downloaded for free.Next, enter this on the command-line (back in the previous terminal session):
perl clocked-euclidean-drums.pl fluid 90
You will hear standard kick, snare, and closed hihat cymbal. And here is a poor recording of this with my phone:To run the code with my multi-timbral drum machine, I enter this on the command-line:
perl clocked-euclidean-drums.pl usb 90 -1
And here is what that sounds like:

The Module

I have coded this logic, and a bit more, into a friendly CPAN module. Check out the eg/euclidean.pl example program in the distribution. It is a work in progress. YMMV.

Credits

Thank you to Andrew Rodland (hobbs), who helped me wrap my head around the “no-sleeping asynchronous” algorithm.

To-do Challenges

  • Make patterns other than prime number based Euclidean phrases.
  • Toggle more than two groove parts.
  • Add snare fills to the (end of the) 4th bars. (here’s my version)
  • Make this code handle odd meter grooves.

Resources



Read more here

posted at: 12:00am on 15-Apr-2026
path: /Programming/Perl | permalink | edit (requires password)

0 comments, click here to add the first



Fastmail Donates USD 10,000 to The Perl and Raku Foundation

Furnished content.


2025 was a tough year for The Perl and Raku Foundation (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. Fastmail 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.

Perl has served us quite well since Fastmail’s inception. We’ve built up a large code base that has continued to work, grow, and improve over twenty years. We’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 & Chief Developer Experience Officer, Fastmail
One of the reasons that you don’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 “just work” after the upgrade. You don’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’t have to care very much about upgrading your Perl. Backwards compatibility is top of mind. If your deployment is boring, it’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’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’s donation has been allocated towards Perl 5 Core maintenance, TPRF is now in the position to re-open the community grants program, 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 become a sponsor, contact:olaf@perlfoundation.org

Read more here

posted at: 12:00am on 05-Feb-2026
path: /Programming/Perl | permalink | edit (requires password)

0 comments, click here to add the first



Cast-Iron Community: Your Chance to Sponsor TPRC 2026

Furnished content.


“Perl is my cast-iron pan - reliable, versatile, durable, and continues to beever so useful.” TPRC 2026 brings together acommunity that embodies all of these qualities, and we’re looking for sponsorsto help make this special gathering possible.

About the Conference

The Perl and Raku Conference 2026 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.

Why Sponsor?

  • Give back to the language and communities which have already given so much to you
  • Connect with the developers and craftspeople who build your tools – the ones that are built to last
  • Help to ensure that The Perl and Raku Foundation can continue to fund Perl 5 core maintenance and Community Grants

Sponsorship Tiers

Platinum Sponsor ($6,000)

  • Only 1 sponsorship is available at this level
  • Premium logo placement on conference website
  • This donation qualifies your organization to be a Bronze Level Sponsor of The Perl and Raku Foundation
  • 5-minute speaking slot during opening ceremony
  • 2 complimentary conference passes
  • Priority choice of rollup banner placement
  • Logo prominently displayed on conference badges
  • First choice of major named sponsorship (Conference Dinner, T-shirts, or Swag Bags)
  • Logo on main stage backdrop and conference banners
  • Social media promotion
  • All benefits of lower tiers

Gold Sponsor ($4,000)

  • Logo on all conference materials
  • One complimentary conference pass
  • Rollup banner on display
  • Choice of named sponsorship (Lunch or Snacks)
  • Logo on backdrop and banners
  • Dedicated social media recognition
  • All benefits of lower tiers

Silver Sponsor ($2,000)

  • Logo on conference website
  • Logo on backdrop and banners
  • Choice of smaller named sponsorship (Beverage Bars)
  • Social media mention
  • All benefits of lower tier

Bronze Sponsor ($1,000)

  • Name/logo on conference website
  • Name/logo on backdrop and banners

All Sponsors Receive

  • Logo/name in Update::Daily conference newsletter sidebar
  • Opportunity to provide materials for conference swag bags
  • Recognition during opening and closing ceremonies
  • Listed on conference website sponsor page
  • Mentioned in conference social media

Named Sponsorship Opportunities

Exclusive naming rights available for:
  • Conference Dinner ($2,000) - Signage on tables and buffet
  • Conference Swag Bags ($1,500) - Logo on bags
  • Conference T-Shirts ($1,500) - Logo on sleeve
  • Lunches ($1,500) - Signage at pickup and on menu tickets
  • Snacks ($1,000) - Signage at snack bar
  • Update::Daily Printing ($200) - Logo on masthead

About The Perl and Raku Foundation

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.

Contact Information

For more information on how to become a sponsor, please contact:olaf@perlfoundation.org

Read more here

posted at: 12:00am on 04-Feb-2026
path: /Programming/Perl | permalink | edit (requires password)

0 comments, click here to add the first



Podlite comes to Perl: a lightweight block-based markup language for everyday use

Furnished content.


My name is Alex. Over the last years I've implemented several versions of the Raku’s documentation format (Synopsys 26 / Raku’s Pod) in Perl and JavaScript.At an early stage, I shared the idea of creating a lightweight version of Raku’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.

The Block Structure of Podlite

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: delimited, paragraph, and abbreviated.

Abbreviated blocks (=BLOCK)

This is the most compact form.A block starts with = followed by the block name.
=head1 Installation Guide=item Perl 5.8 or newer=para This tool automates the process.
  • ends on the next directive or a blank line
  • best used for simple one-line blocks
  • cannot include configuration options (attributes)

Paragraph blocks (=for BLOCK)

Use this form when you want a multi-line block or need attributes.
=for code :lang<perl>say "Hello from Podlite!";
  • ends when a blank line appears
  • can include complex content
  • allows attributes such as :lang, :id, :caption, :nested,

Delimited blocks (=begin BLOCK =end BLOCK)

The most expressive form. Useful for large sections, nested blocks, or structures that require clarity.
=begin nested :notify<important>Make sure you have administrator privileges.=end nested
  • explicit start and end markers
  • perfect for code, lists, tables, notifications, markdown, formulas
  • can contain other blocks, including nested ones
These block styles differ in syntax convenience, but all produce the same internal structure.diagram here showing the three block styles and how they map to the same internal structureRegardless of which syntax you choose:
  • all three forms represent the same block type
  • attributes apply the same way (:lang, :caption, :id, )
  • tools and renderers treat them uniformly
  • nested blocks work identically
  • you can freely mix styles inside a document

Example: Comparing POD and Podlite

Let’s see how the same document looks in traditional POD versus Podlite:POD vs PodliteEach block has clear boundaries, so you don’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:Podlite example

Inside the Podlite Specification 1.0

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:
  • headings (=head1, =head2, )
  • lists and definition lists, and including task lists
  • tables (simple and advanced)
  • CSV-backed tables
  • callouts / notifications (=nested :notify<tip|warning|important|note|caution>)
  • table of contents (=toc)
  • includes (=include)
  • embedded data (=data)
  • pictures (=picture and inline P<>)
  • formulas (=formula and inline F<>)
  • user defined blocks and markup codes
  • Markdown integration
The =markdown 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:Podlite source, including =markdown block

Using Podlite in Perl via the source filter

To make Podlite directly usable in Perl code, there is a module on CPAN:Podlite Use Podlite markup language in Perl programsA minimal example could look like this:
use Podlite; # enable Podlite blocks inside Perl=head1 Quick Example=begin markdownPodlite can live inside your Perl programs.=end markdownprint "Podlite active\n";

Roadmap: what’s next for Podlite

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:
  • CLI tools
    • command-line utilities for converting Podlite to HTML, PDF, man pages, etc.
    • improve pipelines for building documentation sites from Podlite sources
  • VS Code integration
  • Ecosystem growth
    • develop comprehensive documentation and tutorials
    • community-driven block types and conventions

Try Podlite and share feedback

If this resonates with you, I'd be very happy to hear from you:
  • ideas for useful block types
  • suggestions for tools or integrations
  • feedback on the syntax and specification
https://github.com/podlite/podlite-specs/discussionsEven 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:Thanks for reading,Alex

Read more here

posted at: 12:00am on 28-Jan-2026
path: /Programming/Perl | permalink | edit (requires password)

0 comments, click here to add the first


home << Programming << Perl

September 2026
Sun Mon Tue Wed Thu Fri Sat
   
     


  Basic Search
Search:
Entire Site This Topic Only
Match:
Any All
Partial Whole Words only






RSS (site)  RSS (path)

ATOM (site)  ATOM (path)

Categories
 - blog home

 - Announcements  (0)
 - Annoyances  (0)
 - Career_Advice  (0)
 - Domains  (0)
 - Downloads  (3)
 - Ecommerce  (0)
 - Fitness  (0)
 - Health  (1)
 - Home_and_Garden  (0)
     - Cooking  (0)
     - Tools  (0)
 - Humor  (0)
 - Notices  (0)
 - Observations  (1)
 - Oddities  (2)
 - Online_Marketing  (0)
     - Affiliates  (1)
     - Merchants  (1)
 - Policy  (0)
 - Programming  (0)
     - Bookmarklets  (1)
     - Browsers  (1)
     - DHTML  (0)
     - Excel  (1)
     - Javascript  (4)
     - PHP  (0)
     - PayPal  (1)
     - Perl  (48)
          - blosxom  (0)
     - Unidata_Universe  (22)
 - Random_Advice  (1)
 - Reading  (0)
     - Books  (0)
     - Ebooks  (0)
     - Magazines  (0)
     - Online_Articles  (3)
 - Resume_or_CV  (1)
 - Reviews  (2)
 - Rhode_Island_USA  (0)
     - Providence  (1)
 - Shop  (0)
     - Test-Store  (1)
 - Sports  (0)
     - Football  (0)
          - Cowboys  (0)
          - Patriots  (0)
     - Futbol  (0)
          - The_Rest  (0)
          - USA  (0)
 - Technology  (6213)
 - Windows  (1)
 - Woodworking  (0)


Archives
 -2026  September  (66)
 -2026  August  (253)
 -2026  July  (260)
 -2026  June  (256)
 -2026  May  (256)
 -2026  April  (161)
 -2026  March  (178)
 -2026  February  (164)
 -2026  January  (189)
 -2025  December  (171)
 -2025  November  (172)
 -2025  October  (168)
 -2025  September  (157)
 -2025  August  (169)


My Sites

 - Millennium3Publishing.com

 - SponsorWorks.net

 - ListBug.com

 - TextEx.net

 - FindAdsHere.com

 - VisitLater.com