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!