This program can confirm several command for eVY1 Sheeld by character. mbed and eVY1 Sheeld connect only 5V/3.3V/GND/tx(p9)

Dependencies:   mbed

Fork of eVY1Sheld_test_for_LPC1768 by Yuji Notsu

Revision:
1:139a18be7b78
Parent:
0:35804e977865
--- a/main.cpp	Tue Nov 19 16:01:17 2013 +0000
+++ b/main.cpp	Mon Nov 25 13:10:02 2013 +0000
@@ -1,7 +1,30 @@
+////////////////////////////////////////////////////////
+// eVY1 Sheeld Program
+//  mml_play.ino
+//           auther Shinichi-Ohki
+//           Copyright(c) 2013 Yamaha Corporation
+//           Copyright(c) 2013 Switch Science
+// CDEFGAB(ドレミファソラシド)  対応
+// 音符の後ろの長さの数字       対応
+// .  付点(1.5倍)               対応
+// R  休符                      対応
+// T  テンポ                    対応
+// V  ボリューム                対応
+// L  長さセット                対応
+// O  オクターブ変化            対応
+// <  1オクターブ下げる         対応
+// >  1オクターブ上げる         対応
+// P  パン                      未着手
+// #  シャープ                  たぶん対応
+// &  タイ                      未着手
+// P  ポルタメント              未着手
+// 2013/11/25 : modified for mbed1769
+////////////////////////////////////////////////////////
 #include "mbed.h"
  
 Serial evy1(p9, p10); // tx, rx configured for LPC800-MAX
 //Serial evy1(PTA2, PTA1); // tx, rx configured for FRDM-KL25Z
+DigitalOut myled(LED1);
  
 // DO NOT EDIT!!
 const char* phoneticSymbols[] = {
@@ -24,8 +47,37 @@
  
 //lylics
 //さんまのうたがきこえてくるよ
-int lylics[]={10,47,30,24,2,15,50,6,9,3,18,7,42,39};
-char mml[] ="CDEFEDC EFGAGFE";
+//int lylics[]={10,47,30,24,2,15,50,6,9,3,18,7,42,39};
+//char mml[] ="CDEFEDC EFGAGFE";
+
+// 歌詞
+//int voice[] = {25,31,25,31,25,31,1,30,25,31,25,31,30,0};
+int voice[] = {
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,
+  0,1,2,3,4,5,6,7,8,9,
+  0,0,0,0,0,
+  0,1,2,3,4,
+  5,6,7,8,9,
+  10,11,12,13,14,
+  50,50,50,50
+};
+//int voice[] = {6,47,9,47,5,47,9,47,6,47,9,47,5,47,9,47};
+// メロディ
+//char melody[] = "R1T60L8O6EC>G<CDGGGDED>G<CC4";
+char melody[] = "o5cdefgab<cdefgab<co5v1cv3cv7cv15cv31cv63cv127v8cccccccccccrcrrcrrrcrrrrcrrrrrl1cl2cl4cl8cl16cl32cl1rt10crt20crt30crt40crt50crt40c16c8c4c2c1r2l2crc2rc2.rc.";
+//char melody[] = "T80L4O5FF32AA32GG32CC16RCC32GG32AA32FF32";
+//--------------------------------------------
+
+char tempo,tempo_now;
+char volume,volume_now;
+char octave,octave_now;
+char current_time,time_now;
+int temp_int;
+int melody_counter;
+char old_key;
+char time_table[] = {0,32,16,0,8,0,0,0,4,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
+
  
 void Short_Message(int cmd, int d1, int d2) {
   evy1.putc(cmd);
@@ -34,63 +86,156 @@
 }
  
 // send lylics
-void lylic_send(int num){
+void send_voice(int num){
   //hedaer
+  //manual page.8 eVocaloid Phonetic symbols
   evy1.putc(0xF0);
   evy1.putc(0x43);
   evy1.putc(0x79);
   evy1.putc(0x09);
   evy1.putc(0x00);
   evy1.putc(0x50);
-  evy1.putc(0x10);
+  evy1.putc(0x10); //1m Mode m=0(replace)/m=1(append)
   
+  //The number of data have to be under 128byte
   for(int i=0;i<num;i++){
     if(i != 0) evy1.putc(0x2c); // 0x2c is separator
-    evy1.printf(phoneticSymbols[lylics[i]]);
+    evy1.printf(phoneticSymbols[voice[i]]);
   }
   //footer
   evy1.putc(0x00);  // footer for NSX-1
   evy1.putc(0xF7);  // footer of MIDI sys-ex
 }
+
+void read_num() {
+  bool flag = true;
+  temp_int = 0;
+  while (true) {
+    if ((melody[melody_counter + 1] >= '0') && (melody[melody_counter + 1] <= '9')) {
+      temp_int = temp_int * 10 + melody[++melody_counter] - '0';
+      flag = false;
+    } else {
+      if (flag == true) temp_int = -1;
+      else melody_counter++;
+      break;
+    }
+  }
+}
  
  
 int main() {
-  int key = 0x3c; //C
- 
+  //int key = 0x3c; //C
+  tempo = 40;
+  current_time = 4;
+  volume = 5;
+  octave = 4; 
   evy1.baud(31250); // MIDI speed
   wait(5); // waiting for eVY1 module boot up
  while(1)
  {
-  //send lylics
-  int lylic_len = sizeof(lylics) / sizeof(lylics[0]);
-  lylic_send(lylic_len);    // sending lylics first
+   // 歌詞転送
+  int voice_len = sizeof(voice) / sizeof(voice[0]);
+  send_voice(voice_len);
  
-  int mml_len = sizeof(mml) / sizeof(mml[0]);
-  
-  for(int i = 0;i< mml_len ;i++){
-    char c = mml[i];
-    if(c >= 'a' && c <='z') c-= 0x20;
-    if((c>='A' && c<='Z')||c=='<'||c=='>'){
-       //key send
-       if(i!=0){
-         Short_Message(0x90,key,0x7f);   
-         wait(0.5);
-       }
-       key= 0x3c; 
- 
-        switch(c) {
-            case 'C': break;
-            case 'D': key+=2; break;
-            case 'E': key+=4; break;
-            case 'F': key+=5; break;
-            case 'G': key+=7; break;
-            case 'A': key+=9; break;
-            case 'B': key+=11; break;
-            default: break;
+  int melody_len = sizeof(melody) / sizeof(melody[0]);
+  // MML解析&PLAY
+  for (melody_counter = 0;melody_counter < melody_len - 1;melody_counter++) {
+    bool flag = true;
+    while (flag) {
+      char c = melody[melody_counter];
+      if ((c >= 'a') && (c <= 'z')) {  // 小文字を大文字に補正
+        c -= 0x20;
+      }
+      if (((c >= 'A') && (c <= 'G')) || (c == 'R')) {  // 音符または休符
+        int time_temp;
+        if (c != 'R') {
+          char table[] = {9,11,0,2,4,5,7};  // A,B,C,D,E,F,G
+          old_key = table[c - 'A'] + octave_now * 12;
+          if (melody[melody_counter + 1] == '#') {
+            old_key++;
+            melody_counter++;
+          }
+          Short_Message(0x90,old_key,volume_now);  // 鳴らす
+        } else {
+          Short_Message(0x80,old_key,volume_now);  // 止める
+        }
+        read_num();
+        if (temp_int != -1) {
+          if ((temp_int > 0) && (temp_int <= 32)) {
+            melody_counter--;
+            time_temp = time_table[temp_int];
+          } else {
+            myled=1;
+            while(true) {}
+          }
+        } else {
+          time_temp = time_table[time_now];
+        }
+        if (melody[melody_counter + 1] == '.') {
+          time_temp = time_temp * 15 / 10;
+          melody_counter++;
         }
+        wait_ms(tempo_now * time_temp);  // 通常の音符長
+        flag = false;
+      } else {  // 音符以外
+        switch (c) {
+          case 'T':  // テンポのセット(5~100)
+            read_num();
+            if ((temp_int == -1) || (temp_int < 5) || (temp_int > 100)) {
+              myled=1;
+              while(true) {}
+            } 
+            tempo_now = (char)temp_int;
+            break;
+          
+          case 'V':  // ボリュームのセット(0~127)
+            read_num();
+            if ((temp_int == -1) || (temp_int < 0) || (temp_int > 127)) {
+              myled=1;
+              while(true) {}
+            } 
+            volume_now = (char)temp_int;
+            break;
+          case 'O':  // オクターブのセット(0~10)
+            read_num();
+            if ((temp_int == -1) || (temp_int < 0) || (temp_int > 10)) {
+              myled=1;
+              while(true) {}
+            } 
+            octave_now = (char)temp_int;
+            break;
+          case '>':  // オクターブ1下げる
+            if (octave >= 0) {
+              octave_now--;
+              melody_counter++;
+            } else {
+              myled=1;
+              while(true) {}
+            }
+            break;
+          case '<':  // オクターブ1上げる
+            if (octave <= 10) {
+              octave_now++;
+              melody_counter++;
+            } else {
+              myled=1;
+              while(true) {}
+            }
+            break;
+          case 'L':  // 音の長さのセット(1,2,4,8,16,32)
+            read_num();
+            if ((temp_int > 0) && (temp_int <= 32)) {
+              time_now = temp_int;
+            } else {
+              myled=1;
+              while (true) {}
+            }
+            break;
+        }
+      }
     }
   }
-  Short_Message(0x90,key,0x7f);   // note on message. 0x90=1ch, 0x7f=Velocity
+  Short_Message(0x80,old_key,volume_now);  // 止める
   wait(0.5);
  }
 }