2018年06月22日

Open.Theremin@アンテナエクステンションの試作

試験的に演奏を繰り返すうちに、小型筐体のテルミンが持つ共通の問題、アンテナ間のクリアランスが気になってきた。

そこで、アンテナ基台から水平に伸びるロッドの部分をグランド電位に接続したスリーブで覆うことを思いついた。 スリーブは内部に格納した水平部分のアンテナに巻きつけたグラステープで保持・絶縁を行っている。

IMG_8073.JPG

問題は、実質的なアンテナ長が垂直部のみに減少してしまうことで、周波数のドリフトが気になる。で、結果は予想に反して、周波数のレンジが低い方にドリフトしてしまった。 アンテナ端子がグランド電位に近くなることでトータルの静電容量が増えるのだろうか。 ドリフトの量がトリマーでリカヴァー出来る域を超えて仕舞ったので、リファレンス側のオシレーターに22pFを追加して再度周波数のレンジを合わせこむことになった。

調整後、試験的に演奏を行ってみたところ、残念ながら低音域でセンシングが「荒れる」現象を観測できた。 このままでは実用がキツイと判断して、とりあえずアンテナを伸長するためのエクステンションとして、チタンパイプの切れ端にハットフランジを圧入したパーツを製作した。

エクステンション追加時には若干動作の安定を確認できたが、何故か素の状態が一番安定しているようだ。 これは、グランドポイントを取る場所との関連も考えられるので、出来ればアンテナ基台直近からのラインを確保する方向で構造を再検討したいと思う。

IMG_8074.JPG

現状は、思い付きで現用パーツを細工して構造をデッチ上げた状態なので、次はもう少しマトモな構造の試作品を製作したい。 アンテナ長の問題は、カウンタのデータ幅を調整することでも対応できそうなので、同時にソフトウエア面からの対策も講じていくことにする。 それと、プレイヤビリティーの向上のためにローディングコイルの必要性を感じているが、これの収納場所としてアンテナスリーブが有効と思われる。 パーツの外径が問題となりそうなので、事前にサイズ合わせを行っておこう。

追記:

シッカリとしたアースポイントを取った結果、動作が安定した模様。

IMG_8080.JPG

敗戦間際のドイツ軍の戦車みたく、襲い来る問題に対処するために筐体がどんどん改造されて逝くいつものパターンに嵌っているような。

一方、ソフトウエア側でもレンジの問題を何とか出来ないか試行錯誤を続けている。

まず、ピッチ側の動作を確認するために、周波数の差分をカウントする幅を14bitから13→12と圧縮してみたが、低音域のザラザラ感はあまり変わらず、却って高音側が削られるだけだったので、元の14bitに戻すことになった。

自分のような音域が広い楽器が好きな人はこれで良いが、初心者や声域に近い演奏を目指す人は、演奏のスタイルに合わせて帯域を制限したほうが使い易い楽器になるかもしれない。

データ幅を14bitで運用した場合、大凡ではあるが余裕で6oct.をカヴァー出来はするものの、その一方でピッチの制御はかなり難しくなる。低域が怪し気なのは、どのデータ幅でも一緒なので、自分の場合は迷わず14bit制御を選択する。

事前の調整がキモな楽器だが、これの自動化は難しいと思う。 

ハードウエアの製作にかまけていてついつい忘れてしまうのだが、そもそもの間違いは機材が山積みにされたダンジョンでこの楽器のセットアップを行うことなので、原野とは言わないが一度だだっ広くて何も無い空間でテストを敢行すべきだろう。 

これは、撮影用のカメラを駆動するスイッチング電源をアンプの直近に置いただけでチューニングが発狂して仕舞うような代物だということを先ほど思い知らされたばかりだ。 
posted by Yasuski at 20:46| open.Theremin

2018年06月21日

Open.Theremin@テルミンが完成した時の恒例行事



OverloadModeは図に示すようなポジティヴサイドのサイン・カーヴをオシレーター群の出力に乗算して音量を個別にコントロールするTransitionModeの一環だが、

controlSignals.png

全ての出力を減衰無しで加算することで、トータル出力の波形をクリップさせている。 このTransitionの間隔=オフセット値はロータリーエンコーダーで調整することが出来る。

WS000903.JPG

つまり、ピークポイントの間隔を疎にすることで、ある程度は波形のクリップを抑制することができるが、この辺の使い勝手は感覚的に掴んでいくしか無いだろう。

posted by Yasuski at 16:25| open.Theremin

Open.Theremin@DACからCVを取り出す

オシレーターをチューニングするために必要なマルチターンなVRは単価が最低でも1kはする代物で、出来れば製品化時に使用したくない製品なんだが、これを排除するには諦めていたMCUの内蔵DACからの電圧コントロールを実用化する必要がある。

ということで、プログラムの変更を検討しているのだが、完成している楽器をイジってぶち壊すありがちなパターンを回避するために、、、

IMG_8071.JPG

事前調査を別の試作用プラットフォームで行うことにした。

WS001325.JPG

おおまかな変更点は2箇所で、キャリブレーション・モードによるポットの切り替えと、

WS001326.JPG

DAC及びEEPROMにアクセスする項目を追加する。

WS001323.JPG

起動時にDACの出力電圧のプリセットを行った後、Loop内でpot1/pot2をセンシングする通常モード(mode4)に移行する。

WS001324.JPG

スイッチ長押しで、Pitchアンテナのキャリブレーションを行うモード1に移行、pot23aによるDAC出力の変更が可能になる。

WS001317.JPG

スイッチ長押しで、VolumeAnt側のキャリブレーションを行うモード2に移行する。

WS001320.JPG

スイッチ長押しで、EEPROMにデータを書き込むモード3に移行する。

その後、メインプログラムに機能の実装を完了したが、ノイズの影響なのか今ひとつピッチが安定しない。 また、測定を行うまでもなく出音が濁ってノイズが増えているのが明らかだったので、残念ながらDACからCVを取り出す機能の追加は一旦棚上げすることにした。

理由が判然としないところが気持ち悪いが、機能を取り払った状態で再試験を行ったところ、VR単体でCVをコントロールした方が格段に安定している。 原因として処理のタスクが増えたことと、DACからのデジタルノイズの影響が疑われる。

DAC出力でCVコントロールを行う機能とEEPROMにデータを保存する機能は確実に実装できたので、将来的にはハードウエアによる解決も考えているのだが、、、やはりオシレーター系は純アナログシステムで組むのが正解なのだろう。
posted by Yasuski at 12:36| open.Theremin

2018年06月20日

Open.Theremin@波形を観測しながらデモ演奏を行う



将来的には各種出力波形のプロジェクションと共に演奏を行ってみたい。
posted by Yasuski at 17:07| open.Theremin

2018年06月19日

Open.Theremin@波形の解析

AnalogDiscovery2でキャプチャしたOpen.ThereminOnTeensy3.6の出力波形を解析する。

まずは基本波形から。

vlcsnap-2018-06-19-18h43m05s445.png

基本波は普通のサイン波で、これの整数倍の波形をWavetableに登録している。例外的なものとしてサイン波のハーフウエーブ・三角波・ノコギリ波・ランダム等を登録しているが、波形の鋭いエッジがノイズ源となってしまうこともあるために、あまり選択する場面がない。

vlcsnap-2018-06-19-18h43m31s710.png

このシステムは基本的に加算合成方式で波形の編集を行うが、波形が登録されたアドレスにはプリセット14種類、編集が可能な記録バンクが16ch分用意されている。 この波形はプリセットされたもので、任意の波形を選択してレベルを調整したものを加算合成している。

vlcsnap-2018-06-19-18h43m48s632.png

参照波の位相差を利用して、このような波形を合成することが出来る。

vlcsnap-2018-06-19-18h44m16s192.png

プリセット波形のレベル調整は、処理を軽くするためにデータの右シフトという荒っぽい方法で行っているが、何れも開発の極初期段階に直感的にセレクトしたものなので、使用頻度等のフィードバックが得られ次第リファインしたいところ。

vlcsnap-2018-06-19-18h44m23s807.png

このような非常に高い音程の波形を使用する場合、妙な変調が耳についてしまうことがある。

vlcsnap-2018-06-19-18h44m30s567.png

音量の再検討等の運用面のバランスを考慮した改修が必要。

vlcsnap-2018-06-19-18h45m15s972.png

この波形のように、三角波を合成した場合、エッジの効いた「ヒゲ」の部分がノイズに聞こえてしまうことがある。

vlcsnap-2018-06-19-18h23m23s353.png

こちらは、Overloadモードの波形。 これはクリップする前の状態で、Transitionモードとあまり差異はない。

vlcsnap-2018-06-19-18h23m32s088.png

VolumeAntで増幅度を変化させると、このように波形がクリップしてくる。 この段階ではハーモニックエキサイター風のハーフウエーブ・ディストーションに近い波形が出現する。

vlcsnap-2018-06-19-18h23m38s648.png

更に増幅度を上げていくと、波形下側が完全にクリップする。

vlcsnap-2018-06-19-18h24m05s878.png

transitionのオフセット値を調整して、波形の粗密度を設定する。

vlcsnap-2018-06-19-18h24m29s838.png

波形の上下が完全に潰れた形。 波形のエッジをデジタル/アナログLPFで削ぐことで、ノイズ感を減少させている。

vlcsnap-2018-06-19-18h24m45s648.png

上側がクリップした波形。 このような歪の大きな波形が左手の加減によってシームレスに生成されていく。

vlcsnap-2018-06-19-18h25m25s440.png

増幅度を下げると、クリアな音質を得ることが出来る。

vlcsnap-2018-06-19-18h25m54s417.png

上下がクリップした波形とサイン波の下弦の部分を加算合成するとこういった波形になる。

vlcsnap-2018-06-19-18h26m08s662.png

音程が高くなるにつれて、トータルの音声レベルが低下していく。 また、出力コンデンサーに蓄積したDC成分が増大するにつれて、ダイナミックレンジが狭まっていく。 コンデンサーの放電を行うためには発音を中断しなければならない。

vlcsnap-2018-06-19-18h26m19s827.png

各オシレーター出力のピークにオフセットを掛けることで、更に複雑な動的制御が可能となる。

vlcsnap-2018-06-19-18h26m34s997.png

これは、ディストーション・サウンドの典型的な波形。

vlcsnap-2018-06-19-18h26m58s107.png

そこに、いきなりサイン波のスリットが入ってくる。

ここからは、Transitionモードの波形を紹介していく。

vlcsnap-2018-06-19-18h36m48s866.png

VolumeAntと相関させる形でオシレーターのピークポイントをズラすことで、倍音構成に動的な変化を与えている。 コードを演奏する場合は、これにピッチのグラデュエーション効果が加わる。

vlcsnap-2018-06-19-18h36m57s306.png

極限値なので判り難いが、和音の構成を操作している。

vlcsnap-2018-06-19-18h37m12s093.png

発振周波数が高くなった場合の反応。

vlcsnap-2018-06-19-18h37m20s623.png

和音の構成が、、、

vlcsnap-2018-06-19-18h38m10s468.png

段階的に変化していく。

vlcsnap-2018-06-19-18h38m40s293.png

TransitionControlはオシレーターに配分された和音の構成が順送りされる仕組みだが、オシレーター側の設定次第で中間地帯に高い音を仕込むことが可能。

vlcsnap-2018-06-19-18h39m07s340.png

Transitionの最終ポイントで波形は固定される。

vlcsnap-2018-06-19-18h39m25s627.png

TransitionModeを単音で運用した場合、倍音の比率や位相の異なる波の干渉に因って出音の音色が変化する。

vlcsnap-2018-06-19-18h39m42s585.png

音色は段階的に変化したあと、、、

vlcsnap-2018-06-19-18h40m09s085.png

Transitionの最終ポイントに配置されたオシレーターの発音に固定される。

vlcsnap-2018-06-19-18h41m21s318.png

MCUの処理が追いつかなくなると、このように波形の不連続面が発生し、それはノイズとして認識されてしまう。

vlcsnap-2018-06-19-18h42m19s197.png

極端に低いピッチを設定した場合、波形に段差が発生する。

vlcsnap-2018-06-19-18h42m27s890.png

これは、TransitionModeに於いて、PitchMemoryModeで編集した和音構成を展開した時に生じる典型的な例。

vlcsnap-2018-06-19-18h42m35s995.png

このザラつきも、ノイズとして認識される。

vlcsnap-2018-06-19-18h42m43s610.png

処理に割かれるリソースが過大な現状ではadatの送信はかなり厳しいと言わざるをえないが、とりあえずはch数を減らした状態で送信実験を行ってみる予定。
posted by Yasuski at 20:12| open.Theremin

Open.Theremin@OverloadModeを実装する

Overloadモードがようやく稼動状態になった。



音声が出力されなかった原因は複数あって、、、

IMG_8069.JPG

1)DAC周りの回路の配線ミスで、BIAS電圧が供給されていなかった。
2)そのうえ、GNDの接続も適当で、断線している箇所があった。
3)OpAmpのSOIC/.DIP変換基板が不良品で、接続されるべき端子が浮いていた。

IMG_8070.JPG

と、1/3は自分の所為ではなかったのだが、全体的にアホっぽい原因なのが情けない。

で、ノイズをキャンセルするために追加した機能の所為でタスクがオーバーフローした結果、ポリフォニック動作時に出力がノイズまみれになるという本末転倒な事態が発生していた。

この問題を回避するために、WCKの立ち上がり毎に分けていたDACへのデータ送信を旧来のWavetableを参照してミックスを行った後に一括処理するスタイルに戻したところ、ノイズは消滅し、余録として起動時のピポパ音も復活させることが出来た。

Overloadモードは波形をクリップさせる手前、事前にレベルのプリセットが必要で、作業の1/4は最適値を探りだすために費やされることになった。

posted by Yasuski at 12:18| open.Theremin

2018年06月17日

Open.Theremin@TransitionModeを実装する



VolumeControl系のデータの扱いに関しての備忘録。

音量のコントロールには、Wavetableに記録したサインカーヴを使用する。 データのステップは12bitを基本とし、全体の音量を12bit/トランジションの音量を11bitの分解能で制御する。

周波数ディテクターは、オシレーター出力のデューティーサイクルを16bit幅の周波数カウンターでカウントしているが、Volume側ではその14bit分を扱う。 採取されたValueは最終的に3bit右シフトを行って11bit/FSに加工する。 

WS001303.JPG

この11bitステップで音声コントロール用に準備した1/4波長プラス側サイン波のWavetableを参照した後、結果にLPFを挿入してデータのフラつきを防ぐ。 これが、基本的な音声出力カーヴとなる。

WS001305.JPG

現在設定しているVolume側のウエイト値、EMA_b は暫定で0.33を設定しているが、今後は実際に運用を行って最適化を進めていく。

WS001296.JPG

一方、Transitionコントロールを行うための波形は、中央にピークを持たせたプラス側半波長のサイン波で、ステップ数/分解能が共に11bitのWavetableを参照する。 

WS001307.JPG

このデータを基本として、対象となる各オシレーター分の読み出しアドレスにオフセットを掛けたものを準備する。 オフセットの初期値はオシレーター毎に400ステップを設定しているが、これはロータリーエンコーダーよって変更が可能とした。 トータル音声出力のレベル設定は、先に出力した12bit幅の音声出力カーヴとローカルの音声出力パターンを掛けあわせたものを圧縮した12bit/FSで行う。 この出力にも最終段階でLPFによる丸めを個別に行っている。

WS001310.JPG

こちらは、トランジションモードの出力波形とVolume側のオシレーターの相関を記録した映像。



今後、レベル設定の最適化を行う必要があるが、実用上問題がない範囲で可変域を制限した方がよさそうだ。

その後、帰還型のLPFの時定数を変更して、よりデータの変動を抑える方向にチューニングを行った。



モノラル出力の場合には有効性が証明されたが、タスクが重いポリフォニック・モードでは時間切れでノイズが発現してしまうようだ。

以下のサイトをLPF製作の参考にした。

https://www.norwegiancreations.com/2015/10/tutorial-potentiometers-with-arduino-and-filtering/
posted by Yasuski at 23:33| open.Theremin

2018年06月16日

Open.Theremin@新型機がようやく稼動状態になった

開発がスタックしていたオリジナル基板を実装した新型テルミンについて。 

各種時定数の最適化に時間が掛かったが、ロータリーエンコーダーの極性の反転、Volumeコントロールを行う部分のデータ・ハンドリングの修正、誤記のチェック、オーバークロック化に対するカウンタ分周値の最適化等の対症療法を行った結果、曲がりなりにも音が出るようになった。



現時点で、発音されるはずの起動音が聞こえない、メモリー登録時のアラートも同様に聞こえない、断線気味のPitchアンテナ端子による回路の不安定化、調整がクリティカル過ぎるVolumeオシレーター、サブDACの動作不良、、、等々、実際の運用に直結する問題が解決できておらず、現場への投入は無理と判断している。

時間を掛けて調整を行えばなんとか楽器っぽく動作するレベルに落ち着いているが、特にVolumeの扱いが難しい。

追記:

波形を確認したが、ノイズっぽいのはなんとかならんのか、、、。
posted by Yasuski at 16:13| open.Theremin

Open.TherminOnTeensy@pin configurations

#define log10f_fast(x) (log2f_approx(x)*0.3010299956639812f)

#define BAUD 115200 // uncomment if serial is implimented

#define LATCH01 27
#define LATCH01_ON (CORE_PIN27_PORTSET = (1<<15))
#define LATCH01_OFF (CORE_PIN27_PORTCLEAR = (1<<15))

#define LATCH02 20
#define LATCH02_ON (CORE_PIN20_PORTSET = (1<<5))
#define LATCH02_OFF (CORE_PIN20_PORTCLEAR = (1<<5))

#define LATCH03 21
#define LATCH03_ON (CORE_PIN21_PORTSET = (1<<6))
#define LATCH03_OFF (CORE_PIN21_PORTCLEAR = (1<<6))

#define LATCH04 18
#define LATCH04_ON (CORE_PIN18_PORTSET = (1<<3))
#define LATCH04_OFF (CORE_PIN18_PORTCLEAR = (1<<3))

#define LATCH05 16
#define LATCH05_ON (CORE_PIN16_PORTSET = (1<<0))
#define LATCH05_OFF (CORE_PIN16_PORTCLEAR = (1<<0))

#define LATCH06 15
#define LATCH06_ON (CORE_PIN15_PORTSET = (1<<0))
#define LATCH06_OFF (CORE_PIN15_PORTCLEAR = (1<<0))

#define LATCH07 17
#define LATCH07_ON (CORE_PIN17_PORTSET = (1<<1))
#define LATCH07_OFF (CORE_PIN17_PORTCLEAR = (1<<1))

#define CKW 25
#define CKW_ON (CORE_PIN25_PORTSET = (1<<5))
#define CKW_OFF (CORE_PIN25_PORTCLEAR = (1<<5))

#define DATA01 26
#define DATA01_ON (CORE_PIN26_PORTSET = (1<<14))
#define DATA01_OFF (CORE_PIN26_PORTCLEAR = (1<<14))

#define LED 7 // LED on D7
#define LED_ON (CORE_PIN7_PORTSET = (1<<2))
#define LED_OFF (CORE_PIN7_PORTCLEAR = (1<<2))

#define LEDgrn 8 // LED on D8
#define LEDgrn_ON (CORE_PIN8_PORTSET = (1<<3))
#define LEDgrn_OFF (CORE_PIN8_PORTCLEAR = (1<<3))

#define LEDred 9 // LED on D9
#define LEDred_ON (CORE_PIN9_PORTSET = (1<<3))
#define LEDred_OFF (CORE_PIN9_PORTCLEAR = (1<<3))

#define LED2grn 38 // LED on D38
#define LED2grn_ON (CORE_PIN38_PORTSET = (1<<11))
#define LED2grn_OFF (CORE_PIN38_PORTCLEAR = (1<<11))

#define LED2red 37 // LED on D37
#define LED2red_ON (CORE_PIN37_PORTSET = (1<<10))
#define LED2red_OFF (CORE_PIN37_PORTCLEAR = (1<<10))

#define LED2 39 // LED on D39
#define LED2_ON (CORE_PIN39_PORTSET = (1<<17))
#define LED2_OFF (CORE_PIN39_PORTCLEAR = (1<<17))

#define buttonPin01 11 // Button Pin on D11
#define button_State1 (CORE_PIN11_PINREG & (1<<6))

#define buttonPin02 36 // Button Pin on D36
#define button_State2 (CORE_PIN36_PINREG & (1<<9))

#define buttonPin03 3 // Button Pin on D3
#define button_State3 (CORE_PIN3_PINREG & (1<<12))

#define buttonPin04 4 // Button Pin on D4
#define button_State4 (CORE_PIN4_PINREG & (1<<13))

#define buttonPin05 5 // Button Pin on D5
#define button_State5 (CORE_PIN5_PINREG & (1<<7))

#define buttonPin06 6 // Button Pin on D6
#define button_State6 (CORE_PIN6_PINREG & (1<<4))

#define LEDvol 28 // LED on D28
#define LEDvol_ON (CORE_PIN28_PORTSET = (1<<16))
#define LEDvol_OFF (CORE_PIN28_PORTCLEAR = (1<<16))

#define LEDvol2 13
#define LEDvol2_ON (CORE_PIN13_PORTSET = (1<<5))
#define LEDvol2_OFF (CORE_PIN13_PORTCLEAR = (1<<5))

#define SAMPCLK_STATE (CORE_PIN19_PINREG & (1<<2)) //sampling clock in
#define SAMPCLK_MASK (CORE_PIN19_CONFIG = PORT_PCR_IRQC(0)) //masking sampling clock in
#define SAMPCLK_ACTV (CORE_PIN19_CONFIG = PORT_PCR_IRQC(9)) //activate sampling clock in

#define SCK01 30
#define SCK01_ON (CORE_PIN30_PORTSET = (1<<19))
#define SCK01_OFF (CORE_PIN30_PORTCLEAR = (1<<19))

#define SD01 32
#define SD01_ON (CORE_PIN32_PORTSET = (1<<11))
#define SD01_OFF (CORE_PIN32_PORTCLEAR = (1<<11))

#define CS01 29
#define CS01_ON (CORE_PIN29_PORTSET = (1<<18))
#define CS01_OFF (CORE_PIN29_PORTCLEAR = (1<<18))

#define LDAC01 33
#define LDAC01_ON (CORE_PIN33_PORTSET = (1<<24))
#define LDAC01_OFF (CORE_PIN33_PORTCLEAR = (1<<24))

#define DAC16 40
#define DAC16_ON (CORE_PIN40_PORTSET = (1<<28))
#define DAC16_OFF (CORE_PIN40_PORTCLEAR = (1<<28))

#define DAC16_2 31
#define DAC16_2_ON (CORE_PIN31_PORTSET = (1<<10))
#define DAC16_2_OFF (CORE_PIN31_PORTCLEAR = (1<<10))
posted by Yasuski at 07:45| open.Theremin

2018年06月15日

Open.TherminOnTeensy@音声出力波形を観測する

テルミンのWCK強制同期回路の試作は失敗した模様。

インターラプトが動作するポイントにマーカーを追加して、動作不良の原因を探ることになるが、そもそもLoopの設定がアカン感じがする。

何故か単音しか出力されず、出力に妙な変調が掛かったり、インジケータのLEDが動作不能だったりするが、とりあえず左手でVolumeをコントロールできるまでにはなった。

Screen Shot 2018-06-14 at 19.51.05.png

とにかくチューニングがクリティカル過ぎてお話にならないが、アンテナ長分のオフセット設定は計算通りにはいかず、収納する筐体に因ってもズレが発生するのが大問題。

Screen Shot 2018-06-14 at 20.09.52.png

やはり、24bitの計算は無理っぽいので、16bit対応でひとまずまとめることにするかオーバークロックにトライするかで迷うところだが、まずはオーバークロックで無理を確認する。

Screen Shot 2018-06-14 at 20.11.10.png

その後、240MHzにオーバークロックして発音を確認。 相変わらず何かが変だけど、とりあえず音の制御は出来ている。



WCKを32kHzで廻すのもアリ。そもそもがハイファイを目指す意味が無さそうだし。
posted by Yasuski at 20:51| open.Theremin