
オシレータの合成出力からデモジュレートされた入力信号(周波数帯域は数百Hz台)のアップエッジ間を計数したデータに次の更新が行われるまでの間、その数値は「ロック」されることになる。
このロック(数値の固定)によって生じる影響は階段状の不連続な計測値の「段差」の発生で、周期性を持ったそれは入力されたアナログオシレータの周波数が反映されてしまう。

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

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

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

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

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

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

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

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

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

結果として、極低音域で発生していた妙なバタつきが抑えられたのだが、機能の実装後に何故かChromaticModeが起動しない謎のバグに悩まされた。 バグの発生はメモリの整理を行うことで回避することが出来たが、そろそろ空きメモリに余裕がなくなってきたことが動作不良が発生した原因なのかもしれない。
追記: LCDをドライヴする周期を決定すると、出音にフリッカが発生することが判明したので、描画のタイミングをフリーランに戻すことにした。

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


どうしても補正しきれないケースが発生してしまうが、そこは用法でカヴァーするしか手段はない。
EMAを調整する方法もあるが、その場合には当然ながらレスポンスとのトレードオフが発生する。