2020年01月28日

フィルター選択機構の条件分岐をifからswitchに変更する

ifを使って複数の条件に分岐を掛ける場合、参照先のソースを全てチェックする分だけ不要な時間が消費される。 例えるなら、1番最初に設けた条件に合致した後も、2番目以降に設定した条件のチェックを行うことになり、その分だけ計算機のリソースが空費されてしまう。

switchは、入力された整数を参照してcase毎に分岐させて処理を行う機能で、breakを行うことでプログラムの下流に配置された無駄な参照と評価をスキップすることができる。

ただし、これを使う場合には事前に対象となるソースを加工してパラメーターをハンドリングが可能な規模の整数に刻んでおく必要がある。 

改修を行う前に、まずはcase判定用のレジスタをリザーブする。

Screen Shot 2020-01-26 at 19.24.32.png

入力するソースを除算してその結果からレベルを判定し、分岐先でディテクターアウトの変化に掛けるウエイトを選択する。

Screen Shot 2020-01-26 at 20.53.34.png

ifに比べてプログラムがより判り易い構造になった。

Screen Shot 2020-01-26 at 20.52.44.png

何れの場合もデータを16段階に分類している。

Screen Shot 2020-01-26 at 20.53.10.png

レベルの判定を等間隔で行う場合は以上の手法で問題はないのだが、不等間隔でポイントを設定したい場合は、ifによる条件分岐が必須となる。 今回は多項式の表現を用いて視認性をより向上させている。

Screen Shot 2020-01-27 at 10.26.43.png

最近のコンパイラは賢いのでifからswitchに記述を変えても余り差はないという話があって、場合によっては速度が低下することもあるらしい。 

体感上は若干の向上が見られているのだが、これも気分の問題である可能性は否定出来ない。 判り易い判定法としては、廃止したディテクターのstepを比較してアウトプットの同期を切替える機構を復活させ、それにswitchを組み込めばハッキリするので、後ほどこれを試してみる予定。

追記1:

switch投入後のベンチマークとして、一部のモードで動作不良が発覚して廃止に至った「参照step切り替え機構」を復活させてみたが、以前に見られた5和音以上の発音で一部のEnvelopeに遅延が出る不具合が完全に解消されていた。 今回の改訂版では条件分岐を行うルーティンを2箇所追加した分だけタスクが増大している筈だったので、これは予想外の健闘と言えるだろう。

Screen Shot 2020-01-28 at 8.03.00.png

RAMの消費が以前より抑えられているようだが、これは合理的なリソース配分が行われたことを意味している。

よって、改変の御利益はアリと判定する。

追記2:

試験運用の結果、ピッチの中間域という微妙なエリアでバウンシングが発生しだしたため、プログラムのヴァージョンを元に戻すことになった。 出来ればLEDマーカーを仕込んで境界域の挙動を徹底的に調査すべきなのだろうが、とりあえずは現状で不満の少ないヴァージョンを選択することにした。
posted by Yasuski at 02:08| LaVoixski

2020年01月25日

TransitionMode下で発生するエンヴェロープの遅延に対処する

5Voice/PresetTuneModeでTransitionModeの特定の波形プリセットを選択した場合に、オシレーター2のエンヴェロープが遅延する謎現象が再発している。 いまのところ解決策は発見できておらず、問題が発生する発音パターンのプリセットを回避する対症療法を行うしかなさそうだ。

Screen Shot 2020-01-25 at 7.36.04.png

トラブルの発生はMCUの処理能力をオーヴァーした結果なので、これからシステムのダイエットを行っていくことになるのだが、まずは正攻法としてトラブルが発生する発音パターンを把握して原因を解析した後に、発音数を減らす方向で調整を行ってみたが、効果は全く無かった。

システムダイエットの過程で、コンパイラ頼りで適当なデータ型に記述していた箇所、例えば16bitでデータをハンドリングしているところにFloatを突っ込んでいたりするのがマズそうなので、データをキャストして辻褄を合わせることにした。

まず、取り扱うデータ幅を拡張するために、受け側のデータ幅を32bitに設定し直す。 

Screen Shot 2020-01-25 at 7.34.51.png

Pitchデータは16bitでハンドリングしているので、Floatを乗算した後に

Screen Shot 2020-01-25 at 7.35.19.png

データ型のキャストを掛けている。

あと、ステップ数でディテクタの結果を補完するタイミングを切り替える機構を廃止して、

Screen Shot 2020-01-25 at 7.36.21.png

Screen Shot 2020-01-25 at 7.36.36.png

Screen Shot 2020-01-25 at 7.37.29.png

Screen Shot 2020-01-25 at 7.37.49.png

代わりに元データを16bit幅で丸めていた各Transitionの制御信号を32bit精度に変更し、結果をbitshiftする方式にVolumeコントローラーの構造を変更している。

Screen Shot 2020-01-25 at 7.37.01.png

改変のリザルトはマアマアで、グリッチは相変わらず発生するもののエンベロープの遅延を無くすことができた。

削除したステップ数による切り替え機構は有効なので、Teensy4ではこれを復活させることになるだろう。


posted by Yasuski at 22:28| LaVoixski

2020年01月20日

ディテクタの改良

Pitch/Volumeデータが確定するタイミングを、FTMキャプチャ出力が更新されるサイクルの比較とadd_value(wavetableのポインタ)に設定した閾値で切替える機能を追加した。 

Screen Shot 2020-01-20 at 1.47.43.png

更新サイクルが長くなった方のタイミングで処理が行われ、補完のステップにはそれに準拠した値が設定される。

Screen Shot 2020-01-20 at 1.48.02.png

以前行った実験で、Pitch側のタイミングでデータを更確定させると高域でノイズが発生する現象を確認していたが、add_valueに閾値を設定しなかった場合に同じ症状が発現した。 

Screen Shot 2020-01-20 at 1.48.30.png

切替機能の実装後、低域で発生するグリッチが減少した一方で一定の周波数におけるバウンシングの発生を確認している。

オシレーターを物理的にリチューンするとバウンスが消滅することが判明しているが、原因がデジタル側のチューニングシステム内に潜んでいる可能性は否定できない。

現在は暫定でadd_valueの閾値を1000に設定しているが、これは低い方に修正を行うことになりそうだ。

そろそろLocalVariableに割振るRAMの容量が怪しくなってきたので、Wavetableを削除してRAMの余裕を増やしたが、

Screen Shot 2020-01-20 at 0.01.11.png

Screen Shot 2020-01-19 at 17.06.32.png

重タスク環境下でフリーズが発生することが判明、オプティマイザをSmallestCodeからSmallestCodeWithLTOに変更する必要が生じている。

その後、オシレーターのリチューンを行う過程で、ディテクタが参照するオシレーターの素の発振周波数の下限値がバウンシングの発生要因となっている可能性が示唆された。 低い方に周波数を拡張した場合にバウンシングが発生することから、入力信号のアップエッジのタイミングで瞬間値のキャプチャを行うリングカウンタが「一巡する周期」との関連性が疑われるが、その前にハードウエアの個体差から生じる物理的な影響を確認しなければならない。
posted by Yasuski at 06:55| LaVoixski

2020年01月14日

The waveforms around the lower frequency area

出力波形をキャプチャして、低域で発生するグリッチの観測を行った。



Lchのバイアスポイントが変動しているが、これは回路構成によるもの。

Screen Shot 2020-01-13 at 9.48.40.png

ほぼDCな出力周波数で、左手を動かした場合に発生するグリッチの波形。

Screen Shot 2020-01-13 at 8.14.57.png

マイナス側に振れたグリッチの波形を観察する。

Screen Shot 2020-01-13 at 8.15.17.png

波形を拡大していくと、ノイズに対して補完が行われているように見える。

Screen Shot 2020-01-13 at 8.17.05.png

より高速で波形をキャプチャできるオシロスコープでグリッチを観測する。やはり信号に乗っているノイズ成分に対して補完が行われているように見える。

Screen Shot 2020-01-14 at 14.34.26.png

ディテクタとして使用しているD-FFの電源回路に挿入した"L"が回路に影響を及ぼしている可能性があるため、

WS002072.JPG

これらを取り除いた結果、ノイズの軽減を確認できた。 ただし、完全なノイズの排除には至っていない。

WS002073.JPG

今回も Transition Mode を記録しているが、オシレーターを乗り換えるレスポンスを速い方にチューンするとグリッチが増えて仕舞う仕様故、帯域分割したウエイトの設定は実用性との折衷を行うことになる。



ディテクタのオプティマイズを更に進めた出力波形。



低域での安定性を高めるためにStep数の多い方のディテクタを選択して、データ出力の同期を行っているが、これも完全ではない。
posted by Yasuski at 10:12| LaVoixski

2020年01月12日

Hammond/1455K1601専用サイズの基板が届いた

新しい基盤にFPGAを実装し、

IMG_9738.JPG

ファームウエアを書き込んだ。

WS002071.JPG

基板の配置に関してはある程度のマージンが確保されているのだが、ケース上に展開するインターフェイス系部品の配置を優先して基板のセンターを出した場合、ギリに設定しているオーディオ基板とMCU基板のクリアランスが心配になってくる。 厚み方向のクリアランスは現物合わせとなるので、ケースの加工は基板が完成した状態で行うのが安全だろう。

ここ連日、周波数ディテクタのチェックというか最適化を試行錯誤しているのだが、一定の周波数帯域に妙なバウンシングが発生する現象に悩まされている。 バウンシングはオシレーターが冷えた状態で発生する兆しがあるが、家電製品からの電源経由もしくは放射による高周波の影響も看過できない。 電波暗室の必要を感じるレベルというのは大袈裟でもなんでもなく、放射系のノイズに関してはどこもかしこもが劣悪な状態にあると聞く。 廃棄処分のホットカーペットでシールドを作ることも考えているのだが、日本家屋は肝心のアースが甘いのでその効果は限定的になりそうだ。
posted by Yasuski at 15:43| LaVoixski

Pitch側データ出力の更新と線形補間をVolume側がデータを更新するタイミングと同期させる

左手のレスポンスを改善するために、Pitchディテクタのサブルーチン内に展開していたVolume関連の処理をPitchディテクタ関連の処理と共にVolumeディテクタのサブルーチン内に移し替えた。

Screen Shot 2020-01-12 at 5.27.40.png

これでVolume側のデータが更新されるタイミングにPitchデータの更新が同期されることになったが、右手側の追従性に問題は無さそうだ。

Screen Shot 2020-01-12 at 5.28.20.png

グリッチが若干増えているが、速いパッセージの演奏に耐えうるレベルまでレスポンスを改善することが出来た。

左手のレスポンスとグリッチの抑制はトレードオフの関係にあり、現時点で自分が持つスキルでは折衷を行うのが精一杯だが、この「折衷」のポイントには厳密な解がなく個人的な趣向が反映される。
posted by Yasuski at 04:25| LaVoixski

2020年01月10日

Pitch/Volumeの同期を行う

Volume側データ出力の更新と線形補間をPitch側がデータを更新するタイミングと同期させる案を試してみた。

Screen Shot 2020-01-10 at 18.31.41.png

結果は、左手のポジションションに合わせてグリッチの周波数が変化しなくなった一方で「均一にノイズが発生する」現象が発生、しかもこれがPitchの全帯域に影響することが判明した。

Pitchデータの更新が行われるタイミングでVolumeデータに発生する不連続性が固定された結果がノイズとして認識された訳だが、用法で逃げることが難しい上に全帯域に渡ってノイズが目立ってしまうのは本末転倒で、実験はアイデア倒れに終わった。 

ただし、ノイズが「均質化」したのは朗報でもあり、この手法を完全に放棄するのは拙速な判断かもしれない。

Screen Shot 2020-01-10 at 18.33.44.png

なんとかノイズの発生を抑え込む方法はないかとフィルターの数値をいろいろと試してみる過程で、出音に発生するリングモジュレーターのような変調が気になりだした。

ビートが発生する原因は、デモジュレートされたPitch/Volume信号のアップエッジ間を計測するカウンタが「バラバラなタイミング」でデータをキャプチャした際に発生するデータの周期的な不連続ポイントの影響と思われる。 この問題を解消するために考えたのがPitch側のサブルーチン内に確定したVolume側のデータをキャプチャする方法だったが、肝心のVolumeディテクタ側の設定が定まらず、実装は棚上げとなっていた。

今回はVolumeデータを生成するサブルーチンから「丸め処理が行われたデータ」を拾う代わりに、Volume側がキャプチャした素のデータを

Screen Shot 2020-01-10 at 18.34.48.png

Pitch側のデータが確定するタイミングで取り込み、Pitchデータの処理を行うサブルーチン内でVolume側の丸め処理を実行する構造に処理プロセスを変更した。

Screen Shot 2020-01-10 at 18.33.13.png

結果は満足が出来るもので、妙なビートの発生がなくなったうえにグリッチの発生を低減させることに成功した。
posted by Yasuski at 18:29| LaVoixski

2020年01月03日

FrequencyDetectorの再構成を行う

今日は半日周波数ディテクタの調整を行っていたのだが、最終的には以下に示す構成に落ち着いている。

Screen Shot 2020-01-03 at 21.09.57.png

LEDによる有効領域の表示は大凡ではあるが設定したダイナミックレンジに準じるものとなった。

Screen Shot 2020-01-03 at 21.10.14.png

分周率は 1/8 に設定した。 これ以下の分周率ではディテクターの挙動が不安定になることが実験で判明している。

Screen Shot 2020-01-03 at 21.10.47.png

オフセット値は試行錯誤の結果、8191 とした。 12bitのデータ幅を底上げして、見掛け上13bitのデータを扱うことで、アンテナの有感域(物理)を調整している。 

高い方のリミット値は現行 "15" に設定しているが、これは暫定値で再考の余地がある。 

試行錯誤の過程では、より高精度なコントロールを行うことを目指し、FTMの分周率を操作してディテクタのダイナミックレンジを広げる事に腐心していたのだが、、、

Screen Shot 2020-01-03 at 15.38.54.png

ディテクタのスイートスポットがピーキーになり過ぎて、調整が酷く難しい代物となってしまった。

Screen Shot 2020-01-03 at 15.39.10.png

可動域を調整するために対症療法でビットシフトを行って、帯域を制限したものの、、、

Screen Shot 2020-01-04 at 6.29.47.png

1) 速いパッセージに左手の動きが追い付けない 
2) Transitionの感覚が不自然になり乗換えのスムーズさが失われた 
3) スイートスポット化した稼動域の影響で、調整の難易度が上がる 
4) LFOの効きが極端に悪くなった

と結果は散々だった。

諸々の不具合が確認される一方で「グリッチが軽減する」という大きなメリットが存在したのものの、如何せん左手の動きに対するレスポンスが悪過ぎたうえ、Transitionのスムーズな運用が出来ない設定の採用は最終的に論外と判断することとなった。

そういえば、EtherwaveのVolume側の回路構成はBPFによってオシレータからの出力値を積分する設計だったが、左右のディテクタの構成がかなり違ったものになるのは当然の帰結なのだろう。
posted by Yasuski at 23:09| LaVoixski