think I have bit stream working, sounds OK
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Sat, 9 Apr 2016 01:32:43 +0000 (01:32 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Sat, 9 Apr 2016 01:32:43 +0000 (01:32 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@2776 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/octave/newamp.m
codec2-dev/octave/newamp_batch.m
codec2-dev/src/c2sim.c

index f51ebd3bd30a3b0c5e2d744698e89cda575236dc..4e9133b48c1f3d1903f539d1b2f1e98a67e55829 100644 (file)
@@ -70,7 +70,7 @@ function [maskdB_ maskdB_cyclic Dabs dk_ D1 ind] = decimate_in_freq(maskdB, cycl
        [tmp D1_ind] = quantise(0:(2000/15):2500, D1);
        ind = [vq_ind D1_ind];
        [dk_ D1_] = index_to_params(ind, vq);
-       printf(" vq: %4.1f D1: %4.1f\n", std(dk_ - dk), D1_- D1);       
+       %printf(" vq: %4.1f D1: %4.1f\n", std(dk_ - dk), D1_- D1);       
     else
        dk_ = dk;
        D1_ = D1;
@@ -117,7 +117,7 @@ function maskdB_ = params_to_mask(L, k, dk_, D1_)
 
     Dk_ = fft(dk_);
     D_ = zeros(1,L);
-    D_(1) = D1_;                          % energy seprately quantised
+    D_(1) = D1_;                          % energy seperately quantised
     D_(2:k-1) = Dk_(2:k-1);
     D_(L-k+1:L) = Dk_(k+1:2*k);
     d_ = ifft(D_);                        % back to spectrum at rate L
@@ -131,6 +131,7 @@ function maskdB_ = params_to_mask(L, k, dk_, D1_)
     maskdB_ = [maskdB_(1:anchor) ppval(mask_pp, anchor+1:L)];
 endfunction
 
+
 function index = encode_log_Wo(Wo, bits)
     Wo_levels = 2.^bits;
     Wo_min = 2*pi/160;
@@ -799,12 +800,9 @@ endfunction
 
 % decimate frame rate of mask, use linear interpolation in the log domain 
 
-function maskdB_ = decimate_frame_rate(model, decimate, f, frames, mask_sample_freqs_kHz)
+function [maskdB_ Wo L] = decimate_frame_rate(model, decimate, f, frames, mask_sample_freqs_kHz)
     max_amp = 80;
 
-    Wo = model(f,1);
-    L = min([model(f,2) max_amp]);
-
     % determine frames that bracket the one we need to interp
 
     left_f = decimate*floor((f-1)/decimate)+1; 
@@ -837,6 +835,9 @@ function maskdB_ = decimate_frame_rate(model, decimate, f, frames, mask_sample_f
 
     % determine mask for left and right frames, sampling at Wo for this frame
 
+    Wo = left_fraction*left_Wo + right_fraction*right_Wo;
+    L = floor(pi/Wo);
+
     mask_sample_freqs_kHz = (1:L)*Wo*4/pi;
     maskdB_left = ppval(maskdB_left_pp, mask_sample_freqs_kHz);
     maskdB_right = ppval(maskdB_right_pp, mask_sample_freqs_kHz);
index 65d019d71bb4d598cf1f621666367e2fb0ed3a67..eb9fa5403ac240e97f7a435f273450ee24d7109e 100644 (file)
 %   $ cd ~/codec2-dev/octave
 %   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 -
+% 
+
+% Generate voicing file:
+% $ ./c2sim ../../raw/hts2a.raw --dump hts2a --lpc 10 --phase0 --dump_pitch_e hts2a_pitche.txt
+
+% Bit stream decode:
+% $ ./c2sim ../../raw/hts2a.raw --amead hts2a_am.out --awread hts2a_aw.out --Woread hts2a_Wo.out --phase0 --postfilter -o - | play -t raw -r 8000 -s -2 -
 
 
 % process a whole file and write results
@@ -32,6 +39,13 @@ function [dk_log D1_log] = newamp_batch(samname, optional_Am_out_name, optional_
   model_name = strcat(samname,"_model.txt");
   model = load(model_name);
   [frames nc] = size(model);
+  %frames = 5;
+
+  voicing_name = strcat(samname,"_pitche.txt");
+  if exist(voicing_name, "file") == 2
+    pitche = load(voicing_name);
+    voicing = pitche(:, 3);
+  end
   model_ = zeros(frames, nc);
   non_masked_m = zeros(frames,max_amp);
 
@@ -57,8 +71,7 @@ function [dk_log D1_log] = newamp_batch(samname, optional_Am_out_name, optional_
   sd_sum = 0;
   for f=1:frames
     printf("%d ", f);   
-    model_(f,2) = L = min([model(f,2) max_amp-1]);
-    model_(f,1) = Wo = model(f,1);
+    Wo = model(f,1); L = model(f,2);
     model_(f,3:(L+2)) = Am = model(f,3:(L+2));
 
     AmdB = 20*log10(Am);
@@ -91,8 +104,7 @@ function [dk_log D1_log] = newamp_batch(samname, optional_Am_out_name, optional_
     AmdB_ = AmdB;
     if dec_in_freq
       if vq_en
-        [AmdB_ tmp1 Dabs dk_ D1 ind] = decimate_in_freq(maskdB, 1, 10, vq);
-        ind_log = [ind_log; ind];
+        [AmdB_ tmp1 Dabs dk_ D1 ind_vq] = decimate_in_freq(maskdB, 1, 10, vq);
       else
         [AmdB_ tmp1 D dk_ D1] = decimate_in_freq(maskdB, 0, 10);
       end
@@ -103,13 +115,26 @@ function [dk_log D1_log] = newamp_batch(samname, optional_Am_out_name, optional_
     end
     sd_sum += std(maskdB - AmdB_);
 
+    ind_Wo = encode_log_Wo(Wo, 6);    
+    if vq_en
+      ind_log = [ind_log; ind_Wo voicing(f) (ind_vq-1) 0];
+    end
+    model_(f,1) = Wo_ = decode_log_Wo(ind_Wo, 6);
+    L_  = floor(pi/Wo);
+    model_(f,2) = L_ = min([L_ max_amp-1]);
+    L_ = min(L_, length(AmdB_));
     Am_ = zeros(1,max_amp);
-    Am_ = 10 .^ (AmdB_(1:L-1)/20); 
-    model_(f,3:(L+1)) = Am_;
+    Am_ = 10 .^ (AmdB_(1:L_)/20); 
+    model_(f,3:(L_+2)) = Am_;
+    printf("Wo: %f Wo_: %f L: %d L_: %d\n", Wo, Wo_, L, L_);
   end
 
   if train == 0
-    decode_model(model_, Am_out_name, Aw_out_name, synth_phase, dec_in_time);
+    bit_stream_name = strcat(samname,".bit");
+    bits_per_param = [6 1 8 8 4 1];
+    write_bit_stream_file(bit_stream_name, ind_log, bits_per_param);
+    %decode_model(model_, samname, synth_phase, dec_in_time);
+    decode_bit_stream_file(samname, bits_per_param);
   end
 
   printf("\nsd_sum: %5.2f\n", sd_sum/frames);
@@ -117,24 +142,136 @@ function [dk_log D1_log] = newamp_batch(samname, optional_Am_out_name, optional_
 endfunction
 
 
-% generate array of indexes
-% convert to bits and save to file of one char/bit
-% function to encode and save to file of bits
-% function to decode from file of bits
-% quantise Wo
-% move voicing bit through, move Wo through, maybe just load Wo and L and v?
+% Given a matrix with indexes on each row, convert to a bit stream and
+% write to file.  We only write every 4th frame due to DIT
+
+function write_bit_stream_file(fn, ind_log, bits_per_param)
+  fbit  = fopen(fn,"wb"); 
+  decimate = 4;
+
+  % take a row of quantiser indexes, convert to bits, save to file
+
+  [frames nind] = size(ind_log);
+  for f=1:decimate:frames
+    frame_of_bits = [];
+    arow = ind_log(f,:);
+    for i=1:nind
+      printf("i: %d bits_per_param: %d\n", i, bits_per_param(i));
+      some_bits = index_to_bits(arow(i), bits_per_param(i));
+      frame_of_bits = [frame_of_bits some_bits];
+    end
+    fwrite(fbit, frame_of_bits, "uchar");
+    arow
+    frame_of_bits
+
+  end
+
+  fclose(fbit);
+endfunction
+
+
+% Decode from a bit stream file
+
+function decode_bit_stream_file(samname, bits_per_param)
+  max_amp = 80;
+  nc = max_amp + 3;
+  load vq;
+  [tmp1 k2 tmp2] = size(vq)
+  k = k2/2;
+
+  bit_stream_name = strcat(samname,".bit")
+  fbit  = fopen(bit_stream_name, "rb"); 
+
+  model_= []; log_v = [];
+  nind = length(bits_per_param);
+  bits_per_frame = sum(bits_per_param);
+
+  % read a frame, decode to indexes, fill in model_ array
+
+  [frame nread] = fread(fbit, sum(bits_per_param), "uchar");
+  while (nread == bits_per_frame)
+
+    % read a frame, convert to indexes
+
+    nbit = 1;
+    ind = [];
+    for i=1:nind
+      field = frame(nbit:nbit+bits_per_param(i)-1);
+      nbit += bits_per_param(i);
+      ind = [ind bits_to_index(field, bits_per_param(i))];
+    end
+    
+    % convert index to model parameters
+
+    amodel_ = zeros(1,nc);
+    amodel_(1) = Wo_ = decode_log_Wo(ind(1), 6);
+    L_  = floor(pi/Wo_);
+    amodel_(2) = L_ = min([L_ max_amp-1]);
+
+    [dk_ D1_] = index_to_params(ind(3:5)+1, vq);
+    AmdB_ = params_to_mask(L_, k, dk_, D1_);
+
+    Am_ = zeros(1,max_amp);
+    Am_ = 10 .^ (AmdB_(1:L_)/20); 
+    amodel_(3:(L_+2)) = Am_;
+    model_ = [ model_; amodel_; zeros(3,nc)];
+
+    log_v = [log_v ind(2)];
+
+    % read next frame
+
+    [frame nread] = fread(fbit, sum(bits_per_param), "uchar");
+  endwhile
+
+  % decode entire array of model parameters
+
+  decode_model(model_, samname, 1, 1);
+
+  % save voicing file
+  
+  v_out_name = sprintf("%s_v.txt", samname);
+  fv  = fopen(v_out_name,"wt"); 
+  for f=1:length(log_v)
+    for i=1:4
+      fprintf(fv,"%d\n",log_v(f));
+    end
+  end
+  fclose(fv);
+endfunction
+
+
+% convert index to binary bits
+
+function bits = index_to_bits(value, numbits)
+  levels = 2.^numbits;
+  bits = zeros(1, numbits);
+  for b=1:numbits
+    bits(b) = bitand(value,2^(numbits-b)) != 0;
+  end
+end
+
+
+function value = bits_to_index(bits, numbits)
+  value = 2.^(numbits-1:-1:0) * bits;
+endfunction
+
 
-function decode_model(model_, Am_out_name, Aw_out_name, synth_phase, dec_in_time)
+function decode_model(model_, samname, synth_phase, dec_in_time)
   max_amp = 80;
 
+  Am_out_name = sprintf("%s_am.out", samname);
+  Aw_out_name = sprintf("%s_aw.out", samname);
+  Wo_out_name = sprintf("%s_Wo.out", samname);
   fam  = fopen(Am_out_name,"wb"); 
+  fWo  = fopen(Wo_out_name,"wb"); 
   if synth_phase
     faw = fopen(Aw_out_name,"wb"); 
   end
 
   % decoder loop -----------------------------------------------------
 
-  [frames tmp] = size(model_);
+  [frames tmp] = size(model_)
+  
   for f=1:frames
     %printf("frame: %d\n", f);
     L = min([model_(f,2) max_amp-1]);
@@ -142,6 +279,7 @@ function decode_model(model_, Am_out_name, Aw_out_name, synth_phase, dec_in_time
     Am_ = model_(f,3:(L+2));
     AmdB_ = 20*log10(Am_);
     sample_freqs_kHz = (1:L)*Wo*4/pi;
+    %printf("Wo: %f Wo_: %f L: %d L_: %d\n", Wo, Wo_, L, L_);
 
     % run post filter ahead of time so dec in time has post filtered frames to work with
 
@@ -153,18 +291,21 @@ function decode_model(model_, Am_out_name, Aw_out_name, synth_phase, dec_in_time
       % decimate mask samples in time
 
       decimate = 4;
-      AmdB_ = decimate_frame_rate(model_, decimate, f, frames, sample_freqs_kHz);
+      [AmdB_ Wo L] = decimate_frame_rate(model_, decimate, f, frames, sample_freqs_kHz);
     end
 
     Am_ = zeros(1,max_amp);
     Am_(2:L) = 10 .^ (AmdB_(1:L-1)/20);  % C array doesnt use A[0]
     fwrite(fam, Am_, "float32");
+    fwrite(fWo, Wo, "float32");
 
     if synth_phase
 
       % synthesis phase spectra from magnitiude spectra using minimum phase techniques
 
       fft_enc = 512;
+      model_(f,1) = Wo;
+      model_(f,2) = L;
       model_(f,3:(L+2)) = 10 .^ (AmdB_(1:L)/20);
       phase = determine_phase(model_, f);
       assert(length(phase) == fft_enc);
@@ -177,6 +318,7 @@ function decode_model(model_, Am_out_name, Aw_out_name, synth_phase, dec_in_time
   end
 
   fclose(fam);
+  fclose(fWo);
   fclose(faw);
 endfunction
 
index bebb7288adbd3de332c2f4ad60db8cc924080005..523f2ffb874fd03e9e5074fca7cc993e176e875d 100644 (file)
@@ -142,8 +142,8 @@ int main(int argc, char *argv[])
     int   bpfb_en = 0;
     float bpf_buf[BPF_N+N];
     float lspmelvq_mse = 0.0;
-    int   amread;
-    FILE *fam;
+    int   amread, Woread;
+    FILE *fam, *fWo;
     int   awread;
     FILE *faw;
 
@@ -182,6 +182,7 @@ int main(int argc, char *argv[])
         { "bpfb", no_argument, &bpfb_en, 1 },
         { "amread", required_argument, &amread, 1 },
         { "awread", required_argument, &awread, 1 },
+        { "Woread", required_argument, &Woread, 1 },
         #ifdef DUMP
         { "dump", required_argument, &dump, 1 },
         #endif
@@ -278,6 +279,12 @@ int main(int argc, char *argv[])
                        optarg, strerror(errno));
                     exit(1);
                 }
+            } else if(strcmp(long_options[option_index].name, "Woread") == 0) {
+               if ((fWo = fopen(optarg,"rb")) == NULL) {
+                   fprintf(stderr, "Error opening float Wo file: %s: %s.\n",
+                       optarg, strerror(errno));
+                    exit(1);
+                }
             } else if(strcmp(long_options[option_index].name, "amread") == 0) {
                if ((fam = fopen(optarg,"rb")) == NULL) {
                    fprintf(stderr, "Error opening float Am file: %s: %s.\n",
@@ -756,6 +763,11 @@ int main(int argc, char *argv[])
             assert(ret == MAX_AMP);
         }
 
+        if (Woread) {
+            int ret = fread(&model.Wo, sizeof(float), 1, fWo);
+            assert(ret == 1);
+        }
+
        /*------------------------------------------------------------*\
 
           Synthesise and optional decimation to 20 or 40ms frame rate