Exemple #1
0
void MidiAlsaDevice::close()
{
    snd_seq_port_subscribe_t* subs;
    // Allocated on stack, no need to call snd_seq_port_subscribe_free() later.
    snd_seq_port_subscribe_alloca(&subs);

    // Changed by T356. This function appears to be called only by MidiPort::setMidiDevice(),
    //  which closes then opens the device.
    // Because the open flags are set BEFORE setMidiDevice() is called, we must ignore the flags.
    //
    // NOTE: Tested: The read unsubscribe works ok but not the write.
    //               As viewed in say, qjackctl, the connection is clearly lost,
    //                but strangely the events are still accepted, ie, playback notes
    //                are still heard etc. Tried an alsa midi device AND external fluidsynth inst.
    //
    //               Also, jack running and with jack midi disabled, we get messages like
    //                MidiAlsaDevice::0x84512c0 putEvent(): midi write error: No such device
    //                 dst 16:0
    //                only sometimes (not when playing notes), but with jack midi turned on,
    //                we don't get the messages. With jack stopped we get the messages
    //                no matter if jack midi is turned on or not.

    //if (_openFlags & 1) {
    //if (!(_openFlags & 1))
    {
        snd_seq_port_subscribe_set_sender(subs, &losPort);
        snd_seq_port_subscribe_set_dest(subs, &adr);

        // Already subscribed? Then unsubscribe.
        if (!snd_seq_get_port_subscription(alsaSeq, subs))
        {
            if (!snd_seq_unsubscribe_port(alsaSeq, subs))
                _writeEnable = false;
            else
                printf("MidiAlsaDevice::close Error unsubscribing alsa midi port for writing\n");
        }
        else
            _writeEnable = false;
    }

    //if (_openFlags & 2) {
    //if (!(_openFlags & 2))
    {
        snd_seq_port_subscribe_set_dest(subs, &losPort);
        snd_seq_port_subscribe_set_sender(subs, &adr);

        // Already subscribed? Then unsubscribe.
        if (!snd_seq_get_port_subscription(alsaSeq, subs))
        {
            if (!snd_seq_unsubscribe_port(alsaSeq, subs))
                _readEnable = false;
            else
                printf("MidiAlsaDevice::close Error unsubscribing alsa midi port for reading\n");
        }
        else
            _readEnable = false;
    }
}
Exemple #2
0
QString MidiAlsaDevice::open()
{
    _openFlags &= _rwFlags; // restrict to available bits
    snd_seq_port_subscribe_t* subs;
    // Allocated on stack, no need to call snd_seq_port_subscribe_free() later.
    snd_seq_port_subscribe_alloca(&subs);

    QString estr;
    int wer = 0;
    int rer = 0;

    // subscribe for writing
    if (_openFlags & 1)
    {
        snd_seq_port_subscribe_set_sender(subs, &losPort);
        snd_seq_port_subscribe_set_dest(subs, &adr);
        // Not already subscribed (or error)? Then try subscribing.
        if (snd_seq_get_port_subscription(alsaSeq, subs) < 0)
        {
            wer = snd_seq_subscribe_port(alsaSeq, subs);
            if (wer < 0)
                estr += (QString("Play: ") + QString(snd_strerror(wer)) + QString(" "));
        }
        if (!wer)
            _writeEnable = true;
    }

    // subscribe for reading
    if (_openFlags & 2)
    {
        snd_seq_port_subscribe_set_dest(subs, &losPort);
        snd_seq_port_subscribe_set_sender(subs, &adr);
        // Not already subscribed (or error)? Then try subscribing.
        if (snd_seq_get_port_subscription(alsaSeq, subs) < 0)
        {
            //int error = snd_seq_subscribe_port(alsaSeq, subs);
            rer = snd_seq_subscribe_port(alsaSeq, subs);
            if (rer < 0)
                estr += (QString("Rec: ") + QString(snd_strerror(rer)));
        }
        if (!rer)
            _readEnable = true;
    }


    if (wer < 0 || rer < 0)
        return estr;

    return QString("OK");
}
Exemple #3
0
/* Set up ALSA MIDI subscription according to supplied parameter. */
static int
subscribe(snd_seq_port_subscribe_t *sub)
{
  if (snd_seq_get_port_subscription(seq, sub) == 0) {
    dprintf("Connection between editor and device already established\n");
    return 0;
  }

  if (snd_seq_subscribe_port(seq, sub) < 0) {
    dprintf("Couldn't estabilsh connection between editor and device\n");
    return -1;
  }

  return 0;
}
int main(int argc, char **argv)
{
	int c;
	snd_seq_t *seq;
	int queue = 0, convert_time = 0, convert_real = 0, exclusive = 0;
	int command = SUBSCRIBE;
	int list_perm = 0;
	int client;
	int list_subs = 0;
	snd_seq_port_subscribe_t *subs;
	snd_seq_addr_t sender, dest;

#ifdef ENABLE_NLS
	setlocale(LC_ALL, "");
	textdomain(PACKAGE);
#endif

	while ((c = getopt_long(argc, argv, "dior:t:elx", long_option, NULL)) != -1) {
		switch (c) {
		case 'd':
			command = UNSUBSCRIBE;
			break;
		case 'i':
			command = LIST;
			list_perm |= LIST_INPUT;
			break;
		case 'o':
			command = LIST;
			list_perm |= LIST_OUTPUT;
			break;
		case 'e':
			exclusive = 1;
			break;
		case 'r':
			queue = atoi(optarg);
			convert_time = 1;
			convert_real = 1;
			break;
		case 't':
			queue = atoi(optarg);
			convert_time = 1;
			convert_real = 0;
			break;
		case 'l':
			list_subs = 1;
			break;
		case 'x':
			command = REMOVE_ALL;
			break;
		default:
			usage();
			exit(1);
		}
	}

	if (snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, 0) < 0) {
		fprintf(stderr, _("can't open sequencer\n"));
		return 1;
	}
	
	snd_lib_error_set_handler(error_handler);

	switch (command) {
	case LIST:
		do_search_port(seq, list_perm,
			       list_subs ? print_port_and_subs : print_port);
		snd_seq_close(seq);
		return 0;
	case REMOVE_ALL:
		remove_all_connections(seq);
		snd_seq_close(seq);
		return 0;
	}

	/* connection or disconnection */

	if (optind + 2 > argc) {
		snd_seq_close(seq);
		usage();
		exit(1);
	}

	if ((client = snd_seq_client_id(seq)) < 0) {
		snd_seq_close(seq);
		fprintf(stderr, _("can't get client id\n"));
		return 1;
	}

	/* set client info */
	if (snd_seq_set_client_name(seq, "ALSA Connector") < 0) {
		snd_seq_close(seq);
		fprintf(stderr, _("can't set client info\n"));
		return 1;
	}

	/* set subscription */
	if (snd_seq_parse_address(seq, &sender, argv[optind]) < 0) {
		snd_seq_close(seq);
		fprintf(stderr, _("invalid sender address %s\n"), argv[optind]);
		return 1;
	}
	if (snd_seq_parse_address(seq, &dest, argv[optind + 1]) < 0) {
		snd_seq_close(seq);
		fprintf(stderr, _("invalid destination address %s\n"), argv[optind + 1]);
		return 1;
	}
	snd_seq_port_subscribe_alloca(&subs);
	snd_seq_port_subscribe_set_sender(subs, &sender);
	snd_seq_port_subscribe_set_dest(subs, &dest);
	snd_seq_port_subscribe_set_queue(subs, queue);
	snd_seq_port_subscribe_set_exclusive(subs, exclusive);
	snd_seq_port_subscribe_set_time_update(subs, convert_time);
	snd_seq_port_subscribe_set_time_real(subs, convert_real);

	if (command == UNSUBSCRIBE) {
		if (snd_seq_get_port_subscription(seq, subs) < 0) {
			snd_seq_close(seq);
			fprintf(stderr, _("No subscription is found\n"));
			return 1;
		}
		if (snd_seq_unsubscribe_port(seq, subs) < 0) {
			snd_seq_close(seq);
			fprintf(stderr, _("Disconnection failed (%s)\n"), snd_strerror(errno));
			return 1;
		}
	} else {
		if (snd_seq_get_port_subscription(seq, subs) == 0) {
			snd_seq_close(seq);
			fprintf(stderr, _("Connection is already subscribed\n"));
			return 1;
		}
		if (snd_seq_subscribe_port(seq, subs) < 0) {
			snd_seq_close(seq);
			fprintf(stderr, _("Connection failed (%s)\n"), snd_strerror(errno));
			return 1;
		}
	}

	snd_seq_close(seq);

	return 0;
}