First go at adding the tune learner page.

This commit is contained in:
Jim Hague 2013-09-02 11:48:16 +01:00
parent fc1d7cfc88
commit deba133b3b
7 changed files with 254 additions and 27 deletions

View File

@ -22,6 +22,29 @@
<div class="grid_12 dottes-body"> <div class="grid_12 dottes-body">
<h1>@SUBTITLE@</h1> <h1>@SUBTITLE@</h1>
<!--#include file="intro.html" --> <!--#include file="intro.html" -->
<p>See <a href="#printing">below</a> if you'd like to print a book
of these tunes.
<p>Click on the tune title or first line music for a page showing
the dots for the tune and giving links for downloading the tune
in various formats. If you don't read music, or you'd like to work
on practicing learning tunes by ear, or just playing along with
the tune, click on the learner icon
<img width=20 height=20 src="../img/learner.png">
for a page where you can listen to the tune repeatedly, either
at the full playing speed or several slower speeds.
<p>When changes to this site are made, the issue number is incremented.
This is issue @BUILD@.
</div>
<div class="grid_12 dottes-body">
<h1>The tunes</h1>
<div class="dottes-tune-list">
<!--#include file="tunelist.html" -->
</div>
</div>
<div class="grid_12 dottes-body">
<a id="printing"><h1>Printing</h1></a>
<p>You can download a PDF with a booklet of these tunes. There is an <p>You can download a PDF with a booklet of these tunes. There is an
<a href="@BOOK@-A5.pdf">A5 landscape book</a> with one <a href="@BOOK@-A5.pdf">A5 landscape book</a> with one
tune per page, a <a href="@BOOK@-Nook.pdf">4x5in portrait book</a> tune per page, a <a href="@BOOK@-Nook.pdf">4x5in portrait book</a>
@ -33,15 +56,6 @@
<a href="@BOOK@-A5bookletA4.pdf">A5 booklet</a>. <a href="@BOOK@-A5bookletA4.pdf">A5 booklet</a>.
Print this onto A4 paper using both sides of the paper, and fold in half Print this onto A4 paper using both sides of the paper, and fold in half
to make an A5 booklet. to make an A5 booklet.
<p>When changes to this site are made, the issue number is incremented.
This is issue @BUILD@.
</div>
<div class="grid_12 dottes-body">
<h1>The tunes</h1>
<div class="dottes-tune-list">
<!--#include file="tunelist.html" -->
</div>
</div> </div>
</div> </div>
</body> </body>

163
dottes.html.learnertune Normal file
View File

@ -0,0 +1,163 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Cry Havoc tunes - learning @TITLE@</title>
<link rel="stylesheet" href="../css/reset.css" />
<link rel="stylesheet" href="../css/text.css" />
<link rel="stylesheet" href="../css/960.css" />
<link rel="stylesheet" href="../css/dottes.css" />
<link href='http://fonts.googleapis.com/css?family=Pirata+One|Oswald'
rel='stylesheet' type='text/css'>
</head>
<body>
<div class="container_12">
<a href="/">
<div class="grid_12 header-strip banner">
<h1>Ye Crie Havock Booke of Dottes</h1>
</div>
</a>
<div class="grid_12 dottes-body">
<div class="dottes-tune-display">
<div class="dottes-tune-header">
<div class="dottes-tune-header-row">
<div class="dottes-tune-header-left"></div>
<div class="dottes-tune-header-middle">
<h1>@TITLE@</h1>
<h2>@SUBTITLE@</h2>
</div>
<div class="dottes-tune-header-right">
<em>@COMPOSER@</em>
</div>
</div>
</div>
<p>@TITLE@ is in the key of @KEY@.
<div class="dottes-tune-footer">
<div class="dottes-tune-footer-row">
<div class="dottes-tune-footer-left">
<p>Normal speed
</div>
<div class="dottes-tune-footer-centre">
<audio controls loop>
<source src="../@MASTERBOOKE@/@TUNE@.mp3" type="audio/mpeg" />
<source src="../@MASTERBOOKE@/@TUNE@.ogg" type="audio/ogg" />
<object classid="clsid:22D6F312-B0F6-11D0-94AB-0080C74C7E95">
<param name="FileName" value="@TUNE@.mp3" />
<param name="autoStart" value="false" />
<param name="autoplay" value="false" />
<param name="playCount" value="100000" />
<object type="audio/mpeg" data="@TUNE@.mp3">
<param name="controller" value="true" />
<param name="autoplay" value="false" />
<param name="playCount" value="100000" />
</object>
</object>
</audio>
</div>
<div class="dottes-tune-footer-right">
<ul class="tune-data-list">
<li><a class="dottes-link-tune dottes-mp3"
href="../@MASTERBOOKE@/@TUNE@.mp3">MP3</a></li>
<li><a class="dottes-link-tune dottes-ogg"
href="../@MASTERBOOKE@/@TUNE@.ogg">OGG</a></li>
</ul>
</div>
</div>
<div class="dottes-tune-footer-row">
<div class="dottes-tune-footer-left">
<p>Slightly slower
</div>
<div class="dottes-tune-footer-centre">
<audio controls loop>
<source src="../@MASTERBOOKE@/littleslow-@TUNE@.mp3" type="audio/mpeg" />
<source src="../@MASTERBOOKE@/littleslow-@TUNE@.ogg" type="audio/ogg" />
<object classid="clsid:22D6F312-B0F6-11D0-94AB-0080C74C7E95">
<param name="FileName" value="littleslow-@TUNE@.mp3" />
<param name="autoStart" value="false" />
<param name="autoplay" value="false" />
<param name="playCount" value="100000" />
<object type="audio/mpeg" data="littleslow-@TUNE@.mp3">
<param name="controller" value="true" />
<param name="autoplay" value="false" />
<param name="playCount" value="100000" />
</object>
</object>
</audio>
</div>
<div class="dottes-tune-footer-right">
<ul class="tune-data-list">
<li><a class="dottes-link-tune dottes-mp3"
href="../@MASTERBOOKE@/littleslow-@TUNE@.mp3">MP3</a></li>
<li><a class="dottes-link-tune dottes-ogg"
href="../@MASTERBOOKE@/littleslow-@TUNE@.ogg">OGG</a></li>
</ul>
</div>
</div>
<div class="dottes-tune-footer-row">
<div class="dottes-tune-footer-left">
<p>Slow
</div>
<div class="dottes-tune-footer-centre">
<audio controls loop>
<source src="../@MASTERBOOKE@/slow-@TUNE@.mp3" type="audio/mpeg" />
<source src="../@MASTERBOOKE@/slow-@TUNE@.ogg" type="audio/ogg" />
<object classid="clsid:22D6F312-B0F6-11D0-94AB-0080C74C7E95">
<param name="FileName" value="slow-@TUNE@.mp3" />
<param name="autoStart" value="false" />
<param name="autoplay" value="false" />
<param name="playCount" value="100000" />
<object type="audio/mpeg" data="slow-@TUNE@.mp3">
<param name="controller" value="true" />
<param name="autoplay" value="false" />
<param name="playCount" value="100000" />
</object>
</object>
</audio>
</div>
<div class="dottes-tune-footer-right">
<ul class="tune-data-list">
<li><a class="dottes-link-tune dottes-mp3"
href="../@MASTERBOOKE@/slow-@TUNE@.mp3">MP3</a></li>
<li><a class="dottes-link-tune dottes-ogg"
href="../@MASTERBOOKE@/slow-@TUNE@.ogg">OGG</a></li>
</ul>
</div>
</div>
<div class="dottes-tune-footer-row">
<div class="dottes-tune-footer-left">
<p>Very slow
</div>
<div class="dottes-tune-footer-centre">
<audio controls loop>
<source src="../@MASTERBOOKE@/veryslow-@TUNE@.mp3" type="audio/mpeg" />
<source src="../@MASTERBOOKE@/veryslow-@TUNE@.ogg" type="audio/ogg" />
<object classid="clsid:22D6F312-B0F6-11D0-94AB-0080C74C7E95">
<param name="FileName" value="veryslow-@TUNE@.mp3" />
<param name="autoStart" value="false" />
<param name="autoplay" value="false" />
<param name="playCount" value="100000" />
<object type="audio/mpeg" data="veryslow-@TUNE@.mp3">
<param name="controller" value="true" />
<param name="autoplay" value="false" />
<param name="playCount" value="100000" />
</object>
</object>
</audio>
</div>
<div class="dottes-tune-footer-right">
<ul class="tune-data-list">
<li><a class="dottes-link-tune dottes-mp3"
href="../@MASTERBOOKE@/veryslow-@TUNE@.mp3">MP3</a></li>
<li><a class="dottes-link-tune dottes-ogg"
href="../@MASTERBOOKE@/veryslow-@TUNE@.ogg">OGG</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>

View File

@ -3,7 +3,12 @@
<a class="dottes-tune-link" href="@TUNE@.html">@TITLE@</a> <a class="dottes-tune-link" href="@TUNE@.html">@TITLE@</a>
</div> </div>
<div class="dottes-tune-list-item-image"> <div class="dottes-tune-list-item-image">
<a href="@TUNE@.html">
<img class="dottes-tune-table-image" src="firstline-@TUNE@.png" <img class="dottes-tune-table-image" src="firstline-@TUNE@.png"
alt="@TITLE@ first line"> alt="@TITLE@ first line">
</a>
<a href="learner-@TUNE@.html">
<img class="dottes-tune-table-image" src="../img/learner.png" alt="Learner">
</a>
</div> </div>
</div> </div>

View File

@ -13,6 +13,37 @@ fixtitle()
retval=`echo "$1" | sed -e "s/\(.*\), *\(.*\)/\2 \1/"` retval=`echo "$1" | sed -e "s/\(.*\), *\(.*\)/\2 \1/"`
} }
# Format a key in ABC (G, Gmin, etc.) in standard presentation format.
fixkey()
{
letter=${1:0:1}
accidental=${1:1:1}
if [ "$accidental" != "#" -a "$accidental" != "b" ]; then
accidental=""
mode=${1:1:3}
else
mode=${1:2:3}
fi
mode=${mode,,}
mode=${mode/ //g}
if [ "$mode" = "m" -o "$mode" = "min" ]; then
mode="Minor"
elif [ "$mode" = "mix" ]; then
mode="Mixolydian"
elif [ "$mode" = "dor" ]; then
mode="Dorian"
elif [ "$mode" = "phr" ]; then
mode="Phrygian"
elif [ "$mode" = "lyd" ]; then
mode="Lydian"
elif [ "$mode" = "loc" ]; then
mode="Locrian"
else
mode="Major"
fi
retval="${letter}${accidental} ${mode}"
}
if [ $# -lt 2 -o $# -gt 3 ]; then if [ $# -lt 2 -o $# -gt 3 ]; then
echo "Usage: makeWeb.sh <book dir name> <master book dir name> [<instrument name>]" echo "Usage: makeWeb.sh <book dir name> <master book dir name> [<instrument name>]"
exit 1 exit 1
@ -64,6 +95,7 @@ done
cp $1-*.pdf $webdir cp $1-*.pdf $webdir
# Now, for each tune, make the tune page. # Now, for each tune, make the tune page.
rm -f $webdir/$tunelist
find $bookedir -name "*.abc" | sort | find $bookedir -name "*.abc" | sort |
while read filename while read filename
do do
@ -90,28 +122,33 @@ find $bookedir -name "*.abc" | sort |
creditvisibility="yes" creditvisibility="yes"
fi fi
lastchanged=`hg log --limit 1 --template "{date|shortdate}" $filename` lastchanged=`hg log --limit 1 --template "{date|shortdate}" $filename`
key=`$dir/abcfield.py --field K $filename`
fixkey $key
key=$retval
# Copy the ABC into the web. # Copy the ABC into the web.
cp $filename $webdir cp $filename $webdir
# If we are not the master booke, link the mp3 in from the # If we are not the master booke, link the mp3s in from the
# master page in a desperate attempt to make IE8 work. # master page in a desperate attempt to make IE8 work.
# The Jenkins archive will dereference the soft link, it seems, # The Jenkins archive will dereference the soft link, it seems,
# but I guess I can live with copies of the MP3 for now. # but I guess I can live with copies of the MP3 for now.
if [ "$booke" != "$masterbooke" ]; then if [ "$booke" != "$masterbooke" ]; then
pushd ${webdir} > /dev/null pushd ${webdir} > /dev/null
ln -f -s ../${masterbooke}/${name}.mp3 ln -f -s ../${masterbooke}/*${name}.mp3
popd > /dev/null popd > /dev/null
fi fi
# Generate the tune web page. # Generate the tune web page.
tunepage=${name}.html tunepage=${name}.html
learnerpage=learner-${name}.html
# If the title contains HTML character entities, escape # If the title contains HTML character entities, escape
# initial '&' in the title - it means things to sed. # initial '&' in the title - it means things to sed.
sed -e "s/@TITLE@/${title//&/\&}/" \ sed -e "s/@TITLE@/${title//&/\&}/" \
-e "s/@SUBTITLE@/${subtitle}/" \ -e "s/@SUBTITLE@/${subtitle}/" \
-e "s/@COMPOSER@/${composer}/" \ -e "s/@COMPOSER@/${composer}/" \
-e "s/@KEY@/${key}/" \
-e "s/@MASTERBOOKE@/${masterbooke}/" \ -e "s/@MASTERBOOKE@/${masterbooke}/" \
-e "s/@CHANGETITLE@/${changetitle//&/\&}/" \ -e "s/@CHANGETITLE@/${changetitle//&/\&}/" \
-e "s/@CHANGETUNE@/${changefile/.abc/.html}/" \ -e "s/@CHANGETUNE@/${changefile/.abc/.html}/" \
@ -121,6 +158,19 @@ find $bookedir -name "*.abc" | sort |
-e "s/@LASTCHANGED@/${lastchanged}/" \ -e "s/@LASTCHANGED@/${lastchanged}/" \
-e "s/@TUNE@/${name}/" dottes.html.tune > $webdir/$tunepage -e "s/@TUNE@/${name}/" dottes.html.tune > $webdir/$tunepage
sed -e "s/@TITLE@/${title//&/\&}/" \
-e "s/@SUBTITLE@/${subtitle}/" \
-e "s/@COMPOSER@/${composer}/" \
-e "s/@KEY@/${key}/" \
-e "s/@MASTERBOOKE@/${masterbooke}/" \
-e "s/@CHANGETITLE@/${changetitle//&/\&}/" \
-e "s/@CHANGETUNE@/${changefile/.abc/.html}/" \
-e "s/@CHANGEVISIBILITY@/${changevisibility}/" \
-e "s/@CREDIT@/${credit}/" \
-e "s/@CREDITVISIBILITY@/${creditvisibility}/" \
-e "s/@LASTCHANGED@/${lastchanged}/" \
-e "s/@TUNE@/${name}/" dottes.html.learnertune > $webdir/$learnerpage
sed -e "s/@TITLE@/${title//&/\&}/" \ sed -e "s/@TITLE@/${title//&/\&}/" \
-e "s/@TUNE@/${name}/" dottes.html.tuneindex >> $webdir/$tunelist -e "s/@TUNE@/${name}/" dottes.html.tuneindex >> $webdir/$tunelist
done done

View File

@ -16,27 +16,23 @@ builddir=$dir/web/$1
mkdir -p $builddir mkdir -p $builddir
# Make MP3 and OGG files for the input .abc. In case we're generating # Make MP3 and OGG files for the input .abc. Since we're listening to
# to a live site (which we won't be), do this to temp files and rename # a doorbell playing the tunes, go for lowest quality (and hence smallest)
# into place to make updates as atomic as possible. # MP3 and OGG.
makeaudiofiles() makeaudiofiles()
{ {
name=`basename $1 .abc` name=`basename $1 .abc`
tmpname=${name}.tmp
abc2midi $1 -o $builddir/${tmpname}.mid abc2midi $1 -o $builddir/${name}.mid
timidity -OwM -o $builddir/${tmpname}.wav $builddir/${tmpname}.mid timidity -OwM -o $builddir/${name}.wav $builddir/${name}.mid
lame -m m -V 9 --quiet $builddir/${tmpname}.wav $builddir/${tmpname}.mp3 lame -m m -V 9 --quiet $builddir/${name}.wav $builddir/${name}.mp3
# Timidity can generate OGG directly. But we need to generate WAV # Timidity can generate OGG directly. But we need to generate WAV
# for lame, and oggenc produces smaller output. OGG is needed for # for lame, and oggenc produces smaller output. OGG is needed for
# Firefox's audio tag. FF doesn't support MP3, some others support # Firefox's audio tag. FF doesn't support MP3, some others support
# MP3 but not OGG. # MP3 but not OGG.
oggenc -Q -q 0 -o $builddir/${tmpname}.ogg $builddir/${tmpname}.wav oggenc -Q -q 0 -o $builddir/${name}.ogg $builddir/${name}.wav
mv $builddir/${tmpname}.mid $builddir/${name}.mid rm $builddir/${name}.wav
mv $builddir/${tmpname}.mp3 $builddir/${name}.mp3
mv $builddir/${tmpname}.ogg $builddir/${name}.ogg
rm $builddir/${tmpname}.wav
} }
# Make audio for a new tempo for the abc file $1, giving the output files # Make audio for a new tempo for the abc file $1, giving the output files

BIN
web/img/learner.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -26,8 +26,7 @@
dance-out, there is a music-playing session. dance-out, there is a music-playing session.
<p>Havoc musicians come in all shades of experience and ability. <p>Havoc musicians come in all shades of experience and ability.
This collection is intended to help those like me who are inexpert with This collection is intended to help those like me who are inexpert with
instrument and folk music generally, but have a little musical instrument and folk music generally.</p>
background.</p>
<p>Being folk tunes, many of the tunes herein have many variations. <p>Being folk tunes, many of the tunes herein have many variations.
The music presented here is my attempt at reflecting what is actually The music presented here is my attempt at reflecting what is actually
played at Havoc sessions. I'm in no way suggesting that they are played at Havoc sessions. I'm in no way suggesting that they are