parabolic interp working ok on hts1a, hts2a, vk5qi
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Thu, 22 Dec 2016 06:00:07 +0000 (06:00 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Thu, 22 Dec 2016 06:00:07 +0000 (06:00 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@2942 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/octave/newamp.m
codec2-dev/octave/newamp1_batch.m

index 5e15279532b80099152fd5863749df77b6be0663..3609b9eb61cfc824eebf8597164d3062731e3608 100644 (file)
 melvq; % mbest VQ functions
 
 % --------------------------------------------------------------------------------
-% Function used by rate K mel work
+% Functions used by rate K mel work
 % --------------------------------------------------------------------------------
 
+% General 2nd order parabolic interpolator.  Used splines orginally,
+% but this is much simpler and we don't need much accuracy.  Given two
+% vectors of points xp and yp, find interpolated values y at points x
+
+function y = interp_para(xp, yp, x)
+  assert( (length(xp) >=3) && (length(yp) >= 3) );
+
+  y = zeros(1,length(x));
+  for i=1:length(x)
+    xi = x(i);
+
+    % k is index into xp of where we start 3 points used to form parabola
+
+    k = 1;
+    while ((xp(k+1) < xi) && (k < (length(xp)-2))) 
+      k++;
+    end
+    
+    x1 = xp(k); y1 = yp(k); x2 = xp(k+1); y2 = yp(k+1); x3 = xp(k+2); y3 = yp(k+2);
+
+    a = ((y3-y2)/(x3-x2)-(y2-y1)/(x2-x1))/(x3-x1);
+    b = ((y3-y2)/(x3-x2)*(x2-x1)+(y2-y1)/(x2-x1)*(x3-x2))/(x3-x1);
+  
+    y(i) = a*(xi-x2)^2 + b*(xi-x2) + y2;
+  end
+endfunction
+
 
 % quantise input sample to nearest value in table, optionally return binary code
 
@@ -150,7 +177,6 @@ function [rate_K_surface rate_K_sample_freqs_kHz] = resample_const_rate_f(model,
   K = length(rate_K_sample_freqs_kHz);
   rate_K_surface = zeros(frames, K);
 
-
   for f=1:frames
     Wo = model(f,1);
     L = min([model(f,2) max_amp-1]);
@@ -166,8 +192,9 @@ function [rate_K_surface rate_K_sample_freqs_kHz] = resample_const_rate_f(model,
 
     rate_L_sample_freqs_kHz = (1:L)*Wo*4/pi;
     
-    rate_K_surface(f,:) = interp1(rate_L_sample_freqs_kHz, AmdB, rate_K_sample_freqs_kHz, "spline", "extrap");
-    
+    %rate_K_surface(f,:) = interp1(rate_L_sample_freqs_kHz, AmdB, rate_K_sample_freqs_kHz, "spline", "extrap");
+    rate_K_surface(f,:)  = interp_para(rate_L_sample_freqs_kHz, AmdB, rate_K_sample_freqs_kHz);    
+
     %printf("\r%d/%d", f, frames);
   end
   %printf("\n");
@@ -188,7 +215,8 @@ function [model_ AmdB_] = resample_rate_L(model, rate_K_surface, rate_K_sample_f
     
     % back down to rate L
 
-    AmdB_ = interp1(rate_K_sample_freqs_kHz, rate_K_surface(f,:), rate_L_sample_freqs_kHz, "spline", 0);
+    % AmdB_ = interp1(rate_K_sample_freqs_kHz, rate_K_surface(f,:), rate_L_sample_freqs_kHz, "spline", 0);
+    AmdB_ = interp_para([ 0 rate_K_sample_freqs_kHz 4], [0 rate_K_surface(f,:) 0], rate_L_sample_freqs_kHz);
 
     model_(f,1) = Wo; model_(f,2) = L; model_(f,3:(L+2)) = 10 .^ (AmdB_(1:L)/20);
    end
index 63376553111da154770c9d0fd7f94ff3bd1414a9..ef537e01e0771b8322150b4882b3a50cfd5ab975 100644 (file)
@@ -19,6 +19,8 @@
 
   Usage:
 
+    build codec2 with -DDUMP - see codec2-dev/README, then:
+
     ~/codec2-dev/build_linux/src$ ./c2sim ../../raw/hts1a.raw --dump hts1a
     $ cd ~/codec2-dev/octave
     octave:14> newamp1_batch("../build_linux/src/hts1a")
@@ -155,7 +157,13 @@ endfunction
 % -----------------------------------------------------------------------------------------
 % Linear decimator/interpolator that operates at rate K, includes VQ, post filter, and Wo/E
 % quantisation.  Evolved from abys decimator below.  Simulates the entire encoder/decoder.
+
+#{
+   todo: 
+     [ ] M=8 nomenclature, make it closer to existing 25ms C modes
+     [ ] frame by frame-ish operation, close to C implementations
+#}
+
 function [model_ voicing_ indexes] = experiment_rate_K_dec(model, voicing)
   max_amp = 80;
   [frames nc] = size(model);
@@ -171,6 +179,9 @@ function [model_ voicing_ indexes] = experiment_rate_K_dec(model, voicing)
   [surface sample_freqs_kHz] = resample_const_rate_f_mel(model, K);
   target_surface = surface;
 
+  figure(1);
+  mesh(surface);
+
   % VQ rate K surface.  TODO: If we are decimating by M/2=4 we really
   % only need to do this every 4th frame.
 
@@ -181,6 +192,8 @@ function [model_ voicing_ indexes] = experiment_rate_K_dec(model, voicing)
     mean_f(f) = mean(surface(f,:));
     surface_no_mean(f,:) = surface(f,:) - mean_f(f);
   end
+  figure(2);
+  mesh(surface_no_mean);
 
   [res surface_no_mean_ ind] = mbest(train_120_vq, surface_no_mean, m);
   indexes(:,1:2) = ind;
@@ -188,6 +201,8 @@ function [model_ voicing_ indexes] = experiment_rate_K_dec(model, voicing)
   for f=1:frames
     surface_no_mean_(f,:) = post_filter(surface_no_mean_(f,:), sample_freqs_kHz, 1.5);
   end
+  figure(3);
+  mesh(surface_no_mean_);
     
   surface_ = zeros(frames, K);
   energy_q = 10 + 40/16*(0:15);
@@ -198,6 +213,9 @@ function [model_ voicing_ indexes] = experiment_rate_K_dec(model, voicing)
     surface_(f,:) = surface_no_mean_(f,:) + mean_f_;
   end
 
+  figure();
+  mesh(surface_);
+
   % break into segments of M frames.  We have 3 samples in M frame
   % segment spaced M/2 apart and interpolate the rest.  This evolved
   % from AbyS scheme below but could be simplified to simple linear