[BACK]Return to dsp.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / sndiod

Diff for /src/usr.bin/sndiod/dsp.c between version 1.18 and 1.19

version 1.18, 2021/07/05 08:29:59 version 1.19, 2024/04/22 11:01:02
Line 269 
Line 269 
 }  }
   
 /*  /*
  * resample the given number of frames   * Return the number of input and output frame that would be consumed
    * by resamp_do(p, *icnt, *ocnt).
  */   */
 void  void
 resamp_do(struct resamp *p, adata_t *in, adata_t *out, int todo)  resamp_getcnt(struct resamp *p, int *icnt, int *ocnt)
 {  {
           long long idiff, odiff;
           int cdiff;
   
           cdiff = p->oblksz - p->diff;
           idiff = (long long)*icnt * p->oblksz;
           odiff = (long long)*ocnt * p->iblksz;
           if (odiff - idiff >= cdiff)
                   *ocnt = (idiff + cdiff + p->iblksz - 1) / p->iblksz;
           else
                   *icnt = (odiff + p->diff) / p->oblksz;
   }
   
   /*
    * Resample the given number of frames. The number of output frames
    * must match the corresponding number of input frames. Either always
    * use icnt and ocnt such that:
    *
    *       icnt * oblksz = ocnt * iblksz
    *
    * or use resamp_getcnt() to calculate the proper numbers.
    */
   void
   resamp_do(struct resamp *p, adata_t *in, adata_t *out, int icnt, int ocnt)
   {
         unsigned int nch;          unsigned int nch;
         adata_t *idata;          adata_t *idata;
         unsigned int oblksz;          unsigned int oblksz;
           unsigned int ifr;
         int s, ds, diff;          int s, ds, diff;
         adata_t *odata;          adata_t *odata;
         unsigned int iblksz;          unsigned int iblksz;
           unsigned int ofr;
         unsigned int c;          unsigned int c;
         int64_t f[NCHAN_MAX];          int64_t f[NCHAN_MAX];
         adata_t *ctxbuf, *ctx;          adata_t *ctxbuf, *ctx;
         unsigned int ctx_start;          unsigned int ctx_start;
         int q, qi, qf, n;          int q, qi, qf, n;
   
 #ifdef DEBUG  
         if (todo % p->iblksz != 0) {  
                 log_puts("resamp_do: partial blocks not supported\n");  
                 panic();  
         }  
 #endif  
   
         /*          /*
          * Partially copy structures into local variables, to avoid           * Partially copy structures into local variables, to avoid
          * unnecessary indirections; this also allows the compiler to           * unnecessary indirections; this also allows the compiler to
Line 300 
Line 320 
          */           */
         idata = in;          idata = in;
         odata = out;          odata = out;
         diff = p->oblksz;          diff = p->diff;
         iblksz = p->iblksz;          iblksz = p->iblksz;
         oblksz = p->oblksz;          oblksz = p->oblksz;
         ctxbuf = p->ctx;          ctxbuf = p->ctx;
         ctx_start = p->ctx_start;          ctx_start = p->ctx_start;
         nch = p->nch;          nch = p->nch;
           ifr = icnt;
           ofr = ocnt;
   
           /*
            * Start conversion.
            */
   #ifdef DEBUG
           if (log_level >= 4) {
                   log_puts("resamp: copying ");
                   log_puti(ifr);
                   log_puts(" -> ");
                   log_putu(ofr);
                   log_puts(" frames, diff = ");
                   log_puti(diff);
                   log_puts("\n");
           }
   #endif
         for (;;) {          for (;;) {
                 if (diff >= oblksz) {                  if (diff >= oblksz) {
                         if (todo == 0)                          if (ifr == 0)
                                 break;                                  break;
                         ctx_start = (ctx_start - 1) & (RESAMP_NCTX - 1);                          ctx_start = (ctx_start - 1) & (RESAMP_NCTX - 1);
                         ctx = ctxbuf + ctx_start;                          ctx = ctxbuf + ctx_start;
Line 318 
Line 354 
                                 ctx += RESAMP_NCTX;                                  ctx += RESAMP_NCTX;
                         }                          }
                         diff -= oblksz;                          diff -= oblksz;
                         todo--;                          ifr--;
                 } else {                  } else {
                           if (ofr == 0)
                                   break;
   
                         for (c = 0; c < nch; c++)                          for (c = 0; c < nch; c++)
                                 f[c] = 0;                                  f[c] = 0;
Line 361 
Line 399 
 #endif  #endif
                                 *odata++ = s;                                  *odata++ = s;
                         }                          }
   
                         diff += iblksz;                          diff += iblksz;
                           ofr--;
                 }                  }
         }          }
           p->diff = diff;
         p->ctx_start = ctx_start;          p->ctx_start = ctx_start;
   #ifdef DEBUG
           if (ifr != 0) {
                   log_puts("resamp_do: ");
                   log_puti(ifr);
                   log_puts(": too many input frames\n");
                   panic();
           }
           if (ofr != 0) {
                   log_puts("resamp_do: ");
                   log_puti(ofr);
                   log_puts(": too many output frames\n");
                   panic();
           }
   #endif
 }  }
   
   static unsigned int
   uint_gcd(unsigned int a, unsigned int b)
   {
           unsigned int r;
   
           while (b > 0) {
                   r = a % b;
                   a = b;
                   b = r;
           }
           return a;
   }
   
 /*  /*
  * initialize resampler with ibufsz/obufsz factor and "nch" channels   * initialize resampler with ibufsz/obufsz factor and "nch" channels
  */   */
Line 375 
Line 442 
 resamp_init(struct resamp *p, unsigned int iblksz,  resamp_init(struct resamp *p, unsigned int iblksz,
     unsigned int oblksz, int nch)      unsigned int oblksz, int nch)
 {  {
           unsigned int g;
   
           /*
            * reduce iblksz/oblksz fraction
            */
           g = uint_gcd(iblksz, oblksz);
           iblksz /= g;
           oblksz /= g;
   
           /*
            * ensure weird rates don't cause integer overflow
            */
           while (iblksz > ADATA_UNIT || oblksz > ADATA_UNIT) {
                   iblksz >>= 1;
                   oblksz >>= 1;
           }
   
         p->iblksz = iblksz;          p->iblksz = iblksz;
         p->oblksz = oblksz;          p->oblksz = oblksz;
           p->diff = 0;
         p->nch = nch;          p->nch = nch;
         p->ctx_start = 0;          p->ctx_start = 0;
         memset(p->ctx, 0, sizeof(p->ctx));          memset(p->ctx, 0, sizeof(p->ctx));

Legend:
Removed from v.1.18  
changed lines
  Added in v.1.19