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

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

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

Tube ScreamerのDrive回路を実験してみる(修正)

前回のオシロの測定値がおかしかったので計り直してみた。入力レベルが大きいとすぐにダイオードが飽和してガッチリ歪んでしまうので、出力側のプローブのx10とx1の切り替えを間違えていたのが原因だと思う。

測定条件は同じだが、出力レベルが小さいのでオシロの機能で20MHzにアナログ帯域制限し、メモリも1kにしてノイズを除去してみた。

Tube Screamer風(対称ダイオード)


R5:10kΩ

ch1:入力 ch2:出力

R5:47kΩ

R5:100kΩ

R5:220kΩ

R5:330kΩ

R5:470kΩ

OD-1風(非対称ダイオード)


R5:10kΩ

R5:47kΩ

R5:100kΩ

R5:220kΩ

R5:330kΩ

R5:470kΩ

シミュレーションより若干振幅が大きいが、まあこんなもんだと思う。