mbedでmidi(Format 0)を再生

Committer:
Naoto_111
Date:
Sat Aug 09 09:29:31 2014 +0000
Revision:
1:250e7251f8fc
Parent:
0:7c17c3b3a8d7
play_realtime???; ???????1????????????4

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Naoto_111 0:7c17c3b3a8d7 1 #include "mbed.h"
Naoto_111 0:7c17c3b3a8d7 2 #include "midi.h"
Naoto_111 1:250e7251f8fc 3 #define STEP 20
Naoto_111 0:7c17c3b3a8d7 4 Serial pc(USBTX,USBRX);//tx,rx
Naoto_111 0:7c17c3b3a8d7 5 midi::midi(PinName _bzr):bzr(_bzr)
Naoto_111 0:7c17c3b3a8d7 6 {
Naoto_111 0:7c17c3b3a8d7 7 //frequency of equal temperament(octave:4)
Naoto_111 0:7c17c3b3a8d7 8 freq[0]=261.626;//C(do)
Naoto_111 0:7c17c3b3a8d7 9 freq[1]=277.183;//C#
Naoto_111 0:7c17c3b3a8d7 10 freq[2]=293.665;//D
Naoto_111 0:7c17c3b3a8d7 11 freq[3]=311.127;//D#
Naoto_111 0:7c17c3b3a8d7 12 freq[4]=329.628;//E
Naoto_111 0:7c17c3b3a8d7 13 freq[5]=349.228;//F
Naoto_111 0:7c17c3b3a8d7 14 freq[6]=369.994;//F#
Naoto_111 0:7c17c3b3a8d7 15 freq[7]=391.995;//G
Naoto_111 0:7c17c3b3a8d7 16 freq[8]=415.305;//G#
Naoto_111 0:7c17c3b3a8d7 17 freq[9]=440.000;//A
Naoto_111 0:7c17c3b3a8d7 18 freq[10]=466.164;//A#
Naoto_111 0:7c17c3b3a8d7 19 freq[11]=493.883;//B
Naoto_111 0:7c17c3b3a8d7 20
Naoto_111 1:250e7251f8fc 21 //sine
Naoto_111 1:250e7251f8fc 22 table=new double[STEP];
Naoto_111 0:7c17c3b3a8d7 23 for(int i=0; i<STEP; i++)table[i]=sin(i/(STEP/8.0)*atan(1.0));
Naoto_111 1:250e7251f8fc 24
Naoto_111 0:7c17c3b3a8d7 25
Naoto_111 0:7c17c3b3a8d7 26
Naoto_111 0:7c17c3b3a8d7 27 }
Naoto_111 0:7c17c3b3a8d7 28 /*
Naoto_111 0:7c17c3b3a8d7 29 midi::~midi(){
Naoto_111 0:7c17c3b3a8d7 30 delete(cache);
Naoto_111 0:7c17c3b3a8d7 31 }
Naoto_111 0:7c17c3b3a8d7 32 */
Naoto_111 1:250e7251f8fc 33
Naoto_111 0:7c17c3b3a8d7 34 template<class X>
Naoto_111 0:7c17c3b3a8d7 35 void midi::change_endian(X *raw,int byte)
Naoto_111 0:7c17c3b3a8d7 36 {
Naoto_111 0:7c17c3b3a8d7 37 X tmp=0;
Naoto_111 0:7c17c3b3a8d7 38 for(int i=0; i<byte; i++)for(int j=0; j<8; j++)tmp+=((*raw&(1<<((byte-i-1)*8+j)))>>((byte-i-1)*8+j))<<(i*8+j);
Naoto_111 0:7c17c3b3a8d7 39 *raw=tmp;
Naoto_111 0:7c17c3b3a8d7 40 }
Naoto_111 0:7c17c3b3a8d7 41
Naoto_111 1:250e7251f8fc 42 int midi::powi(int a)
Naoto_111 1:250e7251f8fc 43 {
Naoto_111 1:250e7251f8fc 44 int tmp=1;
Naoto_111 1:250e7251f8fc 45 for(int i=0; i<a; i++)tmp=tmp<<1;
Naoto_111 1:250e7251f8fc 46 return tmp;
Naoto_111 1:250e7251f8fc 47 }
Naoto_111 1:250e7251f8fc 48
Naoto_111 1:250e7251f8fc 49
Naoto_111 0:7c17c3b3a8d7 50 void midi::read(const char *path)
Naoto_111 0:7c17c3b3a8d7 51 {
Naoto_111 0:7c17c3b3a8d7 52
Naoto_111 0:7c17c3b3a8d7 53 FILE *mid,*cache;
Naoto_111 0:7c17c3b3a8d7 54 short int pbend;
Naoto_111 0:7c17c3b3a8d7 55 long int dtime,len;
Naoto_111 0:7c17c3b3a8d7 56 int time,ch;
Naoto_111 0:7c17c3b3a8d7 57 float frequency[16];
Naoto_111 1:250e7251f8fc 58 char note,ctrl,value,prgm,prsr,vel,prev;
Naoto_111 1:250e7251f8fc 59 unsigned char tmp,tmp2[64];
Naoto_111 1:250e7251f8fc 60
Naoto_111 0:7c17c3b3a8d7 61 time=tmp=prev=tempo=chmax=0;
Naoto_111 0:7c17c3b3a8d7 62
Naoto_111 0:7c17c3b3a8d7 63 if((mid = fopen(path, "rb")) == NULL)goto end1;
Naoto_111 0:7c17c3b3a8d7 64
Naoto_111 0:7c17c3b3a8d7 65
Naoto_111 0:7c17c3b3a8d7 66 fseek(mid, 10, SEEK_SET);
Naoto_111 0:7c17c3b3a8d7 67 fread(&tracks,2,1,mid);
Naoto_111 0:7c17c3b3a8d7 68 fread(&crochet,2,1,mid);
Naoto_111 0:7c17c3b3a8d7 69
Naoto_111 0:7c17c3b3a8d7 70 change_endian(&tracks,2);
Naoto_111 0:7c17c3b3a8d7 71 change_endian(&crochet,2);
Naoto_111 0:7c17c3b3a8d7 72
Naoto_111 0:7c17c3b3a8d7 73
Naoto_111 0:7c17c3b3a8d7 74
Naoto_111 0:7c17c3b3a8d7 75
Naoto_111 0:7c17c3b3a8d7 76
Naoto_111 0:7c17c3b3a8d7 77 fseek(mid, 4, SEEK_CUR);
Naoto_111 0:7c17c3b3a8d7 78 fread(&len,4,1,mid);
Naoto_111 0:7c17c3b3a8d7 79 change_endian(&len,4);
Naoto_111 0:7c17c3b3a8d7 80 while(1) {
Naoto_111 0:7c17c3b3a8d7 81 fread(&tmp,1,1,mid);
Naoto_111 0:7c17c3b3a8d7 82
Naoto_111 0:7c17c3b3a8d7 83 dtime=0;
Naoto_111 0:7c17c3b3a8d7 84 int i;
Naoto_111 0:7c17c3b3a8d7 85 for(i=0; i<4; i++) {
Naoto_111 0:7c17c3b3a8d7 86 int flag= (tmp&128)==0 ? 1:0;
Naoto_111 1:250e7251f8fc 87
Naoto_111 0:7c17c3b3a8d7 88 if(tmp&128)tmp2[i]=tmp-0x80;
Naoto_111 0:7c17c3b3a8d7 89 else tmp2[i]=tmp;
Naoto_111 0:7c17c3b3a8d7 90 if(flag)break;
Naoto_111 0:7c17c3b3a8d7 91 fread(&tmp,1,1,mid);
Naoto_111 0:7c17c3b3a8d7 92 }
Naoto_111 0:7c17c3b3a8d7 93 for(int j=0; j<=i; j++)dtime+=((long int)tmp2[j]<<(7*(i-j)));
Naoto_111 0:7c17c3b3a8d7 94 time+=(int)tempo*((float)dtime/crochet);
Naoto_111 0:7c17c3b3a8d7 95
Naoto_111 1:250e7251f8fc 96
Naoto_111 0:7c17c3b3a8d7 97 fread(&tmp,1,1,mid);
Naoto_111 0:7c17c3b3a8d7 98 //pc.printf("%d %d\r\n",time,tm.size()*4*1+fq.size()*4*1+ca.size());
Naoto_111 1:250e7251f8fc 99 if(tm.size()>640) {
Naoto_111 1:250e7251f8fc 100 pc.printf("Memory shortage!\r\n");
Naoto_111 1:250e7251f8fc 101 goto end1;
Naoto_111 1:250e7251f8fc 102
Naoto_111 1:250e7251f8fc 103 }
Naoto_111 0:7c17c3b3a8d7 104 if(tmp==0xF0) {
Naoto_111 0:7c17c3b3a8d7 105 len=0;
Naoto_111 0:7c17c3b3a8d7 106 i=0;
Naoto_111 0:7c17c3b3a8d7 107 fread(&tmp,1,1,mid);
Naoto_111 0:7c17c3b3a8d7 108
Naoto_111 0:7c17c3b3a8d7 109 for(i=0; i<4; i++) {
Naoto_111 0:7c17c3b3a8d7 110 int flag= (tmp&128)==0 ? 1:0;
Naoto_111 1:250e7251f8fc 111
Naoto_111 0:7c17c3b3a8d7 112 tmp2[i]=((tmp<<1)>>1);
Naoto_111 0:7c17c3b3a8d7 113 if(flag)break;
Naoto_111 0:7c17c3b3a8d7 114 fread(&tmp,1,1,mid);
Naoto_111 0:7c17c3b3a8d7 115
Naoto_111 0:7c17c3b3a8d7 116 }
Naoto_111 0:7c17c3b3a8d7 117
Naoto_111 0:7c17c3b3a8d7 118 for(int j=i; j>=0; j--)len+=((long int)tmp2[j]<<(7*j));
Naoto_111 0:7c17c3b3a8d7 119
Naoto_111 0:7c17c3b3a8d7 120 fseek(mid, len, SEEK_CUR);
Naoto_111 0:7c17c3b3a8d7 121
Naoto_111 0:7c17c3b3a8d7 122 } else if(tmp==0xF7) {
Naoto_111 0:7c17c3b3a8d7 123 len=0;
Naoto_111 0:7c17c3b3a8d7 124 i=0;
Naoto_111 0:7c17c3b3a8d7 125 fread(&tmp,1,1,mid);
Naoto_111 0:7c17c3b3a8d7 126 for(i=0; i<4; i++) {
Naoto_111 0:7c17c3b3a8d7 127 int flag= (tmp&128)==0 ? 1:0;
Naoto_111 0:7c17c3b3a8d7 128 tmp2[i]=((tmp<<1)>>1);
Naoto_111 0:7c17c3b3a8d7 129 if(flag)break;
Naoto_111 0:7c17c3b3a8d7 130 fread(&tmp,1,1,mid);
Naoto_111 0:7c17c3b3a8d7 131 }
Naoto_111 0:7c17c3b3a8d7 132 for(int j=i; j>=0; j--)len+=((long int)tmp2[j]<<(7*j));
Naoto_111 0:7c17c3b3a8d7 133 fseek(mid, len, SEEK_CUR);
Naoto_111 0:7c17c3b3a8d7 134 } else if(tmp==0xFF) {
Naoto_111 0:7c17c3b3a8d7 135 fread(&tmp,1,1,mid);
Naoto_111 0:7c17c3b3a8d7 136 switch(tmp) {
Naoto_111 0:7c17c3b3a8d7 137 case 0x00:
Naoto_111 0:7c17c3b3a8d7 138 case 0x59:
Naoto_111 0:7c17c3b3a8d7 139 fseek(mid, 3, SEEK_CUR);
Naoto_111 0:7c17c3b3a8d7 140 break;
Naoto_111 0:7c17c3b3a8d7 141
Naoto_111 0:7c17c3b3a8d7 142 case 0x20:
Naoto_111 0:7c17c3b3a8d7 143 case 0x21:
Naoto_111 0:7c17c3b3a8d7 144 fseek(mid, 2, SEEK_CUR);
Naoto_111 0:7c17c3b3a8d7 145 break;
Naoto_111 0:7c17c3b3a8d7 146
Naoto_111 0:7c17c3b3a8d7 147 case 0x54:
Naoto_111 0:7c17c3b3a8d7 148 fseek(mid, 6, SEEK_CUR);
Naoto_111 0:7c17c3b3a8d7 149 break;
Naoto_111 0:7c17c3b3a8d7 150
Naoto_111 0:7c17c3b3a8d7 151 case 0x2F://End of Track
Naoto_111 0:7c17c3b3a8d7 152
Naoto_111 0:7c17c3b3a8d7 153 goto end1;
Naoto_111 0:7c17c3b3a8d7 154 break;
Naoto_111 0:7c17c3b3a8d7 155
Naoto_111 0:7c17c3b3a8d7 156 case 0x51://Tempo
Naoto_111 0:7c17c3b3a8d7 157 fseek(mid, 1, SEEK_CUR);
Naoto_111 0:7c17c3b3a8d7 158 fread(&tempo,3,1,mid);
Naoto_111 0:7c17c3b3a8d7 159 change_endian(&tempo,3);
Naoto_111 0:7c17c3b3a8d7 160 //pc.printf("tempo=%x\r\n",tempo);
Naoto_111 0:7c17c3b3a8d7 161 break;
Naoto_111 0:7c17c3b3a8d7 162
Naoto_111 0:7c17c3b3a8d7 163 case 0x58://Time Signature
Naoto_111 0:7c17c3b3a8d7 164 fseek(mid, 5, SEEK_CUR);
Naoto_111 0:7c17c3b3a8d7 165 break;
Naoto_111 0:7c17c3b3a8d7 166
Naoto_111 0:7c17c3b3a8d7 167 /*case 0x59://Key Signature
Naoto_111 0:7c17c3b3a8d7 168
Naoto_111 0:7c17c3b3a8d7 169 break;
Naoto_111 0:7c17c3b3a8d7 170 */
Naoto_111 0:7c17c3b3a8d7 171 case 0x01:
Naoto_111 0:7c17c3b3a8d7 172 case 0x02:
Naoto_111 0:7c17c3b3a8d7 173 case 0x03:
Naoto_111 0:7c17c3b3a8d7 174 case 0x04:
Naoto_111 0:7c17c3b3a8d7 175 case 0x05:
Naoto_111 0:7c17c3b3a8d7 176 case 0x06:
Naoto_111 0:7c17c3b3a8d7 177 case 0x07:
Naoto_111 0:7c17c3b3a8d7 178 case 0x08:
Naoto_111 0:7c17c3b3a8d7 179 case 0x09:
Naoto_111 0:7c17c3b3a8d7 180 case 0x7F:
Naoto_111 0:7c17c3b3a8d7 181 len=0;
Naoto_111 0:7c17c3b3a8d7 182 i=0;
Naoto_111 0:7c17c3b3a8d7 183 fread(&tmp,1,1,mid);
Naoto_111 0:7c17c3b3a8d7 184
Naoto_111 0:7c17c3b3a8d7 185 for(i=0; i<4; i++) {
Naoto_111 0:7c17c3b3a8d7 186 int flag= (tmp&128)==0 ? 1:0;
Naoto_111 0:7c17c3b3a8d7 187 tmp2[i]=((tmp<<1)>>1);
Naoto_111 0:7c17c3b3a8d7 188 if(flag)break;
Naoto_111 0:7c17c3b3a8d7 189 fread(&tmp,1,1,mid);
Naoto_111 0:7c17c3b3a8d7 190
Naoto_111 0:7c17c3b3a8d7 191 }
Naoto_111 0:7c17c3b3a8d7 192
Naoto_111 0:7c17c3b3a8d7 193 for(int j=i; j>=0; j--)len+=((unsigned long int)tmp2[j]<<(7*j));
Naoto_111 0:7c17c3b3a8d7 194
Naoto_111 0:7c17c3b3a8d7 195 fseek(mid, len, SEEK_CUR);
Naoto_111 0:7c17c3b3a8d7 196
Naoto_111 0:7c17c3b3a8d7 197 break;
Naoto_111 0:7c17c3b3a8d7 198
Naoto_111 0:7c17c3b3a8d7 199 default:
Naoto_111 0:7c17c3b3a8d7 200 break;
Naoto_111 0:7c17c3b3a8d7 201 }
Naoto_111 0:7c17c3b3a8d7 202 } else {
Naoto_111 0:7c17c3b3a8d7 203
Naoto_111 0:7c17c3b3a8d7 204
Naoto_111 0:7c17c3b3a8d7 205 //fseek(mid, 1, SEEK_CUR);
Naoto_111 0:7c17c3b3a8d7 206 //fread(&tmp,1,1,mid);
Naoto_111 0:7c17c3b3a8d7 207
Naoto_111 0:7c17c3b3a8d7 208 MIDIEVENT:
Naoto_111 0:7c17c3b3a8d7 209 if(0x80<=tmp&&tmp<=0xEF)prev=tmp;
Naoto_111 0:7c17c3b3a8d7 210 if(0x80<=tmp&&tmp<=0x8F) { //note off
Naoto_111 0:7c17c3b3a8d7 211 ch=tmp-0x80;
Naoto_111 0:7c17c3b3a8d7 212 if(chmax<ch)chmax=ch;
Naoto_111 0:7c17c3b3a8d7 213 fread(&note,1,1,mid);
Naoto_111 0:7c17c3b3a8d7 214 fseek(mid, 1, SEEK_CUR);
Naoto_111 0:7c17c3b3a8d7 215
Naoto_111 0:7c17c3b3a8d7 216 tm.push_back(time);
Naoto_111 0:7c17c3b3a8d7 217 //ev.push_back(109);
Naoto_111 0:7c17c3b3a8d7 218 ca.push_back(ch);
Naoto_111 0:7c17c3b3a8d7 219 fq.push_back(0);
Naoto_111 0:7c17c3b3a8d7 220 //vo.push_back(0);
Naoto_111 0:7c17c3b3a8d7 221 } else if(0x90<=tmp&&tmp<=0x9F) { //note on
Naoto_111 0:7c17c3b3a8d7 222 ch=tmp-0x90;
Naoto_111 0:7c17c3b3a8d7 223 fread(&note,1,1,mid);
Naoto_111 0:7c17c3b3a8d7 224 frequency[ch]=freq[note%12]*pow(2.0,(note/12-5.0));
Naoto_111 0:7c17c3b3a8d7 225
Naoto_111 0:7c17c3b3a8d7 226 fread(&vel,1,1,mid);
Naoto_111 0:7c17c3b3a8d7 227
Naoto_111 0:7c17c3b3a8d7 228
Naoto_111 0:7c17c3b3a8d7 229 tm.push_back(time);
Naoto_111 0:7c17c3b3a8d7 230 //ev.push_back(109);
Naoto_111 0:7c17c3b3a8d7 231 ca.push_back(ch);
Naoto_111 0:7c17c3b3a8d7 232 fq.push_back(frequency[ch]);
Naoto_111 0:7c17c3b3a8d7 233 //vo.push_back(vel/127.0);
Naoto_111 0:7c17c3b3a8d7 234 }
Naoto_111 0:7c17c3b3a8d7 235
Naoto_111 0:7c17c3b3a8d7 236 else if(0xA0<=tmp&&tmp<=0xAF) { //polyphonic key pressure
Naoto_111 0:7c17c3b3a8d7 237 ch=tmp-0xA0;
Naoto_111 0:7c17c3b3a8d7 238 fread(&note,1,1,mid);
Naoto_111 0:7c17c3b3a8d7 239
Naoto_111 0:7c17c3b3a8d7 240 fread(&vel,1,1,mid);
Naoto_111 0:7c17c3b3a8d7 241 } else if(0xB0<=tmp&&tmp<=0xBF) { //control change
Naoto_111 0:7c17c3b3a8d7 242 ch=tmp-0xB0;
Naoto_111 0:7c17c3b3a8d7 243 fread(&ctrl,1,1,mid);
Naoto_111 0:7c17c3b3a8d7 244
Naoto_111 0:7c17c3b3a8d7 245 fread(&value,1,1,mid);
Naoto_111 0:7c17c3b3a8d7 246 } else if(0xC0<=tmp&&tmp<=0xCF) { //program change
Naoto_111 0:7c17c3b3a8d7 247 ch=tmp-0xC0;
Naoto_111 0:7c17c3b3a8d7 248 fread(&prgm,1,1,mid);
Naoto_111 0:7c17c3b3a8d7 249 } else if(0xD0<=tmp&&tmp<=0xDF) { //channel pressure
Naoto_111 0:7c17c3b3a8d7 250 ch=tmp-0x90;
Naoto_111 0:7c17c3b3a8d7 251 fread(&prsr,1,1,mid);
Naoto_111 0:7c17c3b3a8d7 252 } else if(0xE0<=tmp&&tmp<=0xEF) { //pitch bend
Naoto_111 0:7c17c3b3a8d7 253 ch=tmp-0xE0;
Naoto_111 0:7c17c3b3a8d7 254 fread(&pbend,2,1,mid);
Naoto_111 0:7c17c3b3a8d7 255 } else { //running status
Naoto_111 0:7c17c3b3a8d7 256 tmp=prev;
Naoto_111 0:7c17c3b3a8d7 257 fseek(mid, -1, SEEK_CUR);
Naoto_111 0:7c17c3b3a8d7 258 pc.printf(" ->%x\r\n",tmp);
Naoto_111 0:7c17c3b3a8d7 259 goto MIDIEVENT;
Naoto_111 0:7c17c3b3a8d7 260 }
Naoto_111 0:7c17c3b3a8d7 261 }
Naoto_111 0:7c17c3b3a8d7 262 }
Naoto_111 0:7c17c3b3a8d7 263 end1:
Naoto_111 0:7c17c3b3a8d7 264 fclose(mid);
Naoto_111 0:7c17c3b3a8d7 265
Naoto_111 0:7c17c3b3a8d7 266 pc.printf("Loading complete.\r\n");
Naoto_111 0:7c17c3b3a8d7 267 }
Naoto_111 0:7c17c3b3a8d7 268
Naoto_111 0:7c17c3b3a8d7 269
Naoto_111 0:7c17c3b3a8d7 270
Naoto_111 0:7c17c3b3a8d7 271
Naoto_111 1:250e7251f8fc 272 void midi::play(/*int repeat*/)
Naoto_111 0:7c17c3b3a8d7 273 {
Naoto_111 0:7c17c3b3a8d7 274
Naoto_111 0:7c17c3b3a8d7 275 //FILE *fp;
Naoto_111 0:7c17c3b3a8d7 276 AnalogOut buzzer(bzr);
Naoto_111 0:7c17c3b3a8d7 277 int time, /*event, */ch;
Naoto_111 0:7c17c3b3a8d7 278 float *frequency/*,tmp,tmp2,vel[16]*/;
Naoto_111 0:7c17c3b3a8d7 279 //if((fp = fopen(path, "r")) == NULL)goto end;
Naoto_111 0:7c17c3b3a8d7 280 //if(fscanf(fp,"%d\n",&tracks)==EOF)goto end;
Naoto_111 0:7c17c3b3a8d7 281 frequency=new float[chmax+1];
Naoto_111 0:7c17c3b3a8d7 282 for(int i=0; i<=chmax; i++)frequency[i]=0;
Naoto_111 1:250e7251f8fc 283
Naoto_111 1:250e7251f8fc 284 /*
Naoto_111 1:250e7251f8fc 285 if(!tm.empty())goto end;
Naoto_111 0:7c17c3b3a8d7 286
Naoto_111 0:7c17c3b3a8d7 287
Naoto_111 1:250e7251f8fc 288 pi=tm.begin();
Naoto_111 1:250e7251f8fc 289 time=*pi;
Naoto_111 1:250e7251f8fc 290 tm.pop_front();
Naoto_111 0:7c17c3b3a8d7 291
Naoto_111 1:250e7251f8fc 292 pi=ev.begin();
Naoto_111 1:250e7251f8fc 293 event=*pi;
Naoto_111 1:250e7251f8fc 294 ev.pop_front();
Naoto_111 0:7c17c3b3a8d7 295
Naoto_111 1:250e7251f8fc 296 pi=ca.begin();
Naoto_111 1:250e7251f8fc 297 ch=*pi;
Naoto_111 1:250e7251f8fc 298 ca.pop_front();
Naoto_111 0:7c17c3b3a8d7 299
Naoto_111 1:250e7251f8fc 300 pd=fq.begin();
Naoto_111 1:250e7251f8fc 301 frequency[ch]=*pd;
Naoto_111 1:250e7251f8fc 302 fq.pop_front();
Naoto_111 0:7c17c3b3a8d7 303
Naoto_111 1:250e7251f8fc 304 pd=vo.begin();
Naoto_111 1:250e7251f8fc 305 vel[ch]=*pd;
Naoto_111 1:250e7251f8fc 306 vo.pop_front();
Naoto_111 1:250e7251f8fc 307 */
Naoto_111 0:7c17c3b3a8d7 308
Naoto_111 0:7c17c3b3a8d7 309 t.reset();
Naoto_111 0:7c17c3b3a8d7 310 t.start();
Naoto_111 0:7c17c3b3a8d7 311 time=0;
Naoto_111 0:7c17c3b3a8d7 312 while(1) {
Naoto_111 0:7c17c3b3a8d7 313 //static int count=0;
Naoto_111 0:7c17c3b3a8d7 314 //pc.printf("%d\r\n",count++);
Naoto_111 0:7c17c3b3a8d7 315 int now=t.read_us();
Naoto_111 0:7c17c3b3a8d7 316 while(1) {
Naoto_111 0:7c17c3b3a8d7 317 if(time<=now) {
Naoto_111 1:250e7251f8fc 318
Naoto_111 0:7c17c3b3a8d7 319 if(tm.empty())return;
Naoto_111 1:250e7251f8fc 320
Naoto_111 0:7c17c3b3a8d7 321 pi=tm.begin();
Naoto_111 0:7c17c3b3a8d7 322 time=*pi;
Naoto_111 0:7c17c3b3a8d7 323 if(time>=now)break;
Naoto_111 0:7c17c3b3a8d7 324 tm.pop_front();
Naoto_111 1:250e7251f8fc 325 /*
Naoto_111 1:250e7251f8fc 326 pi=ev.begin();
Naoto_111 1:250e7251f8fc 327 event=*pi;
Naoto_111 1:250e7251f8fc 328 ev.pop_front();
Naoto_111 1:250e7251f8fc 329 */
Naoto_111 0:7c17c3b3a8d7 330 pch=ca.begin();
Naoto_111 0:7c17c3b3a8d7 331 ch=*pch;
Naoto_111 0:7c17c3b3a8d7 332 ca.pop_front();
Naoto_111 1:250e7251f8fc 333
Naoto_111 0:7c17c3b3a8d7 334
Naoto_111 0:7c17c3b3a8d7 335
Naoto_111 0:7c17c3b3a8d7 336 pf=fq.begin();
Naoto_111 0:7c17c3b3a8d7 337 frequency[ch]=*pf;
Naoto_111 0:7c17c3b3a8d7 338 fq.pop_front();
Naoto_111 0:7c17c3b3a8d7 339 /*
Naoto_111 0:7c17c3b3a8d7 340 pd=vo.begin();
Naoto_111 0:7c17c3b3a8d7 341 vel[ch]=*pd;
Naoto_111 0:7c17c3b3a8d7 342 vo.pop_front();
Naoto_111 0:7c17c3b3a8d7 343 */
Naoto_111 0:7c17c3b3a8d7 344 //pc.printf("%d %d %d %lf %lf\r\n",time,event,ch,frequency[ch],vel[ch]);
Naoto_111 0:7c17c3b3a8d7 345 } else break;
Naoto_111 0:7c17c3b3a8d7 346 }
Naoto_111 0:7c17c3b3a8d7 347 float voltage=0;
Naoto_111 0:7c17c3b3a8d7 348 for(int i=0; i<=chmax; i++)voltage+=/*vel[i]*/(0.5/(chmax+1))*table[(int)(STEP*frequency[i]*now/1000000)%STEP];
Naoto_111 0:7c17c3b3a8d7 349 //for(int i=0;i<tracks;i++)voltage+=(0.5/tracks)*sin(2*pi*frequency[i]*now/1000000);
Naoto_111 0:7c17c3b3a8d7 350 buzzer=0.5+voltage;
Naoto_111 1:250e7251f8fc 351
Naoto_111 0:7c17c3b3a8d7 352 }
Naoto_111 0:7c17c3b3a8d7 353 //end:
Naoto_111 0:7c17c3b3a8d7 354 //fclose(fp);
Naoto_111 1:250e7251f8fc 355 }
Naoto_111 1:250e7251f8fc 356
Naoto_111 1:250e7251f8fc 357
Naoto_111 1:250e7251f8fc 358
Naoto_111 1:250e7251f8fc 359
Naoto_111 1:250e7251f8fc 360 void midi::play_realtime(const char *path/*, int repeat*/)
Naoto_111 1:250e7251f8fc 361 {
Naoto_111 1:250e7251f8fc 362 FILE *mid;
Naoto_111 1:250e7251f8fc 363 short int pbend;
Naoto_111 1:250e7251f8fc 364 long int dtime,len,time,ch;
Naoto_111 1:250e7251f8fc 365 char note,ctrl,value,prgm,prsr,vel,prev;
Naoto_111 1:250e7251f8fc 366 unsigned char tmp,tmp2[64];
Naoto_111 1:250e7251f8fc 367 AnalogOut buzzer(bzr);
Naoto_111 1:250e7251f8fc 368
Naoto_111 1:250e7251f8fc 369 time=tmp=prev=tempo=chmax=0;
Naoto_111 1:250e7251f8fc 370
Naoto_111 1:250e7251f8fc 371 if((mid = fopen(path, "rb")) == NULL)return;
Naoto_111 1:250e7251f8fc 372
Naoto_111 1:250e7251f8fc 373 fseek(mid, 10, SEEK_SET);
Naoto_111 1:250e7251f8fc 374 fread(&tracks,2,1,mid);
Naoto_111 1:250e7251f8fc 375 fread(&crochet,2,1,mid);
Naoto_111 1:250e7251f8fc 376
Naoto_111 1:250e7251f8fc 377 change_endian(&tracks,2);
Naoto_111 1:250e7251f8fc 378 change_endian(&crochet,2);
Naoto_111 1:250e7251f8fc 379
Naoto_111 1:250e7251f8fc 380 fseek(mid, 4, SEEK_CUR);
Naoto_111 1:250e7251f8fc 381 fread(&len,4,1,mid);
Naoto_111 1:250e7251f8fc 382 change_endian(&len,4);
Naoto_111 1:250e7251f8fc 383 t.reset();
Naoto_111 1:250e7251f8fc 384 t.start();
Naoto_111 1:250e7251f8fc 385 while(1) {
Naoto_111 1:250e7251f8fc 386 fread(&tmp,1,1,mid);
Naoto_111 1:250e7251f8fc 387
Naoto_111 1:250e7251f8fc 388 //delta time
Naoto_111 1:250e7251f8fc 389 dtime=0;
Naoto_111 1:250e7251f8fc 390 int i;
Naoto_111 1:250e7251f8fc 391 for(i=0; i<4; i++) {
Naoto_111 1:250e7251f8fc 392 int flag= (tmp&128)==0 ? 1:0;
Naoto_111 1:250e7251f8fc 393
Naoto_111 1:250e7251f8fc 394 if(tmp&128)tmp2[i]=tmp-0x80;
Naoto_111 1:250e7251f8fc 395 else tmp2[i]=tmp;
Naoto_111 1:250e7251f8fc 396 if(flag)break;
Naoto_111 1:250e7251f8fc 397 fread(&tmp,1,1,mid);
Naoto_111 1:250e7251f8fc 398 }
Naoto_111 1:250e7251f8fc 399 for(int j=0; j<=i; j++)dtime+=((long int)tmp2[j]<<(7*(i-j)));
Naoto_111 1:250e7251f8fc 400 time+=(int)tempo*((double)dtime/crochet);
Naoto_111 1:250e7251f8fc 401
Naoto_111 1:250e7251f8fc 402
Naoto_111 1:250e7251f8fc 403 while(t.read_us()<time) {
Naoto_111 1:250e7251f8fc 404 double voltage=0;
Naoto_111 1:250e7251f8fc 405 for(list<int>::iterator i =no.begin(); i!=no.end(); i++)voltage+=/*vel[i]*/(0.5/4)*table[(int)(STEP* (freq[*i%12]*powi(*i/12-5)) *t.read_us()/1000000)%STEP];
Naoto_111 1:250e7251f8fc 406 buzzer=0.5+voltage;
Naoto_111 1:250e7251f8fc 407 }
Naoto_111 1:250e7251f8fc 408
Naoto_111 1:250e7251f8fc 409 //event
Naoto_111 1:250e7251f8fc 410 fread(&tmp,1,1,mid);
Naoto_111 1:250e7251f8fc 411
Naoto_111 1:250e7251f8fc 412 //meta event
Naoto_111 1:250e7251f8fc 413 if(tmp==0xF0) {
Naoto_111 1:250e7251f8fc 414 len=0;
Naoto_111 1:250e7251f8fc 415 i=0;
Naoto_111 1:250e7251f8fc 416 fread(&tmp,1,1,mid);
Naoto_111 1:250e7251f8fc 417
Naoto_111 1:250e7251f8fc 418 for(i=0; i<4; i++) {
Naoto_111 1:250e7251f8fc 419 int flag= (tmp&128)==0 ? 1:0;
Naoto_111 1:250e7251f8fc 420
Naoto_111 1:250e7251f8fc 421 tmp2[i]=((tmp<<1)>>1);
Naoto_111 1:250e7251f8fc 422 if(flag)break;
Naoto_111 1:250e7251f8fc 423 fread(&tmp,1,1,mid);
Naoto_111 1:250e7251f8fc 424
Naoto_111 1:250e7251f8fc 425 }
Naoto_111 1:250e7251f8fc 426
Naoto_111 1:250e7251f8fc 427 for(int j=i; j>=0; j--)len+=((long int)tmp2[j]<<(7*j));
Naoto_111 1:250e7251f8fc 428
Naoto_111 1:250e7251f8fc 429 fseek(mid, len, SEEK_CUR);
Naoto_111 1:250e7251f8fc 430
Naoto_111 1:250e7251f8fc 431 } else if(tmp==0xF7) {
Naoto_111 1:250e7251f8fc 432 len=0;
Naoto_111 1:250e7251f8fc 433 i=0;
Naoto_111 1:250e7251f8fc 434 fread(&tmp,1,1,mid);
Naoto_111 1:250e7251f8fc 435 for(i=0; i<4; i++) {
Naoto_111 1:250e7251f8fc 436 int flag= (tmp&128)==0 ? 1:0;
Naoto_111 1:250e7251f8fc 437 tmp2[i]=((tmp<<1)>>1);
Naoto_111 1:250e7251f8fc 438 if(flag)break;
Naoto_111 1:250e7251f8fc 439 fread(&tmp,1,1,mid);
Naoto_111 1:250e7251f8fc 440 }
Naoto_111 1:250e7251f8fc 441 for(int j=i; j>=0; j--)len+=((long int)tmp2[j]<<(7*j));
Naoto_111 1:250e7251f8fc 442 fseek(mid, len, SEEK_CUR);
Naoto_111 1:250e7251f8fc 443 } else if(tmp==0xFF) {
Naoto_111 1:250e7251f8fc 444 fread(&tmp,1,1,mid);
Naoto_111 1:250e7251f8fc 445 switch(tmp) {
Naoto_111 1:250e7251f8fc 446 case 0x00:
Naoto_111 1:250e7251f8fc 447 case 0x59:
Naoto_111 1:250e7251f8fc 448 fseek(mid, 3, SEEK_CUR);
Naoto_111 1:250e7251f8fc 449 break;
Naoto_111 1:250e7251f8fc 450
Naoto_111 1:250e7251f8fc 451 case 0x20:
Naoto_111 1:250e7251f8fc 452 case 0x21:
Naoto_111 1:250e7251f8fc 453 fseek(mid, 2, SEEK_CUR);
Naoto_111 1:250e7251f8fc 454 break;
Naoto_111 1:250e7251f8fc 455
Naoto_111 1:250e7251f8fc 456 case 0x54:
Naoto_111 1:250e7251f8fc 457 fseek(mid, 6, SEEK_CUR);
Naoto_111 1:250e7251f8fc 458 break;
Naoto_111 1:250e7251f8fc 459
Naoto_111 1:250e7251f8fc 460 case 0x2F://End of Track
Naoto_111 1:250e7251f8fc 461
Naoto_111 1:250e7251f8fc 462 goto end2;
Naoto_111 1:250e7251f8fc 463 break;
Naoto_111 1:250e7251f8fc 464
Naoto_111 1:250e7251f8fc 465 case 0x51://Tempo
Naoto_111 1:250e7251f8fc 466 fseek(mid, 1, SEEK_CUR);
Naoto_111 1:250e7251f8fc 467 fread(&tempo,3,1,mid);
Naoto_111 1:250e7251f8fc 468 change_endian(&tempo,3);
Naoto_111 1:250e7251f8fc 469 //pc.printf("tempo=%x\r\n",tempo);
Naoto_111 1:250e7251f8fc 470 break;
Naoto_111 1:250e7251f8fc 471
Naoto_111 1:250e7251f8fc 472 case 0x58://Time Signature
Naoto_111 1:250e7251f8fc 473 fseek(mid, 5, SEEK_CUR);
Naoto_111 1:250e7251f8fc 474 break;
Naoto_111 1:250e7251f8fc 475
Naoto_111 1:250e7251f8fc 476 /*case 0x59://Key Signature
Naoto_111 1:250e7251f8fc 477
Naoto_111 1:250e7251f8fc 478 break;
Naoto_111 1:250e7251f8fc 479 */
Naoto_111 1:250e7251f8fc 480 case 0x01:
Naoto_111 1:250e7251f8fc 481 case 0x02:
Naoto_111 1:250e7251f8fc 482 case 0x03:
Naoto_111 1:250e7251f8fc 483 case 0x04:
Naoto_111 1:250e7251f8fc 484 case 0x05:
Naoto_111 1:250e7251f8fc 485 case 0x06:
Naoto_111 1:250e7251f8fc 486 case 0x07:
Naoto_111 1:250e7251f8fc 487 case 0x08:
Naoto_111 1:250e7251f8fc 488 case 0x09:
Naoto_111 1:250e7251f8fc 489 case 0x7F:
Naoto_111 1:250e7251f8fc 490 len=0;
Naoto_111 1:250e7251f8fc 491 i=0;
Naoto_111 1:250e7251f8fc 492 fread(&tmp,1,1,mid);
Naoto_111 1:250e7251f8fc 493
Naoto_111 1:250e7251f8fc 494 for(i=0; i<4; i++) {
Naoto_111 1:250e7251f8fc 495 int flag= (tmp&128)==0 ? 1:0;
Naoto_111 1:250e7251f8fc 496 tmp2[i]=((tmp<<1)>>1);
Naoto_111 1:250e7251f8fc 497 if(flag)break;
Naoto_111 1:250e7251f8fc 498 fread(&tmp,1,1,mid);
Naoto_111 1:250e7251f8fc 499
Naoto_111 1:250e7251f8fc 500 }
Naoto_111 1:250e7251f8fc 501
Naoto_111 1:250e7251f8fc 502 for(int j=i; j>=0; j--)len+=((unsigned long int)tmp2[j]<<(7*j));
Naoto_111 1:250e7251f8fc 503
Naoto_111 1:250e7251f8fc 504 fseek(mid, len, SEEK_CUR);
Naoto_111 1:250e7251f8fc 505
Naoto_111 1:250e7251f8fc 506 break;
Naoto_111 1:250e7251f8fc 507
Naoto_111 1:250e7251f8fc 508 default:
Naoto_111 1:250e7251f8fc 509 break;
Naoto_111 1:250e7251f8fc 510 }
Naoto_111 1:250e7251f8fc 511 } else {//midi event
Naoto_111 1:250e7251f8fc 512
Naoto_111 1:250e7251f8fc 513
Naoto_111 1:250e7251f8fc 514 //fseek(mid, 1, SEEK_CUR);
Naoto_111 1:250e7251f8fc 515 //fread(&tmp,1,1,mid);
Naoto_111 1:250e7251f8fc 516
Naoto_111 1:250e7251f8fc 517 MIDIEVENT:
Naoto_111 1:250e7251f8fc 518 if(0x80<=tmp&&tmp<=0xEF)prev=tmp;//running status
Naoto_111 1:250e7251f8fc 519 if(0x80<=tmp&&tmp<=0x8F) { //note off
Naoto_111 1:250e7251f8fc 520 ch=tmp-0x80;
Naoto_111 1:250e7251f8fc 521 fread(&note,1,1,mid);
Naoto_111 1:250e7251f8fc 522 fseek(mid, 1, SEEK_CUR);
Naoto_111 1:250e7251f8fc 523 //if(ch)break;
Naoto_111 1:250e7251f8fc 524 list<int>::iterator i =no.begin();
Naoto_111 1:250e7251f8fc 525 for(; i!=no.end(); i++)if(*i==note)break;
Naoto_111 1:250e7251f8fc 526 no.erase(i);
Naoto_111 1:250e7251f8fc 527 } else if(0x90<=tmp&&tmp<=0x9F) { //note on
Naoto_111 1:250e7251f8fc 528 ch=tmp-0x90;
Naoto_111 1:250e7251f8fc 529 fread(&note,1,1,mid);
Naoto_111 1:250e7251f8fc 530
Naoto_111 1:250e7251f8fc 531 fread(&vel,1,1,mid);
Naoto_111 1:250e7251f8fc 532 //if(ch)break;
Naoto_111 1:250e7251f8fc 533 if(vel==0) {
Naoto_111 1:250e7251f8fc 534 fread(&note,1,1,mid);
Naoto_111 1:250e7251f8fc 535 fseek(mid, 1, SEEK_CUR);
Naoto_111 1:250e7251f8fc 536 list<int>::iterator i =no.begin();
Naoto_111 1:250e7251f8fc 537 for(; i!=no.end(); i++)if(*i==note)break;
Naoto_111 1:250e7251f8fc 538 no.erase(i);
Naoto_111 1:250e7251f8fc 539
Naoto_111 1:250e7251f8fc 540 } else no.push_back(note);
Naoto_111 1:250e7251f8fc 541 }
Naoto_111 1:250e7251f8fc 542
Naoto_111 1:250e7251f8fc 543 else if(0xA0<=tmp&&tmp<=0xAF) { //polyphonic key pressure
Naoto_111 1:250e7251f8fc 544 ch=tmp-0xA0;
Naoto_111 1:250e7251f8fc 545 fread(&note,1,1,mid);
Naoto_111 1:250e7251f8fc 546 fread(&vel,1,1,mid);
Naoto_111 1:250e7251f8fc 547 } else if(0xB0<=tmp&&tmp<=0xBF) { //control change
Naoto_111 1:250e7251f8fc 548 ch=tmp-0xB0;
Naoto_111 1:250e7251f8fc 549 fread(&ctrl,1,1,mid);
Naoto_111 1:250e7251f8fc 550 fread(&value,1,1,mid);
Naoto_111 1:250e7251f8fc 551 } else if(0xC0<=tmp&&tmp<=0xCF) { //program change
Naoto_111 1:250e7251f8fc 552 ch=tmp-0xC0;
Naoto_111 1:250e7251f8fc 553 fread(&prgm,1,1,mid);
Naoto_111 1:250e7251f8fc 554 } else if(0xD0<=tmp&&tmp<=0xDF) { //channel pressure
Naoto_111 1:250e7251f8fc 555 ch=tmp-0x90;
Naoto_111 1:250e7251f8fc 556 fread(&prsr,1,1,mid);
Naoto_111 1:250e7251f8fc 557 } else if(0xE0<=tmp&&tmp<=0xEF) { //pitch bend
Naoto_111 1:250e7251f8fc 558 ch=tmp-0xE0;
Naoto_111 1:250e7251f8fc 559 fread(&pbend,2,1,mid);
Naoto_111 1:250e7251f8fc 560 } else { //running status
Naoto_111 1:250e7251f8fc 561 tmp=prev;
Naoto_111 1:250e7251f8fc 562 fseek(mid, -1, SEEK_CUR);
Naoto_111 1:250e7251f8fc 563 pc.printf(" ->%x\r\n",tmp);
Naoto_111 1:250e7251f8fc 564 goto MIDIEVENT;
Naoto_111 1:250e7251f8fc 565 }
Naoto_111 1:250e7251f8fc 566 }
Naoto_111 1:250e7251f8fc 567
Naoto_111 1:250e7251f8fc 568
Naoto_111 1:250e7251f8fc 569
Naoto_111 1:250e7251f8fc 570 }
Naoto_111 1:250e7251f8fc 571
Naoto_111 1:250e7251f8fc 572 end2:
Naoto_111 1:250e7251f8fc 573 fclose(mid);
Naoto_111 0:7c17c3b3a8d7 574 }