with Audio and Midi output
Update June 30, 2014 (text below after the original post)
- MIDI Hardware Interface
- MIDI Software on PC
When practicing playing a musical instrument, one is often confronted with a metronome, that forces the musician to keep the time. After realizing that the metronome is nothing but a sequencer with a rather boring program, the step to building a simple sequencer that acts as a metronome but still forces the player to play on time, was not too long. Thus, the idea of the blues metronome was born. Using a blues sequence is just my preference, the program that I'll discuss below is easily adaptable to other schemes.
So, let's start with the description of the metronome. The schematics is shown in the drawing below. The central component is an Atmel chip with an Arduino bootloader burnt onto it. I built the setup with an Atmel 328 running at 16 MHz, pretending to be an Arduino Uno, or with an Atmel 168 running on the internal oscillator at 8 MHz. You can see that the standard LED is attached to pin 13 the same way a normal Uno is equipped. The speaker is attached to pin 9.
The sequencer has a simple user interface with a potentiometer that is used to adjust the speed or beats per second, one button to start or stop the metronome and two buttons to change the pitch at which the metronome plays its little sequence. I chose half tone steps and at startup the base tone for the metronome is middle C, the key in the center of the piano keyboard.
The fun starts defining the sequence to play. I picked as the basic block a walking bass line, which starts at the base note, then comes major third, followed by fifth, sixth, diminished seventh, sixth, fifth, and finally major third, for a total of eight notes. If we use as unit one half-tone (from the white to the adjacent black key on the piano) the walking bass sequence is (0,4,7,9,10,9,7,4). But listening to the same sequence going up and down is kind of boring, so I arranged it into an outer loop, that steps through the 12-bar blues sequence. In one incarnation, this can be described by 12 bars, each with a harmonic base note. Relative to the base note (or tonica), which determines the first four bars. This is followed by two bars with the fourth, or sub-dominant, as base note and two more bars at the tonica. After these eight bars the final four are based on the fifth, or the dominant, the fourth, and two more at the tonica. In units of half tones this sequence can be described (0,0,0,0,5,5,0,0,7,5,0,0) where 5 denotes five half-tones up from the base. If we for example play in the key of C, the fifth half tone up is F and seven half tones up is G.
The program is written using the Arduino programming environment. The entire program can be found here. Here are just a dew remarks about some of the more important features. At the top the pin for the respective functionality is defined, followed by an array containing the frequencies for the different notes. The array walk contains the half-tone pattern for the walking bass, described above and the array blues the half-tone pattern for the 12 bars of a blues. I also define a few variables, and especially the variable running which is used to suspend running of the metronome.
In the setup routine, which runs only once after booting the Arduino, the output direction of the used pins are defined. Note that I use internal pull-up resistors for the pins used for the buttons. I then fill the second part of the frequencies. After typing in the frequencies for the first two octaves, I remembered that the frequency doubles from one octave to the next.
The routine loop() is called continuously and I make sure it is called once per played note, in order to maintain some responsiveness of the user interface with the buttons. First the start button is queried and if, pressed the logic level is zero and the code in the if statement is executed, where a short beep is produced with the tone function provided by the Arduino library and then the running is toggled. A short delay provides some de-bouncing functionality. After the start button, the up and down buttons are queried. They increment or decrement the variable base by unity, which shifts the base or the key of the blues sequence by one half-tone. In this way the key of the blues accompaniment can be selected.
The following code section is only executed, if the variable running is non-zero. Here we need to keep in mind that we have two loop counters, the variable i loops from zero to 11 and denotes the bar in the blues sequence. The variable j runs from zero to 7 and denotes the position within the walking bass sequence. On the first note in every bar if (j==0) the LED is turned on, then the analog pin 0 that is connected to the central wiper of a potentiometer is read to determine the length of duration of the note and then, finally the tone is played using the built-in function tone(pin,frequency,duration) which takes three arguments: the output pin, the frequency in Hz, and the duration of the tone in ms. Note that we use the frequency that is the array element in the frequency table of notes with index base+blues[i]+walk[j] which is the proper note in bar number i and step j in the walking bass sequence. After playing the tone is launched, the program waits for the desired duration and then turns the LED unconditionally off. The next, rather cryptic line, increments i and j and makes sure that the endpoints are handled correctly. Note that I used this, somewhat arcane construction, in favor of nested loops over i and j, because here the user buttons are queried after every note, even if the tone generation is not running.
I did not address MIDI functionality in the basic description above. But the main parts consist of defining a few variables in the header and including Serial.begin(31250) in the setup section, which opens the serial port connected to the standard Arduino serial IO pins at the MIDI baud rate. In the loop section, between the tone() and the delay() commands, a three-byte MIDI telegram is written to the Serial port. The first byte describes a Note-ON event (0x90) on MIDI channel specified by the variable midi_channel. The next byte specifies which note is played, and we have to add the variable midi_base to make the counting in half-tones used for the plain audio output coincide with the MIDI numbering convention. The last byte is intensity with which the note is played, the velocity in MIDI parlance. After the delay the same MIDI telegram is sent, but as a Note-OFF (0x80) event. Connecting the transmit pin of the Arduino to a 5-pole DIN connector used in MIDI equipment will allow the metronome to control any other MIDI device. You can change the channel and velocity in the declaration section of the program near the top.
I tested the program on a solder-less breadboard and show a photo of the setup below. The 28-pin Atmel chip with the sticker 2009/8 indicating a doumilianove at 8 MHz is used in this particular setup. To the right the FTDI connector, that is needed for programming through the Arduino development system via USB.Near the bottom the green LED and the 330 Ohm resistor is visible. To the left of the Atmel chip is the potentiometer with the red knob. Slight;y above towards the right is a loudspeaker that I salvaged from a discarded motherboard. Also visible are the three small pushbuttons, one between speaker and CPU and two to the left of the potentiometer. Near the top right a pull-up resistor and a blue 100 nF capacitor for the reset circuitry are visible. Note that the USB connector and the rest circuitry are only needed for programming. On this picture the MIDI interface is not implemented, and to be honest, this part is not tested in this setup, but I used it successfully in another project before.
The basic setup using the audio output, however, is fully operational and tested. Of course, this project can be considered as a starting point for improvements, such as a small power amplifier (LM386 style) to make more noise. A user interface with a menu and selection of MIDI channel and velocity. There are plenty of pins available for additional LEDs and buttons. Feel free to add your favorite features.
You might also want to check the web site
Update from June 30, 2014 follows
Using a 16 MHz crystal and flashing the Atmel chip with the Arduino UNO
bootloader is a better choice that using the 8 MHz internal oscillator.
Putting a 10 uF capacitor in series with the loudspeaker is needed
to decouple the DC level.
The midi_velocity value is set to 40 at startup near the top of the
source code file.
I added the pattern for the 'Baby Elephant Walk' from the movie Hatari.
You need to uncomment the appropriate line with in walk=... by removing
the double slashes (//) and putting them in front of the other definition
of the walk for the walking bass line.
I made the code smart enough to figure out the length of the walk and
blues arrays at run time. So if you want to change them, you just need
to replace the pattern in the int walk=... definition.
There is an annoying mismatch between the audio signal and the MIDI
signals, which is somewhat fixed by first sending the NOTE-ON signal,
waiting a few ms, then playing the analog audio sound, waiting and
then sending the NOTE-OFF command.
MIDI Hardware Interface
I tried two MIDI different interfaces for the computer. The first was an
old Soundlaster card that sports a MIDI interface on a DSUB-15 connector
on which pin 4 is ground, pins 1, 8, and 9 carry 5 V and pin 15 is MIDI in.
The only problem is that the sound card manufacturer saved a few pennies by
omitting an optocoupler from the input which is required to avoid ground loops.
I used a 6N135 sandwiched between pin 3 of the Atmel chip and DSUB pin 15
as shown in the attached sketch. It took me a while to get the polarity right,
because an optocoupler behaves like an inverter.
I have not (yet) tried to power the metronome from the DSUB-15 5V line,
but then even the opto-coupler could be omitted. Just make sure the polarity
is correct by adding a transistor inverter.
Finally I bought a USB MIDI interface (from Deltaco, which was least expensive)
and tried the metronome with it. This worked right out-of-the box and enables
me to use a laptop instead of old computers with even older soundblaster cards
sourced at local flea markets.
In order to use the MIDI output we need a MIDI capable output device,
that is, a box that interprets the MIDI instructions coming in on a
serial interface and turning them into something audible. A rather
flexible program to accomplish this is the <TT>vsthost</TT> that can
be downloaded from <TT>http://www.hermannseib.com/english/vsthost.htm</TT>.
This little gem listens to MIDI commands on one end, allows the user to
place a VST plugin in the middle and pipes the output to the soundcard on
the other end. In case you wonder, VST plugins are virtual instruments or
other device such as hall-effect or special amplifiers that are usually
employed in digital audio systems. The vsthost zip file suitable for your
type of operating system (I used the Windows version) can be extracted
straight into a folder (C:\vsthost in my case) and is can be executed
right away. No installation is needed. What is needed, is the installation
of a plugin that gives a voice to the MIDI sequences. In order to store
the plugins I created a subdirectory C:\vsthost\plugins. There are plenty
of sites on the web, both free and commercial, to get plugins and fill
the subdirectory. I use http://www.vst4free.com/ and downloaded the
4Front piano from the page with piano simulations and extract the contents
of the zip file (a .dll and a README file) to the plugins subdirectory.
Now it is time to start up the vsthost.exe program. It comes up with an
empty workspace on which two devices are places, 'Engine Input' on the
left and 'Engine Output' on the right. The first listens to MIDI sequences
and the latter makes sounds. In the file menu, select the 'New Plugin'
selection and navigate to the plugins subdirectory and choose the dll file
of the piano plugin. Doing this results in a new box appearing on the
vsthost workspace. If you connect the red dot on the right hand side of
'Engine Input' to the red dot on the left hand side of the piano, the
latter will listen to MIDI commands. You can test audio output with the
virtual keyboard (View->Keyboard bar, or the keyboard icon in the toolbar).
A small virtual keyboard appears on the bottom of the workspace and clicking
with the mouse on the keys generates some piano sounds. I tried this on a
freshly installed system and sound came out right away. A screenshot of the
workspace is shown in an attached picture. For more details please check the
vsthost manual, that is also in the zip-file.
Playing externally generated signals requires to select the MIDI input source
from the Devices->MIDI menu. You might also consider to install the ASIO4all
sound driver from http://www.asio4all.com/ to improve the latency of the MIDI
handling of your PC.