/* ドレミ・メロディ 楽譜コード <オクターブ><音程><音長>...繰り返し <オクターブ> なし : ノーマルオクターブ - : 一つ下のオクターブ + : 一つ上のオクターブ <音程> d : Do(ド) d# : Do(ド#) r : Re(レ) r# : Re(レ#) m : Mi(ミ) f : Fa(ファ) f# : Fa(ファ#) s : So(ソ) s# : So(ソ#) l : La(ラ) l# : La(ラ#) t : Ti(シ) o : 休符 <音長> 2 : 2分音符 4 : 4分音符 8 : 8分音符 16 : 16分音符 */ //----------------------------------------------- // 楽譜コード(音程と長さ) //----------------------------------------------- char melody[] = "d8f8f2l16s16f8l4o4s4f2r4d2o4"; //----------------------------------------------- // 定数 //----------------------------------------------- // 音程コード #define TONE_PTN 12 #define TONE_DO 0 #define TONE_RE 2 #define TONE_MI 4 #define TONE_FA 5 #define TONE_SO 7 #define TONE_LA 9 #define TONE_TI 11 #define TONE_WAIT 12 int tonedata[] = { 131,139,147,156,165,175,185,196,208,220,233,247, //C3~B3 262,277,294,311,330,349,370,392,415,440,466,494, //C4~B4 523,554,587,622,659,698,740,784,831,880,932,988, //C5~B5 }; // 変数 int mpt = 0; //演奏位置 byte oc = 4; //オクターブ //----------------------------------------------- // 初期設定 //----------------------------------------------- void setup() { } //----------------------------------------------- // メインループ //----------------------------------------------- void loop() { // 楽譜コードを見てメロディの音程を順番に奏でる。 switch( getScore(mpt++) ) { case -1://終了 // メロディが終わったら1秒待って繰り返す。 delay(1000); mpt = 0; break; case '+': // オクターブを上げる if( oc < 5 ) oc++; break; case '-': // オクターブを下げる if( oc > 3 ) oc--; break; // 音 case 'd': playTone(TONE_DO); break; case 'r': playTone(TONE_RE); break; case 'm': playTone(TONE_MI); break; case 'f': playTone(TONE_FA); break; case 's': playTone(TONE_SO); break; case 'l': playTone(TONE_LA); break; case 't': playTone(TONE_TI); break; case 'o': playTone(TONE_WAIT); break; } } //----------------------------------------------- // 音を出す //----------------------------------------------- void playTone(int toneno) { int note = 4;//四分音符 // 楽譜解析。次が#なら半音上げる if( getScore(mpt) == '#' ) { toneno++; mpt++; } // 次は音の長さ? char score = getScore(mpt); if( '0' <= score && score <= '9' ) { note = 0; while( '0' <= score && score <= '9' ) { note = note * 10 + (score - '0'); mpt++; score = getScore(mpt); } } // 休符? if( toneno == TONE_WAIT ) { // 休符 tone(14, 0, 1000/note); } else { // 音を出す。 tone(14, tonedata[(oc-3)*TONE_PTN+toneno], 2000/note); } // 無音時間 delay(2600/note); } //----------------------------------------------- // 楽譜を得る //----------------------------------------------- char getScore(int mpt) { // 終了? if( mpt >= sizeof(melody) ) { return -1; } // データを得る。 return melody[mpt]; }