TPRC 2023 • Toronto, ON
Writing MIDI files
High-level, object-oriented score construction ("Audio LEGOs")
Good ol' procedural algorithms
Song or audio analysis
Real-time audio or MIDI processing
Low-level MIDI events, like note_on, note_off, or sysex messages
Artificial intelligence techniques, like generative adversarial networks
Kittens!
Creation in and of itself!
To make fragments for a larger context - Like a symphony, or game
To satisfy curiosities - "What do juxtapositions of beat patterns sound like?"
For practice and study, with etudes and rhythms
How do you construct a rhythm?
How do you generate pleasing harmony?
How do you make a melody?
How do you structure a tune?
App::MusicTools Csound Guitar::Scale MIDI Music::Bassline::Generate MIDI::Chord::Guitar MIDI::Drummer::Tiny MIDI::Morph MIDI::Pitch MIDI::Praxis::Variation MIDI::Simple::Drummer MIDI::SoundFont MIDI::Tools MIDI::Trans MIDI::Tweaks MIDI::Util Music::AtonalUtil Music::Cadence Music::Canon Music::ChordBot Music::Chord::Namer Music::Chord::Note Music::Chord::Positions Music::Chord::Progression Music::Chord::Progression::Transform Music::Duration Music::Duration::Partition Music::Gestalt Music::Guidonian Music::Harmonics Music::MelodicDevice::Inversion Music::MelodicDevice::Transposition Music::MelodicDevice::Ornamentation Music::NeoRiemannianTonnetz Music::Note Music::Note::Frequency Music::Note::Role::Operators Music::PitchNum Music::RecRhythm Music::RhythmSet Music::ScaleNote Music::Scales Music::Tempo Music::Tension Music::ToRoman Music::VoiceGen Music::Voss Text::Chord::Piano
• Setup, Sync, & Write
use MIDI::Util qw(setup_score);
my $score = setup_score(); # Default piano, volume, bpm, etc
$score->synch(
sub { bass($score) },
sub { treble($score) },
);
$score->write_score("$0.mid"); sub bass {
my ($score) = @_;
for my $note (qw(C3 E3 C3 G3)) { # <- Static notes
$score->n('wn', $note);
}
}
sub treble {
my ($score) = @_;
for my $note (qw(E4 E4 F4 G4 G4 F4 E4 D4 C4 C4 D4 E4 E4 D4 D4)) {
$score->n('qn', $note);
}
} > timidity -c timidity.cfg -A10a code/2-random.pl.mid -Ow -o - \ | ffmpeg -i - -acodec libmp3lame -ab 64k audio/2-random.mp3
• Use random pitches instead of static
use MIDI::Util qw(setup_score set_chan_patch); # New import
use Music::Scales qw(get_scale_MIDI); # New module
my $score = setup_score(bpm => 120); # New arg
$score->synch(
sub { bass($score) },
sub { treble($score) },
) for 1 .. 4; # Loop
$score->write_score("$0.mid"); sub bass {
my ($score) = @_;
set_chan_patch($score, 0, 35); # Fretless on channel 0
my @pitches = get_scale_MIDI('C', 2, 'pentatonic');
for my $n (1 .. 4) {
my $pitch = $pitches[int rand @pitches]; # Random pitch
$score->n('hn', $pitch); # Add note to score
}
} sub treble {
my ($score) = @_;
set_chan_patch($score, 1, 0); # Piano on ch 1
my @pitches = (
get_scale_MIDI('C', 4, 'major'),
get_scale_MIDI('C', 5, 'major'), # <- 2 octaves
);
for my $n (1 .. 4) {
my $pitch = $pitches[int rand @pitches];
$score->n('qn', $pitch);
}
} • Play a list of named chords held for a whole note each
use MIDI::Util qw(setup_score midi_format); # New import
use Music::Scales qw(get_scale_MIDI);
use Music::Chord::Note (); # New module
my $score = setup_score();
$score->synch(
sub { chords($score) },
#sub { treble($score) }, # YMMV!
);
$score->write_score("$0.mid"); sub chords {
my ($score) = @_;
my $mcn = Music::Chord::Note->new;
for my $named (qw(Cm7 F7 BbM7 EbM7 Adim7 D7 Gm)) {
my @chord = $mcn->chord_with_octave($named, 4);
@chord = midi_format(@chord);
# [ C4 Ds4 G4 As4 ], ... [ G4 As4 D5 ], etc.
$score->n('wn', @chord);
}
} Generate combinatorial rhythmic patterns
Produce a randomized, figured bass line
morbo groovetool.pl # http://127.0.0.1:3000
• Phrase generator for rhythmic motifs
my $phrase = Music::Duration::Partition->new( size => 3, # Number of beats to render pool => [qw(hn dqn qn en)], weights => [ 1, 1, 2, 2 ], # Optional groups => [ 1, 1, 1, 2 ], # Optional ); my @motifs = $phrase->motifs(2);
my @pitches = get_scale_MIDI($note, $octave, $scale);
my $voice = Music::VoiceGen->new(
pitches => \@pitches,
intervals => [qw/-4 -3 -2 2 3 4/], # Allowed interval jumps
);
# main phrase voices
my @voices1 = map { $voice->rand } $motifs[0]->@*;
# ... more code ...
my @voices2 = map { $voice->rand } $motifs[1]->@*; This Slideshow is on GitHub (and made with S5)
Perl Algorithmic Composition Tutorial
The #perl-music channel on irc.perl.org
The Groove-Tool, Rock-Tool and Jazz-Tool on GitHub
Shameless plug: My latest album "XI" - youtube, spotify, apple music, etc. and includes the partially algorithmic tune "Permutational" - Check it out!