[Date Prev][Date Next][Thread Prev][Thread Next] [Search] [Date Index] [Thread Index]

[MacPerl] Camptown Races (chords added)



#!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