endfunction
-function [diff_weighted weights error g slope min_ind] = search_vq_weighted(target, vq, weight_gain, fit_order)
+function [diff_weighted weights error g min_ind] = search_vq_weighted(target, vq, weight_gain)
[vq_rows vq_cols] = size(vq);
- % find mse for each vector
+ weight_gain = 0.1; % I like this vairable name as it is funny
- error = g = slope = zeros(1, vq_rows);
- diff = weights = diff_weighted = zeros(vq_rows, vq_cols);
+ % find mse for each vector
- for i=1:vq_rows
+ error = g = zeros(1, vq_rows);
+ diff = weights = diff_weighted = zeros(vq_rows, vq_cols);
- if fit_order == 0
+ weights = max(0.1, weight_gain .* (target + 20));
- % work out gain for best match
+ for i=1:vq_rows
- g(i) = sum(target - vq(i,:))/vq_cols;
- slope(i) = 1;
- end
+ % work out gain for best match
- if fit_order == 1
- % work out linear + gradient fit
- vi = vq(i,:);
- A = [sum(vi) vq_cols; vi*vi' sum(vi)];
- c = [sum(target) target*vi']';
- b = inv(A)*c;
- g(i) = b(2);
- slope(i) = b(1);
- end
+ g(i) = sum((target - vq(i,:)).*weights)/vq_cols;
% Find weighted difference. This allocated more importance
% (error) to samples with higher energy, and stops really low
% level harmonics from having any impact. Note addition in dB
% is multiplication in linear
- diff(i,:) = target - slope(i)*vq(i,:) - g(i);
- weights(i,:) = max(0.1, weight_gain .* (target + 20));
+ diff(i,:) = target - vq(i,:) - g(i);
- diff_weighted(i,:) = diff(i,:) .* weights(i,:);
+ diff_weighted(i,:) = diff(i,:) .* weights;
% abs in dB is MSE in linear
error(i) = sum(abs(diff_weighted(i,:)));
end
- [mn min_ind] = min(error)
+ [mn min_ind] = min(error);
endfunction
output_prefix = input_prefix;
vq_type = "";
vq_filename = "";
- mean_removal = 0;
+ fit_order = 0;
mode = "const";
% parse variable argument list
end
ind = arg_exists(varargin, "nomean");
if ind
- mean_removal = 1;
+ fit_order = 0;
+ end
+ ind = arg_exists(varargin, "noslope");
+ if ind
+ fit_order = 1;
end
ind = arg_exists(varargin, "vqh");
if ind
end
end
- printf("output_prefix: %s\nnomean: %d output: %d vq_type: %s\nvq_filename: %s\n",
- output_prefix, mean_removal, output, vq_type, vq_filename);
+ printf("output_prefix: %s\nfit_order %d output: %d\n", output_prefix, fit_order, output);
model_name = strcat(input_prefix,"_model.txt");
model = load(model_name);
[model_ surface] = experiment_mel_freq(model, 0, 1, voicing);
end
if strcmp(mode, 'const')
- [model_ surface mean_f] = experiment_const_freq(model, mean_removal, vq_type, vq_filename);
+ [model_ surface] = experiment_const_freq(model, fit_order, vq_type, vq_filename);
end
if strcmp(mode, 'piecewise')
model_ = experiment_piecewise(model);
end
fwrite(fhm, Hm, "float32");
end
- fclose(fhm);
end
fclose(fam);
fclose(fWo);
+ if synth_phase
+ fclose(fhm);
+ end
% save voicing file
end
end
- if mean_removal
+ if fit_order == 0;
for f=1:frames
- surface(f,:) -= mean_f(f);
+ surface(f,:) -= mean(surface(f,:));
end
end
+ if fit_order == 1
+ surface = slope_and_mean_removal(surface);
+ end
+
printf("\n")
endfunction
+function surface = slope_and_mean_removal(surface)
+ [frames K] = size(surface);
+ for f=1:frames
+ v = surface(f,:);
+ [m b] = linreg(1:K, v, K);
+ v -= m*(1:K) + b;
+ surface(f,:) = v;
+ end
+endfunction
+
+
function ind = arg_exists(v, str)
ind = 0;
for i=1:length(v)
% Basic unquantised rate K linear sampling then back to rate L. Used for generating
% training vectors and testing vector quntisers.
-function [model_ rate_K_surface mean_f] = experiment_const_freq(model, mean_removal, vq_type, vq_filename)
+function [model_ rate_K_surface] = experiment_const_freq(model, fit_order, vq_type, vq_filename)
melvq;
[frames nc] = size(model);
rate_K_surface = resample_const_rate_f(model, rate_K_sample_freqs_kHz, Fs);
- mean_f = zeros(1,frames);
- if mean_removal
+ rate_K_surface_fit = zeros(frames,K);
+ b = slope = zeros(1,frames);
+
+ if fit_order == 0
for f=1:frames
- mean_f(f) = mean(rate_K_surface(f,:));
- rate_K_surface_no_mean(f,:) = rate_K_surface(f,:) - mean_f(f);
+ b(f) = mean(rate_K_surface(f,:));
+ rate_K_surface_fit(f,:) = rate_K_surface(f,:) - b(f);
+ end
+ end
+
+ if fit_order == 1
+ for f=1:frames
+ [aslope ab] = linreg(1:K, rate_K_surface(f,:), K);
+ rate_K_surface_fit(f,:) = rate_K_surface(f,:) - aslope*(1:K) - ab;
+ slope(f) = aslope; b(f) = ab;
end
end
% optional vector quantise
if quant_en
- assert(mean_removal == 1);
- weight_gain = 0.1; % I like this vairable name as it is funny
-
- rate_K_surface_no_mean_ = zeros(frames, K);
+ rate_K_surface_fit_ = zeros(frames, K);
res = zeros(frames,vq_cols); ind = [];
for f=1:frames
- target = rate_K_surface_no_mean(f, vq_st:vq_en);
-
- [diff_weighted weights error g mn_ind] = search_vq_weighted(target, vq, weight_gain);
+ target = rate_K_surface_fit(f, vq_st:vq_en);
- rate_K_surface_no_mean_(f,:) = rate_K_surface_no_mean(f,:);
- rate_K_surface_no_mean_(f, vq_st:vq_en) = vq(mn_ind,:) + g(mn_ind);
+ [diff_weighted weights error g mn_ind] = search_vq_weighted(target, vq);
+ if (f>=73) && (f<=75)
+ printf("f: %d mn_ind: %d g: %3.2f sd: %3.2f\n", f, mn_ind, g(mn_ind), error(mn_ind));
+ end
+ rate_K_surfacurface_fit_(f, vq_st:vq_en) = vq(mn_ind,:) + g(mn_ind);
%res(f,vq_st:vq_en) = rate_K_surface_no_mean(f,vq_st:vq_en) - rate_K_surface_no_mean_(f,vq_st:vq_en);
res(f,vq_st:vq_en) = diff_weighted(mn_ind,:);
figure(fg++); subplot(211); hist(sd_per_frame); subplot(212); hist(ind,100);
printf("VQ rms SD: %3.2f\n", mean(sd_per_frame));
else
- if mean_removal
- rate_K_surface_no_mean_ = rate_K_surface_no_mean;
- else
- rate_K_surface_ = rate_K_surface;
- end
+ rate_K_surface_fit_ = rate_K_surface_fit;
end
- if mean_removal
- for f=1:frames
- rate_K_surface_(f,:) = rate_K_surface_no_mean_(f,:) + mean_f(f);
- end
+ for f=1:frames
+ rate_K_surface_(f,:) = rate_K_surface_fit_(f,:) + slope(f)*(1:K) + b(f);
end
[model_ AmdB_] = resample_rate_L(model, rate_K_surface_, rate_K_sample_freqs_kHz, Fs);
[vq_rows vq_cols] = size(vq); vq_st = 11; vq_en = K;
end
+ fit_order = 0;
+ ind = arg_exists(varargin, "noslope");
+ if ind
+ fit_order = 1;
+ end
+
% load up text files dumped from c2sim ---------------------------------------
sn_name = strcat(samname,"_sn.txt");
Am_freqs_kHz = (1:L)*Wo*4/pi;
rate_K_vec = resample_const_rate_f(model(f,:), rate_K_sample_freqs_kHz, Fs);
- maskdB = determine_mask(rate_K_vec, rate_K_sample_freqs_kHz, rate_K_sample_freqs_kHz);
- rate_K_vec_no_mean = rate_K_vec - mean(rate_K_vec);
+ if fit_order == 0
+ slope = 0; b = mean(rate_K_vec);
+ rate_K_vec_fit = rate_K_vec - b;
+ end
+ if fit_order == 1
+ [slope b] = linreg(1:K, rate_K_vec, K);
+ rate_K_vec_fit = rate_K_vec - slope*(1:K) - b;
+ end
% plots ----------------------------------
plot(rate_K_sample_freqs_kHz*1000, rate_K_vec, ";rate K;b+-");
if quant_en
- target = rate_K_vec_no_mean(vq_st:vq_en);
- weight_gain = 0.1; % I like this vairable name as it is funny
-
- [diff_weighted weights error g mn_ind] = search_vq_weighted(target, vq, weight_gain);
-
- rate_K_vec_no_mean_ = rate_K_vec_no_mean;
- rate_K_vec_no_mean_(vq_st:vq_en) = vq(mn_ind,:) + g(mn_ind);
- rate_K_vec_ = rate_K_vec_no_mean_ + mean(rate_K_vec);
+ target = rate_K_vec_fit(vq_st:vq_en);
+
+ [diff_weighted weights error g mn_ind] = search_vq_weighted(target, vq);
+ printf("f: %d mn_ind: %d g: %3.2f sd: %3.2f\n", f, mn_ind, g(mn_ind), error(mn_ind));
+
+ rate_K_vec_fit_ = rate_K_vec_fit;
+ rate_K_vec_fit_(vq_st:vq_en) = vq(mn_ind,:) + g(mn_ind);
+ rate_K_vec_ = slope*(1:K) + rate_K_vec_fit_ + b;
[model_ AmdB_] = resample_rate_L(model(f,:), rate_K_vec_, rate_K_sample_freqs_kHz, Fs);
AmdB_ = AmdB_(1:L);
hold off;
figure (4); clf;
- plot(rate_K_sample_freqs_kHz(vq_st:vq_en)*1000, weights(mn_ind,:), ";weights;k+-");
- axis([0 4000 0 max(weights(mn_ind,:))]);
+ plot(rate_K_sample_freqs_kHz(vq_st:vq_en)*1000, weights, ";weights;k+-");
+ axis([0 4000 0 max(weights)]);
+
+ figure (5); clf; plot(error);
% sort and plot top m matches
figure(3); clf;
m = 4;
- [mse_list index_list] = sort(error);
+ [error_list index_list] = sort(error);
- mse_list = mse_list(1:m);
+ mse_list = error_list(1:m);
index_list = index_list(1:m);
for i=1:m
subplot(sqrt(m),sqrt(m),i);
indx = index_list(i);
- y_offset = mean(rate_K_vec);
+ y_offset = g(indx) + b;
if quant_en == 2
y_offset = 0;
end
- plot(target + y_offset,'b+-');
+ l = sprintf("b+-;ind %d g %3.2f sd %3.2f;",indx, g(indx), error(indx));
+ plot(target + y_offset,l);
hold on;
if index_list(i) == mn_ind
- plot(vq(indx,:) + g(indx) + y_offset,'r+-');
+ plot(vq(indx,:) + y_offset,'r-+');
else
- plot(vq(indx,:) + g(indx) + y_offset,'g+-');
+ plot(vq(indx,:) + y_offset,'g+-');
end
if quant_en != 2
plot(diff_weighted(indx,:), "ko-");
end
hold off;
- legend("location", "southwest");
end
end
% interactive menu ------------------------------------------
- printf("\rframe: %d menu: n-next b-back q-quit m-show_quant[%d]", f, quant_en);
+ printf("\rframe: %d menu: n-next b-back q-quit m-show_quant[%d] o-fit order[%d]", f, quant_en, fit_order);
fflush(stdout);
k = kbhit();
if k == 'b'
f = f - 1;
endif
+ if k == 'o'
+ fit_order++;
+ if fit_order == 2
+ fit_order = 0;
+ end
+ endif
until (k == 'q')
printf("\n");