Faust:色付けのないLPF,HPFを作ってみた


Faustで自分が使い易いプラグインを作って、DAWで使ってます。
簡単に作れるし、音も使い勝手も思い通りになるので、ごきげんな感じです。

ここんとこ結構いろものを作ったんで、地味なフィルター類を作ってみました。
次数の切り替えられるバターワースとリンクウィッツ-ライリーのフィルターです。
レゾナンスがつかず切れ味すっきり。ミックスの時にはむしろこっちのほうがよく使います。
特にHPF。

つくりはどれもほとんど同じです。

```C:HPFBW.dsp
declare name "HPFBW";
import("stdfaust.lib");

process = HPFBWMono( order, fs ), HPFBWMono( order, fs );
HPFBWMono( order, fs ) = _
                      <: par( i, 4, fi.highpass( i+1, fs) )
                      : ba.selectn( 4, order-1 ) ;
fs = ba.midikey2hz( note ) : attachSmooM( freqMeter ) ;
order = slope / 6 ;

attachSmooM( m) = _ <: _, (si.smoo : m ) : attach ;

filterGrp( x ) = vgroup("[0]HPFBW", vgroup("[0]",( vgroup("[0]", x ))));
slope     = filterGrp(hslider("[1]Slope[unit:dB]", 12, 6, 24, 6 ));
note      = filterGrp(hslider("[2]note", 69.0 ,15.0, 136.0, 0.0));
freqMeter = filterGrp(hbargraph("[3]Freq[unit:Hz]", 20, 20000 ) ) ;
```

```C:LPFBW.dsp
declare name "LPFBW";
import("stdfaust.lib");

process = LPFBWMono( order, fs ), LPFBWMono( order, fs );
LPFBWMono( order, fs ) = _
                      <: par( i, 4, fi.lowpass( i+1, fs) )
                      : ba.selectn( 4, order-1 ) ;
fs = ba.midikey2hz( note ) : attachSmooM( freqMeter ) ;
order = slope / 6 ;

attachSmooM( m) = _ <: _, (si.smoo : m ) : attach ;

filterGrp( x ) = vgroup("[0]LPFBW", vgroup("[0]",( vgroup("[0]", x ))));
slope     = filterGrp(hslider("[1]Slope[unit:dB]", 12, 6, 24, 6 ));
note      = filterGrp(hslider("[2]note", 69.0 ,15.0, 136.0, 0.0));
freqMeter = filterGrp(hbargraph("[3]Freq[unit:Hz]", 20, 20000 ) ) ;
```

```C:HPFLR.dsp
declare name "HPFLR";
import("stdfaust.lib");

process = HPFLRMono( order, fs ), HPFLRMono( order, fs );
HPFLRMono( order, fs ) = _
                      <: par( i, 2, seq( j, 2, fi.highpass( i+1, fs ) ) )
                      : ba.selectn( 2, order-1 ) ;
fs = ba.midikey2hz( note ) : attachSmooM( freqMeter ) ;
order = slope / 12 ;

attachSmooM( m) = _ <: _, (si.smoo : m ) : attach ;

filterGrp( x ) = vgroup("[0]HPFLR", vgroup("[0]",( vgroup("[0]", x ))));
slope     = filterGrp(hslider("[1]Slope[unit:dB]", 12, 12, 24, 12 ));
note      = filterGrp(hslider("[2]note", 69.0 ,15.0, 136.0, 0.0));
freqMeter = filterGrp(hbargraph("[3]Freq[unit:Hz]", 20, 20000 ) ) ;
```

```C:LPFLR.dsp
declare name "LPFLR";
import("stdfaust.lib");

process = LPFLRMono( order, fs ), LPFLRMono( order, fs );
LPFLRMono( order, fs ) = _
                      <: par( i, 2, seq( j, 2, fi.lowpass( i+1, fs ) ) )
                      : ba.selectn( 2, order-1 ) ;
fs = ba.midikey2hz( note ) : attachSmooM( freqMeter ) ;
order = slope / 12 ;

attachSmooM( m) = _ <: _, (si.smoo : m ) : attach ;

filterGrp( x ) = vgroup("[0]LPFLR", vgroup("[0]",( vgroup("[0]", x ))));
slope     = filterGrp(hslider("[1]Slope[unit:dB]", 12, 12, 24, 12 ));
note      = filterGrp(hslider("[2]note", 69.0 ,15.0, 136.0, 0.0));
freqMeter = filterGrp(hbargraph("[3]Freq[unit:Hz]", 20, 20000 ) ) ;
```

FaustLiveでJuce vstで書き出し、Xcodeでビルドしました。

![スクリーンショット 2018-02-21 14.56.05.png](https://qiita-image-store.s3.amazonaws.com/0/61597/b7a0dd81-41db-8434-0b80-cbebb67a2ba0.png "スクリーンショット 2018-02-21 14.56.05.png")

どれも良い感じでキレてます。スライダーの感じもなかなか良い。
## はまったところ
fi.lowpass(),fi.highpass()は次数が変えられるんだけど、コンパイル時には決ってないといけないみたいです。動的なままだと通らなかった。

あと、周波数リニアでなくオクターブスケールのスライダーがあったらいいな。
## 追記：同じところを括りだしてみた
とりあえずコピペで四つ作ってみたんですが、同じだなあと思い、同じところを .lib にまとめてみました。

```C:filterWithOrder.lib
import("stdfaust.lib");

orderSelectedFilter( filterWithOrder, maxOrder, order, fs ) = _
                      <: par( i, maxOrder, filterWithOrder( i+1, fs ) )
                      : ba.selectn( maxOrder, order-1 ) ;

doubledFilter( filterWithOrder, order, fs ) =
      seq( j, 2, filterWithOrder( order, fs ) ) ;
```
orderSelectedFilter()のイメージ。4次の場合。
![スクリーンショット 2018-02-22 12.52.23.png](https://qiita-image-store.s3.amazonaws.com/0/61597/6c619e33-b38c-8659-43c9-c1566869bda2.png "スクリーンショット 2018-02-22 12.52.23.png")
次数を動的には変えられないので、1次から4次まで全部たちあげてselectn()で選ぶ、という作戦です。

doubledFilter()のイメージ。
![スクリーンショット 2018-02-22 12.52.34.png](https://qiita-image-store.s3.amazonaws.com/0/61597/47226d75-6c6a-e1d5-cd2c-48c64280fb20.png "スクリーンショット 2018-02-22 12.52.34.png")
同じものを二つ直列。引数で次数と周波数を渡せるようにしてます。
バターワースフィルターからリンクウィッツ-ライリーフィルターを作るとき使います。

それぞれこんな感じになりました。


```C:HPFBW.dsp
declare name "HPFBW";
import("stdfaust.lib");
import("filterWithOrder.lib");

process = par( i, 2, orderSelectedFilter( filterWithOrder, maxOrder, order, fs))
  with{
    maxOrder = 4 ;
    filterWithOrder = fi.highpass ;
    fs = ba.midikey2hz( note ) : attachSmooM( freqMeter ) ;
    order = slope / 6 ;
  };

attachSmooM( m) = _ <: _, (si.smoo : m ) : attach ;

filterGrp( x ) = vgroup("[0]HPFBW", vgroup("[0]",( vgroup("[0]", x ))));
slope     = filterGrp(hslider("[1]Slope[unit:dB]", 12, 6, 24, 6 ));
note      = filterGrp(hslider("[2]note", 69.0 ,15.0, 136.0, 0.0));
freqMeter = filterGrp(hbargraph("[3]Freq[unit:Hz]", 20, 20000 ) ) ;
```

```C:LPFBW.dsp
declare name "LPFBW";
import("stdfaust.lib");
import("filterWithOrder.lib");

process = par( i, 2, orderSelectedFilter( filterWithOrder, maxOrder, order, fs))
  with{
    maxOrder = 4 ;
    filterWithOrder = fi.lowpass ;
    fs = ba.midikey2hz( note ) : attachSmooM( freqMeter ) ;
    order = slope / 6 ;
  };

attachSmooM( m) = _ <: _, (si.smoo : m ) : attach ;

filterGrp( x ) = vgroup("[0]LPFBW", vgroup("[0]",( vgroup("[0]", x ))));
slope     = filterGrp(hslider("[1]Slope[unit:dB]", 12, 6, 24, 6 ));
note      = filterGrp(hslider("[2]note", 69.0 ,15.0, 136.0, 0.0));
freqMeter = filterGrp(hbargraph("[3]Freq[unit:Hz]", 20, 20000 ) ) ;
```



```C:HPFLR.dsp
declare name "HPFLR";
import("stdfaust.lib");
import("filterWithOrder.lib");

process = par( i, 2, orderSelectedFilter( filterWithOrder, maxOrder, order, fs))
  with{
    maxOrder = 2 ;
    filterWithOrder = doubledFilter( fi.highpass );
    fs = ba.midikey2hz( note ) : attachSmooM( freqMeter ) ;
    order = slope / 12;
  };

attachSmooM( m) = _ <: _, (si.smoo : m ) : attach ;

filterGrp( x ) = vgroup("[0]HPFLR", vgroup("[0]",( vgroup("[0]", x ))));
slope     = filterGrp(hslider("[1]Slope[unit:dB]", 12, 12, 24, 12 ));
note      = filterGrp(hslider("[2]note", 69.0 ,15.0, 136.0, 0.0));
freqMeter = filterGrp(hbargraph("[3]Freq[unit:Hz]", 20, 20000 ) ) ;
```


```C:LPFLR.dsp
declare name "LPFLR";
import("stdfaust.lib");
import("filterWithOrder.lib");

process = par( i, 2, orderSelectedFilter( filterWithOrder, maxOrder, order, fs))
  with{
    maxOrder = 2 ;
    filterWithOrder = doubledFilter( fi.lowpass );
    fs = ba.midikey2hz( note ) : attachSmooM( freqMeter ) ;
    order = slope / 12;
  };

attachSmooM( m) = _ <: _, (si.smoo : m ) : attach ;

filterGrp( x ) = vgroup("[0]LPFLR", vgroup("[0]",( vgroup("[0]", x ))));
slope     = filterGrp(hslider("[1]Slope[unit:dB]", 12, 12, 24, 12 ));
note      = filterGrp(hslider("[2]note", 69.0 ,15.0, 136.0, 0.0));
freqMeter = filterGrp(hbargraph("[3]Freq[unit:Hz]", 20, 20000 ) ) ;
```


わーいみんな同じになったー。読みやすいかはまた別。
次数を動的に変えたい何かを作るとき参考になるかも。