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

記録ガイドの変更など

周波数検出機構周りを合理化した影響で、何故か音声ガイドが一斉に死亡する案件が発生した。

しかも、関連するLEDの点滅機構が同時に無効化されてしまっているのが謎だ。試しに対象となるLEDを変更したところ、こちらのアクセスは受け付けられるようで、全く訳がわからない。 音声ガイドはギミックなので諦めるとしても、LEDの点滅表示は必要な機能なので不具合を無視することが出来ない。

対策を熟慮した結果、動作不能となった全ての音声ガイド機能の代わりに目視に拠るLEDの発光パターンを組み込むことにした。

WS001664.JPG

WS001665.JPG

WS001660.JPG

波形パターンを登録するチャンネルに記録を行うメソッドをアドレス毎に直接編集するスタイルに変更したため、目視による確認がより効果的との判断もあったが、楽器の構造としてはこちらの方式の方がスマートだろう。

一方、波形編集機能の強化に伴って、オシレーター群のレベル管理に関する問題が表面化してきた。 

Screen Shot 2019-02-16 at 16.18.23.png

VRポットの該当する箇所に記述している volumeInc は、12bitフルスケールで増幅倍率を等倍にするための係数だが、×1倍以上にレベルをオーヴァーさせないために、ロータリーエンコーダーからの出力値を12bit以内に制限するリミッターを設けている。

WS001658.JPG

プリセットを呼び出して、各音源のレベルをゼロにリセットした後、再度レベルの調整を行う。 レベルのリセットはパラメーターをいちいちコールするのが面倒だが、該当するアドレスのノブを2クリック増加方向(右)に回すだけで、ヴォリュームレベルを最小値+1(実質的には最小値)に設定できる。 逆にノブを減少方向(左)に回すと、12bitフルスケールの最大値をコールできる。 

実際的な運用方法としては、ポットの最大値を呼び出してから最適値まで増幅度を下げていく方式が推奨される。

Screen Shot 2019-02-16 at 16.26.27.png

最新のデータがシーンメモリーに反映されない問題を解決するために、データ書き込みのタイミングでレジスタを上書きする仕掛けを追加した。

WS001659.JPG

その後、コード・エディットモード下で波形選択機能を使用した場合に、フリーズが発生するバグを確認した。 これは去年の夏場に体験した症状と酷似している。

既にコンパイラ、もしくはオプティマイザのバグが疑われる状況だったため、これを機にオプティマイザをLTOに変更したところ、問題は解決した。
posted by Yasuski at 07:58| LaVoixski

2019年02月15日

FVCに関連するルーチンの合理化について

少しでもピッチの安定度を向上させるため、周波数ディテクターを構成するFTMとPitch/VolumeValueの処理を行うルーチンのリレーションを強化した。

WS001661.JPG

LaVoixskiのプログラムはフリーラン状態のMainLoopと外部から入力されるオーディオクロックの波形が立ち上がるタイミングで動作するattatchInterruptおよびサブルーチン群で構成されているが、基本的にMainLoop内はフィジカル・インターフェイス系を、

WS001675.JPG

WS001676.JPG

attatchInterrupt内はオーディオ処理系のタスクを中心に配置している。

WS001677.JPG

周波数を検知するFTM(Flexible Timer)は、これらのルーチンが処理を行うタイミングとは独立してカウンタを回しつつ、外部トリガ入力のアップエッジでカウント値の差分をキャプチャしているが、

WS001671.JPG

改装前のコードでは、FVC(Frequency to Value Converter)を総体として見た場合、FTMから駆動されるピッチ/ヴォリューム・コントローラーはMainLoop内に処理ルーチンが内包されていた。 

WS001672.JPG

WS001673.JPG

FTMのカウントデータは、周波数の確定フラグが立った時点でPitch/VolumeValueを生成する処理ルーチンに転送され、計算が始まる。 

今回の改良では、今までMainLoop内に展開されていたPitch/Volume Valueの処理ルーチンをサブルーチン化し、

WS001662.JPG

WS001663.JPG

FTMルーチンから直接これらを駆動することで、同一のタイミングで処理が開始されるようにした。
posted by Yasuski at 16:07| LaVoixski

2019年02月14日

出力波形のパラメーターを修正する機能を追加する

仕込んだ音色の修正を可能にしたいところではあるが、機能の実現にはパラメーター×チャンネル分のレジスタが必要で「Pot周り」の操作系が物凄くややこしくなってしまう。

そういえば、数年前にTeensy3.2の環境でメモリーバンクに直接アクセスして編集を行う機能を実装しようと目論んだが、タスクが重くなり過ぎて諦めたことを思い出した。 現在も既に処理限界に突入しそうな状況なので、これは無駄な改良と思える反面、将来的に採用するMCUの能力が上がった場合に備えて動作を実証する意義は否定出来ない。

いろいろと手段を考えた末、タスクの重い計算をロータリーエンコーダーのセンシングを行うルーチンに分散させること思い付き、リアルタイムで波形合成の編集を行う機能を実装することが出来た。 

Screen Shot 2019-02-14 at 2.02.03.png

サンプリングレートと連動して計算を行っていた時は、オーディオクロック毎に浮動小数点演算のタスクを強いられていたのだが、この場合は数値の確定後に計算をスルーできるのがミソだ。

パラメーターが増えた分だけ運用法が複雑になってしまったが、プリセット状態で演奏を行う場合は全く影響はない。

Screen Shot 2019-02-14 at 2.00.02.png

パラメーターの記録は、各々のアドレスで行うことが出来るようにした。 アドレス16番の波形編集専門チャンネルは不要となったので廃止。 同じアドレスには新たに記録可能なバンクを再構築している。

Screen Shot 2019-02-14 at 2.03.33.png

パラメーターをアサインした場合にヴォリュームがゼロになってしまう弊害が露見しているが、対策として予め存在するデータにロータリーエンコーダーの値を足す方向でプリセットを調整できないか検討を始めている。

追記:

波形選択モードで何故か破綻が発生した結果、ロータリーエンコーダーでパラメーターの差分を扱う計画は失敗に終わった。 これは、閾値がオーヴァーしてしまうために発生するトラブルだと思われるが、現状ではメモリーの仕様が93%超えとカツカツで動作に支障をきたすレベルに到達したため、リミッターを追加しても別件で不具合が発生する可能性は否めない。 ということで、残念ながらこの計画は断念することになった。

実際に編集機能を運用してみたが、差分で操作を行わない仕様であってもあまり違和感を感じなかった。 ただし、音声編集モードに入って編集を行ってしまうと、「電源を落として再立ち上げするまでは元の状態に復帰できない問題」が発覚している。

「電源を落とせば現状に復帰する」というのはあまりに前時代的で不便なので、シーンメモリーにバッファーを追加しよう。

追記2:

バッファーの設定を勘違いしてマヌケなことをやっていたので修正を行った。

Screen Shot 2019-02-14 at 18.20.36.png

要は、データを読みだした時の値を規定値として保持するためのレジスタを追加したということ。 ポットによっては、ローカルにこの手のバッファーを持っているものもあるが、今回はmicroSDからデータを読みだすタイミングでバッファリングを行い、アルペジエーターの起動スイッチがオフの時に保持したデータをポットのレジスタに戻す形で処理を集約している。

Screen Shot 2019-02-14 at 18.23.50.png

編集時に元の音に復旧させる場合に問題があって、トップスイッチのオン・オフは演奏モードの再現を優先するためにリセットにともなって再生アドレスが変わってしまう。 このズレから復帰する方法は簡単で、アルペジエーター起動スイッチ=トップスイッチのオン・オフを行った後にチャンネル選択ノブを1クリック動かして元に戻すタイミングでローカルバッファーのデータを読み込ませればよい。 事前に混乱を避けるには、予め演奏モード上で目的のチャンネルを設定するとよいのだが、2つしかないノブにすべての機能を集約する分、常にアクセスできる情報は2系統となってしまうわけで、インターフェイスの設定はなかなか難しい。

遊んでいるアルペジエーターのスレッショルド設定チャンネルを音声編集用として利用する方法もあるが、それを実現するための具体策はまだ持ちあわせていない。

追記3:

リセットワークをサブルーチン化すれば、UpperKnobの状態=mode2によってリセットを行う対象を切り分けることが出来そうだ。
posted by Yasuski at 02:47| LaVoixski

2019年02月13日

Distortion / LevelShifter の項目を編集可能にする

Distortion/LevelShifterをオン/オフするスイッチをロータリーエンコーダ下側のパラメーター#5・6番に追加した。

WS001651.JPG

選択したモードによって、ポットの機能を切り替える。

本来は、音色の編集を行った後にレベル管理やディストーションの調整を行うのが合理的なのだが、旧仕様では予め設定がプログラム上に仕込まれているために、音声出力をベストな状態に追い込めなかった。 今回の改変ではパラメーターの調整を手元で行えるようにフィジカルインターフェイスを追加して、出音を確認しながらエフェクトの調整が行えるようになった。

WS001650.JPG

コード上に記述したスイッチの状態を単純に切り替えていたのを、ファイルから読みだしたデータを元にオン・オフを判定する構造に変更している。

出力に非線形な効果をもたらすディストーション・エフェクトとレベル管理を行う項目は、音色に与える影響がことの他大きいのだが、固定パラメーターに合わせて直感的に音色の設定を行うのは大変難しい。 今回の改良によって手動で試行錯誤を行いつつシーンメモリーも可能となる予定だ。

WS001653.JPG

情報の量は知れているのだが、32項目×2と結構な量のファイルを取り扱うことになるので、凡ミスによるバグの発生が懸念される。

WS001653.JPG

データの記録はパラメーターの調整を完了した時点でポットを長押しして行う。

無事コンパイルは通したが、稼働状況は不明。 リザルトは実機にプログラムを書き込んだ明朝以降に判明する。

追記:

追加した機能の動作を確認、メモリーの読み出しも正常に行われている。 実際に運用してみると、Distortionの切り替えは問題なく行えていたが、levelShiftの有効性に?が出た。 これは、ハード側の不具合、もしくはチューンの失敗の可能性が高く、回路の精査が必要になった。
posted by Yasuski at 04:32| LaVoixski

2019年02月12日

Pitch/Volumeの処理を分離するために、FTM3を起動する

テルミンのPitch/Volumeアンテナは、要求される動作領域のスケールが異なるために、単一のタイマーによってValueを計測する場合は「どちらかを犠牲にして」サンプリングレートを決定する必要がある。

現時点のFVCはVolume側がスムーズに動作するレートを優先した分周率を採用しているのだが、遊ばせているFTM3にタスクを分散させることによって、それぞれの用途に合わせたサンプリングレートを選択した運用が可能となる。

WS001647.JPG

例のごとく、実験前に動作の保証はないのだが、コンパイルだけは通すことが出来た。

WS001648.JPG

端子の処理は、pin#23に接続されているVolumeAnt側の出力をpin#14にブリッジすれば良いので、明日の朝一番に実験を行おう。

追記:

実験の結果、ヴォリューム側の信号がピッチ側に漏れる謎現象が発生した。 

何故か、ヴォリューム側の動作がピッチに影響してしまう。 確認のためキャリブレーション・モードでオシレーター毎の素の挙動を確かめてみたが、ピッチ側では両手の動きがダダ漏れな一方、ヴォリューム側ではピッチの影響が排除されていた。

この状況から推測されるのは「入力信号の物理的な干渉」で、基板の配線を変更せずにPINの機能を殺して信号をブリッジしているつもりが、モロに影響を受けてしまったようだ。

何れにしても現状では全く使い物にならず、原因究明のために改めて基板の配線を変更しなければならない。別にテスト用の基板を用意してもよいが、FTM3の動作確認を行うためだけに基板を新調するのは無駄なので、これを機会にテストベッドを新調すべきなのだろう。 

試しにFTM3への接続を切った状態でFTM0のみの試験を行ってみたが、残念ながらピッチの安定度が改善することはなかった。

posted by Yasuski at 01:37| LaVoixski

2019年02月10日

Modulus 演算の速度を向上する

Webで発見した処理速度向上のためのTipsをヴォリュームコントロール関連の制御回路に導入した。

計算例では、ARM Cortex: 390 cycles が ARM Cortex: 384 cycles に改善されるという微々たるものではあるが、Transition系のヴォリュームは繰り返し演算を行うので、計算量はVoice分だけ加算される。 タイトなリソース情況に於いて、それが少しであってもクロックサイクルを稼ぐのが正道といえる。

Arduino上で C99 fast data types / uint_fast16_t の使用が有効かどうか心許なかったが、とりあえず必要な場所に導入する分に於いて問題は発生しなかった。

WS001645.JPG

uint_fast16_t の導入に併って %(modulus) 演算 C = A % BC = A - B*(A / B) に変換すると、速度の向上が達成できるということで、Transitionコントロール周辺のコードを改変した。

WS001646.JPG

確かに、左手の動きにともなって発生していた妙にザラついた音が消滅して動作がスムーズになった感触があり、速度向上のTips導入に成功した模様。
posted by Yasuski at 20:05| LaVoixski

ロータリーエンコーダのデータ更新について

Muteスイッチ周りで発生していたバギーなLEDの点灯パターンを修正しつつ、

Screen Shot 2019-02-10 at 1.45.52.png

ロータリーエンコーダの入力状態を参照→レジスタにアクセスというルーティンをスキップする仕掛けを組み込んだ。 

WS001640.JPG

特にレジスタから受取ったデータを加工するModuloや除算を行うルーティンが曲者で、これらの計算が元データが変化していない状態であっても常に規定された参照時間毎に行われていた。

WS001644.JPG

今回は、ロータリーエンコーダの状態の変化を感知する条件分岐の後にbreak;を組込んで、

WS001642.JPG

無用な計算をスキップする仕組みを追加したが、今のところ体感的な変化は実感出来ていない。
posted by Yasuski at 03:20| LaVoixski

2019年02月07日

出力のミュートを行う仕掛けを実装する。

先日行ったライヴでも感じていたことなのだが、テルミンのようなオープンハンドで音が出てしまう仕様の楽器にはミュート機構が必要だ。

出来ればスムーズにフェードイン・アウトが出来る機構を組み込みたいところだが、MCUの処理能力がそろそろ限界なので、とりあえずは単純に音をぶった切る仕掛けを考ることにした。

WS001639.JPG

用法としては、弱音環境でスイッチングを行えばよいのだが、

WS001637.JPG

左手の減衰値ゼロの場合にパラメーターの操作を受け付けない仕様が若干の問題となってくる。

インターフェイスのアサインは下段ロータリーエンコーダのCase 4:に行った。 通常は黄色のミュートスイッチとして機能するが、ピッチ編集モード下でのみ無点灯なピッチ設定ノブに切替わる。

消音の仕組みは単純で、Wavetableから読みだしたヴォリュームカーヴのレジスタに有無を言わせずゼロを代入する。 

これで出音は強制的に消滅するが、音声を出力している間に操作を行った場合は盛大にポップノイズが出てしまう野蛮な仕様だ。

しかも、現実に音量を制御するパラメーターにゼロをアサインすると、何故かフリーズが発生するという怪し気な挙動が見られるのが末期的で、そろそろMCUの処理限界が見えてきたようだ。

音響機器の視点で考え得る常識的なミュート機構の仕掛けとしては、FETに時定数をつけた簡易型のアナログスイッチをまず思いつくのだが、それっぽいものをコードで実現する手段として音声データにカウンタで増減を行う数値を掛け合わせればよさそうだ。 ただし、この用途には周りの動作が全て停止してしまうdelayは使えず、代わりにバックグラウンドで計数を行う仕様のMetroかChronoで組み上げた仕組みを検討する必要が出てくる。

ノイズレスなスイッチの実現に関しては後々考えるとして、とにかく最初に行わなければならないのはレジスタの設定で、この部分に関しては先日製作した出力選択スイッチの構造を流用することにした。

まずはパラメーターを一時的にストアするためのレジスタをArpeggiatorを配置した5チャンネル分とSequencerの8チャンネル分の合計13ch用意しなければならない。 が、スイッチの用法を考えた場合、他のパラメーターのようにレジスタに保持した制御データをSDカードに記録する必然性は低いと思われる。 

SDカード関連のコーディングが必要なくなったものの、出力にArpeggiatorが絡んでくる複雑な構造の箇所に、新規にレジスタを展開するのはそこそこ手間のかかる仕事であった。 

WS001638.JPG

悩まされたのは、Arpeggiatorの起動レベルを設定するセクションが絡むフリーズで、消音後にこのセクションにアクセス(上側ノブの case 9: に設定)した途端に消音状態のまま出力がロックされてしまう。 しかも、これが単なるフリーズではなく、発音やセンシングなど楽器としての機能が生きているにも関わらずMute状態からの回復が不可能になる点が面妖だ。

トラブル回避の対策としてスイッチをアサインしているインターフェイスのアドレスを変更したり、case 9: に関連する機構そのものを抹消したりと解決法をいろいろと試してみたが、最終的にはVolumeValueを処理しているルーチンの内部に、データ・セレクタを展開することでなんとかバグに対応することができた。

追記:

スイッチの内部にChronoを使ったフェードイン/アウト機構を仮導入してみたが、あまり御利益が無い割に謎のフリーズ案件が頻発しはじめたため、この件は失敗と結論した。 ロータリーエンコーダが絡む部分は頻繁にスキャンを行っているが、それによって生じた不具合と推測している。 

そろそろMCUの処理限界が近いと思われるので、これからは低難度の運用でなんとかなるレベルの不具合は無視してもよいだろう。



posted by Yasuski at 15:55| LaVoixski

2019年02月06日

TransitioinControlのシーンメモリーを追加した

WS001636.JPG

ついでに、起動時にsdCardから設定を読み込むステップをLEDの点滅で表示する機能を追加している。

WS001635.JPG

立ち上げ時に下側のロータリーエンコーダに割り振られているcase4のアドレスが現状ではTransitionとなっているが、これはシーンメモリーの機能を考えると少々使い勝手が悪いかもしれない。
posted by Yasuski at 17:01| LaVoixski

2019年02月05日

音源の改良、Arpeggiatorのサブルーチン化とSequencer使用時に発生するピッチの変動問題について

昨日からオシレーターのミックスデータを組み直しているが、オーヴァーレベルによって稼動域が極端に狭くなるディストーション系プリセットのレベル調整が難しい。

現状は、どちらかというと「ソフトに歪む」設定が手薄なので、その辺りの感触をターゲットに音色のデザインを進めていく。

特に仕込み領域のアドレスはツールによる書き換えが必須(ローカルで変更が不能)なので、この部分の調整は手堅く行う必要がある。

現在は暫定で、sin8波、cos4 波、半波長sin、鋸波、三角波、矩形波、ヴァイオリン風の波形 の17種類のWavetableをエントリーしているが、倍音構成が異なる基本波を展開するのが今後の課題だ。

C#SVの規格変更によってArpeggiatorの高域側の設定がズレたので、試しに動作させてみたところ、予想通り不具合が発生している。 動作を修正するには、楽器を分解してデータが格納されたmicroSDを取り出す必要があるが、プラスドライバーを使って側面パネルのネジを4個も外す作業工程を熟すのは一寸億劫に思える。 今後のサービス性を考えた場合、USBから一括書き換えが行えるツールがあった方が便利そうなので、ファイルを一気に書き換える仕掛けを作ることにした。

WS001634.JPG

一方、このところの懸案だったSequencer起動時に主旋律のピッチがヨレる現象は、ソフトウエアの構造を合理化しても解決出来る兆しが見えない。 以前は有効だった筈の制御ルーティン側のインターラプト・マスクを調整してみたが、こちらも上手く行かない。 システムに実装している簡易なシーケンサーは「オマケ」みたいなものなので、これの完成度に拘る必然は無いと思っているが、如何せんピッチが揺らぐのは気味が悪い現象なので、引き続き調査を行うことにした。

その後、Sequencerモード下で発生する「ピッチのよじれ」を巡っていろいろと実験する過程でArpeggiatorのサブルーチン化を行ったりしていたが、

WS001632.JPG

怪し気に見えるmetro周りのコードを解析しても直接的な原因を特定出来ず、肝心のトラブルは一向に解決しない。

症状の発生するタイミングが、Sequencerモードにおけるクロックの表示=空色にLEDを発光させた時だったので、極性を確定するためにLEDのアサインを反転してみたが、何故か状況は変わらず「空色が発色するタイミング」でピッチが上昇する方向によじれている。 

以上の点灯実験から、原因はコードではなく「物理」にあるのではないか?という疑問が生じることになった。

つまり、LED周りの回路が怪しいということで、試しにオレンジの発光を止めて別の色味に設定をやり直したところ、件の「よじれ」は消滅した。

WS001633.JPG 

結局のところ、ピッチは空色のクロックに反応していたのではなく、オレンジの発光に反応して低い方にドリフトしていたということになる。 クロックの点滅表示から連想して、「クロックに関係するルーティンによって負荷が発生している」という予断を行った結果、ドリフトの方向を間違うことになった。

今回のケースでは、おそらく回路上の問題(消費電流もしくは配線の取り回しによる)が、オシレーターのピッチに影響を与えていたのだろう。 予想外の物理的な要因で問題が発生した結果、対策が無用に混乱する典型的なパターンを踏襲した形といえる。

現状のハードウエアは以前よりも程度がマシになったとはいえ所詮は掘っ立て小屋っぽい状況なので、そろそろこの環境を卒業すべき時期なのかもしれないが、ひとまずはソフトウエア側の合理化からこなして行きたい。

WS001631.JPG
posted by Yasuski at 16:31| LaVoixski

2019年02月04日

Sequencerの音域を拡張する

利便性を考慮して、Sequencer の音域を4octまで拡張した。

WS001629.JPG

追加した高音域は "C#SV" の規格を改めて、高域側の表記を C3 = 1, C3# = 1#  D以降は D = 2, E = 3, F = 4, G = 5, A = 6, B = 7, といったトラッドな音階表記に近いスタイルで行うことにした。

WS001630.JPG

システムの都合上、音階の表記は1バイトに限定されるため、C4から上の音域は C = 8, D = 9, E = 0, F = h, G = i, A = j, B = k, C5 = l, と変則的な構成となっている。
posted by Yasuski at 00:48| LaVoixski

2019年02月03日

新しいWavetableのアップロードを行う

Thereminに新しいWavetableを読みこませて起動したところ、音源の具合が悪く妙なノイズが発生するようになった。

これはあからさまに怪しい現象なので、データ長を調べる仕掛けを組み込んで解析すると4095stepと表示された。本来は4096stepあるはずのデータが1bit分足りない。

この欠損によってノイズが発生している公算が高くなったので、読み込ませるデータそのものを調べたところ、怪しいところは発見できなかった。

WS001622.JPG

Screen Shot 2019-02-02 at 14.27.04.png

他に想定される怪し気な場所はデータをmicroSDから読み出すルーチンだが、データの区切りを判定するのにスペースとカンマを用いているところが疑わしい。

WS001623.JPG

「スペース」を読み出せない場合はカンマで区切るのが正解だが、読み込ませるデータを検討したところ、末尾にはカンマが存在していなかった。

WS001624.JPG

つまり、書き込み時にデータの末尾に「スペース」を挿入し忘れていた場合、データが字足らずになってしまうということで、これがノイズが発生する原因となっているようだ。

「スペース」は視認性が悪いので、安全を期するのであれば、データの末尾にカンマを書き加えたほうが良いだろう。

WS001625.JPG

データを修正してmicroSDに書き込んでテストを行ったところ、ノイズの問題は解決した。

Screen Shot 2019-02-02 at 16.00.16.png

音源が抱えていた問題を全面的に解決出来たのは非常に喜ばしいことだ。

追記:

microSDカード上に記録した「出力波形をセレクトするデータをアップロードするためのファイル」に"ゼロ"を書き込もうとすると、何故か56や54が記録されてしまうという謎のバグが発生、該当するチャンネルの出音がノイズになってしまった。

残念ながらバグが発生する要因を特定できないために、今回は根本的な解決策を発見出来ず。 対症療法としては"0"を扱わないという消極的なものしか思い付けなかったが、これによってひとまずトラブルの発生は回避出来た。

また、運用試験の過程で新たにアルペジエーターの下降再生モードの選択が無視されるバグを発見した。 

こちらの原因は、swich()回路内にbrake;の配置を忘れるという何時ものパターンで、該当する文言の追加によって問題を解決することができた。
posted by Yasuski at 03:33| LaVoixski

2019年02月01日

GNU Octave

Wavetableに書き込む波形生成ソフトウエアに、フリーのGNU Octaveを導入することにした。

Webで波形生成ソフトウエアとしての使用法を検索したところ、懇切丁寧にメソッドを解説している人を見つけることができた。



平易な英語により、GNU OctaveでDSPプロセッシングを行うための基本的な操作法を5回シリーズでレクチャーしてくれている。

このレクチャーを参考に、サイン波を加算する方法でWavetableを生成するコードを書いてみた。

WS001615.JPG

手法は単純で、サイン波生成の要素を羅列して倍音を構成している。 データのステップは12bit×12bit。Violin波形の場合はSinとCosを交互に配置しているが、SawToothの場合はSinのみ、Squareの場合は、奇数次倍音のみをエントリーしている。 生成した波形はCSV形式でファイルアウトすると同時に、データーをWavFileに変換して音色を確かめることが出来る。

多少の手間が掛かるが、倍音毎に音量や位相の設定を行って、波形を構築していく。

WS001605.JPG

まず、Webの記事を参考に、Violinの波形を再構築した。

プロットした波形は非対称の矩形波といった趣だが、割と良い感じの音色だった。

WS001606.JPG

波形データを要素の集合として展開することも出来る。

WS001619.JPG

こちらは、13次倍音までを合成した鋸波

WS001618.JPG

データはroundによって整数に丸めてある。

WS001620.JPG

これは矩形波。 奇数次倍音を合成して生成する。 倍音の数を制限して柔らかめの音色にチューニングしてある。

WS001621.JPG

プロットでは不明瞭なデータの幅をこの画面で確認する。 素データを乗算した後にオフセット値を加えて、最適値に調整している。

WS001611.JPG

割と音色を気に入っていたが廃版としていた半波長のサイン波を再構成した。

WS001612.JPG

これは波形が単純なので、最適化の調整は楽だ。

WS001613.JPG

roundで丸められた部分を拡大している。

WS001614.JPG

こちらは、鋸波の拡大図。 波形の状態を目視できるので安心。

WS001616.JPG

結局、8倍音までのWavetableを生成するツールを書いた。

コードには、鋸波・矩形波・半波サイン・サイン・コサイン混成波を合成するテンプレートを実装している。 三角波の合成パターンを追加するかを悩んでいるところだが、半波サインのキャラクターが似ているのでこれは不要かもしれない。

ツールには、CSVの書き出しと同時にWavフォーマットの音声ファイルを出力する便利機能を実装している。
posted by Yasuski at 10:14| LaVoixski