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月05日

kymaConnectの動作不良を改善する

HighSierra上で発生していたkymaConnectの動作不良問題を解消する方法として、ディベロッパーからAvid系kextの排除を勧告された。 

Screen Shot 2019-01-04 at 2.33.24.png

確かに、midi関連の機能を全てOFFにするとPacaranaの認識が行われるようだ。

Screen Shot 2019-01-04 at 3.43.49.png

このままでは、ライヴ演奏時にmidiインターフェイスの使用が出来なくなるので、早速MBP17吋で削除を実行して再起動を行ったところ、何故かシステムが起動不能に陥った。

やはりOSのヴァージョンアップが元凶らしく、ファイルシステムの構造が激変している模様。ROMにも悪さをしている可能性がある。

仕方がないのでSSDを取り出し、外付けHDDに付け替えて元凶たるAMDのkextを排除したところ、外部ドライヴからの起動を確認できた。

もういい加減うんざりである。

その後、気をつけなければならない点として、Extensionフォルダ以外にも /Library/Audio/Plug-Ins/HAL の階層に “Digidesign CoreAudio.plugin” が居ることに注意せよ、とのお達しがあった。

トラブルの原因はやはりAvid系の旧いKextが悪さをしていた模様。 ProTools関連のファイル群の影響によって、kymaConnect上でPacaranaがオフラインになってしまうようだ。 

他に、こちらも旧い設計のM-AudioのKextがトラブル発生の原因となっていたようだが、同様に設計の旧いRME/Fireface800のドライバにも怪し気な雰囲気があった。 

RMEに関してはSierraに対応した「最新版」が出ていたのがラッキーで、これをインストールすることで起動が可能になった。 

Screen Shot 2019-01-05 at 2.35.58.png

RME関連のアプリケーションでは、残念ながらRMEのヴァーチャルミキサーの互換性が失われてしまった。 これは便利な機能だっただけにとても惜しい。

Screen Shot 2019-01-05 at 2.35.34.png

Screen Shot 2019-01-05 at 2.36.12.png

Screen Shot 2019-01-05 at 2.36.28.png
posted by Yasuski at 12:34| Symbolic Sound Kyma

2019年01月03日

2011 MacBook Pro 8,2 のAMD製GPUが死んだ場合の対症法

元旦の日付が変わって間もなく、2011年製MBP17吋のカーソルがフリーズ、再起動後のOS立ち上がりでグレイの画面に固定されてしまう現象が発生した。

以前、15吋(これも2011年製)のGPUが死亡してそのままジャンクと化したケースを体験しているが、これで自宅のi7搭載のMacbookが全滅してしまった。

なんとか対症法はないものかとWebで記事を漁ったところ、

Force 2011 MacBook Pro 8,2 with failed AMD GPU to ALWAYS use Intel integrated GPU (EFI variable fix)

というトピックを発見した。

対症法を要約すると、故障したGPUを切り離して起動する手法で、障害の発生によって途中で起動プロセスがスタックしていたOSを強制的に立ち上げている。 記事に紹介されていた実際の手順を引用すると、、、

First of all, it is possible to successfully boot a MBP to OS X while still using the failed GPU, after you remove the AMD drivers by booting in command line mode (CMD+S) and entering these commands:
1) fsck -fy (to check a disk)
2) mount -uw / (mount a root filesystem with read/write permissions)
3) sudo mkdir /AMD_Kexts/ (make a directory to store the AMD drivers in case you'll need them in future)
4) sudo mv /System/Library/Extensions/AMD*.* /AMD_Kexts/ (move the AMD drivers)
5) sudo rm -rf /System/Library/Caches/com.apple.kext.caches/ (remove the AMD drivers cache)
6) sudo mkdir /System/Library/Caches/com.apple.kext.caches/ (just in case OS X will be dumb and will not recreate this directory, I am creating it for OS X)
7) sudo touch /System/Library/Extensions/ (to update the timestamps so that new driver caches - without AMD drivers - will be definitely rebuilt)
8) sudo umount / (umount a partition to guarantee that your changes are flushed to it)
9) sudo reboot


といった作業のプロセスを経て、OSを正常に(近い状態で)立ち上げることが出来るようになった。

この他、起動時にNVRAMの内容をその都度書き換える方法もあるが、立ち上げ時に毎回儀式が必要になる手間を考えると、OSの起動プロセスを直接編集した方が良さそうだ。

とりあえず主要なアプリケーションの動作を確認できたので、この手当で暫くの間は誤魔化せそうだ。

追記:

17吋でアップデータを走らせたらブルースクリーンが出た、、、。

nvramの書き換えで起動したら取り敢えず処理が開始されたが、全くもって予断が許されない状況に、、、。

49661530_2199186926778420_5235849185781088256_n.jpg

49121592_2199187640111682_5381920954798571520_n.jpg

アップデート終了後に、なんとか起動することができたが、先に紹介した回復のメソッドは無効化されてしまった模様

49348404_2199191803444599_7742837170007703552_n.jpg

MountainLionでは4つだったAMD関連のkextファイルが、HighSierraでは十数個に激増した。 

動作もHighSierraの方が不安定で、画像のリフレッシュが完全に行われず、描画の安定度が著しく低下した。

Screen Shot 2019-01-03 at 21.47.27.png

さらなるアップデートで情況が改善される保証はないので、暫らくの間はこのままで様子を見た方が良いだろう。

Screen Shot 2019-01-03 at 21.47.47.png

外部接続の主要なハードウエアはなんとか動作している模様。

Screen Shot 2019-01-03 at 21.48.04.png

17吋に関しては動作速度に問題は発生していないが、15吋の方は速度の低下が著しい。 速度が速いSSDの外部ドライヴを接続した場合も情況が改善しなかったことから、マザーボードの本格的な故障が疑われるものの、いまのところ原因は不明。

Screen Shot 2019-01-03 at 21.48.23.png
posted by Yasuski at 04:52| AudioElectronics

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