A musical 12-tone alarm for the Raspberry Pi (part 2)

In part 1 I showed the development of the serialrpi.sh script which generates a random 12-tone tune. One of the facilities was to archive all the different tunes it produces. To start part 2 of this article, I will show how to process and make use of the archived tunes so that they can be viewed (and listened to) conveniently.

Creating an archive
We want to create an archive containing say 10 tunes which can be displayed together on a web page. This can be done with serialrpi.sh “as is”, with an entry being added each time it is run, but it will be quicker if we bypass the code which displays the tunes as they are created. To do this  first move to the directory where you have located the serialrpi.sh script, if this is not in your home directory ~/ Mine was in a directory called 12note so I did cd ~/12note
then make a copy of the serialrpi.sh script by typing cp serialrpi.sh makearchive.sh
Now open makearchive.sh either with nano from the command line or with leafpad from the desktop, and do the following [Nano note: you can delete a line in nano using ctrl+k (you can put it back with ctrl+u  These are equivalent to cut and paste commands. YOu can search for a phrase using ctrl+w then type the phrase and push return]

1 In the comments on lines 3 and 4 change serialrpi.sh to makearchive.sh

2 Find and delete the line

prefbrowser=midori #select midori or netsurf

3 Find  and delete the line

quitbrowser=TRUE #TRUE forces browser to quit at end of script or not if FALSE

4  Find and delete the section

#check if Desktop is running
 if [[ `pidof lxsession` = "" ]]
 then
 echo 'no desktop running on the Pi.startx & from this terminal, then rerun'
 exit
 else
 export DISPLAY=:0
 fi
echo prefbrowser is $prefbrowser #print preferred browser name

5  Find and delete the section

if [ "$(pidof $prefbrowser)" ] #first kill existing browser if running
then
killall $prefbrowser
fi
echo 'Starting Web Browser'
if [ $prefbrowser = midori ]
then
#rm -f ~/.config/midori/session.xbel
$prefbrowser -e Fullscreen -a $web &
else 
$prefbrowser file://$web &
fi
sleep 4
#allow time for web browser to open
echo Playing midi file
sleep 2
timidity $midifile &> /dev/null #play midi file
#wait before killing browser
sleep 2
if [ $quitbrowser = TRUE ] #then force browser to quit
then
killall $prefbrowser
echo browser killed
fi

6 resave the file.( If using nano use ctrl+x   Y   ENTER)

7 check that the file is executable. ls -l makearchive.sh should give something similar (apart from the date) to
-rwxr-xr-x 1 pi pi 10754 Aug  8 18:12 makearchive.sh
If the there are no x in the permissions then chmod 755 makearchive.sh should add them

If you don’t want to do the above, you can use serialrpi.sh, but it will take longer to create the archive, as the webrowser has to display the file each time and the tune is played.

For the purposes of this development we will use a fresh archive, so you can either delete any existing archive in ~/tonearchive, the default setting, or change the archivepath in makearchive.sh (or serialrpi.sh if you are going to use that)

using nano or leaf change the line

archivepath=~/tonearchive/ #set path to save timestamped archives (end in /)

to

archivepath=~/testarchive/ #set path to save timestamped archives (end in /)

Alternatively you can cheat and take a copy of makearchive.txt here  or use
wget http://r.newman.ch/rpi/sounding-off/makearchive.txt on your Pi and then
mv makearchive.txt makearchive.sh followed by chmod 755 makearchive.sh
This download already has the archivepath adjusted to ~/test/archive
(Useful tip: make use of the autocomplete facility. It can save a lot of time. you can type the first characters of the command and press ‘TAB’ to complete the command or to be presented available commands beginning with the typed characters, and you can do this repeatedly each time you start a filename or pathname in the command line.)

We will try the script once by typing ./makearchive.sh

All being well, you should see output similar to this

Lapsed time initialised to 0
Generating source music file lilyfile.ly
bar 1 has 2 notes
bar 2 has 4 notes
bar 3 has 5 notes
Total 0 minutes and 1 seconds elapsed.
Compiling lilyfile.ly with lilypond
Total 0 minutes and 27 seconds elapsed.
Archiving
Finished!
Total 0 minutes and 27 seconds elapsed.

and you can check the archive by typing ls ~/testarchive

where you should see a folder with a name similar to
tone-2013-08-08-18-47-31
The numeric part represents the date and time that the tune was created
here 8th August 2013 at 18:47 and 31 seconds. Yours will differ

This folder will contain 6 files like this

tonerow.html
tonerow.midi
tonerow.preview.pdf
tonerow.ly
tonerow.pdf
tonerow.preview.png

Now that you know that makearchive.sh works, delete the testarchive folder using
rm -R ~/testarchive
and we can run the program 10 times in a loop using
for i in {1..10}; do ./makearchive.sh; done
This will take around 5 minutes to complete, and will end up with 10 tune folders
in the archive directory.

Displaying the archive in a web page
We will now create programs to display the ten tunes in the archive in a web page. We will make two versions, the first will just display the printed tunes, the second will process the midi files to produce an mp3 music file for each tune, and produce a web page which displays the tunes, with a link  to play an embedded mp3. This will be for use with an external computer which can handle mp3 plugins. The page will display in Midori but the music can’t be played there.

Images only script

You can see the program by clicking below on createwpimgonly.sh You can collapse the expansion by refreshing the page.

#!/bin/bash
########################################################
#                     createwpimgeonly.sh
#   usage ./createwpimgeonly.sh
#	creates a webpage to display all the archived tunes
#	set pathtoarchive before running
#	written by Robin Newman August 2013
########################################################
# adjust next three lines to suit archive location, webpage dir name and file name
pathtoarchive=~/testarchive/ #end with trailing /
wpdir=webimgpage #name of directory to hold finished webpage
webpage=$wpdir/print.html #path to output web page in  archive directory
# you shouldn't have top make any changes after this line
p=`pwd` #save starting directory
cd $pathtoarchive #work in archive directory
rm -R $wpdir 2>/dev/null #delete any existing wpdir, suppress error if none
mkdir -p $wpdir/img #directory to hold preview images
#now setup web page header info cat all info to it until EOFhtml reached
cat > $webpage << EOFhtml
<meta http-equiv=Content-Type content="text/html; charset=UTF-8">
<title>12-Tone Tune of the Day</title>
<h2>Archive of Random 12-Tone Tune of the Day, with random rhythms</h2>
<p>
EOFhtml
for file in $( find -name *preview.png ) #enumerate the preview.png files
do #for each file found
#echo $file   #uncomment for testing purposes
n=$(echo $file |sed -e 's/\.\///1' -e 's/\/.*//') #strip leading ./  and all after next /
#n holds date info for the file in format tone-yyyy-mm-dd-hh-mm-ss
#echo $n  #uncomment for testing purposes
cp $file $wpdir/img/$n.png #copy and rename file into img directory
done
for file in $(  ls $wpdir/img ) #enumerate files in img directory
do #for each file found
name=$(echo $file |sed -e 's/tone-//' -e 's/\..*//') #strip tone- and .png
# now format name as yyyy-mm-dd at hh:mm and ss seconds
name=$(echo $name |sed -e  's/-/ at /3' -e 's/-/:/3' -e 's/-/ and /3' -e 's/$/ seconds/')
#now build rest of web page
#insert title for tune and image link for each tune
echo processing tune for $name
cat >> $webpage <<EOFhtml
===============================================================================
<h2>Tune compose date $name</h2>
<p>
<img src="img/$file" alt="randomly generated 12-tone row"</img>
<p>
EOFhtml
done
echo 'image only version of webpage finished!'
cd $p #switch back to starting directory
echo 'Present working directory'
pwd
##################### End of Script #######################

you can see the text of the script here or download it to your Pi using
wget http://r.newman.ch/rpi/sounding-off/createwpimageonly.txt and then
mv createwpimageonly.txt createwpimageonly.sh followed by
chmod 755 createwpimageonly.sh

Before we run it perhaps an explanation of what it does is in order.
To make things easier it first save the current directory and then switches to the archive directory.
Then it sets up the webimgpage directory, deleting any existing one first, and puts a blank img directory inside that.
It starts off the webpage (print.html) by putting the header information into the file using the cat > $webpage <<EOFhtml command and entering the following lines into the file until the EOFhtml marker is found.
It finds in turn all the .png files with names ending preview.png, which is all the image files in the archived folders, and keeps a copy in variable n of the name of the initial archive folder by removing the leading ./ and all after the next / end using the sed command twice, and then copies the file into the img directory, renaming it as $n.png
Once all the png files have been copied to the img directory the program loops through each one in turn, strips off the tone- at the start of the filename and the .png at the end, and reformats the resulting string from yyyy-mm-dd-hh-mm-ss to yyy-mm-dd at hh:mm and ss seconds by using three sed substitutions one after the other.
Then the information for each tune is appended to the web page using
cat>> $webpage <<EOFhtml
and listing the following lines into the file until the EOFhtml flag is reached, and then looping back to process the next image.
Finally the programs switches back to the initial working directory and exits.

The path for the archive is ~/testarchive in the program, so we can go ahead and run it.
./createwpimgonly.sh
You will see output similar to this. (note my working directory is ~/testit)

pi@raspberrypi ~/testit $ ./createwpimageonly.sh 
processing tune for 2013-08-08 at 18:47 and 31 seconds
processing tune for 2013-08-08 at 18:47 and 53 seconds
processing tune for 2013-08-08 at 18:48 and 16 seconds
processing tune for 2013-08-08 at 18:48 and 39 seconds
processing tune for 2013-08-08 at 18:49 and 03 seconds
processing tune for 2013-08-08 at 18:49 and 27 seconds
processing tune for 2013-08-08 at 18:49 and 50 seconds
processing tune for 2013-08-08 at 18:50 and 13 seconds
processing tune for 2013-08-08 at 18:50 and 37 seconds
processing tune for 2013-08-08 at 18:51 and 00 seconds
image only version of webpage finished!
Present working directory
/home/pi/testit
pi@raspberrypi ~/testit $

If you now navigate to the archive directory you will see a new webimgpage directory containing the print.html webpage plus the associated img directory. You can copy these anywhere you like, including onto a different computer, as long as they remain in the same directory together.
If you are working directly on your Pi, from the desktop you can use Filemanager to navigate to ~/testarchive/webimgpage and then double click the print.html icon to view it, or right click the icon and choose the web browser you want to use to open it.
From the LXterminal you can type cd ~/testarchive/webimgpage followed by
midori -a print.html to open it in a new tab
or netsurf file://`pwd`/print.html (note the ` before and after pwd)
(file:// requires a full pathname to work) alternatively start netsurf with netsurf file:///home/pi
and then navigate to the print.html file.

The full version script  with mp3 sound
This version produces a web page which not only displays the tune, but holds an embedded mp3 file of what it sounds like. It is intended that the page is copied to another computer for display, or indeed copied to an external website to be displayed there. In my case my Pi has a mounted share on my Mac computer and I can copy and display it there. I also ftp the file to my external website for display there, more of which anon.

For simplicity I use two scripts, one to create the mp3 files, and the other, similar to the createwpimgonly.sh script to assemble the web page. They can be combined, or just run one after the other.

First setupmidimp3.sh

#!/bin/bash
########################################################
#                  setupmidimp3.sh
#   usage ./setupmidimp3.sh
#	sets up midi and mp3 directories for the archived tunes
#	set pathtoarchive before running
#	precedes use of createmp3webpage.sh script
#	written by Robin Newman August 2013
########################################################
pathtoarchive=~/testarchive/ #end with trailing /
wpdir=webpagefull #name of directory to hold finshed webpage
p=`pwd` #save starting directory
echo $p
cd $pathtoarchive
echo 'archive stored in '$pathtoarchive
rm -R $wpdir 2>/dev/null  #delete any existing wpdir suppressing error if none
mkdir -p $wpdir/midi
mkdir -p $wpdir/mp3

for file in $( find -name *tonerow.midi ) #enumerate tonerow.midi files
do
n=$(echo $file |sed -e 's/\.\///1' -e 's/\/.*//') #strip ./ and /tonerow.midi
#echo $file #'     '$n #show filename and stripped part uncomment for testing
cp $file $wpdir/midi/$n.midi #copy midi file to midi directory renaming with time part
done
for file in $( ls $wpdir/midi ) #enumerate files in midi directory
do
mp3file=${file//\.midi/\.mp3} #for each name replace .midi with .mp3
echo $wpdir/midi/$file converting to mp3 #print conversion to be done
#now make the file
#timdity outputs WAVE file to pipe from midi/$file input lame takes piped WAVE file and
#converts to mp3/$mp3file text output is discarded using &> /dev/null
`timidity -Ow -o - $wpdir/midi/$file 2> /dev/null | lame - $wpdir/mp3/$mp3file &>/dev/null`
done
echo 'Conversion finished. Files at '$pathtoarchive$wpdir'/mp3'
cd $p #switch back to starting directory
echo 'Present working directory'
pwd
####################  End of script  #######################

you can see the text of the script here or download it to your Pi using
wget http://r.newman.ch/rpi/sounding-off/setupmidimp3.txt and then
mv setupmidimp3.txt setupmidimp3.sh followed by
chmod 755 setupmidimp3.sh

The script starts saving the current directory, and switching to the archive directory where it removes any previous webpage directory It then makes the directory in variable wpdir (here set to webpagefull) and new sub directories midi and mp3 It then finds all the midi files in the archive directories stored for each tune and copies them to the midi directory, renaming them on the way as previously described in the createwpimgonly.sh script. for example the file in directory tone-2013-08-08-18-48-39 named tonerow.midi would become the file tone-2013-08-08-18-48-39.midi stored in the mp3 directory. Now it loops through the files in the midi directory and uses timidity and lame to create an mp3 file of each one, using the same file name, but replacing .midi with .mp3. The main processing line is `timidity -Ow -o – $wpdir/midi/$file 2> /dev/null | lame – $wpdir/mp3/$mp3file &>/dev/null` The `    ` execute the command in between once it has been evaluated timidity generates a wave file -OW which it outputs to a pipe -o – using the source file $wpdir/midi$file [which is for example  webpagefull/midi/tone-2013-08-08-18-48-39.midi] The pipe feeds the file to lame  [input file – from the pipe] which converts it to an mp3 file saved in  $wpdir/mp3/$mp3file [which expands for example to  webpagefull/mp3/tone-2013-08-08-18-48-39.mp3] The &2>/dev/null discards the text output of timidity and lame The loop continues until all the files have been processed taking 20 seconds or so for each one. If you run the script by typing ./setupmidimp3.sh you will see output similar to

pi@raspberrypi ~/testit $ ./setupmidimp3.sh 
/home/pi/testit
archive stored in /home/pi/testarchive/
webpagefull/midi/tone-2013-08-08-18-47-31.midi converting to mp3
webpagefull/midi/tone-2013-08-08-18-47-53.midi converting to mp3
webpagefull/midi/tone-2013-08-08-18-48-16.midi converting to mp3
webpagefull/midi/tone-2013-08-08-18-48-39.midi converting to mp3
webpagefull/midi/tone-2013-08-08-18-49-03.midi converting to mp3
webpagefull/midi/tone-2013-08-08-18-49-27.midi converting to mp3
webpagefull/midi/tone-2013-08-08-18-49-50.midi converting to mp3
webpagefull/midi/tone-2013-08-08-18-50-13.midi converting to mp3
webpagefull/midi/tone-2013-08-08-18-50-37.midi converting to mp3
webpagefull/midi/tone-2013-08-08-18-51-00.midi converting to mp3
Conversion finished. Files at /home/pi/testarchive/webpagefull/mp3
Present working directory
/home/pi/testit
pi@raspberrypi ~/testit $

This shows the name of each midi file being converted, one after the other.

Now we run a script similar to the setupwpimageonly.sh script, but modified to include the mp3 file link in the web page code.
The script is called createmp3webpage.sh and you can see the code by clicking on its title displayed below. Remember you can collapse the display afterwards by refreshing this page.

#!/bin/bash
########################################################
#            createmp3webpage.sh
#   usage ./createmp3webpage.sh
#	NB SOULD BE RUN AFTER /setupmidimp3.sh script
#	creates a webpage to play all the archived tunes
#	set pathtoarchive before running
#	written by Robin Newman August 2013
########################################################
pathtoarchive=~/testarchive/ #end with trailing /
wpdir=webpagefull #name of directory to hold finished webpage
webpage=$wpdir/print.html #path to output webpage in archive directory
p=`pwd` #save starting directory
cd $pathtoarchive
mkdir -p $wpdir/img #directory to hold preview images
rm $wpdir/img/* 2>/dev/null #empty but suppress errors if already empty
#now setup web page header info cat all info to it until EOFhtml reached
cat > $webpage << EOFhtml
<meta http-equiv=Content-Type content="text/html; charset=UTF-8">
<title>12-Tone Tune of the Day</title>
<h2>Archive of Random 12-Tone Tune of the Day, with random rhythms</h2>
<p>
EOFhtml
for file in $( find -name *preview.png) #enumerate preview.png files
do #for each file found
#echo $file  #uncomment for testing purposes
n=$(echo $file |sed -e 's/\.\///1' -e 's/\/.*//') #strip ./ at start & all after second /
#echo $n #n holds date info for the file uncomment for testing purposes
cp $file $wpdir/img/$n.png #copy and rename file into img directory
done

for file in $(  ls $wpdir/img ) #enumerate files in img directory
do #for each file found
name=$(echo $file |sed -e 's/tone-//' -e 's/\..*//') #strip tone- and .img
# now foramt name as yyyy-mm-dd at hh:mm and ss seconds
name=$(echo $name |sed -e  's/-/ at /3' -e 's/-/:/3' -e 's/-/ and /3' -e 's/$/ seconds/')
mp3file=${file//\.png/\.mp3} #create mp3 filename replacing .img with .mp3
#now build rest of web page
#insert title for tune,image and mp3 links for each tune
echo processing tune for $name
cat >> $webpage <<EOFhtml
===============================================================================
<h2>Tune compose date $name</h2>
<p>
<table border=0>
<tr>
<td width=78%><img src="img/$file" alt="randomly generated 12-tone row"</img></td>
<td width=22%></td>
</tr></table>
<p>
EOFhtml
done
echo 'mp3 version of webpage finished!'
cd $p #switch back to starting directory
echo 'Present working directory'
pwd
####################  End of script  #######################

you can see the text of the script here or download it to your Pi using
wget http://r.newman.ch/rpi/sounding-off/createmp3webpage.txt and then
mv createmp3webpage.txt createmp3webpage.sh followed by
chmod 755 createmp3webpage.sh

I won’t go into the operation of this script in detail, because it is very similar to the previously described createwpimageonly.sh script. The additions are a line to generate the corresponding mp3 filename from each image file name, and a change made to the code inserted into the web page for each tune to hold a placeholder for the mp3 file. In order to tidy up the layout in the webpage a simple table structure is incorporated in teh html code to line things up visually.

you run the script by typing ./createmp3webpage.sh

All being well, you now have a directory called webpagefull in the testarchive directory containing webpage print.html, together with the img, mp3 and midi directories. Strictly speaking the midi directory is not required for the web page, but I haven’t automatically deleted it, as it may be useful in the future in this format.

Copying the webpages elsewhere
The full version of the webpage will not play the music under midori or netsurf as they don’t support the necessary plugins to play the mp3 files directly.
You can of course play mp3 files directly on the Pi installing for example mpg321. I prefer to use the program sox together with the library libsox-fmt-mp3
you can install these with sudo apt -get install -y sox libsox-fmt-mp3

You can then use play filename.mp3

You can now copy the webpagefull directory, or just the print.html file and img and mp3 directories to another computer, putting them in the same directory or folder there, and load and run the print.html file there in a browser.

to copy the folder via scp, first put it into an archive file.

cd ~/testarchive
tar -cvzf webpagefull.tar.gz webpagefull

Then from a mac you can use scp in a terminal to type

scp pi@ipaddress-of-raspberry-pi:~/testarchive/webpagefull.tar.gz ~/.
to transfer it to your mac home directory (it will ask you for the pi password)
Once there you can type tar -zxvf webpagefull.tar.gz to extract the directory again.
You can then open it in the normal way from the mac desktop,by double clicking on the print.html icon.

From a windows computer you can install winscp and use that to copy the files across.

Alternatively you could transfer it to an external web server if you have access to one. I installed lftp on my Pi and transferred them to my r.newman.ch server using that.
You can see the files in a browser here webimgpage and here webpagefull

That completes part 2 of this article

In the final part I will discuss a version of the tune creation script which runs on the Pi but displays the results automatically on a Mac, entirely contrelled from the Pi

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s