source: buchla-68k/orig/GEMDOS/MIDIVIEW.C

Last change on this file was 3ae31e9, checked in by Thomas Lopatic <thomas@…>, 7 years ago

Imported original source code.

  • Property mode set to 100755
File size: 19.1 KB
Line 
1/* midiview.c - a MIDI data display program
2 7/22/87 by J. Johnson
3
4 Original version compiled with Megamax C version 1.1
5 This modified version compiled with Mark Williams C
6
7 (c) 1987 by Antic Publishing, Inc. */
8
9#include <stdio.h>
10#include <osbind.h>
11#include <gemdefs.h>
12/* #include <string.h> */ /* Used with Megamax C compiler */
13
14#define note_string "CCDDEFFGGAAB" /* For data to note conversion */
15#define MIDI 2 /* device number */
16
17/* globals and arrays for GEM */
18int intin[256], intout[256], ptsin[256];
19int ptsout[256], contrl[12];
20int handle, dummy;
21int gr_mkmx, gr_mkmy; /* X & Y coordinates of mouse */
22int gr_mkmstate, gr_mkkstate; /* mouse button and keyboard status */
23
24int byte_num = 1; /* counter for two byte MIDI data fields */
25
26struct iorec /* structure for MIDI buffer description */
27{ char *ibuf;
28 int ibufsize;
29 int ibufhd;
30 int ibuftl;
31 int ibuflow;
32 int ibufhigh;
33};
34
35/* MAIN PROGRAM LOOP */
36main()
37{ int midistat, midibyte, device;
38
39 init_gem(); /* GEM initialization */
40 midi_buffer(); /* move MIDI buffer & increase size */
41 form_alert(1,"[0][MIDIVIEW - A MIDI Data Window| By Jim Johnson| Press Alternate to pause| or Control to quit|][Let's go]");
42
43 device = form_alert(1,"[2][ |Send output to..][Screen|Printer]");
44
45 v_hide_c(handle); /* hide cursor */
46 v_clrwk(handle); /* clear screen */
47 clean_buffer(); /* clear out MIDI buffer */
48 printf("Ready to accept MIDI data.\n");
49
50 if (device == 2)
51 { printf("Output will go to printer.\n");
52 freopen("PRN:","w",stdout);
53 }
54
55 /* Check for Esc and Control keys */
56 gr_mkkstate = 0;
57 while(gr_mkkstate != 4)
58 { graf_mkstate(&gr_mkmx, &gr_mkmy, &gr_mkmstate, &gr_mkkstate);
59 while(gr_mkkstate == 8)
60 { graf_mkstate(&gr_mkmx, &gr_mkmy, &gr_mkmstate, &gr_mkkstate);
61 }
62 midistat = midi_status();
63 if(midistat != 0)
64 { midibyte = from_midi();
65 print_midi(midibyte);
66 }
67 }
68
69
70 v_show_c(handle);
71 appl_exit();
72}
73/* FUNCTIONS */
74
75/* initialize GEM and application*/
76init_gem()
77{ int i;
78 for(i = 0; i < 10; intin[i++]=1);
79 intin[10] = 2;
80 appl_init();
81 handle = graf_handle(&dummy, &dummy, &dummy, &dummy);
82 v_opnvwk(intin, &handle, intout);
83}
84
85/* set up MIDI buffer */
86midi_buffer()
87{ char *malloc();
88 unsigned size;
89 long temp_pointer; /* temporary storage for pointers -
90 must be type cast to pointer after
91 assignment */
92 struct iorec *midi_buff;
93 size = 16384; /* 16K MIDI buffer */
94
95 temp_pointer = Iorec(MIDI); /* pointer to buffer descriptor */
96 midi_buff = (struct iorec *)temp_pointer; /* cast to pointer */
97 (*midi_buff).ibuf = malloc(size); /* change address of buffer */
98 (*midi_buff).ibufsize = size; /* and size, too */
99}
100
101/* get MIDI byte */
102from_midi()
103{ int midibyte;
104 midibyte = Bconin(3);
105 midibyte &= 0x00ff;
106 return(midibyte);
107}
108
109/* print midibyte */
110print_midi(midibyte)
111int midibyte;
112
113{ char interpretation[40];
114 static int index;
115 interpret(midibyte,interpretation);
116 printf(" %6d %-4d %s\n",++index,midibyte,interpretation);
117 return;
118}
119
120/* check midi status */
121midi_status()
122{ int midistat;
123 midistat = Bconstat(3);
124 if (midistat != 0)
125 midistat = 1;
126 return(midistat);
127}
128
129/* clean out MIDI buffer */
130clean_buffer()
131{ int midibyte, data_flag;
132 data_flag = midi_status();
133 while(data_flag == 1)
134 { from_midi();
135 data_flag = midi_status();
136 }
137}
138
139interpret(midibyte,interpretation)
140int midibyte;
141char *interpretation;
142{ static int type;
143 extern int byte_num;
144 if (midibyte>127)
145 type = num_to_status(midibyte,interpretation, type);
146 else if (byte_num == 1)
147 { switch(type)
148 { case 0:
149 type_to_text(type,interpretation);
150 break;
151 case 1:
152 case 2:
153 num_to_note(midibyte,interpretation);
154 break;
155 case 3:
156 num_to_cc(midibyte,interpretation);
157 break;;
158 case 4:
159 type_to_text(type,interpretation);
160 break;
161 case 5:
162 num_to_pb(midibyte,interpretation);
163 break;
164 case 6:
165 num_to_spp(midibyte,interpretation);
166 break;
167 }
168 }
169 else
170 { switch (type)
171 { case 0:
172 case 1:
173 case 2:
174 case 3:
175 case 4:
176 type_to_text(type,interpretation);
177 break;
178 case 5:
179 num_to_pb(midibyte,interpretation);
180 break;
181 case 6:
182 num_to_spp(midibyte,interpretation);
183 break;
184 }
185 }
186 return;
187}
188
189/* convert MIDI status byte to text description */
190num_to_status(midibyte,interpretation,old_type)
191int midibyte, old_type;
192char *interpretation;
193{ char *int_string;
194 int new_type;
195 extern int byte_num;
196 new_type = old_type;
197 if (midibyte<240)
198 { new_type = num_to_ch_mess(midibyte,interpretation,new_type);
199 byte_num = 1;
200 }
201 else
202 { switch(midibyte)
203 { case 240:
204 int_string = "System Exclusive";
205 new_type = 4;
206 byte_num = 1;
207 break;
208 case 242:
209 int_string = "Song Position Pointer";
210 new_type = 6;
211 byte_num = 1;
212 break;
213 case 243:
214 int_string = "Song Select";
215 new_type = 4;
216 byte_num = 1;
217 break;
218 case 246:
219 int_string = "Tune";
220 new_type = 0;
221 break;
222 case 247:
223 int_string = "End of SysEx";
224 new_type = 0;
225 break;
226 case 248:
227 int_string = "Clock";
228 break;
229 case 250:
230 int_string = "Start";
231 break;
232 case 251:
233 int_string = "Continue";
234 break;
235 case 252:
236 int_string = "Stop";
237 break;
238 case 254:
239 int_string = "Active Sense";
240 break;
241 case 255:
242 int_string = "System Reset";
243 break;
244 default:
245 int_string = "Undefined";
246 new_type = 0;
247 break;
248 }
249 strcpy(interpretation,int_string);
250 }
251 return new_type;
252}
253
254/* convert MIDI byte to channel message description */
255num_to_ch_mess(midibyte,interpretation,old_type)
256int midibyte, old_type;
257char *interpretation;
258{ int top_nybble, channel, new_type;
259 char chan_string[3], *int_string;
260 new_type = old_type;
261 top_nybble = ((midibyte & 112)/16);
262 channel = (midibyte & 15)+1;
263 switch (top_nybble)
264 { case 0:
265 int_string = "Note Off, Channel ";
266 new_type = 1;
267 break;
268 case 1:
269 int_string = "Note On, Channel ";
270 new_type = 1;
271 break;
272 case 2:
273 int_string = "Key Pressure, Channel ";
274 new_type = 2;
275 break;
276 case 3:
277 int_string = "Control Change, Channel ";
278 new_type = 3;
279 break;
280 case 4:
281 int_string = "Program Change, Channel ";
282 new_type = 4;
283 break;
284 case 5:
285 int_string = "Channel Pressure, Channel ";
286 new_type = 2;
287 break;
288 case 6:
289 int_string = "Pitch Bend, Channel ";
290 new_type = 5;
291 break;
292 }
293 strcpy(interpretation, int_string);
294 itoa(channel,chan_string);
295 strcat(interpretation,chan_string);
296 return new_type;
297}
298
299/* convert MIDI data byte to text description */
300type_to_text(number,text)
301int number;
302char *text;
303{ char *string;
304 extern int byte_num;
305 switch(number)
306 { case 0:
307 string = "?";
308 break;
309 case 1:
310 string = "Velocity";
311 byte_num = 1;
312 break;
313 case 2:
314 case 3:
315 string = "Value";
316 byte_num = 1;
317 break;
318 case 4:
319 string = "Data";
320 break;
321 }
322 strcpy(text,string);
323 return;
324}
325
326/* convert MIDI note number to Dr. T pitch notation */
327 /* data types 1 & 2 */
328num_to_note(number,note)
329int number;
330char *note;
331{ int octave, pitch;
332 extern int byte_num;
333 byte_num = 2; /* next byte is velocity value */
334 *(note+3)='\0';
335 octave=(number/12)-1;
336 switch (octave)
337 { case -1:
338 *(note+2)='-';
339 break;
340 default:
341 *(note+2)=octave+48;
342 break;
343 }
344 pitch=number % 12;
345 *note=note_string[pitch];
346 switch (pitch)
347 { case 1:
348 case 3:
349 case 6:
350 case 8:
351 case 10:
352 *(note+1)='#';
353 break;
354 default:
355 *(note+1)=' ';
356 break;
357 }
358 return;
359}
360
361
362/* convert MIDI controller to text description */
363 /* data type 3 */
364num_to_cc(number,controller)
365int number;
366char *controller;
367{ char *string, *lsb;
368 extern int byte_num;
369 byte_num = 2;
370 switch(number)
371 { case 1:
372 case 33:
373 string = "Modulation Wheel";
374 break;
375 case 2:
376 case 34:
377 string = "Breath Controller";
378 break;
379 case 3:
380 case 35:
381 string = "DX7 Pressure";
382 break;
383 case 4:
384 case 36:
385 string = "Pedal";
386 break;
387 case 5:
388 case 37:
389 string = "Portamento Time";
390 break;
391 case 6:
392 case 38:
393 string = "Data Entry";
394 break;
395 case 7:
396 case 39:
397 string = "Volume";
398 break;
399 case 8:
400 case 40:
401 string = "Balance";
402 break;
403 case 10:
404 case 42:
405 string = "Pan";
406 break;
407 case 11:
408 case 43:
409 string = "Expression";
410 break;
411 case 16:
412 case 48:
413 string = "General Purpose #1";
414 break;
415 case 17:
416 case 49:
417 string = "General Purpose #2";
418 break;
419 case 18:
420 case 50:
421 string = "General Purpose #3";
422 break;
423 case 19:
424 case 51:
425 string = "General Purpose #4";
426 break;
427 case 64:
428 string = "Sustain Switch";
429 break;
430 case 65:
431 string = "Portamento Switch";
432 break;
433 case 66:
434 string = "Sustenuto Switch";
435 break;
436 case 67:
437 string = "Soft Pedal";
438 break;
439 case 69:
440 string = "Hold Switch";
441 break;
442 case 80:
443 string = "General Purpose #5";
444 break;
445 case 81:
446 string = "General Purpose #6";
447 break;
448 case 82:
449 string = "General Purpose #7";
450 break;
451 case 83:
452 string = "General Purpose #8";
453 break;
454 case 92:
455 string = "Tremolo";
456 break;
457 case 93:
458 string = "Chorus";
459 break;
460 case 94:
461 string = "Celeste";
462 break;
463 case 95:
464 string = "Phase";
465 break;
466 case 96:
467 string = "Data Increment";
468 break;
469 case 97:
470 string = "Data Decrement";
471 break;
472 case 98:
473 string = "Non-registered Parameter MSB";
474 break;
475 case 99:
476 string = "Non-registered Parameter LSB";
477 break;
478 case 100:
479 string = "Registered Parameter MSB";
480 break;
481 case 101:
482 string = "Registered Parameter LSB";
483 break;
484 case 122:
485 string = "Local Control";
486 break;
487 case 123:
488 string = "All Notes Off";
489 break;
490 case 124:
491 string = "Omni Off";
492 break;
493 case 125:
494 string = "Omni On";
495 break;
496 case 126:
497 string = "Mono On";
498 break;
499 case 127:
500 string = "Poly On";
501 break;
502 default:
503 string = "Unassigned Controller";
504 break;
505 }
506 strcpy(controller,string);
507 if ((number > 31) && (number < 64))
508 { lsb = ", LSB";
509 strcat(controller,lsb);
510 }
511 return;
512}
513
514/* convert MIDI pitch bend to value */
515 /* data type 5 */
516num_to_pb(number,value)
517int number;
518char *value;
519{ extern int byte_num;
520 char *string;
521 static int pitch_bend;
522 if (byte_num == 1)
523 { string = " ";
524 pitch_bend = number;
525 byte_num = 2;
526 strcpy(value,string);
527 }
528 else
529 { pitch_bend += 128*number;
530 pitch_bend -= 8192;
531 itoa(pitch_bend,value);
532 byte_num = 1;
533 }
534 return;
535}
536
537/* convert MIDI song position pointer to text description */
538 /* data type 6 */
539num_to_spp(number,pointer)
540int number;
541char *pointer;
542{ extern int byte_num;
543 int measure, beat, clock;
544 static int spp;
545 char *string, b[3], c[3], *colon; /* b$[3] and c$[3] in Megamax */
546 colon = ":";
547 if (byte_num == 1)
548 { string = " ";
549 spp = number;
550 byte_num = 2;
551 strcpy(pointer,string);
552 }
553 else
554 { spp += number*128;
555 measure = (spp/16)+1;
556 itoa(measure,pointer);
557 beat = ((spp % 16)/4)+1;
558 itoa(beat,b);
559 clock = (6*((spp % 16) % 4)+1);
560 itoa(clock,c);
561 strcat(pointer,colon);
562 strcat(pointer,b);
563 strcat(pointer,colon);
564 strcat(pointer,c);
565 byte_num = 1;
566 }
567 return;
568}
569
570/* convert integer to string */
571itoa(number, string)
572char string[];
573int number;
574{ int i, sign;
575 if ((sign = number) < 0 )
576 number = -number;
577 i = 0;
578 do
579 { string[i++] = number % 10 + '0';
580 } while ((number /= 10) > 0);
581 if (sign < 0)
582 string[i++] = '-';
583 string[i] = '\0';
584 rev_string(string);
585}
586
587/* reverse string in place */
588rev_string(string)
589char string[];
590{ int c, i, j;
591 for (i = 0, j = strlen(string)-1; i < j; i++, j--)
592 { c = string[i];
593 string[i] = string[j];
594 string[j] = c;
595 }
596}
597
598
599
600
Note: See TracBrowser for help on using the repository browser.