2023 twenty-four merry days of Perl Feed

Ornamenting Jingle Bells

Music::MelodicDevice::Ornamentation - 2023-12-01

SITUATION

Santa was growing tired of the music piped into his workshop.

For example, Jingle Bells was just too ordinary sounding to his ears. It needed a bit of Christmas cheer to pep up the Elves!

And here is a bit of that tune, that plays at the workshop:

Ordinary to say the least!

ASSESSMENT

Santa asked a couple of his more creative elves to come up with a way to brighten things up musically. And they tinkered, the way elves do.

The cowbell was proposed, but that got shot down quick. Eventually, the most musically experienced elf suggested adding "ornamentation" to certain notes. This she said, included commonly heard things like "trills." (And it is said that she toured as a roadie, in the 60s with Hendrix, CSN, and others.)

After some thinking about exactly how to add ornaments to Christmas tunes, a young guitarist elf pointed to CPAN and the Music::MelodicDevice::Ornamentation module, that seemed to fit the bill perfectly.

Then after reading the examples, the team modified the source and gave it a try... They listened to each of the ornaments and decided to trigger them from a dispatch table, based for the moment, on a loop counter. More sophisticated triggers based on advanced music theory concepts were considered, but Christmas was fast approaching!

PROTOTYPE

Here is the prototype code they came up with for Santa. (And it has too much ornamentation for just 16 bars, on purpose for illustration purposes.)


1: 
2: 
3: 
4: 
5: 
6: 
7: 
8: 
9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
34: 
35: 
36: 
37: 
38: 
39: 
40: 
41: 
42: 
43: 
44: 
45: 
46: 
47: 
48: 
49: 
50: 
51: 
52: 
53: 
54: 
55: 
56: 
57: 
58: 
59: 
60: 
61: 
62: 
63: 
64: 
65: 
66: 
67: 
68: 
69: 
70: 
71: 

 

#!/usr/bin/env perl
use strict;
use warnings;

use MIDI::Util qw(setup_score midi_format);
use Music::MelodicDevice::Ornamentation ();

# The number of notes before resetting the note counter
use constant MAX => 16;

# Sixteen measure fragment of "duration.pitch" notes
my @notes = qw(
    qn.E4 qn.E4 hn.E4
    qn.E4 qn.E4 hn.E4
    qn.E4 qn.G4 qn.C4 qn.D4
    wn.E4

    qn.F4 qn.F4 qn.F4 qn.F4
    qn.F4 qn.E4 qn.E4 qn.E4
    qn.E4 qn.D4 qn.D4 qn.E4
    hn.D4 hn.G4

    qn.E4 qn.E4 hn.E4
    qn.E4 qn.E4 hn.E4
    qn.E4 qn.G4 qn.C4 qn.D4
    wn.E4

    qn.F4 qn.F4 qn.F4 qn.F4
    qn.F4 qn.E4 qn.E4 qn.E4
    qn.G4 qn.G4 qn.F4 qn.D4
    wn.C4
)
;

# Setup a new MIDI score
my $melody = setup_score(bpm => 140);

# Setup a new musical ornament maker
my $ornament = Music::MelodicDevice::Ornamentation->new(
    scale_note => 'C',
    scale_name => 'major',
);

# Dazzle with musical ornamentation (based on beat position for now)
my %dazzle = (
     2 => sub { $ornament->mordent(@_, 1) },
     7 => sub { $ornament->trill(@_, 2, 1) },
    10 => sub { $ornament->turn(@_, 1) },
    13 => sub { $ornament->grace_note(@_, -1) },
);

# For each duration.note pair...
my $counter = 0;
for my $note (@notes) {
    my @note = split /\./, $note;

# Add either an ornamented or a "plain" note to the score
if (exists $dazzle{$counter}) {
        my $fancy = $dazzle{$counter}->(@note);
        my @fancy = map { [ midi_format(@$_) ] } @$fancy; # turn '#' into 's' and 'b' into 'f'
        $melody->n(@$_) for @fancy;
    }
    else {
        $melody->n(midi_format(@note));
    }

# Increment the counter, or start over if we've reached the max
$counter = $counter == MAX ? 0 : $counter + 1;
}

# Write out the fancy score as a MIDI file
$melody->write_score("$0-fancy.mid");

 

RESULT

And here is the result:

Santa approved the MIDI and the code review, and the team of intrepid elves went to work tastefully implementing ornamentation into the rest of the music system - all driven by Perl, of course!

SYNOPSIS

      $ perl jingle-bells.pl
      $ timidity jingle-bells.pl-fancy.mid  # for unix-like systems

PLAYBACK

On Windows

On Microsoft Windows, use the Legacy Media Player. This app just works. MIDI support was removed from the current Microsoft Media Player app.

On unix-like systems

TiMidity++ is a brilliant software synthesizer that can play MIDI files without a hardware synthesizer. It was written in 1995 by elf, Tuukka Toivonen. A file called a SoundFont tells TiMidity what sounds to play for each MIDI note.

The excellent player, VLC can be used to render MIDI files, too.

Either should be available from your system package manager (apt, homebrew, etc.).

SEE ALSO

Gravatar Image This article contributed by: Gene Boggs <gene.boggs@gmail.com>