end
+% simple resampling to a fixed length vector on mel scale
+% fixed freq grid resampling
+
+function [decmaskdB mel_sample_freqs_kHz mel_masker_amps_dB min_error mse_log1 best_min_mse ind_log] = make_decmask_mel(maskdB, AmdB, Wo, L, mask_sample_freqs_kHz, freq_quant, amp_quant)
+
+ % set up mel sampling grid
+
+ Nmel = 20;
+ mel_st = freq2mel(Wo*4000/pi);
+ mel_en = freq2mel(L*Wo*4000/pi);
+ m_step = (mel_en-mel_st)/Nmel;
+ m = mel_st:m_step:mel_en;
+ mel_sample_freqs_kHz = mel2freq(m)/1000;
+
+ % resample on mel grid
+
+ mask_pp = splinefit(mask_sample_freqs_kHz, maskdB, L);
+ mel_masker_amps_dB = ppval(mask_pp, mel_sample_freqs_kHz);
+
+ % resample on Wo grid
+
+ mel_pp = splinefit(mel_sample_freqs_kHz, mel_masker_amps_dB, L);
+ decmaskdB = ppval(mel_pp, mask_sample_freqs_kHz);
+ size(decmaskdB)
+ min_error = 0; mse_log1=[]; best_min_mse=0; ind_log=[];
+end
+
+
function mel = freq2mel(f)
mel = 70*log10(1 + f/700);
endfunction
plot_spectrum = 1;
freq_quant = 0;
amp_quant = 0;
+ decimate_in_freq = 0;
sn_name = strcat(samname,"_sn.txt");
Sn = load(sn_name);
Wo = model(f,1);
L = model(f,2);
Am = model(f,3:(L+2));
- %[h w] = freqz([1 -1],1,(1:L)*Wo); % pre-emphasise to reduce dynamic range
- %Am = Am .* abs(h);
AmdB = 20*log10(Am);
% plotting
[maskdB Am_freqs_kHz] = mask_model(AmdB, Wo, L);
- %plot(Am_freqs_kHz*1000, maskdB, 'g');
- %plot(Am_freqs_kHz2*1000, maskdB2, 'r');
+ plot(Am_freqs_kHz*1000, maskdB, 'g');
- % optionally plot synthesised spectrum (early simple model)
+ % Lets try to come up with a smoothed model. Replace points from 3500 Hz on with
+ % those than match low end of spectrum. This will make it more cyclical and make
+ % DFT happier, less high freq energy. Need a better way to describe that.
- if 0
- AmdB_ = maskdB;
- plot(Am_freqs_kHz*1000, AmdB_, 'g');
- plot(Am_freqs_kHz*1000, AmdB_, 'g+');
- end
+ anchor = floor(7*L/8);
+ xpts = [ anchor-1 anchor L+1 L+2];
+ ypts = [ maskdB(anchor-1) maskdB(anchor) maskdB(1) maskdB(2)];
+ mask_pp = splinefit(xpts, ypts, 1);
+ maskdB_smooth = [maskdB(1:anchor) ppval(mask_pp, anchor+1:L)];
- % decimate in frequency
+ plot(Am_freqs_kHz*1000, maskdB_smooth, 'b');
- mask_sample_freqs_kHz = (1:L)*Wo*4/pi;
- [decmaskdB masker_freqs_kHz masker_amps_dB min_error mse_log1] = make_decmask_abys(maskdB, AmdB, Wo, L, mask_sample_freqs_kHz, freq_quant, amp_quant);
+ if decimate_in_freq
+ % decimate in frequency
+
+ mask_sample_freqs_kHz = (1:L)*Wo*4/pi;
+ [decmaskdB masker_freqs_kHz masker_amps_dB min_error mse_log1] = make_decmask_mel(maskdB, AmdB, Wo, L, mask_sample_freqs_kHz, freq_quant, amp_quant);
% find turning points - prototype for finding PF freqs when we decimate in time
- d = decmaskdB(2:L) - decmaskdB(1:L-1);
- tp = [];
- for m=1:L-1
- if (d(m) > 0) && (d(m+1) < 0)
- tp = [tp m+1];
+ if 0
+ d = decmaskdB(2:L) - decmaskdB(1:L-1);
+ size(d)
+ tp = [];
+ for m=1:L-1
+ if (d(m) > 0) && (d(m+1) < 0)
+ tp = [tp m+1];
+ end
end
end
- figure(2)
+ figure(2)
- tonef_kHz = masker_freqs_kHz;
- nlm = length(tonef_kHz);
-
- plot(tonef_kHz*1000, zeros(1,nlm), ';AbyS Mask Freqs;bk+');
- plot(mask_sample_freqs_kHz*1000, decmaskdB, ';AbyS Mask;m');
- plot(tp*Wo*4000/pi, 5*ones(1,length(tp)), ';PF Freqs;r+');
- legend('boxoff');
- %plot(mask_sample_freqs_kHz*1000, min_error);
+ tonef_kHz = masker_freqs_kHz;
+ nlm = length(tonef_kHz);
+
+ plot(tonef_kHz*1000, zeros(1,nlm), ';AbyS Mask Freqs;bk+');
+ if decimate_in_freq
+ plot(mask_sample_freqs_kHz*1000, decmaskdB, ';AbyS Mask;m');
+ end
+ %plot(tp*Wo*4000/pi, 5*ones(1,length(tp)), ';PF Freqs;r+');
+ legend('boxoff');
+ %plot(mask_sample_freqs_kHz*1000, min_error);
+
+ end
+
hold off;
- if 0
+ % lets get a feel for the "spectrum" of the smoothed spectral envelope
+ % this will give us a feel for how hard it is to code, ideally we would like
+ % just a few coefficents to be non-zero
+
figure(3)
clf
- plot((1:L)*Wo*4000/pi, mse_log1');
- axis([0 4000 0 max(mse_log1(1,:))])
- title('Error as a function of position for each AbyS stage');
- end
+
+ D = abs(fft(maskdB));
+ en = floor(length(D)/2+1);
+ stem(D(2:en),'g')
+ hold on;
+ D_smooth = abs(fft(maskdB_smooth));
+ stem(D_smooth(2:en),'b')
+ hold off;
+
+ % let plot the cumulative amount of energy in each DFT
+
+ figure(4)
+ clf
+ plot(cumsum(D(2:en)/sum(D(2:en))),'g');
+ hold on;
+ plot(cumsum(D_smooth(2:en)/sum(D_smooth(2:en))),'b');
+ hold off;
+ axis([1 L 0 1])
+
+ % try truncating DFT coeffs and see what that looks like
+
+ D = fft(maskdB_smooth);
+ keep = 7;
+ D(keep+1:L-keep) = 0;
+ d = ifft(D);
+
+ figure(2)
+ hold on;
+ plot(Am_freqs_kHz*1000, real(d), 'c')
+ hold off;
% decimated in time