As you are probably already aware, I have done some work with creating chords for use in MIDI music. I haven't shown you how to use them (with the exception of with Win32::MIDI). So I pulled out my snippets and went to work.
My grandparents used to have a grandfather clock that played the same tune as the Westminster chimes. It did this every hour, on the hour as chords. If you are not familiar with the Westminster chimes see this.
This takes the Westminster chimes tune and creates a MIDI file of that tune.
#!/usr/bin/perl -w use strict; use MIDI::Simple; # 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::Si +mple'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}); # 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, $sco +re) = @_; 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; }
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: My Favorite MIDI "Chordified"
by zentara (Cardinal) on Feb 14, 2003 at 13:47 UTC |