dsPIC33FJ64GP802 (11) --- DSP 命令と DSP ライブラリ (9)

 IIRCanonic() 関数と IIRTransposed() 関数を使ったプログラムの断片を下に示します。 フィルタ係数の配列の詳細は 2018 年 10 月 10 日付けの記事 (→こちら) に記載しています。
 WaveSpectra による特性測定のために使ったプログラムでは、ふたつの 1/12 オクターブバンド・フィルタの両方とも IIRTransposed() で実現していますが、以下に示すプログラムでは 880 Hz は IIRCanonic()、932.33 Hz は IIRTransposed() を使っています。

#include <xc.h>
#include <stdint.h>
#include <dsp.h>
. . . . . . <中略> . . . . . .
#define N_sample        (4)
#define N_sect          (3)
. . . . . . <中略> . . . . . .
// delay element in Y-DATA memory
// for IIRCanonic()
fractional _YBSS(2) d_880[2*N_sect];
// for IIRTransposed()
fractional _YBSS(2) d1_932[N_sect];
fractional _YBSS(2) d2_932[N_sect];
. . . . . . <中略> . . . . . .
// 1/12 octave band filter coeffs for IIRCanonic()
// center freq. = 880 Hz @ fs = 12 kHz
fractional _XDATA(2) IIRC_coef_880[] = {
// 内容は 2018 年 10 年 10 日付けの記事に記載
}; // fractional IIRC_coef_880[]]
// 1/12 octave band filter coeffs for IIRTransposed()
// center freq. = 932.328 Hz (A#) @ fs = 12 kHz
// exported from Filter component of PSoC Creator
fractional _XDATA(2) IIRT_coef_932[] = {
// 内容は 2018 年 10 年 10 日付けの記事に記載
}; // fractional IIRT_coef_932[]]
. . . . . . <中略> . . . . . .
IIRCanonicStruct    IIRC_prof_880;
IIRTransposedStruct IIRT_prof_932;
fractional src_data[N_sample];
fractional dstL_data[N_sample];
fractional dstR_data[N_sample];
. . . . . . <中略> . . . . . .
int main(int argc, char** argv)
{
. . . . . . <中略> . . . . . .
// initialize IIRCanonic profile for f0 = 880 Hz
  IIRC_prof_880.numSectionsLess1 = N_sect-1;
  IIRC_prof_880.coeffsBase  = &IIRC_coef_880[0];
  IIRC_prof_880.coeffsPage  = COEFFS_IN_DATA;
  IIRC_prof_880.delayBase   = &d_880[0];
// pick up scaling factors
  IIRC_prof_880.initialGain = IIRC_coef_880[5*N_sect];
  IIRC_prof_880.finalShift  = IIRC_coef_880[5*N_sect+1];
// initialize IIRTransposed profile for f0 = 932.33 Hz
  IIRT_prof_932.numSectionsLess1 = N_sect-1;
  IIRT_prof_932.coeffsBase = &IIRT_coef_932[0];
  IIRT_prof_932.coeffsPage = COEFFS_IN_DATA;
  IIRT_prof_932.delayBase1 = &d1_932[0];
  IIRT_prof_932.delayBase2 = &d2_932[0];
  IIRT_prof_932.finalShift = 0;
// zero-clear delay element  
  IIRCanonicInit(&IIRC_prof_880);
  IIRTransposedInit(&IIRT_prof_932);
. . . . . . <中略> . . . . . .
  while (1) { // infinite loop
. . . . . . <中略> . . . . . .
      IIRCanonic(N_sample,      // numSamps
                 &dstL_data[0], // output samples (L-ch)
                 &src_data[0],  // input samples (sweep sine)
                 &IIRC_prof_880 // filter profile (880 Hz)
                 );    
      IIRTransposed(N_sample,      // numSamps
                    &dstR_data[0], // output samples (R-ch)
                    &src_data[0],  // input samples (sweep sine)
                    &IIRT_prof_932 // filter profile (932 Hz)
                   );
. . . . . . <中略> . . . . . .
  } // while (1) {
} // int main()

 IIRCanonic() のスケーリング係数「initialGain」と「finalShift」の値はフィルタ係数の配列の末尾に格納しておき、IIRCanonicStruct 構造体の初期化の際に配列から拾い上げて対応するフィールドに設定しています。
 フィルタの入出力ベクトルのサイズ (N_sample) は 、内蔵ステレオ・オーディオ DACFIFO サイズ (4 ワード) に合わせて (N_sample = 4) と選んでいます。
 上のプログラムの断片では省略していますが、DACFIFO が「空」であることを確認すると、4 ワード分のデータを連続して書き込んでいます。