% $ 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
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);
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);
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
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);
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]);
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
% 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);
end
fclose(fam);
+ fclose(fWo);
fclose(faw);
endfunction