[xiph-cvs] cvs commit: speex/libspeex sb_celp.c testenc_wb.c
Jean-Marc Valin
jm at xiph.org
Thu Nov 13 00:45:57 PST 2003
jm 03/11/13 03:45:56
Modified: libspeex sb_celp.c testenc_wb.c
Log:
fixed-point: converting wideband excitation gain to int (halfway done)
Revision Changes Path
1.148 +43 -22 speex/libspeex/sb_celp.c
Index: sb_celp.c
===================================================================
RCS file: /usr/local/cvsroot/speex/libspeex/sb_celp.c,v
retrieving revision 1.147
retrieving revision 1.148
diff -u -r1.147 -r1.148
--- sb_celp.c 12 Nov 2003 17:16:38 -0000 1.147
+++ sb_celp.c 13 Nov 2003 08:45:55 -0000 1.148
@@ -489,10 +489,11 @@
for (sub=0;sub<st->nbSubframes;sub++)
{
spx_sig_t *exc, *sp, *res, *target, *sw;
- float tmp, filter_ratio;
+ float tmp;
+ spx_word16_t filter_ratio;
int offset;
- float rl, rh, eh=0, el=0;
- int fold;
+ float rl, rh;
+ spx_word16_t eh=0;
offset = st->subframeSize*sub;
sp=st->high+offset;
@@ -532,12 +533,11 @@
rl=1/(fabs(rl)+.01);
rh=1/(fabs(rh)+.01);
/* Compute ratio, will help predict the gain */
+#ifdef FIXED_POINT
+ filter_ratio=128*fabs(.01+rh)/(.01+fabs(rl));
+#else
filter_ratio=fabs(.01+rh)/(.01+fabs(rl));
-
- fold = filter_ratio<5;
- /*printf ("filter_ratio %f\n", filter_ratio);*/
- fold=0;
-
+#endif
/* Compute "real excitation" */
fir_mem2(sp, st->interp_qlpc, exc, st->subframeSize, st->lpcSize, st->mem_sp2);
/* Compute energy of low-band and high-band excitation */
@@ -546,13 +546,13 @@
if (!SUBMODE(innovation_quant)) {/* 1 for spectral folding excitation, 0 for stochastic */
float g;
-
+ float el;
el = compute_rms(low_innov+offset, st->subframeSize);
/* Gain to use if we want to use the low-band excitation for high-band */
g=eh/(.01+el);
- g *= filter_ratio;
+ g *= filter_ratio/128.;
/*print_vec(&g, 1, "gain factor");*/
/* Gain quantization */
{
@@ -566,25 +566,46 @@
}
} else {
- float gc, scale, scale_1;
-
+ spx_word16_t gc;
+ spx_word32_t scale;
+ spx_word16_t el;
el = compute_rms(low_exc+offset, st->subframeSize);
- /*FIXME: cleanup the "historical" mess with sqrt(st->subframeSize) */
- gc = (1+eh)*filter_ratio/(1+el)/sqrt(st->subframeSize);
+ gc = DIV32_16(MULT16_16((int)(filter_ratio),(1+eh)),1+el);
+
+ /* This is a kludge that cleans up a historical bug */
+ if (st->subframeSize==80)
+ gc *= 0.70711;
+ /*printf ("%f %f %f %f\n", el, eh, filter_ratio, gc);*/
+#ifdef FIXED_POINT
{
- int qgc = (int)floor(.5+3.7*(log(gc)+2));
+ int qgc = (int)floor(.5+3.7*(log(gc/128.)+0.15556));
if (qgc<0)
qgc=0;
if (qgc>15)
qgc=15;
speex_bits_pack(bits, qgc, 4);
- gc = exp((1/3.7)*qgc-2);
+ gc = 128*exp((1/3.7)*qgc-0.15556);
}
+#else
+ {
+ int qgc = (int)floor(.5+3.7*(log(gc)+0.15556));
+ if (qgc<0)
+ qgc=0;
+ if (qgc>15)
+ qgc=15;
+ speex_bits_pack(bits, qgc, 4);
+ gc = exp((1/3.7)*qgc-0.15556);
+ }
+#endif
+ if (st->subframeSize==80)
+ gc *= 1.4142;
- scale = gc*(1+el*sqrt(st->subframeSize))/filter_ratio;
- scale_1 = 1/scale;
-
+#ifdef FIXED_POINT
+ scale = SHL(DIV32_16(SHL(gc,SIG_SHIFT-4),filter_ratio),4)*(1+el);
+#else
+ scale = gc*(1.+el)/filter_ratio;
+#endif
for (i=0;i<st->subframeSize;i++)
exc[i]=VERY_SMALL;
exc[0]=SIG_SCALING;
@@ -615,7 +636,7 @@
for (i=0;i<st->subframeSize;i++)
exc[i]=0;
- signal_div(target, target, SIG_SCALING*scale, st->subframeSize);
+ signal_div(target, target, scale, st->subframeSize);
/* Reset excitation */
for (i=0;i<st->subframeSize;i++)
@@ -627,7 +648,7 @@
innov, syn_resp, bits, stack, (st->complexity+1)>>1);
/*print_vec(target, st->subframeSize, "after");*/
- signal_mul(innov, innov, SIG_SCALING*scale, st->subframeSize);
+ signal_mul(innov, innov, scale, st->subframeSize);
for (i=0;i<st->subframeSize;i++)
exc[i] += innov[i];
@@ -643,7 +664,7 @@
SUBMODE(innovation_params), st->lpcSize, st->subframeSize,
innov2, syn_resp, bits, tmp_stack, (st->complexity+1)>>1);
for (i=0;i<st->subframeSize;i++)
- innov2[i]*=scale*(1/2.5);
+ innov2[i]*=scale*(1/2.5)/SIG_SCALING;
for (i=0;i<st->subframeSize;i++)
exc[i] += innov2[i];
}
<p><p>1.34 +72 -29 speex/libspeex/testenc_wb.c
Index: testenc_wb.c
===================================================================
RCS file: /usr/local/cvsroot/speex/libspeex/testenc_wb.c,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -r1.33 -r1.34
--- testenc_wb.c 8 Oct 2003 05:03:47 -0000 1.33
+++ testenc_wb.c 13 Nov 2003 08:45:55 -0000 1.34
@@ -1,6 +1,11 @@
#include "speex.h"
#include <stdio.h>
#include <stdlib.h>
+#include "speex_callbacks.h"
+
+#ifdef COUNT_MIPS
+extern long long spx_mips;
+#endif
#define FRAME_SIZE 320
#include <math.h>
@@ -8,8 +13,11 @@
{
char *inFile, *outFile, *bitsFile;
FILE *fin, *fout, *fbits=NULL;
- short in[FRAME_SIZE];
- float input[FRAME_SIZE], bak[FRAME_SIZE], bak2[FRAME_SIZE];
+ short in_short[FRAME_SIZE];
+ short out_short[FRAME_SIZE];
+ float in_float[FRAME_SIZE];
+ float sigpow,errpow,snr, seg_snr=0;
+ int snr_frames = 0;
char cbits[200];
int nbBits;
int i;
@@ -18,34 +26,52 @@
SpeexBits bits;
int tmp;
int bitCount=0;
+ int skip_group_delay;
+ SpeexCallback callback;
+
+ sigpow = 0;
+ errpow = 0;
- for (i=0;i<FRAME_SIZE;i++)
- bak2[i]=0;
st = speex_encoder_init(&speex_wb_mode);
dec = speex_decoder_init(&speex_wb_mode);
-
+
+ callback.callback_id = SPEEX_INBAND_CHAR;
+ callback.func = speex_std_char_handler;
+ callback.data = stderr;
+ speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback);
+
+ callback.callback_id = SPEEX_INBAND_MODE_REQUEST;
+ callback.func = speex_std_mode_request_handler;
+ callback.data = st;
+ speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback);
+
tmp=0;
speex_decoder_ctl(dec, SPEEX_SET_ENH, &tmp);
tmp=0;
speex_encoder_ctl(st, SPEEX_SET_VBR, &tmp);
- tmp=10;
+ tmp=8;
speex_encoder_ctl(st, SPEEX_SET_QUALITY, &tmp);
tmp=5;
speex_encoder_ctl(st, SPEEX_SET_COMPLEXITY, &tmp);
tmp=3;
speex_encoder_ctl(st, SPEEX_SET_HIGH_MODE, &tmp);
- tmp=6;
+ tmp=7;
speex_encoder_ctl(st, SPEEX_SET_LOW_MODE, &tmp);
-
+
+
+ speex_mode_query(&speex_wb_mode, SPEEX_MODE_FRAME_SIZE, &tmp);
+ fprintf (stderr, "frame size: %d\n", tmp);
+ skip_group_delay = 223;
+
if (argc != 4 && argc != 3)
- {
+ {
fprintf (stderr, "Usage: encode [in file] [out file] [bits file]\nargc = %d", argc);
exit(1);
}
inFile = argv[1];
fin = fopen(inFile, "r");
outFile = argv[2];
- fout = fopen(outFile, "w");
+ fout = fopen(outFile, "w+");
if (argc==4)
{
bitsFile = argv[3];
@@ -54,41 +80,58 @@
speex_bits_init(&bits);
while (!feof(fin))
{
- fread(in, sizeof(short), FRAME_SIZE, fin);
+ fread(in_short, sizeof(short), FRAME_SIZE, fin);
if (feof(fin))
break;
for (i=0;i<FRAME_SIZE;i++)
- bak[i]=input[i]=in[i];
+ in_float[i]=in_short[i];
speex_bits_reset(&bits);
- speex_encode(st, in, &bits);
+
+ speex_encode(st, in_short, &bits);
nbBits = speex_bits_write(&bits, cbits, 200);
bitCount+=bits.nbBits;
- /*printf ("Encoding frame in %d bits\n", nbBits*8);*/
+
if (argc==4)
fwrite(cbits, 1, nbBits, fbits);
- {
- float enoise=0, esig=0, snr;
- for (i=0;i<FRAME_SIZE;i++)
- {
- enoise+=(bak2[i]-input[i])*(bak2[i]-input[i]);
- esig += bak2[i]*bak2[i];
- }
- snr = 10*log10((esig+1)/(enoise+1));
- /*printf ("real SNR = %f\n", snr);*/
- }
speex_bits_rewind(&bits);
-
- speex_decode(dec, &bits, in);
+ speex_decode(dec, &bits, out_short);
speex_bits_reset(&bits);
- fwrite(in, sizeof(short), FRAME_SIZE, fout);
+
+ fwrite(&out_short[skip_group_delay], sizeof(short), FRAME_SIZE-skip_group_delay, fout);
+ skip_group_delay = 0;
}
-
fprintf (stderr, "Total encoded size: %d bits\n", bitCount);
speex_encoder_destroy(st);
speex_decoder_destroy(dec);
- speex_bits_destroy(&bits);
+
+ rewind(fin);
+ rewind(fout);
+
+ while ( FRAME_SIZE == fread(in_short, sizeof(short), FRAME_SIZE, fin)
+ &&
+ FRAME_SIZE == fread(out_short, sizeof(short), FRAME_SIZE,fout) )
+ {
+ float s=0, e=0;
+ for (i=0;i<FRAME_SIZE;++i) {
+ s += (float)in_short[i] * in_short[i];
+ e += ((float)in_short[i]-out_short[i]) * ((float)in_short[i]-out_short[i]);
+ }
+ seg_snr += 10*log10((s+160)/(e+160));
+ sigpow += s;
+ errpow += e;
+ snr_frames++;
+ }
fclose(fin);
fclose(fout);
+
+ snr = 10 * log10( sigpow / errpow );
+ seg_snr /= snr_frames;
+ fprintf(stderr,"SNR = %f\nsegmental SNR = %f\n",snr, seg_snr);
+
+#ifdef COUNT_MIPS
+ printf ("Total: %f MIPS\n", (float)(1e-6*50*spx_mips/snr_frames));
+#endif
+
return 1;
}
<p><p>--- >8 ----
List archives: http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body. No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.
More information about the commits
mailing list