#!/usr/bin/perl -w

# Copyright (c) 2010 Jim Peters (http://uazu.net)

# TODO: judge difficulty of a scale based on both 2nd version and
# alternate-note slur exercise

%wikipedia = ('major' => 'http://en.wikipedia.org/wiki/Major_scale',
	      'harm-minor' => 'http://en.wikipedia.org/wiki/Minor_scale',
	      'mel-minor' => 'http://en.wikipedia.org/wiki/Minor_scale',
	      'chromatic' => 'http://en.wikipedia.org/wiki/Chromatic_scale',
	      'wholetone' => 'http://en.wikipedia.org/wiki/Whole_tone_scale',
	      'diminished' => 'http://en.wikipedia.org/wiki/Octatonic_scale',
	      'major-penta' => 'http://en.wikipedia.org/wiki/Pentatonic_scale',
	      'minor-penta' => 'http://en.wikipedia.org/wiki/Pentatonic_scale',
	      'yo-penta' => 'http://en.wikipedia.org/wiki/Pentatonic_scale',
	      'acoustic' => 'http://en.wikipedia.org/wiki/Lydian_dominant_scale',
	      'prometheus' => 'http://en.wikipedia.org/wiki/Hexatonic_scale#Prometheus_scale',
	      'hungarian' => 'http://en.wikipedia.org/wiki/Hungarian_gypsy_scale',
	      'minor-gypsy' => 'http://en.wikipedia.org/wiki/Gypsy_scale#Minor_gypsy_scale',
	      'byzantine' => 'http://en.wikipedia.org/wiki/Double_harmonic_scale',
	      'phrygian-dom' => 'http://en.wikipedia.org/wiki/Spanish_gypsy_scale',
	      'persian' => 'http://en.wikipedia.org/wiki/Persian_scale',
	      'dom-bebop' => 'http://en.wikipedia.org/wiki/Jazz_scale#Bebop_scales',
	      'major-bebop' => 'http://en.wikipedia.org/wiki/Jazz_scale#Bebop_scales',
	      'major-blues' => 'http://en.wikipedia.org/wiki/Jazz_scale#Blues_scale',
	      'minor-blues' => 'http://en.wikipedia.org/wiki/Jazz_scale#Blues_scale',
	      'major-arp' => '',
	      'minor-arp' => '',
	      'aug-triad-arp' => '',
	      'dom-7-arp' => '',
	      'min-7-arp' => '',
	      'min-maj-7-arp' => '',
	      'dim-7-arp' => '',
	      'half-dim-7-arp' => ''
	      );

sub write_file {
    my $fnam = shift;
    die "Can't create file: $fnam"
	unless open OUT, ">$fnam";
    print OUT join("\n", @_, '');
    die "Error writing file: $fnam"
	unless close OUT;
}

sub scalecode {
    my $tmp = shift;
    $tmp =~ s/^([CG]\d\d\d\d\d\d).*$/$1/;
    return $tmp;
}

sub title_key_short {
    my $key = title_key(shift);
    $key =~ s/-sharp$/#/;
    $key =~ s/-flat$/b/;
    $key =~ s/^One-octave (.*)$/$1-oct/;
    return $key;
}

sub title_key {
    my $tmp = shift;
    return $1 if ($tmp =~ /^(One-\S+\s\S+)\s+(.*)$/);
    return $1 if ($tmp =~ /^(\S+)\s+(.*)$/);
    die;
}

sub title_scale {
    my $tmp = shift;
    return $2 if ($tmp =~ /^(One-\S+\s\S+)\s+(.*)$/);
    return $2 if ($tmp =~ /^(\S+)\s+(.*)$/);
    die;
}

sub scalename {
    my $scale = shift;
    return substr($code2fnam{"C00${scale}00"}, 7);
}

sub wikiref { 
    my $scale = shift;
    my $name = substr(scalename($scale), 1);
    my $wikiref = $wikipedia{$name};
    die "Wikipedia scale not found: $name"
        unless defined $wikiref;
    return $wikiref;
}

sub status {
    print @_, "\e[K\r";
}

$| = 1;

@names = ();
@codes = ();
%sizes = ();
%titles = ();
%diffs = ();
%code2fnam = ();

%keyhtml = ();
%scalehtml = ();
%exchtml = ();

%name2hash = ();

die "Can't open hash list"
    unless open IN, "<tmp-hash-list";
while (<IN>) {
    my ($name, $hash) = split;
    $name =~ s/\.ly//;
    $name2hash{$name} = $hash;
    my $code = scalecode($name);
    $code2fnam{$code} = $name;
    push @names, $name;
    push @codes, $code;
}
die unless close IN;


die "Can't set up pipe from pnginfo"
    unless open IN, "cd out/img && pnginfo *.png |";
status "  Loading PNG sizes ...";
my $hash;
while (<IN>) {
    if (m|(.*)\.png|) {
	$hash = $1;
    }
    if (/Image Width:\s+(\d+)\s+Image Length:\s+(\d+)/) {
	$sizes{$hash} = "width='$1' height='$2'";
    }
}
#die "Error closing pipe from pnginfo"
#    unless close IN;
close IN;
status "";

for my $fnam (sort @names) {
    my $hash = $name2hash{$fnam};
    die "Missing size for name: $fnam" 
        unless defined $sizes{$hash};
    die "Can't open file: out/img/$hash.ly"
	unless open IN, "<out/img/$hash.ly";
    while (<IN>) {
	$titles{$fnam} = $1 if (/%% Title: (.*)$/);
	$diffs{$fnam} = $1 if (/%% Diff: (.*)$/);
    }
    die "Can't close file: out/img/$hash.ly"
	unless close IN;
}

@names = sort grep { /^[CG]\d/ } @names;
@codes = sort grep { /^[CG]\d/ } @codes;

@ocarinas = ("C", "G");
@keys = ("99", "00" .. "11");
@scales = map { substr($_, 3, 2) } grep { /^C00..00/ } @names;
@keyscales = map { substr($_, 1, 4) } grep { /^C....00/ } @names;

# Set up filenames
for my $oc (@ocarinas) {
    for my $key (@keys) {
        my $html = "key$key-$oc.html";
        $keyhtml{"$oc$key"} = $html;
    }
    for my $scale (@scales) {
        $scalehtml{"$oc$scale"} = 
            "scale" . scalename($scale) . "-$oc.html";
    }
    for my $keyscale (@keyscales) {
        $exchtml{"$oc$keyscale"} = 
            substr($keyscale, 0, 2) . scalename(substr($keyscale, 2, 2)) . "-$oc.html";
    }
}

# Standard header
sub header {
    my $title = shift;
    my @out = ();
    push @out, '<html><head><title>' . $title . '</title>';
    push @out, '<style type="text/css">';
    push @out, 'h1 { text-align:center }';
    push @out, 'h2 { text-align:center }';
    push @out, 'p.sub { text-align:center; font-style:italic; font-size:smaller }';
    push @out, 'p.swoc { text-align:center }';
    push @out, '.d0 { background-color:#33ff33 }';
    push @out, '.d1 { background-color:#99cc33 }';
    push @out, '.d2 { background-color:#ff9933 }';
    push @out, '.d3 { background-color:#ff6633 }';
    push @out, '.d4 { background-color:#ff3333 }';
    push @out, '.hh { background-color:#dddddd }';
    push @out, 'td.norm { padding-left:0.5ex; padding-right:0.5ex; text-align:center; }';
    push @out, 'td.d0 { padding-left:0.5ex; padding-right:0.5ex; text-align:center; }';
    push @out, 'td.d1 { padding-left:0.5ex; padding-right:0.5ex; text-align:center; }';
    push @out, 'td.d2 { padding-left:0.5ex; padding-right:0.5ex; text-align:center; }';
    push @out, 'td.d3 { padding-left:0.5ex; padding-right:0.5ex; text-align:center; }';
    push @out, 'td.d4 { padding-left:0.5ex; padding-right:0.5ex; text-align:center; }';
    push @out, 'td.hh { text-align:center; }';
    push @out, 'td.nobr { white-space:nowrap; }';
    push @out, '</style></head><body>';
    return @out;
}
sub footer { 
    my $out = '<p align="right"><i>This work is licenced under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.0/uk/">Creative Commons Licence</a></i>: <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.0/uk/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-sa/2.0/uk/88x31.png" /></a></p>';
    return $out . "\n</body></html>";
}

%keyclass = ();

sub calckeyclasses { 
    my $oc = shift;
    my $scale = shift;
    %keyclass = ();
    my $levmin = undef;
    my $levmax = undef;
    for my $key (@keys) {
	my $lev = $diffs{$code2fnam{$oc . $key . $scale . '00'}};
	$levmin = $lev if (!defined $levmin || $lev < $levmin);
	$levmax = $lev if (!defined $levmax || $lev > $levmax);
    }
    for my $key (@keys) {
	my $lev = $levmin == $levmax ? 0 :
	    ($diffs{$code2fnam{$oc . $key . $scale . '00'}} - $levmin) / ($levmax - $levmin);
	my $diff = 
	    $lev < 0.2 ? 'd0' : 
	    $lev < 0.4 ? 'd1' : 
	    $lev < 0.6 ? 'd2' : 
	    $lev < 0.8 ? 'd3' : 'd4';
	$keyclass{$oc . $key} = $diff;
    }
}
    

sub scalekeylinks {
    my $oc = shift;
    my $scale = shift;
    my $keybold = shift;
    my @out = ();
    calckeyclasses($oc, $scale);
    for my $key (@keys) {
	my $base = $oc . $key . $scale;
	my $name00 = $base . '00';
	if (defined $keybold && $keybold eq $key) {
	    push @out, "<td class='$keyclass{$oc . $key}'><a href='$exchtml{$base}'><b>" . 
		title_key_short($titles{$code2fnam{$name00}}) . "</b></a></td>";
	} else {
	    push @out, "<td class='$keyclass{$oc . $key}'><a href='$exchtml{$base}'>" . 
		title_key_short($titles{$code2fnam{$name00}}) . "</a></td>";
	}
    }
    return @out;
}


# Standard navigation block
sub navigation {
    my $oc = shift;
    my $noheader = shift;
    my @out = ();
    if (!$noheader) {
        push @out, "<p><br/><hr/></p>";
        push @out, "<h2>300 Scales and Arpeggios for ".
            "<a href='http://www.mountainsocarina.com/'>Mountains Ocarina</a></h2>";
    }
    push @out, "<table align='center' border='0'>";
    push @out, "<tr><td class='nobr'><a href='index.html'><b>Introduction, tricks and tips</b></a></td>";
    push @out, "<td class='hh' colspan='13'><b><a href='" . $keyhtml{"C99"} . 
        "'>C ocarina</a></b></td>";
    push @out, "<td class='norm'>&nbsp;</td>";
    push @out, "<td class='hh' colspan='13'><b><a href='" . $keyhtml{"G99"} . 
        "'>G ocarina</a></b></td>";
    push @out, "</tr>";
    push @out, "<tr><td class='nobr'><b>All scales in:</b></td>";
    my $first = 1;
    for my $oc (@ocarinas) {
        if ($first) { $first = 0; } else { push @out, "<td class='norm'>&nbsp;</td>"; }
        for my $key (@keys) {
            my $name = title_key_short($titles{$code2fnam{$oc . $key . "0000"}});
            push @out, "<td class='norm'><a href='" . $keyhtml{"$oc$key"} . "'>" . 
                "<b>" . $name . "</b></a></td>";
        }
    }
    push @out, "</tr>";

    my $cnt = 0;
    for my $scale (sort @scales) {
	push @out, "<tr><td class='nobr'><a href='" . $scalehtml{"$oc$scale"} . "'><b>" . 
	    title_scale($titles{$code2fnam{$oc . "00" . $scale . "00"}}) . 
            "</b></a>&nbsp;&nbsp;</td>";
        my $first = 1;
        for my $oc (@ocarinas) {
            if ($first) { $first = 0; } else { push @out, "<td class='norm'>&nbsp;</td>"; }
            push @out, scalekeylinks($oc, $scale);
        }
	push @out, "</tr>";
    }	
    push @out, "</table></p>";

    return @out;
}

sub img_tag {
    my $fnam = shift;
    my $hash = $name2hash{$fnam};
    die "Hash not found for file: $fnam" unless defined $hash;
    return "<img border='0' src='img/$hash.png' " . $sizes{$hash} . "/>";
}

sub other_oc {
    my $oc = shift;
    for (@ocarinas) {
        return $_ if ($_ ne $oc);
    }
}

sub oc_switch {
    my ($oc2, $html2) = @_;
    my $oc1 = other_oc($oc2);
    if ($oc1 eq $ocarinas[0]) {
        return "<p class='swoc'>For: <b>$oc1 ocarina</b> | <a href='$html2'>$oc2 ocarina</a></p>";
    } else {
        return "<p class='swoc'>For: <a href='$html2'>$oc2 ocarina</a> | <b>$oc1 ocarina</b> </p>";
    }
}

# All exercises for one key/scale
for my $oc (@ocarinas) {
    my $oc2 = other_oc($oc);
    for my $keyscale (@keyscales) {
        status "  Exercises $oc $keyscale ...";
        my $base = "$oc$keyscale";
        my $name00 = $code2fnam{$base . "00"};
        my $name01 = $code2fnam{$base . "01"};
        my $name02 = $code2fnam{$base . "02"};
        my $name03 = $code2fnam{$base . "03"};
        my $name04 = $code2fnam{$base . "04"};
        
        my $title = $titles{$name00};
        my $fnam = "out/" . $exchtml{$base};

        my $wikiref = wikiref(substr($keyscale, 2, 2));

        my @out = header $title;
        push @out, "<h1>$title</h1>";
        push @out, oc_switch($oc2, $exchtml{"$oc2$keyscale"});
        push @out, "<p class='sub'>(see also:";
        push @out, "<a href='" . $keyhtml{substr($base, 0, 3)} . "'>" . 
            title_key($title) . ", all scales</a>" . ($wikiref ne '' ? "," : " and");
        push @out, "<a href='" . $scalehtml{$oc . substr($base, 3, 2)} . "'>" . 
            title_scale($title) . ", all keys</a>" . ($wikiref ne '' ? ", and" : "");
        push @out, "<a href='$wikiref'>Wikipedia</a>"
            if ($wikiref ne '');
        push @out, ")</p>";
        
        push @out, "<p align='center'>" . img_tag($name00) . "</p>";
        
        push @out, "<p>Exercise 1: Try this either tongued or with the slurs as marked.</p>";
        push @out, "<p align='center'>" . img_tag($name01) . "</p>";
        
        push @out, "<p>Exercise 2: Upper mordents.  " .
            "Use alternative fingerings if that helps.</p>";
        push @out, "<p align='center'>" . img_tag($name02) . "</p>";
        
        push @out, "<p>Exercise 3: Inverted mordents.  " .
            "Use alternative fingerings if that helps.</p>";
        push @out, "<p align='center'>" . img_tag($name03) . "</p>";
        
        push @out, "<p>Exercise 4: Turns.  " .
            "Use alternative fingerings if that helps.</p>";
        push @out, "<p align='center'>" . img_tag($name04) . "</p>";
        
        push @out, navigation($oc);
        
        write_file $fnam, @out, footer();
    }
}

# For each scale, all keys
for my $oc (@ocarinas) {
    my $oc2 = other_oc($oc);
    for my $scale (@scales) {
        status "  Scale $oc $scale ...";
        my $fnam = "out/" . $scalehtml{"$oc$scale"};
        my $sname = title_scale($titles{$code2fnam{$oc . "00" . $scale . "00"}});
        my $title = "$sname, all keys";

        my $wikiref = wikiref($scale);
        
        my @out = header $title;
        push @out, "<h1>$title</h1>";
        push @out, oc_switch($oc2, $scalehtml{"$oc2$scale"});
        push @out, "<p class='sub'>(click on the score to view exercises for any scale" .
            ($wikiref ne '' ? "; see also <a href='$wikiref'>Wikipedia</a>" : "") .
            ")</p>";
        
        calckeyclasses($oc, $scale);
        
        for my $key (@keys) {
            my $base = $oc . $key . $scale;
            my $name00 = $code2fnam{$base . "00"};
            my $stit = $titles{$name00};
            push @out, "<p><span class='" . $keyclass{"$oc$key"} . 
                "'>&nbsp;$stit&nbsp;</span></p>";
            push @out, "<p align='center'><a href='$exchtml{$base}'>" .
                img_tag($name00) . "</a></p>";
        }
        
        push @out, navigation($oc);
        
        write_file $fnam, @out, footer;
    }
}
    
# For each key, all scales
for my $oc (@ocarinas) {
    my $oc2 = other_oc($oc);
    for my $key (@keys) {
        status "  Key $oc $key ...";
        my $fnam = "out/" . $keyhtml{"$oc$key"};
        my $title = title_key($titles{$code2fnam{$oc . $key . "0000"}}) . ", all scales";
        
        my @out = header $title;
        push @out, "<h1>$title</h1>";
        push @out, oc_switch($oc2, $keyhtml{"$oc2$key"});
        push @out, "<p class='sub'>(click on the score to view exercises for any scale)</p>";
        
        for my $scale (@scales) {
            my $base = $oc . $key . $scale;
            my $name00 = $code2fnam{$base . "00"};
            
            my $stit = $titles{$name00};
            push @out, '<p>' . $stit . '</p>';
            push @out, "<p align='center'><a href='$exchtml{$base}'>" .
                img_tag($name00) . "</a></p>";
            push @out, "<p align='center'><table border='0'><tr>";
            push @out, "<td class='norm'><a href='" .
                $scalehtml{"$oc$scale"} . "'>All keys</a></td>";
            push @out, "<td class='norm'>&nbsp</td>";
            push @out, scalekeylinks($oc, $scale, $key);
            push @out, "</tr></table></p>";
        }
        
        push @out, navigation($oc);
        
        write_file $fnam, @out, footer;
    }
}

@out = header "300 Scales and Arpeggios for Mountains Ocarina";
push @out, <<'EOF';
<h2>300 Scales and Arpeggios for
<a href='http://www.mountainsocarina.com/'>Mountains Ocarina</a></h2>

<p class='swoc'>
<a href="#intro">Introduction</a> | 
<a href="#scales">Scales + Arpeggios</a> | 
<a href="#notes">Notes</a> | 
<a href="#keysig">Key Signatures</a> | 
<a href="#fing">Alternate Fingerings</a> | 
<a href="#breath">Breathing</a> | 
<a href="#tricks">Tricks</a> | 
<a href="#dl">Download</a>
</p>

<h3><a name="intro">Introduction</a></h3>

<p><tt>&nbsp;&nbsp;&nbsp;&nbsp;</tt><a href="#scales"><i>SKIP straight
to the scales &gt;&gt;&gt;</i></a></p>

<p>Not so long ago I started learning to play the <a
href='http://www.mountainsocarina.com/'>Mountain Ocarina</a>.  I
started learning some tunes out of the "300 Celtic Folksongs" book,
but I also felt that I needed some exercises to help me master all the
fingerings and get used to playing in different keys.  Also, I have an
interest in improvisation.  This lead me to write some code to
generate a complete set of scales and arpeggios in all the possible
keys, with fingerings, for easy reference as I needed them.
(Engraving was done with <a href="http://lilypond.org/">LilyPond</a>.)</p>

<p>Most of the time playing music on an ocarina, you find yourself
going up and down a scale of some type: normally the major or minor
scale of some key, but sometimes a more exotic scale.  So it makes
sense to me to practice playing scales in the 3-4 keys that I use most
often so that the fingerings come easily.  The aim is to play the
scale easily FROM MEMORY, without looking at the music or fingering
charts.  Only then has it been mastered.</p>

<p>I also generated some additional exercises to help in practicing
ornamentation and steps of more than one note, again aiming to have
these changes come easily whilst playing or improvising.  Again, these
should be played FROM MEMORY for greatest benefit.</p>

<p>Since a lot of improvisation is based around scales other than the
plain major and minor scales, I searched through Wikipedia for all the
scales that I could find that use normal Western tuning.  Several of
these come from other varieties of flute, so are especially suited to
the ocarina's sound.  These are all shown with fingerings for all the
12 different keys.  (There are other Arab scales that it might be
possible to play on the ocarina, but only with a lot of
experimentation to find fingerings for quarter-semitones and so
on.)</p>

<p>Note that scales are pretty pointless in themselves -- they are
only the means to an end, which is greater proficiency on the ocarina
to play real music or to improvise.  Realistically, you're only going
ever need a few of these.  To help you choose easy keys to improvise
in, the scales that are most natural to play on the ocarina are shown
in green in the table below, and the most awkward are shown in red.
(This is calculated on the basis of the number of finger-changes that
the scale requires as you go up and down).  There are two versions of
these pages, one for the G ocarina and the other for the C ocarina.
The reason for this is the difference in the ideal fingering for the
B-flat (see below).</p>


<h3><a name="scales">Scales + Arpeggios</a></h3>
EOF

push @out, navigation("G", 1);
push @out, <<'EOF';

<h3><a name="notes">Notes on the scales</a></h3>

<p>All scales start and end on the root note, but to exercise the full
range of the ocarina for that scale, the top and bottom notes used in
the scale usually aren't the root note.  The scale goes up as high as
it can then down as low as it can, before returning to the root
note.</p>

<p>Below each scale are links to other keys.  The colour behind the
key-name text is related to how easy the scale is likely to be to
play, based on how complicated the finger-changes are.  Green is
easiest, red is most awkward.</p>


<h3><a name="keysig">Key Signatures</a></h3>

<p>Finding the key from a key-signature:</p>

<table border='0'><tr>
EOF

for my $qmin (0, 1) {
    for my $xx (!$qmin ? 0..7 : 5..11) {
        push @out, "</tr><tr>" if (!$qmin ? $xx == 5 : $xx == 7);
        my $maj = ($xx * 7) % 12;
        my $min = ($xx * 7 + 12 - 3) % 12;
        my $majkey = title_key_short($titles{$code2fnam{sprintf("C%02d0000", $maj)}});
        my $minkey = title_key_short($titles{$code2fnam{sprintf("C%02d0100", $min)}});
        my $majname = "$majkey major";
        my $minname = "$minkey minor";
        $majname = undef if ($qmin && $xx >= 5 && $xx <= 7);
        $minname = undef if (!$qmin && $xx >= 5 && $xx <= 7);
        ## Error in -minor file numbering, so -1
        $imgnam = ($qmin ? sprintf("keysig-%02d-minor", $xx-1) :
                           sprintf("keysig-%02d-major", $xx));
        push @out, "<td class='norm'>" . img_tag($imgnam) . "<br/>" .
            (defined $majname ? 
             "<a href='" . $exchtml{sprintf("G%02d00", $maj)} . "'>$majname</a>" :
             "&nbsp;") . "<br/>" .
            (defined $minname ? 
             "<a href='" . $exchtml{sprintf("G%02d01", $min)} . "'>$minname</a>" :
             "&nbsp;") . "</td>";
    }
}

push @out, <<'EOF';
</table>


<h3><a name="fing">Alternate Fingerings</a></h3>

<p>There are several sets of alternate fingerings for the Mountain
Ocarina.</p>

<p>For B-flat, the first fingering sounds best to me on my
polycarbonate C ocarina, but the second sounds best to me on my G
ocarina.  The official fingering is the last one, which sounds sharp
to me on both.  (I checked this by playing up and down the 
EOF

push @out, "<a href='" . $exchtml{"G0500"} . "'>F major</a>";

push @out, <<'EOF';
scale from F to C on both instruments, and also checking with a guitar
tuner.)  Of course you can adjust the tuning with your breath, so you
can compensate to some extent whatever the fingering, and your
instrument may be different in any case.  However, I had trouble with
'hearing' the wrong note and adjusting up instead of down sometimes
when playing scales from the official fingerings, which is why I've
included a different set of pages for the C ocarina.  The pages for
the C ocarina use the first fingering below, and for the G ocarina use
the official fingering.  Alternative fingering can also be useful to
make ornamentation easier:</p>
EOF

push @out, "<p align='center'>" . img_tag('alt-b-flat') . "</p>";

push @out, <<'EOF';
<p>For E-flat, sometimes in the scales you will see the second
fingering, where it is easier in a particular scale:</p>
EOF

push @out, "<p align='center'>" . img_tag('alt-e-flat') . "</p>";

push @out, <<'EOF';
<p>For C-sharp, the first fingering is always used on the sheets
because the second one can't be used on the C ocarina.</p>
EOF

push @out, "<p align='center'>" . img_tag('alt-c-sharp') . "</p>";

push @out, <<'EOF';

<h3><a name="breath">Breathing</a></h3>

<p>I have had some trouble with not getting enough oxygen in my lungs
when playing long pieces, especially with the G ocarina which doesn't
require much air.  Same if I am trying to play whilst walking along --
I get out of breath and have to stop playing to get some oxygen.  I
got some advice from an experienced woodwind/ recorder/
early-instrument musician.  There were a couple of suggestions to
try:</p>

<ul>

<li>At each breathing opportunity, breath out on the first and breath
in on the next, alternating; i.e. breath out, play a bit more, breath
in, play a bit more, and so on.  That way you change the air in your
lungs, i.e. you don't keep refilling the top 10%.  This is an oboe
technique.</li>

<li>Alternatively, breath out gently through the nose at the same time
as blowing into the ocarina.  That way you use up more air, and so you
can take a whole lungful of air at the next breath mark.  This is a
recorder technique.</li>

</ul>

<p>As a variation to the previous technique, you can also try
loosening your lips and blowing slightly 'around' the ocarina on a
long note, which has the same effect.  I'm still experimenting with
what is best for the ocarina.</p>

<p>There is also circular breathing, which is supposed to be really
hard to master, but which lets you blow forever without gaps; it
involves storing a bit of air pressure in your mouth to keep the note
going, whilst closing the back of the mouth and breathing in through
the nose.  I have no idea if it would work with the ocarina.</p>


<h3><a name="tricks">Tricks</a></h3>

<p>Some tricks with the mountain ocarina:</p>

<ul>

<li><b>Slides</b>: If you put down or lift up all of the fingers
simultaneously slowly and smoothly, almost in a rolling motion, you
can slide the pitch smoothly from one note to another.  Try sliding
slowly from low C to high C.  You can also use this to put little
'whoops' before a note, as a form of ornamentation.</li>

<li><b>Untongued notes</b>: If you start a note without tonguing it,
it has a softer start, which can be useful as another form of
expressiveness in the music.</li>

<li><b>Overdriven sound</b>: One of the nice things about the Mountain
Ocarina is that you can 'overdrive' the sound by blowing just a little
too hard.  You can give the start of the note a more aggressive edge,
or you can overdrive the sound for the whole note.  This is one of the
things that lets you vary the sound and communicate different emotions
through the music.</li>

<li><b>Reaching top F</b>: This is possible on both C and G ocarinas.
It seems harder to control on the C ocarina, though.  I found that
bringing the body of the ocarina down towards my chin helped
somehow.</li>

</ul>

<h3><a name="dl">Download</a></h3>

<p>All these web-pages can be downloaded as a ZIP for you to view on
your computer offline.  The ZIP also contains the LilyPond source for
the music, which you could use to generate PDFs or printouts.  It also
includes the Perl source for generating the LilyPond files, for any
programmers out there.</p>

<p><tt>&nbsp;&nbsp;&nbsp;&nbsp;<a
href="300scales.zip">300scales.zip</a></tt></p>

EOF

write_file "out/index.html", @out, footer;


status "";
