2017年5月31日水曜日

キックマシン KIK01の妄想

Sonic AcademyのKICK2というソフト音源がある。キックに特化しためずらしいシンセだ。

おためし版を少しいじってみたが、操作もかんたんでいろんなKICK音を作れる。

KICK音と言えば、サンプル・サウンドを切った貼ったして好み音を作るというのが普通だと思うが、KICK2はアナログモデリング音源とサンプラー音源の合わせ技で音作りする。

ソフト音源としてはかなりおもしろい音源だと思います。

で、KICK2にインスパイアされて、マイコンとアナログ回路でキック音源を作れないかな~と考えてみた。

リズムマシンからの派生


以前PSoC 5 LP Protyping Kitを使って作ったリズムマシンはまあまあ使えはするが、MPUで波形から振幅変調、音の合成をすべて行っていて、チープな感じが拭えない。せめてキックだけでも音のバリエーションを増やせないかという目論見。

妄想図

上から二段目の「アナログ音源」と書いてあるあたりが今回の妄想。

KICK、SNR、TOMは音の作り方としては、サイン波を振幅変調するのが基本なので同じくくりにしてみた。

TR-909の波形



これはTR-909のKICKのサンプリング波形で、基本的にサイン波を振幅変調しているのがわかると思う。以前TR-808のKICKと比較してみたが、TR-909は周波数変調も行っているようで最初は周波数が高く、徐々に低周波数に変化している。

妄想図に書いたように今回はサイン波を周波数変調したく、3つぐらい考えてみた。

1) サイン波発生器をフルアナログでやればアナログVCO。マイコンでエンベロープを生成してやって、電圧値を出力すれば周波数変調できる。ただしサイン波のアナログVCOは製作が大変そう。

2) デジタル・ポテンショメータを使えばマイコンで抵抗値を制御できるので、例えばウィーンブリッジ回路(参考「小ネタ実験: ウィーンブリッジ正弦波発振回路の実験」)を使ってアナログ的に周波数可変の正弦波生成ができそう。

3) マイコンで波形を生成する。つまりVCOはデジタル音源となる。一番かんたんそうだ。後段にアナログVCAで振幅変調するのでそこそこアナログチックな音になるかもしれない。

エンベロープ波形


一番悩んでいるのは、エンベロープの波形だ。1)のVCOならエンベロープ波形(電圧値)を例えばCR LPFを通してやればアナログチックな波形になりそうだが、2)のデジタル・ポテンショメータを使う場合だとデジタル波形がそのままエンベロープにあらわれてしまうので対策しないといけない。(もちろん3)のフル・デジタルでも)

必要なエンベロープ波形(?)

振幅(Amp)と周波数(Freq)を変調するので、エンベロープは2系統でTR-909の波形を見ると上記2つが必要そう。リニアな補間ではなく時定数っぽいカーブ。

このようなエンベロープ波形をマイコンでリアルタイムで生成できれば、なんとなくアナログっぽいEGとして使えるかもしれない。

トリガ信号


リズムマシンやベースマシンを作ってあるので、これらと絡ませて遊びたい。Kickを楽曲でつかう場合はだいたい4分音符。

リズムマシンにTrigger信号を出してもらってこれを拾って1音分出力できればいい。音程はシーケンサーから制御する必要はないと思うが、アナログ・シンセで言うGate信号を使うようにすれば音の長さをコントロールできそうだが。

MIDI-CVコンバーターを作ればPCのDAWからでも制御できそう。

リズムマシンとのミックス


シンバルとう金物はとりあえずリズムマシンから出力して、アナログ的にキックマシンとMixする。キックだけ別系統で出力すれば単体で歪み系のエフェクトが掛けられると思うので、これも楽しみ。

妄想は広がりますが、ひとりアジャイルが開発スタイルなので一番かんたんそうなところからやっていくつもりです。

2017年5月28日日曜日

デジタルフィルタ MicroModeler DSPを使ってみる

デジタルフィルタは、リズムマシンを作った時PSoC5 LPのDFBを使ったことがある。(参考:「PSoC 5LPのデジタル・フィルタを使ってみる」「PSoC 5LPのデジタル・フィルタを使ってみる CPUで波形生成」)

PSoC 5LPのDFBはPSoC CreatorのFilterコンポーネントを使うとかんたんにデジタルフィルタを実装できるが、コアがCortex-M3なので浮動小数点演算がなかなかしにくい。(もうすぐPSoC6(Cortex-M4 & Cortex-M0+)が出そうなので期待しています。)

デジタルフィルタの設計ツールとして「MicroModeler DSP」というツールを見つけたので試してみた。コミュニティ版は非商用なら無償で使える。

デジタルフィルタの種類


「音遊び!Blackfin DSP基板でディジタル信号処理初体験」の付録についているAnalog DevicesのBlackfinを使ったボードでデジタルフィルタを試したことがある。



この本はDSPの使い方入門といった感じで、信号処理の理論的なことにはあまり触れられていないが、DSPとはいかなるもので、どうやってプログラミングすればいいのか?という取っ掛かりにはちょうどいいと思う。

DSPの実行環境はなかなかないので付録基板ですぐに試せるのが大きなメリット。

<追記:2017.05.31>
amazonの転売はふっかけすぎですが、marutsuでは新品を定価販売されているようです。
</追記>

最初の方の三章を使って、移動平均、FIR(有限インパルス応答)、IIR(無限インパルス応答)の説明がなされている。

これにしたがって、MicroModeler DSPで3つのフィルターを試してみた。

MicroModeler DSPではコードを自動生成してくれるので、Visual StudioでWindowsのコンソールプログラムを作り、出力をExcelでグラフ化してみた。

デジタルフィルタの方式が変わっても、インターフェイスは変わらないようなので、

#define LOOP    (2)
#define PERIOD  (50)

int _tmain(int argc, _TCHAR* argv[])
{
    filter1Type* filter = filter1_create();

    printf("Sample\tInput\tOutput\n");
    int count = 0;
    for (int i = 0; i < LOOP; i++) {
        float in = 1.0f;
        for (int j = 0; j < PERIOD / 2; j++) {
            filter1_writeInput(filter, in);
            float out = filter1_readOutput(filter);
            printf("%d\t%f\t%f\n", count, in, out);
            count++;
        }
        in = 0.0f;
        for (int j = 0; j < PERIOD / 2; j++) {
            filter1_writeInput(filter, in);
            float out = filter1_readOutput(filter);
            printf("%d\t%f\t%f\n", count, in, out);
            count++;
        }
    }

    return 0;
}

というコードで矩形波を入力してフィルタ応答を出力してみた。

移動平均


一番かんたんなLPFで実装が楽で高速。パラメータは前の値を保持しておくバッファ長のみ。


横軸が時間で、縦軸が出力値。かんたんなだけあって過渡応答も線形。

FIR(Lth Band Filter)


フィードバックなしのデジタルフィルタ。フィードバックしないので安定的で発振しない。カットオフ周波数がサンプリング周波数の1/Nに限定される。


スマホのファンクションジェネレータ等、デジタル機器の矩形波出力によく似た応答だと思う。

IIR(バターワース特性)


フィードバックありでアナログフィルタに近い応答をする。設計をミスると発振する。


Orderが4の場合の過渡応答で、4次LPFに相当すると思う。FIRに比べるとアナログ回路で見慣れた波形。

Orderを1にしてみる


Orderを1にした場合は、多少きれいすぎるがCRの1次LPFの過渡応答にそっくりさんだ。

Github:
https://github.com/ryood/DigitalFilterTest

少し触っただけだが、デジタルフィルタについてほとんど知識がなくても使えた。←画面に出てくる「Z-Plane」や「Transfer Fuction」が何なのかわからないレベル(^q^;

ゼロや極で特性を決めることもできるようだ。←これは制御工学でやったので名前だけは知ってるレベル(^q^:

生成されるコードは、標準Cの他に、ARMのCMSISのライブラリを使ったものも出力できる。(IIRだとオプションでBuiquadsをDirect Form1にしてやる必要がある。)

「ARM + CMSIS」で生成されたコードを見ると

float32_t filter1_coefficients[10] =
{
// Scaled for floating point

    0.0979448726126829, 0.1958897452253658, 0.0979448726126829, 0.7973802425733677, -0.17423867505153404,// b0, b1, b2, a1, a2
    0.125, 0.25, 0.125, 0.8219434348269887, -0.34174007022989955// b0, b1, b2, a1, a2

};

//<中略>

 void filter1_init( filter1Type * pThis )
{
    arm_biquad_cascade_df1_init_f32(    &pThis->instance, filter1_numStages, filter1_coefficients, pThis->state );
    filter1_reset( pThis );

}

//<中略>

 int filter1_filterBlock( filter1Type * pThis, float * pInput, float * pOutput, unsigned int count )
{
    arm_biquad_cascade_df1_f32( &pThis->instance, pInput, pOutput, count );
    return count;

}

となっていてフィルターの演算はCMSISにまかせている。もしかしたらDSP付きのARMならDSPを使うようになってるのかもしれない?

また、標準Cでもfloat型だけではなく整数型(固定小数点型)のコードも出力してくれるようだ。FPUが付いていないCoretex-M0やM3で演算速度を上げたい場合にも使えるかも?

メモ:


デジタル的な波形をアナログチックにするために、(1- e^(-t/τ))みたいな関数を使って変換しようかと漠然と考えていたが、この用途にはIIRが使えるかもしれない。

多分IIRの方が速度的に有利な気がする。積分を数式で解くのはしんどいが、コンピューターを使って数値積分すれば近似的に解けるみたいな。

エンベロープ波形をMPU内部でアナログチックにするのに一度使ってみようか?

2017年5月26日金曜日

ベースマシンの音出し動画


BaseMachine(SVF DCF) → TS-OD1 → PT2399-Echo
RhythmMachine

MiniMixerでMixしてAudio I/F経由で録音してみた。Over Driveをかけているので音はダーティな感じになっています。

メモ:


一応、RhythmMachineとBaseMachineはsyncさせているが、ツッコミ気味な感じがしないでもない(^q^;

TS-OD1はバイパスが欲しい。

Filter Envelopeは使いづらいのでもうちょっと考えてみる。

シーケンサーは32Stepぐらい欲しいとこだが、いっそのことMIDIで長いパターンの再生やPOTの動きを記録できるようにしてみる?

2017年5月23日火曜日

ベースマシン フィルターにエンベロープを掛けてみる。

ファームウェアを改修してFilterのCutoffにエンベロープを掛けられるようにしてみた。

構想段階では、まずはエンベロープはVCAにかけて音量を変化させることだけを考えていて、フィルターの変調は「できたらやってみる」という努力目標にしていた。

アナログ的に値を設定するPOT×8パネルの中でエンベロープの初期音量を設定する「Level」ツマミはあまり使わないので、これをフィルターにエンベロープをかける量を調整する用途で使ってみることにしてみた。


ほんとは、VCAにかけるエンベロープとVCFにかけるエンベロープを分けて2系統にできればいいんだが、Nucleo F401のI/O pinが足りなくてこれ以上はかんたんに入力デバイスを増やせない。

スイッチでエンベロープをかける対象を選択するという方法も、エンベロープを設定するデバイスが「可変抵抗」なのでなかなかむずかしい。モードを切り替えると、現在のPOTの位置が別のエンベロープの値に反映されてしまう。

これはMIDI入力デバイスでもよくあり、高価なMIDI入力機器はスライドボリュームにモーターが仕込まれていてシーケンサーから送った値でツマミの位置を力ずくで変更するようになっている。さらにタッチ・センスも仕込まれていて人が触っているかどうか判別して、ツマミの位置制御の入力/出力を切り替えるようにもなっている。

さすがに今回はそこまでやるつもりはないので、できる範囲で(ファームウェアもあまりいじらない方向で)考えることにした。

エンベロープは1波形しか使えないので、VCAのエンベロープを浅くかけるか、深くかけるかを「FLT MOD」ツマミで調節するだけ。

↓シーケンサーのプログラムの一部

void updateTicks(int ticks)
{
    uint16_t level = EnvelopeGenerator.update(sequences[SequenceSender.getStep()].isTie());
    
    // Amp
    uint16_t ampLevel = level;
    if (sequences[SequenceSender.getStep()].isNoteOn())
    {
        ampLevel = ampLevel >> 1;
        if (sequences[SequenceSender.getStep()].isAccent())
        {
            ampLevel = ampLevel * (1.0f + ((float)UIController.getAccentLevel()) / 128.0f);
        }
    }
    else
    {
        ampLevel = 0;
    }
    AmpController.outDca(ampLevel);
    
    // Oscillator
    OscController.setFrequency10(SequenceSender.getFrequency10());
    OscController.outDco();
    
    // Filter Env Mod
    uint16_t cutoff16 = FilterController.getCutoff();
    uint8_t resonance = FilterController.getResonance();
    uint8_t mod = FilterController.getModLevel();
    float modCoeff = (float)mod / (float)(cutoff16 << 1);
    cutoff16 = cutoff16 * (1.0f + ((float)level / 0x8000) * modCoeff);
    if (cutoff16 > 255) {
        cutoff16 = 255;
    }
    FilterController.outDcf(cutoff16, resonance);
    
    if (ticks == 0)
    {
        EnvelopeGenerator.init(envelope);
        playingStep = SequenceSender.getStep();
        UIController.setPlayingStep(playingStep);
    }
}

シーケンサーの本体で1msごとにシンセ(DCO, DCF, DCA)に値を送っている部分。

BaseMachineのファームウェアは最初はArduino Unoでやっていたので基本的に16bit整数演算にしていたが、Nucleo F401はCortex-M4でFPU付きなのでFilterにエンベロープをかけるあたりは単精度浮動小数点演算で妥協した。

もう少し考えれば整数演算に落とし込めると思うが、なんと言ってもめんどくさい(@@;

Cortex-M4もM0とくらべて高いわけでもないし、次にシーケンサーを作るとしたらCortex-M4の浮動小数点数演算でどこまでできるかという話になるかもしれません。

mbed repository:
https://developer.mbed.org/users/ryood/code/BaseMachine/ revision:29

メモ:


DCAのエンベロープはDACのMCP4922で受けて電流値に変換し、OTAのNJM13700をDCAとして使っているので、自然と(あ、いやLPFを一回かましているのでわざとです)アナログチックな波形になっているが、今回はDigital POTのAD8403でデジタル的に受けているので、エンベロープ波形もデジタル的だと思う。過激なので面白いと言えば面白いですが。

演算で対数カーブにするのもコンセプトとずれるし、アナログ素子を通してなんとかならないかなあ。

今日はもう疲れたので次こそは音出し動画をつくります。

やったことを書き留めておかないと1週間後には何をやってたか忘れてしまいますゆえ。

2017年5月20日土曜日

OverDrive TS-OD1でけた


いつも使ってるデジカメが故障して写らなくなったのでiPadで撮影してみたが、被写界深度が浅いのか手ブレなのかちょっとボケ気味です。

今回もひとまず、プラケースに収めた。

回路図

C5、C6は0.33uFで実験していたが、0.22uFを仕入れて試してみると0.22uFの方がToneの効きが良かった。

オリジナルでOPAMP周りに0.1uF程度のデカップリングコンデンサが入っていなかったので、TS-OD1も入れていない。

基板図

部品面

抵抗がキンピが多いのは、ほとんどキンピしかストックしていないからで、深い意味はないです。

アルミ電解は出力のACカップリング用の10uFだけオーディオ用のものにした。0.22uF、1uFはTDKのMKTにした。

ハンダ面

メモ:


ベースマシンにかけると、TubeScreamerタイプの対称ダイオードの方が効きがいい。

ベースマシンのSVF DCFのレゾナンスとPT2399 DelayとOverDriveが合わさると、思ってもみない音の変化がある。

リズムマシンにも掛けたいからもう一個ぐらいいずれ作るかも。

2017年5月19日金曜日

Nucleo(mbed OS5)のSPI通信を検証してみる。

ベースマシンではNucleo(mbed)のSPIでIC間の通信を行っている。UI系とシンセの制御系でNucleoボードを分けてみたが、ボード間のSPI通信でエラーが発生してしまい、分離するのをあきらめた。(参考:このブログの2016年10月あたり)

mbed OS 5がリリースされた時期も重なって何かと混乱してしまった。

検証のため、mbed OS 5を使ってNucleo同士でSPI通信させてみてみた。

Master側プログラム
https://developer.mbed.org/users/ryood/code/mbed-os_SPITest_Master/

#include "mbed.h"

SPI spiM(D11, D12, D13);
DigitalOut cs(D10);

int main()
{
    printf("SPIMaster Test\r\n");

    spiM.format(8, 0);
    spiM.frequency(1000000);

    uint8_t sdata = 0;

    for (;;) {
        cs = 0;
        uint8_t rdata = spiM.write(sdata);
        cs = 1;

        printf("Master: sdata:%d rdata:%d ", sdata, rdata);

        uint8_t err = sdata - rdata;
        if (err != 1) {
            printf("err:%d", err);
        }
        printf("\r\n");

        sdata++;
        
        //wait_ms(100);
    }
}

Slave側プログラム
https://developer.mbed.org/users/ryood/code/mbed-os_SPITest_Slave/

#include "mbed.h"

#define UART_TRACE  (1)

SPISlave spiS(D11, D12, D13, A2); // mosi, miso, sclk, ssel

int main()
{
    printf("SPISlave Test\r\n");
   
    spiS.format(8, 0);
    spiS.frequency(1000000);
   
    uint8_t pdata = 0;
   
    for (;;) {
        if (spiS.receive()) {
            uint8_t rdata = spiS.read();
           
           
            #if (UART_TRACE)
            printf("Slave: rdata:%d", rdata);
           
            uint8_t err = rdata - pdata;
            if (err != 1) {
                printf(" err: %d", err);
            }
           
            printf("\r\n");
            #endif
           
            pdata = rdata;
           
            uint8_t sdata = rdata;
            spiS.reply(sdata);
        }
    }
}

NucleoのArduino Header同士をジャンパ線で直結すると通信はほぼほぼうまくいく。


UART出力

ブレッドボードを使って少し意地悪な状態にするとエラーが多発


UART出力

信号波形

直結

ch1:MOSI ch2:SCK

意地悪

ch1:MOSI ch2:SCK

意地悪のほうはSCKとMOSIの波形がずれているように見えるが、よくわからない(@@;
←MOSIは無通信時(CSがアクティブになっていない時)の状態は不定なので、クロック、信号線、CSを同時に測定しないとはっきりしない。

メモ:


まだわからないことだらけだが、SPI通信は配線の状況によって通信エラーが発生することはわかった。

ベースマシンではNucleoからシンセに回しているSPI信号をバス・バッファICのTC74HC541を入れて補強しているが、ケーブルが長いので通信エラーが発生している可能性は大きい。

できることならシンセを制御しているMPUはシンセの近くにしてUI系のMPUとは分けた方がいいのかも(@@?

2017年5月16日火曜日

OverDrive TS-OD1の基板設計

回路図

基板図

部品並べ

もう少し頑張ればC基板でも収まりそうですが、これぐらいで妥協。

前、LME49600HPAで仮におさめていたプラケースを使いまわして収納するつもりです。


休みの日にはんだ付けとテスト合わせて2日はかかりそうですが、息抜きに他のことをやりつつぼちぼちやっていきます。

2017年5月15日月曜日

OverDirve TS-OD1の設計

いつも適当な名前を付けていて後で呼び方に困っているので、今回は名前をつけてみた。その名も「TS-OD1」(^q^;

TubeScreamerを基本に、
ベースマシンで使いやすいように定数を多少変更。
対称ダイオードと非対称ダイオードをジャンパで切り替え可。
回路図

D3のダイオードをピンソケットで実装し、ダイオードを挿すかジャンパ線を挿すかで歪み方を切り替える。R1、R8、C4もピンソケットで実装するつもり。R1は入力レベル調整、R8、C4でクリッピング回路の増幅率(歪み方)と周波数特性を変えられる。

仮想GNDはオリジナルのように単にRで分圧しているだけ。

LTSpiceでシミュレーション


シミュレーション回路図

過渡解析

100Hz 1Vp-pのノコギリ波を入力して過渡解析した。Driveの値を変化させている。


AC解析

オリジナルに比べると、低域の減衰が少ない。

全体をブレッドボードで実験


電源部を含めて全体をつないでブレッドボードで実験してみた。

ブレッドボード配線図


9V電池を電源にしてみた。

出力波形


シミュレーションと同じように約1Vp-pのノコギリ波を入力してDrive POTを回して出力波形を測定してみた。

電源電圧:9.53V
電源電流:4.37mA

Level POT:最大
Tone POT:90%程度

Drive 20%程度

Drive 50%程度

Drive 80%程度

Drive 100%程度

メモ:


測定時は回路図にあるR15の10kΩとは別に、負荷抵抗として10kΩのRをつないでいる。

2017年5月14日日曜日

ProCo RATとOD-1をシミュレーションしてみる。

ProCo RATのDrive部


シミュレーション回路図

TubeScreamerに比べるとOPAMP周りの増幅回路にダイオードを入れるのではなく、コンデンサ入りの非反転増幅回路で味付けをした後に互い違いに入れたダイオードでクリッピングしているようだ。

過渡解析

TubeScreamerに比べると歪み方がガチガチで、おそらくこのタイプの方が効果はわかりやすいと思う。

AC解析

上が非反転増幅回路からの出力、下がダイオードでクリッピングしたあとの出力で、音色はクリッピングする前にほぼ決まっている。

ProCo RATのトーン部


シミュレーション回路図

過渡解析

AC解析

Toneは(R1+R2)/C1の一次LPFのRの定数で決めている。出力段がJ-FETなので味つけになってるのかどうか。

OD-1の出力部


OD-1のDrive部は定数が若干異なりますがTubeScreamerとほとんど一緒です。

シミュレーション回路図

OD-1にはToneの調整ができず、出力レベルのみ。U1あたりは1倍の反転増幅回路回路に1次LPFがくっついたもの。出力段のTrは2SC732GRというタイプらしい。

過渡解析

AC解析

2017年5月13日土曜日

Tube ScreamerのTone回路を実験してみる

Tube ScreamerのTone回路とLevel調節&バッファ回路をシミュレーションしてみた。

シミュレーション回路図

入力はDrive回路からの出力で、4.5Vの仮想GNDを基準とした波形になる。

Toneと書いてあるあたりのR9/R10のPOTでToneを調整し、Volumeと書いてあるあたりのR14/R15のPOTで出力振幅を調節。Q2のNPN Trのエミッタフォロワで出力を強化し、C9/R19でACカップリングして、DC成分を除去して波形をGNDレベルに戻している。

AC解析

AC解析を見ると、Toneのツマミの位置で1kHzあたりを持ちげる効果があるようだ。

過渡解析(ノコギリ波)

100Hzのノコギリ波を入力して過渡解析してみた。ノコギリ波がなまる(緑色)~エッジが強調(マゼンタ)まで波形が変化している。

Tone部の回路のシミュレーション


Toneと書いてあるあたりの回路構成は今まで見たことがないので、単体でシミュレーションしてみた。

シミュレーション回路図

OUT1、OUT2はPOTを左右にいっぱいに回した状態、OUT3はAC解析を見ながら中間値として値を決めた。

AC解析

ここの回路はHi-Passというか高域を持ち上げる回路として働いているようだ。

反転端子、非反転端子がバーチャル・ショートしているとしてノード間のインピーダンスを計算すれば、理屈でもわかりそうなもんだが、頭がこんがらがってよくわからない(^q^;

こういう回路で高域を持ち上げられると覚えてしまったほうがよさそうなきがする。

ここの回路でハイ上げの効果があって、元のシミュレーション回路図のR7/C5がFc≒724Hzの一次LPFなので、ハイ上げ回路と合わさって1kHzあたりを持ち上げるTone回路になっているんだと思う。

ブレッドボードで実験


C5,C7は手持ちの関係で0.33uFのフィルムコンにした。

OPAMP: NJM4580D
NPN: 2SC1814Y
電源: 5V安定化電源×2

20kΩのPOTの手持ちがなくて、10kΩ/BのPOTを使った。ここのPOTの値は周波数特性に絡むのであんまり適当な値を使えない。一応手持ちにある50kΩと10kΩでシミュレーションしてみると、10kΩの方が良さそうだった。



自作のファンクションジェネレータで100Hz/1Vp-pのノコギリ波を入力してToneのツマミを回して出力を見てみた。Volumeは最大。

ツマミを左いっぱい

ch1:入力 ch2:出力

入力は+5Vあたりを中心に振幅、出力はGNDを中心に振幅している。

ツマミを中点ぐらい

ツマミを右いっぱい

シミュレーションと似たような出力結果になっていると思う。

メモ:

OPAMPを使ったアクティブ・フィルタとバッファ回路を使えば似たような特性の回路は作れそうだが、なかなかアーティスティックな回路だと思った。

おそらくシミュレーター(や、ブレッドボードも?)がなかった時代に紙と鉛筆で計算してこういう回路を作っていたのだろうかと思うと感慨深いです。

敬意を表して、ディスクリートでやっているところはディスクリートで組んでみようと思います。