F401REにてアナログモデリングシンセもどきを作ってみました。 リングモジュレーターっぽいことやってみてます。正弦波、三角波、矩形波の関数が用意してあります。sin(2pift)のftをサンプリングレートごとに積分したものをiftとしてます。iftのポインタを関数に与えるだけで特に計算は入りません。
Diff: main.cpp
- Revision:
- 8:ce5b480a2646
- Parent:
- 7:725b3bc34e7e
--- a/main.cpp Fri Jul 22 13:26:16 2016 +0000 +++ b/main.cpp Fri Jul 22 14:55:29 2016 +0000 @@ -4,8 +4,8 @@ PwmOut mypwm(PC_8); DigitalIn sw(USER_BUTTON); -#define sound_duty 0.1 +//duty must input 0.1-0.9 bool flip_flag; void flip() @@ -13,48 +13,57 @@ 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 ft,data,late; - int freq_out = 5000; + 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) { - //のこぎり波 - if(sw == 0) data = ft; - - //のこぎり波、下り - //else data = 1 - ft; - - //正弦波 - //else data = sin(6.28 * ft) + 1; - //三角波 - - else { - if(ft < sound_duty) data = ft * (1 / sound_duty); - else data = (1 / (1 - sound_duty)) * (1 - ft); - } - - //矩形波 - /* - else{ - if(ft < sound_duty) data = 1;//thをいじればduty変わりそう - else data = 0; - } - */ + data = (sin_osc(late,1200,ift_1) * sin_osc(late,1210,ift_2)) + 1; mypwm.write( data / 20 ); - ft += late * freq_out; - if(ft > 1) ft--; - flip_flag = 0; } }