static inline int midi_adlib_event1(guint8 command, guint8 note, guint8 velocity) { guint8 channel, oper; channel = command & 0x0f; oper = command & 0xf0; switch (oper) { case 0x80: adlib_stop_note(channel, note, velocity); return 0; case 0x90: adlib_start_note(channel,note,velocity); return 0; case 0xe0: /* Pitch bend needs scaling? */ SEQ_BENDER(dev, channel, ((note << 8) & velocity)); SEQ_DUMPBUF(); break; case 0xb0: /* CC changes. we ignore. */ /* XXXX we need to parse out 0x07 volume, at least. */ return 0; case 0xd0: /* aftertouch */ SEQ_CHN_PRESSURE(dev, channel, note); SEQ_DUMPBUF(); return 0; default: printf("ADLIB: Unknown event %02x\n", command); return 0; } SEQ_DUMPBUF(); return 0; }
void seq_close() { SEQ_DUMPBUF(); ioctl(seqfd,SNDCTL_SEQ_SYNC); close(seqfd); d_free(voices); }
void seq_close() { SEQ_DUMPBUF(); ioctl(seqfd,SNDCTL_SEQ_SYNC); close(seqfd); D2_FREE(voices); }
/* change the instrument on a given channel */ virtual void programchange( char program, char channel = 0x0 ) { if (mFile == -1) return; SEQ_PGM_CHANGE( mDevice, program, channel ); SEQ_SET_PATCH( mDevice, channel, program ); SEQ_DUMPBUF(); // write immediately }
void stop_all() { int i; #ifdef WANT_AWE32 int j; if (card_info.synth_type == SYNTH_TYPE_SAMPLE && card_info.synth_subtype == SAMPLE_TYPE_AWE32) { for (i=0; i<16;i++) for (j=0;j<128;j++) SEQ_STOP_NOTE(synth_dev,i,j,0); } else #endif #ifdef WANT_MPU401 if (card_info.synth_type==SYNTH_TYPE_MIDI) { MIDI_RESET; SEQ_DUMPBUF(); } else #endif { for (i=0; i<card_info.nr_voices;i++) SEQ_STOP_NOTE(synth_dev,i,voices[i].note,0); } }
int adlib_stop_note(int chn, int note, int velocity) { int i, op=255; for (i=0;i<ADLIB_VOICES && op==255;i++) { if (oper_chn[i] == chn) if (oper_note[i] == note) op=i; } if (op==255) { printf ("can't stop.. chn %d %d %d\n", chn, note, velocity); return 255; /* not playing */ } SEQ_STOP_NOTE(dev, op, note, velocity); SEQ_DUMPBUF(); oper_chn[op] = 255; oper_note[op] = 255; note_time[op] = 0; free_voices++; return op; }
static void adlib_start_note(int chn, int note, int velocity) { int free; struct timeval now; if (velocity == 0) { adlib_stop_note(chn, note, velocity); return; } gettimeofday(&now, NULL); if (free_voices <= 0) free = adlib_kill_one_note(chn); else for (free = 0; free < ADLIB_VOICES ; free++) if (oper_chn[free] == 255) break; /* printf("play operator %d/%d: %d %d %d\n", free, free_voices, chn, note, velocity); */ oper_chn[free] = chn; oper_note[free] = note; note_time[free] = now.tv_sec * 1000000 + now.tv_usec; free_voices--; SEQ_SET_PATCH(dev, free, instr[chn]); SEQ_START_NOTE(dev, free, note, velocity); SEQ_DUMPBUF(); }
void seq_close() { SEQ_DUMPBUF(); ioctl(seqfd,SNDCTL_SEQ_SYNC); close(seqfd); delete[] voices; voices = NULL; }
int adlib_kill_one_note(int chn) { int oldest = 255, i = 255; long time = 0; if (free_voices >= ADLIB_VOICES) { printf("Free list empty but no notes playing\n"); return 255; } /* No notes playing */ for (i = 0; i < ADLIB_VOICES ; i++) { if (oper_chn[i] != chn) continue; if (note_time[i] == 0) continue; if (time == 0) { time = note_time[i]; oldest = i; continue; } if (note_time[i] < time) { time = note_time[i]; oldest = i; } } /* printf("Killing chn %d, oper %d\n", chn, oldest); */ if (oldest == 255) return 255; /* Was already stopped. Why? */ SEQ_STOP_NOTE(dev, oldest, oper_note[oldest], 0); SEQ_DUMPBUF(); oper_chn[oldest] = 255; oper_note[oldest] = 255; note_time[oldest] = 0; free_voices++; return oldest; }
static inline int midi_adlib_event2(guint8 command, guint8 param) { guint8 channel; guint8 oper; channel = command & 0x0f; oper = command & 0xf0; switch (oper) { case 0xc0: { /* change instrument */ int inst = param; instr[channel] = inst; /* XXXX offset? */ // SEQ_SET_PATCH(dev, channel, inst); // SEQ_DUMPBUF(); return 0; } default: printf("ADLIB: Unknown event %02x\n", command); } SEQ_DUMPBUF(); return 0; }
/* release the midi note, velocity is ignored and should be 0 */ virtual void release( char note, char channel = 0x0, char velocity = 0x00 ) { if (mFile == -1) return; SEQ_STOP_NOTE( mDevice, channel, note, 0 ); SEQ_DUMPBUF(); // write immediately }
/* trigger the midi note, on channel, with velocity */ virtual void trigger( char note, char channel = 0x0, char velocity = 0x40 ) { if (mFile == -1) return; SEQ_START_NOTE( mDevice, channel, note, velocity ); SEQ_DUMPBUF(); // write immediately }
int seq_init() { int nrmidis,nrsynths,i; if ((seqfd = open(SEQ_DEV, O_WRONLY, 0)) < 0) { perror ("Error opening sequencer device"); return (-1); } if (ioctl(seqfd, SNDCTL_SEQ_NRSYNTHS, &nrsynths) == -1) { perror ("There is no soundcard"); return (-1); } if (ioctl(seqfd, SNDCTL_SEQ_NRMIDIS, &nrmidis) == -1) { perror ("There is no soundcard"); return (-1); } if(nrsynths < 1 && nrmidis < 1) { con_printf(CON_URGENT,"No synth or midi device!\n"); return -1; } synth_dev = 0; //Check if we have wavetable synth device for (i=0; i < nrsynths; i++) { card_info.device = i; if (ioctl(seqfd, SNDCTL_SYNTH_INFO, &card_info) == -1) { perror("cannot get info on soundcard"); return (-1); } if (card_info.synth_type == SYNTH_TYPE_SAMPLE) { synth_dev = i; break; } } #ifdef WANT_AWE32 for (i=0; i < nrsynths; i++) { card_info.device = i; if (ioctl(seqfd, SNDCTL_SYNTH_INFO, &card_info) == -1) { perror("cannot get info on soundcard"); return (-1); } if (card_info.synth_type==SYNTH_TYPE_SAMPLE &&card_info.synth_subtype==SAMPLE_TYPE_AWE32) { synth_dev = i; break; } } #endif #ifdef WANT_MPU401 for (i=0; i < nrmidis; i++) { struct midi_info cinfo; cinfo.device = i; if (ioctl(seqfd, SNDCTL_MIDI_INFO, &cinfo) == -1) { perror("cannot get info on soundcard"); return (-1); } // Just take first available for now. card_info.synth_type=SYNTH_TYPE_MIDI; card_info.device=i; synth_dev=i; break; } if (card_info.synth_type!=SYNTH_TYPE_MIDI) { #endif card_info.device = synth_dev; if (ioctl(seqfd, SNDCTL_SYNTH_INFO, &card_info) == -1) { perror("cannot get info on soundcard"); return (-1); } #ifdef WANT_MPU401 } if (card_info.synth_type==SYNTH_TYPE_MIDI) { MIDI_RESET; SEQ_DUMPBUF(); } else #endif #ifdef WANT_AWE32 if (card_info.synth_type == SYNTH_TYPE_SAMPLE && card_info.synth_subtype == SAMPLE_TYPE_AWE32) { AWE_SET_CHANNEL_MODE(synth_dev,1); AWE_DRUM_CHANNELS(synth_dev,drumflag); } else #endif { voices = malloc(sizeof(Voice_info)*card_info.nr_voices); for (i=0;i<card_info.nr_voices;i++) { voices[i].note = -1; voices[i].channel = -1; } } return(0); }
static int midi_adlib_close(void) { SEQ_DUMPBUF(); return close(seqfd); }
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; }
static void midooss_write(unsigned char val) { SEQ_MIDIOUT(0, val); SEQ_DUMPBUF(); }