Our project set up to measure the response of a set of speakers.
Many people have graphic equalizers, but are unsure how to set them for optimum performance. Being somewhat audiophiles, my lab partner and I decided to build a device that would aid in setting the equalizer to give the most natural response. Some users may still adjust the equalizer depending on their tastes in music, i.e. if a person likes drum and base they will set an equalizer to deliver more bass or classical, more in the mid and high range, but in many professional situations, one would want the most natural response from the speakers, to see what the speakers are capable of by themselves. The device can also be used on its own to examine the frequency response of speakers to see how they respond to recreate the charts that many speaker companies give of their speakers. Speakers have a range at which they respond very well, and then roll off at the low and high ends. The better designed the speakers, the larger the range of frequencies at which they reproduce well and the smaller the roll off range.
We set out to measure the frequency response of an individual speaker. This is accomplished by producing a set of sinewaves at known frequencies and all at the same amplitude. The resulting sound level on a microphone is measured by the ATmega163. This value is manipulated to give a frequency response at each frequency played. These are in units of decibels relative to the average response of the system to all frequencies. Provided with thins information, a person can then set their equalizer sliders to the opposite value and attempt null-out imperfections in a speakers frequency response. We chose frequencies the are standard center frequencies for 7, 9, 10, 15 and 31 band equalizers making this device compatible with most any graphic equalizer.
We decided to split the design among ourselves, one would handle most of the hardware design while the other wrote the software to control the microprocessor. The most complicated calculation for the software involved creating the sine waves needed to produce certain frequencies , fortunately we had already written code to produce sine waves of many frequencies in lab 5, and since we went beyond the base requirements, we were already able to produce frequencies over the entire audible range.
Delay loops calculation and explanation:
To calculate the delay loops value we had to create a function of our assembly code with respect to the value of delay loops, i.e. how many instructions it took for different values of delay loops to generate each sample. We calculated that this value was frequency = 10 + 7 * delay loops. We rearranged the equation and determined that delay loops = (500000/frequency 10)/7. At first we just used that rounded off value, but we found that it was causing our frequency to be too inaccurate so we changed it to a float and rounded up wards if the decimal was 0.5 or more and down otherwise.
To calculate the frequency response we must produce the sine waves and then read them in with a microphone. Using this analog information, we can have the ATMega converter it into a digital value and easily perform operations on it. The first thing we need to do is to account for the DC offset, so we had to subtract this value from each frequency's A to D value. Once we had an array of these values, we had to calculate the average response, which just meant averaging the values in the array for the number of bands we are using. We then looked up an equation that would convert these values into a decibel scale, which we found to be:
20 * log(P/Po)
In our case, Po is the average response to all frequencies and P is the value for each individual frequency. Once we had these values we had the frequency response in decibels, our goal. These decibel values are relative to an idea 0 dB frequency response that would be achieved by a perfect set of speakers in an anechoic chamber.
The hardware used in this project consisted of a microphone, 4 op-amps, an 0808 DAC chip, a 16x2 line LCD display, two potentiometers, four pushbuttons, an ATmega163, an 8MHz crystal, a pin headers for in circuit programming of the MCU, LCD connection, serial connection, power, audio output, and mic input, as well as various other small components.
Main Hardware Elements:
The bands select screen.
We were able to use our sinewave generation code from lab 5 as a basis producing our sinewaves. We already knew that our code worked for producing sine waves from 500Hz to 55kHz, but we were unsure of how well it would do on the lower ranges. We tested it down to 20Hz and it worked fine, so a separate routine was not necessary for producing lower frequencies. We needed to be able to interrupt the hardware loop in our code, so further speed optimization was required to offset the performance loss that resulted from testing of a stop flag.
We had already decided most of the rudimentary external hardware that was to be used, all that remained was how to use it. We decided to set Port A as an input for the microphone, Port B as the output for the sine wave generator, Port C as an output for the 2x16 LCD, and Port D (pins 4-7) as an input for the 4 buttons we would need. These could be rearranged with the exception of port a as the microphone needed to be connected to one of the analog inputs so that we could use the on chip A to D converter.
Time accuracy was not a big issue in designing this project with the exception of the sine waves, but these were not timer dependent since it was all written in assembly. We decided to implement a two task scheduling system as we have done in many of our labs with timer 0 used to schedule the performance of the tasks. We built a debouncing state machine in task one and the second task would decode the button presses and perform appropriately. The four buttons that would be used were back, up, down, and enter. Back would be assigned to pin 4, up to pin 6, down to pin 5, and enter to pin 7.
We built a start up menu that would allow the user to scroll through the different number of bands, in this case, 7, 9, 10, 15, and 31 and display some text along with the number of bands. Once we had this written we tried to test the code we had so far and found that it did nothing. We were very puzzled, so we cleaned up the debouncing code a little, reprogrammed the chip, but still nothing happened. We went to debugging and found that the program was just infinitely resetting. Eventually we discovered that the only problem was that we imported the 8515 library and not the Mega library. Once this was fixed the buttons worked fine.
The next step to figure out was to make the sine wave generator stop. In lab 5 we just let the method run infinitely until an external interrupt was triggered upon which the whole setup would reset itself. However we could not do this anymore because we needed to run through many frequencies and analyze them after they have been produced. We decided to let each frequency be produced for one second, and to do this we would use timer one set to use the interrupt on match set to one second. This would then trigger a flag that told the sine wave method to stop. This meant turning on timer 1 in assembly, which turned out to just involve setting a few pins to certain values using the out instruction.
Once this worked we needed to actually read in the A to D values, at first we just did one per frequency, but we decided it would be better to do an average of 8 values. We then realized we needed to calculate a DC offset to account for the input to PA0 being non-zero when no sound is being made (see audio input section of hardware design) so we did this once the user decided to start the process. The only thing left to do at this point was to actually analyze the data we had. The calculations are explained in the High level design section, but here they are again:
To calculate the frequency response we must produce the sine waves and then read them in with a microphone. Using this analog information, we can have the ATMega converter it into a digital value and easily perform operations on it. The first thing we need to do is to account for the DC offset, so we had to subtract this value from each frequency's A to D value. Once we had an array of these values, we had to calculate the average response, which just meant averaging the values in the array for the number of bands. We then looked up an equation that would convert these values into a decibel scale, which we found to be:
20 * log(P/Po)
In our case, Po is the average response and P is the value for each individual response. Once we had these values we had the frequency response relative to in decibels, our goal.
Once this was all written, the basic outline of the whole program was completed. We then went back and cleaned up some of the displays on the LCD and added a screen that would be used while the device was producing different sine waves telling the user what frequencies were being produced. We also added a start up screen that displays when the device is first booted up. We also added a check to see if the speakers were at an appropriate level, so that we are analyzing more than just noise. The test for too soft works well. We have also written a test to handle the case that occurs when the volume is too high, maxing out the ADC. This remains untested because we could not get the speakers in the lab to produce a sound loud enough to be at 5 volts. That and everyone else in the lab probably would have killed us if we got louder speakers.
A screen showing the output of our program following a set of measurements.
We tested our project on two different pairs of speakers. A set of Labtec CS-550 (with both bass and treble boost on and off) and a set of SLN-167 speakers. Both sets of speakers were small, powered computer speakers. As such, they could not be expected to exhibit very good frequency response in low or high frequency extremes. This was indeed the response our device obtained for each set of speakers. We then tried to improve the frequency response of the Labtec speakers by using a 9 band equalizer. We were able to smooth out the frequency response of the speakers in the ranges the it could actually handle, but no amount of signal boosting was going to make those speakers put out 20 Hz at a decent volume. Here is a link to our measurements from these tests.
The frequency response values were repeatable showing, that we had managed to counteract most of the noise that originally interfered with our measurements.
The frequency response values are fairly accurate, given the frequency response of our microphone also shows up in any values an is unknown. Our code contains arrays of frequency values that are meant to be set to the frequency response of the microphone, allowing it to compensate for this problem, but the equipment to do this calibration was not available, nor was a calibrated mic.
MCU Connections and LCD Connections
Audio Output Section, -5V Supply, and Audio Input Section