Example #1
0
void MidiSndio::run( void )
{
	struct pollfd pfd;
	nfds_t nfds;
	char buf[0x100], *p;
	size_t n;
	int ret;
	while( m_quit == false && m_hdl )
	{
		nfds = mio_pollfd( m_hdl, &pfd, POLLIN );
		ret = poll( &pfd, nfds, 100 );
		if ( ret < 0 )
			break;
		if ( !ret || !( mio_revents( m_hdl, &pfd ) & POLLIN ) )
			continue;
		n = mio_read( m_hdl, buf, sizeof(buf) );
		if ( !n )
		{
			break;
		}
		for (p = buf; n > 0; n--, p++)
		{
			parseData( *p );
		}
	}
}
Example #2
0
static int
mio_psleep(struct mio_hdl *hdl, int event)
{
	struct pollfd pfd[MIO_MAXNFDS];
	int revents;
	int nfds;

	nfds = mio_nfds(hdl);
	if (nfds > MIO_MAXNFDS) {
		DPRINTF("mio_psleep: %d: too many descriptors\n", nfds);
		hdl->eof = 1;
		return 0;
	}
	for (;;) {
		nfds = mio_pollfd(hdl, pfd, event);
		while (poll(pfd, nfds, -1) < 0) {
			if (errno == EINTR)
				continue;
			DPERROR("mio_psleep: poll");
			hdl->eof = 1;
			return 0;
		}
		revents = mio_revents(hdl, pfd);
		if (revents & POLLHUP) {
			DPRINTF("mio_psleep: hang-up\n");
			return 0;
		}
		if (revents & event)
			break;
	}
	return 1;
}
void* SndioMidiDriver_thread( void* param )
{
	SndioMidiDriver *instance = ( SndioMidiDriver* )param;
	MidiMessage msg;
	struct pollfd pfd;
	nfds_t nfds;
	char buf[1], sysex_data[256], status = 0;
	int i, msglen, count = 0, sysex_len = 0;

	_INFOLOG("SndioMidiDriver_thread starting");

	while (instance->m_bRunning) {
		nfds = mio_pollfd(instance->hdl, &pfd, POLLIN);
		if (poll(&pfd, nfds, 100) < 0) {
			_ERRORLOG("poll error; aborting midi thread");
			break;
		}
		if (!(mio_revents(instance->hdl, &pfd) & POLLIN))
			continue;

		if (!mio_read(instance->hdl, buf, 1)) {
			_ERRORLOG("read error; aborting midi thread");
			break;
		}

		if (buf[0] & 0x80) {
			status = buf[0];
			count = 0;
			msglen = 2;
			msg.m_type = MidiMessage::UNKNOWN;
			msg.m_nData1 = msg.m_nData2 = 0;
			switch (status & 0xf0) {
			case 0x80:
				msg.m_type = MidiMessage::NOTE_OFF;
				break;
			case 0x90:
				msg.m_type = MidiMessage::NOTE_ON;
				break;
			case 0xa0:
				msg.m_type = MidiMessage::POLYPHONIC_KEY_PRESSURE;
				break;
			case 0xb0:
				msg.m_type = MidiMessage::CONTROL_CHANGE;
				break;
			case 0xc0:
				msg.m_type = MidiMessage::PROGRAM_CHANGE;
				break;
			case 0xd0:
				msg.m_type = MidiMessage::CHANNEL_PRESSURE;
				break;
			case 0xe0:
				msg.m_type = MidiMessage::PITCH_WHEEL;
				break;
			case 0xf0:
				switch (status) {
				case 0xf0:
					msg.m_type = MidiMessage::SYSTEM_EXCLUSIVE;
					sysex_len = 0;
					break;
				case 0xf1:
					msg.m_type = MidiMessage::QUARTER_FRAME;
					msglen = 1;
					break;
				case 0xf2:
					msg.m_type = MidiMessage::SONG_POS;
					break;
				case 0xf3:
					/* song select */
					break;
				case 0xf6:
					/* tune */
					break;
				case 0xf7:
					if (!sysex_len)
						continue;
					for (i = 0; i < sysex_len; i++)
						msg.m_sysexData.push_back(sysex_data[i]);
					instance->handleMidiMessage(msg);
					break;
				case 0xf8:
					/* clock */
					break;
				case 0xf9:
					/* tick */
					break;
				case 0xfa:
					msg.m_type = MidiMessage::START;
					msglen = 0;
					break;
				case 0xfb:
					msg.m_type = MidiMessage::CONTINUE;
					msglen = 0;
					break;
				case 0xfc:
					msg.m_type = MidiMessage::STOP;
					msglen = 0;
					break;
				case 0xfe:
					/* active sense */
					break;
				case 0xff:
					/* reset */
					break;
				}
				break;
			}
			if (msg.m_type == MidiMessage::UNKNOWN) {
				/* _INFOLOG("Unhandled midi message type: " + QString::number(status & 0xff)); */
				continue;
			}
			if (msglen > 0)
				continue;
		}

		/* some bytes left in buffer? */
		if (status == 0)
			continue;

		if (status == 0xf0) {
			if (sysex_len > 255) {
				_ERRORLOG("already 256 bytes in midi sysex buffer!");
				continue;
			}
			sysex_data[sysex_len++] = buf[0];
			continue;
		}

		if (msglen > 0) {
			switch (count) {
			case 0:
				msg.m_nData1 = buf[0];
				break;
			case 1:
				msg.m_nData2 = buf[0];
				break;
			default:
				continue;
			}
			if (++count < msglen)
				continue;
		}

		msg.m_nChannel = (status & 0x0f);

		instance->handleMidiMessage(msg);
	}

	_INFOLOG("MIDI Thread DESTROY");
	pthread_exit(NULL);
	return NULL;
}