Frequency Shifter の検討(その4)試作した回路
試作した回路
試作した基板は、入院中に発注し自宅に届いていたものです。
構成要素となる、Dome Filter , 二相sine/cosOSC , Ring Modulator は、個別に検証・調整が必要なので、この基板はブレッドボードのつもりで、これらの構成要素は基板上で未接続にしています。
空きエリアにはユニバーサル部が設けられているので、検証後はここを利用して接続し、Frequency Shifterに仕上げようという目論見です。
示した回路図は、ここの構成要素を個別に検証後、手配線で接続したものを含んだ全体の回路図です。
また、Frequency Shifter は、サブセットとしてRing Modulatorを含んでいるので、スイッチ( FS/RM )で切り替え比較できるようにしています。
二相sine/cosOSCは、ふたつの積分器のCを切り替え、レンジを広げています。
スイッチ( Freq +/- )は、sine/cos発振器の周波数を負にすることも出来るようにしています。例の式(2A)(2B)を切り替えることに相当します。 これによりFrequency を上げる方向と下げる方向の両方が切り替えられます。
スイッチ( Mix )は、Frequency Shifter の出力に原音をミックスする機能です。
例えば周波数を0.3Hzシフトした出力と原音をミックスすると、ディチューンした2オシレータの様な音が作れます。 実際のディチューンとの違いは、基本波のうなりが0.3Hzになるだけで無く、全ての倍音同士のうなりも0.3Hzになるので、とてもソフトでやさしい、一味違うユニゾンコーラスに感じました。
またスイッチ( FS / RM )で、Ring Modulatorと比較すると違いが良く分かります。
Ring Modulatorは、原音に高調波の少ない音を入れないと、発生した和と差の二つの音の倍音同士が不協和になり、濁った音になりますが、
Frequency Shifter に切り替えると、二つの音の片方が消えるためきれいな音になります。
これについては、周波数によっては完全に消えずに小さく残る場合も有り、完全にするためにはDome Filter の精度を上げる必要がありそうです。ただ、現状でも十分効果は発揮できていますので、何を狙うかにより改善点がかわりますね。
面白いのが、Ring Modulatorで1Hzなどの低周波で変調すると、1Hzで音量が変化するAMのトレモロ音になりますが、Frequency Shifter に切り替えると、振幅の変動は消え、1Hz だけ周波数がシフトした音が得られますので、原理は分かっていても不思議な気がします。
したがって、これに原音をミックスするとユニゾンコーラスになる訳です。
VCOの音をそのままシフトしても、ピッチと響きは変わるのですが、それほどの面白味は無く、特定のピッチを持たないリズム系の音の方が、周波数シフトの印象が強烈にでます。
また時間を取って、音のサンプルを録音したいと思います。
Frequency Shifter の検討(その3) 二相正弦波発振器
grapf 1
circuit 1
二相正弦波発振器
Frequency Shifter を構成するには、下式のcos(αt) , sin(αt) 二相の変調用の正弦状波発振器が必要です。
私がFrequency Shifterに期待する効果が、
(A) 周波数シフト(上下) & 倍音構成を崩す
(B) ディチューンによるコーラス効果
です。
変調用発振器の発振周波数としては、(A)の為には原音の音高以上の可変域が必要になり、
(B)の為には0.1 Hz以下までの超低周波まで可変域の下限が必要です。
また、応用を広げる意味では VCO にしたいところですが、今回は早く結果・効果が知りたいのでVCOは諦めることにします。
また、簡単な構成で低歪みな正弦状波を出力したいので、ファンクションジェネレータ方式にはしないで、正弦状波を直接発振する方式とします。
選んだ方式は、二重積分ループを使った状態変数型の発振回路です。
circuit1 がその回路です。
U2,U3が反転積分器でU1で反転させてメジャーループを構成しています。
out2を cos out とすると、それをU1で反転した -cos を反転積分した out1 は、sin outになり、
それをさらに反転積分した out2 は cos になり正帰還ループになります。
またout1からのマイナーループもあり振幅の安定化を計っています。
発振周波数は、二つの積分器の時定数を変えることにより行います。
C=C1=C2, R=R3=R4 とすると発振周波数は、f = 1/(2π C R )になります。
実際には、2連VRを使うことになります。例えば100KのVRを使うとき直列に例えば1Kの抵抗を接続します。このように、この構成でそこそこ実用的に可変できる範囲は二桁程度です。それ以上欲張ると、周波数の高域の可変カーブが急峻になりすぎ使えません。また、2連VRのトラッキング誤差が高域で顕著になるので発振が安定しなくなります。
したがって、目標の可変域を得るためには、Cを何段階かに切り替えることにします。
積分時定数を変える方法として、2連VRで入力電圧をアッテネートした上でその電圧を固定のRを使った積分器を使う構成もあります。 この構成はA型VRを使うと周波数の可変カーブが自然になるので私もよく使っていましたが、低周波側では積分器の入力電圧が低くなるため、オフセットバイアス電圧の影響が顕著になるためやはり可変範囲を大きく出来ないので、採用しないことにしました。
この定数でシミュレーションしたのがPhoto1です。
発振ループゲインの調整は、R7を増減します。
R7を大きくしすぎると発振が止まり、小さくしすぎるとout1の正弦状波出力のつぶれが増えてきます。out2の歪みは変化しません。
周波数切り替えで、Cを切り替えたときR7 の調整値が変わらなければ良いのですが。
Frequency Shifter の検討(その2) Dome Filterの検討
graph 1
circuit1
Dome Filter ?
入力された原音の基音と高調波の位相を90°シフトするフィルタをDome Filterと呼びます。
ヒルベルト変換のアナログ近似で、実部用と虚部用の二つのAll Pass Filter ( Phase Shifter )で構成します。
各Phase Shifterは、オーディオ帯域を出来るだけ直線的に位相をシフトするため、一段で180°シフトできる一次のPhase Shifterをつなぎ目を滑らかに6段つないで広帯域に直線的位相シフトをしています。graph1の上と下のカーブがcircuit1の上段と下段のPhase Shifterの特性です。
20Hzから20KHzの範囲でほぼ直線に見え、上段と下段の出力間の位相差は90°になるようにしています。実際シミュレーションではこの範囲でほぼ90°になっています。
この特性を得るにはR,Cの精度が相当必要と思われますが、時定数のRの値が全て異なるのでこれを実装するのは大変です。
実際どんな音が得られれば良いのかも未知数ですので、今回の試作では5%以下で良いつもりでやります。
入力された原音の基音と倍音を全て90°位相シフトするのは、アナログでは不可能(?)なので、このような少しごまかしっぽい構成がとられています。
人間の耳はオーディオ信号の位相が変化しても分からないということで、上段の出力を原音の代わりとみなすことで、90°シフトを実現していると理解しています。
Frequency Shifter の検討(その1) 原理と構成について
Fig1
Freqency Shifterって?
長い入院生活の間で何か面白いモジュールの検討をしたいと思っていました。
そのとき頭に浮かんだのが、Freqency Shifter です。
かなりマイナーなモジュールで、私自身も実際の製品を見たことも無く、音を聞いたこともありません。
なぜ思いついたかというと、10年近く前ですが、houshu氏が学会で京都に来たとき、折角だからということで夜に京都でお会いし飲む機会がありました。
そのとき、彼が話題のひとつとして持ってきてくれたのがFreqency Shifterで、資料としてたしかUSP(米国特許)を見せて貰ったように思います。
このモジュールがどれほど音作り効果が期待できるかはともかく、技術的な面白さに大層興奮したことだけは記憶しています。
検討に入る前のおぼろげな私の理解
・Ring Modulatorで得られるピッチシフトは、必ず二つの周波数(和と差の周波数)が発生する。
多くの場合不協和の2音が現れるので、倍音が多い原音を入れるとすぐ濁ってしまうので、きれいな音を出すには、原音は倍音の少ないものに限定される。または、あえて濁った音を出す使い方になる。
・なんとかして和や差だけの周波数が得られれば、濁らせずにピッチシフトができ、より広範囲な応用ができそう。
・Ring Modulatorでの4象限乗算を90度位相のずれた、sineとcosで各々行えば、差の出力を打ち消すことが出来そうである。
・自分で発生する変調信号では、sineと同時にcosも出力するの構成が可能。
しかし、入力される任意の原音(倍音も含めて)に対して90度位相のずれた信号(倍音含む)を作るのは困難。たぶん不可能だろう。(各倍音を検出して90度位相のずれた信号を作るデジタル的な手法は×。原音には和音や打楽器音なども来るため。)
・dome filterという巧妙な技術により原音を二相化できそう。
ポイントは原音の全ての倍音を二相化するのでは無く、位相の絶対的なシフトは気にせず(耳では位相だけがずれても違いは分からないはずなので)相対的に90度位相のずれた出力を出す二組のPhase Shifter(広域に直線的に位相がシフトよう設計された)の二組の出力を、sineとcosとする。
dome filterはFreqency Shiftwerのキモですので次回詳しく説明します。
今回の検討
病室からhoushu氏にメールして、moog他の資料のURLを教えて頂き、時間を掛けて検討を進めました。
その結果を整理すると、
(1) Freqency Shifter(FS) は Ring Modulator(RM) の発展系である。
・Ring Modulator(RM)
RMの機能を数式で表すと、原音を正弦状波 cos(ωt)、変調波も正弦状波 cos(αt)とすると、
両信号の4象限乗算になるので、
となり、よく知られているように、両信号の和の周波数の正弦状波と、差の周波数の正弦状波がミックスされたものになります。
実用的には変調波には正弦状波が用いられますが、原音には何が入力されるか解かりません。
倍音も含む場合は、例えば2倍音に対しても式(1)からα加算とα減算のミックスが生成されます。
倍音に対して一定周波数が加減算されるので、ピッチか変わる効果と倍音構成が崩れる効果が得られます。
・Freqency Shifter(FS)
ピッチシフト効果を狙うためには、和のみや差のみを取り出したいところです。
それが得られる数式が、三角関数の加法定理です。
(2A)を用いると和のみが得られ、(2B)で差が得られます。
これを実現するには、二つのRing Modulator と加減算器が必要で、
構成を図で表すとFig.1 のようになります。
変調側のsin(αt)を作るのは、cos(αt)とsin(αt)を発振する二相発振器で可能ですが、
もっと難しいのは、sin(ωt)を作ることです。
これには、上で説明したDome filterを使います。
6809/Z80マシーンを発掘しました(4) マルチCPUの仕組み(2) ソフト編
マルチCPUの仕組み(2) ソフト編
動いているCPUが自分自身を停止させ、相手を動かせるハードの仕組みについては、
6809/Z80マシーンを発掘しました(3) マルチCPUの仕組み(1) ハード編 - 電音の歩み
を見てください。
とてもシンプルなハードですが、シンプルすぎてどのように使えば良いのか疑問にもたれた方もあるでしょう。
実際、このハードだけではCPUを交互に動かせるだけなので何もできません。
これを活かすソフト面での仕掛けが、「CPU Manager」です。
この図は、発掘したソースコードを見て、私が再発見しながら書いた「CPU Manager」の動作フローです。左半分は6809コード、右半分はZ80コードです。
仕組みはとてもシンプルですが、驚くほどパワフルです。
この「CPU Manager」の狙いは、
(1) 6809からZ80の関数を、Z80から6809の関数を引数付きでコールできる。
( ACCA, X ) は、 ( Areg , HLreg )に相互に引き継がれます。
(2)相互の関数コールは、多重にできる。
だけです。
これができれば、相手のCPUの関数も自在に利用できることになりますよね。
まず、基本動作を説明します。
■Z80側の初期化
Resetが掛かると最初に6809が動き出すので6809側の色々な初期化は自由にできますがZ80側の初期化も必要です。
話を簡単にするため、ここには書いていない6809側の初期化コードで、Z80をResetから起動しSPを設定し、< 0 >のルートでCHG_CPUのポイントまで導き、制御を6809の初期化コードに戻します。(Z80 のRESET後の例外的な動きのためハードでもRESETを記憶するD-FFが付いています)
これで Z80 側の準備もできました。
重要なのは、CHG_CPU(どちらのCPUからも切替ポートにダミーライトすると相手に制御が移る)のポイントは、どちらのCPUも1箇所しか無いことです。
■6809からZ80の関数をコールする動作
6809でZ80の関数(サブルーチン)を呼びたいときは、
CALLZ80 address
というマクロを記述します。
実際の命令は、
JSR CALZ80
FDB address
というコードが生成されます。
シーケンス< A >
JSR 命令の後ろに続くコーリングシーケンスのアドレスを取り出し、引数メモリの (PC) に格納し、" CFLG = 0"にします。これは、6809からZ80をコールすることを意味します。
さらに、 X レジスタを ( XREG )、 ACCA を( AREG )に書き込み、CHG_CPUポイントでCPUを Z80 に切り替えます。
シーケンス< 2 >< 4 >< 5 >
6809は停止し、Z80は CHG_CPUポイントから動き出します。
( XREG )を HL レジスタに、( AREG ) を A レジスタにロードし、CFLG をチェックします。
ここでは CFLG は 0 なので、( PC )のアドレスのサブルーチンをコールします。
関数から戻ってくると、今度は CFLG は 6809 に Z80 から帰ってきたことを示すために" CFLG = 0" に再設定し、HL と A レジスタを書き戻し、CHG_CPUポイントでCPUを 6809 切り替えます。
シーケンス< B >< C >
CHG_CPUポイントから戻ってきた6809は、レジスタの引き継ぎを行い、 CFLG をチェックし ここでは CFLGが 0 なので、Z80 の関数から戻ってきたことが分かり、リターンします。
ここが重要なポイントですが、もしこのとき CFLG が 1 であった場合、6809からコールしたZ80の関数から戻ってきたのでは無く、そのZ80の関数の中からさらに6809の関数をコールしたことになり、シーケンス< C >ではなくシーケンス< D >に向かいます。
このCFLG の仕組みと、6809 と Z80 それぞれのスタックの働きにより、何重にでも多重コールが実現できることになります。
話が飛びましたが、こんどはZ80から6809を呼ぶ動作を説明します。
■Z80から6809の関数をコールする動作
シーケンス< 1 >
CALL CALL6809
DW address
と記述すると、シーケンス < 1 >に入り、" CFLG = 1"として CHG_CPU に行き、制御を 6809に移します。
シーケンス< B >< D >< E >
6809はレジスタを引き継ぎ、 CFLG が 1 であることを確認し、addressの関数を間接アドレッシングのJSR命令でコールします。
戻ってくると6809関数からの復帰を知らせるため、CFLG を再度 1 に設定し<
CHG_CPUポイントからZ80に復帰します。
シーケンス< 2 >
レジスタを引き継ぎ、CFLGが 1 なので6809からの帰還と見なしRETします。
■6809からZ80の関数をコールし、その関数は6809の関数をコールしているときの動作
6809で書かれたアプリケーションソフトが CP/M で動作している様子を見てみましょう。アプリは既に動いており、スクリーンに文字を表示しようととしています。
6809コードのアプリですので、Z80コードのCP/M の API をコールするためには、CALLZ80機能を使います。
ここまでで、CFLG=0 でシーケンス < A><2 > < 4 >まで来ました。
CP/M の API は さらにZ80コードのBIOSをコールします。
ところが呼ばれたBIOS の大半のAPI はそのまま 6809 で書かれた ROM内ルーチンをコールするだけで済ませています。
即ち、CFLG=1 として、シーケンス< 1 >< B >< D >と進みます。
< D >で呼ばれたROM内の6809コードで文字表示を行い、CFLG = 1として< E >
を進み、CHG_CPUで< 2 >< 3 >と抜け6809関数コールを終えます。
この関数コールをしていたのは、< 4 >で6809から呼ばれていたZ80 のBIOSですので、CFLG = 0 として< 5 >に進み、CHG_CPU ポイントから、6809コードで書かれたアプリに戻ってきます。
万事うまくいくでしょう。
このような仕組みにより、FLEX09用に作られた6809コードのスクリーンエディタ " DUET " ですが、APIコールだけ CP/M 用に変更して、立派な CP/M アプリとして動いています。
アプリのコードも実際のBIOSの下請けコードも全部 6809 なので、このアプリの動作中はほとんど赤のLEDが点いています。
6809/Z80マシーンを発掘しました(3) マルチCPUの仕組み(1) ハード編
マルチCPUシステムの工夫
実家をあさっていると、このシステム(たぶん)の回路図や資料も出てきました。
今見ても面白い点があるので、一度まとめて紹介します。
まず一番の売りは、「6809からZ80のサブルーチンをコール」したり、逆に「Z80から6809をコール」したり自由に(多重に)できることです。
これを使って、CP/MのBIOSを6809のコードで書いたりしています。
この機能は、ハードとソフトの連携で実現しているのですが、ハード側は、単にCPUを切り替えるだけの回路で大変シンプルです。
■CPU切り替えのハード側の仕組(アービトレーション)
このシステムは、68B09(2MHz)とZ80(4Hz)、ふたつのCPUのアドレスバスとデータバスを完全にパラ接続する完全密結合のマルチCPUシステムで、ダイナミックにふたつのCPUが切り替えられます。
切替には1bitの切替ポートが用意されており、最初は6809側になっています。
6809が動いているときはZ80は*BUSREQ状態のためアドレス/データバスを開放(ハイインピーダンス状態に)して止まっています。
そこで6809が切替ポートをダミーライト(青矢印)すると、切替ポート(LS393)がZ80側に代わります。緑矢印により6809にHALTが掛けられ、6809がバスを開放して停止したのをBSとBAにより確認してから、Z80の*BUSREQを外しZ80が動き出します。
逆にZ80が切替ポートにダミーライトすると(このポートはトグル動作なので)こんどは6809側になり、Z80に*BUSREQをかけます。こんどはZ80がバスを開放して停止したのを*BASACKにより確認してから、6809の*HALTを外し6809が動き出します。
このように6809とZ80がたすき掛けになったフリップフロップのような動作をして、とてもシンプルなバスアービトレーションを実現しています。
D-FFは、RESET時にZ80を起動させない働き(リセットを解除させない)をします。
最初の切り替えアドレスに6809がダミーライトして初めてZ80のリセットが外れます。
この仕掛けにより、6809側のソフトとZ80側のソフトをCPU切り替えハンドラに導くことが出来ます。
具体的には、
① リセットで起動した6809はCPU切り替えハンドラに到達し、Z80に切り替える。
② Z80のリセットが外れ、Z80もCPU切り替えハンドラに到着し、6809に切り替える。
③ 制御は6809に戻り、かつZ80は切り替えハンドラで切り替えられるのを待機する状態になっている。
ソフト側の仕掛けは次回