2019年01月17日

CHnIEの設定について

昨日からCortex-M4/K66系列のアプリケーション・ノートを読んでいるのだが、何処を探してもその機能が明示されていない項目があって困り果てている。 

昔と違って今は検索ワードで探せるので、無いものは無い。 CHnIEというインターラプト関連のレジスタがどういった場合に起動するのか、もしくは何処で設定するのかの詳細が、何処を探しても明示されていないのがなんとも不可解。

The channel (n) interrupt is generated when (CHnIE = 1) and (CHnF = 1).

と書かれてはいるものの、フラグが立つ理由はCHnFしか明示されておらず、CHnIEは多分フラグをイネーブルにする端子。確かに、カウンタの概念図にはCHnFCHnIEが入力に記されたAND記号が書かれている。

おそらくは、カウンターのオーヴァーフローを示すTOIEが絡んでいるのだろうけど、それも明示されていない。 実際、TOIE

The timer overflow interrupt is generated when (TOIE = 1) and (TOF = 1).


とあるように完全に別項目で扱われている。

TOIEに関しては、FTMx_SC field descriptionsField 6 にレジスタのアドレスが明示されていて、

Timer Overflow Interrupt Enable. 
Enables TPM overflow interrupts. 


と解説があるのに、CHnIEには設定を行うためのレジスタが存在しないようだ。

これはいくらなんでも不自然なので、試しに CHIE で検索を行ったところ、FTMx_CnSC field descriptions の中に項目を発見した。

ちなみに、FTMx_SC field では、オーバーフローフラグを作動させない設定にしていたので、インターラプトの発生にカウンタのオーバーフローは関与しない。

一方、チャンネルイベントの発生は、CHnF のフラグによって発生することから、フィルターに設定した分だけイベントのタイミングが遅延される仕組みということになる。 

現状ではフィルターの設定は 0xFF なので、15クロック分の遅延が生じていることになるが、一度これをFVCのdebounceの設定値のみを活かす"0"に変更して、挙動を確かめると良いだろう。 ちなみに、debounceの1カウントに要する時間は32kHz=31.25uSなので、FTM_FILTERによる遅延とは桁が違う。
posted by Yasuski at 09:19| LaVoixski

2019年01月16日

FVCの構造について

LaVoixskiで採用しているFVC(Frequency-To-Value Converter)は、OpenTheremin.Unoのコードを参考にCortexM4/K-66シリーズに搭載されているFTM(Flexible Timer)に合わせて最適化を行っている。

処理の流れを説明すると、、、

まず、基本事項として、

1)FTMはアップカウントで円環するフリーラン状態に設定。
2)カウンターのスケールは16bit。
3)FTM_FILTERで設定したタイミングで入力信号のアップエッジ間を計測し、キャプチャしたカウンタの値を専用レジスタ FTM0_CnV に記録した後、debounceカウンターのリセットを行う。

WS001583.JPG

4)入力ポートは FTM0_0FTM0_1 の2つを指定。

一方、FVCの処理は以下のステップで実行される

WS001582.JPG

1)入力信号の状態が"H”の間、オーディオクロックの立ち上がるタイミングでPitch/Volumeのデータを取り扱うdebounce用カウンタのカウントをインクリメントする。
2)debounceカウンタのカウント3で、FTMカウンタのレジスタからPitch/Volumeデータを取り込み、前のタームで記録したバッファーから参照したデータとの差分を計算、結果を出力レジスタに格納した後、新しいデータをPitch/Volumeバッファーレジスタに格納する。
3)debounceカウンタのカウント5で、Pitch/Volumeのハンドリング開始フラグを立てる。
4)以降、CHイベントが発生してdebounceカウンタがクリアされるまでは、待機状態に。

単純にFTMカウンタの値を使用せず、奇数回のdebounceカウント(1カウントに要する時間は32kHz=31.25uS)のタイミングでFTMカウンタの差分を拾うことで、実質的にカウンタのレンジが拡張されているのだが、直感的に何が起こっているのか判別できないために、動作の最適化はかなり困難な作業になっている。

追記:

後で気付いたことではあるが、オリジナルのコードはFTM_FILTERに準ずる機能が存在しないハードウエアを前提に設計された仕組であり、現状はdebounceとFTM_FILTERによって二重にフィルターを掛けていることになる。この辺のチューンを考え直すことで動作の改善を目指せるかもしれない。
posted by Yasuski at 08:41| LaVoixski

2019年01月14日

FTMの制御について

そろそろFTMの制御方法に関する記憶が揮発してきたので、ここで今一度おさらいをしておく。

FTMとはFlexible Timerの略で、NXP/Freescale系のCortexM4に搭載されている機能。 

ちなみに、導入を検討しているSTMicro系CortexM4のマニュアルを確認したところTimerの仕様は同一ではなく、周波数の検知法は別途考え直す必要がある。

FTMに話を戻す。 FTMの運用はPWM信号の生成を含む各種モードを選択できるが、周波数検知回路として使用できるのはInputCaptureModeDualEdgeCaptureModeの2つで、現行型のプログラムではこのうち用法が簡単なInputCaptureModeを選択している。

まず、FTMのモード設定を、Features Mode Selection (FTMx_MODE) レジスタで行う。

以下にレジスタの詳細を記す: 

FAULTIE=0, FAULTM=00, CAPTEST=0, PWMSYNC=0, WPDIS=1, INIT=0, FTMEN=1

レジスタの書き込みプロテクトを外して WPDIS=1 、FTMを活動状態 FTMEN=1 に設定する。

FTM0_MODE = 0x05;     // WPDIS = 1(writeprotection)/FTMEN = 1(Flexble Timer Enable) 

入力のバタ付きによる誤動作を軽減するために、Input Capture Filter Control (FTMx_FILTER)レジスタでフィルターの設定を行う。 

フィルターは入力ch0からch3までチャンネル別に設定が可能。 今回はch0/1を使用するので、レジスタの設定は

FTM0_FILTER = 0xnn;  // 0で機能をキャンセル、1〜Fが設定値。

となる。

フィルターの計算式は、4+4×val clock cycles(n)で、 システムクロックが48MHz/フィルターの値が"F"の場合、トリガーのエッジから排除される最小単位は、4+4*16 = 68 clock cycles = 1.41666us に設定される。 これより速い入力信号の変化は受け付けられない。

カウンタのレジスタは以下のように設定している。

FTM0_SC = 0x00; // Set zero
FTM0_CNT = 0x0000; // Reset the count to zero
FTM0_MOD = 0xFFFF; // max modulus = 65535


ディバイダの設定は

FTM0_SC = 0x09; // TOF=0 TOIE=1 CPWMS=0 CLKS=01 PS=001 (divide by 2)
// FTM0_SC = 0x0A; // TOF=0 TOIE=0 CPWMS=0 CLKS=01 PS=010 (divide by 4)
// FTM0_SC = 0x0B; // TOF=0 TOIE=0 CPWMS=0 CLKS=01 PS=011 (divide by 8)
// FTM0_SC = 0x0C; // TOF=0 TOIE=0 CPWMS=0 CLKS=01 PS=100 (divide by 16)
// FTM0_SC = 0x0D; // TOF=0 TOIE=0 CPWMS=0 CLKS=01 PS=110 (divide by 32)


1/2分周としているが、最適値はディテクターの設計によって変化する。

カウンタの初期値を"0"に設定し、

FTM0_CNTIN = 0;

入力チャンネルのステイタス・コントロールで

FTM0_C0SC = 0x48; // CHF=0 CHIE=1 MSB=0 MSA=0 ELSB=1 ELSA=0 rsv=0 DMA=0
FTM0_C1SC = 0x48; // CHF=0 CHIE=1 MSB=0 MSA=0 ELSB=1 ELSA=0 rsv=0 DMA=0


信号のアップエッジでカウントを行うモードを選択。

FTMに関係する入力端子の対応表から、端子の機能を選択するレジスタでFTM0に対応する端子#22/#23をALT4に設定する。

CORE_PIN22_CONFIG = PORT_PCR_MUX(4); //set the ALT4 pin mode
CORE_PIN23_CONFIG = PORT_PCR_MUX(4);


Screen Shot 2019-01-09 at 18.06.20.png

ステイタスの変化を表す、FTM0_C0SC のフラグビット & 0x80 を読んだタイミングで カウンタの値をキャプチャしている。

WS001572.JPG
posted by Yasuski at 09:46| LaVoixski

2019年01月08日

コードを整理する

LaVoixskiは、FTMに入力されたディテクターからの信号のアップ・エッジ間の時間を計測する方式で、オシレーターから復調された信号の周波数を検知する。 

発振器の差分を検出するディテクターには、データ入力とクロック入力にリファレンス用に周波数が固定された発振器とVCOの出力を接続したD-FFを採用しているが、

WS000503c.JPG

簡易型のLC発振器は周波数特性やリニアリティーに特筆すべきところはなく、楽器用途としてはいささか頼りない仕様と言える。

Screen20Shot202018-05-0620at2016.00.52.png

デジタルテルミンの長所は、このような「あまり高性能とはいえない発振器」の、直線性の良い周波数偏移が行われる部分を切り取って使用できる点にあるが、発振器の素の特性の影響は無視できない。 つまり、発振器のアナログ的な特性を追い込むことが安定した楽器を作る上での正道ではある。

とはいうものの、現在の実験環境はプアな性能の発振器を使用することを強いられているわけだが、ソフトウエア面からのアプローチによって安定した性能を獲得することにフォーカスを絞ることにした。

以下、そのような観点から行った試行錯誤を記録していく。

まず、MicroSDからアップロードされたデータのうち、一切の変更が認められない項目を固定した。 具体的には制御用のWaveTable群がそれにあたる。

WS001557.JPG

ピッチ関連のデータも同様に固定することにした。

WS001558.JPG

FTMのカウンタを駆動するクロックの分周率の設定が難しいが、今回は分周率を上げる方向で実験を行っていく。

分周率を上げると低域の処理が安定する半面、再生周波数のレンジは低い方に推移する。

WS001559.JPG

動作を出来るだけ軽くするために、Loop内に記述していたgotoを排除し、While文に書き換えた。

WS001560.JPG

FVCの改良点として、まずPitchアンテナ側のValueに15bitのリミッターを設置している。

WS001561.JPG

当初は、Volumeアンテナ側とPitchアンテナ側に分散してイニシャル値を記録する方式を試していたが、動作に問題が生じたために後ほどこれを修正している。

WS001562.JPG

処理ステップを削減するためにインターラプトのマスクを行うルーティンの合理化を目指したが、周波数ディテクタ入力の介入ポイントが限定されてしまう弊害が認められたため、処理をまとめた項目それぞれに対してこまめにマスクを行う方式に変更した。

WS001563.JPG

また、音の歪みが気になったサブ音声出力に関して、データ送信ルーティンの処理を最適化した後にattatchInterruptのルーティン内にデータ送信のタスクを集中することで、ノイズの発生を回避することができた。

WS001564.JPG

FVCの改良に関しては、まずSwitchで選択しているキャリブレーション関連の処理を、項目別に一元化する整理を行った。

WS001565.JPG

動作の安定を図るため、キャリブレーション-モードの切り替え機構の処理を分散させている。 例えば、EEPROMのハンドリングはVolume側で行っている。

WS001566.JPG

改変の結果はご覧のとおり、入力値が確実に反映されるようになった。

Screen Shot 2019-01-08 at 6.33.53.png

Pitch側の出力値のスケール設定が難しく試行錯誤が続いている。 ビットシフトによる分解能の縮小は安定化に寄与する半面、低域音階の変化が不連続になってしまう。

Screen Shot 2019-01-08 at 20.53.12.png

特に低域の不安定さを解消するために平滑化を強化する方向でウエイトを設定するような対処法では動作速度に支障が出てしまう。 例示している値では演奏に耐えることが出来なかった。

Screen Shot 2019-01-09 at 10.35.38.png

一方、Volume制御側に感じていた問題点は、左手の位置をセンシング出来る領域の狭さで、14bitに設定していたValueの制限値を下方に広げることで領域の拡張を試行したものの、結果はいまひとつだった。

Screen Shot 2019-01-09 at 10.36.32.png

FTMに関しては、Pitch/Volume双方に求められる最適な特性が異なるため、設定値の選択が非常に難しい。 特にVolume側は”分周比2”以外の選択肢がなく、結局はPitch側に折衷を迫られることになった。

Screen Shot 2019-01-09 at 18.06.20.png

結的に、選択した平滑処理に設定するウエイトの値はこうなった。

Screen Shot 2019-01-09 at 18.06.50.png

動作が不安定だったEEPROMの書き込みルーティンには二重動作の防止と、待機時間の設定、それとイニシャル値の再読み込み機能を追加している。

Screen Shot 2019-01-09 at 18.07.21.png

試行錯誤の結果、Volume側には帯域制限が必要なことが判明、最適値の選択はこうなった。

Screen Shot 2019-01-09 at 18.07.29.png

この時点でPitch側のフルスケールは15bitとなっているが、その分平滑化のウエイトを増やすことで対処している。

Screen Shot 2019-01-09 at 18.07.52.png

その後、Pitch側のFVCのスケールを16bitに拡張したので、ついでにウエイトの方も重めな設定に変更した。

Screen Shot 2019-01-10 at 6.29.44.png

オシレーターのイニシャル値はこの設定で安定している。

Screen Shot 2019-01-10 at 6.39.52.png

現在機能は殺してあるが、adatに対応するための2'sComplimentに出力値を変換する機能を実装しておく。

33764270_1871013596262423_2066379358188077056_n.jpg

12bitFSのWavetableは中央値が2048なので其処をゼロポイントとし、それ以上の値は2048との差分を、以下の値は2048から変化量を減算した後、全ビットにXORを掛けてデータを反転したものに1を加えている。

16bitFSでPitchをコントロールする場合、Wavetableの読み出しアドレスを8132stepにすることで、低域の安定度を上げることが出来る。 その場合、波形の登録を1/2に削減しなければならないが、実験を行う価値はあるだろう。 

追記: 

q15_tに指定していたWavetableやVolumeControl系のデータ型をuint16_tに修正した。 

WS001573.JPG

妙なノイズが発生していた原因はコレだった模様。 int16_tを浮動小数点型にまとめて変換した時にミスって指定を行っていたようで、

WS001574.JPG

処理幅が12bitのVolumeControl系は要所要所に"&0x7FF"でリミッターを掛けていたので影響はなかったが、

WS001575.JPG

流石にWavetableの指定はマズかった。

WS001576.JPG

修正後は、出力波形の歪が軽減された。 ついでにVolume系のリミッター群も取り除き、少しでも処理速度のマージンを稼ぐ事を目指している。

WS001577.JPG
posted by Yasuski at 00:00| LaVoixski

2019年01月01日

SequencialArpeggiatorのクロックを、Sequencerに設定したTempoと同期させる

インターフェイスの処理を行っているMainLoop上では、SequencerやArpeggiatorを駆動するタスクの処理を行っているが、この部分のif構文に拠る総当りな条件分岐をSwitchによる選択制に変更し、処理のステップを軽減することを思いつく。

Screen Shot 2018-12-29 at 18.27.56.png

要は、mode3の切り替えに応じてSwitchした後、そのルーチンでArpeggiatorの設定とステップの計数を行うようにコードを改変している。タスク終了後には総当りしていた計数ルーチンをすっ飛ばして次のタスクに移行する。 

処理の軽減が進んで余裕が出てきたので、SequencialArpeggiatorのクロックをSequencerに設定したTempoと同期させる機構を実装してみた。 

これは、非同期なArpeggiatorの推移のズレがSequencerで設定したループのタイミングが外れる度に生じてしまう違和感を解消するための施策で、当初はフリーランに拠る「自由度」を期待したものの、あまり効果的な用法を編み出せず弊害の方が気になりだした為に当初の方針を変更することになった。

手当を行った後は、これまでのフリーランの結果生じていた字余りっぽい挙動がある程度は軽減された模様。

WS001553.JPG

その後、クロックを同期するための割り算の精度を小数点以下8桁から13桁に上げた結果、発音のヒゲ(字余りの軽度なもの)の発生頻度を改善することが出来た。 

拍子に合わせた分散和音を展開できるようになるのはSequencerの用法としては正解だろう。

WS001554.JPG

拍子の「刻み」に誤差が出てしまうのは「3拍子」の表現を行うために「割り切れない数字」を扱うためだが、これはどうしても行わざるをえない折衷案だ。 

WS001550.JPG

Sequencerには、先に思い付いた「和音のシーケンスを行う機能の実装」を実現できず現在作業はペンディング中だが、必ずしも演奏に必須な機能ではないのでこのまま放置する展開もあり得る。

WS001555.JPG

和音の同時発音には少数点以下の数値を扱うデータアレイの実装が必要だが、現時点では何故かデータの読み出しを失敗してしまう。 コードを構成する和声のアレイ化は問題なく行えているのだが、それらを統合するアレイの構築法が判らない。 多分桁の扱いが問題なのだろうが、現時点では最適な用法を思いつくことができていない。

Screen Shot 2018-12-30 at 4.52.11.png
posted by Yasuski at 21:49| LaVoixski

2018年12月29日

ピッチ検出機構の改良

不安定なピッチ検出機構の改良を試行錯誤していたが、データを帯域制限した後に乗算してスケールを拡張する手法に到達するまでに数時間余りを費やすことになった。

ピッチの分解能の制限を安定性とトレードオフした結果、新たに立ち上がってくる問題は高音域の縮小で、制限前に6オクターヴだったものが5オクターヴ以下になってしまう。 このような状態を回避するため、当初はbitshift を使って2倍に乗算を行ってみたが、出力が荒れる現象は解消出来なかった。 結局は、出力値に1.5を掛けることで調整を行えたが、これは閾値の段差を上手く回避する方法だったようだ。

WS001547.JPG

その後、sequencerモード上で、アンテナ入力からドライヴする音源のピッチが、テンポを表示するLEDが点滅するタイミングでブレてしまう現象が発覚した。

ピッチ検出ルーティンに新設したタスクの増加による遅延の影響なのかどうかは不明だが、出来るだけシンプルな位置にsequencerのピッチを決定するコードを移転させることにした。

現状はswitchの条件分岐上にコードを展開していたが、

WS001546.JPG

これをクロックディバイダの直後に置き換えたところ、ピッチの崩れを解消することが出来たようだ。

WS001545.JPG

posted by Yasuski at 11:32| LaVoixski

2018年12月28日

SequencialArpeggiatorを増設する

製作したルート音追従アルペジエーターを実験してみたが、アルペジエーター側の同期が適当な所為なのか、微妙にランダム分散和音発生器っぽくなってしまった。

今回選択したアルペジエーターのフレーズは5種類で、フレーズの構成を単純に順送りに設定したことも、「不思議伴奏」が現出してしまった原因だ。 

相互に影響しあうフレーズの選択が難しい。ベースラインとアルペジエーターのフレーズの間で「食い合せ」の問題が出ないように、事前に熟考する必要がある。 今回使用しているベースラインは細かいステップで構成されているので、それがピッチ選択の不安定さの原因になった。

ルート音を半端に追従する現状は「これはこれで味がある」とも言えるレベルなので、伴奏のスタイルとしてはアリだと思うのだが、ベストな運用法とはいえない。 一度分解能が粗くて遅いテンポのベースラインを使って、安定した運用を試すべきだろう。

アルペジエーター側の再生レート設定は、シーケンサー側と相関させたほうが良いかもしれないが、安定性が担保される反面、演奏が機械的になってしまう欠点がある。

アルペジエータに発生していた誤動作の問題は、ローカル・レジスタの増設と、無音状態のスキップ、シーケンスデータの分解能を向上させることで解決できた。

WS001535.JPG

WS001536.JPG

WS001537.JPG

WS001538.JPG

WS001539.JPG

WS001540.JPG

WS001541.JPG

WS001542.JPG

WS001543.JPG

WS001544.JPG

大雑把な内容だが、2種類の手段でルート音をチェイスするSequencialArpeggiatorの動作を記録した。



今回は、SequencerModeのアドレス# 1/#2 に、アルペジエーターのルート音の設定が入力に反応するモードとファイルされたデータに反応するモードの2種類を実装した。

何れの場合も、Arpeggiatorの動作パターンの選択はSequenceFileから行っている。

posted by Yasuski at 03:33| LaVoixski

2018年12月27日

ベース・ノートにアルペジエーターが自動追従するシーケンサーのCHを新設する

ベースラインに合わせて任意のパターンでアルペジエーターを駆動する仕掛けを思い付いた。 

Screen Shot 2018-12-26 at 22.05.04.png

まずは下準備から。 シーケンサーのアドレス#2に、アルペジエーター専用の設定アレイ読み出しカウンタを追加する。

Screen Shot 2018-12-26 at 22.04.50.png

次に設定値をストアするローカル・レジスタを追加。

Screen Shot 2018-12-26 at 22.04.24.png

こちらはアルペジエーターのステップを駆動するローカル・レジスタ。

Screen Shot 2018-12-26 at 22.03.22.png

ストアしたアルペジエータ−用の設定値を呼び出すレジスタを追加する。

単純に分散和音を記録する代わりに予め用意したパターンを選択することで、メモリーの消費を抑えつつステップ当たりの情報量を増やすことができる。

Screen Shot 2018-12-26 at 22.03.06.png



Screen Shot 2018-12-26 at 22.02.46.png

実際に運用したところ少々忙しない感じだったので、ピッチを参照するタイミング・クロックを分周して、変動を抑えることにした。

WS001532.JPG

WS001533.JPG

WS001534.JPG
posted by Yasuski at 04:19| LaVoixski

2018年12月26日

ArpeggiatorをEnvelopeGenerator風に使用するアイデア

音声出力のエンヴェロープをアルペジエーターを使ってパルス制御風に駆動するモードを思い付いた。

その仕組みは単純で、microSDに登録した等倍=C2・無音=0のピッチ情報を用いて主旋律にピッチを連動させたアルペジエーターを駆動するだけなので、実装それ自体は簡単に済みそうだ。

インターフェイスは、アルペジエーターをオン・オフする閾値の制御用に追加した空きチャンネルを選択した時にEGを起動すればよいのだが、閾値/EGのモードを切り替えるためのスイッチを増設する必要がある。

さらにお手軽な手法として、アルペジエーターのピッチ情報を固定したデータをパターン選択ルーティンの後方に貼り付ける選択肢もある。 この場合は、既存のノート情報のアサインを変更するだけで済む。 

WS001531.JPG

現状、アルペジエーターは実質的に15ch程余っているのだが、これらは制御不能紙一重な仕様故にアドレスを数CH程潰したとしても楽器の運用に支障は生じないだろう。

WS001530.JPG

とりあえず、ノート情報をストアするための関数、inNotes を27番まで増す。

WS001528.JPG

リードカウンタの n は既にリザーブ済。 n の容量は32ステップもあれば十分だろう。 記録用のCHは最低でも4つは欲しいので、TEXTファイルの読み出し機構をあと2つ追加する必要あり。(遊んでいる2chを既に実装している) 

WS001529.JPG

出音の制御は、Pitch情報を真ん中の 等倍="0"・無音="x" に限定して、addValue に掛け算すればOK。

テルミンは明確なアタックを伴った発音が苦手なので、アルペジエーター系の発音一発目はタイミングが合わせ難いものの、この手のエフェクトを使用することで表現のヴァリエーションを増やすことができる。

posted by Yasuski at 08:02| LaVoixski

2018年12月25日

microSD関連のバグについて

microSDにデータを格納する際に発生するストアミスの原因は、データを転送するために準備したバッファーの桁不足にありそうだ。

Webで似たような症例を検索してみた結果、このような記事を発見した

ということで、とりあえず不足していた1文字分*を増やしてみた。

WS001527.JPG

データをアップロードする前のリザルトはこれ。 本来は1桁な筈の arptn_d の数値が2桁あるのがおかしい。

Screen Shot 2018-12-25 at 5.00.52.png

修正したファームウエアを書き込んだ後に、メモリにデータをストアしてシステムを再起動した結果がこちら。

Screen Shot 2018-12-25 at 5.00.52.png

arptn_d の値には設定域内の適正値 "3" が記録されている。

まだ、他のチャンネルでデータをストアした場合に不具合が再発生する可能性が残っているが、ひとまず修正は成功したといえるだろう。

*その後、16桁では不足かもしれないことに気付き、17文字に変更している。
posted by Yasuski at 05:16| LaVoixski

パラメーターの再設定時に発生したバグについて

SEQUENCER を駆動するクロックを分周した影響で遅くなったテンポの再設定を行おうとしたところ、入力を受け付けず調整不能に陥ってしまうバグが発生した。

原因を解明するのに少々手間取ったが、Metroに設定していたクロックの発生周期の最小単位を80msから20msに書き換えることで、実用域までクロックのタイミングを修正することが出来た。

WS001523.JPG

今後は実用レベルで瑕疵が発生しそうなので、出来ることならライヴに楽器を持ち込んで試験的な運用を行いたいところ。
posted by Yasuski at 01:03| LaVoixski

2018年12月24日

Metroのクロックレートを調整する

実用面から考えると無駄に速かったArpeggiatorのクロックに1/2分周を行った。

WS001524.JPG

ついでにSequencerにも同じ手当を行った結果、実用的なテンポを設定することが出来るようになった。

WS001526.JPG

要は、Metroがアクセプト出来るインターバルの制限が1000msなために発生していた不具合だが、分周によって最長1980msのインターバルでクロックをドライヴすることが可能となった。
posted by Yasuski at 18:07| LaVoixski

条件分岐処理の合理化を考える

アルペジエーター関連のタスクを積み上げ過ぎた結果、音質に悪影響が出てきた。 設定の処理を行うループ内にタスクが集中していることが原因と思われる。 今回追加したタスクの大半が条件分岐なので、この部分の処理速度を上げるのが手っ取り早い高速化のメソッドだろう。

処理の合理化をキーワードにしてWebの資料を漁った結果、if の代わりに switch を使うことで選択後の分岐処理をスキップ出来ることが解った。 

例えば、if()構文で条件分岐を行う場合、条件がヒットした後であってもタスクの終了後に残りの条件が総当りで参照されてしまい、この過程が処理の遅延に直結する。 記事で提案されていたのは switch/case で分岐を組む手法。 処理を行った後にbreakを行うことで、他の余分な条件をすっ飛ばして分岐のルーティンを終了するところが良い。

実際に行っていた処理の例では、アルペジエーターの再生パターンの選択やメモリーの管理をif()構文で行っているのだが、これが結構な量のステップを消費しているように見える。 そこで、この部分を switch による条件分岐に書き換えて、稼働試験を行った。

Screen Shot 2018-12-24 at 9.15.37.png

結果は発音に明らかな改善が見られたので、if()構文を可能な限りswitch/caseに書き換えることにした。

その他、発音機構のタスクを減らすために constrain で行っていたヴォリューム関連の出力制限をより単純な value && 0X0FFF によるマスキングに変更している。 弊害として、最小ヴォリュームから桁下がりで最大値に転換してしまう閾値周りの挙動が荒っぽくなるが、実用上は問題無さそうだったので、しばらくの間はこの仕様で様子を見ることにする。
posted by Yasuski at 10:12| LaVoixski

2018年12月23日

microSD関連のバグについて

microSDにデータを記録するタスクに、記録するチャンネルに対応する条件分岐を設定し直した。

以前から「対応するアドレス毎に」条件分岐を設定していたのだが、

WS001521.JPG

バグが発生する状態ではやたらと記録に時間が掛かる傾向があった。 電源投入後の立ち上げに掛かる時間とほぼ一緒なのが、何気に危ない。

以上の現象から想像するに、メモリーにデータを書き込みむ際に発動される条件分岐が無視されて、全てのデータが書き換えられているようだ。 これを阻止するために、さらに上位の篩分けとなる「mode2のチャンネル」によって分岐を行うことにしたのだが、、、。

WS001520.JPG

コンパイルが通ったので、後ほど実機で試験を行おう。

追記:

実験の結果、データのストアは正常に機能している模様。 ビープ音の再生も問題なく行われた。

ストアに要する時間が短縮されたことから、書き込み時の誤動作は解消したと解釈してもよいだろう。
posted by Yasuski at 08:57| LaVoixski

Arpeggiator#12にバグを発見する

再生を繰り返す過程でアルペジエータ12番の挙動が怪しいことが発覚、コードを精査したところローカルに配置した円環カウンタのクリア機構にアサイン・ミスを発見した。

WS001519.JPG

が、、、作業の甲斐無く、アルペジエーターのおかしな挙動は一向に改善しない。

これは「読み出したファイルの記述自体にミスがある」と考えてmicroSD にストアされたファイルの内容を確認したところ、本来は並んで記述してはいけないセパレーターの , (コンマ)と # (シャープ)がダブっていることを発見した。

不具合の原因はこれで決まりだが、面妖なのはソフトウェア側の該当する箇所の近辺に別のミスが潜んでいたことだ。

その他に確認されている怪しげな箇所としては、Sequencer内でアルペジエータの再生レートが設定不能になるバグがある。 ロータリーエンコーダーにアクセスする手順を間違うと、二度とパラメーターを変更することが出来なくなってしまう。

原因は、ロータリーエンコーダーの出力バッファーがMetroで組んだ回路と切り離されてしまうことだと思われるが、トリガーと連動してバッファーの値を取り込めるように、コードを改編する必要がある。

その後、該当する箇所にデータを読み込むためのコードを追加して問題は解決したが、microSDにデータを書き込むためのルーティンが何故か上手く動作しない。 いまのところ原因は不明だが、IDE自体のバグの可能性もあるので、しばらくの間は様子をみることにしよう。
posted by Yasuski at 00:14| LaVoixski

2018年12月22日

SequencerのTempoFlashのタイミングを調整する

Sequencerの音符の分解能を高めた場合にTempoFlashの間隔が速くなり過ぎて視認性が悪化する問題に対策を行った。

例えば、16部音符を最小分解能とした場合、全音符には16stepが費やされるが、この間にLEDがチカチカと8回も瞬くことになる。

この問題を解消するために、テンポの設定に合わせてFlashのクロックを分周することにした。 

まずは分周用のカウンタを構成する関数を設定し、、、

WS001517.JPG

次に、metroを駆動するパラメーターの値を条件分岐で振り分けて、個別に分周比の設定を行う。 

今回は、1/4、1/2、等倍の3種類を準備した。

Screen Shot 2018-12-22 at 10.05.30.png

分周比を振り分ける閾値の設定が心配だったが、稼働試験の結果は違和感のないものになった。 
posted by Yasuski at 10:25| LaVoixski

2018年12月21日

VolumeAntennaの出力にThresholdを設定してArpeggiatorの起動を行う仕掛け

デモ映像を収録している時に思い付いたのだが、アルペジエーターのオン・オフをVolumeAntでスイッチしたくなった。

スイッチの閾値をマニュアルで設定できれば、より豊かな表現が行えそうだ。 アルペジエーターを使用することで機械的になりがちな演奏の雰囲気を、マニュアルスイッチング機能によって和らげることが出来るのではないか。

まずは、スイッチを構成するために必要な関数を設定し、、、

WS001509.JPG

Arpeggiatorをアクティヴェイトするためのスイッチ用にトリガーを追加して、、、

WS001510.JPG

metroが起動する度に、フラッグを反転させるラインを記述する。

ひとまずThreshold設定が可能なスイッチ回路を構成してみた。



各モードでスイッチングを行っているが、クロックの表示があったほうが便利そうだ。

Sequencerはクロックのレートが異なるので、専用のフラッグを追加した。 

WS001511.JPG

短いシーケンスを再生する場合にレートが速くなり過ぎることを回避するために、スケールを900msから1800msに広げている。

WS001512.JPG

こちらは、Arpeggiator用のフラッグ。 やはり、全モードで表示を行ったほうが良いということで、RGBロータリーエンコーダーのLEDを駆動する回路を追加した。 

WS001513.JPG

実際に動作させると、こんな感じになる。



LEDの輝度にカメラの感度を調整出来なかったためにイマイチ点滅の雰囲気が判り辛いが、ArpeggiatorのPlaybackRateに合わせて行われるLEDの点滅は結構インパクトがある。

ちなみに、Sequencerは再生レートが違うので点滅回路を別建で用意した。 

Arpeggiatorを起動するThresholdのパラメーターは、RGBロータリーエンコーダーの上側最終アドレス(#9/無点灯=黒)にアサインしている。 何れの場合も、Arpeggiatorの起動時にクロックのタイミングでLEDが水色に点滅する。

WS001514.JPG

microSDの記録が正常に行われない問題はフィックスできていないが、とりあえずデータを書き込む際に使用していた条件分岐の関数を整理しておいた。

WS001515.JPG

トリガーのスレッショルド出力には、Volume表示用のLED出力とは別に独立させたものを準備している。

WS001516.JPG

閾値はゼロから設定が可能。ゼロ設定で実質的にスイッチが無効化する。 メモリー機能は必要性が不明なのでまだ実装を行っていない。

Sequencerのテンポが判るのは良いのだが、ステップの分解能(の設定)によっては点滅が速過ぎて視認性が低下するのが問題。 条件分岐を行って分周比を変更する等、表示を最適化する必要を感じている。
posted by Yasuski at 16:45| LaVoixski

アルペジエーターの機能を比較する

発音バンク別に設定したアルペジエーターの機能を紹介する映像。



2~5Voice、フリーにPitchをエディット出来るモード、Seqencialにアルペジエーターの設定を設定できるモードの6種類を切り替えている。
posted by Yasuski at 01:18| LaVoixski

アルペジエーターの動作不良

偶に発生していたアルペジエーターの動作不良の原因は、アルペジエーターのパターンを設定するデータが負の値に変換されて発生するバグだった。 

WS001501.JPG

何故ここで−1していたのか? 原因は不明だが、microSDカードを扱う試行錯誤の段階で、コードを修正し忘れていたのだろう。
posted by Yasuski at 01:13| LaVoixski

2018年12月19日

シーケンサーに「アルペジエーターのアドレス読み出し機能」を実装する(2)

アルペジエーターのシーケンス制御を行う計画は、専用のシーンメモリーを追加して、仕組みとしてはほぼ固まってきた。

WS001495.JPG

WS001496.JPG

WS001497.JPG

シーケンサからの出力を観測したところ、フレーズを選択するLSBは正常に動作している模様だが、何故かモードを選択するMSBのビットが常時オン状態になって切り替えが効かない。

試しにMSBの値を"L"に固定したところ、モードが正常に選択されていたことから、仕掛けの構造自体には問題はないと思われる。

不具合の原因は不明だが、シーケンサのみ単体でシステムを走らせて出力を監視して動作の検討を行うことにした。

WS001498.JPG

設定値を有効化するため、トリガーで駆動するシーケンスのルーティン間に項目を偏在させた結果、ようやくモードの切り替えを確認することができた。 

ただ、現在試験用に組んでいるシーケンスは60ステップとパターンの変化がめまぐるしく、テンポをかなり遅く設定する必要がある。 



実用面を考えた場合、ステップ数を管理する方向で運用を検討したほうが良いだろう。

WS001494.JPG

WS001499.JPG

WS001500.JPG

posted by Yasuski at 05:48| LaVoixski