2019/11/10

sox equalizer

目的


soxのequalizerのヘルプに書かれている [q|o|h|k] の意味がわからないので、調べてみます。
$ sox --help-effect equalizer
sox:      SoX v14.4.2

Effect usage:

equalizer frequency width[q|o|h|k] gain
幅の単位であることは読み取れます。

調査に使ったコード


調査には https://git.code.sf.net/p/sox/code を利用しました。 コミットのハッシュ値は 2f6b3fec2dddfbb869a9f7de3110c9aaa31517c9 (Date: Wed Aug 1 23:45:59 2018 -0400) でした。

結果


hはHz、qはHzの逆数に操作する周波数を掛けた値であることがわかりました。また、oはオクターブっぽく、kはよくわからないこともわかりました。

記載箇所


equalizerは src/biquads.c に記述されています。

オプションの解析部分を追っていくと、

q = width_Q
o = width_bw_oct
h = width_bw_Hz
k = width_bw_kHz
であることがわかります。

このファイル内に、これらを使っている箇所があります。

static int start(sox_effect_t * effp)
{
  ...
  if (p->width) switch (p->width_type) {
    case width_slope:
      alpha = sin(w0)/2 * sqrt((A + 1/A)*(1/p->width - 1) + 2);
      break;

    case width_Q:
      alpha = sin(w0)/(2*p->width);
      break;

    case width_bw_oct:
      alpha = sin(w0)*sinh(log(2.)/2 * p->width * w0/sin(w0));
      break;

    case width_bw_Hz:
      alpha = sin(w0)/(2*p->fc/p->width);
      break;

    case width_bw_kHz: assert(0); /* Shouldn't get here */

    case width_bw_old:
      alpha = tan(M_PI * p->width / effp->in_signal.rate);
      break;
  }
  ...
width_Qはwidth_bw_Hzとは逆に動いているので、qを大きくすると幅が狭くなるようです。

width_bw_kHzについては、assert(0)では止まらないので、はwidth_bw_old扱いになるようです。 全然kHzではありませんね。

参考までに、pの型はbiquad_tで、定義は、src/biquad.h より、

typedef struct {
  double gain;             /* For EQ filters */
  double fc;               /* Centre/corner/cutoff frequency */
  double width;            /* Filter width; interpreted as per width_type */
  width_t width_type;

  filter_t filter_type;

  double b0, b1, b2;       /* Filter coefficients */
  double a0, a1, a2;       /* Filter coefficients */

  sox_sample_t i1, i2;     /* Filter memory */
  double      o1, o2;      /* Filter memory */
} biquad_t;
です。