#!perl # "Camptown Races" # words and music written by Stephen Foster in 1849 # (refers to 1849 California gold rush) # v. 1.3 (Chords added) # v. 1.2 (Song format changed) # by David D. Seay g-s@navix.net # October 1999 # original was November 1998 use Mac::Speech; $chordSpeech = 'e e e' x 200; $chordNotes = 3; # could be 1, 2, 3, or 4 @chordNoteIntervals = split(",", "0,4,7,12"); @noteNames = split(" ", "c d e f g a b C D E F G A B C1"); @scalePitches = split(",", "48,50,52,53,55,57,59,60,62,64,65,67,69,71,72"); for $p (0..$#scalePitches) { $pitch{$noteNames[$p]} = $scalePitches[$p]; } $tempo_factor = .25; # Increase if ends of words are clipped # NOTE DURATIONS $dur{e} = .50 * $tempo_factor; # eighth note $dur{de} = .75 * $tempo_factor; # dotted eighth note $dur{'q'} = 1.0 * $tempo_factor; # quarter note $dur{dq} = 1.5 * $tempo_factor; # dotted quarter note $dur{h} = 2.0 * $tempo_factor; # half note $dur{he} = 2.5 * $tempo_factor; # half note + an eighth $dur{dh} = 3.0 * $tempo_factor; # dotted half note $dur{dhe} = 3.5 * $tempo_factor; # dotted half note + an eighth $dur{w} = 4.0 * $tempo_factor; # whole note # SONG FORMAT # Notes: Items must be delimited by tabs # 1) word or syllable to be sung # 2) pitch (how high or low) # 3) duration (how long # # Chords: Each chord must be on a line by itself. # (use elements of @noteNames for chord names) # # Hint: You can use a spreadsheet program to enter a new song. # 1) Put each note's info on a separate row. # 2) Column 1 = word; Column 2 = pitch; Column 2 = duration # 2) Select all of the spreadsheet cells. # 3) Paste into the '$song' variable below. # $song = <<"EOF"; c camp g q townn g q ray e q sis g q sing a q this g q sonnng e h g do e q daa d dh do e q daa d dh C five g q mile g q ray e de sis g q all a q day g q lonnng e h g oh d dq do e de da d q c day c w C go c q na c e run e q all g q night C w F go a dq na a e run C q all a q C day g w c bet g q my g q muh e e nee e e on g e the g e bob a q tail g q nag e dh g some d q bah d e dee d e bet e dq on d e the d e C bay c w EOF @song = split("\n",$song); $channel[0] = NewSpeechChannel ($Voice{'Ralph'}) or die $^E; SpeakText $channel[0], "Camptown Races" or die $^E; while (SpeechBusy()) {} for $v (0..$chordNotes) { $channel[$v] = NewSpeechChannel($Voice{'Zarvox'}) or die $^E; } $n = -1; while($n < $#song + 1) { $n++; if ($song[$n] eq "") { next } if (length($song[$n]) < 5 && $pitch{$song[$n]}) { # Chord ($word,$note,$dur) = split("\t",$song[$n+1]); SetSpeechPitch $channel[0], $pitch{$note}; for $c (1..$chordNotes) { SetSpeechPitch $channel[$c], $pitch{$song[$n]} + $chordNoteIntervals[$c]; } SpeakText $channel[0], $word or die $^E; for $c (1..$chordNotes) { SpeakText $channel[$c], $chordSpeech or die $^E; } select(undef, undef, undef, $dur{$dur} - .25); $n++; } else { ($word,$note,$dur) = split("\t",$song[$n]); # Note SetSpeechPitch $channel[0], $pitch{$note}; SpeakText $channel[0], $word or die $^E; select(undef, undef, undef, $dur{$dur}); } } select(undef, undef, undef, .5); for $v (0..$chordNotes) { DisposeSpeechChannel $channel[$v]; } # ===== Want to unsubscribe from this list? # ===== Send mail with body "unsubscribe" to macperl-request@macperl.org