Re: Example of online MIDI through Perl at looknohands.com
[email protected] (zentara) Fri, 04 Jul 2003 09:11:15 -0400
| Newsgroups | perl.midi |
|---|---|
| Message-ID | <[email protected]> |
On Fri, 04 Jul 2003 08:08:00 +0000, [email protected] (Erique De La Neutique) wrote: > >Anyway, what I am trying to do is really quite simple for now. I just want >to play a single guitar chord. However, for more advanced features I need >higher level control over writing the MIDI file than manually coding every >single MIDI event. I assume that is something that the modules would prefer. >Thanks for any feedback on the page and any hints on how I might use the >MIDI Perl Modules for this instead. This was written by Mr Muskrat of perlmonks. It may give you some ideas. This will make the midi in whatever chord you select further down in the script, where I've indicated with #!!!!!!!!!!!!!!!!!!!!. ############################################################## #!/usr/bin/perl -w use strict; use MIDI::Simple; #Mr Muskrat # Here are our chord values my %chords = ( major => [0, 4, 7, 12], minor => [0, 3, 7, 12], major7 => [0, 4, 7, 11], minor7 => [0, 3, 7, 10], minor75 => [0, 3, 6, 10], dim => [0, 3, 6, 9], dom7 => [0, 4, 7, 10], major9 => [0, 4, 7, 11, 14], minor9 => [0, 3, 7, 10, 14], ); # the notes to be "chordified" and durations for our "score" # you will notice that this is the opposite notation taken by MIDI::Simple's n procedure # This is to make it extremely simple to "parse" # in this case, the tune is Westminster Chimes my @notes = ( ['Cs4', 'qn'], ['F4'], ['Ds4'], ['Gs3', 'hn'], ['Cs4', 'qn'], ['Ds4'], ['F4'], ['Cs4', 'hn'], ['F4', 'qn'], ['Cs4'], ['Ds4'], ['Gs3', 'hn'], ['Gs3', 'qn'], ['Ds4'], ['F4'], ['Cs4', 'hn'], ); #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # create the "score" in a major chord my @score = chordify(\@notes, $chords{major); #my @score = chordify(\@notes, $chords{dim}); #my @score = chordify(\@notes, $chords{minor}); #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # this the text_events we will add to the MIDI my @text = ( 'http://www.ely.anglican.org/parishes/camgsm/bells/chimes.html', 'Lord through this hour/ be Thou our guide', 'so, by Thy power/ no foot shall slide' ); # Setup the MIDI score and write to file MakeMIDI(96, 127, 4, 1, 14, 'westminster_chimes.mid', \@text, \@score); sub MakeMIDI { # MakeMIDI(QNM, VOLUME, OCTAVE, CHANNEL, PATCH, FILENAME, TEXT_EVENTS, SCORE); # Take a "score" of notes and write it out as a MIDI file # $qnm is quarter notes per minute # $volume is numeric or text # $octave, $channel, $patch are numeric # $filename is the complete filepath for the output file # $text is a reference to an array of text events # $score is a reference to my version of a score array # example of a valid "score array" # my @score = ( # [ 'qn', 'C5' ], # [ 'E5' ], # [ 'en', 'F5', 'A5' ], # [ 'G5' ], # [ 'wn', 'rest' ], # ); my ($qnm, $volume, $octave, $channel, $patch, $filename, $text, $score) = @_; my $tempo = int(60_000_000/$qnm); my @text = @$text; my @score = @$score; new_score; if (@text > 0) { for my $event (@text) { text_event $event; } } set_tempo $tempo; patch_change $channel, $patch; $channel = 'c'.$channel; $octave = 'o'.$octave; noop $channel, $volume, $octave; # Setup for my $line (@score) { n @$line; } write_score $filename; } sub chord { # chord(NOTE, CHORD); # NOTE is the base note of the chord # CHORD is a reference to the chord array # uses MIDI::Simple's interval procedure my ($note, $chord) = @_; return interval $chord, $note; } sub chordify { # chordify(NOTES, CHORD); # nice name, huh? # Take a "score" of notes and return a "score" of chords # NOTES is a reference to an array of notes to "chordify" # CHORD is a reference to the chord array # returns my version of a "score" # an AoA containing duration and notes... my ($notes, $chord) = @_; my @notes = @$notes; my ($dur, @score); for my $line (@notes) { my $note; ($note, $dur) = @$line; my @chord = chord($note, $chord); $dur ? push @score, [$dur, @chord]: push @score, [@chord]; } return @score; }