NAME
Test2::Tools::MIDI - test MIDI file contents
SYNOPSIS
use MIDI::Simple;
my $o = new_score;
$o->{Score} = []; # KLUGE clear the init text_event
noop c9, o4;
for (1 .. 4) { n 'qn', 'Gs' }
write_score 'cowbell.midi';
use Test2::Tools::MIDI;
open my $fh, '<', 'cowbell.midi' or die "open $!\n";
binmode $fh;
midi_header $fh, 0, 1, 96; # format 0, 1 track, 96 ticks
midi_track $fh, 36;
for (1 .. 4) {
midi_note_on $fh, 0, 9, 56, 64;
midi_note_off $fh, 96, 9, 56, 0;
}
midi_footer $fh, 0;
midi_eof $fh;
DESCRIPTION
This module offers functions that test whether MIDI files (or an in-memory string) contain particular MIDI structures and events. See the MIDI module (among other software and hardware) for means to generate MIDI files.
Details of the MIDI protocol might be good to know. In brief, there is a midi_header structure that indicates among other things how many tracks there are. Each midi_track has a header structure and a footer event, in between which are various MIDI events of some predetermined length (including that of the footer event). Events are generally composed of a time delay (a variable length quantity, see read_vlq), followed by an event ID, followed by event specific data, if any. MIDI::Event documents the general structure of the events.
FUNCTIONS
The midi_*
functions are exported by default; other utility functions are not. Various functions will confess if something goes awry, usually due to I/O errors on the MIDI file-handle.
- midi_aftertouch file-handle dtime channel pitch velocity
-
Test that a
key_after_touch
event is what it should be. - midi_channel_aftertouch file-handle dtime channel velocity
-
Check that a MIDI
channel_aftertouch
is correct. - midi_control_change file-handle dtime channel controller value
-
Test a MIDI control change event. Note that controller may be reported as a pitch problem and value as a velocity problem due to this sharing code with midi_note_on and similar functions.
- midi_eof file-handle
-
Test that the file-handle ends where it is expected to.
- midi_header file-handle format ntracks division
-
Test for a MIDI header which among other things will have a particular format (
0
for a single track,1
for multiple tracks, or possibly other values), some number of tracks ntracks, and a particular division (usually a positive number of ticks such as96
).A MIDI header is generally followed by some number of tracks (that ideally should agree with ntracks), each of which containing some number of events.
-
Check that there is a MIDI footer event with the given dtime (usually
0
) in the file-handle. (The MIDI::Opus module hides the footer in dumps though does parse it.) - midi_note_off file-handle dtime channel pitch velocity
-
Check that there is a MIDI note_off event with the given details in the file-handle. See the MIDI::Event module for more documentation on the fields.
- midi_note_on file-handle dtime channel pitch velocity
-
Like midi_note_off but checks for a slightly different MIDI code. Some software (LilyPond comes to mind) does not generate midi_note_off events but instead issues a midi_note_on with the velocity set to
0
. - midi_patch file-handle dtime channel patch
-
Check for a patch change event with the given details.
- midi_pitch_wheel file-handle dtime channel wheel
-
Test that a MIDI pitch wheel event is correct. The wheel is a 14-bit value split into two bytes that has an offset applied to it.
- midi_skip file-handle size
-
Skips over size bytes in the file-handle. Good for any pesky MIDI events that are not (yet?) supported by this module.
- midi_skip_dtime file-handle size
-
Like midi_skip but first skips over a variable length quantity, which will be of some unknown length between 1 and 4 bytes, inclusive.
$ perl -E 'say for map { length pack w => $_ } 0, 0xFFFFFFF' 1 4
- midi_tempo file-handle dtime tempo
-
Check that a MIDI tempo event with the given dtime and tempo is present.
- midi_track file-handle length
-
Test that a MIDI track is of a certain length in bytes.
- midi_text file-handle dtime text-type string
-
Test that there is a text event of the given text-type with the text string. text-type must be one of:
text copyright name instrument lyric marker cue text8 text9 texta textb textc textd texte textf
- read_vlq file-handle
-
Reads a variable length quantity (VLQ) from the file-handle, or failing that throws an error. VLQ are used for MIDI durations (dtime). The
w
template to thepack
orunpack
functions is a more efficient way to convert such quantities, though does not work on a file handle.
BUGS
None known. However, the module is very incomplete.
SEE ALSO
COPYRIGHT AND LICENSE
Copyright 2024 Jeremy Mates
This program is distributed under the (Revised) BSD License: https://opensource.org/licenses/BSD-3-Clause