FAUST:フェイザーっぽいコーラス?コーラスっぽいフェイザー?を作ってみた

[フェイザーペダルとオールパスフィルタについての覚書](https://qiita.com/Aogiri-m2d/items/846746c7bf9bdd51ab57)を読んで[自分好みのフェイザーを作ってみた](https://qiita.com/ttatsf/items/c3a9123614e75649247d)続き。
良い気になってAPFの段数を増やしていったら、もう原音と別の音として聴こえてきて、「これってもうコーラスだよね」と思い、APFでコーラス(っぽいもの)を作ってみました。

ほぼ[フェイザー](https://qiita.com/ttatsf/items/c3a9123614e75649247d)と同じですが、APFの設定を散らして,おおむね中域3オクターブにわたって同じくらいの遅延になるようにしてみました。
選んだ中域がコーラスで、それより低域と高域はフェイザー、みたいな感じです。

低音のディレイがすくなめになるので、うまくやると普通のコーラスより自然な感じになるかな?
もちろん、過激で吐きそうなセッティングも可能です。

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

process = phorusMono( 0.0 ), phorusMono( phaseDiff ) ;

phorusMono(phaseDiff) = _
  <: _ , ( + : apfSeq) ~ *( 0 - nfb )
  : *(1 - wet), *(wet)
  :> _
    with{
      apfSeq = _, stage
        : seq( i, 12, bypassIfZero( APFDelayMono( F ) ) )
        : _, ! ;
      F = ba.midikey2hz( note ) ;
      note = centerNote + ampMod * os.oscp(modF, phaseDiff * ma.PI) ;
      centerNote = hz2midi( breakF ) ;
      ampMod = depth / 2.0 ;
    };

APFDelayMono( F ) = APF( F, 1.5 )
      			: APF( F * 2.828, 4.5 )
      			: APF( F * 5.0, 6.3 )
      			: APF( F * 6.4, 15 ) ;

bypassIfZero( func, x, stage ) =
  ( x : ba.bypass1( stage == 0, func ) ), max( 0, stage - 1 ) ;

hz2midi(f) = 12*ma.log2(f/440.0) + 69.0;

phorusGrp( x ) = hgroup("[0]Phorus", hgroup("[0]", hgroup("[0]", x ))) ;
stage     = phorusGrp( hslider("[0]Delay[style:knob]", 12, 5, 24, 1 ) ) ;
breakF    = phorusGrp( hslider("[2]Band[style:knob]", 250, 200, 2000, 0)) ;
modF      = phorusGrp( hslider("[3]Speed[style:knob][unit:Hz]", 1.0, 0.01, 5.0, 0.01)) ;
depth     = phorusGrp( hslider("[4]Depth[style:knob]", 4, 1, 12, 0.1)) ;
phaseDiff = phorusGrp( hslider("[5]Width[style:knob]", 0.5, -1.0, 1.0, 0.1)) ;
nfb       = phorusGrp( hslider("[6]FeedBack[style:knob]", 0.0, 0.0, 1.0, 0.01));
wet       = phorusGrp( hslider("[7]Wet[style:knob]", 0.5, 0.0, 0.5, 0.001) ) ;
```
これを 自作の[biquad filter用のライブラリ"RBJ.lib"](https://qiita.com/ttatsf/items/86d29b58b717b0d57a78)と同階層においてFaustLiveでJuce vstで書き出し、Xcodeでビルド。


![スクリーンショット 2018-02-16 20.39.59.png](https://qiita-image-store.s3.amazonaws.com/0/61597/dee202bc-d825-d07e-8cc3-310663a91e62.png "スクリーンショット 2018-02-16 20.39.59.png")

# 追記：使ってみて修正
ノブをグリグリしたときの感じがいまいちだったので、Bandノブを周波数リニアでなくMIDIノートに変えてみました。
こっちの方が断然合せやすく気持いい...

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

process = phorusMono( 0.0 ), phorusMono( phaseDiff ) ;

phorusMono(phaseDiff) = _
  <: _ , ( + : apfSeq) ~ *( 0 - nfb )
  : *(1 - wet), *(wet)
  :> _
    with{
      apfSeq = _, stage
        : seq( i, 12, bypassIfZero( APFDelayMono( F ) ) )
        : _, ! ;
      F = ba.midikey2hz( note ) ;
      note = centerNote + ampMod * os.oscp(modF, phaseDiff * ma.PI) ;
      // centerNote = hz2midi( breakF ) ;
      ampMod = depth / 2.0 ;
    };

APFDelayMono( F ) = APF( F, 1.5 )
      			: APF( F * 2.828, 4.5 )
      			: APF( F * 5.0, 6.3 )
      			: APF( F * 6.4, 15 ) ;
      				
bypassIfZero( func, x, stage ) =
  ( x : ba.bypass1( stage == 0, func ) ), max( 0, stage - 1 ) ;

// hz2midi(f) = 12*ma.log2(f/440.0) + 69.0;

phorusGrp( x ) = hgroup("[0]Phorus", hgroup("[0]", hgroup("[0]", x ))) ;
stage     = phorusGrp( hslider("[0]Delay[style:knob]", 12, 5, 24, 1 ) ) ;
// breakF    = phorusGrp( hslider("[2]Band[style:knob]", 250, 200, 2000, 0)) ;
centerNote= phorusGrp( hslider("[2]Band[style:knob]", 59.0, 44.0, 94.0, 0.0)) ;
modF      = phorusGrp( hslider("[3]Speed[style:knob][unit:Hz]", 1.0, 0.01, 5.0, 0.01)) ;
depth     = phorusGrp( hslider("[4]Depth[style:knob]", 4, 1, 12, 0.1)) ;
phaseDiff = phorusGrp( hslider("[5]Width[style:knob]", 0.5, -1.0, 1.0, 0.1)) ;
nfb       = phorusGrp( hslider("[6]FeedBack[style:knob]", 0.0, 0.0, 1.0, 0.01));
wet       = phorusGrp( hslider("[7]Wet[style:knob]", 0.5, 0.0, 0.5, 0.001) ) ;
```

いい気になってノブを上げすぎると発振して音が止まるようなので、安全圏を探って、Bandノブを94までに制限しました。