ds48to16.c

来自「julius version 4.12.about sound recognit」· C语言 代码 · 共 363 行

C
363
字号
/** * @file   ds48to16.c * * <JA> * @brief  48kHz -> 16kHz ダウンサンプリング * * </JA> * <EN> * @brief  Down sampling from 48kHz to 16kHz * * </EN> * * @author Akinobu LEE * @date   Sun Feb 13 16:18:26 2005 * * $Revision: 1.2 $ *  *//* * Copyright (c) 1991-2007 Kawahara Lab., Kyoto University * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology * Copyright (c) 2005-2007 Julius project team, Nagoya Institute of Technology, Nagoya Institute of Technology * All rights reserved */#include <sent/stddefs.h>#include <sent/adin.h>/// TRUE if use embedded values on header#define USE_HEADER_COEF/// USB device sampling rate#ifdef USE_HEADER_COEF/// filter parameters in header#include "lpfcoef_3to4.h"#include "lpfcoef_2to1.h"#endif/* work area for down sampling */#define	mod(x)	((x) & (DS_RBSIZE -1)) ///< Buffer index cycler#ifdef USE_HEADER_COEF/**  * Set 1/2 filter coefficients from header values. *  * @param f [out] filter info */static voidload_filter_from_header_2to1(DS_FILTER *f){  int i;   /* read the filter coefficients from header file */  for(i=0;i<DS_RBSIZE + 1; i++) {    if (i >= lpfcoef_2to1_num) break;    f->hdn[i] = lpfcoef_2to1[i];  }  f->hdn_len = i - 1;}/**  * Set 4/2 filter coefficients from header values. *  * @param f [out] filter info */static voidload_filter_from_header_3to4(DS_FILTER *f){  int i;   /* read the filter coefficients from header file */  for(i=0;i<DS_RBSIZE + 1; i++) {    if (i >= lpfcoef_3to4_num) break;    f->hdn[i] = lpfcoef_3to4[i];  }  f->hdn_len = i - 1;}#else  /* ~USE_HEADER_COEF *//**  * Read filter coefficients from file. *  * @param f [out] filter info * @param coeffile [in] filename */static booleanload_filter(DS_FILTER *f, char *coeffile){  FILE *fp;  static char buf[512];  int i;   /* read the filter coefficients */  if ((fp = fopen(coeffile, "r")) == NULL) {    jlog("Error: ds48to16: failed to open filter coefficient file \"%s\"\n", coeffile);    return FALSE;  }  for(i=0;i<DS_RBSIZE + 1; i++) {    if (fgets(buf, 512, fp) == NULL) break;    f->hdn[i] = atof(buf);  }  fclose(fp);  if (i <= 0) {    jlog("Error: ds48to16: failed to read filter coefficient from \"%s\"\n", coeffile);    return FALSE;  }  f->hdn_len = i - 1;  return TRUE;}#endif/**  * Initialize filter values *  * @param f [i/o] filter info * @param u [in] up sampling rate * @param d [in] down sampling rate */static voidinit_filter(DS_FILTER *f, int d, int u){   f->decrate = d;  f->intrate = u;  /* set filter starting point */  f->delay = f->hdn_len / (2 * f->decrate);  /* reset index */  f->indx = 0;  /* reset pointer */  f->bp = 0;  /* reset output counter */  f->count = 1;}/**  * Store input for FIR filter *  * @param f [i/o] filter info * @param in [in] an input sample * </EN> */static voidfirin(DS_FILTER *f, double in){  f->indx = mod(f->indx - 1);  f->rb[f->indx] = in;}/**  * Get filtered output from FIR filter *  * @param f [i/o] filter info * @param os [in] point *  * @return output value */static doublefirout(DS_FILTER *f, int os){  double out;  int k, l;    out = 0.0;  for(k = os, l = f->indx ; k <= f->hdn_len; k += f->intrate, l = mod(l + 1)) {    out += f->rb[l] * f->hdn[k];  }  return(out);}/**  * Perform down sampling of input samples. *  * @param f [i/o] filter info * @param dst [out] store the resulting samples * @param src [in] input samples * @param len [in] number of input samples * @param maxlen [in] maximum length of dst *  * @return the number of samples written to dst, or -1 on errror. * </EN> */static intdo_filter(DS_FILTER *f, double *dst, double *src, int len, int maxlen){  int dstlen;  int s;  int d;  int i, k;  s = 0;  dstlen = 0;  while(1) {    /* fulfill temporal buffer */    /* at this point, x[0..bp-1] may contain the left samples of last call */    while (f->bp < DS_BUFSIZE) {      if (s >= len) break;      f->x[f->bp++] = src[s++];    }    if (f->bp < DS_BUFSIZE) {	      /* when reached last of sample, leave the rest in x[] and exit */      break;    }    /* do conversion from x[0..bp-1] to y[] */    d = 0;    for(k=0;k<f->bp;k++) {      firin(f, f->x[k]);      for(i=0;i<f->intrate;i++) {	f->count--;	if(f->count == 0) {	  f->y[d++] = firout(f, i);	  f->count = f->decrate;	}      }    }    /* store the result to dst[] */    if(f->delay) {      if(d > f->delay) {	/* input samples > delay, store the overed samples and enter no-delay state */	d -= f->delay;	for(i=0;i<d;i++) {	  if (dstlen >= maxlen) break;	  dst[dstlen++] = f->y[f->delay + i];	}	f->delay = 0;	if (dstlen >= maxlen) {	  jlog("Error: ds48to16: buffer overflow in down sampling, inputs may be lost!\n");	  return -1;	}      } else {	/* input samples < delay, decrease delay and wait */	f->delay -= d;      }    } else {      /* no-delay state: store immediately */      for(i=0;i<d;i++) {	if (dstlen >= maxlen) break;	dst[dstlen++] = f->y[i];      }      if (dstlen >= maxlen) {	jlog("Error: ds48to16: buffer overflow in down sampling, inputs may be lost!\n");	return -1;      }    }    /* reset pointer */    f->bp -= DS_BUFSIZE;  }  return dstlen;}/**  * Setup for down sampling *  * @return newly allocated buffer for down sampling */DS_BUFFER *ds48to16_new(){  DS_BUFFER *ds;  int i;  /* define 3 filters:      48kHz --f1(3/4)-> 64kHz --f2(1/2)-> 32kHz --f3(1/2)-> 16kHz */    ds = (DS_BUFFER *)mymalloc(sizeof(DS_BUFFER));  for(i=0;i<3;i++) ds->fir[i] = (DS_FILTER *)mymalloc(sizeof(DS_FILTER));#ifdef USE_HEADER_COEF  /* set from embedded header */  load_filter_from_header_3to4(ds->fir[0]);  load_filter_from_header_2to1(ds->fir[1]);  load_filter_from_header_2to1(ds->fir[2]);  jlog("Stat: ds48to16: loaded FIR filters for down sampling\n");#else  /* read from file */  if (load_filter(ds->fir[0], "lpfcoef.3to4") == FALSE) return FALSE;  if (load_filter(ds->fir[1], "lpfcoef.2to1") == FALSE) return FALSE;  if (load_filter(ds->fir[2], "lpfcoef.2to1") == FALSE) return FALSE;  jlog("Stat: ds48to16: initialize FIR filters for down sampling\n");#endif  init_filter(ds->fir[0], 3, 4);  init_filter(ds->fir[1], 2, 1);  init_filter(ds->fir[2], 2, 1);  ds->buflen = 0;  return(ds);}/**  * Free the down sampling buffer. *  * @param ds [i/o] down sampling buffer to free *  */voidds48to16_free(DS_BUFFER *ds){  int i;  if (ds->buflen != 0) {    for(i=0;i<4;i++) free(ds->buf[i]);  }  for(i=0;i<3;i++) free(ds->fir[i]);    free(ds);}/**  * Perform down sampling of input samples to 1/3. *  * @param dst [out] store the resulting samples * @param src [in] input samples * @param srclen [in] number of input samples * @param maxdstlen [in] maximum length of dst * @param ds [i/o] down sampling buffer *  * @return the number of samples written to dst, or -1 on errror. * </EN> */intds48to16(SP16 *dst, SP16 *src, int srclen, int maxdstlen, DS_BUFFER *ds){  int i, n, tmplen;  if (ds->buflen == 0) {    ds->buflen = srclen * 2;		/* longer buffer required for 3/4 upsamling */    for(n=0;n<4;n++) {      ds->buf[n]  = (double *)mymalloc(sizeof(double) * ds->buflen);    }  } else if (ds->buflen < srclen * 2) {    ds->buflen = srclen * 2;    for(n=0;n<4;n++) {      ds->buf[n]  = (double *)myrealloc(ds->buf[n], sizeof(double) * ds->buflen);    }  }  for(i=0;i<srclen;i++) ds->buf[0][i] = src[i];  tmplen = srclen;  for(n=0;n<3;n++) {    tmplen = do_filter(ds->fir[n], ds->buf[n+1], ds->buf[n], tmplen, ds->buflen);  }  if (maxdstlen < tmplen) {    jlog("Error: ds48to16: down sampled num > required!\n");    return -1;  }  for(i=0;i<tmplen;i++) dst[i] = ds->buf[3][i];  return(tmplen);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?