-
Notifications
You must be signed in to change notification settings - Fork 197
/
Copy pathlpcMPEenc.m
85 lines (66 loc) · 2.17 KB
/
lpcMPEenc.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
function [T,M]=lpcMPEenc(A,E,N,H,G)
% [T,M] = lpcMPEenc(A,E,N,H,G) Encode LPC residual with multi-pulses
% A and E are the filter and excitation, respectively, returned by
% lpcfit. H is the hopsize in samples (128). Find an N-pulse (default 10)
% approximation to E for each frame, using a perceptual filter weighted
% by G (default 0.8). Each row of T specifies N sample indices, and
% each row of M gives the magnitudes of impulses at those times.
% 2001-03-20 [email protected]
if nargin < 3
N = 10;
end
if nargin < 4
H = 128;
end
if nargin < 5
G = 0.8;
end
% How many points to use for pcp wt filter
irlen = 40;
[nhops, ncols] = size(A);
T = zeros(nhops, N);
M = zeros(nhops, N);
for hop = 1:nhops;
base = (hop-1)*H;
efrag = E(base+[1:H]);
% Figure IR approx to pcp wt filter bit
ag = [1, A(hop, 2:ncols).*(G.^(1:(ncols-1)))];
hgamma = filter(1,ag,[1, zeros(1,(irlen - 1))]);
% Apply pcp wt to Efrag
wte = filter(1,ag,[efrag, zeros(1,(irlen))]);
wteorig = wte;
esynth = zeros(1,H);
% Iteratively find pulses
ptsdone = 0;
while ptsdone < N
rhw = conv(fliplr(hgamma), wte);
% Limit to acceptable range
rhw = rhw(length(hgamma) + [0:(H-1)]);
pos = find(abs(rhw) == max(abs(rhw)));
val = rhw(pos)/sum(hgamma.^2);
if esynth(pos) ~= 0
% Updating an existing point
oldval = esynth(pos);
%disp(['hop=',num2str(hop),' pt=',num2str(pt),' degenerate pos=',num2str(pos), ' val=', num2str(oldval),'->',num2str(val)]);
%plot([1:length(wte)], wte, pos - 1 + [1:length(hgamma)], val*hgamma);
%pause;
oldpt = find(T(hop,:) == pos);
% Update the values of the old point
M(hop,oldpt) = oldval + val;
esynth(pos) = oldval+val;
else
% It's a new point, so add a new pulse to our list
ptsdone = ptsdone + 1;
T(hop, ptsdone) = pos;
M(hop, ptsdone) = val;
esynth(pos) = val;
end
% Subtract from the residual
wte(pos - 1 + [1:length(hgamma)]) = wte(pos - 1 + [1:length(hgamma)]) - val*hgamma;
end
% subplot(211)
% plot(1:H,wteorig(1:H),1:H,wte(1:H),'r');
% subplot(212)
% plot(1:H, efrag, 1:H, esynth, 'r');
% pause
end