Matt Wright took Music 320 from Julius Smith in Winter of 2003.
He read most of these two books:
Mathematics of the Discrete Fourier Transform (DFT), by Julius O. Smith
Introduction to Digital Filters, by Julius O. Smith
He did a bunch of homework problems, many of which resulted in matlab programs. You can browse the directory of his homework results.
His final project was analysis and filtering of signals from a 3D accelerometer attached to a flute. Components of this project include the following:
Attaching accelerometer board to flute, getting data into Pd patch. (I had accomplished this already as part of my 250A project.)
Write incoming accelerometer values into Pd tables. (I used this Pd patch.)
Write Pd tables out as WAV files to be read into Matlab. You can browse the directory of these wav files or download them all in a single 161k tar.gz file. Beware, the headers on these say that they're sampled at 44.1k, but in fact they were sampled at about 625.5 Hertz. (It turns out that Matlab has a bug reading multi-channel WAV files, so all the work I did to get Pd to write 3-channel sound files (for accelerometer X, Y, and Z) had to be laboriously undone with a sound file editor to get triples of mono sound files instead.)
Load the sampled accelerometer data into Matlab with this script (I just copy and paste that code directly into the Matlab interpreter so that everything will be loaded as global variables.)
To listen to the accelerometer signals, just upsample the accelerometer data to audio rate like this
You can view the accelerometer signals in the time and frequency domains like this. One of the striking things I learned by looking at the data for key clicks (percussive tone hole closures with no excitation from the mouth) is that they're extremely broad spectrum with very little roll-off at "high" frequencies, i.e., up to the 312.25 Hz Nyquist rate. Another interesting thing is that different key clicks have different notches in frequency; although all are broad band, any given key click might or might not have energy at any particular frequency. We thought maybe this could be due to different ways that the mechanical system of the flute would be damped depending on which keys were down in any given moment. As expected, the key closures were much less obvious when breath was going through the flute (versus percussive key clicks).
One goal is to design efficient, low-latency filters that can separate the various performance gestures that are contained in the accelerometer data. The accelerometer outputs are centered around 2.5 volts, which when digitized by a 0-5 volt 10-bit ADC results in a DC bias near 500. One goal was to remove this DC bias adaptively, so as to avoid the currently-necessary calibration step. Another goal with the filters was to separate out the very low frequency changes in acceleration due to tilt of the flute (because of a change in the direction of gravity with respect to the accelerometer's frame of reference) versus the motions of the flute and the transients from key closures.
I tried to use the PeZ graphical pole/zero placement filter designer to design some of these filters. I didn't end up keeping any of these, but along the way I wrote this script for reading PeZ-outputted filter coefficients back into Matlab
To evaluate the results of different filters, I wrote the Matlab script try_filter.m which takes a signal and two arrays of LTI filter coefficients and plots the original signal, the filtered signal, and the difference between the original and the filtered signal. The variable copies (which should be an optional argument) sets the number of concatenated copies of the input signal that are fed through the filter to get rid of any transients.
To design a DC blocker, I wrote the Matlab script try_dcblock.m. The argument is the signal to be filtered and the radius of the pole for the one-pole DC blocker filter. The closer the pole is to 1 the smoother the DC component that will be filtered out (and the more time the filter takes before the DC is gone from the output). Visually, it seemed to me that a pole radius of 0.98 gave a DC signal that looked like the motion of the flute, but you can see for yourself:
try_dcblock(tiltx, 0.8); try_dcblock(tiltx, 0.9); try_dcblock(tiltx, 0.95); try_dcblock(tiltx, 0.98); try_dcblock(tiltx, 0.99); %% Set "copies" much higher in try_filter to get %% the transient out of this one: try_dcblock(tiltx, 0.9999);
I've just scratched the surface of this project. A few obvious next steps include separating a true dc blocker from the low frequency/high frequency tile/impact crossover filter and event detection for the key click impacts.