summaryrefslogtreecommitdiff
path: root/apps/plugins/midi/midifile.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/midi/midifile.c')
-rw-r--r--apps/plugins/midi/midifile.c427
1 files changed, 212 insertions, 215 deletions
diff --git a/apps/plugins/midi/midifile.c b/apps/plugins/midi/midifile.c
index c786b8e5a6..412cc6104d 100644
--- a/apps/plugins/midi/midifile.c
+++ b/apps/plugins/midi/midifile.c
@@ -26,233 +26,232 @@ void bail(const char *);
26 26
27struct MIDIfile * loadFile(char * filename) 27struct MIDIfile * loadFile(char * filename)
28{ 28{
29 struct MIDIfile * mf; 29 struct MIDIfile * mf;
30 int file = rb->open (filename, O_RDONLY); 30 int file = rb->open (filename, O_RDONLY);
31 31
32 if(file==0) 32 if(file==-1)
33 { 33 {
34 bail("Could not open file\n"); 34 bail("Could not open file\n");
35 } 35 }
36 36
37 mf = (struct MIDIfile*)allocate(sizeof(struct MIDIfile)); 37 mf = (struct MIDIfile*)allocate(sizeof(struct MIDIfile));
38 38
39 if(mf==NULL) 39 if(mf==NULL)
40 { 40 {
41 rb->close(file); 41 rb->close(file);
42 bail("Could not allocate memory for MIDIfile struct\n"); 42 bail("Could not allocate memory for MIDIfile struct\n");
43 } 43 }
44 44
45 rb->memset(mf, 0, sizeof(struct MIDIfile)); 45 rb->memset(mf, 0, sizeof(struct MIDIfile));
46 46
47 if(readID(file) != ID_MTHD) 47 if(readID(file) != ID_MTHD)
48 { 48 {
49 rb->close(file); 49 rb->close(file);
50 bail("Invalid file header chunk."); 50 bail("Invalid file header chunk.");
51 } 51 }
52 52
53 if(readFourBytes(file)!=6) 53 if(readFourBytes(file)!=6)
54 { 54 {
55 rb->close(file); 55 rb->close(file);
56 bail("Header chunk size invalid."); 56 bail("Header chunk size invalid.");
57 } 57 }
58 58
59 if(readTwoBytes(file)==2) 59 if(readTwoBytes(file)==2)
60 { 60 {
61 rb->close(file); 61 rb->close(file);
62 bail("MIDI file type not supported"); 62 bail("MIDI file type not supported");
63 } 63 }
64 64
65 mf->numTracks = readTwoBytes(file); 65 mf->numTracks = readTwoBytes(file);
66 mf->div = readTwoBytes(file); 66 mf->div = readTwoBytes(file);
67 67
68 int track=0; 68 int track=0;
69 69
70 printf("\nnumTracks=%d div=%d\nBegin reading track data\n", mf->numTracks, mf->div); 70 printf("\nnumTracks=%d div=%d\nBegin reading track data\n", mf->numTracks, mf->div);
71 71
72// return; 72
73 73 while(! eof(file) && track < mf->numTracks)
74 74 {
75 while(! eof(file) && track < mf->numTracks) 75 unsigned char id = readID(file);
76 { 76
77 unsigned char id = readID(file); 77
78 78 if(id == ID_EOF)
79 79 {
80 if(id == ID_EOF) 80 if(mf->numTracks != track)
81 { 81 {
82 if(mf->numTracks != track) 82 printf("\nError: file claims to have %d tracks.\n I only see %d here.\n", mf->numTracks, track);
83 { 83 mf->numTracks = track;
84 printf("\nError: file claims to have %d tracks.\n I only see %d here.\n", mf->numTracks, track); 84 }
85 mf->numTracks = track; 85 return mf;
86 } 86 }
87 return mf; 87
88 } 88 if(id == ID_MTRK)
89 89 {
90 if(id == ID_MTRK) 90 mf->tracks[track] = readTrack(file);
91 { 91 //exit(0);
92 mf->tracks[track] = readTrack(file); 92 track++;
93 //exit(0); 93 } else
94 track++; 94 {
95 } else 95 printf("\n SKIPPING TRACK");
96 { 96 int len = readFourBytes(file);
97 printf("\n SKIPPING TRACK"); 97 while(--len)
98 int len = readFourBytes(file); 98 readChar(file);
99 while(--len) 99 }
100 readChar(file); 100 }
101 } 101 return mf;
102 }
103 return mf;
104 102
105} 103}
106 104
107 105
108int rStatus = 0; 106int rStatus = 0;
109 107
110//Returns 0 if done, 1 if keep going 108/* Returns 0 if done, 1 if keep going */
111int readEvent(int file, void * dest) 109int readEvent(int file, void * dest)
112{ 110{
113 struct Event dummy; 111 struct Event dummy;
114 struct Event * ev = (struct Event *) dest; 112 struct Event * ev = (struct Event *) dest;
115 113
116 if(ev == NULL) 114 if(ev == NULL)
117 ev = &dummy; //If we are just counting events instead of loading them 115 ev = &dummy; /* If we are just counting events instead of loading them */
118 116
119 ev->delta = readVarData(file); 117 ev->delta = readVarData(file);
120 118
121 119
122 int t=readChar(file); 120 int t=readChar(file);
123 121
124 if((t&0x80) == 0x80) //if not a running status event 122 if((t&0x80) == 0x80) /* if not a running status event */
125 { 123 {
126 ev->status = t; 124 ev->status = t;
127 if(t == 0xFF) 125 if(t == 0xFF)
128 { 126 {
129 ev->d1 = readChar(file); 127 ev->d1 = readChar(file);
130 ev->len = readVarData(file); 128 ev->len = readVarData(file);
131 129
132 //Allocate and read in the data block 130 /* Allocate and read in the data block */
133 if(dest != NULL) 131 if(dest != NULL)
134 { 132 {
135 ev->evData = readData(file, ev->len); 133 ev->evData = readData(file, ev->len);
136 printf("\nDATA: <%s>", ev->evData); 134 printf("\nDATA: <%s>", ev->evData);
137 } 135 }
138 else 136 else
139 { 137 {
140 //Don't allocate anything, just see how much it would tale 138 /*
141 //To make memory usage efficient 139 * Don't allocate anything, just see how much it would tale
142 140 * To make memory usage efficient
143 int a=0; 141 */
144 for(a=0; a<ev->len; a++) 142 unsigned int a=0;
145 readChar(file); //Skip skip 143 for(a=0; a<ev->len; a++)
146 } 144 readChar(file); //Skip skip
147 145 }
148 if(ev->d1 == 0x2F) 146
149 { 147 if(ev->d1 == 0x2F)
150 return 0; //Termination meta-event 148 {
151 } 149 return 0; /* Termination meta-event */
152 } else //If part of a running status event 150 }
153 { 151 } else /* If part of a running status event */
154 rStatus = t; 152 {
155 ev->status = t; 153 rStatus = t;
156 ev->d1 = readChar(file); 154 ev->status = t;
157 155 ev->d1 = readChar(file);
158 if ( ((t & 0xF0) != 0xD0) && ((t & 0xF0) != 0xC0) && ((t & 0xF0) > 0x40) ) 156
159 { 157 if ( ((t & 0xF0) != 0xD0) && ((t & 0xF0) != 0xC0) && ((t & 0xF0) > 0x40) )
160 ev->d2 = readChar(file); 158 {
161 } else 159 ev->d2 = readChar(file);
162 ev->d2 = 127; 160 } else
163 } 161 ev->d2 = 127;
164 } else //Running Status 162 }
165 { 163 } else /* Running Status */
166 ev->status = rStatus; 164 {
167 ev->d1 = t; 165 ev->status = rStatus;
168 if ( ((rStatus & 0xF0) != 0xD0) && ((rStatus & 0xF0) != 0xC0) && ((rStatus & 0xF0) > 0x40) ) 166 ev->d1 = t;
169 { 167 if ( ((rStatus & 0xF0) != 0xD0) && ((rStatus & 0xF0) != 0xC0) && ((rStatus & 0xF0) > 0x40) )
170 ev->d2 = readChar(file); 168 {
171 } else 169 ev->d2 = readChar(file);
172 ev->d2 = 127; 170 } else
173 } 171 ev->d2 = 127;
174 return 1; 172 }
173 return 1;
175} 174}
176 175
177 176
178 177
179struct Track * readTrack(int file) 178struct Track * readTrack(int file)
180{ 179{
181 struct Track * trk = (struct Track *)allocate(sizeof(struct Track)); 180 struct Track * trk = (struct Track *)allocate(sizeof(struct Track));
182 rb->memset(trk, 0, sizeof(struct Track)); 181 rb->memset(trk, 0, sizeof(struct Track));
183 182
184 trk->size = readFourBytes(file); 183 trk->size = readFourBytes(file);
185 trk->pos = 0; 184 trk->pos = 0;
186 trk->delta = 0; 185 trk->delta = 0;
187 186
188 int numEvents=0; 187 int numEvents=0;
189 188
190 int pos = rb->lseek(file, 0, SEEK_CUR); 189 int pos = rb->lseek(file, 0, SEEK_CUR);
191 190
192 while(readEvent(file, NULL)) //Memory saving technique 191 while(readEvent(file, NULL)) /* Memory saving technique */
193 numEvents++; //Attempt to read in events, count how many 192 numEvents++; /* Attempt to read in events, count how many */
194 //THEN allocate memory and read them in 193 /* THEN allocate memory and read them in */
195 rb->lseek(file, pos, SEEK_SET); 194 rb->lseek(file, pos, SEEK_SET);
196 195
197 int trackSize = (numEvents+1) * sizeof(struct Event); 196 int trackSize = (numEvents+1) * sizeof(struct Event);
198 void * dataPtr = allocate(trackSize); 197 void * dataPtr = allocate(trackSize);
199 trk->dataBlock = dataPtr; 198 trk->dataBlock = dataPtr;
200 199
201 numEvents=0; 200 numEvents=0;
202 201
203 while(readEvent(file, dataPtr)) 202 while(readEvent(file, dataPtr))
204 { 203 {
205 if(trackSize < dataPtr-trk->dataBlock) 204 if(trackSize < dataPtr-trk->dataBlock)
206 { 205 {
207 printf("\nTrack parser memory out of bounds"); 206 printf("\nTrack parser memory out of bounds");
208 exit(1); 207 exit(1);
209 } 208 }
210 dataPtr+=sizeof(struct Event); 209 dataPtr+=sizeof(struct Event);
211 numEvents++; 210 numEvents++;
212 } 211 }
213 trk->numEvents = numEvents; 212 trk->numEvents = numEvents;
214 213
215 return trk; 214 return trk;
216} 215}
217 216
218 217
219int readID(int file) 218int readID(int file)
220{ 219{
221 char id[5]; 220 char id[5];
222 id[4]=0; 221 id[4]=0;
223 BYTE a; 222 BYTE a;
224 223
225 for(a=0; a<4; a++) 224 for(a=0; a<4; a++)
226 id[a]=readChar(file); 225 id[a]=readChar(file);
227 if(eof(file)) 226 if(eof(file))
228 { 227 {
229 printf("\End of file reached."); 228 printf("\End of file reached.");
230 return ID_EOF; 229 return ID_EOF;
231 } 230 }
232 if(rb->strcmp(id, "MThd")==0) 231 if(rb->strcmp(id, "MThd")==0)
233 return ID_MTHD; 232 return ID_MTHD;
234 if(rb->strcmp(id, "MTrk")==0) 233 if(rb->strcmp(id, "MTrk")==0)
235 return ID_MTRK; 234 return ID_MTRK;
236 return ID_UNKNOWN; 235 return ID_UNKNOWN;
237} 236}
238 237
239 238
240int readFourBytes(int file) 239int readFourBytes(int file)
241{ 240{
242 int data=0; 241 int data=0;
243 BYTE a=0; 242 BYTE a=0;
244 for(a=0; a<4; a++) 243 for(a=0; a<4; a++)
245 data=(data<<8)+readChar(file); 244 data=(data<<8)+readChar(file);
246 return data; 245 return data;
247} 246}
248 247
249int readTwoBytes(int file) 248int readTwoBytes(int file)
250{ 249{
251 int data=(readChar(file)<<8)+readChar(file); 250 int data=(readChar(file)<<8)+readChar(file);
252 return data; 251 return data;
253} 252}
254 253
255//This came from the MIDI file format guide 254/* This came from the MIDI file format guide */
256int readVarData(int file) 255int readVarData(int file)
257{ 256{
258 unsigned int value; 257 unsigned int value;
@@ -270,37 +269,35 @@ int readVarData(int file)
270 269
271 270
272/* 271/*
273//This function should not be needed because we
274//can just release the whole memory buffer at once
275void unloadFile(struct MIDIfile * mf) 272void unloadFile(struct MIDIfile * mf)
276{ 273{
277 if(mf == NULL) 274 if(mf == NULL)
278 return; 275 return;
279 int a=0; 276 int a=0;
280 //Unload each track 277 //Unload each track
281 for(a=0; a<mf->numTracks; a++) 278 for(a=0; a<mf->numTracks; a++)
282 { 279 {
283 int b=0; 280 int b=0;
284 281
285 if(mf->tracks[a] != NULL) 282 if(mf->tracks[a] != NULL)
286 for(b=0; b<mf->tracks[a]->numEvents; b++) 283 for(b=0; b<mf->tracks[a]->numEvents; b++)
287 { 284 {
288 if(((struct Event*)((mf->tracks[a]->dataBlock)+b*sizeof(struct Event)))->evData!=NULL) 285 if(((struct Event*)((mf->tracks[a]->dataBlock)+b*sizeof(struct Event)))->evData!=NULL)
289 free(((struct Event*)((mf->tracks[a]->dataBlock)+b*sizeof(struct Event)))->evData); 286 free(((struct Event*)((mf->tracks[a]->dataBlock)+b*sizeof(struct Event)))->evData);
290 } 287 }
291 288
292 if(mf->tracks[a]!=NULL && mf->tracks[a]->dataBlock != NULL) 289 if(mf->tracks[a]!=NULL && mf->tracks[a]->dataBlock != NULL)
293 free(mf->tracks[a]->dataBlock); //Unload the event block 290 free(mf->tracks[a]->dataBlock); //Unload the event block
294 291
295 if(mf->tracks[a]!=NULL) 292 if(mf->tracks[a]!=NULL)
296 free(mf->tracks[a]); //Unload the track structure itself 293 free(mf->tracks[a]); //Unload the track structure itself
297 } 294 }
298 free(mf); //Unload the main struct 295 free(mf); //Unload the main struct
299} 296}
300*/ 297*/
301void bail(const char * err) 298void bail(const char * err)
302{ 299{
303 rb->splash(HZ*3, true, err); 300 rb->splash(HZ*3, true, err);
304 exit(0); 301 exit(0);
305} 302}
306 303