8 static int parse_args(int argc, char **argv);
10 static int bottom[] = {
11 0, 2, 4, 5, 7, 9, 11, 12, 14, 16
14 -1, 1, 3, -1, 6, 8, 10, -1, 13, 15
17 static int port = 0x330;
19 static int octave = 4;
20 static int octave_offs = 60;
24 static int note_state[128];
26 static const char *helptext =
28 " Play using the bottom two rows of the keyboard. Esc to exit.\n"
29 " change MIDI channel: 1-8 change instrument: (/)\n"
30 " shift octave: [/] change velocity: +/-\n";
33 int main(int argc, char **argv)
36 char *env, *ptr, *endp;
38 if((env = getenv("BLASTER")) && ((ptr = strstr(env, "P:")) ||
39 (ptr = strstr(env, "p:")))) {
40 port = strtol(ptr + 2, &endp, 16);
42 fprintf(stderr, "invalid MPU port specified in BLASTER environment variable, ignoring\n");
47 if(parse_args(argc, argv) == -1) {
53 printf("Initializing MIDI interface at port %x\n", port);
54 if(midi_init(port) == -1) {
55 fprintf(stderr, "failed to initialize MPU port\n");
58 midi_chprog(chan, prog);
60 fputs(helptext, stdout);
69 if(ev.code >= 44 && ev.code <= 53) {
70 note = bottom[ev.code - 44] + octave_offs;
71 if(note_state[note] != ev.press) {
72 midi_note(chan, note, ev.press ? vel : 0);
74 note_state[note] = ev.press;
76 } else if(ev.code >= 30 && ev.code <= 40) {
77 if((note = top[ev.code - 30]) != -1) {
79 if(note_state[note] != ev.press) {
80 midi_note(chan, note, ev.press ? vel : 0);
82 note_state[note] = ev.press;
84 } else if(c >= '1' && c <= '8') {
90 octave_offs = --octave * 12 + 12;
91 printf("octave: %d (midi offset: %d)\n", octave, octave_offs);
97 octave_offs = ++octave * 12 + 12;
98 printf("octave: %d (midi offset: %d)\n", octave, octave_offs);
103 prog = (prog - 1) & 0x7f;
104 printf("[%d] instrument: %d\n", chan, prog);
105 midi_chprog(chan, prog);
109 prog = (prog + 1) & 0x7f;
110 printf("[%d] instrument: %d\n", chan, prog);
111 midi_chprog(chan, prog);
117 printf("velocity: %d\n", vel);
124 printf("velocity: %d\n", vel);
137 static const char *usage_fmt = "Usage: %s [options]\n"
139 " -p <port>: set MIDI base I/O port\n"
140 " -c <channel>: set MIDI channel\n"
141 " -i <instrument>: MIDI instrument\n"
142 " -o <octave>: select octave (1-7)\n"
143 " -h: print usage information and exit\n"
146 static int parse_args(int argc, char **argv)
151 for(i=1; i<argc; i++) {
152 if(argv[i][0] == '-') {
154 fprintf(stderr, "invalid option: %s\n", argv[i]);
155 printf(usage_fmt, argv[0]);
160 if(!argv[++i] || ((port = strtol(argv[i], &endp, 16)), endp == argv[i])) {
161 fprintf(stderr, "-p should be followed by the port number in hex\n");
167 if(!argv[++i] || !(chan = atoi(argv[i]))) {
168 fprintf(stderr, "-c should be followed by the channel number\n");
174 if(!argv[++i] || !(prog = atoi(argv[i]))) {
175 fprintf(stderr, "-i should be followed by a valid channel number\n");
181 if(!argv[++i] || !(octave = atoi(argv[i]))) {
182 fprintf(stderr, "-o should be followed by the octane number.\n");
187 printf(usage_fmt, argv[0]);
191 fprintf(stderr, "invalid option: %s\n", argv[i]);
192 printf(usage_fmt, argv[0]);
196 fprintf(stderr, "unexpected argument: %s\n", argv[i]);
197 printf(usage_fmt, argv[0]);