1オクターブの比を求める |
---|
#include "mbed.h" Serial pc(USBTX, USBRX); // tx, rx int main() { pc.baud(115200); for(int n=0; n<=12; n++) { float scale = powf(2.0, (float)n/12.0f); pc.printf("%2d %8.5f\n", n, scale); } } |
0 1.00000 1 1.05946 2 1.12246 3 1.18921 4 1.25992 5 1.33484 6 1.41421 7 1.49831 8 1.58740 9 1.68179 10 1.78180 11 1.88775 12 2.00000右側の数字に440を掛ければ各々の周波数になります。もしイ長調だとすると。 ドは440、レは493.88、ミは554.37、ファは587.33Hz・・・・となります。
メインプログラム(main.cpp) | |
---|---|
#include "mbed.h" #include "Sound.h" int main() { Sound sound(p21); char kaeru[] = "C2D2E2F2E2D2C2B2E2F2G2A2G2F2E2B2C1B3C1B3C1B3C1B3C1C1D1D1E1E1F1F1E1B1D1B1C1B3"; char snd; int Length=strlen(kaeru); while (true) { for (int i = 0; i< Length; i++) { snd = kaeru[i]; if (('A' <= snd) && (snd <= 'G')) { if (snd == 'B') sound.stop(0.01); else sound.Tone(snd-'A'); } else if ('1' <= snd && snd <= '9') { double w = (snd - '0') * 0.2; wait(w); } } sound.stop(0.01); } } |
1 mbed用ヘッダーファイル 2 この音程用ヘッダーファイル 3 4 5 音はPWMを用いるのでp21に割り当てる 6 音程と音の長さデータ 7 8 音程データを一つ入れる変数 9 音程データの文字列の長さを求める 10 永久ループ 11 12 音程データの最初から最後までスキャンする 13 14 一文字取り出す 15 そのデータが音程だったら 16 17 それが'シ'だったら便宜的に休符にしてしまう 18 そうでなければ、その音程の音を出す 19 20 1~9の長さデータだったら 21 22 伸ばす時間を計算する 23 音をその時間鳴らす 24 25 26 音を止める 27 28 |
ヘッダーファイル(Sound.h) | |
---|---|
#include "mbed.h" class Sound { private: PwmOut* pwm; static int period[]; int tone; double dura; public: Sound(PinName pin); void Tone(int n); void Tone(int n, double dura); void stop(double w); }; |
1 mbed用ヘッダーファイル 2 3 クラスの宣言 4 5 プライベートなインスタンス変数の宣言 6 PWMのクラスオブジェクトのアドレスを入れる変数 7 ドレミファソラシドの周期データ、クラス変数にしている 8 音程データ 9 音の長さ 10 11 コンストラクタ 12 音を出す 13 duraの長さで音を出す 14 wミリ秒間音を止める 15 セミコロンを忘れずに |
C++クラスの本体(Sound.cpp) | |
---|---|
#include "Sound.h" int Sound::period[]= {4545,4050,3817,3401,3034,2864,2551,2273,2025, 1911,1703,1517,1432,1276,1136,1012, 956, 851, 758, 716, 638, 568, 506, 478}; Sound::Sound(PinName pin) { pwm = new PwmOut(pin); } void Sound::Tone(int n) { int p = period[n+7]; int half = p/2; pwm->period_us(p); pwm->pulsewidth_us(half); } void Sound::Tone(int n, double dura) { Tone(n); wait(dura); } void Sound::stop(double w) { pwm->pulsewidth_us(0); wait(w); } |
1 このクラスを宣言しているヘッダーファイルを読み込む 2 ドレミファソラシドの周期データ 3 どのオブジェクトでも同じなので、静的変数となっている 4 5 6 7 コンストラクタ 8 pinをPWM出力とするオブジェクトを作り、その先頭アドレスを 9 pwmに格納する。 10 11 12 Toneメソッド 13 14 周期データを取り出す 15 半周期を計算する 16 PWM周期を設定する 17 デューティサイクル50%となるように設定 18 19 Toneメソッド 20 21 音を出して 22 duraミリ秒時間待ちする 23 24 stopメソッド 25 26 デューティサイクルを0%として波形を出さないように設定 27 wミリ秒時間待ちする 28 |