2020年12月30日

Chromatic Tuner の製作

Chromatic Tuning System に関して、ある程度の実用性が確保できたので、ここに開発時に行った試行錯誤の備忘録を記す。

まず、システムを稼働させるタイミングを設定するスイッチの構築からプログラムの開発に手を付けたものの、

Screen Shot 2020-12-27 at 8.19.36.png

パッセージの速度に反応する仕組みは実際の運用が難しく、当初の思惑からは外れて稼働時間の設定を重視する方向に機能が変更されることになった。

スイッチは、Mills() を使用してオン/オフの間隔を計測する構造で、

Screen Shot 2020-12-30 at 11.59.28.png

VolumeDetector から出力される値から起動ポイントを観測し、設定された時間の長さでフラグを立てる。

このスイッチのトリガーとなる信号は VolumeDetector のサブルーチン内で生成される。

Screen Shot 2020-12-30 at 12.00.41.png

トリガーが起動する パラメータ の設定項目は UpperEncoder の Mode 9 内に増設した。

Screen Shot 2020-12-31 at 8.35.35.png

Screen Shot 2020-12-31 at 8.35.20.png

トリガー出力の判定は、サブルーチン PitchDetector のインターラプト・マスクのエリア外となる末尾で行い、サブルーチン ChromaticTune に分岐する。

Screen Shot 2020-12-30 at 12.01.00.png

ChromaticTune では、音程の判定を行う前に PitchValue から Root C を基底とした 7 octave の領域を測定し、Switch にて分岐を行う。 

Screen Shot 2020-12-30 at 11.59.10.png

分岐先では更に入力値を12音の数値と照らし合わせてピッチの判定を行っている。インターラプト・マスクを掛けられた処理を終了した後、

Screen Shot 2020-12-30 at 11.59.55.png

音程の暴れを防ぐために導入したエンヴェロープ生成回路、サブルーチン EG2 にジャンプする。

EG2 では、ChromaticTuner 起動時に発生するピッチの段付きをChrono によって時定数を与えられた LPF を使って軽減し、音程がスムーズに移行するように信号の加工を行っている。

Screen Shot 2020-12-30 at 12.00.08.png



posted by Yasuski at 14:38| LaVoixski

2020年12月27日

クロマチック・モードの実装を考える

TaxiDriverのサントラを聴いていて思い付いたのだが、テルミンで速いパッセージを演奏した場合に、自動的にスケールが設定できるような仕掛けを作ってみたくなった。

スピードを判定する時定数の設定が難しいのだが、緩やかなスピードの演奏の場合には、スケール機能をオフってレガートで演奏、ピッチの速い変化を検知した場合に、選択したスケールを演奏するという仕掛けを作動させる。

フレーズのスピードをセンシングするのが右手のピッチアンテナではなく「左手側のヴォリュームアンテナ」というのがこの仕掛の勘所で、つまりスタッカートを検知した場合に、Pitch側のスケール機能が発動するという仕様だ。 

Screen Shot 2020-12-27 at 8.19.36.png

要は、センシングエリアにスレッショルドを掛けた左手側のVCA信号をトリガーとし、それが発動する間隔を測定して既定値よりも短い間隔のパルスを検知した場合にクロマチック機能を作動させるのだが、しきい値を設定するUIの設計が難しい。

実験の結果、入力の状態が低止まりした状態(この場合の入力はプルアップしていて、スイッチはプッシュ・オフの設定)で、出力がオンに固定されるダメなところ(立ち上がりの微妙なレベルでクロマチックモードが起動する)が判明しているが、



実際には「ほぼ音が出ていない状態」なので問題はなさそうだ。 もし、音の段付きが気になる場合は、目玉LEDの点灯とクロマチックモードを起動するフラグを&&して、強制的にオフにすればよい。

トリガーが発動する値を固定値とする場合、実際に演奏しながらまずはその値を探ることになるのだが、トリガーの間隔から判定を行うための時定数はマニュアルで設定できるようにしたい。これは、大凡で200ms前後が最適値と思われるが、タイム感には個人差が存在する故マニュアルで設定を行うのが正解であろう。

ピッチをクロマチックにトランスポーズする機構は、まずCをルートに設定してオクターヴ毎にピッチ・エリアの判定を行った後、各エリアにSwitchして、そこで12平均律の判定を行い、その返しから別のSwitchを使ってピッチデータの出力を強制的に12平均律に固定する方法を考えている。ifを使わずにSwitchで条件分岐を行うことで総当りを回避する仕掛けなのだが、、、これで上手くいくのだろうか???

UIはクロマチックモードの稼働時にLowerLEDが紫もしくは赤に発色する仕様が判り易いか。

出来上がったもの(12月27日の現時点で動作確認は未了)は野蛮な構成のプログラムとなってしまったが、

Screen Shot 2020-12-27 at 1.29.03.png

これは鍵盤みたいなものと考えれば良いのだろう。

Screen Shot 2020-12-27 at 22.45.59.png
posted by Yasuski at 03:27| LaVoixski

2020年12月24日

OLEDを使ったUIの実装を検討する

OLEDを使った波形編集時の表示を考えている.

oled128x128.jpg

表示を行う手段として、

1)リアルタイムで出力信号を拾う 
2)編集データを反映させて描画を行う

の、2つの方式を思い付いた。

編集データを波形の描画に反映させる方式は、処理に負荷が掛からない点が良い。 
一方、動作が判り難いTransitionの状態等の動的な変化をリアルタイムで表示することが課題となる。

具体的にはオシレーターに設定された各ヴォリューム参照してそれを表示することになりそうだが、UIの設計にセンスが問われる。 最終的にコードを統合するにしても、画像処理を行うパートのみをまず開発した方が混乱が少ないだろう。 別に表示専用のMCUを準備して処理を分散させる場合には、通信ラインの確保が必要となる。

残念ながら、現状ではMCUの端子が足らず、通信に割く余裕がない。 LEDの駆動をPWMに変更する予定なので、スタティックな信号を対応する端子から取り出す案はアウトだ。

信号の配置が可能な空き端子を整理するために接続端子の整理を行っていたところ、Teensy4.1に対応させたつもりがTeensy3.6のpin配置でLEDをアサインしていたことが発覚した。 PWMに対応していないD38ではLEDの発色が行えないため、LEDの配線をD38からPWMの出力が可能なD33にスワップした。

諸般の事情を考慮した結果、OLEDディスプレイへの対応を踏まえて、SPI1を活かす形で端子の配列をやり直すことになった。

LaVoixski41_1_card.png

薄緑のラベルがSPIが割振られる端子。 D0/1、D26/27を接続する。OLED側の残る2端子、DCとRSTは、D18/22/23/41の何れかにアサインすれば良い。

IMG_0219.JPG

一方、OLEDの表示に関して行っていた調査の過程で発見した記事から、ロータリーエンコーダーを接続した端子の状態の変化を検出して、millis() を起動し、Timer の代わりに使用する手法を知った。 当方が現用しているClickEncoderは、Timer1 を使って10ms毎に状態をチェックする仕様なので、やっていることに余り変わりはないのだが、Timer1 が使用出来ない他のMCUにコードを移植する際には millis() を代用する手段が使えそうだ。

ある程度データが揃ったので、とりあえずライブラリをいじってTeensy4.1に設定可能なOLEDモジュールとの通信回線をオリジナルのSPI0からSPI1に変更してみた。

Screen Shot 2020-12-24 at 4.16.57.png

ライブラリの修正箇所は、接続端子の変更の他、SPIをSPI1に、LPSPI4をLPSPI3に書換えている。

テスト用に準備されたスケッチは、エラーを発生させることなくコンパイルが完了したが、メモリの使用量が気になる。

Screen Shot 2020-12-24 at 4.27.28.png

次は実機を繋いで実験してみよう。

基板の方は、D27pinへのアクセスを可能にする。

Screen Shot 2020-12-26 at 4.37.53.png

ちなみに、Teensy4.0ではSPI1に対応不能なことが判っている。

teensy40_pinout2.png
posted by Yasuski at 05:59| LaVoixski

2020年12月17日

HighSierraのアップデート時にGPU通電のキャンセルが無効化してしまった場合の対処法

MBP2011y上の故障したGPUの通電を阻止して、起動時に発生するスタックの回避を行う作業の流れを以下に示す。

一連の作業は、MacRumorsに公開された記事を参考にしている。

Screen Shot 2020-12-16 at 18.53.09.png

1)SMC Reset
  シャットダウン時に、leftShift + Ctrl + Option + Power for about 15 secs
2)PRAM Reset
  起動と同時に、Command + Option + P + R を押し続けて起動音を2回確認
3)Boot in Safe Mode
  シャットダウン(強制)後に、Command + S で再起動。
4)Manually type 後にリターン
  nvram fa4ce28d-b62f-4c99-9cc3-6815686e30f9:gpu-power-prefs=%01%00%00%00
5)Manually type 後にリターン
  nvram boot-args="-v"
6)Manually type 後にリターン
  reboot
7)再起動時に修復モードを選択、Apple Logo が確認できる
  Command + R
8)メニューバーからUtilitiesを選択して、Terminal を起動
  
9)Manually type 後にリターン (何故かコマンドが受け付けられず)
  csrutil disable
10)Manually type 後にリターン
  nvram fa4ce28d-b62f-4c99-9cc3-6815686e30f9:gpu-power-prefs=%01%00%00%00
11)Manually type 後にリターン
  nvram boot-args="-v"
12)Manually type 後にリターン
  reboot
13)Boot in Safe Mode
  Command + S で再起動。
14)Manually type 後にリターン
  /sbin/mount -uw /
15)Manually type 後にリターン
  mkdir -p /System/Library/Extensions-off
16)Manually type 後にリターン
  mv /System/Library/Extensions/AMDRadeonX3000.kext /System/Library/Extensions-off/

この16番目の操作の結果、“Directory not empty” と表示されて、操作が撥ねられるケースが報告されていて、今回も同じ現象を確認している。

この場合の対処法は、該当するファイルの強制消去で、、、

17)Manually type 後にリターン
  rm -rf /System/Library/Extensions-off/AMDRadeonX3000.kext
18)Manually type 後にリターン
  touch /System/Library/Extensions/
19)Manually type 後にリターン
  reboot

現状では、verbose mode で起動するので、これが気になる人は、、、

20)修復モードを選択して起動、Apple Logo を確認
  Command + R
21)メニューバーからUtilitiesを選択して、Terminal を起動

22)Manually type 後にリターン
  nvram boot-args=" agc=0"
23)Manually type 後にリターン
  reboot

以上で作業は完了。

posted by Yasuski at 04:06| AudioElectronics