Exemplo n.º 1
0
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;
}
Exemplo n.º 2
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;
	}
}
Exemplo n.º 3
0
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
Exemplo n.º 5
0
/*
 * 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