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 + -
显示快捷键?