Dependencies:   mbed

Committer:
Midimetric
Date:
Tue Jun 07 13:32:20 2011 +0000
Revision:
0:71d791204057
Version 1.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Midimetric 0:71d791204057 1 #include "mbed.h"
Midimetric 0:71d791204057 2 #include <vector>
Midimetric 0:71d791204057 3 #include "MODSERIAL.h"
Midimetric 0:71d791204057 4
Midimetric 0:71d791204057 5 DigitalOut led[4] = { LED1, LED2, LED3, LED4 };
Midimetric 0:71d791204057 6 MODSERIAL SL[] = { MODSERIAL( p28, p27, 32, 256 ),
Midimetric 0:71d791204057 7 MODSERIAL( p13, p14, 32, 256 ),
Midimetric 0:71d791204057 8 MODSERIAL( p9, p10, 32, 256 )
Midimetric 0:71d791204057 9 };
Midimetric 0:71d791204057 10 Timer tempo;
Midimetric 0:71d791204057 11 bool HasBank, HasData, HasSysx; // flags to know if special type messages have a route defined. If not, these will be treated as plain cc or not stored.
Midimetric 0:71d791204057 12
Midimetric 0:71d791204057 13 int AvailableMemory()
Midimetric 0:71d791204057 14 {
Midimetric 0:71d791204057 15 register int low = 0;
Midimetric 0:71d791204057 16 register int mid = 0;
Midimetric 0:71d791204057 17 register int high = 8001;
Midimetric 0:71d791204057 18 void* p = NULL;
Midimetric 0:71d791204057 19
Midimetric 0:71d791204057 20 while( high - low > 1 )
Midimetric 0:71d791204057 21 if( ( p = malloc( mid = ( low + high ) / 2 ) ) == NULL )
Midimetric 0:71d791204057 22 high = mid;
Midimetric 0:71d791204057 23 else
Midimetric 0:71d791204057 24 {
Midimetric 0:71d791204057 25 free( p );
Midimetric 0:71d791204057 26 low = mid;
Midimetric 0:71d791204057 27 }
Midimetric 0:71d791204057 28 return low;
Midimetric 0:71d791204057 29 }
Midimetric 0:71d791204057 30
Midimetric 0:71d791204057 31 #include "midi.h"
Midimetric 0:71d791204057 32 #include "stack.h"
Midimetric 0:71d791204057 33
Midimetric 0:71d791204057 34 #include "memory.h"
Midimetric 0:71d791204057 35 MemList ML;
Midimetric 0:71d791204057 36
Midimetric 0:71d791204057 37 #include "filter.h"
Midimetric 0:71d791204057 38 FilterList FL;
Midimetric 0:71d791204057 39
Midimetric 0:71d791204057 40 #include "parse.h"
Midimetric 0:71d791204057 41
Midimetric 0:71d791204057 42 byte Last[] = {0,0,0}; // last message type for ports 1,2,3
Midimetric 0:71d791204057 43 MidiM* Previous[3][17] = {
Midimetric 0:71d791204057 44 {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL},
Midimetric 0:71d791204057 45 {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL},
Midimetric 0:71d791204057 46 {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}
Midimetric 0:71d791204057 47 }; // keep previous per channel 0-15 or not channeled 16, and per port. Call to Route must use Previous from same channel & port than Current.
Midimetric 0:71d791204057 48
Midimetric 0:71d791204057 49 void Data_in( int port /* 0,1,2*/ )
Midimetric 0:71d791204057 50 {
Midimetric 0:71d791204057 51 int v = SL[port].getc();
Midimetric 0:71d791204057 52 if( v == 0xFE ) return; // active sensing
Midimetric 0:71d791204057 53
Midimetric 0:71d791204057 54 led[port] = 1;
Midimetric 0:71d791204057 55
Midimetric 0:71d791204057 56 MidiM* current = NULL;
Midimetric 0:71d791204057 57 int beforelast = Last[port]; // backup in case of incomplete message
Midimetric 0:71d791204057 58 // new command
Midimetric 0:71d791204057 59 if( v > 0x7F ) // with explicit command
Midimetric 0:71d791204057 60 current = MidiCreateMessage( Last[port] = v );
Midimetric 0:71d791204057 61 else if( Last[port] ) // with implicit command (same than before)
Midimetric 0:71d791204057 62 {
Midimetric 0:71d791204057 63 current = MidiCreateMessage( Last[port] );
Midimetric 0:71d791204057 64 current->Append( v );
Midimetric 0:71d791204057 65 }
Midimetric 0:71d791204057 66 else // this is junk
Midimetric 0:71d791204057 67 {
Midimetric 0:71d791204057 68 led[port] = 0;
Midimetric 0:71d791204057 69 return;
Midimetric 0:71d791204057 70 }
Midimetric 0:71d791204057 71 int ch = current->Channel == NAKW ? 16 : current->Channel;
Midimetric 0:71d791204057 72
Midimetric 0:71d791204057 73 while( current->Next != NONE )
Midimetric 0:71d791204057 74 {
Midimetric 0:71d791204057 75 tempo.reset();
Midimetric 0:71d791204057 76 tempo.start();
Midimetric 0:71d791204057 77 while( SL[port].rxBufferEmpty() )
Midimetric 0:71d791204057 78 {
Midimetric 0:71d791204057 79 if( tempo.read_us() > 512 ) // normal rate should 256 us beetwen bytes. If twice that, assume message end is lost.
Midimetric 0:71d791204057 80 {
Midimetric 0:71d791204057 81 if( current->Type==BANK || current->Type==DATA || current->Type==RPN_ || current->Type==NRPN ) // LSB may be skipped
Midimetric 0:71d791204057 82 {
Midimetric 0:71d791204057 83 current->Next = NONE;
Midimetric 0:71d791204057 84 break;
Midimetric 0:71d791204057 85 }
Midimetric 0:71d791204057 86 // else, abort reading this message without transmission
Midimetric 0:71d791204057 87 tempo.stop();
Midimetric 0:71d791204057 88 Last[port] = beforelast; // forget last received command
Midimetric 0:71d791204057 89 delete current;
Midimetric 0:71d791204057 90 current = NULL;
Midimetric 0:71d791204057 91 led[port] = 0;
Midimetric 0:71d791204057 92 return;
Midimetric 0:71d791204057 93 }
Midimetric 0:71d791204057 94 }
Midimetric 0:71d791204057 95 tempo.stop();
Midimetric 0:71d791204057 96
Midimetric 0:71d791204057 97 if( current->Next != NONE )
Midimetric 0:71d791204057 98 {
Midimetric 0:71d791204057 99 int b = SL[port].getcNb();
Midimetric 0:71d791204057 100 if( ( b > -1 ) && ( b < 0xF8 ) ) // to ignore real time messages
Midimetric 0:71d791204057 101 {
Midimetric 0:71d791204057 102 if( ! current->Append( b ) )
Midimetric 0:71d791204057 103 {
Midimetric 0:71d791204057 104 // not a pair message (for example: NRPN lsb not followed by msb but by DATA)
Midimetric 0:71d791204057 105 if( current->Type==RPN_ || current->Type==NRPN || current->Type==BANK )
Midimetric 0:71d791204057 106 {
Midimetric 0:71d791204057 107 if( Previous[ ch ][port] != NULL ) delete Previous[ ch ][port];
Midimetric 0:71d791204057 108 Previous[ ch ][port] = current;
Midimetric 0:71d791204057 109 current = MidiCreateMessage( Last[port] );
Midimetric 0:71d791204057 110 if( current->Next != NONE )
Midimetric 0:71d791204057 111 current->Append( b );
Midimetric 0:71d791204057 112 }
Midimetric 0:71d791204057 113 }
Midimetric 0:71d791204057 114 }
Midimetric 0:71d791204057 115 }
Midimetric 0:71d791204057 116 }
Midimetric 0:71d791204057 117 // now message is complete (or LSB/MSB from compound message will not follow)
Midimetric 0:71d791204057 118 led[port] = 0;
Midimetric 0:71d791204057 119
Midimetric 0:71d791204057 120 FL.Route( port, *current, *(Previous[ current->Channel == NAKN ? 16 : current->Channel ][port]) ); // pass also 'previous' in case of multipart messages (RPN|NRP)+(DATA|INC|DEC)
Midimetric 0:71d791204057 121 if( current->Type != DATA && current->Type != INCR && current->Type != DECR )
Midimetric 0:71d791204057 122 {
Midimetric 0:71d791204057 123 if( Previous[ ch ][port] != NULL ) delete Previous[ ch ][port];
Midimetric 0:71d791204057 124 Previous[ ch ][port] = current;
Midimetric 0:71d791204057 125 current = NULL;
Midimetric 0:71d791204057 126 }
Midimetric 0:71d791204057 127 else
Midimetric 0:71d791204057 128 delete current;
Midimetric 0:71d791204057 129
Midimetric 0:71d791204057 130 }
Midimetric 0:71d791204057 131
Midimetric 0:71d791204057 132 void Blinking( int ntimes )
Midimetric 0:71d791204057 133 {
Midimetric 0:71d791204057 134 if( ntimes )
Midimetric 0:71d791204057 135 {
Midimetric 0:71d791204057 136 for( int i = 0 ; i < ntimes ; i++ )
Midimetric 0:71d791204057 137 {
Midimetric 0:71d791204057 138 led[3] = 1;
Midimetric 0:71d791204057 139 wait(0.2);
Midimetric 0:71d791204057 140 led[3] = 0;
Midimetric 0:71d791204057 141 wait(0.6);
Midimetric 0:71d791204057 142 }
Midimetric 0:71d791204057 143 wait(2);
Midimetric 0:71d791204057 144 }
Midimetric 0:71d791204057 145 }
Midimetric 0:71d791204057 146
Midimetric 0:71d791204057 147 int main()
Midimetric 0:71d791204057 148 {
Midimetric 0:71d791204057 149 for( int i = 0 ; i < 3 ; i++ ) SL[i].baud( 31250 );
Midimetric 0:71d791204057 150
Midimetric 0:71d791204057 151 if( ! Parse() )
Midimetric 0:71d791204057 152 {
Midimetric 0:71d791204057 153 Blinking(ParseError);
Midimetric 0:71d791204057 154 return 0;
Midimetric 0:71d791204057 155 }
Midimetric 0:71d791204057 156
Midimetric 0:71d791204057 157 while(1)
Midimetric 0:71d791204057 158 {
Midimetric 0:71d791204057 159 for( int i = 0 ; i < 3 ; i++ ) if( SL[i].readable() ) Data_in(i);
Midimetric 0:71d791204057 160 }
Midimetric 0:71d791204057 161
Midimetric 0:71d791204057 162 }