From: drowe67 Date: Fri, 18 Mar 2016 02:08:36 +0000 (+0000) Subject: deriving post filter freqs from decoded mask when dec-in-time, seems to work OK X-Git-Url: http://git.whiteaudio.com/gitweb/?a=commitdiff_plain;h=3bafef10dba03b86c96aaf2aee31f750caa8f85f;p=freetel-svn-tracking.git deriving post filter freqs from decoded mask when dec-in-time, seems to work OK git-svn-id: https://svn.code.sf.net/p/freetel/code@2750 01035d8c-6547-0410-b346-abe4f91aad63 --- diff --git a/codec2-dev/octave/newamp.m b/codec2-dev/octave/newamp.m index 1f0b4e8f..b6cecba9 100644 --- a/codec2-dev/octave/newamp.m +++ b/codec2-dev/octave/newamp.m @@ -271,7 +271,7 @@ function [decmaskdB masker_freqs_kHz min_error mse_log1 mse_log2] = make_decmask % quantise the deltas - masker_amps_dB_lin_delta_ = zeros(4,1); + masker_amps_dB_lin_delta_ = zeros(Nsamples,1); if amp_quant == 1 for i=1:Nsamples masker_amps_dB_lin_delta_(i) = quantise(-21:3:21, masker_amps_dB_lin_delta(i)); diff --git a/codec2-dev/octave/newamp_batch.m b/codec2-dev/octave/newamp_batch.m index 6c0129ac..f7c6118e 100644 --- a/codec2-dev/octave/newamp_batch.m +++ b/codec2-dev/octave/newamp_batch.m @@ -21,7 +21,7 @@ function [non_masked_f_log non_masked_amp_log] = newamp_batch(samname, optional_ more off; max_amp = 80; - decimate_in_freq = 1; + decimate_in_freq = 0; postfilter = 1; decimate_in_time = 1; synth_phase = 1; @@ -74,7 +74,12 @@ function [non_masked_f_log non_masked_amp_log] = newamp_batch(samname, optional_ [decmaskdB masker_freqs_kHz] = make_decmask_abys(maskdB, AmdB, Wo, L, mask_sample_freqs_kHz, freq_quant, amp_quant); non_masked_amp = decmaskdB; non_masked_amp_log = [non_masked_amp_log; non_masked_amp']; + + % Save this for decoder, so it knows where to apply post filter + % Basically the frequencies of the AbyS samples + non_masked_m(f,:) = min(round(masker_freqs_kHz/(Wo*4/pi)),L); + non_masked_m_log = [non_masked_m_log; non_masked_m(f,:)']; non_masked_f_log = [non_masked_f_log; masker_freqs_kHz]; maskdB_ = decmaskdB; @@ -94,25 +99,52 @@ function [non_masked_f_log non_masked_amp_log] = newamp_batch(samname, optional_ % decoder loop ----------------------------------------------------- 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)); maskdB_ = 20*log10(Am_); mask_sample_freqs_kHz = (1:L)*Wo*4/pi; + %maskdB_ = mask_model(maskdB_, Wo, L); if decimate_in_time % decimate mask samples in time - maskdB_ = decimate_frame_rate(maskdB_, model_, 4, f, frames, mask_sample_freqs_kHz); + 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 + + 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 + a_non_masked_m = tp; + else + % read non-maksed (PF freqs) from analysis stage + % number of non-masked samples is variable when not using AbyS, + % but fixed when using AbyS + + m = max(find(non_masked_m(f,:) > 0)); + a_non_masked_m = non_masked_m(f,1:m); + end % post filter - bump up samples by 6dB, reduce mask by same level to normalise gain if postfilter + + % Apply post filter - enhances formants, suppresses others, as pe Part 1 blog + % Pretty simple but makes a big difference + maskdB_pf = maskdB_ - 6; - m = max(find(non_masked_m(f,:) > 0)); - a_non_masked_m = non_masked_m(f,1:m); maskdB_pf(a_non_masked_m) = maskdB_pf(a_non_masked_m) + 6; + + Am_ = zeros(1,max_amp); + Am_ = 10 .^ (maskdB_pf(1:L-1)/20); + model_(f,3:(L+1)) = Am_; else maskdB_pf = maskdB_; end @@ -122,15 +154,33 @@ function [non_masked_f_log non_masked_amp_log] = newamp_batch(samname, optional_ fwrite(fam, Am_, "float32"); if synth_phase + % synthesis phase spectra from magnitiude spectra using minimum phase techniques + fft_enc = 512; - model_(f,3:(L+2)) = 10 .^ (maskdB_pf(1:L)/20); + model_(f,3:(L+2)) = 10 .^ (maskdB_(1:L)/20); phase = determine_phase(model_, f); assert(length(phase) == fft_enc); Aw = zeros(1, fft_enc*2); Aw(1:2:fft_enc*2) = cos(phase); Aw(2:2:fft_enc*2) = -sin(phase); - + + if 0 + % optional plotting to ensure amd and phase aligned on a few frames + figure(1) + clf; + subplot(211) + plot(mask_sample_freqs_kHz, maskdB_); + hold on; + plot(mask_sample_freqs_kHz, maskdB_pf,'g'); + hold off; + axis([0 4 0 70]) + + subplot(212) + plot((0:(fft_enc/2)-1)*8000/fft_enc, phase(1:fft_enc/2)) + axis([0 4000 -pi pi]) + k = kbhit(); + end fwrite(faw, Aw, "float32"); end end diff --git a/codec2-dev/octave/newamp_fbf.m b/codec2-dev/octave/newamp_fbf.m index aeea6163..9a4463b5 100644 --- a/codec2-dev/octave/newamp_fbf.m +++ b/codec2-dev/octave/newamp_fbf.m @@ -69,7 +69,6 @@ function newamp_fbf(samname, f=10) end [maskdB Am_freqs_kHz] = mask_model(AmdB, Wo, L); - [maskdB2 Am_freqs_kHz2] = mask_model(maskdB, Wo, L); %plot(Am_freqs_kHz*1000, maskdB, 'g'); %plot(Am_freqs_kHz2*1000, maskdB2, 'r'); @@ -84,9 +83,17 @@ function newamp_fbf(samname, f=10) % decimate in frequency - if 1 mask_sample_freqs_kHz = (1:L)*Wo*4/pi; [decmaskdB masker_freqs_kHz min_error mse_log1 mse_log2] = make_decmask_abys(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]; + end end figure(2) @@ -94,10 +101,9 @@ function newamp_fbf(samname, f=10) tonef_kHz = masker_freqs_kHz; nlm = length(tonef_kHz); - if 1 plot(tonef_kHz*1000, zeros(1,nlm), ';AbyS Mask Freqs;bk+'); 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); hold off;