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 ); } } }
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; }