A metronome...


 
Thread Tools Search this Thread
Operating Systems OS X (Apple) A metronome...
# 1  
Old 06-05-2015
A metronome...

As you all know I hit the hardware and do strange things with the HW using shell scripting.

This is yet another one...

Well computer audio systems have two flaws, this code exploits one of them and the other I found with AudioScope.sh.
There are others so minor I will not pursue them any further.
Ignoring the second as it would not matter to the absolute vast majority of users I will decsribe the first.
All sound systems suffer with a click if the sound card is accessed by other SW.

As this occurs on EVERY PC I have used I decided to exploit it.

So I decided to test out this anomoly by creating a metronome.
In the case of this MBP the maximum beats per minute I could obtain was 180 so this became the upper limit.

The code is a fun one as I decided to make the click a tick and a tock... ;o)

The code is error proofed as far as is possible and any errors fix the BPM, (beats per minute), to 90 or 120.

It is called from anywhere you put it after changing the permissions to your requirements, as, './tick <BPM>[RETURN/ENTER]' without the quotes.

I don't think this has been done before...

Enjoy...
Code:
#!/bin/bash
# tick <bpm from 30 to 180>
# A simple metronome for kids...
# Issued as Public Domain at www.unix.com by B.Walker, G0LCU.
# MBP 13 inch, circa August 2012, OSX 10.7.5, default bash terminal.
clear
echo "Simple fun metronome for kids usage."
echo "Press Ctrl C to stop."
TIME=0.166
TIMER=0.000
BPM=$1
case $BPM in
	*[!0-9]*)
		BPM=120
		echo "User error, set the metronome to $BPM beats per minute..."
		;;
	*)
		BPM=$1
		;;
esac
if [ $BPM -lt 30 ] || [ $BPM -gt 180 ]
then
	echo "Usage: tick <bpm from 30 to 180>"
	BPM=90
	echo "User error, set the metronome to $BPM beats per minute..."
fi
# Generate the tick.wav and tock.wav files.
> /tmp/tick.wav
> /tmp/tock.wav
printf "\x52\x49\x46\x46\x2C\x00\x00\x00\x57\x41\x56\x45\x66\x6D\x74\x20\x10\x00\x00\x00\x01\x00\x01\x00\x40\x1F\x00\x00\x40\x1F\x00\x00\x01\x00\x08\x00\x64\x61\x74\x61\x40\x1F\x00\x00" >> /tmp/tick.wav
cp /tmp/tick.wav /tmp/tock.wav 
printf "\x00\xFF\x00\xFF\x00\xFF\x00\xFF" >> /tmp/tick.wav
printf "\x00\x00\xFF\xFF\x00\x00\xFF\xFF" >> /tmp/tock.wav
# Playback the tick tock pair to set up the TIMER variable.
echo "Testing 'tick'..."
afplay /tmp/tick.wav
echo "Testing 'tock'..."
TIMER=( $(time (afplay /tmp/tock.wav) 2>&1 1>/dev/null) )
TIMER="${TIMER[1]:2:5}"
TIME=$(echo "scale=3;((60/$BPM)-$TIMER)" | bc)
tock()
{
	afplay /tmp/tick.wav
	sleep $TIME
	afplay /tmp/tock.wav
	sleep $TIME
}
echo "Now running the metronome at $BPM beats per minute..."
while true
do
	tock
done

This User Gave Thanks to wisecracker For This Post:
# 2  
Old 06-05-2015
Interesting idea, it'd be more accurate to generate appropriate amounts of silence in a file and let the sound card do its own accounting of time. You could get quite high rates that way. Something like:

Code:
dd if=/dev/zero bs=1 count=${silence_bytes} > /tmp/silence.raw

while true
do
        cat /tmp/tick.raw /tmp/silence.raw /tmp/tock.raw /tmp/silence.raw
done > /dev/dsp

rm /tmp/silence /tmp/tick /tmp/tock

# 3  
Old 06-05-2015
Hi C688...

I already knew that and have already done similar in some Linux flavours but there is no such animal as /dev/dsp in Apple gear. There is not likely to be either so __direct__ access to a device is not possible. Hence the use of OSX's afplay command that exists in virgin OSX installs.

Bazza...

EDIT:
You might be interested in this I wrote a few years ago:-
Metronome For Beginner Musicians... « Python recipes « ActiveState Code

Last edited by wisecracker; 06-05-2015 at 06:55 PM.. Reason: see above.
# 4  
Old 06-16-2015
You use "tick" and "tock" alternating. My suggestion is to introduce another parameter "bar". It should be able to take values 2-13. Have the "tick" only on beat 1 for every bar, e.g.:

Bar=2 tick tock tick tock ....
Bar=3 tick tock tock tick tock tock ...
Bar=4 tick tock tock tock tick tock tock tock ....

etc..

The rationale is that any "bar" has some "inner structure". For instance a 4/4 bar is not just a sequence of 4 equal beats but in fact the first and third beats are stronger than 2 and 4 and 1 is even stronger than 3. For this reason "3/4" and "6/8" may look like the same fracture but in fact the beats are sounding quite differently (when higher numbers denote more stress on a beat 3/4 is "2 1 1 2 1 1 ..." whereas 6/8 is usually "3 1 1 2 1 1 3 1 1 2 1 1 ...". It makes sense to help the user of the metronome recognize the 1-beat (usually the stroke with the most significance) in every bar by making it sound differently.

Why 2-13: the longest metrum of any significance in practical music is 13/8, used for instance in "Blue Rondo à la Turk" by the Dave Brubeck Quartet (it is sometimes denoted as 9/8 // 4/4 alternating metrum, but i think it is a genuine 13-stroke bar structure). 12/8 is commonly used for slow Blues with the "triplet shuffle" feeling,

I hope this helps.

bakunin
These 3 Users Gave Thanks to bakunin For This Post:
# 5  
Old 06-16-2015
Hi bakunin...

By creating two more files like the original two but with less _amplitude_ then emphasis is easily possible.

SOX OTOH is capable of volume settings per call so that could override the above sentence except if someone decided to use '/dev/dsp' then the multiple file method is the only way.

Your suggestion of a "bar" parameter is equally simple I might just do it for fun...

Thanks for your interest...

(BTW I was classically trained on the Bb Boehme Clarinet and Cello and I am a self taught guitar player. Sadly however age has caught up and is taking its toll.)
Login or Register to Ask a Question

Previous Thread | Next Thread
Login or Register to Ask a Question