Re: midi re-tempoizer
[email protected] (zentara) Fri, 03 Dec 2004 05:18:00 -0500
| Newsgroups | perl.midi |
|---|---|
| Message-ID | <[email protected]> |
On Thu, 02 Dec 2004 20:22:14 -0900, [email protected] (Sean M. Burke) wrote: >Speeds up or slows down a MIDI file by altering its set_tempo >events: > >require 5; >use strict; >use warnings; >use constant DEBUG => 0; >use MIDI; > ># [email protected] 2004-12-02 > >$ARGV[0] = $1/$2 if $ARGV[0] and $ARGV[0] =~ m[^(\d+)/(\d+)$]s; > >my( $scale, $in, $out ) = @ARGV; >die "Usage: scaletempo scalefactor infile.mid outfile.mid > scalefactor = how much faster to make it. > 2 = twice as fast > 6/7 = slow it down to 6/7ths of its current speed > .5 = slow it down to half of its current speed >" > unless @ARGV == 3 > and $scale =~ m/^(?: (?: \d*\.\d+ ) | \d+ )$/sx and $scale != 0 > and length( $in ) and length( $out ) > and -e $in and -r $in >; > >my $opus = MIDI::Opus->new({ 'from_file' => $in }); > >DEBUG and print "$in contains ", scalar($opus->tracks), " tracks.\n"; > >my $tweaked = 0; >foreach my $t ( $opus->tracks ) { > DEBUG and print " Tweaking track $t\n"; > foreach my $e ( @{ $t->events_r || next } ) { > if( $e->[0] eq 'set_tempo' ) { > $tweaked = 1; > DEBUG > 1 and print " event @$e\n"; > $e->[2] = int( .5 + $e->[2] / $scale ); > DEBUG > 1 and print " => @$e\n"; > } > } >} > >unless($tweaked) { > DEBUG and print "No track events found. Faking it.\n"; > my $new_ev = [ 'set_tempo', 0, int( .5 + 500_000 / $scale ) ]; > if( $opus->tracks == 1 ) { > DEBUG and print "Prepending [@$new_ev] to the one track.\n"; > unshift @{ $opus->tracks_r->[0]->events_r > || die "No events in track 0?!" }, $new_ev; > } else { > DEBUG and print "Prepending a [@$new_ev] tempo-track.\n"; > unshift @{ $opus->tracks_r }, > MIDI::Track->new( { 'events' => [$new_ev], } ); > } >} > >DEBUG and print "Writing $out\n"; >$opus->write_to_file( $out ); >DEBUG and print "Done.\n"; >exit; >__END__ Cool. This is a much asked for utility. I've been wracking my brain trying to figure out how to get the total playlength of a midi using Perl. Would anyone know how to do this? -- I'm not really a human, but I play one on earth. http://zentara.net/japh.html