Exemple #1
0
static
int midi_update_pfds(process_midi_t *proc)
{
    midi_port_t *port = proc->port;
    if (port->npfds == 0) {
        port->npfds = snd_rawmidi_poll_descriptors_count(port->rawmidi);
        if (port->npfds > proc->max_pfds) {
            debug_log("midi: not enough pfds for port %s", port->name);
            return 0;
        }
        snd_rawmidi_poll_descriptors(port->rawmidi, proc->wpfds, port->npfds);
    } else if (proc->rpfds != proc->wpfds) {
        memmove(proc->wpfds, proc->rpfds, sizeof(struct pollfd) * port->npfds);
    }
    return 1;
}
MidiAlsaRaw::MidiAlsaRaw() :
	MidiClientRaw(),
	m_inputp( &m_input ),
	m_outputp( &m_output ),
	m_quit( false )
{
	int err;
	if( ( err = snd_rawmidi_open( m_inputp, m_outputp,
					probeDevice().toLatin1().constData(),
								0 ) ) < 0 )
	{
		printf( "cannot open MIDI-device: %s\n", snd_strerror( err ) );
		return;
	}

	snd_rawmidi_read( m_input, NULL, 0 );

	snd_rawmidi_nonblock( m_input, 1 );
	m_npfds = snd_rawmidi_poll_descriptors_count( m_input );
	m_pfds = new pollfd[m_npfds];
	snd_rawmidi_poll_descriptors( m_input, m_pfds, m_npfds );

	start( QThread::LowPriority );
}
Exemple #3
0
int main(int argc, char **argv) {
        int inputf, e, err;
	int sock;
        struct input_event buffer;
	int npfds;
	struct pollfd *pfds;
	struct sockaddr_in si_me, si_other;
	int len, slen = sizeof(si_other);
	int optval = 1;

        if(argc < 2) {
                fprintf(stderr, "%s <device>\n", argv[0]);
                exit(-1);
        }
        e = snd_rawmidi_open(&input, &output, argv[1], SND_RAWMIDI_NONBLOCK);
	if (e == -1) {
	        fprintf(stderr, "snd:rawmidi:open-%X\n", e);
		return 1;
	}

	if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
		perror("udp socket");
		return 1;
	}

	memset((void *) &si_me, 0, sizeof(si_me));
	si_me.sin_family = AF_INET;
	si_me.sin_port = htons(UDPMIDI_PORT);
	si_me.sin_addr.s_addr = htonl(INADDR_ANY);

	memset((void *) &si_other, 0, sizeof(si_me));
	si_other.sin_family = AF_INET;
	si_other.sin_port = htons(UDPMIDI_PORT);
	si_other.sin_addr.s_addr = htonl(INADDR_BROADCAST);

	if (bind(sock, (const struct sockaddr*)&si_me, sizeof(si_me)) == -1) {
		perror("udp port");
		close(sock);
		return 1;
	}

	if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &optval, sizeof (optval)) ==- 1) {
		perror("udp broadcast");
		close(sock);
		return 1;
	}

	npfds = snd_rawmidi_poll_descriptors_count(input) + 1;
	pfds = malloc((npfds + 1) * sizeof(struct pollfd));
	snd_rawmidi_poll_descriptors(input, pfds, npfds);
	pfds[npfds-1].fd = sock;
	pfds[npfds-1].events = POLLRDNORM;

	setvbuf (stdout, NULL, _IONBF, BUFSIZ);

        while(1) {
		int i,rlen, midiin;
		err = poll(pfds, npfds, 200);

		midiin = 0;
		for (i = 0; i < npfds; ++i) {
			if (pfds[i].revents & POLLIN)
				midiin = 1;
		}
		if (midiin) {
			unsigned char buf[10];
			unsigned char outbuf[12];

			printf("m");
			rlen = snd_rawmidi_read(input, buf, sizeof(buf));
			if (rlen == -EAGAIN)
				continue;
			if (rlen < 0) {
				fprintf(stderr, "Cannot read from port \"%s\": %s", argv[1], snd_strerror(err));
				break;
			}
			// UDP broadcast
			memcpy(outbuf, packet_signature, 2);
			if (rlen > 10) continue;
			memcpy(outbuf + 2, buf, rlen);
			if (sendto(sock, outbuf, 2 + rlen, 0, (struct sockaddr *)&si_other, sizeof(si_other)) == -1) {
				fprintf(stderr, "Error sending broadcast packet.\n");
			}
			memcpy(last_packet, outbuf, rlen + 2);
		}

		if (pfds[npfds-1].revents & POLLRDNORM) {
			int len,slen;
			unsigned char buffer[10];

			slen = sizeof(si_other);
			len = recvfrom(sock, buffer, 10, 0, (struct sockaddr *)&si_other, &slen);
			// Drop our own broadcast packets
			if (memcmp(last_packet, buffer, len) == 0) continue;

			printf("u");
			if (len > 2 && memcmp(buffer, packet_signature, 2) == 0) {
        			int wlen = snd_rawmidi_write(output, buffer + 2, len - 2);
				if (wlen < len - 2) {
					fprintf(stderr, "Midi out: Wrote %d of %d bytes\n", wlen, len - 2);
				}
			}
		}
        }

        return 0;
}
Exemple #4
0
gpointer read_data_thread(gboolean *stop)
{
    /* This is mostly taken straight from alsa-utils-1.0.19 amidi/amidi.c
       by Clemens Ladisch <*****@*****.**> */
    int err;
    int npfds;
    struct pollfd *pfds;
    GString *string = NULL;

    npfds = snd_rawmidi_poll_descriptors_count(input);
    pfds = alloca(npfds * sizeof(struct pollfd));
    snd_rawmidi_poll_descriptors(input, pfds, npfds);

    do {
        unsigned char buf[256];
        int i, length;
        unsigned short revents;

        /* SysEx messages can't contain bytes with 8th bit set.
           memset our buffer to 0xFF, so if for some reason we'll
           get out of reply bounds, we'll catch it */
        memset(buf, '\0', sizeof(buf));

        err = poll(pfds, npfds, 200);
        if (err < 0 && errno == EINTR)
            break;
        if (err < 0) {
            g_error("poll failed: %s", strerror(errno));
            break;
        }
        if ((err = snd_rawmidi_poll_descriptors_revents(input, pfds, npfds, &revents)) < 0) {
            g_error("cannot get poll events: %s", snd_strerror(errno));
            break;
        }
        if (revents & (POLLERR | POLLHUP))
            break;
        if (!(revents & POLLIN))
            continue;

        err = snd_rawmidi_read(input, buf, sizeof(buf));
        if (err == -EAGAIN)
            continue;
        if (err < 0) {
            g_error("cannot read: %s", snd_strerror(err));
            break;
        }

        length = 0;
        for (i = 0; i < err; ++i)
            if ((unsigned char)buf[i] != 0xFE) /* ignore active sensing */
                buf[length++] = buf[i];

        i = 0;

        while (i < length) {
            int pos;
            int bytes;

            if (string == NULL) {
                while (buf[i] != 0xF0 && i < length)
                    i++;
            }

            pos = i;

            for (bytes = 0; (bytes<length-i) && (buf[i+bytes] != 0xF7); bytes++);

            if (buf[i+bytes] == 0xF7) bytes++;

            i += bytes;

            if (string == NULL)
                string = g_string_new_len((gchar*)&buf[pos], bytes);
            else
                g_string_append_len(string, (gchar*)&buf[pos], bytes);

            if ((unsigned char)string->str[string->len-1] == 0xF7) {
                /* push message on stack */
                push_message(string);
                string = NULL;
            }
        }
    } while (*stop == FALSE);

    if (string) {
        g_string_free(string, TRUE);
        string = NULL;
    }

    return NULL;
}