static int mlib_store_meta_event (mlib_desc * desc, mlib_track * track, int *optr, unsigned char *evbuf, int len) { int type = evbuf[0]; int i; /* * The event is stored at the end of this function. If there is no * need to store the event, the case entry should return (return 1). */ switch (type) { case 0x00: /* Extension events ?????????????? */ /* Not supported yet */ break; case 0x01: /* Descriptive text */ case 0x02: /* Copyright notice */ case 0x03: /* Sequence/track name */ case 0x04: /* Instrument name */ case 0x05: /* Lyric */ case 0x06: /* Marker */ case 0x07: /* Cue point */ #if 0 for (i = 0; i < len - 1; i++) printf ("%c", evbuf[1 + i]); printf ("\n"); #endif break; case 0x21: /* What is this */ break; /* Here is a big hole in the known meta event space */ case 0x2f: /* End of track */ break; /* Here is a big hole in the known meta event space */ case 0x51: /* Set tempo (usec per MIDI quarter-note) */ { int tempo_bpm = 120; unsigned int usecs_per_qn; usecs_per_qn = (evbuf[1] << 16) | (evbuf[2] << 8) | evbuf[3]; tempo_bpm = (60000000 + (usecs_per_qn / 2)) / usecs_per_qn; STORE (SEQ_SET_TEMPO (tempo_bpm)); return 1; } break; case 0x54: /* SMPTE offset */ break; case 0x58: /* Time signature */ { unsigned sig; sig = evbuf[1] << 24; sig |= evbuf[2] << 16; sig |= evbuf[3] << 8; sig |= evbuf[4]; if (!desc->timesig) desc->timesig = sig; STORE (SEQ_TIME_SIGNATURE (sig)); } break; case 0x59: /* Key signature */ break; case 0x7f: /* Vendor specific meta event */ if (evbuf[1] == 0 && evbuf[2] == 0 && evbuf[3] == 0x41) { /* Microsoft ?? */ if (len == 4) DEB_ALWAYS (printf ("GM file flag \n")); /* Don't forget to add more code here */ } else { DEB_ALWAYS (printf ("Private meta event:\n")); for (i = 0; i < len; i++) DEB_ALWAYS (printf ("%02x ", evbuf[i])); DEB_ALWAYS (printf ("\n")); for (i = 0; i < len; i++) DEB_ALWAYS (printf ("%c", (evbuf[i] >= ' ' && evbuf[i] < 127) ? evbuf[i] : '.')); DEB_ALWAYS (printf ("\n")); } break; default: DEB_ALWAYS (printf ("Meta event: 0x%02x???\n", type)); for (i = 0; i < len; i++) DEB_ALWAYS (printf ("%02x ", evbuf[i])); DEB_ALWAYS (printf ("\n")); for (i = 0; i < len; i++) DEB_ALWAYS (printf ("%c", (evbuf[i] >= ' ' && evbuf[i] < 127) ? evbuf[i] : '.')); DEB_ALWAYS (printf ("\n")); } STORE (META_EVENT (type, evbuf, len)); return 1; }
static int midi_adlib_open(int data_length, byte *data_ptr, int data2_length, byte *data2_ptr, void *seq) { int nrdevs, i, n; struct synth_info info; struct sbi_instrument sbi; if (data_length < 1344) { printf ("invalid patch.003"); return -1; } for (i = 0; i < 48; i++) make_sbi((adlib_def *)(data_ptr+(28 * i)), adlib_sbi[i]); if (data_length > 1344) for (i = 48; i < 96; i++) make_sbi((adlib_def *)(data_ptr+2+(28 * i)), adlib_sbi[i]); memset(instr, 0, sizeof(instr)); if (!IS_VALID_FD(seqfd=open("/dev/sequencer", O_WRONLY, 0))) { perror("/dev/sequencer"); return(-1); } if (ioctl(seqfd, SNDCTL_SEQ_NRSYNTHS, &nrdevs) == -1) { perror("/dev/sequencer"); return(-1); } for (i=0;i<nrdevs && dev==-1;i++) { info.device = i; if (ioctl(seqfd, SNDCTL_SYNTH_INFO, &info)==-1) { perror("info: /dev/sequencer"); return(-1); } if (info.synth_type == SYNTH_TYPE_FM) dev = i; } if (dev == -1) { fprintf(stderr, "ADLIB: FM synthesizer not detected\n"); return(-1); } /* free_voices = info.nr_voices; */ adlib_init_lists(); printf("ADLIB: Loading patches into synthesizer\n"); sbi.device = dev; sbi.key = FM_PATCH; for (i = 0; i < 96; i++) { for (n = 0; n < 32; n++) memcpy(sbi.operators, &adlib_sbi[i], sizeof(sbi_instr_data)); sbi.channel=i; SEQ_WRPATCH(&sbi, sizeof(sbi)); SEQ_DUMPBUF(); } SEQ_START_TIMER(); SEQ_SET_TEMPO(60); SEQ_DUMPBUF(); return 0; }