Introduction: How to Make a Analog Modeling Synthesizer

About: 高専生やってます。電子工作、鉄道模型、GBA等・・・ コメントお待ちしてます。 I am electric engneering to study.I belive your comment.

I was make a analog modeling synthesizer by nucleo F401RE.

秋月電子通商でも販売されているNucleoF401REを使ってアナログモデリングシンセやってみました。

PC_3 and GND of F401RE connect to headphone(L-CH only).

今回はできるだけ簡単に作るために音はイヤホンからだし、PWMで音を鳴らしてます。L-CHのみをF40REのPC_3(一番右上のピン)につなぎ、comonをGNDに繋ぎました。

I was make a headphone dupont adapter.

イヤホンジャックをブレッドボードに挿せるようにしたやつを作成しました。これでイヤホンとボードを接続しています。

コネクタは千石電商や共立エレショップで購入可能かと思います。2550コネクタといった名前で売られてます。

私はaliexのgreatElectronicsから購入してます。ここのコネクタは安くて良いのですが、オスピンは半田で補強しないと折れます。

I use hardware F401RE , headphone, headphone adapter only.

output is interrupt per sample late.

サンプリングレートごとに割り込みをしまして、計算と出力を行ってます。

正確には割り込みでフラグを立てて、フラグを検出した時に処理してます。

all function easy Control . can not calc.

正弦波、三角波、矩形波の関数を用意してます。毎回、関数外で計算行ったことは不要です。

それぞれの関数は引数に周波数、DUTY、サンプリングレートと位相を保持する変数のアドレスを入れるだけです。

develop by mbed online compiler.

MBEDにて開発してます。ソースコードは下記アドレスよりご覧になれます。

this Mbed site can see all source.

https://developer.mbed.org/users/gitakichi/code/An...

今回はシンセっぽくリングモジュレーターをやってます。今後、楽器として使えそうなモノを製作しようと思います。

Step 1: Sin-wave

E = sin(ωt+θ) mean sin wave at electric circuit.

上記の式で正弦波を表すことが出来ます。

ω is angular velocity.

ω = 2πf

ωは角周波数で一般には2πfとされます。

f is freq.

fは周波数

t is time.

tは時間です

θ is firstest phase.

θは初期位相です。

I use under formura.

今回は初期位相は不要ですので下記の式で

E = sin(2 * 3.14 * f * t).

under is Program.

下記に正弦波のソースを示します。

double sin_osc(double late,double freq_out,double &ift)
{

double data;

data = sin(6.28 * ift);

ift += late * freq_out; if(ift > 1) ift--;

return data;

}

Step 2: Square-wave

under is square-wave Program.

下記に矩形波のソースを示します。全部の関数で位相を保持する変数のアドレスを引数に渡してますのでこの関数に同じ引数を入れて実行するだけで波形が出力されます。

double square_osc(double late,double freq_out,double duty,double &ift)

{

double data;

if(duty > ift) data = 1; else data = -1;

ift += late * freq_out; if(ift > 1) ift--;

return data;

}

Step 3: Triangle-wave

under is triangle wave Program.三角波ですdutyは0.1から0.9で入れてください。dutyに1を入れると正常に動作しない可能性が有ります。dutyの0.1付近と0.9付近ではのこぎり波に近いものになります。

double triangle_osc(double late,double freq_out,double duty,double &ift)

{

double data; if(ift < duty) data = 2 * (ift * (1 / ift) - 0.5); else data = 2 *( (1 / (1 - duty)) * (1 - ift) - 0.5);

ift += late * freq_out; if(ift > 1) ift--;

return data;

}

Step 4: All Source Code

#include "mbed.h"

Ticker flipper; PwmOut mypwm(PC_8); DigitalIn sw(USER_BUTTON);

//duty must input 0.1-0.9 bool flip_flag;

void flip() { flip_flag = 1; }

double sin_osc(double late,double freq_out,double &ift) { double data;

data = sin(6.28 * ift);

ift += late * freq_out; if(ift > 1) ift--;

return data; } double square_osc(double late,double freq_out,double duty,double &ift) { double data;

if(duty > ift) data = 1; else data = -1;

ift += late * freq_out; if(ift > 1) ift--;

return data; } double triangle_osc(double late,double freq_out,double duty,double &ift) { double data; if(ift < duty) data = 2 * (ift * (1 / ift) - 0.5); else data = 2 *( (1 / (1 - duty)) * (1 - ift) - 0.5);

ift += late * freq_out; if(ift > 1) ift--;

return data; }

int main() { double data,late,ift_1,ift_2; late = 20 * 0.001 * 0.001;

mypwm.period_us(20); flipper.attach_us(&flip,20);

while(1) {

if(flip_flag == 1) {

data = (sin_osc(late,1200,ift_1) * sin_osc(late,1210,ift_2)) + 1; mypwm.write( data / 20 );

flip_flag = 0; } } }

Step 5: Reference