2019年03月02日

Wavetableを使用したコンプレッサーの実験

処理のタスクを少しでも減らせるように、このような非線形処理を行っているルーチンを省力化出来ないか検討を行った結果、GNU/Octaveを使って、出力波形圧縮用のWaveTableを作ることを思い付いた。 。

WS001268.JPG

問題はメモリーの残量だが、実際に24bitデータをリザーヴするのは非現実的で、そもそも処理が重すぎてOctaveからデータアレイを出力することができなかった。

いっそのこと理想としていた24bit/adatフォーマットを諦め、16bit長でデータをやりくりするという割切りもアリではある。  結局、16bit×16bitのデータは難なくアウトプット出来たが、、、

WS001735.JPG

これを適応させた場合、出力波形は相当なレベルで歪むことになる。

WS001734.JPG

解像度を上げると結構ガタガタになるが、まあこんなものであろう。

例えば、真空管アンプの実際の歪率は物凄いことになっているのだが、アレはアレでというかあっちのほうが音圧があって味を感じてしまうのが人情なので、出音が気に入るのであれば「波形のピュアさ」などという視点は無視したほうが良いのかもしれない。

で、予想はしていたがメモリーの総量が限界を超えてコンパイルが通らなくなったので、システム全体のダイエットを行うことにした。 まずは64bit長でエントリーしていた関数全てを32bit長に修正したところ、なんとメモリーの余裕が30%も増えた、、、。

WS001736.JPG

次に、エントリーしているWavetableのうち、cos波形を排除してRAMの使用量をさらに圧縮した。

全体に余裕ができたので、音量調整用の16bitFileをエントリーしてみたが、何故かRAMの使用量が二倍になって仕舞い、破綻が発生することが判った。

ローカルで関数を宣言しないのが正解かも?と考えて、Volume制御系のデータArrayに、出力直をアサインしてみたが、、、

WS001737.JPG

これもアウト。 サブルーチン上にWavetableを展開するとメモリーをリザーブしただけでは済まず、実質的にダブルエントリーとなってしまうようだ、、、。

結局、今回はコンプ機能の導入を諦めることになったが、どうしても出音が気になってくる。 

明日は徹底的にWavetableのダイエットを行った実験用のプラットフォームを作って結果を試してみよう。

ちなみにこの方式を応用すると、リングモジュレーターやFM音源が作れそうだ。

posted by Yasuski at 03:40| LaVoixski

2019年03月01日

タイマーカウンタのセットアップ

CubeMXは、このようにタイマーカウンタをセットアップするためのコードを吐き出してくれる。

WS001732.JPG

Arduinoで記述していたこの部分のコードがそれに相当する。

WS001559.JPG

データブックを引かなくてもさっさとコードを吐き出してくれるのはとても便利だ。

WS001727.JPG

WS001728.JPG

WS001729.JPG

WS001726.JPG

WS001730.JPG

WS001731.JPG



posted by Yasuski at 13:49| AudioElectronics

STM32F407ZET6ボード

去年の年末辺りからTeensyへのオルタナティヴとなりそうなボードを探っていたのだが、高性能なSpresenseは敷居が高すぎるうえに今のところ開発に必要なデータが揃わない。

そこで、まずは手軽に試せそうな STM32F407ZET6 を搭載したボードをArduinoに対応させてみた。

IMG_8942.JPG

単価は1.3k程と激安だが、オーバークロックさせない素の状態では168MHzと処理能力はシステムクロックを最高速に設定したTeensy3.6の2/3位になるだろうか。 Spresenseとは違って、出せるpinを全て引き出している構成がとても好ましい。

Brand: Unbranded/Generic
Markings: STM32F4XX STM32_F4XX V3.0 1606

Specs:
STM32F407ZET6 ARM Cortex M4
168MHz, 210 DMIPS / 1.25 DMIPS / MHz
1.8V - 3.6V operating voltage
8MHz system crystal
32.768KHz RTC crystal
2.54mm pitch pins
JTAG/SWD header
512KByte Flash, 192 + 4 KByte SRAM
3x SPI, 3x USART, 2x UART, 2x I2S, 3x I2C
1x FSMC, 1x SDIO, 2x CAN
1x USB 2.0 FS / HS controller (with dedicated DMA)
1x USB HS ULPI (for external USB HS PHY)
Micro SD
Winbond W25Q16 16Mbit SPI Flash
RTC battery CR1220
1MB SRAM footprint, unpopulated (IS62WV51216-1M)
1x 10/100 Ethernet MAC
1x 8 to 12-bit Parallel Camera interface
3x ADC (12-bit / 16-channel)
2x DAC (12-bit)
12x general timers, 2x advanced timers
AMS1117-3.3V: 3.3V LDO voltage regulator, max current 800mA
Micro USB for power and comms
Yellow user LED D1 (PF9) active low
Yellow user LED D2 (PF10) active low
Yellow power LED D3
2x jumpers for bootloader selection
Reset button, Wakeup button, 2x user buttons K0 (PE4) and K1 (PE3)
2x30 side pins + 2x16 bottom pins + 1x4 ISP pins
2x16 FMSC LCD Interface
NRF24L01 socket
M3 mounting holes
Dimensions: 95.1mm x 74.6mm

ボード側のピン接続はこうなる。

<-----+
|_1 _2| Pin 1 = 3v3
|_3 _4| Pin 4 = GND
|_5 _6|
|_7 _8| Pin 7 = SWDIO
|_9 10| Pin 9 = SWCLK
|11 12|
|13 14|
|15 16|
|17 18|
|19 20|
<-----+

当初はボードが認識されずにあれこれ試行錯誤を行っていたが、単に配線が外れているだけだったという何時ものマヌケぶりを発揮してしまった。

凡ミスを防ぐために、書き込みケーブルには専用のコネクタ付きのものを購入したほうが良さそうだ。

今回は、Arduino IDEからBlinkLEDを書き込んで、ポートアサインの確認を行った。 

WS001723.JPG

Pinナンバーは数字単体ではなく、回路図にあるようにPF9と記述すれば良いようだ。 コンパイルには結構な時間が掛かっている。 単なるBlinkに数分掛かるようではこの先が思いやられてしまう。

WS001724.JPG

ボードへのデータの書き込みはST-Linkを介して行うことになる。 ST-Linkはファームウエアやドライバのアップデートを確認出来るUtilityを併用すると便利だ。

WS001721.JPG

何れは使用するであろう直アサインの記述は、MCUのアプリケーションデータで確認する必要がある。

STM32F4シリーズは、カウンタの構造などチップの構成がTeensyで使い慣れたFreeScaleのMCUとは大幅に異なるので、これからデータブックを読み込んでいかなければならないが、もしかするとST製のM3を搭載した Due に近い命令体型なのかもしれない。

追記:

KeilにExampleコードを引っ張ってきて検討しているところだが、Timerの構成はFreescaleのものと比べて複雑な印象がある。 あまりに項目が多くて選択肢がつかめないので、予め必要とされる機能を選択した使用例を探した方が早道だろう。

WS001725.JPG

基本的にはリングカウンターの瞬間値を入力PINのアップエッジでキャプチャー出来れば良いだけなのだが、入力信号の分周まで出来てしまうのが便利なのかどうか? 構造をよく理解していない現時点では何とも言えないがが、もしかするとコード側にも根本的な構造の改変が必要になるかもしれない。
posted by Yasuski at 06:22| Arduino

2019年02月27日

ロータリーエンコーダーの実装に関して

ここ数日間、新規に導入を検討しているロータリーエンコーダーシステムの実験を行っていたのだが、どうやっても増/減同一方向にしかカウントできない案件が発生。 当初はロータリーエンコーダーの故障を疑ったが、端子を変えても同じ動作をする。 また、プログラム側で極性を変えた場合でも、同一方向にのみカウントが亢進してしまう。

これは明らかに物理の問題なのだが、試しにPinA/Bに接続したノイズサプレッサ用のコンデンサを交換してみても状況は一向に改善しない。 回路的には変移する入力ステイタスのタイミングを見て、増減の方向を判断しているのだが、多分「特定パターンの変移」が読めないためにおかしな動作が発生しているようだ。

元記事を読んで、これが328向けに書かれたコードだったことを確認したが、328と比較して無闇矢鱈と処理速度が速いK-66では「pinの変移が読めないかもしれない」ことに気付いた。 

で、試しに数クロック分の無駄なタスクを追加した結果、

WS001708.JPG

ロータリーエンコーダーの正常な動作を確認できた。

WS001705.JPG

NOPは、無駄な動作を行っていないか確認を行うためのダミー。 pinに変移が発生した時のみ、タスクの処理を行っている。

WS001707.JPG

プラマイ両極性の変移も良好。 ノイズサプレッサの威力は絶大で、見事に誤動作を排除している。

動作が確認できたので、これもダミーで本来のシステムに近い状態を作って実験を行ってみたが、ひとつのカウンタを使い回す状態ではポットの個別データを保持することが出来ない。

WS001709.JPG

結局、ポット分のカウンタをロータリーエンコーダーの変移感知ルーチン側に仕込んで、スイッチで切り替えることになったが、これをパラメーターが多い側に仕込むのは結構な作業量になってしまう。

WS001717.JPG

結果的にはこうなってしまったわけだが、まともに動かせる自信がなくなってきた。 実際、RAMの使用量は94%に突入しているので、ここ数日の努力が無駄に終わってしまう可能性が疑われ始める。

WS001713.JPG

ポットの状態を管理するルーチンは、元のコードと比べて工程数が激減するわけでもなく、実際にMCU側の処理ステップ数で時間を計測してみたら存外遅延が増えている可能性もあるが、Timerで設定されたタイミンで定時に連絡を取りに行かないところがアドヴァンテージとなる筈だ。

WS001712.JPG

とはいえ、導入には巨大なカウンタのクラスタを生成する必要があり、そろそろメモリの余裕が無くなってき¥た。 従来はローカル関数で処理していたのだろうが、これらのアドレスが固定されてしまった状況で、はたしてシステムが正常に動作するのか? 実験を行って確かめたいところだが、その前にノイズサプレッサ=コンデンサの仕込みを行う必要がある。

WS001715.JPG

一方、クリックを検出する機構はループの巡回毎に端子の状態を読みに行くが、こちらの処理は軽く、遅延の発生は最小限に抑えられる。

クリック・ダブルクリックを行う毎にpotの読み出しアドレスを増減するインターフェイスの構造は従来のものと同じ。 ただし、アクセス時にpotの値を読み込まないので、無駄なデータの処理にタスクを割かれることはない。

このように、バックグラウンドの処理を極力抑えられたのは良いことなのだが、パラメーターの移植は大変な作業になった。

添付してたライブラリ類がなくなって、ソフトウエアのパッケージとしてはかなり身軽になったように錯覚したものの、本体はデータ別腹で4万行超えている。 物理面でもメモリをバカ食いしてるのが大問題で、ウエーブテーブル等はClass10とオーヴァースペックなmicroSDから直読みすればいけそうな気もするんだが、現行システムでは何故か通信のデータレートが激遅過ぎるので、それは無理っぽい。

追記:

実験の結果、残念ながらattatchInterruputを使用したロータリーエンコーダーの導入は失敗に終わった。

理由は憶測ではあるが、オーディオクロックの立ち上がり毎にハードなタスクをこなさなければならない状況の中で、他の外部端子からのスイッチングに拠るインターラプトが競合した場合に、ロータリーエンコーダー側の入力が競り負けてしまう現象で、入力に対する反応が安定せず、正常な動作を保証することができなかった。 

比較実験の過程で、奇しくもClickEncoderのセンシング・レートを低く設定した時に入力の精度が落ちる似たような状況に陥ってしまった。 センシングの頻度を下げた場合は、フリーランするループ内でエンコーダーの状態を反映するタイミングを外してしまい、結果としてエンコーダーの動作がおぼつかなくなることが判った。

ピッチの揺れに関する問題は、新規に導入した読み出しシステムの環境下で若干の改善が見られたが、インターラプト起動時に発生するタスクの変化が音声に反映される弊害も発覚している。 これにより、ロータリーエンコーダーの使用に伴って発生する処理演算のタスクが音声に影響していることを証明する形になったが、楽器としての実用性を考えた場合、出力音声が外乱からの影響を受ける現象を看過することが出来ない。

よって、計画は棚上げ・中止とすることが決定した。 
posted by Yasuski at 21:36| LaVoixski

2019年02月26日

ロータリーエンコーダーが消費するプロセッシングパワーについて

現在採用しているclickEncoderはTimer1に設定した1000usのタイミングに従って定期的にロータリーエンコーダーが接続された端子のセンシングを行っているが、毎時データを参照する分だけどうしてもタスクが増えてしまう。

WS001704.JPG

オーディオクロックを基準にすると1000usは1kHzとなるが、1ms毎に発生するタスクは結構大きなものがある。

フリーランさせているLoopルーチン内で発生する無駄なタスクの増加を解消するために、ロータリーエンコーダーからの入力をattatchInterruptで検知させて、その都度出力を行う方式への転換を検討している。

WS001702.JPG

clickEncoderを排除する手前、ダブルクリックの扱いにも変更を行うことになる。
posted by Yasuski at 03:35| LaVoixski

2019年02月25日

TFT液晶パネルの採用を考える

OLEDに対する拘りを捨てると、選択肢は一気に広がる。

s-l640.jpg

基板の端子配列パターンはおおまかに2種類存在しているようだが、一応両方のモデルを購入している。

3.5-inch-TFT-Touch-Screen-LCD-Module-3.jpg

が、青い方はどうもArduino互換ではなかった模様で(トップページから連想される製品仕様からするとこれはウソ)対処法としてはNucleoボードに搭載するか、もしくはリボンケーブルで配線を変更するしか無い。

基盤の設計は完了していて、赤い方の基板にはこれを使用することが出来る。

dueScope8.png

新しい設計の基板では、ロータリーエンコーダーの配線を変更してパラレル通信用の端子を確保している。

dueScope8sch.png
posted by Yasuski at 17:47| LaVoixski

2019年02月24日

dueScope2基板の設計

OLEDパネルをピギーバック形式で実装するスタイルに設計を変更した。

4ch分の入力を切替えられるようにアナログスイッチを導入し、プリアンプを3ch分、バイアス電圧ラインにバッファーアンプを追加している。

dueScope7.png

回路はほぼ完成形で、新たに見つけた製作記事にも対応できるように端子類を整理している。

描画が妙にトロいのはOLEDの仕様?なのか??? それでもDueではマトモに動かせている一方で、Teensyとの相性は最悪だ。 フォーラムではSPIからI2Cに駆動方式をスイッチしたほうが良いのでは?という意見もあったが、ボードの単価はDueの方が圧倒的に安くなる(コピー品を使うが問題は無さそう)ので、ことオシロに関してはDueを選択すべきだろう。

dueScope7sch.png

先に紹介した「しなぷすさんによるオシロの製作記事」は素晴らしい内容で、基本的なオシロスコープの機能をほぼ網羅している。 今回は駆動の作法が違うOLEDが使えるようにプログラムを改装しているのだが、これがなかなかの難物で描画が妙なことになってしまう。

IMG_8934.JPG

オリジナルの設計ではモノクロの64×128という画素数が少ないデバイスを使用しているが、今回採用する予定のOLEDは120×160のカラーで、アスペクト比が異なるのが問題で、文字の表示域に制限が出来てしまう。

また、デバイスに送るコマンドの文法が異なるため、項目毎にコマンドの翻訳を行うことになるのだが、項目が存在しない=翻訳できないコマンドの処理が難しい。 例えば、モノクロ液晶ではテクストの反転コマンドが存在するが、カラーデバイスの場合はテクストの色みを変える等に表示方法の仕様を変更する必要が出てくる。

いろいろとコードをいじくり回した結果、ひとまずは画像のような感じになっていて、描画に関しては表面上の辻褄を合わせることが出来ているのだが、

IMG_8935.JPG

テクストの表示を行うエリアがスコープの表示によって潰されてしまうため、パラメーターの入力が発生した時点で規定時間だけテクストをオシロ画面に上書きする仕掛けを追加しなければならない。

同時に、RGBロータリーエンコーダーを使用したClickEncoderの導入を画策しているのが無理筋で、オリジナル回路のスイッチ類をClickEncoderに置き換えるのに苦労している。 オリジナル回路は4つのタクトスイッチを使って項目の選択とパラメーターの増減をこなしているが、これをロータリーエンコーダーで代用する場合に項目の切り替えがどうやっても上手く行かない。

試行錯誤の結果、ClickEncoderには擬似的なスイッチ機能を持たせ、これによって生成されたロジック信号を端子から出力し、元来はタクトスイッチが接続されていた端子に物理で突っ込むという原始的な方法に転換しつつある。 

Arduinoは端子の通信速度が激遅く、それを解消するためにポートの直アサインを行っているのだが、液晶ディスプレイ等を駆動するためにLibraryを使用する場合、端子を共通化するためのArduinoの胡乱な仕掛けがボトルネックになってしまう。 その「共通化」の影響を少しでも減らすためにdigitalWriteFast等の関数を使うことになるのだが、Dueの場合ある時期からこの手の関数が使えなくなって仕舞っていた。

で、新しく見つけたのがリンク先のライブラリで、これの御蔭でDueでも出力の高速化を行えるようになった。 

digitalWriteFastをLCDとの通信に使うことで少しでも動作速度を改善する狙いがあるのだが、

WS001691.JPG

OLEDディスプレイの場合はどうもドライバ側にボトルネックがあるように思える。 極端に遅い描画速度を検証するために、比較用の液晶ディスプレイを購入した方が良いかもしれない。

現在、インターフェイスの実験を行うために、入力信号用のプリアンプを組み込んだ試作ボードをユニバーサル基板上で製作しているが、完成には二三日掛かりそう。
posted by Yasuski at 22:44| AudioElectronics

2019年02月19日

dueScopeの製作

IMG_8928.JPG

とりあえず、ClickEncoderの機能は実装できた模様。



Rateもキッチリと切り替わっている。 

今回のテストではRGBロータリーエンコーダーを使用していないので、LEDの点灯テストは未了。

IMG_8921.JPG

一時期対応できなかったスタートアップの画像もちゃんと読み込めるようになった。

IMG_8920.JPG

Teensyでは何故か欠けてしまっていたドットを復活させた。

IMG_8919.JPG

過大レベルを入力すると若干ドットの取りこぼしが発生してしまうが、Teensyと比較すると格段に良好。

IMG_8918.JPG

Dueの動作は速攻で描画が始まるTeensyとは違っていて、バッファーに一旦貯め込んだデータを逐次出しているように見える。 殆ど同じ内容のプログラムでどうして差が出てしまうのか?現時点でその原因は解らないのだが、TeensyのForumで見つけたトピックによると「Teensyが扱う32bit幅のデータがミスマッチしている」可能性が示唆されていた。 Teensy専用にライブラリを書き換える必要がありそうだ。

その後、運用法を考えた結果、Dueにピギーバックさせるのが良さそうということで、oledディスプレイを填め込んで実装できる基板を設計した。

dueScope2.png

入力には簡単なバッファーアンプを追加している。 回路は構造が単純単純なので、ユニバーサル基板に手組で製作を行う場合でも再現性は高いと思う。

dueScopeSch.png

Dueのタイマー系の構成について、詳細を記した資料を見つけた。

https://github.com/ivanseidel/DueTimer/blob/master/TimerCounter.md
posted by Yasuski at 15:45| AudioElectronics

OLED OscilloScope

Teensy3.6 に対応する OLED OscilloScope のコードを書いた。

WS001679.JPG>

インターフェイスにはLaVoixskiのロータリーエンコーダー周りのコードを転用した機能切り替え機構をなんとか組み込むことが出来たが、肝心のオシロスコープの性能は相変わらずイマイチで凹む。 あと、MCUのアナログ入力はポートを選ばないと性能にバラつきがありそう。

WS001680.JPG

波形表示のオフセット値の設定が滅茶苦茶になるのは何故なのか??? 24MHzまでMCUのクロックをダウンしないと動かないのも謎だ。 DUEで動かしていた時は、クロックのことなど気にしたことはなかったのに、これまた不思議な症状である。

Teemsyにフィッティングを行う一方で、遊んでいるArduinoDueが勿体無いのでOscilloscopeを仕込んでみようと昨晩から頑張っていたのだが、

WS001679.JPG

動作を確認できているOscilloscopeを制御するClickEncoderが規格違いで実装出来ず、試行錯誤をしていたら夜が明けた。

WS001681.JPG

ClickEncoderは便利な機能なので大変気に入っているのだが、これが使えない状況は結構ツライ。

WS001682.JPG

コンパイルを通してはいるものの、エラーを潰すためにAVR系のライブラリーを無理矢理に排除した状態なので、ちゃんと動くかどうかは不明。

WS001683.JPG

いろいろと怪し気なところがあるのでこれからバグを潰していくことになるが、Teensyみたいな他所の子の環境でなんとか動かせるものが本家のDueではアウトというのが情けない

WS001686.JPG

Teensyから単純に載せ替えが出来ないのが歯痒いが、元はDueで開発していたのをTeensyに移植した経過を思い出して、複雑な心境になっている。

DueではClickEncoderを駆動するTimerOneライブラリが使えなかったので、Timer3というのを代わりに使っている。

オリジナルのコードは

  Timer1.initialize(1000);
   Timer1.attachInterrupt(timerIsr);

と記述していたのだが、Timer3には initialize というコマンドは存在せず、代わりにそれらしいコマンドをデッチ上げることにしたのだが、、、。

コンパイルにはやたらと時間が掛かった。 

WS001685.JPG

Teensyの場合も同様で、メモリのキャパを高々10%消費する程度の短いコードの割に、時間を食わせられるのが謎だ。 LCDのデータの取り溢しに関してはDueの方がマシなのは何故なのか? 動作クロックの問題など、解らないことが多い。

書き込み完了時の表示。 なんだかよく解らない文字が羅列されている。 

WS001684.JPG

書き込みのプロセスがバーグラフで表示された以前とは仕様が激変している。

Oscilloscope自体はAD周りがイマイチなTeensyよりも安定して動いている感じなので出来れば完成させたいところなのだが、DueはAVR系のライブラリを一切受け付け無い不親切極まりない仕様で、その余波でTimer系のライブラリの互換性が確保できない等、潤沢なリソース(だけ)が売りのArduinoとは思えない所業である。

この手の使い物にならんハードウエアを、よりにもよって本家筋が作って仕舞ったのは理解不能だが、確かにWebを検索しても製作例を殆ど見かけないのであった。
posted by Yasuski at 08:58| oled

2019年02月16日

音声編集のメソッドについて

プリセット・チャンネルの出力波形の編集を行う際に採り得る選択肢として、

1)目的とするヴォリューム群を一旦ゼロにリセットすることから始める。
2)もしくは12bit幅の最大値に上書きを行う。

という、2通りの方法が考えられる。

ポットの設定は簡単で、ポットを選択後に右側に2クリック動かすとほぼ最小値に、左側に動かすと最大値に出力を振り切らせることができる。

WS001678.JPG

より簡単に修正を行うには、最大値から適正値まで出力を減算していく手法が最適解と思われるが、この時に誤って波形データの変更を行うとオリジナルの状態が掴めなくなってしまうので、ポットを切替える時には誤動作に注意しなければならない。

問題は、今現在どのオシレーターを選択しているのかが判り難い点で、その場合は波形を切替えて該当するオシレーターを確認することになる。

何れにしても、離散したパラメーター群をまとめて俯瞰することは難しく、オシロスコープを併用した方がより確実に編集を行える。 出来れば専用のツールを開発したいところだ。
posted by Yasuski at 21:06| LaVoixski