Faust:自分好みのディストーションを作ってみた

ギターは弾かないんですけどディストーションはときどき使います。
綺麗すぎる音を派手に汚したり、古さや暖かさが欲しいときに軽くかけたり。

DAWを64bit環境にしたら今まで使っていたのが使えなくなってしまったんで、これも作ってみました。

ディストーションにはいろんな種類があるようですが、ぼくが作ったのはトランスのシミュレーションです。

+ degradeで高域特性
+ lossでヒステリシス損
+ clip部分で飽和 

を調整します。

ヒステリシスは、ちゃんとシミュレーションすると大変なことになりそうだったので、ちょっとだけ過去をひきずった感じで動けばよくね? 程度の実装です。

+ 入力を正負に分け
+ それぞれエンベロープフォロワにかけ
+ 再び合成 (エンベロープフォロワ内にabs()が入っているのでここでは減算)

みたいなことです。
いわゆるオーディオレートで使うため、エンベロープフォロワはかなり速く動かしてます。そこが普通とちょっと違うかな。

```js:Hystortion.dsp
declare name "Hystortion";
import("stdfaust.lib");
s_c = library("SQClip.dsp");

process = HystST : s_c.process  ;


HystST = HystMono( ds, ls ) , HystMono( ds, ls )
  with {
    ds = degradeSlider : /(100000.0) ;
    ls = lossSlider : /(100000.0) ;
  };
HystMono(degrade, loss) =
  _<: max(0), min(0)
  : an.amp_follower_ud( degrade, goodRel ) , an.amp_follower_ud( degrade, goodRel )
  : -
  with {
    goodRel = max( degrade, loss);
  };

hystGrp( x ) = vgroup("[00]Hyst", x );
ctrlGrp( x ) = hystGrp(hgroup("[0]", x ));
degradeSlider = ctrlGrp(vslider("[0]degrade[style:knob]", 10, 1, 20, 1));
lossSlider = ctrlGrp(vslider("[1]loss[style:knob]", 20, 1, 80, 1));
```
飽和部分は前に作ったやつのつかいまわしです。GUIだけ調整しました。

```js:SQClip.dsp
declare name "sqClip";

import("stdfaust.lib");

process = preGain : clipper : postGain  ;

preGain = preGainMono, preGainMono ;
preGainMono = *( preSlider : ba.db2linear )  ;

clipper = clipperMono(vuMeterL), clipperMono(vuMeterR) ;
clipperMono( m, x ) = clipGain( clipSlider, x) <: _, meter(m) : attach : *(x) ;
clipGain( s, x ) =  f0,f1,f2,f3 : ba.selectn(4,nx)
  with{
    w = s : ba.db2linear;
    c0 = abs(x) <= w ;
  	c1 = (abs(x) > w) & (abs(x) <= 1) ;
  	c2 = (abs(x) > 1) & (abs(x) <= 1/w) ;
  	c3 = abs(x) > 1/w ;
  	nx = ba.if(c0,0,0) : ba.if(c1,1) : ba.if(c2,2) : ba.if(c3,3);
    f0 = 1 ;
    f1 = abs(x)/(2 * (w^2 - 1)) + (w^2 - w - 1)/(w^2 - 1) + 1/abs(x) * w^2 / (2 * (w^2 - 1)) ;
    f2 = abs(x) * w^2 / (2 * (w^2 - 1)) - w / (w^2 - 1) + 1/abs(x) * (2 * w^2 - 1) / (2 * (w^2 - 1)) ;
    f3 = 1 / abs(x) ;
  };
meter(m) = _ : ba.linear2db : si.smoo : m ;
postGain = postGainMono, postGainMono ;
postGainMono = *( postSlider : ba.db2linear ) ;

clipGrp(x) = hgroup("[0]Clip", x ) ;
ctrlGrp(x) = clipGrp(hgroup("[0]Ctrl", x )) ;
meterGrp(x) = clipGrp(hgroup("[1]Meter", x )) ;
preSlider = ctrlGrp(vslider("[0]pre[unit:dB]", 0, 0, 20, 1 )) ;
clipSlider = ctrlGrp(vslider("[1]clip[unit:dB]", -1, -30, -1, 1 )) ;
postSlider = ctrlGrp(vslider("[2]post[unit:dB]", 0, -10, 10, 1 )) ;
vuMeterL = meterGrp(vbargraph( "[0]GR L[unit:dB]", -20, 1 ));
vuMeterR = meterGrp(vbargraph( "[1]GR R[unit:dB]", -20, 1 ));
```
この二つのファイルを同階層に置いてFaust LiveからVSTを作りました。
[Faust&JUCEによる超高速VST開発](https://qiita.com/tomoyanonymous/items/79b3e551984a707b5c9a)
Faust Liveからも同様にできます。
[とりあえずFaustを始めたい人のための4つの環境](https://matsuuratomoya.com/blog/2016-12-04/faust_start/)
右クリックして Export As...
<img src="https://qiita-image-store.s3.amazonaws.com/0/61597/efe35a34-12d2-8a56-6f91-fcea088be7cc.png" width=50%>
後は一緒です。

出来上がったVSTプラグイン。
<img src="https://qiita-image-store.s3.amazonaws.com/0/61597/1166e7d9-bc66-c8e0-846c-2f95eedbba81.png" width=50%>

音は...うん。歪んでる。ぼくの好きな感じです。
lossコントロールを新たに加えたのでバリエーションが広がったかな。
前使ってたのよりいいかも。使える。