[ ] Milestone 2 - Spectral amplitudes quantised
[ ] Milestone 3 - Prototype 2400 bit/s codec
+LPC Modelling
+-------------
+
+$ ./sinedec ../raw/hts1a.raw hts1a.mdl --lpc 10 - hts1a_lpc10.raw
+
+Disucss why LPC modelling works so well when Am recovered via RMS method
+(Section 5.1 of thesis). Equal area model of LPC spectra versus harmonic?
+Seems to work remarkably well, especially compared to sampling. SNRs up to
+30dB on female frames.
+
+Octave Scripts
+--------------
+
+pl.m - plot a segment from a raw file
+
+pl2.m - plot the same segments from two different files to compare
+
+plamp.m - menu based GUI interface to "dump" files, move back and forward
+ through file exaimining time and frequency domain parameters, lpc
+ model etc
+
+ $ ./sinedec ../raw/hts1a.raw hts1a.mdl --lpc 10 --dump hts1a
+ $ cd ../octave
+ $ octave
+ octave:1> plamp("../src/hts1",25)
+
Directories
-----------
% Copyright David Rowe 2009
% This program is distributed under the terms of the GNU General Public License
% Version 2
+%
+% Plot ampltiude modelling information from dump files.
function plamp(samname, f)
sn_name = strcat(samname,"_sn.txt");
Sn = load(sn_name);
+ sw_name = strcat(samname,"_sw.txt");
+ Sw = load(sw_name);
model_name = strcat(samname,"_model.txt");
model = load(model_name);
modelq_name = strcat(samname,"_qmodel.txt");
pw_name = strcat(samname,"_pw.txt");
Pw = load(pw_name);
- figure(1);
- clg;
- s = [ Sn(2*f+1,:) Sn(2*f+2,:) ];
- plot(s);
-
- figure(2);
- Wo = model(f,1);
- L = model(f,2);
- Am = model(f,3:(L+2));
- plot((1:L)*Wo*4000/pi, 20*log10(Am),";Am;");
- hold on;
- Amq = modelq(f,3:(L+2));
- plot((1:L)*Wo*4000/pi, 20*log10(Amq),";Amq;" );
- plot((0:255)*4000/256, 10*log10(Pw(f,:)),";Pw;");
- plot((1:L)*Wo*4000/pi, 20*log10(Amq) - 20*log10(Am),";Am_err;" );
- hold off;
+ do
+ figure(1);
+ clg;
+ s = [ Sn(2*f+1,:) Sn(2*f+2,:) ];
+ plot(s);
+ axis([1 length(s) -20000 20000]);
+
+ figure(2);
+ Wo = model(f,1);
+ L = model(f,2);
+ Am = model(f,3:(L+2));
+ plot((1:L)*Wo*4000/pi, 20*log10(Am),";Am;");
+ axis([1 4000 -10 80]);
+ hold on;
+ plot((0:255)*4000/256, Sw(f,:),";Sw;");
+ Amq = modelq(f,3:(L+2));
+ plot((1:L)*Wo*4000/pi, 20*log10(Amq),";Amq;" );
+ plot((0:255)*4000/256, 10*log10(Pw(f,:)),";Pw;");
+ signal = Am * Am';
+ noise = (Am-Amq) * (Am-Amq)';
+ snr = 10*log10(signal/noise);
+ Am_err_label = sprintf(";Am_err SNR %4.2f dB;",snr);
+ %plot((1:L)*Wo*4000/pi, 20*log10(Amq) - 20*log10(Am),";Am_err;" );
+ plot((1:L)*Wo*4000/pi, 20*log10(Amq) - 20*log10(Am), Am_err_label);
+ hold off;
+
+ printf("\rframe: %d menu: n-next b-back q-quit ", f);
+ fflush(stdout);
+ k = kbhit();
+ if (k == 'n')
+ f = f + 1;
+ endif
+ if (k == 'b')
+ f = f - 1;
+ endif
+ until (k == 'q')
+ printf("\n");
- Am_err = mean(abs(20*log10(Amq) - 20*log10(Am)))
endfunction
SINENC_OBJ = sinenc.o globals.o initenc.o four1.o refine.o spec.o
SINEDEC_OBJ = sinedec.o globals.o initenc.o initdec.o four1.o synth.o \
- quantise.o lpc.o dump.o
+ quantise.o lpc.o dump.o refine.o
all: sinenc sinedec
static int dumpon = 0;
static FILE *fsn;
+static FILE *fsw;
static FILE *fmodel;
static FILE *fqmodel;
static FILE *fpw;
fsn = fopen(s, "wt");
assert(fsn != NULL);
+ sprintf(s,"%s_sw.txt", prefix);
+ fsw = fopen(s, "wt");
+ assert(fsw != NULL);
+
sprintf(s,"%s_model.txt", prefix);
fmodel = fopen(s, "wt");
assert(fmodel != NULL);
fprintf(fsn,"\n");
}
+void dump_Sw(COMP Sw[]) {
+ int i;
+
+ if (!dumpon) return;
+
+ for(i=0; i<FFT_ENC/2; i++)
+ fprintf(fsw,"%f\t",
+ 10.0*log10(Sw[i].real*Sw[i].real + Sw[i].imag*Sw[i].imag));
+ fprintf(fsw,"\n");
+}
+
void dump_model(MODEL *model) {
int l;
void dump_on(char filename_prefix[]);
void dump_off();
void dump_Sn(float Sn[]);
+void dump_Sw(COMP Sw[]);
void dump_model(MODEL *m);
void dump_quantised_model(MODEL *m);
void dump_Pw(COMP Pw[]);
float ak[MAX_ORDER+1];
float E;
int i;
- float sd; /* spectral distortion for this frame */
+ float snr;
for(i=0; i<AW_ENC; i++)
Wn[i] = Sn[i]*w[i];
for(i=0; i<=order; i++)
E += ak[i]*R[i];
- aks_to_M2(ak,order,model,E,&sd); /* {ak} -> {Am} LPC decode */
+ aks_to_M2(ak,order,model,E,&snr); /* {ak} -> {Am} LPC decode */
- return sd;
+ return snr;
}
/*---------------------------------------------------------------------------*\
int order,
MODEL *model, /* sinusoidal model parameters for this frame */
float E, /* energy term */
- float *sd /* spectral distortion for this frame in dB */
+ float *snr /* signal to noise ratio for this frame in dB */
)
{
COMP Pw[FFT_DEC]; /* power spectrum */
float r; /* no. rads/bin */
float Em; /* energy in band */
float Am; /* spectral amplitude sample */
- float noise;
+ float signal, noise;
r = TWO_PI/(FFT_DEC);
/* Determine magnitudes by linear interpolation of P(w) -------------------*/
- noise = 0.0;
+ signal = noise = 0.0;
for(m=1; m<=model->L; m++) {
am = floor((m - 0.5)*model->Wo/r + 0.5);
bm = floor((m + 0.5)*model->Wo/r + 0.5);
Em += Pw[i].real;
Am = sqrt(Em);
- noise += pow(log10(Am/model->A[m]),2.0);
+ signal += pow(model->A[m],2.0);
+ noise += pow(model->A[m] - Am,2.0);
model->A[m] = Am;
}
- *sd = 20.0*sqrt(noise/model->L);
-
+ *snr = 10.0*log10(signal/noise);
}
#include "sine.h"
float lpc_model_amplitudes(float Sn[], MODEL *model, int order, int lsp);
-void aks_to_M2(float ak[], int order, MODEL *model, float E, float *sd);
+void aks_to_M2(float ak[], int order, MODEL *model, float E, float *snr);
#endif
char out_file[MAX_STR];
int arg;
- float sd;
- float sum_sd;
+ float snr;
+ float sum_snr;
int lpc_model, order;
int dump;
/* Main loop ------------------------------------------------------------*/
frames = 0;
- sum_sd = 0;
+ sum_snr = 0;
while(fread(&model,sizeof(model),1,fmodel)) {
frames++;
for(i=0; i<N; i++)
Sn[i+N+AW_ENC/2] = buf[i];
dump_Sn(Sn);
-
+ dft_speech(); dump_Sw(Sw);
+
dump_model(&model);
/* optional LPC model amplitudes */
if (lpc_model) {
- sd = lpc_model_amplitudes(Sn, &model, order, 0);
- sum_sd += sd;
+ snr = lpc_model_amplitudes(Sn, &model, order, 0);
+ sum_snr += snr;
}
dump_quantised_model(&model);
fclose(fout);
if (lpc_model)
- printf("sd av = %5.2f dB\n", sum_sd/frames);
+ printf("SNR av = %5.2f dB\n", sum_snr/frames);
if (dump)
dump_off();