12-polyphonic "chiptune" MIDI synthesizer for LPC1768 (Standalone version)

Dependencies:   ClockControl PowerControl mbed

Files at this revision

API Documentation at this revision

Comitter:
kayekss
Date:
Tue Dec 23 21:50:53 2014 +0000
Parent:
5:7bc917d03bd6
Commit message:
Supports "Panic on offline" feature when using MIDI-port input

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/main.cpp	Tue Dec 09 16:13:06 2014 +0000
+++ b/main.cpp	Tue Dec 23 21:50:53 2014 +0000
@@ -23,6 +23,7 @@
 Ticker            t1ms;
 Ticker            tSample;
 volatile uint32_t __countMs;
+volatile uint32_t __lastActiveSenseReceivedMs;
 bool              serSource;
 GeminiCore        gemCore(NUM_INSTRUMENT_IN_PERFORMER, SAMPLING_RATE);
 RingBuffer<char>  buffer(BUFFER_LENGTH);
@@ -52,6 +53,8 @@
         // Discard if input byte is an active sensing message
         if (c != 0xfe) {
             buffer.write(c);
+        } else {
+            __lastActiveSenseReceivedMs = __countMs;
         }
     }
 }
@@ -115,6 +118,7 @@
     
     // Start Timer
     __countMs = 0;
+    __lastActiveSenseReceivedMs = __countMs;
     t1ms.attach_us(&count1ms, 1000);
     
     // Start playback & attach interrupt
@@ -122,23 +126,33 @@
     tSample.attach_us(&sampleOut, 1000000 * clockUpRatio / SAMPLING_RATE);
 }
 
+void panic() {
+    for (uint8_t i = 0; i < NUM_INSTRUMENT_IN_PERFORMER; i++) {
+        gemCore.noteOff(i);
+        noteSent[i].noteOnMs = 0;
+        noteSent[i].channel = 0;
+        noteSent[i].noteNumber = 0;
+        noteSent[i].velocity = 0;
+    }
+}
+
 void consoleOperations(uint8_t c) {
     switch (c) {
-    case 'b':
+    case 'b':  // Check buffer
         checkBuffer();
         break;
-    case 'e':
+    case 'e':  // Toggle event dump
         if (dumpMode != DUMP_EVENTS) {
             dumpMode = DUMP_EVENTS;
         } else {
             dumpMode = DUMP_NOTHING;
         }
         break;
-    case 'f':
+    case 'f':  // Flush buffer
         buffer.flush();
         console.printf("* Buffer flushed.\r\n");
         break;
-    case 'i':
+    case 'i':  // Toggle Instrument dump
         if (dumpMode == DUMP_INST) {
             dumpMode = DUMP_INST_DETAIL;
         } else if (dumpMode == DUMP_INST_DETAIL) {
@@ -147,17 +161,10 @@
             dumpMode = DUMP_INST;
         }
         break;
-    case 'p':
-        // Panic
-        for (uint8_t i = 0; i < NUM_INSTRUMENT_IN_PERFORMER; i++) {
-            gemCore.noteOff(i);
-            noteSent[i].noteOnMs = 0;
-            noteSent[i].channel = 0;
-            noteSent[i].noteNumber = 0;
-            noteSent[i].velocity = 0;
-        }
+    case 'p':  // Panic
+        panic();
         break;
-    case 'r':
+    case 'r':  // Print received MIDI bytes
         console.printf("* Received MIDI bytes: %u\r\n", receivedBytes);
         break;
     default: break;
@@ -180,22 +187,22 @@
         
         statePanic = swPanic;
         
-        // Panic (all note off and flush buffer)
+        // Panic and flush buffer
         if (!statePanic && prevstatePanic) {
             buffer.flush();
-            for (uint8_t i = 0; i < NUM_INSTRUMENT_IN_PERFORMER; i++) {
-                gemCore.noteOff(i);
-                noteSent[i].noteOnMs = 0;
-                noteSent[i].channel = 0;
-                noteSent[i].noteNumber = 0;
-                noteSent[i].velocity = 0;
-            }
+            panic();
         }
         
         // Preserve this time's switch states
         prevstatePanic = statePanic;
     }
     
+    // Panic on active sensing failure
+    if (serSource && (__countMs > __lastActiveSenseReceivedMs + 400)) {
+        __lastActiveSenseReceivedMs = __countMs;
+        panic();
+    }
+    
     // Parse MIDI messages
     parseMessage(buffer);