NAME
MIDI::Segment - means to segment MIDI by equal duration
SYNOPSIS
use MIDI;
use MIDI::Segment;
my $opus = MIDI::Opus->new( { from_file => 'cowbell.midi' } );
my ( $mis, $durations ) = MIDI::Segment->new($opus);
die "not possible to split equally" unless @$durations;
for my $dur (@$durations) {
my $segments = $mis->split($dur);
warn "duration $dur has " . scalar(@$segments) . " segments\n";
for my $seg (@$segments) {
# deal with @$seg which are array references for each track that
# in turn contain some number of MIDI::Event arrays ...
}
}
See also eg/melody-shuffle
.
DESCRIPTION
This module provides a means to split MIDI::Opus into MIDI::Event segments of equal duration, assuming that is possible. Typical uses would be to display the possible segments or to shuffle them into a new composition with e.g. the shuffle call in List::Util.
MIDI does not contain durations; the dtime or "delta time" of the last note_on
event of track may be 0
; if that note_on
is the last event of the track then the duration of that note is unknown. Also MIDI tracks may be of different durations. These cases are not handled by this module; the user will need to alter the MIDI so that the tracks are of equal duration and the last note_on
events have a suitable dtime set. MIDI::Event may be helpful to study if this paragraph did not make much sense, and inspecting the contents of MIDI files with eg/midi-dump
.
$ perl ./eg/midi-dump t/cowbell.midi
Other problems with MIDI include that zero dtime events can be associated with either some previous or next event; worse, these might be ordered so that the control change for the future note happens prior to the off event of the previous note. This has been a long way to say that random MIDI may not segment itself cleanly.
Lilypond MIDI files in particular contain a control track that will need to be removed as this track contains no note_on events.
my $opus = MIDI::Opus->new( { from_file => 'lilypond.midi' } );
shift @{ $opus->tracks_r };
my ( $mis, $durations ) = ...
METHODS
These will throw an exception if anything goes awry.
- new opus
-
Creates a new object and performs duration calculations on the given MIDI::Opus object. Returns the object and an array reference of durations that the opus can be split on, if any.
- split duration
-
Splits the opus into segments of the given duration, assuming that is possible. The returned array reference of segments consists of array references for each track, which in turn contain one or more MIDI event array references.
BUGS
Probably, given the lack of real world MIDI that has been thrown at the code.
SEE ALSO
COPYRIGHT AND LICENSE
Copyright 2023 Jeremy Mates
This program is distributed under the (Revised) BSD License: https://opensource.org/licenses/BSD-3-Clause