From 6e6518a4951f97ff44f2903be9f668a5432a2ef5 Mon Sep 17 00:00:00 2001 From: drowe67 Date: Tue, 25 Aug 2015 05:59:04 +0000 Subject: [PATCH] trying out a new analysisi by synthesis method for choosing the location of samples. Works OK compared to local minima, still some background noise problems git-svn-id: https://svn.code.sf.net/p/freetel/code@2282 01035d8c-6547-0410-b346-abe4f91aad63 --- codec2-dev/octave/newamp.m | 54 ++++++++++++++++++++++++++------ codec2-dev/octave/newamp_batch.m | 2 +- codec2-dev/octave/newamp_fbf.m | 7 +++-- 3 files changed, 51 insertions(+), 12 deletions(-) diff --git a/codec2-dev/octave/newamp.m b/codec2-dev/octave/newamp.m index c6bc3e9f..aedd37fe 100644 --- a/codec2-dev/octave/newamp.m +++ b/codec2-dev/octave/newamp.m @@ -117,6 +117,49 @@ function [decmaskdB local_maxima_sort] = make_decmask(maskdB, AmdB, Wo, L, mask_ endfunction +% Alternative way to come up with a decimated mask model, using +% analysis by synthesis to determine the best place to put samples. +% Ahh, takes me back to when I was a slip of a speech coder, playing +% with my first CELP codec! + +function [decmaskdB dec_samples] = make_decmask_abys(maskdB, AmdB, Wo, L, mask_sample_freqs_kHz) + + % band pass filter: limit search to 250 to 3800 Hz + + m_st = max(1,floor((pi*250/4000)/Wo)); + m_en = floor((pi*3800/4000)/Wo); + + target = maskdB; + decmaskdB = zeros(1,L); + dec_samples = []; + + + for sample=1:4 + + % find best position for sample to minimise distance to target + + min_mse = 1E32; + for m=m_st:m_en + single_mask_m = schroeder(m*Wo*4/pi, mask_sample_freqs_kHz) + AmdB(m); + candidate = max(decmaskdB, single_mask_m); + candidate = max(zeros(1,L), candidate); + error = target - candidate; + mse = sum(error .^ 2); + %printf("m: %d f: %f error: %f\n", m, m*Wo*4/pi, mse); + if (mse < min_mse) + min_mse = mse; + min_mse_m = m; + min_candidate = candidate; + end + end + + decmaskdB = min_candidate; + dec_samples = [dec_samples; AmdB(min_mse_m) min_mse_m]; + end + +endfunction + + % determine cumulative mask, using amplitude of each harmonic. Mask is % sampled across L points in the linear domain @@ -131,19 +174,12 @@ function maskdB = determine_mask(masker_amps_dB, masker_freqs_kHz, mask_sample_f end -% Sample mask as model for Am, tweaked a bit to enhance -% the formants:antiformant radtio, like the LPC postfilter +% Sample mask as model for Am -function [maskdB_pf Am_freqs_kHz peaks_kHz] = mask_model(AmdB, Wo, L) +function [maskdB Am_freqs_kHz] = mask_model(AmdB, Wo, L) Am_freqs_kHz = (1:L)*Wo*4/pi; maskdB = determine_mask(AmdB, Am_freqs_kHz, Am_freqs_kHz); - non_masked_m = find(maskdB < AmdB); - peaks_kHz = non_masked_m*Wo*4/pi; - maskdB_pf = maskdB; - %maskdB_pf = zeros(1,L); - %maskdB_pf(non_masked_m) = maskdB(non_masked_m) + 6; - endfunction diff --git a/codec2-dev/octave/newamp_batch.m b/codec2-dev/octave/newamp_batch.m index 62db3779..db432e71 100644 --- a/codec2-dev/octave/newamp_batch.m +++ b/codec2-dev/octave/newamp_batch.m @@ -36,7 +36,7 @@ function newamp_batch(samname) maskdB = mask_model(AmdB, Wo, L); mask_sample_freqs_kHz = (1:L)*Wo*4/pi; - [newmaskdB local_maxima] = make_decmask(maskdB, AmdB, Wo, L, mask_sample_freqs_kHz); + [newmaskdB local_maxima] = make_decmask_abys(maskdB, AmdB, Wo, L, mask_sample_freqs_kHz); [nlm tmp] = size(local_maxima); non_masked_m = local_maxima(1:min(4,nlm),2); diff --git a/codec2-dev/octave/newamp_fbf.m b/codec2-dev/octave/newamp_fbf.m index 44a16cef..39e0cbde 100644 --- a/codec2-dev/octave/newamp_fbf.m +++ b/codec2-dev/octave/newamp_fbf.m @@ -14,6 +14,7 @@ function newamp_fbf(samname, f) + more off; newamp; sn_name = strcat(samname,"_sn.txt"); @@ -51,7 +52,7 @@ function newamp_fbf(samname, f) plot((0:255)*4000/256, Sw(f,:),";Sw;"); [maskdB Am_freqs_kHz] = mask_model(AmdB, Wo, L); - %plot(Am_freqs_kHz*1000, maskdB, 'g'); + plot(Am_freqs_kHz*1000, maskdB, 'g'); % optionally show harmonics that are not masked @@ -72,7 +73,7 @@ function newamp_fbf(samname, f) % estimate low rate samples mask_sample_freqs_kHz = (1:L)*Wo*4/pi; - [decmaskdB local_maxima] = make_decmask(maskdB, AmdB, Wo, L, mask_sample_freqs_kHz); + [decmaskdB local_maxima] = make_decmask_abys(maskdB, AmdB, Wo, L, mask_sample_freqs_kHz); [nlm tmp] = size(local_maxima(:,2)); nlm = min(nlm,4); @@ -99,6 +100,8 @@ function newamp_fbf(samname, f) hold off; + figure(3) + plot(decmaskdB) % interactive menu printf("\rframe: %d menu: n-next b-back p-png q-quit m-all", f); -- 2.25.1