Skip to content

Instantly share code, notes, and snippets.

@jeffa
Created April 30, 2024 14:29
Show Gist options
  • Save jeffa/cc05345b914c75a88501ab1e13dcf6dc to your computer and use it in GitHub Desktop.
Save jeffa/cc05345b914c75a88501ab1e13dcf6dc to your computer and use it in GitHub Desktop.
Convert textual Morse Code into MIDI events
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
use MIDI;
use Text::Morse;
use Pod::Usage;
use Getopt::Long;
GetOptions (
'message|m=s' => \my $message,
'filename|f=s'=> \my $filename,
'pitch|p=s' => \my $pitch,
'tight' => \my $tight,
'help' => \my $help,
'man' => \my $man,
);
pod2usage( -verbose => 0 ) if $help;
pod2usage( -verbose => 2 ) if $man;
die "--message required\n" unless $message;
die "--filename required\n" unless $filename;
$pitch ||= 69;
my %duration = (
'.' => 24,
'-' => 48,
);
my $encoder = Text::Morse->new;
$message = $encoder->Encode( $message );
warn "$message\n";
my @event;
for ($message =~ /(.)/g) {
my ($duration, $velocity);
if ($duration = $duration{$_}) {
$velocity = 120;
} else {
#rest
$duration = $tight ? 48 : 96;
$velocity = 0;
}
# add note_on/note_off pair
push @event, mk_event( $pitch, $duration, $velocity );
}
# add 'final rest' by doubling duration of last event
$event[-1]->[1] *= 2;
my $opus = MIDI::Opus->new({
format => 0,
ticks => 96,
tracks => [ MIDI::Track->new({
events => [ @event ],
})],
});
$opus->write_to_file( $filename );
sub mk_event {
my ($p, $d, $v) = @_;
return
[note_on => 0, 1, $p, $v],
[note_off => $d, 1, $p, 0],
;
}
__END__
=head1 NAME
morse-midi - generate Morse encoded MIDI
=head1 SYNOPSIS
morse-midi [options]
Options:
--message the message to Morse encode
--pitch the default pitch for notes
--filename name of output MIDI file
--help list usage for methods and parameters
--man print man page
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment