diff options
author | jmvalin <jmvalin@0101bb08-14d6-0310-b084-bc0e0c8e3800> | 2002-02-14 03:19:53 +0300 |
---|---|---|
committer | jmvalin <jmvalin@0101bb08-14d6-0310-b084-bc0e0c8e3800> | 2002-02-14 03:19:53 +0300 |
commit | 41e7cab29613c4ecd749e5d60b107153777f1b70 (patch) | |
tree | ef4adf4e564c746aa0b538913158229f58ef6daa |
Initial commit, some LPC stuff is already there...Initial
git-svn-id: http://svn.xiph.org/trunk/speex@3043 0101bb08-14d6-0310-b084-bc0e0c8e3800
-rw-r--r-- | libspeex/lpc.c | 90 | ||||
-rw-r--r-- | libspeex/lpc.h | 18 | ||||
-rw-r--r-- | libspeex/speex.c | 75 | ||||
-rw-r--r-- | libspeex/speex.h | 33 | ||||
-rw-r--r-- | libspeex/testenc.c | 33 |
5 files changed, 249 insertions, 0 deletions
diff --git a/libspeex/lpc.c b/libspeex/lpc.c new file mode 100644 index 0000000..877a9cb --- /dev/null +++ b/libspeex/lpc.c @@ -0,0 +1,90 @@ +/* + Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, + Technische Universitaet Berlin + + Any use of this software is permitted provided that this notice is not + removed and that neither the authors nor the Technische Universitaet Berlin + are deemed to have made any representations as to the suitability of this + software for any purpose nor are held responsible for any defects of + this software. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + + As a matter of courtesy, the authors request to be informed about uses + this software has found, about bugs in this software, and about any + improvements that may be of general interest. + + Berlin, 28.11.1994 + Jutta Degener + Carsten Bormann +*/ + + +/* LPC- and Reflection Coefficients + * + * The next two functions calculate linear prediction coefficients + * and/or the related reflection coefficients from the first P_MAX+1 + * values of the autocorrelation function. + */ + +/* Invented by N. Levinson in 1947, modified by J. Durbin in 1959. + */ + +#include "lpc.h" + +float /* returns minimum mean square error */ +wld( + float * lpc, /* [0...p-1] LPC coefficients */ + const float * ac, /* in: [0...p] autocorrelation values */ + float * ref, /* out: [0...p-1] reflection coef's */ + int p + ) +{ + int i, j; float r, error = ac[0]; + + lpc[0]=1; //for compatibility + lpc++; //for compatibility + + if (ac[0] == 0) { + for (i = 0; i < p; i++) ref[i] = 0; return 0; } + + for (i = 0; i < p; i++) { + + /* Sum up this iteration's reflection coefficient. + */ + r = -ac[i + 1]; + for (j = 0; j < i; j++) r -= lpc[j] * ac[i - j]; + ref[i] = r /= error; + + /* Update LPC coefficients and total error. + */ + lpc[i] = r; + for (j = 0; j < i/2; j++) { + float tmp = lpc[j]; + lpc[j] += r * lpc[i-1-j]; + lpc[i-1-j] += r * tmp; + } + if (i % 2) lpc[j] += lpc[j] * r; + + error *= 1.0 - r * r; + } + return error; +} + + +/* Compute the autocorrelation + * ,--, + * ac(i) = > x(n) * x(n-i) for all n + * `--' + * for lags between 0 and lag-1, and x == 0 outside 0...n-1 + */ +void autocorr( + const float * x, /* in: [0...n-1] samples x */ + float *ac, /* out: [0...lag-1] ac values */ + int lag, int n) +{ + float d; int i; + lag++; //Compensate for the old routine + while (lag--) { + for (i = lag, d = 0; i < n; i++) d += x[i] * x[i-lag]; + ac[lag] = d; + } +} diff --git a/libspeex/lpc.h b/libspeex/lpc.h new file mode 100644 index 0000000..b87120e --- /dev/null +++ b/libspeex/lpc.h @@ -0,0 +1,18 @@ +#ifndef LPC_H +#define LPC_H + +void autocorr( + const float * x, /* in: [0...n-1] samples x */ + float *ac, /* out: [0...lag-1] ac values */ + int lag, int n); + +float /* returns minimum mean square error */ +wld( + float * lpc, /* [0...p-1] LPC coefficients */ + const float * ac, /* in: [0...p] autocorrelation values */ + float * ref, /* out: [0...p-1] reflection coef's */ + int p + ); + + +#endif diff --git a/libspeex/speex.c b/libspeex/speex.c new file mode 100644 index 0000000..528e192 --- /dev/null +++ b/libspeex/speex.c @@ -0,0 +1,75 @@ +#include "speex.h" +#include "lpc.h" +#include <stdlib.h> +#include <string.h> +#include <math.h> + +void encoder_init(EncState *st) +{ + int i; + st->frameSize = 128; + st->windowSize = 256; + st->subframeSize=64; + st->lpcSize = 10; + st->bufSize = 256; + st->inBuf = malloc(st->bufSize*sizeof(float)); + for (i=0;i<st->bufSize;i++) + st->inBuf[i]=0; + st->window = malloc(st->windowSize*sizeof(float)); + /* Hanning window */ + for (i=0;i<st->windowSize;i++) + st->window[i]=.5*(1-cos(2*M_PI*i/st->windowSize)); + st->buf2 = malloc(st->windowSize*sizeof(float)); + st->lpc = malloc(st->lpcSize*sizeof(float)); + st->autocorr = malloc(st->lpcSize*sizeof(float)); + st->lsf = malloc(st->lpcSize*sizeof(float)); + st->rc = malloc(st->lpcSize*sizeof(float)); +} + +void encoder_destroy(EncState *st) +{ + free(st->inBuf); + free(st->window); + free(st->buf2); + free(st->lpc); + free(st->autocorr); + free(st->lsf); + free(st->rc); +} + +void encode(EncState *st, float *in, int *outSize, void *bits) +{ + int i; + float error; + + /* Copy new data in input buffer */ + memmove(st->inBuf, st->inBuf+st->bufSize-st->frameSize, (st->bufSize-st->frameSize)*sizeof(float)); + for (i=0;i<st->frameSize;i++) + st->inBuf[st->bufSize-st->frameSize+i] = in[i]; + + /* Window for analysis */ + for (i=0;i<st->windowSize;i++) + st->buf2[i] = st->inBuf[i] * st->window[i]; + + autocorr(st->buf2, st->autocorr, st->lpcSize-1, st->windowSize); + st->autocorr[0] += 1; /* prevents nan */ + st->autocorr[0] *= 1.0001; /* 40 dB noise floor */ + /*Should do lag windowing here */ + error = wld(st->lpc, st->autocorr, st->rc, st->lpcSize-1); + printf ("prediction error = %f, R[0] = %f, gain = %f\n", error, st->autocorr[0], + st->autocorr[0]/error); + +} + + +void decoder_init(DecState *st) +{ +} + +void decoder_destroy(DecState *st) +{ +} + +void decode(DecState *st, float *bits, float *out) +{ +} diff --git a/libspeex/speex.h b/libspeex/speex.h new file mode 100644 index 0000000..74bdd40 --- /dev/null +++ b/libspeex/speex.h @@ -0,0 +1,33 @@ +#ifndef SPEEX_H +#define SPEEX_H + + +typedef struct EncState { + int frameSize; + int subframeSize; + int lpcSize; + int bufSize; + float *inBuf; + float *window; + int windowSize; + float *buf2; + float *autocorr; + float *lpc; + float *lsf; + float *rc; +} EncState; + +typedef struct DecState { +} DecState; + +void encoder_init(EncState *st); +void encoder_destroy(EncState *st); +void encode(EncState *st, float *in, int *outSize, void *bits); + +void decoder_init(DecState *st); +void decoder_destroy(DecState *st); +void decode(DecState *st, float *bits, float *out); + + + +#endif diff --git a/libspeex/testenc.c b/libspeex/testenc.c new file mode 100644 index 0000000..53e34d3 --- /dev/null +++ b/libspeex/testenc.c @@ -0,0 +1,33 @@ +#include "speex.h" +#include <stdio.h> +#include <stdlib.h> + +#define FRAME_SIZE 128 + +main(int argc, char **argv) +{ + char *inFile, *outFile; + FILE *fin, *fout; + short in[FRAME_SIZE]; + float input[FRAME_SIZE]; + int i; + EncState st; + + encoder_init(&st); + if (argc != 3) + { + fprintf (stderr, "Usage: encode [in file] [out file]\n"); + exit(1); + } + inFile = argv[1]; + fin = fopen(inFile, "r"); + outFile = argv[2]; + fout = fopen(outFile, "w"); + while (!feof(fin)) + { + fread(in, sizeof(short), FRAME_SIZE, fin); + for (i=0;i<FRAME_SIZE;i++) + input[i]=in[i]; + encode(&st, input, NULL, NULL); + } +} |