2022年12月30日

LaVoixski@InputCaptureのデータ補完システムを導入する

WaveTable を読み出すタイミングを決定する”サンプリング・クロック = LRCK”と、フリーランするGPTの状態を外部からのトリガで記録する InputCapture により発動されるインターラプトは、当然ながら非同期の関係にあり、、、

Screen Shot 2022-09-14 at 7.03.32.png

オシレータの合成出力からデモジュレートされた入力信号(周波数帯域は数百Hz台)のアップエッジ間を計数したデータに次の更新が行われるまでの間、その数値は「ロック」されることになる。 

このロック(数値の固定)によって生じる影響は階段状の不連続な計測値の「段差」の発生で、周期性を持ったそれは入力されたアナログオシレータの周波数が反映されてしまう。 

Screen Shot 2020-01-14 at 14.34.26.png

この段差がスプリアス状の信号となって音声出力に影響を及ぼしているのだが、

Screen Shot 2020-03-06 at 4.33.54.png

今回行った試みは「段差の隙間」を埋める機構を追加する手法で、InputCaptureのトリガが発生する間隔をサンプリング・クロックのタイミングで計数し、そのステップ数を費やしてデータに発生した差分の解消を行う仕掛けだ。

Screen Shot 2023-01-10 at 2.58.52.png

まず、InputCaptureのデータが更新される間隔を、サンプリング・クロックによって駆動される AttatchInterrupt のタイミングで計数する。

Screen Shot 2022-12-31 at 4.19.46.png

データに発生した差分は、既に計数したStep数に分割され、サンプリング・クロックのタイミングで次の更新値まで加算される。

Screen Shot 2022-12-31 at 4.07.35.png

Pitch側のサブルーチンにジャンプするタイミングで、更新に掛かった時間を計数した結果をレジスタに取り込みつつ、カウンタをリセットする。

Screen Shot 2022-12-30 at 2.26.31.png

事前に10サイクル分の平均値を取った後、記録した1サイクル前のデータとの差分を比較して、1 step 当たりに加減を行う数値を割出す。

Screen Shot 2022-12-30 at 2.27.10.png

Volume側もPitch側と同様に、Volumeデータを取り扱うサブルーチンにジャンプしたタイミングで、更新に掛かった時間を計数した結果をレジスタに取り込み、カウンタをリセットする。

Screen Shot 2022-12-31 at 4.08.13.png

こちらも10サイクル分のデータから平均値を割り出した後に、1サイクル前のデータとの差分を比較して、1 step 当たりに加減を行う数値を割出す。 

Screen Shot 2022-12-31 at 4.08.48.png

ここでは、Transition に関するエンヴェロープ・データの更新を行っている。

Screen Shot 2022-12-31 at 4.08.57.png

結果として、極低音域で発生していた妙なバタつきが抑えられたのだが、機能の実装後に何故かChromaticModeが起動しない謎のバグに悩まされた。 バグの発生はメモリの整理を行うことで回避することが出来たが、そろそろ空きメモリに余裕がなくなってきたことが動作不良が発生した原因なのかもしれない。

追記: LCDをドライヴする周期を決定すると、出音にフリッカが発生することが判明したので、描画のタイミングをフリーランに戻すことにした。

Screen Shot 2022-12-31 at 4.09.41.png

追記2:

Volume側のValueが1000を超える辺りで発生する変化量は急峻で

Screen Shot 2022-07-13 at 3.54.41.png

Screen Shot 2022-07-26 at 16.35.30.png

どうしても補正しきれないケースが発生してしまうが、そこは用法でカヴァーするしか手段はない。 

EMAを調整する方法もあるが、その場合には当然ながらレスポンスとのトレードオフが発生する。
posted by Yasuski at 03:12| LaVoixski