From 1d5c81e8268f7ba1785ba939a440957fabd457ad Mon Sep 17 00:00:00 2001 From: drowe67 Date: Wed, 16 Sep 2015 00:16:15 +0000 Subject: [PATCH] implemented decimation in time, from update rates of 10 to 40ms, with linear interp in the dB domain. Works well for hts1a, hts2a, ve9qrp, just a slight degration in quality git-svn-id: https://svn.code.sf.net/p/freetel/code@2336 01035d8c-6547-0410-b346-abe4f91aad63 --- codec2-dev/octave/newamp.m | 48 ++++++++++++++++++++++++++++++++ codec2-dev/octave/newamp_batch.m | 11 ++++++-- codec2-dev/octave/newamp_fbf.m | 16 ++++++++--- 3 files changed, 68 insertions(+), 7 deletions(-) diff --git a/codec2-dev/octave/newamp.m b/codec2-dev/octave/newamp.m index 7d6a39bb..bbe72f50 100644 --- a/codec2-dev/octave/newamp.m +++ b/codec2-dev/octave/newamp.m @@ -330,6 +330,54 @@ function maskdB = resonator(freq_tone_kHz, mask_sample_freqs_kHz) end endfunction +function maskdB = resample_mask(model, f, mask_sample_freqs_kHz) + max_amp = 80; + + Wo = model(f,1); + L = min([model(f,2) max_amp-1]); + Am = model(f,3:(L+2)); + AmdB = 20*log10(Am); + masker_freqs_kHz = (1:L)*Wo*4/pi; + maskdB = determine_mask(AmdB, masker_freqs_kHz, mask_sample_freqs_kHz); +endfunction + + +% decimate frame rate of mask, use interpolation in the log domain + +function maskdB_ = decimate_frame_rate(maskdB, model, decimate, f, frames, mask_sample_freqs_kHz) + max_amp = 80; + + Wo = model(f,1); + L = min([model(f,2) max_amp-1]); + + if (mod(f-1,decimate) && (f < (frames-decimate))) + + % determine frames that bracket the one we need to interp + + left_f = decimate*floor(f/decimate)+1; + right_f = decimate*ceil(f/decimate)+1; + + % determine fraction of each frame to use + + right_fraction = mod(f-1,decimate)/decimate; + left_fraction = 1 - right_fraction; + + printf("\nf: %d left_f: %d right_f: %d left_fraction: %f right_fraction: %f \n",f,left_f,right_f,left_fraction,right_fraction) + + % determine mask for left and right frames, sampling at Wo for this frame + + mask_sample_freqs_kHz = (1:L)*Wo*4/pi; + maskdB_left = resample_mask(model, left_f, mask_sample_freqs_kHz); + maskdB_right = resample_mask(model, right_f, mask_sample_freqs_kHz); + + maskdB_ = left_fraction*maskdB_left + right_fraction*maskdB_right; + else + maskdB_ = maskdB; + printf("\n"); + end +endfunction + + % plot some masking curves, used for working on masking filter changes function plot_masking diff --git a/codec2-dev/octave/newamp_batch.m b/codec2-dev/octave/newamp_batch.m index 715ca1e7..50ca81cb 100644 --- a/codec2-dev/octave/newamp_batch.m +++ b/codec2-dev/octave/newamp_batch.m @@ -13,6 +13,7 @@ % octave:14> newamp_batch("../build_linux/src/hts1a") % ~/codec2-dev/build_linux/src$ ./c2sim ../../raw/hts1a.raw --amread hts1a_am.out -o - | play -t raw -r 8000 -s -2 - + % process a whole file and write results function newamp_batch(samname, optional_Am_out_name) @@ -20,7 +21,7 @@ function newamp_batch(samname, optional_Am_out_name) more off; max_amp = 80; - use_decmask = 1; + use_decmask = 0; postfilter_en = 1; decimate = 1; @@ -38,14 +39,14 @@ function newamp_batch(samname, optional_Am_out_name) fam = fopen(Am_out_name,"wb"); for f=1:frames - printf("\rframe: %d", f); + printf("frame: %d", f); L = min([model(f,2) max_amp-1]); Wo = model(f,1); Am = model(f,3:(L+2)); AmdB = 20*log10(Am); - % find mask and decimated mask + % find mask and decimate mask samples mask_sample_freqs_kHz = (1:L)*Wo*4/pi; maskdB = mask_model(AmdB, Wo, L); @@ -59,6 +60,8 @@ function newamp_batch(samname, optional_Am_out_name) non_masked_m = find(AmdB > maskdB); end + maskdB_ = decimate_frame_rate(maskdB_, model, decimate, f, frames, mask_sample_freqs_kHz); + % post filter - bump up samples by 6dB, reduce mask by same level to normalise gain if postfilter_en @@ -68,6 +71,7 @@ function newamp_batch(samname, optional_Am_out_name) maskdB_pf = maskdB_; end + if 0 % Early work as per blog post part 1 % Attempt 1 @@ -91,3 +95,4 @@ function newamp_batch(samname, optional_Am_out_name) endfunction + diff --git a/codec2-dev/octave/newamp_fbf.m b/codec2-dev/octave/newamp_fbf.m index 04050323..4a90df8a 100644 --- a/codec2-dev/octave/newamp_fbf.m +++ b/codec2-dev/octave/newamp_fbf.m @@ -25,7 +25,8 @@ function newamp_fbf(samname, f) model_name = strcat(samname,"_model.txt"); model = load(model_name); - + [frames tmp] = size(model); + plot_all_masks = 0; k = ' '; do @@ -41,6 +42,8 @@ function newamp_fbf(samname, f) Wo = model(f,1); L = model(f,2); Am = model(f,3:(L+2)); + %[h w] = freqz([1 -1],1,(1:L)*Wo); % pre-emphasise to reduce dynamic range + %Am = Am .* abs(h); AmdB = 20*log10(Am); % plotting @@ -70,7 +73,7 @@ function newamp_fbf(samname, f) plot(Am_freqs_kHz*1000, AmdB_, 'g+'); end - % estimate low rate samples + % decimate in frequency mask_sample_freqs_kHz = (1:L)*Wo*4/pi; [decmaskdB local_maxima error_log candidate_log target_log] = make_decmask_abys(maskdB, AmdB, Wo, L, mask_sample_freqs_kHz); @@ -79,8 +82,8 @@ function newamp_fbf(samname, f) nlm = min(nlm,4); tonef_kHz = local_maxima(1:nlm,2)*Wo*4/pi; toneamp_dB = local_maxima(1:nlm,1); - plot(tonef_kHz*1000, 70*ones(1,nlm), 'bk+'); - plot(mask_sample_freqs_kHz*1000, decmaskdB, 'm'); + %plot(tonef_kHz*1000, 70*ones(1,nlm), 'bk+'); + %plot(mask_sample_freqs_kHz*1000, decmaskdB, 'm'); % fit a line to amplitudes @@ -88,6 +91,11 @@ function newamp_fbf(samname, f) %plot(tonef_kHz*1000, tonef_kHz*m + b, "bk"); %plot(tonef_kHz*1000, 60 + toneamp_dB - (tonef_kHz*m + b), "r+"); + % decimated in time + + maskdB = decimate_frame_rate(maskdB, model, 4, f, frames, mask_sample_freqs_kHz); + plot(mask_sample_freqs_kHz*1000, maskdB, 'k'); + % optionally plot all masking curves if plot_all_masks -- 2.25.1