Problem 1 consists of four parts.
I first recorded myself saying my first and last name. Then, the time waveform, wideband spectrogram, and narrowband spectrogram are generated and displayed. Finally, two 30ms vowel segments are chosen and their magnitude and phase spectra are displayed.
The code for all four parts can be found here:
Code for Problem 1
Sound for Problem 1 (my name)
Problem 2
In this problem, we first generate a chirp signal that goes from 20Hz to 20kHz (human audible range). Next, an equal loudness curve is generated using the official iso226 standard. Finally, an “equal loudness chirp” is created by filtering the original chirp in the frequency domain by simple multiplication of the equal loudness curve. An audio file was also passed through the filtering process to generate and equal loudness version of the sound. The spectrums of the original and equal loudness versions can be seen in the last figure in the link below. It is apparent that the low frequencies were boosted, but not as obvious for the high frequencies because there weren’t many to begin with.
Code and figures for Problem 2
Sound for Problem 2 (chirp)
Sound for Problem 2 (equal loudness chirp)
BONUS
I chose the second method outlined in Zwicker, which uses two pure tones and the threshold of narrowband noise that is found by changing the separation of the two tones. The most challenging part of this bonus problem was generating narrowband noise (100Hz bandwidth) when the sampling rate is as high as 44100 Hz. I tried every kind of filter design technique I knew to get a filter with those specifications: IIR, FIR, butterworth, chebyshev, elliptical, parks-mclellen, cascaded second order section filtering, etc. None of these techniques provided the appropriate filter. I believe the problems I was having are discussed in the elliptical filter’s help file under the “Limitations” section. I finally gave up and used Simulink blocks to produce the appropriate noise source. Even then, it took simulink about 4 minutes to generate two seconds of narrowband noise!
I set out to verify Zwicker’s data in the Critical Band PDF where they show the test data of the test to find the critical band at 2kHz. I have two main loops in the program. The outer loop adjusts the frequency separation of the two pure tones, and the inner loop adjusts the level of the narrowband noise until the user decides it is masked. This was as accurate as I could think to make it. Thankfully, I did end up with a graph that closely resembles the one found in Zwicker’s book, and I got a similar result for the critical bandwidth at 2kHz.
This work definitely could have been extended to find critical bandwidths at other frequencies, but I believe that I have demonstrated the appropriate concepts. All I would have to do is add another outer loop that iterates over different center frequencies. The link below shows the code and the resulting figures from these tests.
Conclusion and Results
The first problem was straightforward. I originally forgot to unwrap the phase, but everything else went smoothly. However, the second problem did present quite a challenge. I was not satisfied by estimating an equal loudness curve, so I downloaded the official ISO226 files from the MathWorks website. This file returned length 29 arrays – frequencies and levels – that correspond to the equal loudness curve. These frequency values are heavily weighted towards those under 500 Hz. Basically, the spl values were not linearly spaced apart in frequency. To remedy this situation, I used spline interpolation over a range of 0 to 20500 for 100 data points. This created 100 points that were indeed linearly spaced in frequency and also went up to our Nyquist frequency (the iso226 spec stops at 12500Hz). The, I resampled the new dataset to be the appropriate length for my frequency domain multiplication. The final chip’s waveform clearly shows the equal loudness curve boosting and attenuating the signal in appropriate places. There is some slight noise in the final signal. This could be a result of the equal loudness curve zeroing out a very small range of high frequencies. When an audio file was used and its equal loudness counterpart was generated, this noise was not noticeable. (The “Bonus” section contains a thorough discussion/conclusion about finding critical bands with MATLAB)