end
Dabs = abs(D); % this returned for plotting
-if 0
- D_ = D; % + 10*randn(1,L) + 10*j*randn(1,L);
- D_(Nkeep+1:L-Nkeep) = 0; % truncate
- d = ifft(D_); % back to spectrum at rate L
- maskdB_ = real(d);
-end
-
% truncate D to rate k, convert to 2k length real vector for quantisation and transmission
Dk = [0 D(2:k-1) real(D(k)) D(L-k+1:L)];
endfunction
+function tp = est_pf_locations(maskdB_)
+ % find turning points - used for finding PF freqs when we decimate in time
+
+ L = length(maskdB_);
+ d = maskdB_(2:L) - maskdB_(1:L-1);
+ tp = [];
+ for m=1:L-2
+ if (d(m) > 0) && (d(m+1) < 0)
+ tp = [tp m+1];
+ end
+ end
+endfunction
+
+
% Create a "decimated mask" model using just a few samples of
% critical band filter centre frequencies. For voiced speech,
% we fit the amplitude of these samples to a straight line.
more off;
max_amp = 80;
- dec_in_freq = 1;
- postfilter = 1;
- dec_in_time = 0;
- synth_phase = 0;
- vq_en = 1;
+ dec_in_freq = 0;
+ postfilter = 3;
+ dec_in_time = 1;
+ synth_phase = 1;
+ vq_en = 0;
dk_log = [];
model_name = strcat(samname,"_model.txt");
model = load(model_name);
[frames nc] = size(model);
model_ = zeros(frames, nc);
- nom_masked_m = zeros(frames,max_amp);
+ non_masked_m = zeros(frames,max_amp);
if nargin == 1
Am_out_name = sprintf("%s_am.out", samname);
% encoder loop ------------------------------------------------------
-
sd_sum = 0;
for f=1:frames
printf("%d ", f);
% save post filter positions for decode
maskdB_ = maskdB;
- a_non_masked_m = find(AmdB > maskdB);
- non_masked_m(f,1:length(a_non_masked_m)) = a_non_masked_m;
+ if (postfilter == 1) || (postfilter == 3)
+ a_non_masked_m = find(AmdB > maskdB);
+ end
+ if postfilter == 2
+ a_non_masked_m = est_pf_locations(maskdB_);
+ end
+ if length(a_non_masked_m)
+ non_masked_m(f,1:length(a_non_masked_m)) = a_non_masked_m;
+ end
+
+ if postfilter == 3
+ maskdB_ = maskdB_ - 9;
+ maskdB_(a_non_masked_m) = maskdB_(a_non_masked_m) + 9;
+ end
if dec_in_freq
if vq_en
- [maskdB_ tmp1 D dk_] = decimate_in_freq(maskdB, 1, 7, vq);
+ [maskdB_ tmp1 D dk_] = decimate_in_freq(maskdB_, 1, 7, vq);
else
- [maskdB_ tmp1 D dk_] = decimate_in_freq(maskdB, 1);
+ [maskdB_ tmp1 D dk_] = decimate_in_freq(maskdB_, 1);
end
dk_log = [dk_log; dk_];
+ sd_sum += sum(maskdB - maskdB_);
end
- sd_sum += sum(maskdB - maskdB_);
+
Am_ = zeros(1,max_amp);
Am_ = 10 .^ (maskdB_(1:L-1)/20);
if dec_in_time
% decimate mask samples in time
- maskdB_ = decimate_frame_rate(model_, 4, f, frames, mask_sample_freqs_kHz);
- % find turning points - prototype for finding PF freqs when we decimate in time
+ decimate = 4;
+ maskdB_ = decimate_frame_rate(model_, decimate, f, frames, mask_sample_freqs_kHz);
+
+ if 0
+ a_non_masked_m = est_pf_locations(maskdB_);
+ end
+
+ if 0
+
+ left_f = decimate*floor((f-1)/decimate)+1;
+ right_f = left_f + decimate;
+
+ m = max(find(non_masked_m(left_f,:) > 0));
+ a_non_masked_m = non_masked_m(left_f,1:m);
+
+ % now convert these to m on current frame
- d = maskdB_(2:L) - maskdB_(1:L-1);
- tp = [];
- for m=1:L-2
- if (d(m) > 0) && (d(m+1) < 0)
- tp = [tp m+1];
- end
+ left_L = min([model_(left_f,2) max_amp-1]);
+ a_non_masked_m = round(a_non_masked_m*L/left_L);
end
- a_non_masked_m = tp;
else
% read non-masked (PF freqs) from analysis stage
% number of non-masked samples is variable when not using AbyS,
% post filter - bump up samples by 6dB, reduce mask by same level to normalise gain
- if postfilter
+ if (postfilter == 1) || (postfilter == 2)
% Apply post filter - enhances formants, suppresses others, as pe Part 1 blog
% Pretty simple but makes a big difference
newamp;
more off;
plot_spectrum = 1;
- vq_en = 1;
+ vq_en = 0;
% load up text files dumped from c2sim ---------------------------------------
model = load(model_name);
[frames tmp] = size(model);
- if vq_en
- load vq;
- end
+ load vq;
% Keyboard loop --------------------------------------------------------------
[maskdB_ maskdB_cyclic D_cyclic dk_] = decimate_in_freq(maskdB, 1);
end
- plot(Am_freqs_kHz*1000, maskdB, ';mask;g');
- plot(Am_freqs_kHz*1000, maskdB_cyclic, ';mask cyclic;b');
+ %plot(Am_freqs_kHz*1000, maskdB, ';mask;g');
+ %plot(Am_freqs_kHz*1000, maskdB_cyclic, ';mask cyclic;b');
plot(Am_freqs_kHz*1000, maskdB_, ';mask trunated;c');
+ % Optional decimated parameters
+ % need to general model_ parameters either side
+
+ decimate = 4;
+ model_ = set_up_model_(model, f, decimate, vq_en, vq);
+ maskdB_dit = decimate_frame_rate(model_, decimate, f, frames, Am_freqs_kHz);
+ plot(Am_freqs_kHz*1000, maskdB_dit, ';mask dit;b');
+
+ % post filter locations
+
+ a_non_masked_m = find(AmdB > maskdB);
+ nmf = a_non_masked_m*4000*Wo/pi;
+ plot(nmf, AmdB(a_non_masked_m)+3, ';pf mask;g+');
+
+ tp = est_pf_locations(maskdB_);
+ nmf = tp*4000*Wo/pi;
+ plot(nmf, AmdB(tp)+6, ';pf trunc;c+');
+
+ tp = est_pf_locations(maskdB_dit);
+ nmf = tp*4000*Wo/pi;
+ plot(nmf, AmdB(tp)+9, ';pf dit;b+');
+
+ hold off;
+
% 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
endfunction
+
+function model_ = set_up_model_(model, f, decimate, vq_en, vq)
+ [frames nc] = size(model);
+ model_ = zeros(frames, nc);
+ left_f = decimate*floor((f-1)/decimate)+1;
+ right_f = left_f + decimate;
+
+ model_(left_f,:) = set_up_maskdB_(model, left_f, vq_en, vq);
+ model_(right_f,:) = set_up_maskdB_(model, right_f, vq_en, vq);
+ model_(f,1) = model(f,1); % Wo
+ model_(f,2) = model(f,2); % L
+endfunction
+
+
+function amodel_row = set_up_maskdB_(model, f, vq_en, vq)
+ [frames nc] = size(model);
+ max_amp = 80;
+
+ Wo = model(f,1);
+ L = model(f,2);
+ Am = model(f,3:(L+2));
+ AmdB = 20*log10(Am);
+ [maskdB Am_freqs_kHz] = mask_model(AmdB, Wo, L);
+
+ a_non_masked_m = find(AmdB > maskdB);
+ maskdB_pf = maskdB - 6;
+ maskdB_pf(a_non_masked_m) = maskdB_pf(a_non_masked_m) + 6;
+ maskdB = maskdB_pf;
+
+ if vq_en
+ maskdB_ = decimate_in_freq(maskdB, 1, 7, vq);
+ else
+ maskdB_ = decimate_in_freq(maskdB, 1);
+ end
+ maskdB_ = maskdB;
+
+ amodel_row = zeros(1,nc);
+ amodel_row(1) = Wo;
+ amodel_row(2) = L;
+ Am_ = zeros(1,max_amp);
+ Am_ = 10 .^ (maskdB_(1:L)/20);
+ amodel_row(3:(L+2)) = Am_;
+endfunction