Comparing the "Tone" of musical instruments in matlab
12 views (last 30 days)
Show older comments
I am trying to find a way to compare the likeness of short 500 millisecond recordings using metlab of the same note played on different instruments.
Going into detail on this specific topic: I am a music student that has been given the task to objectively determine the tone of various modern low brass instruments to determine what instrument should replace the obsolete "ophicleide" or Bass keyed bugle. I first used a visual comparison of a spectrograph of it and 6 other instruments, but that approach was too subjective.
I recorded all of the instruments with the same microphone, equipment, gain levels, and the same notes. For this reason, I believe that the signals are similar enough to use metlab tools.
I believe that comparing the fft is going to be the most accurate calculation. I tried at first a freq-domain correlation, and tested different segments of the same tone (eu, and eu2 being variables)
corr(abs(fft(eu)),abs(fft(eu2))) ans = 0.9963
Which is a step in the right direction, but I seem to get the opposite result when I compare different signals: (euphonium and ophicleide sound almost identical)
corr(abs(fft(eu)),abs(fft(ophi))) ans = 0.5242
euphonium and bass clarinet sound completely different, but this shows higher correlation
corr(abs(fft(eu)),abs(fft(basscl))) ans = 0.8506
I tried a normalized maximum cross-correlation magnitude formula that I found online, but I am getting the same results
>> norm_max_xcorr_mag = @(x,y)(max(abs(xcorr(x,y)))/(norm(x,2)*norm(y,2)));
x =eu2; y = eu;
norm_max_xcorr_mag(x,y)
ans = 0.9638
I get a similar result when comparing the other samples
>> norm_max_xcorr_mag = @(x,y)(max(abs(xcorr(x,y)))/(norm(x,2)*norm(y,2)));
x = eu; y = basscl;
ans = 0.6825
compared to
>> norm_max_xcorr_mag = @(x,y)(max(abs(xcorr(x,y)))/(norm(x,2)*norm(y,2)));
x = eu; y = ophi;
norm_max_xcorr_mag(x,y)
ans = 0.3519
The euphonium and Bass Clarinet (basscl) have a completely different sound, and completely different harmonic series, but these formulas are showing closer correlation than the Euphonium and Ophicleide, whose frequency bands look almost like an identical match.
I am worried that these correlations are showing the correlation of true pitch (I am playing the same note on all of these instruments, but the ophicleide might be out of tune by up to 1 Hz) It could also be accounting for phase, or even total amplitude.
does anyone know of a better clear cut method in comparing the proportions of the harmonic overtones of these complex waveforms?
or am I barking up the wrong tree?
2 Comments
Star Strider
on 2 Jun 2014
It’s MATLAB ported to Babbage’s Difference Engine. Early releases were, appropriately, called metal lab, owing to its technology.
Answers (1)
Star Strider
on 1 Jun 2014
Disclaimer: I love early music and am attempting to teach myself the lute (that won’t stay in tune).
I suggest knnsearch to start. I would use the magnitude ( abs ) of the fft of the signals, since they are sampled at the same time and in the same conditions, and are therefore the same length and frequency resolution. The phase information may not be necessary if you are simply comparing the spectral magnitude.
If this fails to reveal the true inheritor of the ophicleide’s place in early music, consider various Feature Transformation procedures on the magnitude spectra of the candidate instruments for dimension reduction to define the important features of the various instruments. (This is the sort of procedure used for biomedical signal analysis and classification, so it is likely valid for your application.)
4 Comments
Star Strider
on 2 Jun 2014
Edited: Star Strider
on 2 Jun 2014
I hope you did the baseline subtraction and normalisation before you did the knnsearch. Nonetheless, something is obviously wrong, unless I missed something in your latest comment. First, I may have gotten the argument order backwards in my suggested call to knnsearch. See what:
D = knnsearch(FFTInst, abs(fft(x)))
returns. It will be a vector of 12 indices in the ascending order of ‘distance’ from (similarity to) the magnitude of the fft of the ophicleide. Those indices will correspond to the rows in FFTInst. For instance, D(1) will be the index of the closest to the ophicleide, and so on for all 12.
- IDX = knnsearch(X,Y) finds the nearest neighbor in X for each point in Y . X is an mx-by-n matrix and Y is an my-by-n matrix. Rows of X and Y correspond to observations and columns correspond to variables. IDX is a column vector with my rows. Each row in IDX contains the index of nearest neighbor in X for the corresponding row in Y .
- [IDX,D] = knnsearch(X,Y) returns an my-by-1 vector D containing the distances between each observation in Y and the corresponding closest observation in X. That is, D(i) is the distance between X(IDX(i),:) and Y(i,:).
The output of knsearch should produce a vector for the indices of the various other instruments in order of ‘nearness’ of the their fft magnitudes to that of the ophicleide. By my count you should have one column vector (or two, depending on how you called knnsearch) that has only 12 elements. What are you plotting? I have no idea what knnsearch returns without any output arguments. Usually this is simply the first output, but it seems it returned something entirely different in your call to it.
If you want the correlation coefficients, include abs(fft(x)) (the fft magnitude vector for the ophicleide), possibly as the first row in a slightly differently named FFTInst matrix (maybe FFTInstR), and then use that matrix as the argument to the corr or corrcoef functions. You need to use all the functions with output arguments to understand the information they’re giving you.
Don’t worry about your hypothesis being disproved just yet. When we get all this sorted, it may turn out that you are correct.
See Also
Categories
Find more on Measurements and Feature Extraction in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!