2017年10月14日

Open.Theremin@波形合成の実験

昨日の晩は波形の加算合成の実験を行っていたのだが、出力レベルのリミットでソフト・ディストーションが掛かる機構を追加したことが功を奏したのか、いきなりパッツンと逝く情況には陥らず過渡特性がマイルドになった。 フルヴォリュームに近くなるに連れて歪が増していく特性には慣れが必要だが、ヴォリュームアンテナ側の設定次第では、自由度の高い表現を行える可能性がある。

ノイズっぽい出力特性は、それが目立ちにくいSawtoothやHalfWaveTriangleなSine波との相性がよいようで、加算合成時のミックスバランスを間違えなければ、面白い音を作ることが出来た。 

波形の選択によっては逆相になるものがあって、これを積極的に使うことで、強烈なフィルター効果を得ることが出来るが、波形同士の相対的な関係に依存する現象なので、出来ればオシロスコープで波形を観察しながら編集を行った方が効率がアップする筈だ。

確かに、6波の相関関係を直感的に把握することは難しく、簡易タイプで良いのでオシロスコープの導入を行ったほうが良いのだろうが、問題となるのはそれを格納するケースの仕様だ。 

現在、試作品としてID-292を使用したものを製作中だが、OLEDパネルの実装スペースがギリギリで量産には向きそうにない。 最終的にはスペースに余裕を持たせられるHammond/1455シリーズ辺りを選択することになるだろう。
posted by Yasuski at 02:31| open.Theremin

2017年10月13日

Open.Theremin@Teensy3.2搭載の初期型が再起不能に陥る

今朝方、Teensy3,2を使って構築したテルミン開発用のプラットフォームが、修正プログラムをアップロードしたのをキッカケにご逝去された。 原因の詳細は不明。

最新のプログラムをオーバークロック仕様でアップロードした後に通電すると、LEDが文字通り白目を剥いたまま反応しない。 起動時のピポパ音も沈黙している。

Teensy3.2単体でチェックすると、ROMの内容を起動時に吐いているし、プログラムを書き換えてLEDチカも可能。 なにがどうなっているのか訳が解らないが、とにかく楽器が死亡したとしか言いようが無い。

このままでは故障の詳細が判らず、部品をサルベージしてオシロに化けさせるしか無いのだろうか? 幸い、Teensy3.2は試作中のオシロに必要なので、転用は可能ではある。

この機会に、旧型弾薬箱アンプと新型V3基盤対応テルミンのコンビネーションを試したが、妙なノイズがクローズアップされてしまって、イマイチ相性が良くない。これは、D-Classアンプのチョッパー周波数とテルミンのDACから漏れる高調波の相性と思われるが、LPFの部品係数を考え直した方が良い感触であった。

そういえば、以前にも白目を剥いて死亡したことがあったように記憶しているが、結局はマイコンを交換するしか無かったような。 最後にライヴで活躍できたのが幸いだったが、この楽器は退役させることになりそうだ。 

で、去年のことを思い出したのだが、故障の直接的な原因は処理能力をオーヴァーしたプログラムをオーバークロック仕様でアップロードしたことにあるようで、この行為がキッカケでMCUに搭載されているROMの領域を荒らしてしまったのかもしれない。

過去に似たようなトラブルが発生した時にプログラムを使ってROMを強制的にクリアしてなんとか復活させたことがあり、これは一度試す価値があるトラブルの対応法だろう。

追記:

ROM消去もクリアしているし、データの書込みも問題なく、シグナルトレースを行っても各ルーティンをちゃんとこなしているようにしか見えず、(ソフトウエア上の)LEDの点灯サインも出ているが、何れもMCUをハードウエアから切り離した単独の状態での反応で、ハードウエア接続後はRGBエンコーダが白眼を剥いてしまい、クリック等外部からのアクセスに対して一切の反応が無くなる。

この様子では、短絡等による原因でシステム全体の電圧が降下している可能性が大きくなってきたが、ハードの検査は億劫なので、このままパーツのサルベージを行いつつシステムをバラすことになりそう。
posted by Yasuski at 17:11| open.Theremin

2017年10月12日

Open.Theremin@半音階ドリフトの謎

昨日からテルミンの楽器としての運用試験を本格化しているが、例の半音階だけ音がズレる現象を考えると、ランダムな周波数の変動ではなく「ほぼ正確に半音分ズレる」ところに問題があり、これはバグの匂いがする。

プログラム上、音階の関係は半音単位で以下のように関数化しているのだが、

double pitch1 = 1.0600;
double pitch2 = 1.1236;
double pitch3 = 1.1910;
double pitch4 = 1.2625;
double pitch5 = 1.33823;
double pitch6 = 1.41852;
double pitch7 = 1.50363;
double pitch8 = 1.59385;
double pitch9 = 1.68948;
double pitch10 = 1.79085;
double pitch11 = 1.8983;


double pitchInc = 0.00006103515625;

これはあくまで基音に対して相対化された値であり、A=440Hzといった厳密なものではない。

音源の音程は、Wavetableを読みだすポインターにオーディオクロックの周期で追加される「データを読み飛ばす係数」によって決定される。 add_valというのがそれだが、そこにピッチの変動を掛けることで、音階を決定していく。

case 35: pointer = pointer + (add_val);
pointer2 = pointer + (add_val);
pointer3 = pointer3 + (add_val * pitch5);
pointer4 = pointer4 + (add_val * pitch7);
pointer5 = pointer5 + (add_val * pitch9);
pointer6 = pointer6 + (add_val * pitch11);
break;


一方、半音階に規定されない自由な音程関係をプリセットする機能はこのような形で実現しているのだが、、、

case 41: pointer = pointer + (tuner);
pointer2 = pointer2 + (tuner * (pot3a * pitchInc ));
pointer3 = pointer3 + (tuner * (pot3b * pitchInc ));
pointer4 = pointer4 + (tuner);
pointer5 = pointer5 + (tuner * (pot10a * pitchInc ));
pointer6 = pointer6 + (tuner * (pot10b * pitchInc ));
break;

この機能を選択し、pot_x を呼び出し、tuner が乗算された結果が”ゼロ”からそれ以上に転じた瞬間に、何故か変動が生じないはずの tuner * (potx * pitchInc) が加算されない pinter2 や pointer5 において音程が変化するのが謎なのだ。

追記:


今一度コードを解析した結果、pointerのデータを元にWavetableを読み込むルーチン

uint16_t offset = (uint16_t)(pointer>>5) & 0x3ff;
uint16_t offset2 = (uint16_t)(pointer2>>5) & 0x3ff;
uint16_t offset3 = (uint16_t)(pointer3>>5) & 0x3ff;
uint16_t offset4 = (uint16_t)(pointer4>>5) & 0x3ff;
uint16_t offset5 = (uint16_t)(pointer5>>5) & 0x3ff;
uint16_t offset6 = (uint16_t)(pointer6>>5) & 0x3ff;
                    
の ”後 ”に、ピッチの設定を行っていることが原因と判明した。 

対策は単純で、pointerの値からWavetableの読み出しを行うoffsetが確定する ”前” に switch/case を選択してしまえば良い。

追記2:

ついでに、pointerに行っていたbitshift命令で1bit分過剰にデータを削っていたことが発覚している。本来は2048ステップのところを1024ステップでデータを扱っていたわけで、大変にマヌケである。 修正後は周波数の再生レンジが広くなり、調整がやり易くなった。

追記3:

追試を行ったところ、若干のピッチドリフトが発生している模様。 つまり、処理に伴う負荷が影響しているものと推測される。
posted by Yasuski at 15:06| open.Theremin

2017年10月11日

Open.Theremin@トランジション・モード時に発生するピッチ変動の問題

今週は、テルミンの音量コントロールを改良しているが、トランジション・モードを選択した時に予期せぬ音程の変動が発生していることに気付いた。



音程の変動といえば、和音をプリセットするページで、パラメーターを呼び出す毎に全体の音程が下がる謎の現象を確認しているが、どうもそれに似た雰囲気のトラブルだ。

で、音程の変動が確認される情況は、パラメーターの初期値”ゼロ’が入力された時が怪しい。

試しに、"ゼロ"が入力される機会を調べてみたところ、トランジションを設定しているヴォリュームの変化カーヴと、、、・

Screen Shot 2017-10-11 at 1.47.08 PM.png

Wavetableのアドレスを指定するパートを見つけた。 余り無し=ゼロ なので、この部分には常に”1”以上を出力するように細工を行った。 同時に不感帯を設定して、ヴォリュームカーヴの変化が発生するポイントをズラしている。

Screen Shot 2017-10-11 at 1.46.07 PM.png

以上のように、Wavetableを含む音量コントロール関連のパラメーターから”ゼロ”を追放したところ、音程の変動は綺麗に無くなった。

ちなみに、この手当を行う前にオシレーターの発音を5音に制限してみたが、情況は殆ど変わらなかったことを記録しておく。
posted by Yasuski at 15:21| open.Theremin

2017年10月10日

open.Theremin@Volumeコントロールの改良について

Wavetableから変化量の推移を記録したカーヴを参照することで、より自然な音量のコントロールが行えるようになった。



ただし、トランジションコントロール時の段付きが復活している。 そろそろ処理能力の限界を超えているのかもしれない。 

ArduinoIDEは何をやらかしているかわからないところがあるので、より判り易い形で処理速度の向上を狙うため試験的にアセンブラコードの導入を試しているが、

WS001153.JPG

これが実際に関数を仕込んでみるとコンパイルが通らず、バグレポートを送れとのアラートが出てくる。 

が、これは過去の経験からバグではなく、用法を間違えている感じがしている。 

やはり別に簡単な検証用のプログラムを組んでみて動作の確認を行ったほうが良いのだろうが、アセンブラに関しては引き続き実験を行うとして、3.5を使用する環境に関しては音源を1つ減らす方向でも検討していくことになる。

posted by Yasuski at 20:07| open.Theremin

2017年10月09日

Open.Theremin@VolumeControler周りの問題について

8bit処理時代に感じていた不具合が段階的に軽減されたきたものの、VolumeAntの反応について常に不満を感じ続けていることもまた事実。

Open.ThereminのVolumeControlの構造について解析すると、まずハード面の違いはオシレーターの中心周波数が40kHz程下なこと位で、Pitch側と殆ど構造は同じ。 ソフト面も似たような構成だが、周波数カウンタでカウント=センシングされた値をMaxVolumeの規定値4095=12bit/FSから減算するところに違いがある。 つまり、センシングされる周波数の差分が大きくなるほど、音量設定のデータは低くなっていく。 センシングされた差分の最大値は予め4095にリミットされているので、マイナスの値は出てこない。

一方、オシレーターの周波数変化にはリニアリティーが要求されているために、当然ながらValueの変化もリニアになる。 が、これは音量をコントロールする数値変化に要求される変化のカーヴとしては頂けない。 弱音から一気に音量が増えてしまう感覚は、このようなシステムの在り方に起因している。

ここで、今一度整理することを目的に、現時点で追加した改良点を列挙しておく。

1) 処理ビットの幅を8bitから11bitに拡大。 

8bit幅ではどうしても「段差」を感じてしまうため、より細かな変化幅でドライヴすることが望ましい。 が、分解能が上がると、それだけ計算に必要な時間が増える。 ので、トレードオフとして11bit程度が妥当と判断した。

WS001152.JPG

2) フィルターの追加。 

レジスタを追加して積分を行い、細かな反応を地均ししている。

Screen Shot 2017-10-09 at 9.15.03 PM.png

3) オーバーフロー対策用のリミッターを追加。 

トランジションをコントロールした場合、いきなりデータがフルになる情況が発生するので、それを回避するための仕掛け。

WS001151.JPG

4) トランジション使用時のオーバーフロー対策として、ヴォリュームカーヴ設定ファイルの最大値を変更。

リミッターでは吸収されないレベルの変化幅の発生を予め予防するために、ピークの重複を見越してWavetableの最大値を設定している。

WS001147.JPG

5) FTMカウンターの分周率を1/2から1/4に変更。

差分のセンシングを行う場合、反応の速さとセンス出来る最低周波数はトレードオフとなる。低い方のセンシングを安定させたい場合は分周率を上げる方向で調整するが、遅延時間が大きくなると音響処理に使用出来る時間が削られてしまう。

WS001148.JPG

6) VolumeCounterから出力される16bitデータを右に1bit分シフト。

4bit分の不感帯を多少なりとも解消するための細工。 センシングと同時にInitialValueに記憶されるレジスタの変更を忘れずに。

WS001149.JPG

以上の変更を行っていたが、イマイチ効果が薄い。

そこで、Wavetable方式で、ヴォリュームカーヴを読み取り出力に反映することにした。

Screen Shot 2017-10-09 at 9.13.11 PM.png

これにはかなり効果があって、ピアニッシモ時の息継ぎ現象や、急峻な音量変化を抑えることができている。

ただし、妙にノイズっぽい音質の改善は進んでおらず、引き続き対策を考えなければならない。
posted by Yasuski at 18:47| open.Theremin

2017年10月08日

open.Theremin@

一昨日は、Teensy搭載テルミンの組み込み用筐体を製作していた。

溶けやすいリボンケーブルのハンダ付けがすこぶるやり難く、テフロンスリーブのリボンケーブルが欲しくなった。

IMG_7666.JPG

来月には稼働させたいところだが、多分オシレーターのチューニングで躓くだろう。

IMG_7652.JPG

ロータリーエンコーダーの配線を終えたところ。

VCOへの影響が若干心配ではある。

IMG_7656.JPG

Dupont製のリボンケーブルだが、線材が細く、ハンダ付けがすこぶるやり難かった。 多分簡単に断線するので、ケースの開け閉めは最小限に抑えなければならない。

IMG_7657.JPG

目玉スイッチとの接触面に絶縁用のガラステープを貼っている。

IMG_7658.JPG

収納時には、このままケーブルを折り畳むような形で基板を押し込んでいく。

IMG_7662.JPG

開発環境としての利便性を追求するために、接続用のUSB端子を増設している。

IMG_7659.JPG

USB端子は華奢なMicroBに代わってMiniBに昇格。 取付方法はGFRPによるシムで挟む形で固定するというトリッキーな方法なので、耐久性がちと心配。

IMG_7650.JPG

分解したExtraCore搭載のOpenTheremin。 ExtraCoreは切手大サイズのArduino。 接続にはケーブルを使うしか無く、かなりなスパゲッティー状態である。

IMG_7651.JPG

VCO周りをいじったV1基板。 こちらのオペアンプはオーディオ系のみをOPA4134に交換していた。
posted by Yasuski at 22:45| open.Theremin

Open.Theremin@波形の観測

新調したOpen.Thereminの出力波形を描画した画像をアップした。



音声を扱えるスタンドアロンのオシロが欲しいところだが、漏れているVolume制御のリップルが気になる。 なんとか対策できないものか。

評価用に仕込んだ判り易い波形を観測したところ、予想以上に鈍っているようだ。 急峻な立ち上がり・立ち下がりに、電圧の変化が着いて行けない様子がよく判るが、これは出力に挿入したLPFの影響もあるのだろう。

ここで、恥ずかしい告白をすると、画像でこの波形を検討するまでは、アドレス[0]の所謂「半波長」のサイン波を基本波と勘違いしていた。  

vlcsnap-2017-10-05-22h32m51s142.png

三角波とサイン波が合成されたような波形だ。これは、Web上でサイン波を生成するソフトウエアの理解が中途半端だったのが原因だが、基本波の正解はアドレス[1]のSine02。

vlcsnap-2017-10-05-22h34m05s089.png

勘違いの結果、妙な倍音を含む波形をラインアップに追加していたのだが、これは、音色的にはアリ。 ただし、単純なサイン波による波形合成を行う上では混乱の原因となるので、アドレスの割当てを変えることにした。

vlcsnap-2017-10-05-22h28m26s274.png

ノコギリ波は適度にナマってくれているのが良い。

vlcsnap-2017-10-05-22h31m16s830.png

これは、期せずして作った更に訛ったノコギリ波。 ポテンヒットみたいな行幸である。

vlcsnap-2017-10-05-22h32m15s902.png

これは、ランダムに数値を編集した波形。 妙な高調波を含んでいるが、結構使えるかもしれない。

vlcsnap-2017-10-05-22h56m24s253.png

基本波の半波長に二倍高調波が加算された波形。

vlcsnap-2017-10-05-22h57m09s987.png

こちらが正しい2倍高調波。

vlcsnap-2017-10-05-22h57m21s002.png

二倍高調波の半波長に3倍高調波がプラスされている。

vlcsnap-2017-10-05-23h03m28s025.png

これが、3倍高調波。

vlcsnap-2017-10-05-23h05m42s215.png

これは三角波を作ろうとして失敗こいた例で、間違って半波長を生成した結果がこれである。

ステレオ運用時の波形を観測した映像。



やはり、処理能力に余裕があるのか、3.2よりも波形が綺麗だ。 録音のラストの音色はパイプオルガンっぽい感じで、低音のみをシングルで出力しつつ、もう一方のチャンネルで高音を被せている。 これはスピーカーの展開次第では面白い効果が得られるかもしれない。 和音は16bitDACから、単音は12bitDACから、、、といった用法が正解だろう。 3chから出力するだけで、立体的な音場を構築できるはず。
posted by Yasuski at 16:30| open.Theremin

Open.Theremin@波形観測用にOLEDオシロスコープの製作を再開する

OLEDを使った簡易オシロをTeensyに移植する計画の準備として、調子の悪いArduinoDueを引っ張りだしてダメ元でMacに繋いだところ、何故かこれが認識された。 その後、LEDチカをやって書き込みの確認をしてみたが、肝心のオシロのスケッチにコンパイルエラーが出て再書込が行えない状態になってしまった。 どうも、OLEDディスプレイのドライバファイルに速度アップのためにいろいろと仕込みをしたのがArduino側の仕様変更で無効になった可能性が高い。

仕方がないので、コンパイルが通るまで怪しげなポイントをすこしずつ取っ払った結果、基本的な機能は再現できた。



で、波形を観測したのだが、なんとなく思っていたトランジション・コントロールを行っている音源の音量がショボいことを再確認することになった。

対策として、Valueがフルスケールになる辺りの挙動を考えて、トランジションを操作するWavetableのダイナミックレンジ設定をイロイロとイジってみたのだが、6波あるコントローラーValueの合算が実質的に12bit範囲に収まりそうな値を探るのに一苦労させられた。 荒っぽい計算だが、1350段階程度に変化量を抑えると、6波加算時のオーバーフローの頻発を軽減できるようだ。

実際の運用を考えた場合、6波を合成するのだから「音が荒れないように」ダイナミックレンジを抑めにミックスを行っていく手法が常道ではあるものの、レベル管理のためのインジケーターが存在しない情況で編集の操作性をカヴァーするにはソフト側をインテリジェント化しなければならない。 単純に合算を行う現状ではトータルの出力バランスが最適化されたセッティングを得るのは難しい。

そのオシロの機能選択のパートをプログラミングしている過程で、処理をサブルーチンに飛ばした結果生じる遅延の大きさに気付いた。 特にロータリーエンコーダーのセンシングを行っている部分のスイッチ→サブルーチンに飛ぶ構造で一様に処理の遅れが発生していると判断し、OpenThereminのプログラム内に設定しているサブルーチン処理をスイッチ内部に内包する方向に改善を行った。 その結果、ヴォリュームコントロール時に、聴感上生じていた不連続な息づき現象が軽減されたことから改良にはそれなりのご利益があったものと思われる。

本体の改良を終え、波形表示を行う計画に戻る。 当初開発を行っていたArduino/Dueはフットプリントが大き過ぎてID-292に実装できない。 そこでサイズがコンパクトなTeensy3.2にプログラムの移植を進めていたのだが、去年の時点ではコンパイルが通らず全く刃が立たなかった。 その後、OLEDのインターフェイス設定を行う部分をプログラムの先頭に移動してみた結果、すんなりとドライヴが可能になった。  



波形を上書きすべきところを取り零しているが、原因はおそらくOLEDユニットの通信スピードの限界で、そこがボトルネックとなっているようだ。

当初はそれに気づかずにTeensyのクロックを72MHzで運用しようと試みていたが描画が全く安定しない。 どうもOLED側でデータの取り零している雰囲気になってきたので、試しに24MHzまでクロックを落としたところ、なんとか正常に近い形で描画が行われるようになった。 が、まだグリッドの描画が負担に見えたため、表示を外して実験を再開している。

ハードウエア的には、バイアス電圧の追加と、オーヴァーレベル対策を行う必要がある。 オーヴァーレベル対策は、LEDによるダイオードクリッパーの採用を考えている。 波形表示を優先すべきところをオシロとして多機能を盛り込もうとしたのが間違いと考えを改め、波形表示に専念する内容にプログラムを書き換えていく。 



その後、表示オフセット設定等の細工を施した結果、なんとなく行けそうな雰囲気になってきた。

ACカップリングを行っていない白入力にDC成分が見える。信号入力回路にはヘッドアンプとリミッターの追加が必須。 ケースは例のID-292になる予定だ。 回路の構成は、波形観測を行いつつ信号の分岐が出来るようにしたい。 エフェクターを内装すれば更に便利だが、スペースの余裕に難がある。

設定は固定しても問題なさそうだが、設定変更用のIFとしてトップパネルに準備されたタッチスイッチを流用することが可能だ。 起動時の判定で簡易周波数カウンタの機能を持たせても良いが、入力の設計が難しいかもしれない。 何れにしても筐体に基本回路をまとめさえすれば後々機能を追加できるので、まずはプラットフォームの構築に専念しなければならない。

オシロ機能の初期設定はプログラムのこの部分で行っている。

WS001147.JPG

プログラムの開発に目処が付いてきたので、トップパネルを切削してオシロの基台を作ることにした。 調子に乗って覗き窓を切り出していたが、OLEDのベース基板の寸法を計算に入れるのを忘れた結果、このままでは実装が不可能なことに気付いた。

IMG_7678.JPG

穴位置を右に寄せすぎて、OLED基板の装着が不可能になってしまったが、OLED基盤自体を分解することで問題を解決できそうだ。 例え窓の位置を左に寄せるにしてもスペースがギリなことは変わらない。 残念ながらID_292に組み込むスタイルは試作だけで終わりそうだ。


トップパネルにはカットした青基板を取り付けて基台にするつもりだったが、青基盤にスリットを入れてOLEDの制御パネルを挿入してアングルで固定すれば構造がスッキリする。 初代の基盤はトップパネルと取り付け位置がズレているので、オシレーター側を5ミリほどカットした後、真ん中のTOSLINK用の切り欠きから右側をバッサリと落とせば丁度良い基台になるだろう。 オペアンプはステレオ仕様になっているが、バイアスポイントの追加とACカップリングを行う必要がある。 

MCUにはTeensy3.2を取り付けて、余ったロータリーエンコーダー用の端子を可変抵抗のポートに転用する。 第一世代の青基板はTOSLINKを配置するために空けたスリットが既に入っているので、加工が楽だ。

IMG_7686.JPG

入出力コネクタは例によってHiroseの6pinを使用するが、これをトップパネルの左端上下にマウントして、トップパネルにすべての回路を集約する。 プログラム書き換え時のトラブルはこれでほぼ防止できるはずだ。

IMG_7687.JPG

中央の孔には、電池駆動を前提にして電源スイッチを配置する事を考えたが、RGB LEDを装着してパラメーターの状態を表示させるのが一番スマートな方法かもしれない。 ちなみに、基板上にUSB端子のランドが存在するが今回は使わないことにした。

posted by Yasuski at 15:25| open.Theremin

2017年10月05日

Open.Theremin@オシレーターの音色について

テルミンの音色をセットする用法に関して、和音と単音でプリセットの作法が異なることを再考している。 

和音を演奏する時は当然ながら音はバラけるのだが、構成音を倍音の合成を目的に設定している場合、音程の関係が当初の想定よりも複雑になってしまう。 また、左手の動きによってトランジションコントロールを行う場合であっても、重なる音は最大で3和音程度なので、これも単音時とのフィールが大きく違ってくる。 

つまり、最終的な演奏形態を考えて音色の選定を行うべきということなんだが、これを逆の視点から考えた場合、単純であっても Sawtooth Triangle Sqare の3波形を和音を構成する場合の選択肢として準備すべきというのが結論。

ということで、適当に波形をなまらせたプリセットを追加しよう。
posted by Yasuski at 09:53| open.Theremin