💾 Archived View for thrig.me › blog › 2023 › 07 › 18 › melody-chop-shop.gmi captured on 2023-07-22 at 16:13:39. Gemini links have been rewritten to link to archived content
-=-=-=-=-=-=-
"Composing with Constraints" exercise 9 has one chop a given melody into segments of equal length and presumably to reorder those segments as you see fit, possibly randomly. Musikalisches Würfelspiel was popular a few years ago. With a computer one might imagine software that splits music into suitable segments, and now you have two problems: the original exercise, and new software to write.
Worse, not all MIDI is suitable to segmentation; there may be zero "dtime" events associated with either a previous or the next note, and the next note event could appear before the previous note event. Perhaps there is a patch change for the next note, and then a "note_off" event for some prior "note_on" event. Most MIDI is not like this, though tracks that have long sustains ("note_on" without a corresponding or very late "note_off") will also be a problem for a simple segmentation process that only considers "note_on" events.
#!/usr/bin/env perl use 5.36.0; use MIDI; my @events = ( [ 'note_on', 0, 0, 56, 127 ], # dtime, channel, note, velocity [ 'patch_change', 192, 0, 48 ], # new instrument for next note [ 'note_off', 0, 0, 56, 127 ], # turn off the prior note [ 'note_on', 0, 0, 56, 127 ], [ 'note_off', 192, 0, 56, 127 ], ); my $t = MIDI::Track->new( { events => \@events } ); MIDI::Opus->new( { tracks => [$t] } )->write_to_file('out.midi');
This MIDI may not be portable; one noise-maker might react to the "patch_change" for the currently playing note, while another will not. Still, you can try arbitrary MIDI files or normalize them first so that shuffled stray events do not cause problems.
$ perl eg/melody-shuffle duration 96 has 21 segments duration 288 has 7 segments duration 672 has 3 segments
Anyways, there's a module for MIDI segmentation on CPAN, and most of the obvious bugs have been fixed.
https://metacpan.org/pod/MIDI::Segment
tags #midi #perl