Standard MIDI file player for the eVY1 shield and analog joy stick

Dependencies:   DirectoryList SDFileSystem mbed

Fork of eVY1_SMF_player by Toyomasa Watarai

MicroSDカードからSMF(スタンダードMIDIファイル)を読み込み、データをシリアルでeVY1シールドに転送して再生します。 MIDIファイル形式は、Format 0のみ対応しています。アナログジョイスティックを使用してテンポとピッチの変更が出来るようにしました。

動作確認は、mbed FRDM-K64Fで行っています。

eVY1シールドをそのまま刺して使用できます(オンボードのMicroSDスロットを使います)。

eVY1を使用した場合、MIDIデータのCH.1は強制的にeVocalodによる歌声として使用されてしまうため(プログラムチェンジも不可)、強制的にCH.16に割り当てています。そのため、CH.16を使用しているMIDIファイルはデータ通りに再生する事が出来ません。

アナログジョイスティックの X Y データは、それぞれアナログ入力の A0, A1 に接続しています。

Revision:
1:c536df09d2e8
Parent:
0:12d69da08021
Child:
2:4bcf9c18896b
--- a/main.cpp	Sat Jul 18 01:40:09 2015 +0000
+++ b/main.cpp	Mon Jul 20 09:06:05 2015 +0000
@@ -1,3 +1,18 @@
+/**
+ *  Standard MIDI file player for the eVY1 shield
+ *
+ *  @author  Toyomasa Watarai
+ *  @version 0.1
+ *  @date    July-2015
+ *
+ *  This program parse MIDI format 0 files on SDCard
+ *  and plays the data using eVY1 shield
+ *
+ *  Ported by Arduino example code of the SWITCHSCIENCE, Thanks!
+ *  https://github.com/SWITCHSCIENCE/eVY1_Shield
+ *
+ */
+
 #include "mbed.h"
 #include "SDFileSystem.h"
 #include "DirectoryList.h"
@@ -15,6 +30,9 @@
 SDFileSystem sd(dp2, dp1, dp6, dp4, "sd"); // MOSI, MISO, SCK, CS
 RawSerial midi(dp16, NC);
 InterruptIn btn(dp9);
+#if defined(_DEBUG)
+#undef _DEBUG
+#endif
 
 #endif
 
@@ -69,7 +87,6 @@
         buf[2] = midi_read();
 #if defined(_NO_eVocaloid_)
         if ((buf[0] & 0x0f) == 0x0f) {    // CH.16
-            DEBUG_PRINT("*");
             return;
         }
         if ((buf[0] & 0x0f) == 0x00) {    // CH.1
@@ -118,6 +135,13 @@
                         disable_timer();
                         STATE = 2;
                         break;
+                    case 0x01:
+                    case 0x02:
+                        cnt = midi_read(); // len
+                        for(uint32_t i=0; i<cnt; i++)
+                            DEBUG_PRINT("%c", midi_read());
+                        DEBUG_PRINT("\n");
+                        break;
                     default:
                         cnt = midi_read(); // len
                         for(uint32_t i=0; i<cnt; i++)
@@ -146,7 +170,6 @@
     TIMER = 0;
     tempo = 500; // default value
 
-#if defined(_DEBUG)
     // Skip MIDI header
     for (uint32_t i=0; i<8; i++) {
         midi_read();
@@ -156,21 +179,19 @@
     format = (midi_read() << 8);
     format |= midi_read();
 
-    if (format != 0)
-        DEBUG_PRINT("This is not MID format 0 file!\n");
+    if ( format > 2) {
+        DEBUG_PRINT("This is not a MIDI format file!\n", format);
+        STATE = 2;
+        return;
+    } else {
+        DEBUG_PRINT("MIDI format : %d\n", format);
+    }
 
     uint32_t track;
     track = (midi_read() << 8);
     track |= midi_read();
 
-    if (track != 1)
-        DEBUG_PRINT("Number of tracks should be 1!\n");
-#else
-    // Skip MIDI header
-    for (uint32_t i=0; i<12; i++) {
-        midi_read();
-    }
-#endif
+    DEBUG_PRINT("Number of tracks : %d\n", track);
 
     // timebase
     delta_time = (midi_read() << 8);
@@ -190,11 +211,12 @@
 {
     STATE = 2;
 }
-    
+
 int main()
 {
     DEBUG_PRINT("Initializing...\n");
 
+    btn.mode(PullUp);
     btn.fall(&skip);
     midi.baud(31250);
 
@@ -215,11 +237,11 @@
         DEBUG_PRINT("directory could not be opened\r\n");
         return -1;
     }
-    
+
     for ( int i = 0; i < dir.size(); i++ ) {
         sprintf(buf, "/sd/%s", dir[ i ].c_str() );
 #else
-    for ( uint32_t i = 0; i < 10; i++ ) {        
+    for ( uint32_t i = 0; i < 10; i++ ) {
         sprintf(buf, "/sd/%d.mid", i);
 #endif
 
@@ -230,6 +252,14 @@
             timer.reset();
             timer.start();
             smf_init();
+            if ( STATE == 2 ) {
+                fclose(fp);
+#if defined(__MICROLIB) && defined(__ARMCC_VERSION) // with microlib and ARM compiler
+                free(fp);
+#endif
+                continue;
+            }
+
             DEBUG_PRINT("Now, playing (%s)... \n", buf);
             while (1) {
                 smf_main_loop();