Skip to content

Commit 0ee8536

Browse files
committed
Clean up LPC code documentation
1 parent 53612f0 commit 0ee8536

16 files changed

+155
-114
lines changed

Formant Analyzer/FormantPlotterTests/FormantPlotterTests.swift

+14-14
Original file line numberDiff line numberDiff line change
@@ -43,20 +43,20 @@ class FormantPlotterTests: XCTestCase {
4343
}
4444

4545
func testVowelRange() {
46-
XCTAssertEqual(analyzerForBaseName("arm").vowelRange().location, 24405)
47-
XCTAssertEqual(analyzerForBaseName("beat").vowelRange().location, 29961)
48-
XCTAssertEqual(analyzerForBaseName("bid").vowelRange().location, 25146)
49-
XCTAssertEqual(analyzerForBaseName("calm").vowelRange().location, 30662)
50-
XCTAssertEqual(analyzerForBaseName("cat").vowelRange().location, 26092)
51-
XCTAssertEqual(analyzerForBaseName("four").vowelRange().location, 34962)
52-
XCTAssertEqual(analyzerForBaseName("who").vowelRange().location, 22331)
46+
XCTAssertEqual(analyzerForBaseName("arm").vowelRange().location, 24407)
47+
XCTAssertEqual(analyzerForBaseName("beat").vowelRange().location, 29963)
48+
XCTAssertEqual(analyzerForBaseName("bid").vowelRange().location, 25147)
49+
XCTAssertEqual(analyzerForBaseName("calm").vowelRange().location, 30664)
50+
XCTAssertEqual(analyzerForBaseName("cat").vowelRange().location, 26093)
51+
XCTAssertEqual(analyzerForBaseName("four").vowelRange().location, 34964)
52+
XCTAssertEqual(analyzerForBaseName("who").vowelRange().location, 22332)
5353

54-
XCTAssertEqual(analyzerForBaseName("arm").vowelRange().length, 9993)
55-
XCTAssertEqual(analyzerForBaseName("beat").vowelRange().length, 6085)
56-
XCTAssertEqual(analyzerForBaseName("bid").vowelRange().length, 6217)
57-
XCTAssertEqual(analyzerForBaseName("calm").vowelRange().length, 9706)
58-
XCTAssertEqual(analyzerForBaseName("cat").vowelRange().length, 12004)
59-
XCTAssertEqual(analyzerForBaseName("four").vowelRange().length, 9854)
60-
XCTAssertEqual(analyzerForBaseName("who").vowelRange().length, 9936)
54+
XCTAssertEqual(analyzerForBaseName("arm").vowelRange().length, 9994)
55+
XCTAssertEqual(analyzerForBaseName("beat").vowelRange().length, 6086)
56+
XCTAssertEqual(analyzerForBaseName("bid").vowelRange().length, 6219)
57+
XCTAssertEqual(analyzerForBaseName("calm").vowelRange().length, 9707)
58+
XCTAssertEqual(analyzerForBaseName("cat").vowelRange().length, 12006)
59+
XCTAssertEqual(analyzerForBaseName("four").vowelRange().length, 9855)
60+
XCTAssertEqual(analyzerForBaseName("who").vowelRange().length, 9938)
6161
}
6262
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
LPC Formant Estimation
2+
======================
3+
4+
The isolated signals are analyzed with a Linear Predictive Coding model to find
5+
the formants.
6+
7+
Algorithm Description
8+
---------------------
9+
10+
1. Perform autocorrelation autoregressive model (LPC) of order `LPC_COEFF`
11+
12+
2. Calculate the complex roots of the LPC model
13+
14+
3. Ignore roots with positive imaginary part (arbitrary, could have also
15+
ignored the negatives)
16+
17+
4. Convert roots to frequency domain based on sampling frequency
18+
19+
And the chosen constants are given as:
20+
21+
- `LPC_COEFF` = 50;
22+
23+
**Warning: MATLAB documentation for the **`LPC`** function notes that windowing
24+
is implicitly implied. However, this might be a problem because our input is a
25+
periodic signal which does not go to zero at the beginning and end.**
26+
27+
Analysis
28+
========
29+
30+
You can perform this analysis using by running `estimateFormants.m`.
31+
32+
Following are the transfer functions for each recording.
33+
34+
![](<transferFunctions.png>)
35+
36+
Following are the complex roots.
37+
38+
![](<poles.png>)
39+
40+
Lastly, all the vowels are plotted on the common two formant plot. The first
41+
formant is the X axis and the second formant is the Y axis.
42+
43+
![](<formantPlots.png>)
44+
45+
Processing
46+
==========
47+
48+
Following is the full output:
49+
50+
> LPC error for arm is 2421
51+
52+
> First five format frequencies are: 697 1218 1845 2656 3253
53+
54+
> LPC error for beat is 2515
55+
56+
> First five format frequencies are: 329 2209 2224 2823 3245
57+
58+
> LPC error for bid is 2220
59+
60+
> First five format frequencies are: 463 1715 2633 3054 3271
61+
62+
> LPC error for calm is 2158
63+
64+
> First five format frequencies are: 449 750 1310 2900 2959
65+
66+
> LPC error for cat is 7835
67+
68+
> First five format frequencies are: 754 1650 2433 2827 3386
69+
70+
> LPC error for four is 3009
71+
72+
> First five format frequencies are: 411 612 1832 2810 3341
73+
74+
> LPC error for who is 3897
75+
76+
> First five format frequencies are: 455 1319 2363 2962 3427
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
%% LPC Formant Estimation
2+
% This routine reads 7 raw buffers with tails already clipped.
3+
% Then it applies LPC modeling to find the formant frequencies.
4+
%
5+
6+
LPC_COEFF = 50;
7+
8+
recordings = {'arm', 'beat', 'bid', 'calm', 'cat', 'four', 'who'};
9+
index = 1;
10+
11+
for recording = recordings
12+
base_file_name = recording{1};
13+
inFile = ['../Audio files/3-' recording{1} '-isolated.raw'];
14+
15+
Fs = 44100;
16+
fileId = fopen(inFile, 'r');
17+
audioSamples = fread(fileId, 'int16');
18+
fclose(fileId);
19+
20+
% Perform the LPC estimation
21+
[a,e] = lpc(audioSamples, LPC_COEFF);
22+
fprintf(1,'LPC error for %s is %0.f\n', base_file_name, e);
23+
24+
% Plot format frequencies for just this segment
25+
r = roots(a);
26+
r = r(imag(r) > 0);
27+
ffreq = sort(atan2(imag(r), real(r)) * Fs / (2*pi));
28+
fprintf(1, 'First five format frequencies are: ');
29+
fprintf('%0.f ',ffreq(1:5));
30+
fprintf('\n');
31+
32+
33+
% Plot #1: transfer function
34+
[h,f] = freqz(1, a, 1024, Fs);
35+
figure(1)
36+
subplot(7, 1, index)
37+
plot(f, 20*log10(abs(h)), 'LineWidth', 2);
38+
title(base_file_name)
39+
axis tight
40+
41+
42+
% Plot #2: the poles
43+
figure(2)
44+
subplot(7, 1, index)
45+
hold off
46+
zplane(r);
47+
xlabel('')
48+
ylabel('')
49+
axis([0 1 0 1])
50+
51+
52+
% Plot #3: plot with all formants
53+
figure(3)
54+
hold on
55+
plot(ffreq(1), ffreq(2), '*');
56+
text(ffreq(1)+2, ffreq(2)+2, base_file_name, 'Color', 'blue');
57+
58+
index = index + 1;
59+
end
60+
61+
62+
figure(3)
63+
axis tight
64+
axis(axis .* [0.9 1.1 0.9 1.1])
65+
grid on
Loading
Loading
Loading

Offline MATLAB analysis/Truncated_LPC/README.txt

-1
This file was deleted.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

Offline MATLAB analysis/Truncated_LPC/truncated_lpc_plot.m

-99
This file was deleted.
Binary file not shown.

0 commit comments

Comments
 (0)