今回実装を行っているPhaseShifter=Phaserは、PitchBendModeに組み込まれた「ピッチシフトを行うタイミングを制御するトリガー」と、「エンヴェロープの継続時間を決定し、それをWavetableの読み出し機構に反映するシステム」を応用したもので、

本来は、ピッチの揺らぎを認知するに足りる時間分の出力(200msから2sec位まで)が維持されるべきエンヴェロープを「極小値」(10ms以下)に設定した状態でピッチの変位⁄復帰を行うことで、Wavetableの読み出しポイントにオフセットを掛けて、メインの音程を追従するサブオシレータの位相をシフトするという、位相制御の方法としては邪道な方式を採用している。
位相の変化を反映するタイミング=RATEパラメータの調整は、ピッチシフトを行うトリガー、THAR2をコントロールすることで行っているのだが、、、

トリガーの生成は、GPT2がInputCptureにより入力信号のValueを決定するタイミングと同期させている。

オーディオクロックはGPTを定期的に監視する周期を決定しているに過ぎず、RATEパラメータのデータが確定するタイミングは、あくまで外部オシレータからの入力に準拠する。
RATEのValueはLPF2のLFOと共有していて、値の更新はTHAR2と同様にGPT2から出力されたトリガーを切っ掛けに行われる

THAR2が生成されるタイミングは、LFO専用のWavetableを読み出す12bit幅のアドレスのLSBから4bit目をbitWiseすることで決定しているが、これはデータを更新する切っ掛けを作るためのトリガーに過ぎない。

PitchShiftを行う値にはLFOの出力をそのまま転用しているので、選択された波形に準ずる形でPitchShiftの変化量が決定される。

LPFの波形には8種類のWavetableがリザーブされているが、これらの波形が持つキャラクターによって、位相がシフトしていくパターンが微妙に変化する。
一方、RATEはPitchを更新するタイミングを制御するパラメータに過ぎず、周期のスピードをコントロールするという一般的な概念のものではないところに注意が必要だ。
このシステムに於けるRATEは、極小値(スムーズ)から段階的(ステップ)に位相の変化量を決定するパラメータで、ステップ状に変化する位相からはSample&Hold的な効果が得られる。
追記:
LPFにDepthを追加した。 Modulationを掛けない状態でValueを設定するWavShpパラメータでオフセット値を設定する。

初期状態からノブを左回転させて値を加算する方法で、有効値に最も早くアクセスすることができる。
追記2:
システムの稼働開始後1時間で、PhaseShifterにロックアップが発生したが、位相のリセットを行うことよって動作が復活した。
かなり厳しいタイミングとギリギリなメモリのリソースで処理を行っている所為で、この手のロックアップが生じている可能性が高いのだが、トラブルの発生を防止するよりも「リセット機能を充実させる」方向に設計が進んでしまっている現状を今一度認識すべきだ。 予想されるトラブルの発生を事前に防止する方策として、操作系の迷路に迷い込まないようにプリセットを充実することを考えているのだが、そのうえで「困った時はリセット」それも段階を経たリセットのシステム(最後は電源の再投入)を組むことが現時点に考え得る最適解だろう。
追記3:
ブレッドボードに回路を組んでいる「バラック状態」が原因で発生する物理系のトラブルは、無視することができない不安要素だ。既にVolumeオシレータの信号の乱れによるトラブルの発生が確認されている。 これはPhaseShifterのロックアップが発生する原因とも考えられるので、トラブルを切り分けるための試験機を早急に完成させたいところだ。
追記4:
位相が変化する周期はPitch入力の周波数に依存しているのだが、音程に比例して増加する周期のスピードが速過ぎることが判明、PhaseShifterの構造を根本的に考え直す必要が出てきた。以下、暫定ではあるが、変更点を列挙していく。
まず、bitWiseを使った条件分岐を撤廃して、トリガーをシンプルな構造に改変しつつ、、、

PitchBendを行う際の初期値を2倍に調整し、、、

PitchBendを行うサブルーチン EG(); をAudioClockのタイミングで更新するように構造を変更した。
結果、周期の速さをある程度は修正することができたが、今度は低音域の周期が長くなり過ぎたきらいがある。
やはり、周期を一定に保つためには入力された周波数とPitchBendの初期値が逆比例するような構造を導入した方が良いのだが、最適値を割り出すにはしばらく時間が掛かりそうだ。
追記5:
とりあえず、入力周波数の影響を排除できるようにコードを書き換えた。

問題は除算で、Arduinoは小数点以下の計算が反映されない。 解決策として、整数で除算を行った後に小数点以下の乗算を実行することで、なんとか結果を代入することが出来た。

これらの作業によって入力周波数の軛から逃れられた訳だが、副産物としてSpeedのパラメータを実装することが可能になった。 パラメータを追加するには新たにロータリーエンコーダの割り振りを考えなければならないが、既にメモリの使用量が限界なのが、苦しいところだ。
追記6:
やはりシュワンシュワンさせたいPhaserには「Speedの設定が不可欠」ということで、機能を追加した。
スピードを設定するパラメータには、LFOの波形選択にリザーヴされたものを流用している。
posted by Yasuski at 08:07|
LaVoixski