dan@0
|
1 % multi_freq_ddm_int tests..
|
dan@0
|
2 N = 2^10-1;
|
dan@0
|
3 N_fft = 2^12-1;
|
dan@0
|
4
|
dan@0
|
5 fs = 44100;
|
dan@0
|
6
|
dan@0
|
7 dsc_idxs = ([-(N-1)/2:(N-1)/2]);
|
dan@0
|
8
|
dan@0
|
9 frqs_fft = [0:N_fft-1]*fs/N_fft;
|
dan@0
|
10
|
dan@0
|
11 the_frq = 416;
|
dan@0
|
12 the_fm1 = 7000;
|
dan@0
|
13 the_ph = 0.2;
|
dan@0
|
14 the_amp = 0.1;
|
dan@0
|
15 pk_offst_rt = 0.01;
|
dan@0
|
16 %frqs = [438,442.5] * 2 *pi; % as many frequencies as desired...
|
dan@0
|
17 fft_bin_hz = fs/N_fft;
|
dan@0
|
18 t = [-(N-1)/2:(N-1)/2]/fs;
|
dan@0
|
19 % monomials matlab style...
|
dan@0
|
20 ply_len = 2;
|
dan@0
|
21 mdl_poly = flipud(diag(ones(ply_len+1,1))); % vector of polynomials
|
dan@0
|
22 mdl_poly_der = zeros(size(mdl_poly));% vector of time derivated polynomials
|
dan@0
|
23
|
dan@0
|
24 % the actual time domain values of time derivated polynomials
|
dan@0
|
25 mdl_poly_der_vals = zeros(N,size(mdl_poly,1));
|
dan@0
|
26
|
dan@0
|
27 % window and time derivated window...
|
dan@0
|
28 w = 0.5+0.5*cos(2*pi*dsc_idxs/(N-1));
|
dan@0
|
29 w_d = -pi*fs/(N-1)*sin(2*pi*dsc_idxs/(N-1));
|
dan@0
|
30 w = w(:);
|
dan@0
|
31 w_d = w_d(:);
|
dan@0
|
32
|
dan@0
|
33 % calculate time domain plys...
|
dan@0
|
34 for k = 1:size(mdl_poly,1)
|
dan@0
|
35 pp = polyder(mdl_poly(k,:));
|
dan@0
|
36 mdl_poly_der(k,:) = [zeros(1,ply_len+1-size(pp,2)) pp ];
|
dan@0
|
37 mdl_poly_der_vals(:,k) = polyval( mdl_poly_der(k,:),t);
|
dan@0
|
38 end
|
dan@0
|
39
|
dan@0
|
40 mdl_poly_der_vals = mdl_poly_der_vals(:,2:end);
|
dan@0
|
41
|
dan@0
|
42 sig_r = real(exp(the_amp+1j*(the_fm1*t.^2 + t*the_frq*2*pi + the_ph*pi))).';
|
dan@0
|
43 %sig = hilbert(sig_r);
|
dan@0
|
44 sig = sig_r;
|
dan@0
|
45
|
dan@0
|
46 [id_s id_e ] = zpzh_idxs(N);
|
dan@0
|
47 sig_zp = sig .* w;
|
dan@0
|
48 sig_zp = [sig_zp(id_s);zeros(N_fft-N,1);sig_zp(id_e)];
|
dan@0
|
49
|
dan@0
|
50 sig_fft = fft(sig_zp, N_fft);
|
dan@0
|
51 [pk_vl,pk_idx] = max(abs(sig_fft));
|
dan@0
|
52 pk_frq_hz = (pk_idx - 1) * fs / N_fft;
|
dan@0
|
53 %pk_offst_rt = (fft_bin_hz/the_frq);
|
dan@0
|
54 %frqs_test = [pk_frq_hz*(1 - pk_offst_rt),pk_frq_hz, pk_frq_hz*(1 + pk_offst_rt)] * 2 *pi; % as many frequencies as desired...
|
dan@0
|
55 frqs_test = [pk_idx - 2, pk_idx - 1, pk_idx ] * 2 * pi * fs / N_fft;
|
dan@0
|
56 %frqs_test = [pk_idx - 0.5, pk_idx - 1.5, pk_idx ] * 2 * pi * fs / N_fft;
|
dan@0
|
57
|
dan@0
|
58
|
dan@0
|
59 [fks fks_drs] = fourier_kernel_win(frqs_test, N, fs, w, w_d);
|
dan@0
|
60 [gdi, A, b,gdi_lns,r_lns] = ...
|
dan@0
|
61 gen_ddm_int(fks, fks_drs, mdl_poly_der_vals, sig, N, 0);
|
dan@0
|
62
|
dan@0
|
63 errs = A(:,1) - sig_fft(pk_idx-1:pk_idx+1);
|
dan@0
|
64 assert( sum(errs < (1 + 1j) * 10^(-11)) == 3);
|
dan@0
|
65
|
dan@0
|
66 %gdi = gdi_lns;
|
dan@0
|
67
|
dan@0
|
68 err_rel_frq_log = log10(abs((imag(gdi(1)) / 2 / pi - the_frq)/(imag(gdi(1)) / 2 / pi) ));
|
dan@0
|
69 err_rel_fm1_log = log10(abs((imag(gdi(2)) - the_fm1) / imag(gdi(2)) ));
|
dan@0
|
70 assert(err_rel_frq_log < -3);
|
dan@0
|
71 assert(err_rel_fm1_log < -2);
|
dan@0
|
72 real(gdi(1))
|
dan@0
|
73 real(gdi(2))
|
dan@0
|
74 ply_est = fliplr(gdi.');
|
dan@0
|
75 frq_est = imag(ply_est(end));
|
dan@0
|
76 the_fm1
|
dan@0
|
77 imag(ply_est(end-1))
|
dan@0
|
78 frq_est/2/pi
|
dan@0
|
79 %ply_est(end) = real(ply_est(end)) + 1j*(imag(ply_est(end)) - the_frq);
|
dan@0
|
80 ply_est(end) = real(ply_est(end)); % hm....
|
dan@0
|
81 wmp = win_mod_poly(N, t, [ply_est 0], w);
|
dan@0
|
82
|
dan@0
|
83 % this creates a bias but it's fast...
|
dan@0
|
84
|
dan@0
|
85 krnl_dmd = exp(1j * frq_est * t');
|
dan@0
|
86 dtft_dmd = sum(w .* sig .* conj(krnl_dmd),1);
|
dan@0
|
87 r0 = dtft_dmd / wmp;
|
dan@0
|
88 err_rel_amp_log = log10(abs((abs(r0)*2 - exp(the_amp)) / exp(the_amp)) )
|
dan@0
|
89 err_rel_phs_log = log10(abs((angle(r0) / pi - the_ph)/the_ph));
|
dan@0
|
90
|
dan@0
|
91 assert(err_rel_amp_log < -2);
|
dan@0
|
92 sprintf('%15.15f', (angle(r0) / pi-the_ph) )
|
dan@0
|
93
|
dan@0
|
94
|
dan@0
|
95
|
dan@0
|
96
|
dan@0
|
97
|
dan@0
|
98 %% plots
|
dan@0
|
99 figure(3);clf;
|
dan@0
|
100 subplot(211);
|
dan@0
|
101 hold on;
|
dan@0
|
102 plot(frqs_fft,abs(sig_fft),'.k-');
|
dan@0
|
103 plot(frqs_test'/2/pi,abs(A(:,1)),'r*');
|
dan@0
|
104 subplot(212);
|
dan@0
|
105 hold on
|
dan@0
|
106 plot(frqs_fft,angle(sig_fft),'.k-');
|
dan@0
|
107 plot(frqs_test'/2/pi,angle(A(:,1)),'r*');
|
dan@0
|
108
|
dan@0
|
109 display('tests completed successfully!');
|
dan@0
|
110 display('accuracy:');
|
dan@0
|
111 display([ ' frq: ' num2str(err_rel_frq_log)]);
|
dan@0
|
112 display([ ' amp: ' num2str(err_rel_amp_log)]);
|
dan@0
|
113 display([ ' fm1: ' num2str(err_rel_fm1_log)]);
|
dan@0
|
114 display([ ' phs: ' num2str(err_rel_phs_log)]);
|
dan@0
|
115 display([ ' rcond: ' num2str(r_lns)]);
|
dan@0
|
116
|
dan@0
|
117
|