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

2019年01月30日

output3 にメモリー機能を追加する

output3 のSelectorを拡張した後、メモリー機能を追加した。

Screen Shot 2019-01-29 at 21.28.36.png

output level は通常のモードとTransitionの切り替えが可能。

Screen Shot 2019-01-29 at 20.58.14.png

出力設定は Voice mode 毎に記録するが、Sequencer mode のみ、呼び出した Sequence 毎に記録が行える。

ついでに昨日行ったライヴのリハというか、サウンドチェックの模様をアップ。



倍音風の和音をコントロールする奏法のチェックをしているところ。 同時にエフェクトの掛かり具合や、会場の反響の具合を試していた。

今回は3ch出力のうち、主旋律をセンターから出している。ディレイエフェクトはセンターをメインに掛け、L/Rへのエフェクト成分は薄すめに配分した。 アルペジオの発音が左右に分散されるので、音が濁らず効果的に音像が移動していることがなんとなく判ると思う。



芯のある音でライヴ演奏を行いたい場合は、最低でも3ch出力が必要だと思うが、機能面ではこれがギリギリ。DACの処理スピードがボトルネックとなっているが、FPGA等で外部バッファーを構築すれば、なんとか5chまでは拡張できる可能性がある。

posted by Yasuski at 01:09| LaVoixski

2019年01月26日

バグへの対応

アルペジエーターのパラメーターの操作が「被る」バグを発見。 

これは、パラメーター間を移行して操作を行ったときに操作前に選択していたパラメーターに影響が出る現象で、かなりダメな部類のバグである。

で、コードの精査を行ったところ、条件分岐を switch に改変した結果「入れ子構造」になった部分に”brake;”を追加していなかったことが原因と判明した。 brake を配置して問題は解決したが、改変の影響で若干ピッチに狂いが出始めているのが不安な兆候だ。

他に発生しているバグは、パラメーターの名称を整理したプログラムを起動した時に、SDカードからデータを読み出さない現象。 調査の結果、これが特定のファイルにのみ発生しているのが謎だ。

結局、関数の名称を変更していない元のプログラムに運用を戻したが、バグの発生したコードの周辺には変更の影響は無い筈で、実際にコードの記述を比較してもなんら差異は発見できなかった。 このことは、SDカードをハンドリングするルーティンが特定のファイル名を扱う場合に何らかの影響を受けている可能性を示唆している。

SD周りは対応不能な謎のバグが潜んでいそうなので、とりあえず「動いている」プログラムの運用を優先することにした。
posted by Yasuski at 15:24| LaVoixski

2019年01月23日

Sequencer使用時にドライヴ・クロックがオン・オフするタイミングでピッチが微妙にズレる案件

音質の改善とトレードオフする形で、Sequencer使用時にクロックのオン・オフに合わせてピッチが微妙にズレる案件が再発した。

以前はオプティマイズ・メソッドの変更で改善が見られたが、今回はどうやってもアウト。 attatchInterruptのルーチン内に集約したDACへのデータ転送ルーチンが規定時間内に終了出来ず、Loop処理を行っているパートにタスクが侵食している模様。

一方、Loop処理内に展開している「アルペジエーターの駆動を行うパート」にはインターラプト・マスクを施しているが、これらの影響でピッチの管理を行っているルーチンに破綻が生じている可能性がある。

ということで、関連するマスクを全て除去したところ、ピッチの変動に改善が見られた。

新しく導入するボードでは、より高速なDACの採用によってデータトランスファーに要する時間が圧縮できるので、現在置かれている怪し気な状況は好転すると思われる。

今回のピッチが変動するケースは、MCUの処理能力のマージンがほぼ限界に達していることを示唆する現象なので、今後はコードのダイエットを進めていかなければならない。

追記:

LaVoixskiの音声出力・CH3にはオシレーターの単独出力を固定でアサインしているが、ここにオシレーター選択機構を実装してみることにした。

オシレーターを選択するパラメーターは、ChordEditModeのみで使用している「チューニング・ノブ」に割り当てている。 

Screen Shot 2019-01-23 at 15.15.55.png

これといったエラーもなく切り替え機能を実装できたものの、発音関連のタスクが増加した影響で、SequencerModeの音のズレが再発してしまった。

やはりこの辺がTeensy3.6の性能限界ということで、今後新たに機能を追加する場合には「出音を4voiceに減らす」か、実装済みの機能のうち「使用頻度の低いものを端折る」か、機能を削る選択を迫られることになる。

折衷案としては、SequencerModeの出音のみを4Voiceに制限する方法も考えられるので、一度このダイエット法を実験してみよう。

追記2:

Pitchに生じるドリフトがLEDの点滅とあからさまに連動しているのが怪しかったので、点滅機構周りのプログラムを精査したところ、不要な条件分岐を行っていたことが発覚した。

これは、対象する全てのチャンネルのORを取るという間抜けな仕様で、この分岐構文を排除して回路を単純化した結果、SequencerMode選択時に生じていたピッチの変動を抑えこむことに成功した。

Screen Shot 2019-01-24 at 7.58.59.png

同時に、サブ出力チャンネルの選択機構を稼働させることにも成功、

Screen Shot 2019-01-24 at 8.11.18.png

ついでに、ピッチ検出機構の if() 構文をより負荷が少ない switch() 構文に変更している。

Screen Shot 2019-01-24 at 8.11.31.png
posted by Yasuski at 12:31| LaVoixski

2019年01月17日

CHnIEの設定について

昨日からCortex-M4/K66系列のアプリケーション・ノートを読んでいるのだが、何処を探してもその機能が明示されていない項目があって困り果てている。 

昔と違って今は検索ワードで探せるので、無いものは無い。 CHnIEというインターラプト関連のレジスタがどういった場合に起動するのか、もしくは何処で設定するのかの詳細が、何処を探しても明示されていないのがなんとも不可解。

The channel (n) interrupt is generated when (CHnIE = 1) and (CHnF = 1).

と書かれてはいるものの、フラグが立つ理由はCHnFしか明示されておらず、CHnIEは多分フラグをイネーブルにする端子。確かに、カウンタの概念図にはCHnFCHnIEが入力に記されたAND記号が書かれている。

おそらくは、カウンターのオーヴァーフローを示すTOIEが絡んでいるのだろうけど、それも明示されていない。 実際、TOIE

The timer overflow interrupt is generated when (TOIE = 1) and (TOF = 1).


とあるように完全に別項目で扱われている。

TOIEに関しては、FTMx_SC field descriptionsField 6 にレジスタのアドレスが明示されていて、

Timer Overflow Interrupt Enable. 
Enables TPM overflow interrupts. 


と解説があるのに、CHnIEには設定を行うためのレジスタが存在しないようだ。

これはいくらなんでも不自然なので、試しに CHIE で検索を行ったところ、FTMx_CnSC field descriptions の中に項目を発見した。

ちなみに、FTMx_SC field では、オーバーフローフラグを作動させない設定にしていたので、インターラプトの発生にカウンタのオーバーフローは関与しない。

一方、チャンネルイベントの発生は、CHnF のフラグによって発生することから、フィルターに設定した分だけイベントのタイミングが遅延される仕組みということになる。 

現状ではフィルターの設定は 0xFF なので、15クロック分の遅延が生じていることになるが、一度これをFVCのdebounceの設定値のみを活かす"0"に変更して、挙動を確かめると良いだろう。 ちなみに、debounceの1カウントに要する時間は32kHz=31.25uSなので、FTM_FILTERによる遅延とは桁が違う。
posted by Yasuski at 09:19| LaVoixski