static int osc_midi ( DssiEditor *pDssiEditor, lo_arg **argv ) { static snd_midi_event_t *s_pAlsaCoder = NULL; static snd_seq_event_t s_aAlsaEvent[4]; const unsigned char *data = argv[0]->m; #ifdef CONFIG_DEBUG qDebug("osc_midi: path \"%s\", midi 0x%02x 0x%02x 0x%02x 0x%02x", pDssiEditor->path, data[0], data[1], data[2], data[3]); #endif qtractorDssiPlugin *pDssiPlugin = pDssiEditor->plugin; if (pDssiPlugin == NULL) return 1; qtractorMidiManager *pMidiManager = (pDssiPlugin->list())->midiManager(); if (pMidiManager == NULL) return 1; if (s_pAlsaCoder == NULL && snd_midi_event_new(4, &s_pAlsaCoder)) return 1; snd_midi_event_reset_encode(s_pAlsaCoder); if (snd_midi_event_encode(s_pAlsaCoder, &data[1], 3, s_aAlsaEvent) < 1) return 1; // Send the event directly to snd_seq_event_t *pEvent = &s_aAlsaEvent[0]; if (snd_seq_ev_is_channel_type(pEvent)) pMidiManager->direct(pEvent); return 0; }
void SeqContext::set_channel(snd_seq_event_t *ep, int chan) { if( verbose ) fprintf(stderr, "set channel: event type=%d; channel = %d\n", ep->type, chan); switch (ep->type) { case SND_SEQ_EVENT_NOTE: case SND_SEQ_EVENT_NOTEON: case SND_SEQ_EVENT_NOTEOFF: ep->data.note.channel = chan; break; case SND_SEQ_EVENT_KEYPRESS: case SND_SEQ_EVENT_PGMCHANGE: case SND_SEQ_EVENT_CHANPRESS: case SND_SEQ_EVENT_PITCHBEND: case SND_SEQ_EVENT_CONTROL14: case SND_SEQ_EVENT_NONREGPARAM: case SND_SEQ_EVENT_REGPARAM: case SND_SEQ_EVENT_CONTROLLER: ep->data.control.channel = chan; break; default: if (snd_seq_ev_is_channel_type(ep)) fprintf(stderr,"Missed a case in set_channel"); break; } }
static int prioq_remove_match(struct snd_seq_remove_events *info, struct snd_seq_event *ev) { int res; if (info->remove_mode & SNDRV_SEQ_REMOVE_DEST) { if (ev->dest.client != info->dest.client || ev->dest.port != info->dest.port) return 0; } if (info->remove_mode & SNDRV_SEQ_REMOVE_DEST_CHANNEL) { if (! snd_seq_ev_is_channel_type(ev)) return 0; /* data.note.channel and data.control.channel are identical */ if (ev->data.note.channel != info->channel) return 0; } if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_AFTER) { if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_TICK) res = snd_seq_compare_tick_time(&ev->time.tick, &info->time.tick); else res = snd_seq_compare_real_time(&ev->time.time, &info->time.time); if (!res) return 0; } if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_BEFORE) { if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_TICK) res = snd_seq_compare_tick_time(&ev->time.tick, &info->time.tick); else res = snd_seq_compare_real_time(&ev->time.time, &info->time.time); if (res) return 0; } if (info->remove_mode & SNDRV_SEQ_REMOVE_EVENT_TYPE) { if (ev->type != info->type) return 0; } if (info->remove_mode & SNDRV_SEQ_REMOVE_IGNORE_OFF) { /* Do not remove off events */ switch (ev->type) { case SNDRV_SEQ_EVENT_NOTEOFF: /* case SNDRV_SEQ_EVENT_SAMPLE_STOP: */ return 0; default: break; } } if (info->remove_mode & SNDRV_SEQ_REMOVE_TAG_MATCH) { if (info->tag != ev->tag) return 0; } return 1; }
void snd_midi_process_event(struct snd_midi_op *ops, struct snd_seq_event *ev, struct snd_midi_channel_set *chanset) { struct snd_midi_channel *chan; void *drv; int dest_channel = 0; if (ev == NULL || chanset == NULL) { snd_printd("ev or chanbase NULL (snd_midi_process_event)\n"); return; } if (chanset->channels == NULL) return; if (snd_seq_ev_is_channel_type(ev)) { dest_channel = ev->data.note.channel; if (dest_channel >= chanset->max_channels) { snd_printd("dest channel is %d, max is %d\n", dest_channel, chanset->max_channels); return; } } chan = chanset->channels + dest_channel; drv = chanset->private_data; if (ev->type == SNDRV_SEQ_EVENT_NOTE) return; if (ev->type == SNDRV_SEQ_EVENT_NOTEON && ev->data.note.velocity == 0) ev->type = SNDRV_SEQ_EVENT_NOTEOFF; if (ev->type == SNDRV_SEQ_EVENT_NOTEON || ev->type == SNDRV_SEQ_EVENT_NOTEOFF || ev->type == SNDRV_SEQ_EVENT_KEYPRESS) { if (ev->data.note.note >= 128) return; } switch (ev->type) { case SNDRV_SEQ_EVENT_NOTEON: if (chan->note[ev->data.note.note] & SNDRV_MIDI_NOTE_ON) { if (ops->note_off) ops->note_off(drv, ev->data.note.note, 0, chan); } chan->note[ev->data.note.note] = SNDRV_MIDI_NOTE_ON; if (ops->note_on) ops->note_on(drv, ev->data.note.note, ev->data.note.velocity, chan); break; case SNDRV_SEQ_EVENT_NOTEOFF: if (! (chan->note[ev->data.note.note] & SNDRV_MIDI_NOTE_ON)) break; if (ops->note_off) note_off(ops, drv, chan, ev->data.note.note, ev->data.note.velocity); break; case SNDRV_SEQ_EVENT_KEYPRESS: if (ops->key_press) ops->key_press(drv, ev->data.note.note, ev->data.note.velocity, chan); break; case SNDRV_SEQ_EVENT_CONTROLLER: do_control(ops, drv, chanset, chan, ev->data.control.param, ev->data.control.value); break; case SNDRV_SEQ_EVENT_PGMCHANGE: chan->midi_program = ev->data.control.value; break; case SNDRV_SEQ_EVENT_PITCHBEND: chan->midi_pitchbend = ev->data.control.value; if (ops->control) ops->control(drv, MIDI_CTL_PITCHBEND, chan); break; case SNDRV_SEQ_EVENT_CHANPRESS: chan->midi_pressure = ev->data.control.value; if (ops->control) ops->control(drv, MIDI_CTL_CHAN_PRESSURE, chan); break; case SNDRV_SEQ_EVENT_CONTROL14: if (ev->data.control.param < 32) { chan->control[ev->data.control.param + 32] = ev->data.control.value & 0x7f; do_control(ops, drv, chanset, chan, ev->data.control.param, ((ev->data.control.value>>7) & 0x7f)); } else
/* * Process an event in a driver independent way. This means dealing * with RPN, NRPN, SysEx etc that are defined for common midi applications * such as GM, GS and XG. * There modes that this module will run in are: * Generic MIDI - no interpretation at all, it will just save current values * of controllers etc. * GM - You can use all gm_ prefixed elements of chan. Controls, RPN, NRPN, * SysEx will be interpreded as defined in General Midi. * GS - You can use all gs_ prefixed elements of chan. Codes for GS will be * interpreted. * XG - You can use all xg_ prefixed elements of chan. Codes for XG will * be interpreted. */ void snd_midi_process_event(struct snd_midi_op *ops, struct snd_seq_event *ev, struct snd_midi_channel_set *chanset) { struct snd_midi_channel *chan; void *drv; int dest_channel = 0; if (ev == NULL || chanset == NULL) { pr_debug("ALSA: seq_midi_emul: ev or chanbase NULL (snd_midi_process_event)\n"); return; } if (chanset->channels == NULL) return; if (snd_seq_ev_is_channel_type(ev)) { dest_channel = ev->data.note.channel; if (dest_channel >= chanset->max_channels) { pr_debug("ALSA: seq_midi_emul: dest channel is %d, max is %d\n", dest_channel, chanset->max_channels); return; } } chan = chanset->channels + dest_channel; drv = chanset->private_data; /* EVENT_NOTE should be processed before queued */ if (ev->type == SNDRV_SEQ_EVENT_NOTE) return; /* Make sure that we don't have a note on that should really be * a note off */ if (ev->type == SNDRV_SEQ_EVENT_NOTEON && ev->data.note.velocity == 0) ev->type = SNDRV_SEQ_EVENT_NOTEOFF; /* Make sure the note is within array range */ if (ev->type == SNDRV_SEQ_EVENT_NOTEON || ev->type == SNDRV_SEQ_EVENT_NOTEOFF || ev->type == SNDRV_SEQ_EVENT_KEYPRESS) { if (ev->data.note.note >= 128) return; } switch (ev->type) { case SNDRV_SEQ_EVENT_NOTEON: if (chan->note[ev->data.note.note] & SNDRV_MIDI_NOTE_ON) { if (ops->note_off) ops->note_off(drv, ev->data.note.note, 0, chan); } chan->note[ev->data.note.note] = SNDRV_MIDI_NOTE_ON; if (ops->note_on) ops->note_on(drv, ev->data.note.note, ev->data.note.velocity, chan); break; case SNDRV_SEQ_EVENT_NOTEOFF: if (! (chan->note[ev->data.note.note] & SNDRV_MIDI_NOTE_ON)) break; if (ops->note_off) note_off(ops, drv, chan, ev->data.note.note, ev->data.note.velocity); break; case SNDRV_SEQ_EVENT_KEYPRESS: if (ops->key_press) ops->key_press(drv, ev->data.note.note, ev->data.note.velocity, chan); break; case SNDRV_SEQ_EVENT_CONTROLLER: do_control(ops, drv, chanset, chan, ev->data.control.param, ev->data.control.value); break; case SNDRV_SEQ_EVENT_PGMCHANGE: chan->midi_program = ev->data.control.value; break; case SNDRV_SEQ_EVENT_PITCHBEND: chan->midi_pitchbend = ev->data.control.value; if (ops->control) ops->control(drv, MIDI_CTL_PITCHBEND, chan); break; case SNDRV_SEQ_EVENT_CHANPRESS: chan->midi_pressure = ev->data.control.value; if (ops->control) ops->control(drv, MIDI_CTL_CHAN_PRESSURE, chan); break; case SNDRV_SEQ_EVENT_CONTROL14: /* Best guess is that this is any of the 14 bit controller values */ if (ev->data.control.param < 32) { /* set low part first */ chan->control[ev->data.control.param + 32] = ev->data.control.value & 0x7f; do_control(ops, drv, chanset, chan, ev->data.control.param, ((ev->data.control.value>>7) & 0x7f)); } else