Srempy

03s_242_1srempy.jpg
デジタルエフェクターというとディスプレイをつけたくなるもので、ポットなしでスイッチのみを使って操作するというエフェクターを製作しました。精度よく角穴加工するのはかなり大変なので、Tabby's工房さんにお願いしました。

▽ディスプレイ・スイッチ基板レイアウト
03s_242_2srempyL.png
いつものようにチャタリング防止を行っています。OLEDディスプレイ基板用押ボタンスイッチは秋月電子で購入しました。

DSP基板はOwm Pedalと同じものを使用しています。下写真のように合体させます。
03s_242_3srempyi.jpg

ディスプレイの詳細は前回記事をご覧ください。スイッチ操作は割り込みではなくメインループで処理しています(GitHubはこちら)。エフェクトオフ時にはスイッチの反応が速くなりますが、実用上問題ないので特に対処していません。▲▼スイッチ長押しでフラッシュメモリにパラメータ保存できます。下記ページの内容を使わせていただきました。
sora lab - STM + HAL Flashの書き込み・読み込み

エフェクトプログラムはもちろん変え放題ですが、今回私が考えたものを紹介したいと思います。※信号処理は旧処理方法(TxRxCpltCallback関数利用なし、16ビット)のままです。



アナログ回路でのフィルタ設計は複雑になる場合が多く、コンデンサの容量値も限られています。また、リアルタイムに動かすとなると可変抵抗やフォトカプラを使うぐらいしか選択肢がありません。デジタル信号処理でのフィルタについては計算方法が確立しているため、専門知識がなくとも設計可能で、任意の定数を動かすこともできます。計算式は下記ページのものを利用させていただきました。
C++でVST作り - 簡単なデジタルフィルタの実装

フェイザーはノッチフィルタがかかったような周波数特性で、谷となる周波数が動いています(参考ページ→MXR Phase 90 Analysis)。今回はこの特性をピーキングフィルタを使って再現、発展させたエフェクトを考えました。フェイザーとワウを合わせたような効果で、5つのモード(STD、SOFT、INV、HIGH、LOW)があります。名前の由来は3つ(Three)のピーキングフィルタ(Peaking Filter)です。

<STD・SOFTモード>
03s_242_4srempyF1.png
SOFTモードでは、単純に谷となるフィルタを2つかけています。谷と谷の間は減衰し、スッキリとした感じとなります。STD(スタンダード)モードは、Phase 90の特性に近づけています。うねり感を得るためには、2つの谷の間に山が必要なようです。ちなみに2つの谷の間隔が広いとユニヴァイブのコーラスモードっぽい音になります。谷となる周波数の揺れ幅や高低は、出音への影響は少なかったです。

<INV・HIGH・LOWモード>
03s_242_5srempyF2.png
フィルタを谷ではなく山にした場合、山が1つだとオートワウのようになります。山を2つにすると、クセは強いもののフェイザーっぽいシュワシュワ感が現れます。INV(インバース)モードでは、2つの山の間にさらに谷を追加しています。HIGH/LOWモードは谷と山を混ぜており、通常のフェイザーの高音域/低音域が強調された感じとなります。

<計算高速化>
BiQuadフィルタの係数は三角関数の計算が入っていて、そのままでは処理に時間がかかり過ぎると思われます。そのため表計算ソフトで近似式を算出するなどして対応しています。それでも実際のCPU使用率は70%程度となってしまいましたので、計算高速化についてはもう少し検討していく予定です。

タグ : 自作エフェクター 周波数特性 マイコン フェイザー 

Owm Pedal ソフトウェア編

自作デジタルエフェクター「Owm Pedal」の各設定、内部プログラミングをしていきます。
Owm Pedal ハードウェア編はこちら
内部データ、STM32CubeMX用iocファイルはGitHub



<ピン、クロック設定>
・ST-LINK接続
STM32CubeMX設定:System Core→SYS→Debug [Serial Wire]

上写真右上に見える2つのジャンパを外し、NucleoボードのST-LINK部分のみ使用します。SWDピンをそのままの順番でOwmボードへ接続できます。今回は外部から電源供給するため、3.3Vピンは接続しません。

・クロック源として外部水晶振動子を使用
STM32CubeMX設定:System Core→RCC→High Speed Clock (HSE) [Crystal/Ceramic Resonator]

▽クロック設定図

I2Sクロックは、オーディオサンプリングレート48kHzに対する誤差が少なくなるような設定としました(48×2048=98304)。

▽全ピン設定図

PC2はデバッグ時オシロスコープを接続する場合に利用しています。

<スイッチ>
割り込みではなくメインループで処理しています。今までAVRマイコンでやっていたカウントを増やす方式なので、長押しにも対応できます。

<ADC>
設定方法は過去記事(→NucleoボードのADCを使う)と同じで、チャンネル数が増えるだけです。ポットの値の取得は低速で構わないため、Sampling Time : 144 Cycles としています。

<I2S>
設定方法は過去記事(→NucleoボードとオーディオコーデックICとの通信)と同じですが、I2Cは不使用です。信号処理を優先するため、DMAのPriorityは[Very High]に、他の割り込みの優先度は下記の通り変更しました。
STM32CubeMX設定:System Core→NVIC→
 Time base: System tick timer→Preemption Priority [10]
 DMA2 stream0 global interrupt→Preemption Priority [5]

今回は受信したデータを信号処理後に送信することになります。I2Sの受信バッファに半分データがたまると「HAL_I2SEx_TxRxHalfCpltCallback」という関数(以下Half関数)が呼び出されます。しかしデータが全て溜まったときの「HAL_I2SEx_TxRxCpltCallback」は呼び出されないバグがあるようです。修正方法がわからない(あまり調べていません)ので、このままHalf関数のみで処理するようにしました。Half関数は送信と受信で2回起こってしまうので、送信側(DMA1 Stream4)の割り込みは無効化しています。

※処理方法を変更しました。→HAL_I2SEx_TransmitReceive_DMA使用時の割り込み修正(2019年3月25日追記)

下図はブロックサイズを32(ステレオなのでバッファ配列の要素数は64)で処理する場合のものです。配列の1グループは16...31, 0...15の順番となります。
03s_238_4owmI2S.png
最初の割り込みでグループAを一旦全て信号処理配列へ移し、次の割り込みで信号処理後のグループA(A')を送信バッファに送ります。このときA'[16]は送信されずA'[17]から送信されてしまいます。そこで処理後データA'を送信バッファへ代入するとき、1サンプルずらしています。もっとスマートに解決する方法(FIFO?)がありそうですが、現状問題が起こっていないので追求していません。遅延時間(レイテンシ)実測値は、ブロックサイズ16で1.7ms、32で2.4ms程度でした。

通常のやり方は、最初の割り込みの時にグループAのデータを1つずつ信号処理と送信を行うというものだと思います。しかしその場合たまに波形が乱れることがあったので、今回は少し回りくどい方法を採用しています。遅延が余計に発生してしまいますが…


<I2Sエラー対処>
たまにI2S通信がうまくいかないことがありましたが、フレームエラーというのが起こっていました。マスター(オーディオコーデックV4220M)がクロック送信する前にスレーブ側(マイコン)のI2S設定をする方がいいようです。デバッグ時は先にV4220Mが起動しているためかエラーが起こりやすく、エラー時はソフトリセットで対応するようにしました。本来はI2Sのみのリセットで済むかもしれませんが、DMAを使っているため全リセットするのが確実でしょう。電源を入れなおした際はV4220Mが後から起動するため、エラーはほぼ発生しません。とはいえオーディオコーデックのリセットピンはマイコンと繋げておくべきだったと思います。

<エフェクト処理>
main.cとmain.hのユーザーコード部分を編集する以外に、2つのファイル(fx.c、overdrive.c)を追加しています。詳細はコード内のコメントをご参照ください。エフェクトはとりあえずオーバードライブで、操作はフットスイッチ(バイパス)、左上ポット(LEVEL)、右上ポット(GAIN)、中央LEDのみ使っています。

overdrive.cでフィルタを使っていますが、過去のデータ(x1、y1)を利用するため、static修飾子を付けて前の計算結果を残したままにしておく必要があります。その結果、フィルタの数だけ関数を準備しておく状態となっています。今後複雑なエフェクトに対応するために、C++言語を使う必要性が出てきそうです。

タグ : 自作エフェクター マイコン 

Owm Pedal ハードウェア編

03s_237_1owmp.jpg
STM32F405という32ビットマイコンを搭載した自作デジタルエフェクター「Owm Pedal」です。名前は同じマイコンを搭載した既存のペダル「OWL Pedal」をもじってつけました。(Owm Pedal ソフトウェア編はこちら

オーディオコーデックはCS4220のセカンドソース品V4220Mです。サンプリングレートが48kHzまでですが差動入出力で価格が安く(秋月電子で240円)、エフェクターに最適だと考えました。

▽回路図
03s_237_2owms.png
<V4220M周辺>
データシートに入出力の回路が記載してあるのですが、抵抗値はよく使う値へと変更しました。バイアス電圧用に8.25kΩの抵抗があるところは、10kΩと100kΩ2個を並列にして8.33kΩとしています。

V4220Mのデータシートでは音量等をコントロールできそうに書いてありますが、実際はできないようです。マスターモードで動作させる場合は8番(DOUT)ピンに47kΩのプルダウン抵抗を入れます。また、CS4220のデータシートには電源オン時に27番(RSTN)ピンを10msの間LOWにしておくように書いてあるため、10uFのコンデンサを入れました。4・5・8・9番ピンからマイコンへ接続しますが、通信線の長さが短いためダンピング抵抗は不要かと思います。

<電源>
電源はレギュレータで以下のように分けました。
・マイコン用→デジタル3.3V(100mA)
・V4220M用→デジタル5V(20mA) デジタル3.3V(5mA) アナログ5V(60mA)
・OPA1678×3用→アナログ5V(20mA)
アナログ5V電源は通常分離する必要はありませんが、万一問題があったとき基板発注し直すのが嫌なので分けています。

▽DSP基板(Owm Board)レイアウトについて(KiCadデータはGitHubへ)
真ん中あたりに電源、上側がデジタル、下側がアナログという配置となっています。GNDは裏面を一面プレーンにしました。入力のカップリングコンデンサはPMLCAPを使っており、やや大きくて高価ですが歪率は下がるでしょう。残念ながらBIASに接続すべきところをGNDにつなぐというありがちな間違いをしてしまいましたので、内部写真では妙なジャンパー線が写っています(KiCadデータは修正済)。

ピン間隔が狭いICはパッドを1mm程度長くすると半田付けしやすいです。マイコンのピンはほとんど使えるように引き出しました。一応I2C用にプルアップ抵抗の取り付けもできます。マイコン上側のLEDはデバッグ用のつもりです。水晶振動子周りのパターン設計は下記ページを参考にしました。
水晶振動子 ガイド - RSオンライン

▽ポット類基板レイアウト
03s_237_3owml.png
ポット類基板と筐体はRasPd4のものを使いまわしました。回路図は描いていません。無理やりジャンパーを飛ばしてチャタリング対策の抵抗やコンデンサを入れました。下写真のように基板を合体させます。
03s_237_4owmpp.jpg

とりあえず何もエフェクトをかけないスルー音が出るようにプログラミングし、周波数特性と歪率を測定しました。歪率は、クリップしない最大入力約0.7Vrmsでの結果です。
03s_237_5owmf.png
100Hzの歪率が思ったより悪いですが問題ないでしょう。ノイズも測定限界以下だったので、歪み系エフェクトでもおそらく大丈夫だと思います。

タグ : 自作エフェクター レイアウト 回路図 マイコン 周波数特性 歪率 

RasPd3 操作方法

RasPd3の内部プログラムが概ね完成したので、自分用に取扱説明書のようなものを記載しておきます。LCDの文字が小さいですがなんとか大丈夫そうです。そのうちタップテンポやチューナーも実装できたらいいなと思っています。



03_230_1raspd3sh.jpg
<コントロール類と略称>
・左側ロータリーエンコーダ:LR
・中央ロータリーエンコーダ:CR
・右側ロータリーエンコーダ:RR
・左側押しボタンスイッチ:LS
・中央押しボタンスイッチ:CS
・右側押しボタンスイッチ:RS
・左側フットスイッチ:LF
・右側フットスイッチ:RF



<画面中央 緑色領域>
・エフェクトの種類とエフェクトパラメータを「プリセット」として8パターン(A~H)保存
(Pure Dataのプログラムを「パッチ」と呼ぶので、混同しないよう「プリセット」という呼称にしている。)
・プリセット1つにつき直列に6つのエフェクト(上3つ→下3つへ繋がっている)
・エフェクトは内蔵エフェクト20種類から選択(1つのプリセット内で複数重複使用は不可)
・エフェクトオン状態のエフェクトの名前右横に白色の丸印がつく
・「RF割当」を設定したエフェクトの名前右横に紫色の四角形がつく

※RF割当:プリセット内部モード(後述)時、RF押下でオンオフが切り替わるエフェクトを割り当てられる。
【例】ディストーション(オン)とコーラス(オフ)にRF割当を設定しておくと、RF押下時にディストーションをオフ、コーラスをオンという風に切り替えられる。

<画面右側 青色領域>
・プリセットの切替順番を3パターン保存
・フットスイッチで上下にプリセットを切り替える

<画面下側 灰色領域>
・エフェクトパラメータを表示
・エフェクトオンの場合、右に[ON]が表示される
・「RF割当」を設定している場合、右に[EN]が表示される



<2種類のモード(●プリセット切替、◆プリセット内部)と操作方法>
※LSを押しながらCSを押す:データ保存、押し続けるとシャットダウン(両モード共通)

●プリセット切替モード
複数のプリセットをフットスイッチで切り替えるモード。プリセット切替の順番を編集できる。

LR:カーソル左右移動
CR:カーソル上下移動
RR:プリセットA~Hまたは「X」を選択
※「X」を選択すると、フットスイッチでのプリセット切替時にX以降への切替がキャンセルされる。
【例】A→B→C→D→X→F→E→Gの場合…Dの後はA、Aの前はDに切り替わる。

LS:「プリセット内部モード」へ切替
CS、RS:なし
LF:プリセット切替(下側へ)
RF:プリセット切替(上側へ)

◆プリセット内部モード
1つのプリセット内で単独もしくは複数のエフェクトのオン・オフを切り替えるモード。エフェクトの種類やパラメータを編集できる。

LR:カーソル左右(エフェクト順番)移動
CR:カーソル上下(プリセット間)移動
RR:エフェクトの種類またはバイパスを選択
(エフェクトパラメータ編集時は、各ロータリーエンコーダでパラメータを増減させる)

LS:押す度にエフェクトパラメータ上段→エフェクトパラメータ下段→エフェクトの種類へと編集箇所切替
CS:「プリセット切替モード」へ切替
RS:「RF割当」設定/解除
LF:選択中のエフェクトをオン/オフ(オンの時、左側LED点灯)
RF:「RF割当」が設定されたエフェクトをオン/オフ

タグ : 自作エフェクター RaspberryPi 

2ループスイッチャー+絶縁型パワーサプライ

02_224_1lpswp.jpg
直列可2ループボックス+パワーサプライのスイッチが経年劣化のためか接触不良となっていました。もう一度配線をやり直す気にはなれなかったので、AVRマイコンを使ったスイッチャーとして生まれ変わらせました。当初はアナログスイッチICを使おうと思っていましたが、バッファーが必要で複雑になりすぎるようです。普通にメカニカルリレーを使うことにして、ついでにパワーサプライ部分はなんとなく絶縁型へと変更しました。

▽回路図
02_224_2lpsws.png
マイコンはATtiny13Aだとプログラムメモリが足りないので、ATtiny85です。ATtiny13Aの使用方法と同様に、Arduino IDEをATtiny85にも対応させます。参考ページ→Arduino IDE で ATtiny 他の開発

5Vレギュレーターは念のため78M05としていますが、9V入力であれば78L05でも大丈夫でしょう。リレー941H-2C-5Dのコイル駆動電流は30mAで、マイコンから直接流し続けるのは無理があるため、トランジスタを使用します。

▽レイアウト(KiCadデータはこちらへ)
02_224_3lpswl.png
パワーサプライ部分は別基板となっています。絶縁型DC-DCコンバータが大きいので内部がかなり窮屈になってしまいました。

▽Arduinoスケッチ(133行)
const int L_SW_PIN = 4;
const int R_SW_PIN = 3;
const int A_PIN = 1;
const int B_PIN = 2;
const int LED_PIN = 0;
int mode = 0; // 0→マニュアル 1→ex1 2→ex2
int L_sw_value = 0;
long L_sw_count = 0;
int R_sw_value = 0;
long R_sw_count = 0;
boolean A_state = false;
boolean B_state = false;

void setup() {
pinMode(L_SW_PIN, INPUT_PULLUP);
pinMode(R_SW_PIN, INPUT_PULLUP);
pinMode(A_PIN, OUTPUT);
pinMode(B_PIN, OUTPUT);
pinMode(LED_PIN, OUTPUT);
digitalWrite(A_PIN, HIGH); // 電源オン時LED点灯
delay(300);
digitalWrite(LED_PIN, HIGH);
delay(300);
digitalWrite(B_PIN, HIGH);
delay(300);
digitalWrite(A_PIN, LOW);
digitalWrite(LED_PIN, LOW);
digitalWrite(B_PIN, LOW);
}
// ループをオン
void on_A() {
A_state = true;
digitalWrite(A_PIN, HIGH);
}
void on_B() {
B_state = true;
digitalWrite(B_PIN, HIGH);
}
// ループをオフ
void off_A() {
A_state = false;
digitalWrite(A_PIN, LOW);
}
void off_B() {
B_state = false;
digitalWrite(B_PIN, LOW);
}
// ループのオンオフ切替
void chg_A() {
if(A_state) {
off_A();
} else {
on_A();
}
}
void chg_B() {
if(B_state) {
off_B();
} else {
on_B();
}
}
void loop() {
// 中央LEDの処理
if (mode == 0) {
digitalWrite(LED_PIN, LOW);
} else {
digitalWrite(LED_PIN, HIGH);
}

L_sw_value = digitalRead(L_SW_PIN);
if (L_sw_value == LOW) {
L_sw_count += 1;
} else {
L_sw_count = 0;
}

R_sw_value = digitalRead(R_SW_PIN);
if (R_sw_value == LOW) {
R_sw_count += 1;
} else {
R_sw_count = 0;
}

// 左フットスイッチ短押
if (L_sw_count == 10) {
if (mode == 0) {
chg_B();
} else if (mode == 1) {
mode = 2;
on_A();
on_B();
} else {
mode = 1;
off_A();
on_B();
}
}
// 右フットスイッチ短押
if (R_sw_count == 10) {
if (mode == 0) {
chg_A();
} else if (mode == 1) {
chg_A();
chg_B();
} else {
mode = 1;
on_A();
off_B();
}
}
// 左フットスイッチ長押
if (L_sw_count == 1000) {
if (mode == 0) {
mode = 1;
if(A_state) {
off_B();
} else {
on_B();
}
}
}
// 右フットスイッチ長押
if (R_sw_count == 1000) {
if (mode == 0) {
} else {
mode = 0;
off_A();
off_B();
}
}
delay(1);
}
スイッチに関する部分はMOSリレーバイパスと同じで、長押しの判定はsw_countを増やすだけです。メインループが1msごとなので長押しは1秒となるはずですが、処理に時間がかかるので実測では1.8秒ぐらいでした。

▽操作方法
 ・マニュアルモード(中央LED消灯)
   左スイッチ: ループBのオンオフ切替、長押しで特殊モードへ
   右スイッチ: ループAのオンオフ切替
 ・特殊モード(中央LED点灯)
   左スイッチ: ループA→ループBの順で直列接続
    ※直列切替後は右スイッチでAのみ、左スイッチでBのみオンの状態に戻る
   右スイッチ: ループAのみオンとループBのみオンを切り替え、長押しでマニュアルモードへ

タグ : 自作エフェクター 回路図 レイアウト マイコン 

管理人

管理人

自己紹介のページ
記事一覧
Twitter
GitHub

ブログ内検索
カテゴリー
タグ

自作エフェクター   レイアウト   回路図   歪み   周波数特性   マイコン   PureData   波形・倍音   RaspberryPi   エレキギター   アンプ   歪率   エフェクター自作方法   エレキベース   真空管   コーラス   ピックアップ   静音ギター   ヘッドフォンアンプ   擬似ギター出力   市販エフェクター   アコースティックギター   ブースター   コンデンサ   ソロギター   ポールピース   イコライザー   コンプレッサー   ビブラート   フェイザー   トレモロ   TAB譜   ディレイ   DIY_Layout_Creator   ワウ   オートワウ   バッファー   

最近の記事
最新コメント
Twitter
RSS
メールフォーム
当ブログに関するお問い合わせはこちらからお願いします。 ※FAQ(よくある質問)もお読みください。

お名前
メールアドレス
件名
本文

アクセスカウンター