| MIDI-Tools documentation | Contained in the MIDI-Tools distribution. |
MIDI::Tools - Various functions dealing with MIDI Events
use MIDI::Tools qw(...); # too much stuff, see below
MIDI::Tools - Various functions dealing with MIDI events
This is a collection of functions evaluating or transforming lists of MIDI events, probably most useful for algorithmic composition. It is designed to be compatible with Sean M. Burke MIDI-Perl suite of modules.
This module is in an early alpha stage of development. Interfaces are not written in stone yet, and stuff needs to be added. Near-future plans include: Dealing with intervals. Dealing with scales (transpose in scale, measure outsideness). Swingifying. Dealing with Chords.
All functions take a reference to a list of MIDI events as parameter and return a scalar or list of results.
Returns number of note_on events (excluding those with a velocity of 0).
Returns lowest and highest pitch ocurring in note_on events, or undef if no note_on events occur in $events.
Returns mean and standard deviation of pitches in MIDI note_on events.
All functions take a reference to a list of MIDI events as parameter and modify the events directly.
Remove all note_on and note_off events whose pitches lie outside ($lowest .. $highest).
Transpose events by a (positive or negative) number of semitones. Notes will not be transposed below 0 or above 127.
Christian Renz, <crenz@web42.com>
Copyright 2003 by Christian Renz
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
| MIDI-Tools documentation | Contained in the MIDI-Tools distribution. |
package MIDI::Tools; use 5.005; use strict; use warnings; require Exporter; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); @ISA = qw(Exporter); # Items to export into callers namespace by default. Note: do not export # names by default without a very good reason. Use EXPORT_OK instead. # Do not simply export all your public functions/methods/constants. # This allows declaration use MIDI::Tools ':all'; # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK # will save memory. %EXPORT_TAGS = ( 'all' => [ qw(note_count note_range note_mean note_limit note_transpose) ] ); @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); @EXPORT = qw( ); $VERSION = '0.02';
sub note_count { my ($e) = @_; return 0 if (!defined $e || !ref $e); my $count = 0; foreach (@{$e}) { $count++ if (ref $_ && $#{$_} >= 4 && $_->[0] eq 'note_on' && $_->[4] > 0); } return $count; }
sub note_range { my ($e) = @_; return undef if (!defined $e || !ref $e); my ($lo, $hi); foreach (@{$e}) { if (ref $_ && $#{$_} >= 4 && $_->[0] eq 'note_on' && $_->[4] > 0) { $lo = $_->[3] if (!defined $lo || $_->[3] < $lo); $hi = $_->[3] if (!defined $hi || $_->[3] > $hi); } } return undef if (!defined $lo); return ($lo, $hi); }
sub note_mean { my ($e) = @_; return undef if (!defined $e || !ref $e); my ($count, $sum) = (0, 0); foreach (@{$e}) { if (ref $_ && $#{$_} >= 4 && $_->[0] eq 'note_on' && $_->[4] > 0) { $count++; $sum += $_->[3]; } } return undef if ($count == 0); my $avg = $sum / $count; my $variance = 0; foreach (@{$e}) { if (ref $_ && $#{$_} >= 4 && $_->[0] eq 'note_on' && $_->[4] > 0) { $variance += ($_->[3] - $avg) * ($_->[3] - $avg); } } $variance /= $count; return ($avg, sqrt($variance)); }
sub note_limit { my ($e, $lowest, $highest) = @_; return undef if (!defined $e || !ref $e); my $i = 0; while ($i <= $#{$e}) { for ($e->[$i]) { if (ref $_ && $#{$_} >= 4 && $_->[0] =~ '^note_o(n|ff)$' && ($_->[3] < $lowest || $_->[3] > $highest)) { splice(@{$e}, $i, 1); } else { $i++; } } } }
sub note_transpose { my ($e, $semitones) = @_; return undef if (!defined $e || !ref $e); my ($count, $sum) = (0, 0); foreach (@{$e}) { if (ref $_ && $#{$_} >= 4 && $_->[0] =~ '^note_o(n|ff)$') { $_->[3] += $semitones; $_->[3] = 0 if ($_->[3] < 0); $_->[3] = 127 if ($_->[3] > 127); } } }
1;