Srempy

デジタルエフェクターというとディスプレイをつけたくなるもので、ポットなしでスイッチのみを使って操作するというエフェクターを製作しました。精度よく角穴加工するのはかなり大変なので、Tabby's工房さんにお願いしました。
▽ディスプレイ・スイッチ基板レイアウト

いつものようにチャタリング防止を行っています。OLEDディスプレイ・基板用押ボタンスイッチは秋月電子で購入しました。
DSP基板はOwm Pedalと同じものを使用しています。下写真のように合体させます。

ディスプレイの詳細は前回記事をご覧ください。スイッチ操作は割り込みではなくメインループで処理しています(GitHubはこちら)。エフェクトオフ時にはスイッチの反応が速くなりますが、実用上問題ないので特に対処していません。▲▼スイッチ長押しでフラッシュメモリにパラメータ保存できます。下記ページの内容を使わせていただきました。
・sora lab - STM + HAL Flashの書き込み・読み込み
エフェクトプログラムはもちろん変え放題ですが、今回私が考えたものを紹介したいと思います。※信号処理は旧処理方法(TxRxCpltCallback関数利用なし、16ビット)のままです。
アナログ回路でのフィルタ設計は複雑になる場合が多く、コンデンサの容量値も限られています。また、リアルタイムに動かすとなると可変抵抗やフォトカプラを使うぐらいしか選択肢がありません。デジタル信号処理でのフィルタについては計算方法が確立しているため、専門知識がなくとも設計可能で、任意の定数を動かすこともできます。計算式は下記ページのものを利用させていただきました。
・C++でVST作り - 簡単なデジタルフィルタの実装
フェイザーはノッチフィルタがかかったような周波数特性で、谷となる周波数が動いています(参考ページ→MXR Phase 90 Analysis)。今回はこの特性をピーキングフィルタを使って再現、発展させたエフェクトを考えました。フェイザーとワウを合わせたような効果で、5つのモード(STD、SOFT、INV、HIGH、LOW)があります。名前の由来は3つ(Three)のピーキングフィルタ(Peaking Filter)です。
<STD・SOFTモード>

SOFTモードでは、単純に谷となるフィルタを2つかけています。谷と谷の間は減衰し、スッキリとした感じとなります。STD(スタンダード)モードは、Phase 90の特性に近づけています。うねり感を得るためには、2つの谷の間に山が必要なようです。ちなみに2つの谷の間隔が広いとユニヴァイブのコーラスモードっぽい音になります。谷となる周波数の揺れ幅や高低は、出音への影響は少なかったです。
<INV・HIGH・LOWモード>

フィルタを谷ではなく山にした場合、山が1つだとオートワウのようになります。山を2つにすると、クセは強いもののフェイザーっぽいシュワシュワ感が現れます。INV(インバース)モードでは、2つの山の間にさらに谷を追加しています。HIGH/LOWモードは谷と山を混ぜており、通常のフェイザーの高音域/低音域が強調された感じとなります。
<計算高速化>
BiQuadフィルタの係数は三角関数の計算が入っていて、そのままでは処理に時間がかかり過ぎると思われます。そのため表計算ソフトで近似式を算出するなどして対応しています。それでも実際のCPU使用率は70%程度となってしまいましたので、計算高速化についてはもう少し検討していく予定です。
フェイザー(Pure Data パッチ)
Pure Data(Pd)でのオールパスフィルター(APF)は[rzero_rev~]と[rpole~]を組み合わせて作ります。原音とAPFを通した音を足せばフェイザーとなります。参考ページ→Making and using all-pass filters
(このパッチをダウンロード)
[rzero_rev~]と[rpole~]に入れる係数計算は、1次ローパスフィルターのときの[rpole~]用計算式をそのまま使うとうまくいきました。上側の[expr~]が2π*fc/fsの計算ですが、周波数はMXR Phase 90を参考に150~2250Hzで変化するようにしています。
Uni-Vibeもフェイザーと似た仕組みなので再現できそうなのですが、いまいち係数の設定がうまくいきませんでした。今後使いたくなったときに作るかもしれません。
【フィードバックについて】
Phase 90ではAPF最終段から2段目にフィードバックがかかっていますが、Pdで同じことをやろうとすると、「error: DSP loop detected」と出てしまいます。このエラーを回避するには、[send~][receive~]を使い1ブロックサイズ分遅延を発生させます。参考ページ→What's A "DSP-Loop"?
今回のフェイザーでは上記の方法だと出音がアナログの場合とは違うように感じたので、結局フィードバックは入れないことにしました。[block~]でブロックサイズを減らし遅延を少なくする方法もありますが、CPU負荷を考えると現実的ではないと思います。

[rzero_rev~]と[rpole~]に入れる係数計算は、1次ローパスフィルターのときの[rpole~]用計算式をそのまま使うとうまくいきました。上側の[expr~]が2π*fc/fsの計算ですが、周波数はMXR Phase 90を参考に150~2250Hzで変化するようにしています。
Uni-Vibeもフェイザーと似た仕組みなので再現できそうなのですが、いまいち係数の設定がうまくいきませんでした。今後使いたくなったときに作るかもしれません。
【フィードバックについて】
Phase 90ではAPF最終段から2段目にフィードバックがかかっていますが、Pdで同じことをやろうとすると、「error: DSP loop detected」と出てしまいます。このエラーを回避するには、[send~][receive~]を使い1ブロックサイズ分遅延を発生させます。参考ページ→What's A "DSP-Loop"?
今回のフェイザーでは上記の方法だと出音がアナログの場合とは違うように感じたので、結局フィードバックは入れないことにしました。[block~]でブロックサイズを減らし遅延を少なくする方法もありますが、CPU負荷を考えると現実的ではないと思います。
MXR PHASE45改

何だか最近作り直しが多かったんですが、思いつきでフェイズ45を作ってみました。松美庵さんのサイトのモディファイを加えようと思って試してみましたが、やっぱりシンプルなのが一番いいみたいで1ノブです。スイッチをつける場合高さを低くしなければいけないので、電解コンデンサを寝かせてみましたが結局スイッチはつけずじまいでした。
▽回路図
TONEPAD Phase 45 プロジェクトファイル ダウンロードページ
▽レイアウト

▽PCB(横55.9mm縦43.2mm)

ゲインを少し上げてレベル調整トリマを入れています。ポットは500kAしか手持ちがなくて逆に配線してRATEになってます。ポットの2番ピンにつながる抵抗は、4.1kΩぐらいから揺れが耳で聞き取れるぐらいになるみたいです。
FETはほぼ同じIdssのものを選別した効果なのか揺れに深みがある気がします。でもやはりさわやかな揺れで、もっとエグい方が面白いかなぁとも思います。8段のフェイザーを作ってみたいです。
塗装は青と白を適当に吹いてみました。わざと間近から吹き付けたので色が混ざっています。さすがにマーブルっぽくはなりませんでした。
(2016年11月9日PCB追加)