If you play a musical instrument, especially if you play a wind instrument, you’re going to want to tune once you’re sufficiently warmed up. For the not so musically-inclined, tuning is the process of making an adjustment to your instrument so that the notes you play, in particular notes which correspond naturally to the construction of the instrument, are produced accurately. Electronically speaking, you could say the notes are reproduced with the correct frequency.
For a simple example, consider the clarinet shown above. As with any tubular musical instrument, it’s fundamental pitch (the note it most naturally plays) is proportional to its length. In particular, the clarinet above is a B-flat clarinet, so by slightly lengthening it or shortening it, the fundamental note it produces can be made to match a concert B-flat.
Without going into too much detail, modern instruments tune to notes relative to A = 440 Hz above middle C (think the middle key on a piano). In the case of a B-flat clarinet, its fundamental pitch has a frequency of 466.164 Hz. Thus, a clarinet is “in tune” when a player adjusts his/her embouchure (the relative tension of the facial muscles and positioning of the lips and teeth) to play a B-flat and the sound that comes out of the instrument has a frequency of 466.164 Hz.
If the sound that comes out of a clarinet when attempting to play a B-flat has a frequency that is lower than expected, the instrument is said to be flat. Similarly, if the frequency of the sound is too high, the instrument is said to be sharp.
On a clarinet, the mouthpiece, which is the plastic and metal assembly against which the player blows, can be pushed in or pulled out slightly to adjust its tuning. So, if the player’s B-flat is sharp, the mouthpiece can be pulled out a little to lower the frequency and bring it in tune. Likewise, if the B-flat is flat (too low), the mouthpiece is pushed in slightly to raise the instrument’s pitch. Tuning an instrument to its proper concert pitch (B-flat in the case of our clarinet example) is a necessary first step to getting the other notes it can produce to also be in tune when they are played.
Experienced musicians and people with perfect pitch can tune by ear simply by listening to the note produced and adjusting the instrument’s tuning mechanism accordingly. The rest of us generally rely upon a device called a tuner that compares the frequency of the note we play to its mathematically calculated frequency. A modern digital tuner can be a standalone electronic device or even an application for a smartphone. An example is shown in Figure 2.
Figure 2. OEM Digital Tuner
These devices, which can be had for as little as $15, are generally powered by inexpensive, 8-bit microcontrollers. Knowing this, we can probably assume that such a tuner does not make use of digital signal processing (e.g. finding the fundamental frequency by means of a FFT) to compare the frequency of the note played to what it ideally should be. Instead, we figured such a device would probably operate in the time domain by comparing the note played to what it should be purely by means of frequency comparison.
Every instrument produces a unique sound that is colored by timbral impurities. These impurities are introduced by the shape of the instrument, the materials from which it’s constructed, and by the uniqueness of the musician’s embouchure (for wind players) or touch (for string and percussion players). The net result of these variations is that the waveform of the sound produced on a given instrument as played by any one musician is not spectrally pure but instead consists of a fundamental frequency superimposed by waveforms with various overtones (integer multiples of the fundamental frequency).
Knowing this, we felt that a tuning method that operates purely in the time domain with no consideration of spectral content would be most suitable for a low-cost processor. Considering that dedicated digital tuners run off one or two AA or AAA batteries, such an approach would also have the benefit of being particularly energy efficient.
Our goal was to construct a digital instrument tuner that could:
We implemented what might be considered a very simply analog-to-digital converter that takes the output from an analog microphone and turns it into a pulse train with the frequency equal to that of the note’s fundamental. The pulse train is then easily captured by a microcontroller, which can then perform all of the aforementioned tasks.
For hardware, we opted to use the EFM32 Series 1 Giant Gecko Starter Kit. While the Series 1 Giant Gecko microcontroller might be a bit overkill for the project at hand, the starter kit has a nice dot matrix memory LCD to use for output. Optimization for a smaller EFM32 microcontroller could follow later once the whole concept and application code had been proven.
To capture the sound from the instrument and output the pulse train, we used an analog MEMS microphone with an amplifier circuit connected to a 74VHC14 Schmitt-triggered inverter. Because we would need to both measure the frequency of the note being played and keep the tuner display updated, a multi-threaded software foundation was a no-brainer.
We used Micrium’s µC/OS real-time kernel to provide this environment, along with the kernel services needed to protect shared resources and synchronize the tasks. This RTOS foundation allowed us to simplify the design and implementation of our application code, which, at its most basic level, required just two tasks: one for sampling the pulse train and the other for displaying the tuner’s output.
For the display task to know what pitch is being detected, the measurement task needs some way to communicate results. To do this, we opted for a simple shared variable which the measurement task updates after each sampling period.
In multi-threaded applications, shared data must be protected by a kernel mechanism, such as a semaphore. Pending on a semaphore usually means that a task might block (be stuck waiting for new data) until it becomes available. This behavior is undesirable for our measurement task because it must sample the pulse train periodically.
µC/OS allows a non-blocking pend on semaphore, which provides resource safety without the risk of having a task block indefinitely. The drawback of this method is that some measurements might never be communicated to the display task. In practice, this is not an issue for the tuner because we are more concerned with a fast response to changes in pitch.
The design of our display task (Figure 3) follows the general outline of the flowchart below. However, we have included a signaling semaphore that the measurement task uses to notify the display task when the frequency variable has been updated. The display task blocks on this semaphore to avoid updating the display multiple times with the same data. This helps to reduce the overall energy use of the application.
Once it is signaled, the display task tries to access the shared frequency variable. It does so by trying to grab the tuner semaphore which is used to protect the shared data. Eventually, the semaphore will become available, allowing us to read the frequency value. The frequency is converted into a pitch using a simple lookup table. The remainder of the task deals with how the user interface will look when the pitch is displayed. We decided on a minimal design which provides a visual representation of how in or out of tune the played note is, as shown in Figure 4.
Figure 4. Tuner Display Output
The measurement task (Figure 5) implements an algorithm for reading the pulse train and calculating its average frequency. Pulses are captured using the WTIMER0 peripheral, while the LDMA reads a timestamp from WTIMER0 for each pulse detected. The timestamps are copied into a memory buffer over a period of 125 ms, as measured by the CRYOTIMER peripheral. Once the 125 ms has elapsed, the CRYOTIMER interrupt notifies the measurement task that the sample is ready.
The task averages the periods between pulses to calculate the frequency of the pulse train. This value is reported to the display task using the mechanisms described above. The LDMA and timer peripherals are then reinitialized for the next sample, and the task waits for the next CRYOTIMER interrupt.
A primary goal of this project was to devise a means of detecting the frequency of a note played by a musical instrument without the use of complex and computationally expensive signal processing algorithms. Use of such techniques, for example, FFTs, complicates software development, requires a substantial number of processing cycles, and increases energy use.
We needed a computationally simpler and less energy-intensive solution that would still permit reliable detection of the frequency of the note being played. A combination of hardware signal processing and software capture and analysis allowed us to do this with a substantially smaller computational footprint and, thus, less energy, than an FFT-based or similar approach.
The hardware front end of the frequency measurement portion of the tuner consists of an ADMP401 analog MEMS microphone with preamplifier circuitry followed by a 74VHC14 inverting Schmitt trigger. Figure 6 shows the signal flow through each stage of the hardware.
Although not currently implemented in the project due to time constraints but available for future implementation, a digitally-tunable low pass filter is placed between the microphone and the Schmitt trigger. Ideally, this would filter out harmonics (overtones) above the fundamental frequency of the note being played in order to improve the quality of the input to the Schmitt trigger. Figure 7 shows the hardware front end prototype.
The MEMs microphone captures the note played and passes an analog signal to the input of the Schmitt trigger. Depending on the instrument being played, this analog waveform will have a different envelope or shape, but it will still be periodic in nature and have the fundamental frequency of that note. As such, it will have periodic vertical crossings of the high and low Schmitt trigger threshold voltages if the input signal is properly scaled. In Figure 8, CH1 shows the input analog waveform at a frequency of about 866 Hz.
Figure 8. Oscilloscope Capture showing analog audio signal (microphone output) on CH1 and Schmitt-triggered output on CH2
A Schmitt trigger is essentially a comparator circuit with hysteresis, and, in this application, it functions as a 1-bit analog-to-digital converter. Thus, as the input signal rises above the Schmitt trigger input high threshold voltage (VIH), the inverting Schmitt trigger output transitions from logic high to logic low. Likewise, when the analog signal falls below the input low threshold voltage (VIL), the inverting Schmitt trigger output transitions from logic low to logic high.
Note that the Schmitt trigger implements hysteresis where VIH > VIL resulting in a more stable digital output in the presence of a noisy or non-monotonic input signal. The resulting output is a pulse train with the same frequency as the input analog waveform, in this case about 880 Hz. This digital signal is then routed to one of the MCU’s timer input pins where its edges are captured and used to quickly calculate the frequency of the note being played.
Surprisingly, the application ran almost exactly as expected when first tested with simulated instrument sounds. However, we did encounter a problem with higher frequencies resulting in pulse trains that did not correspond with the expected frequencies. In this case, our problem was caused by failure to reset the timer before each new sampling period. This meant that any pulses occurring after one measurement task ended up being counted and affecting the frequency calculated in the next run of the measurement task.
The system responded well to clean inputs from frequency generators, sine waves recorded through the microphone, and some simulated instrument sounds. However, accuracy began to degrade when more complex tones were played, such as those from a brass instrument.
As noted above, one aspect of the project originally conceived but not yet implemented is a low-pass filter that can be tuned to strip out harmonics coloring the sound from instruments as played by real people. Time constraints prevented this feature from being integrated into the demonstrated project. Naturally, more effort can still be spent to optimize energy use and get the entire system to provide substantial operating life from one or two alkaline batteries.