(略)
typedef int32_t Q28; // 小数部28ビットの符号付き固定小数点数
typedef int16_t Q14; // 小数部14ビットの符号付き固定小数点数
#define ONE_Q28 ((Q28) (1 << 28)) // Q28型の1.0
#define ONE_Q14 ((Q14) (1 << 14)) // Q14型の1.0
#define PI      ((float) M_PI)    // float型の円周率
(略)
//////// オシレータ //////////////////////////////
static uint32_t Osc_freq_table[8] = {   // 周波数テーブル
  261.6F * (1LL << 32) / FS,
  293.7F * (1LL << 32) / FS,
  329.6F * (1LL << 32) / FS,
  349.2F * (1LL << 32) / FS,
  392.0F * (1LL << 32) / FS,
  440.0F * (1LL << 32) / FS,
  493.9F * (1LL << 32) / FS,
  523.3F * (1LL << 32) / FS };
static Q28 Osc_wave_tables[8][512];     // 波形テーブル群
(略)
static void Osc_init() {
(略)
    uint32_t harm_max = // 最大倍音次数
      (23000.0F * (1LL << 32) / FS)
                          / Osc_freq_table[pitch];
(略)
      Osc_wave_tables[pitch][i] = float2fix(sum,
                                            28);
(略)
}
static inline Q28 Osc_process() {
  static uint32_t phase = 0; // 位相
  phase += Osc_freq_table[Osc_pitch];

  Q28* wave_table = Osc_wave_tables[Osc_pitch];
  uint32_t curr_index = phase >> 23;
  uint32_t next_index = (curr_index + 1) &
                                       0x000001FF;
  Q28 curr_sample = wave_table[curr_index];
  Q28 next_sample = wave_table[next_index];
  uint32_t next_weight = phase & 0x007FFFFF;
  uint32_t curr_weight = 0x00800000 - next_weight;
  return (((int64_t) curr_sample * curr_weight) +
     ((int64_t) next_sample * next_weight)) >> 23;
}
//////// フィルタ ////////////////////////////////
struct F_COEFS { Q28 b0_a0, b1_a0, b2_a0,
                            a1_a0, a2_a0; };
(略)
static void Fil_init() {
(略)
      Fil_table[res][cut].b0_a0 =
                           float2fix(b0 / a0, 28);
      Fil_table[res][cut].b1_a0 =
                           float2fix(b1 / a0, 28);
      Fil_table[res][cut].b2_a0 =
                           float2fix(b2 / a0, 28);
      Fil_table[res][cut].a1_a0 =
                           float2fix(a1 / a0, 28);
      Fil_table[res][cut].a2_a0 =
                           float2fix(a2 / a0, 28);
(略)
}
static inline Q28 Fil_process(Q28 x0) {
(略)
  static Q28 x1 = 0, x2 = 0, y1 = 0, y2 = 0;
  Q28 y0 = (((int64_t) coefs->b0_a0 * x0)
          + ((int64_t) coefs->b1_a0 * x1)
          + ((int64_t) coefs->b2_a0 * x2)
          - ((int64_t) coefs->a1_a0 * y1)
          - ((int64_t) coefs->a2_a0 * y2)) >> 28;
  x2 = x1; y2 = y1; x1 = x0; y1 = y0;
  return y0;
}
//////// アンプ //////////////////////////////////
(略)
static inline Q28 Amp_process(Q28 in) {
  static Q28 curr_gain = 0;            // ゲイン現在値
  Q28        targ_gain = Amp_on << 28; // ゲイン目標値
  curr_gain = targ_gain -
    (Q28) (((int64_t) (targ_gain - curr_gain) * 255)
                                               / 256);

  return ((int64_t) in * curr_gain) >> 28;
}
//////// PWMオーディオ出力部 /////////////////////
(略)
static inline void PWMA_process(Q28 in) {
  int32_t level_int32 = (in >> 18) + (PWMA_CYCLE / 2);
(略)
}
(略)
