Julius 4.2
libsent/src/adin/ds48to16.c
説明を見る。
00001 
00019 /*
00020  * Copyright (c) 1991-2011 Kawahara Lab., Kyoto University
00021  * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology
00022  * Copyright (c) 2005-2011 Julius project team, Nagoya Institute of Technology, Nagoya Institute of Technology
00023  * All rights reserved
00024  */
00025 
00026 #include <sent/stddefs.h>
00027 #include <sent/adin.h>
00028 
00030 #define USE_HEADER_COEF
00031 
00033 
00034 #ifdef USE_HEADER_COEF
00035 
00036 #include "lpfcoef_3to4.h"
00037 #include "lpfcoef_2to1.h"
00038 #endif
00039 
00040 /* work area for down sampling */
00041 #define mod(x)  ((x) & (DS_RBSIZE -1)) ///< Buffer index cycler
00042 
00043 
00044 #ifdef USE_HEADER_COEF
00045 
00050 static void
00051 load_filter_from_header_2to1(DS_FILTER *f)
00052 {
00053   int i;
00054  
00055   /* read the filter coefficients from header file */
00056   for(i=0;i<DS_RBSIZE + 1; i++) {
00057     if (i >= lpfcoef_2to1_num) break;
00058     f->hdn[i] = lpfcoef_2to1[i];
00059   }
00060   f->hdn_len = i - 1;
00061 }
00062 
00068 static void
00069 load_filter_from_header_3to4(DS_FILTER *f)
00070 {
00071   int i;
00072  
00073   /* read the filter coefficients from header file */
00074   for(i=0;i<DS_RBSIZE + 1; i++) {
00075     if (i >= lpfcoef_3to4_num) break;
00076     f->hdn[i] = lpfcoef_3to4[i];
00077   }
00078   f->hdn_len = i - 1;
00079 }
00080 
00081 #else  /* ~USE_HEADER_COEF */
00082 
00089 static boolean
00090 load_filter(DS_FILTER *f, char *coeffile)
00091 {
00092   FILE *fp;
00093   static char buf[512];
00094   int i;
00095  
00096   /* read the filter coefficients */
00097   if ((fp = fopen(coeffile, "r")) == NULL) {
00098     jlog("Error: ds48to16: failed to open filter coefficient file \"%s\"\n", coeffile);
00099     return FALSE;
00100   }
00101   for(i=0;i<DS_RBSIZE + 1; i++) {
00102     if (fgets(buf, 512, fp) == NULL) break;
00103     f->hdn[i] = atof(buf);
00104   }
00105   fclose(fp);
00106   if (i <= 0) {
00107     jlog("Error: ds48to16: failed to read filter coefficient from \"%s\"\n", coeffile);
00108     return FALSE;
00109   }
00110   f->hdn_len = i - 1;
00111 
00112   return TRUE;
00113 }
00114 
00115 #endif
00116 
00124 static void
00125 init_filter(DS_FILTER *f, int d, int u)
00126 {
00127  
00128   f->decrate = d;
00129   f->intrate = u;
00130 
00131   /* set filter starting point */
00132   f->delay = f->hdn_len / (2 * f->decrate);
00133 
00134   /* reset index */
00135   f->indx = 0;
00136 
00137   /* reset pointer */
00138   f->bp = 0;
00139 
00140   /* reset output counter */
00141   f->count = 1;
00142 }
00143 
00151 static void
00152 firin(DS_FILTER *f, double in)
00153 {
00154   f->indx = mod(f->indx - 1);
00155   f->rb[f->indx] = in;
00156 }
00157 
00166 static double
00167 firout(DS_FILTER *f, int os)
00168 {
00169   double out;
00170   int k, l;
00171   
00172   out = 0.0;
00173   for(k = os, l = f->indx ; k <= f->hdn_len; k += f->intrate, l = mod(l + 1)) {
00174     out += f->rb[l] * f->hdn[k];
00175   }
00176   return(out);
00177 }
00178 
00191 static int
00192 do_filter(DS_FILTER *f, double *dst, double *src, int len, int maxlen)
00193 {
00194   int dstlen;
00195   int s;
00196   int d;
00197   int i, k;
00198 
00199   s = 0;
00200   dstlen = 0;
00201 
00202   while(1) {
00203     /* fulfill temporal buffer */
00204     /* at this point, x[0..bp-1] may contain the left samples of last call */
00205     while (f->bp < DS_BUFSIZE) {
00206       if (s >= len) break;
00207       f->x[f->bp++] = src[s++];
00208     }
00209     if (f->bp < DS_BUFSIZE) {   
00210       /* when reached last of sample, leave the rest in x[] and exit */
00211       break;
00212     }
00213     /* do conversion from x[0..bp-1] to y[] */
00214     d = 0;
00215     for(k=0;k<f->bp;k++) {
00216       firin(f, f->x[k]);
00217       for(i=0;i<f->intrate;i++) {
00218         f->count--;
00219         if(f->count == 0) {
00220           f->y[d++] = firout(f, i);
00221           f->count = f->decrate;
00222         }
00223       }
00224     }
00225     /* store the result to dst[] */
00226     if(f->delay) {
00227       if(d > f->delay) {
00228         /* input samples > delay, store the overed samples and enter no-delay state */
00229         d -= f->delay;
00230         for(i=0;i<d;i++) {
00231           if (dstlen >= maxlen) break;
00232           dst[dstlen++] = f->y[f->delay + i];
00233         }
00234         f->delay = 0;
00235         if (dstlen >= maxlen) {
00236           jlog("Error: ds48to16: buffer overflow in down sampling, inputs may be lost!\n");
00237           return -1;
00238         }
00239       } else {
00240         /* input samples < delay, decrease delay and wait */
00241         f->delay -= d;
00242       }
00243     } else {
00244       /* no-delay state: store immediately */
00245       for(i=0;i<d;i++) {
00246         if (dstlen >= maxlen) break;
00247         dst[dstlen++] = f->y[i];
00248       }
00249       if (dstlen >= maxlen) {
00250         jlog("Error: ds48to16: buffer overflow in down sampling, inputs may be lost!\n");
00251         return -1;
00252       }
00253     }
00254 
00255     /* reset pointer */
00256     f->bp -= DS_BUFSIZE;
00257   }
00258 
00259   return dstlen;
00260 }
00261 
00262 
00268 DS_BUFFER *
00269 ds48to16_new()
00270 {
00271   DS_BUFFER *ds;
00272   int i;
00273   /* define 3 filters: 
00274      48kHz --f1(3/4)-> 64kHz --f2(1/2)-> 32kHz --f3(1/2)-> 16kHz */
00275   
00276   ds = (DS_BUFFER *)mymalloc(sizeof(DS_BUFFER));
00277   for(i=0;i<3;i++) ds->fir[i] = (DS_FILTER *)mymalloc(sizeof(DS_FILTER));
00278 #ifdef USE_HEADER_COEF
00279   /* set from embedded header */
00280   load_filter_from_header_3to4(ds->fir[0]);
00281   load_filter_from_header_2to1(ds->fir[1]);
00282   load_filter_from_header_2to1(ds->fir[2]);
00283   jlog("Stat: ds48to16: loaded FIR filters for down sampling\n");
00284 #else
00285   /* read from file */
00286   if (load_filter(ds->fir[0], "lpfcoef.3to4") == FALSE) return FALSE;
00287   if (load_filter(ds->fir[1], "lpfcoef.2to1") == FALSE) return FALSE;
00288   if (load_filter(ds->fir[2], "lpfcoef.2to1") == FALSE) return FALSE;
00289   jlog("Stat: ds48to16: initialize FIR filters for down sampling\n");
00290 #endif
00291   init_filter(ds->fir[0], 3, 4);
00292   init_filter(ds->fir[1], 2, 1);
00293   init_filter(ds->fir[2], 2, 1);
00294 
00295   ds->buflen = 0;
00296 
00297   return(ds);
00298 }
00299 
00306 void
00307 ds48to16_free(DS_BUFFER *ds)
00308 {
00309   int i;
00310 
00311   if (ds->buflen != 0) {
00312     for(i=0;i<4;i++) free(ds->buf[i]);
00313   }
00314   for(i=0;i<3;i++) free(ds->fir[i]);
00315   
00316   free(ds);
00317 }
00318 
00331 int
00332 ds48to16(SP16 *dst, SP16 *src, int srclen, int maxdstlen, DS_BUFFER *ds)
00333 {
00334   int i, n, tmplen;
00335 
00336   if (ds->buflen == 0) {
00337     ds->buflen = srclen * 2;            /* longer buffer required for 3/4 upsamling */
00338     for(n=0;n<4;n++) {
00339       ds->buf[n]  = (double *)mymalloc(sizeof(double) * ds->buflen);
00340     }
00341   } else if (ds->buflen < srclen * 2) {
00342     ds->buflen = srclen * 2;
00343     for(n=0;n<4;n++) {
00344       ds->buf[n]  = (double *)myrealloc(ds->buf[n], sizeof(double) * ds->buflen);
00345     }
00346   }
00347 
00348   for(i=0;i<srclen;i++) ds->buf[0][i] = src[i];
00349 
00350   tmplen = srclen;
00351   for(n=0;n<3;n++) {
00352     tmplen = do_filter(ds->fir[n], ds->buf[n+1], ds->buf[n], tmplen, ds->buflen);
00353   }
00354 
00355   if (maxdstlen < tmplen) {
00356     jlog("Error: ds48to16: down sampled num > required!\n");
00357     return -1;
00358   }
00359   for(i=0;i<tmplen;i++) dst[i] = ds->buf[3][i];
00360 
00361   return(tmplen);
00362 }