function [maskdB_ maskdB_cyclic Dabs dk_ D1 ind] = decimate_in_freq(maskdB, cyclic=1, k=7, vq)
+ L = length(maskdB);
+
% Lets try to come up with a smoothed, cyclic model. Replace
% points from 3500 Hz to 4000Hz with a sequence that joins without
% a step to points at the 0Hz end of the spectrum. This will make
% it more cyclical and make the DFT happier, less high freq
% energy. Yes, happier is an extremely technical term.
- L = length(maskdB);
anchor = floor(7*L/8);
xpts = [ anchor-1 anchor L+1 L+2];
ypts = [ maskdB(anchor-1) maskdB(anchor) maskdB(1) maskdB(2)];
[tmp D1_ind] = quantise(0:(2500/15):2500, D1);
ind = [vq_ind D1_ind];
[dk_ D1_] = index_to_params(ind, vq);
+ D1_ = D1;
%printf(" vq: %4.1f D1: %4.1f\n", std(dk_ - dk), D1_- D1);
else
dk_ = dk;
D_(1) = D1_; % energy seperately quantised
D_(2:k-1) = Dk_(2:k-1);
D_(L-k+1:L) = Dk_(k+1:2*k);
- d_ = ifft(D_); % back to spectrum at rate L
+ d_ = ifft(D_); % back to spectrum at rate L
maskdB_ = real(d_);
% Finally fix up last 500Hz, taper down 10dB at 4000Hz
% Decode from a bit stream file
-function decode_bit_stream_file(samname, bits_per_param)
+function decode_bit_stream_file(samname, bits_per_param, ber_mask, ber)
max_amp = 80;
nc = max_amp + 3;
load vq;
[tmp1 k2 tmp2] = size(vq);
k = k2/2;
+ rand("seed", 0);
+ f = 1;
bit_stream_name = strcat(samname,".bit");
fbit = fopen(bit_stream_name, "rb");
[frame nread] = fread(fbit, sum(bits_per_param), "uchar");
while (nread == bits_per_frame)
+ % optionally add bit errors
+
+ if nargin == 4
+ error_pattern = bitand(rand(bits_per_frame,1) < ber, ber_mask);
+ frame = bitxor(frame, error_pattern);
+ end
+
% read a frame, convert to indexes
nbit = 1;
ind = [ind bits_to_index(field, bits_per_param(i))];
end
ind_log = [ind_log; ind];
+ printf("f: %d\n", f);
+ ind
+ if 0
+ if sum(error_pattern)
+ printf(" Error f: %d\n", f);
+ %if f == 169
+ % ind(1) = 50;
+ %end
+ end
+ end
% convert index to model parameters
Am_ = 10 .^ (AmdB_(1:L_)/20);
amodel_(3:(L_+2)) = Am_;
model_ = [ model_; amodel_; zeros(3,nc)];
+ f+=4;
log_v = [log_v ind(2)];
end
end
fclose(fv);
+
endfunction
% decoder loop -----------------------------------------------------
[frames tmp] = size(model_);
-
+
for f=1:frames
- %printf("frame: %d\n", f);
L = min([model_(f,2) max_amp-1]);
Wo = model_(f,1);
+
Am_ = model_(f,3:(L+2));
AmdB_ = 20*log10(Am_);
sample_freqs_kHz = (1:L)*Wo*4/pi;
+ printf("frame: %d Fo: %f L: %d\n", f, Wo*4000/pi, L);
% run post filter ahead of time so dec in time has post filtered frames to work with
endfunction
+% work out a gradient m and y intercept c to map x to y using
+% a least sqaures fit, y_ = m*x + c
+
+function [m c] = map_vector(x, y)
+ L = length(x);
+ num = sum(x.*y) - sum(y)*sum(x)/L;
+ den = sum(x.*x) - sum(x)*sum(x)/L;
+ m = num/den;
+ c = (sum(y) - m*sum(x))/L;
+endfunction
+
+
+% for each target
+% run thru each cb entry
+% find m and c
+% measure MSE
+% record best
+
+function [best_i best_mse best_vec] = search_linear_fit(target, vq)
+ [rows cols] = size(vq);
+ best_mse = 1E32;
+ best_i = 1;
+ for i=1:rows
+ [m c] = map_vector(vq(i,:),target);
+ error = m*vq(i,:) + c - target;
+ mse = sum(error.^2);
+ if mse < best_mse
+ best_mse = mse;
+ best_i = i;
+ best_vec = m*vq(i,:) + c;
+ best_m = m; best_c = c;
+ end
+ end
+ printf("best_m: %f best_c: %f\n", best_m, best_c);
+endfunction
+
% $ ./c2sim ../../raw/hts2a.raw --dump hts2a --lpc 10 --phase0 --dump_pitch_e hts2a_pitche.txt
% Bit stream decode:
-% $ ./c2sim ../../raw/hts2a.raw --amead hts2a_am.out --awread hts2a_aw.out --Woread hts2a_Wo.out --phase0 --postfilter -o - | play -t raw -r 8000 -s -2 -
+% $ ./c2sim ../../raw/hts2a.raw --amread hts2a_am.out --awread hts2a_aw.out --Woread hts2a_Wo.out --phase0 --postfilter -o - | play -t raw -r 8000 -s -2 -
% process a whole file and write results
max_amp = 80;
dec_in_freq = 1;
postfilter = 0;
- dec_in_time = 1;
+ dec_in_time = 0;
synth_phase = 1;
vq_en = 1;
D_log = []; dk_log = []; D1_log = []; ind_log = [];
train = 0;
- fully_quant = 1;
- Wo_quant = 1;
+ fully_quant = 0;
+ Wo_quant = 0;
+ diff_freq = 0;
model_name = strcat(samname,"_model.txt");
model = load(model_name);
if vq_en
load vq;
+ load d20_vq;
end
+ load d20_vq;
+ prev_dk_ = zeros(1,2*10);
% encoder loop ------------------------------------------------------
dk_log = [dk_log; dk_];
D1_log = [D1_log D1];
end
+
+ if diff_freq
+ diff_dk = dk_ - 0.9*prev_dk_;
+ [res tmp vq_ind] = mbest(d20_vq, diff_dk, 4);
+ %printf("vq_ind: %d\n", vq_ind);
+ dk_d = 0.9*prev_dk_ + tmp;
+ prev_dk_ = dk_d;
+ AmdB_ = params_to_mask(L, 10, dk_d, D1);
+ end
end
sd_sum += std(maskdB - AmdB_);
more off;
plot_spectrum = 1;
dec_in_freq = 1;
- dec_in_time = 1;
- vq_en = 0;
+ dec_in_time = 0;
+ vq_en = 1;
mask_en = 1;
+ k = 10;
% load up text files dumped from c2sim ---------------------------------------
[frames tmp] = size(model);
load vq;
+ load d20_vq;
+
+ prev_dk_ = zeros(1,2*k);
% Keyboard loop --------------------------------------------------------------
- k = ' ';
+ key = ' ';
do
figure(1);
clf;
%a_non_masked_m = find(AmdB > maskdB);
%maskdB = maskdB - 6;
%maskdB(a_non_masked_m) = maskdB(a_non_masked_m) + 6;
- %plot(Am_freqs_kHz*1000, maskdB, ';mask;g');
+ plot(Am_freqs_kHz*1000, maskdB, ';mask;g');
if mask_en
AmdB_ = AmdB = maskdB;
end
if dec_in_freq
[tmp1 tmp2 D] = decimate_in_freq(AmdB, 0);
+ [AmdB_ AmdB_cyclic D_cyclic dk D1] = decimate_in_freq(AmdB_, 1, k);
if vq_en
- [AmdB_ AmdB_cyclic D_cyclic dk_] = decimate_in_freq(AmdB, 1, 10, vq);
- plot(Am_freqs_kHz*1000, AmdB_, ';mask trunc vq;c');
- else
- [AmdB_ AmdB_cyclic D_cyclic dk_] = decimate_in_freq(AmdB_, 1, 10);
- plot(Am_freqs_kHz*1000, AmdB_, ';mask trunc;c');
+ [AmdB_ AmdB_cyclic D_cyclic dk_ D1_ ind] = decimate_in_freq(AmdB, 1, k, vq);
+ plot(Am_freqs_kHz*1000, AmdB_, ';vq;c');
end
- plot(Am_freqs_kHz*1000, AmdB_cyclic, ';mask cyclic;b');
- AmdB_pf = AmdB_*(1.5);
- AmdB_pf += max(AmdB_) - max(AmdB_pf);
- %max(AmdB_pf)-max(AmdB_)
- %AmdB_pf -= max(AmdB_pf)-max(AmdB_);
+ % experimental differential in time
+ % get mask from 20ms ago (two frames), VQ delta, put back together.
+
+ diff_dk = dk - prev_dk_;
+ [res tmp vq_ind] = mbest(d20_vq, diff_dk, 1);
+ dk_d = prev_dk_ + tmp;
+ prev_dk_ = dk_d;
+ AmdB_d_ = params_to_mask(L, k, dk_d, D1);
+ plot(Am_freqs_kHz*1000, AmdB_d_, ';vq diff;bk');
+
+ %plot(Am_freqs_kHz*1000, AmdB_cyclic, ';mask cyclic;b');
+ %AmdB_pf = AmdB_*1.5;
+ %AmdB_pf += max(AmdB_) - max(AmdB_pf);
+ %plot(Am_freqs_kHz*1000, AmdB_, ';ind vq;g');
+
+ % option decode from indexes, used to test effect of bit errors on Wo
+
+ if 0
+ Wo_ = pi*169/4000;
+ L_ = floor(pi/Wo_);
+ if vq_en
+ [dk_ D1_] = index_to_params(ind, vq);
+ end
+ maskdB_ = params_to_mask(L_, k, dk_, D1_);
+ plot((1:L_)*Wo_*4000/pi, maskdB_, ';ind vq;b-+');
+ end
end
- %AmdB_pf = AmdB_*(1.5);
- %AmdB_pf += mean(AmdB) - mean(AmdB_pf);
- %AmdB_pf = AmdB_;
-
- %plot(Am_freqs_kHz*1000, AmdB_pf, ';after pf;g');
axis([0 4000 00 80]);
% Optional decimated parameters
figure(5)
clf
- stem(dk_);
- axis([0 20 -60 60])
+ stem(dk,'b');
+ hold on;
+ stem(dk_,'g');
+ hold off;
end
% interactive menu ------------------------------------------
printf("\rframe: %d menu: n-next b-back q-quit m-mask_en", f);
fflush(stdout);
- k = kbhit();
+ key = kbhit();
- if (k == 'm')
+ if (key == 'm')
if mask_en
mask_en = 0;
else
mask_en = 1;
end
endif
- if (k == 'n')
+ if (key == 'n')
f = f + 1;
endif
- if (k == 'b')
+ if (key == 'b')
f = f - 1;
endif
- until (k == 'q')
+ until (key == 'q')
printf("\n");
endfunction