⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 _csl_reszcalccoef.c

📁 TI达芬奇dm644x各硬件模块测试代码
💻 C
字号:
/** @file _csl_reszCalcCoef.c
 *
 *  @brief    File for functional layer of CSL API @a CSL_reszCalcCoef()
 *
 *  Description
 *    - The @a CSL_reszCalcCoef() function definition & it's associated
 *      functions
 *
 *  @date 10th May, 2005
 *  @author Jesse Villarreal (code borrowed from Ching-Yu).
 */

#include <csl_resz_aux.h>

#pragma CODE_SECTION (CSL_reszCalcCoef, ".text:csl_section:resz");

//#include <stdio.h>
#include <stdlib.h>
#include <math.h>

/* coefficients per direction = 
                  8 phases x 4 taps (or 4 phases x 8 taps - only 7 are used) */
#define  NUM_PHASES 8
#define  NUM_TAPS   4
#define  NUM_D2PH   4  /* for downsampling 2+x ~ 4x, number of phases */
#define  NUM_D2TAPS 7  /* for downsampling 2+x ~ 4x, number of taps */
#define  NUM_COEFS (NUM_PHASES * NUM_TAPS) 
                       /* Note that NUM_D2PH*NUM_D2TAPS must <= NUM_COEFS */

/* filter bit depth = 10-bit = sign + 1.8 */ 
#define  FIR_RND_ADD 128
#define  FIR_RND_SHIFT 8
#define  FIR_RND_SCALE 256

#define BLACKMAN_WINDOW 1

//	rsz_calc_coef_sample(res, &vcoef[0]);

/** @brief Calculates the appropriate filter coefficients
 *	
 */
CSL_Status  CSL_reszCalcCoef(
    /** Resize value 
	 */
    short									  rsz,
    /** Array of coefficients
	 */
    short									 *coef_arr
	){

  int   i, j;
  int   u, d, m, ntaps;
  int   nphases, w;
  float win, t, c;
  float interlv_coef[NUM_COEFS+1];
  float deinterlv_coef[NUM_COEFS+1];
  float acc;
  float pi;
  float scale;
  int   ofst_per_phase;
  int   max_idx, max_coef;
  long  acc_long;

  pi = atan(1.0) * 4.0;

  /* window length = W = 32 or 28 (8 phases x 4 taps or 4 phases x 7 taps)*/
  /* first generate triangular window = i or (W - i), only i=1..W-1 nonzero */
  /* then generate filter coefficients and multiply with window */
  /* M = max(u,d), 
     coef(t) = sin(pi*t/M) / (pi*t/M), 3 lobes, zero at t=-2M, -M, M, 2M,

     upsampling: M=u, interlv_coef[i] = coef((i-16)*u/8), i=0..32,
                                      = sin(pi*(i-16)/8) / (pi*(i-16)/8) 
     downsampling 4-tap: M=d, coef sampled at u/8,
                      interlv_coef[i] = coef((i-16)*u/8), i=0..32,
                                 = sin(pi*(i-16)*u/(8*d))/(pi*(i-16)*u/(8*d))
     downsampling 7-tap: M=d, coef sampled at u/4,
                      interlv_coef[i] = coef((i-14)*u/4), i=0..28,
                                 = sin(pi*(i-14)*u/(4*d))/(pi*(i-14)*u/(4*d))
  */

  u = 256;  d = rsz;
  m = (u > d) ? u : d;
  ntaps = (rsz > 512) ? NUM_D2TAPS : NUM_TAPS;  /* < 1/2x -> 7-tap */
  nphases = (rsz > 512) ? NUM_D2PH : NUM_PHASES; 
  ofst_per_phase = (rsz > 512) ? NUM_TAPS*2 : NUM_TAPS; /* 4 or 8, never 7 */
  w = nphases * ntaps;

  for (i=0; i<=w; i++) { /* note that we need one extra here */

#if BLACKMAN_WINDOW 
    win = 0.42 - 0.5*cos(2*pi*i/w) + 0.08*cos(4*pi*i/w);
#else
    win = (i < w/2) ? i : (w-i);
#endif

    t = ((float) i - w/2) * u / nphases;
    interlv_coef[i] = (i == w/2) ? win : win * (sin(pi*t/m) / (pi*t/m));
  }

  for (j=0; j<NUM_COEFS; j++)   
    coef_arr[j] = 0;          /* prefill 0 so that 7-tap mode gets 8th tap=0 */

  /* de-interleave into phases (diagram is for 8-phase 4-tap case) */
  /* phase_to_use = input_ptr % nphases, must agree in calc_coef and in resizer
      (X = input points, o = possible output points, V = current output point)
                X-o-o-o-o-o-o-o-X-o-o-o-o-o-o-o-X-o-o-o-o-o-o-o-X-o-o-o-o ...
     inp_ptr    ^                               V
     intlv_coef 0 c c c c c c c c c c c c c c c c c c c c c c c c c c c c ...
     idx coef at inputs         8              16              24    (phase 0)

     inp_ptr      ^                               V
     intlv_coef   0 c c c c c c c c c c c c c c c c c c c c c c c c c c c ...
     idx coef at inputs         7              15              23    (phase 1)  
     ...

     inp_ptr                  ^                               V
     intlv_coef               0 c c c c c c c c c c c c c c c c c c c c c ...
     idx coef at inputs         1               9              17    (phase 7)       
  */

  for (j=0; j<nphases; j++)   /* j=phase */
    for (i=0; i<ntaps; i++)   /* i=tap */
      deinterlv_coef[ofst_per_phase*j + i] = 
          interlv_coef[nphases*i + nphases - j];

  /* normalize for each phase */
  for (j=0; j<nphases; j++) {  /* j=phase */
    acc = 0.0;
    for (i=0; i<ntaps; i++) /* i=tap */
      acc += deinterlv_coef[ofst_per_phase*j + i];
    scale = 1.0 / acc;  /* normalize sum of weights to 1.0 */
    for (i=0; i<ntaps; i++) /* taps */
      coef_arr[ofst_per_phase*j + i] = 
          (short) (deinterlv_coef[ofst_per_phase*j + i] * FIR_RND_SCALE 
                   * scale + 0.5);
  }

  /* sum up each phase and adjust largest coef to comprehend rounding errors 
     in previous pass */
  for (j=0; j<nphases; j++) {  /* j=phase */
    acc_long = 0;
    max_coef = 0;
    max_idx = 0;
    for (i=0; i<ntaps; i++) { /* taps */
      acc_long += coef_arr[ofst_per_phase*j + i];
      if (coef_arr[ofst_per_phase*j + i] > max_coef) {
        max_coef = coef_arr[ofst_per_phase*j + i];
        max_idx = ofst_per_phase*j + i;
      }
    }
    acc_long = FIR_RND_SCALE - acc_long;
    coef_arr[max_idx] += acc_long;
  }

  return (CSL_SOK);
}

⌨️ 快捷键说明

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