Example #1
0
void
RKR::miramidi ()
{

  if (snd_seq_event_input_pending (midi_in, 1))
    {
      do
	{
	  midievents ();

	}
      while (snd_seq_event_input_pending (midi_in, 0));
    }

};
Example #2
0
/* handles all the midi calls */
void midi_action(snd_seq_t *seq_handle) {
	snd_seq_event_t *ev;
	do {
	snd_seq_event_input(seq_handle, &ev);
		printf( "%i \n", ev->data.control.channel, ev->data.control.value);
		switch (ev->type) {
			
			case SND_SEQ_EVENT_CONTROLLER: 
				printf("Control event on Channel %2d: %5d       \n",
			        ev->data.control.channel, ev->data.control.value);
				midi_set(ev, 2);
				pedal_set(ev);
			break;
			case SND_SEQ_EVENT_PITCHBEND:
				printf("Pitchbender event on Channel %2d: %5d   \n", 
			        ev->data.control.channel, ev->data.control.value);
			break;
			case SND_SEQ_EVENT_NOTEON:
				printf("Note On event on Channel %2d: %5d       \n",
			        ev->data.control.channel, ev->data.note.note);
			break;        
			case SND_SEQ_EVENT_NOTEOFF: 
				printf("Note Off event on Channel %2d: %5d      \n",         
			        ev->data.control.channel, ev->data.note.note);           
			break;        
			case SND_SEQ_EVENT_PGMCHANGE: 
				printf("PGM event on Channel %2d: %5d      \n",         
			        ev->data.control.channel, ev->data.control.value);   
				midi_set(ev, 1);
			break; 
		}
	   	snd_seq_free_event(ev);
	  } while (snd_seq_event_input_pending(seq_handle, 0) > 0);
}
Example #3
0
    void run()
    {
        snd_seq_t *seq = m_sampl->alsa_seq();
        if (seq == NULL)
            return;

        m_running = true;

        int nfds;
        struct pollfd *pfds;

        nfds = snd_seq_poll_descriptors_count(seq, POLLIN);
        pfds = (struct pollfd *) alloca(nfds * sizeof(struct pollfd));
        snd_seq_poll_descriptors(seq, pfds, nfds, POLLIN);

        int poll_rc = 0;

        while (m_running && poll_rc >= 0) {
            poll_rc = ::poll(pfds, nfds, 200);
            while (poll_rc > 0) {
                snd_seq_event_t *ev = NULL;
                snd_seq_event_input(seq, &ev);
                m_sampl->alsa_capture(ev);
                //	snd_seq_free_event(ev);
                poll_rc = snd_seq_event_input_pending(seq, 0);
            }
        }

        m_running = false;
    }
/* TODO: ADD MIDI PANIC/ALL NOTES OFF */
int midi_callback() {

    snd_seq_event_t *ev;
    int l1;

    do {
        snd_seq_event_input(seq_handle, &ev);
        switch (ev->type) {
            case SND_SEQ_EVENT_NOTEON:
                for (l1 = 0; l1 < POLY; l1++) {
                    if (!note_active[l1]) {
                        note[l1] = ev->data.note.note;
			printf("Note ON  %d FREQ %d\n", note[l1] ,(note[l1])*FREQ_CHANNEL_WIDTH+FREQ_START);
                        velocity[l1] = ev->data.note.velocity / 127.0;
                        env_time[l1] = 0;
                        gate[l1] = 1;
                        note_active[l1] = 1;
                        break;
                    }
                }
                break;
            case SND_SEQ_EVENT_NOTEOFF:
                for (l1 = 0; l1 < POLY; l1++) {
                    if (gate[l1] && note_active[l1] && (note[l1] == ev->data.note.note)) {
			printf("Note OFF %d \n", note[l1]);
                        env_time[l1] = 0;
                        gate[l1] = 0;
                    }
                }
                break;
        }
        snd_seq_free_event(ev);
    } while (snd_seq_event_input_pending(seq_handle, 0) > 0);
    return (0);
}
    int MidiInputDeviceAlsa::Main() {
        int npfd;
        struct pollfd* pfd;
        snd_seq_event_t* ev;

        npfd = snd_seq_poll_descriptors_count(hAlsaSeq, POLLIN);
        pfd = (struct pollfd*) alloca(npfd * sizeof(struct pollfd));
        snd_seq_poll_descriptors(hAlsaSeq, pfd, npfd, POLLIN);
        while (true) {
            if (poll(pfd, npfd, 100000) > 0) {
                do {
                    snd_seq_event_input(hAlsaSeq, &ev);
                    int port = (int) ev->dest.port;
                    MidiInputPort* pMidiInputPort = Ports[port];

                    switch (ev->type) {
                        case SND_SEQ_EVENT_CONTROLLER:
                            if (ev->data.control.param == 0)
                                pMidiInputPort->DispatchBankSelectMsb(ev->data.control.value, ev->data.control.channel);
                            else if (ev->data.control.param == 32)
                                pMidiInputPort->DispatchBankSelectLsb(ev->data.control.value, ev->data.control.channel);
                            pMidiInputPort->DispatchControlChange(ev->data.control.param, ev->data.control.value, ev->data.control.channel);
                            break;

                        case SND_SEQ_EVENT_CHANPRESS:
                            pMidiInputPort->DispatchControlChange(128, ev->data.control.value, ev->data.control.channel);
                            break;

                        case SND_SEQ_EVENT_PITCHBEND:
                            pMidiInputPort->DispatchPitchbend(ev->data.control.value, ev->data.control.channel);
                            break;

                        case SND_SEQ_EVENT_NOTEON:
                            if (ev->data.note.velocity != 0) {
                                pMidiInputPort->DispatchNoteOn(ev->data.note.note, ev->data.note.velocity, ev->data.control.channel);
                            }
                            else {
                                pMidiInputPort->DispatchNoteOff(ev->data.note.note, 0, ev->data.control.channel);
                            }
                            break;

                        case SND_SEQ_EVENT_NOTEOFF:
                            pMidiInputPort->DispatchNoteOff(ev->data.note.note, ev->data.note.velocity, ev->data.control.channel);
                            break;

                        case SND_SEQ_EVENT_SYSEX:
                            pMidiInputPort->DispatchSysex(ev->data.ext.ptr, ev->data.ext.len);
                            break;

                        case SND_SEQ_EVENT_PGMCHANGE:
                            pMidiInputPort->DispatchProgramChange(ev->data.control.value, ev->data.control.channel);
                            break;
                    }
                    snd_seq_free_event(ev);
                } while (snd_seq_event_input_pending(hAlsaSeq, 0) > 0);
            }
        }
        // just to avoid a compiler warning
        return EXIT_FAILURE;
    }
Example #6
0
void SeqDriver::procEvents()
{
    int l1;
    snd_seq_event_t *evIn, evOut;
    bool outOfRange = false;
    bool unmatched = false;
    MidiMap* mm;

    do {
        snd_seq_event_input(seq_handle, &evIn);
        emit midiEvent(evIn);
        unmatched = true;
        for(l1 = 0; l1 < midiMapList->count(); l1++) {
            mm = midiMapList->at(l1);
            if (mm->isMap(evIn)) {
                unmatched = false;
                mm->doMap(evIn, &evOut, &outOfRange);
                if (!outOfRange) {
                    snd_seq_ev_set_subs(&evOut);  
                    snd_seq_ev_set_direct(&evOut);
                    snd_seq_ev_set_source(&evOut, portid_out[mm->portOut]);
                    snd_seq_event_output_direct(seq_handle, &evOut);
                }  
            }
        }
        if (!discardUnmatched && unmatched) {
            snd_seq_ev_set_subs(evIn);  
            snd_seq_ev_set_direct(evIn);
            snd_seq_ev_set_source(evIn, portid_out[portUnmatched]);
            snd_seq_event_output_direct(seq_handle, evIn);
        }
    } while (snd_seq_event_input_pending(seq_handle, 0) > 0);  
}
int AlsaSeqMidiInDriver::read(unsigned char* buf, int max)
{
  if (!this->is_open())
    throw std::logic_error("Device not open");

  int bytes_read= 0;
  int err;
  snd_seq_event_t *ev;

  do
    {
      if (snd_seq_event_input(m_impl->seq, &ev) > 0 )
	{
	  err = snd_midi_event_decode (m_impl->decoder, buf, max, ev);
	  //snd_seq_free_event( ev );
	  
	  if (err > 0)
	    {
	      buf += err;
	      bytes_read += err;
	      max -= err;
	    }
	  else
	    {
	      // error or buffer full -> drop midi event
	    }
	}
    }
  while (snd_seq_event_input_pending(m_impl->seq, 0) > 0);

  return bytes_read;
}
bool
mastermidibus::is_more_input ()
{
#ifdef SEQ64_HAVE_LIBASOUND
    automutex locker(m_mutex);
    return snd_seq_event_input_pending(m_alsa_seq, 0) > 0;
#else
    return false;
#endif
}
Example #9
0
static PyObject *
alsaseq_inputpending(PyObject *self, PyObject *args)
{
  int res;
        
	if (!PyArg_ParseTuple(args, "" ))
		return NULL;
        res = snd_seq_event_input_pending( seq_handle, 1 ); /* fetch_sequencer */

        return PyInt_FromLong( res );
}
Example #10
0
bool
mastermidibus::is_more_input ()
{
#ifdef HAVE_LIBASOUND
    automutex locker(m_mutex);
    int size = snd_seq_event_input_pending(m_alsa_seq, 0);
#else
    int size = 0;
#endif
    return size > 0;
}
Example #11
0
bool 
mastermidibus::is_more_input( ){
    
    lock();

    int size = snd_seq_event_input_pending(m_alsa_seq, 0);

    unlock();

    return ( size > 0 );
}
Example #12
0
static PyObject *get_event_nb(PyObject *self, PyObject *args)
{
    if (!PyArg_ParseTuple(args, "")) /* no args */
        return NULL;

    int n_events = snd_seq_event_input_pending(seq, 1);
    if (n_events > 0)
        return get_event(self, args);

    Py_INCREF(Py_None);
    return Py_None;
}
    void run()
    {
        const int maxEventSize = 16 * 1024;
        snd_midi_event_t* midiParser;

        if (snd_midi_event_new (maxEventSize, &midiParser) >= 0)
        {
            HeapBlock <uint8> buffer (maxEventSize);

            const int numPfds = snd_seq_poll_descriptors_count (seqHandle, POLLIN);
            struct pollfd* const pfd = (struct pollfd*) alloca (numPfds * sizeof (struct pollfd));

            snd_seq_poll_descriptors (seqHandle, pfd, numPfds, POLLIN);

            while (! threadShouldExit())
            {
                if (poll (pfd, numPfds, 500) > 0)
                {
                    snd_seq_event_t* inputEvent = nullptr;

                    snd_seq_nonblock (seqHandle, 1);

                    do
                    {
                        if (snd_seq_event_input (seqHandle, &inputEvent) >= 0)
                        {
                            // xxx what about SYSEXes that are too big for the buffer?
                            const int numBytes = snd_midi_event_decode (midiParser, buffer, maxEventSize, inputEvent);

                            snd_midi_event_reset_decode (midiParser);

                            if (numBytes > 0)
                            {
                                const MidiMessage message ((const uint8*) buffer,
                                                           numBytes,
                                                           Time::getMillisecondCounter() * 0.001);


                                callback->handleIncomingMidiMessage (midiInput, message);
                            }

                            snd_seq_free_event (inputEvent);
                        }
                    }
                    while (snd_seq_event_input_pending (seqHandle, 0) > 0);

                    snd_seq_free_event (inputEvent);
                }
            }

            snd_midi_event_free (midiParser);
        }
    };
Example #14
0
static PyObject *
alsaseq_inputpending(PyObject *self, PyObject *args)
{
  int res;
        
	if (!PyArg_ParseTuple(args, "" ))
		return NULL;

        if (!seq_handle) {
                PyErr_SetString(PyExc_RuntimeError, "Must initialize module with alsaseq.client() before using it");
                return NULL;
        }

        res = snd_seq_event_input_pending( seq_handle, 1 ); /* fetch_sequencer */

        return PyInt_FromLong( res );
}
Example #15
0
static ssize_t snd_rawmidi_virtual_read(snd_rawmidi_t *rmidi, void *buffer, size_t size)
{
	snd_rawmidi_virtual_t *virt = rmidi->private_data;
	ssize_t result = 0;
	int size1, err;

	while (size > 0) {
		if (! virt->in_buf_ofs) {
			err = snd_seq_event_input_pending(virt->handle, 1);
			if (err <= 0 && result > 0)
				return result;
			err = snd_seq_event_input(virt->handle, &virt->in_event);
			if (err < 0)
				return result > 0 ? result : err;

			if (virt->in_event->type == SND_SEQ_EVENT_SYSEX) {
				virt->in_buf_ptr = virt->in_event->data.ext.ptr;
				virt->in_buf_size = virt->in_event->data.ext.len;
			} else {
				virt->in_buf_ptr = virt->in_tmp_buf;
				virt->in_buf_size = snd_midi_event_decode(virt->midi_event,
									  (unsigned char *)virt->in_tmp_buf,
									  sizeof(virt->in_tmp_buf),
									  virt->in_event);
			}
			if (virt->in_buf_size <= 0)
				continue;
		}
		size1 = virt->in_buf_size - virt->in_buf_ofs;
		if ((size_t)size1 > size) {
			memcpy(buffer, virt->in_buf_ptr + virt->in_buf_ofs, size);
			virt->in_buf_ofs += size;
			result += size;
			break;
		}
		memcpy(buffer, virt->in_buf_ptr + virt->in_buf_ofs, size1);
		size -= size1;
		result += size1;
		buffer += size1;
		virt->in_buf_ofs = 0;
	}

	return result;
}
/* TODO: ADD MIDI PANIC/ALL NOTES OFF */
int midi_callback() {

    snd_seq_event_t *ev;
    int l1;

    do {
        snd_seq_event_input(seq_handle, &ev);
        switch (ev->type) {
            case SND_SEQ_EVENT_NOTEON:
                for (l1 = 0; l1 < POLY; l1++) {
                    if (!note_active[l1]) {
                        note[l1] = ev->data.note.note;
			midichannel[l1] = ev->data.note.channel;
			velocity[l1] = ev->data.note.velocity / 127;
			attron(COLOR_PAIR(1));			
			printw("CH %2.0f ", midichannel[l1]+1);
			printw("Note %3d ", note[l1]);
			printw("Velocity %3.0f ", velocity[l1] * 127);
			printw("Frequency %3.1f \n", ((note[l1]*FREQ_CHANNEL_WIDTH)+((128*FREQ_CHANNEL_WIDTH*midichannel[l1])+FREQ_START)) );
			refresh();
			attroff(COLOR_PAIR(1));
                        env_time[l1] = 0;
                        gate[l1] = 1;
                        note_active[l1] = 1;
                        break;
                    }
                }
                break;
            case SND_SEQ_EVENT_NOTEOFF:
                for (l1 = 0; l1 < POLY; l1++) {
                    if (gate[l1] && note_active[l1] && (note[l1] == ev->data.note.note)) {
			printw("Note OFF %3d \n", note[l1]);
                        env_time[l1] = 0;
                        gate[l1] = 0;
                    }
                }
                break;
        }
        snd_seq_free_event(ev);
    } while (snd_seq_event_input_pending(seq_handle, 0) > 0);
    return (0);
}
Example #17
0
	// The main thread executive.
	void run()
	{
		snd_seq_t *pAlsaSeq = m_pMidiDevice->alsaSeq();
		if (pAlsaSeq == NULL)
			return;

		int nfds;
		struct pollfd *pfds;

		nfds = snd_seq_poll_descriptors_count(pAlsaSeq, POLLIN);
		pfds = (struct pollfd *) alloca(nfds * sizeof(struct pollfd));
		snd_seq_poll_descriptors(pAlsaSeq, pfds, nfds, POLLIN);

		qxgeditMidiInputRpn xrpn;

		m_bRunState = true;

		int iPoll = 0;
		while (m_bRunState && iPoll >= 0) {
			// Wait for events...
			iPoll = poll(pfds, nfds, 200);
			// Timeout?
			if (iPoll == 0)
				xrpn.flush();
			while (iPoll > 0) {
				snd_seq_event_t *pEv = NULL;
				snd_seq_event_input(pAlsaSeq, &pEv);
				// Process input event - ...
				// - enqueue to input track mapping;
				if (!xrpn.process(pEv))
					m_pMidiDevice->capture(pEv);
			//	snd_seq_free_event(pEv);
				iPoll = snd_seq_event_input_pending(pAlsaSeq, 0);
			}
			// Process pending events...
			while (xrpn.isPending()) {
				snd_seq_event_t ev;
				if (xrpn.dequeue(&ev))
					m_pMidiDevice->capture(&ev);
			}
		}
	}
Example #18
0
int midi_action(snd_seq_t *seq_handle) {

	snd_seq_event_t *ev;
	int cnt = 0;

	do {
		snd_seq_event_input(seq_handle, &ev);
		switch (ev->type) {
			case SND_SEQ_EVENT_NOTEON:
				if (channels && !(channels & (1<<ev->data.note.channel)))
					break;
				if (ev->data.note.velocity != 0) {
					note_on(ev->data.note.note, ev->data.note.velocity);
					cnt++;
				}
			}
		snd_seq_free_event(ev);
	} while (snd_seq_event_input_pending(seq_handle, 0) > 0);
	return cnt;
}
Example #19
0
int midi_callback() {

    snd_seq_event_t *ev;
    int l1;
  
    do {
        snd_seq_event_input(seq_handle, &ev);
        switch (ev->type) {
            case SND_SEQ_EVENT_PITCHBEND:
                pitch = (double)ev->data.control.value / 8192.0;
                break;
            case SND_SEQ_EVENT_CONTROLLER:
                if (ev->data.control.param == 1) {
                    modulation = (double)ev->data.control.value / 10.0;
                } 
                break;
            case SND_SEQ_EVENT_NOTEON:
                for (l1 = 0; l1 < POLY; l1++) {
                    if (!note_active[l1]) {
                        note[l1] = ev->data.note.note;
                        velocity[l1] = ev->data.note.velocity / 127.0;
                        env_time[l1] = 0;
                        gate[l1] = 1;
                        note_active[l1] = 1;
                        break;
                    }
                }
                break;        
            case SND_SEQ_EVENT_NOTEOFF:
                for (l1 = 0; l1 < POLY; l1++) {
                    if (gate[l1] && note_active[l1] && (note[l1] == ev->data.note.note)) {
                        env_time[l1] = 0;
                        gate[l1] = 0;
                    }
                }
                break;        
        }
        snd_seq_free_event(ev);
    } while (snd_seq_event_input_pending(seq_handle, 0) > 0);
    return (0);
}
Example #20
0
int midi_read() {

    snd_seq_event_t *ev;
    int channel,value,note,velocity,param;

    do {
        snd_seq_event_input(seq_handle, &ev);
        switch (ev->type) {
            case SND_SEQ_EVENT_NOTEON:
		channel = ev->data.note.channel;
		note = ev->data.note.note & 0x7f;
		velocity = ev->data.note.velocity;
		note_on_action(channel,note,velocity);
		break;
            case SND_SEQ_EVENT_NOTEOFF:
		channel = ev->data.note.channel;
		note = ev->data.note.note;
		velocity = ev->data.note.velocity;
		note_off_action(channel,note,velocity);
		break;
            case SND_SEQ_EVENT_PGMCHANGE:
		channel = ev->data.control.channel;
		value = ev->data.control.value;
		program_change_action(channel,value);	
		break;
            case SND_SEQ_EVENT_CONTROLLER:
		channel = ev->data.control.channel;
		param = ev->data.control.param;
		value = ev->data.control.value;
		control_change_action(channel,param,value);	
		break;	    
	 
        }
        snd_seq_free_event(ev);
    } while (snd_seq_event_input_pending(seq_handle, 0) > 0);
    return (0);
}
Example #21
0
void midi_action(snd_seq_t *seq_handle) {

  snd_seq_event_t *ev;

  do {
    snd_seq_event_input(seq_handle, &ev);
    switch (ev->type) {
      case SND_SEQ_EVENT_CONTROLLER:
        printf(MIDI_FORMAT, MIDI_CONTROL, ev->data.control.channel, ev->data.control.value);
        break;
      case SND_SEQ_EVENT_PITCHBEND:
        printf(MIDI_FORMAT, MIDI_PITCH_BEND, ev->data.control.channel, ev->data.control.value);
        break;
      case SND_SEQ_EVENT_NOTEON:
        printf(MIDI_FORMAT, MIDI_NOTE_ON, ev->data.control.channel, ev->data.note.note);
        break;
      case SND_SEQ_EVENT_NOTEOFF:
        printf(MIDI_FORMAT, MIDI_NOTE_OFF, ev->data.control.channel, ev->data.note.note);
        break;
    }
		fflush(stdout); fflush(stderr);
    snd_seq_free_event(ev);
  } while (snd_seq_event_input_pending(seq_handle, 0) > 0);
}
Example #22
0
    /* this version uses the asynchronous "read()" ... */
void sys_alsa_poll_midi(void)
{
   unsigned char buf[ALSA_MAX_EVENT_SIZE];
   int count, alsa_source;
   int i;
   snd_seq_event_t *midievent = NULL;

   if (alsa_nmidiout == 0 && alsa_nmidiin == 0) return;
   
   snd_midi_event_init(midiev);

   if (!alsa_nmidiout && !alsa_nmidiin) return;
   count = snd_seq_event_input_pending(midi_handle,1);
   if (count != 0)
        count = snd_seq_event_input(midi_handle,&midievent);
   if (midievent != NULL)
   {
       count = snd_midi_event_decode(midiev,buf,sizeof(buf),midievent);
       alsa_source = midievent->dest.port;
       for(i=0;i<count;i++)
           sys_midibytein(alsa_source, (buf[i] & 0xff));
       //post("received %d midi bytes\n",count);
   }
}
Example #23
0
static gboolean
data_pending (void)
{
    return snd_seq_event_input_pending (seq, TRUE) != 0;
}
Example #24
0
static	int		vj_dequeue_midi_event( vmidi_t *v )
{
	int ret = 0;
	int err = 0;
	while( snd_seq_event_input_pending( v->sequencer, 1 ) > 0 ) {
		int data[4] = { 0,0,0,0};
		int isvalid = 1;
		snd_seq_event_t *ev = NULL;

		err = snd_seq_event_input( v->sequencer, &ev );
		if( err == -ENOSPC || err == -EAGAIN )
			return ret;

		data[0] = ev->type;
		switch( ev->type )
		{
			/* controller: channel <0-N>, <modwheel 0-127> */
			case SND_SEQ_EVENT_CONTROLLER:
				data[1] = ev->data.control.channel*256+ev->data.control.param; // OB: added chan+param as identifier
				data[2] = ev->data.control.value;
				break;
			case SND_SEQ_EVENT_PITCHBEND:
				data[1] = ev->data.control.channel;
				data[2] = ev->data.control.value;
				break;
			case SND_SEQ_EVENT_NOTE:
				data[1] = ev->data.control.channel;
				data[2] = ev->data.note.note;
				break;
			case SND_SEQ_EVENT_NOTEON:
				data[2] = ev->data.control.channel;
				data[1] = ev->data.note.note;
				break;
			case SND_SEQ_EVENT_NOTEOFF:
				data[2] = ev->data.control.channel;
				data[1] = ev->data.note.note;
				break;
			case SND_SEQ_EVENT_KEYPRESS:
				data[1] = ev->data.control.channel;
				data[2] = ev->data.note.velocity;
				break;
			case SND_SEQ_EVENT_PGMCHANGE:
				data[1] = ev->data.control.param;
				data[2] = ev->data.control.value;
				break;
			default:
				data[1] = -1;
				data[2] = -1;
				isvalid = 0;
				veejay_msg(VEEJAY_MSG_WARNING, "unknown midi event received: %d %x %x",ev->type,data[1],data[2],data[2]);
				break;
		}

		if( isvalid == 1 ) {
			vj_midi_send_vims_now( v, data );
		}

		if( ev ) {
			snd_seq_free_event( ev );
			ret ++;
		}
	}

	return ret; 
}
Example #25
0
int main( int argc, char *argv[] )
{
	jack_client_t *jackClient;

	snd_seq_t *seqport;
	struct pollfd *pfd;
	int npfd;
	snd_seq_event_t *midievent;
	int channel, midiport;
	
	int note, length, i;
	double freq;

	puts( "SO-666 v.1.01 by 50m30n3 2009-2010" );

	if( argc > 1 )
		channel = atoi( argv[1] );
	else
		channel = 0;

	signal( SIGINT, sig_exit );
	signal( SIGTERM, sig_exit );


	puts( "Connecting to Jack Audio Server" );
	
	jackClient = jack_client_open( "SO-666", JackNoStartServer, NULL );
	if( jackClient == NULL )
	{
		fputs( "Cannot connect to Jack Server\n", stderr );
		return 1;
	}

	jack_on_shutdown( jackClient, jack_shutdown, 0 );

	outport = jack_port_register( jackClient, "output", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput | JackPortIsTerminal, 0 );

	jack_set_process_callback( jackClient, process, 0 );

	samplerate = jack_get_sample_rate( jackClient );


	puts( "Initializing synth parameters" );

	feedback = 32;
	cutoff = 64;
	resonance = 64;
	volume = 100;

	fcutoff = pow( (cutoff+50.0)/200.0, 5.0 );
	freso = resonance/127.0;
	ffeedback = 0.01+pow( feedback/127.0, 4.0)*0.9;

	for( note=0; note<NUMNOTES; note++ )
	{
		freq = 440.0*pow( 2.0, (note+BASENOTE-69) / 12.0 );
		//stringcutoff[note] = ( freq * 16.0 ) / (double)samplerate;
		stringcutoff[note] = 0.9;
		length = (double)samplerate / freq;
		stringlength[note] = length;
		strings[note] = malloc( length * sizeof( double ) );
		if( strings[note] == NULL )
		{
			fputs( "Error allocating memory\n", stderr );
			return 1;
		}
		
		for( i=0; i<length; i++ )
		{
			strings[note][i] = 0.0;
		}
		stringpos[note] = 0;
		status[note] = 0;
	}

	lpval = lplast = 0.0;
	hpval = hplast = 0.0;

	jack_activate( jackClient );


	printf( "Listening on MIDI channel %i\n", channel );

	if( snd_seq_open( &seqport, "default", SND_SEQ_OPEN_INPUT, 0 ) < 0 )
	{
		fputs( "Cannot connect to ALSA sequencer\n", stderr );
		return 1;
	}

	snd_seq_set_client_name( seqport, "SO-666" );

	midiport = snd_seq_create_simple_port( seqport, "input",
		SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE,
		SND_SEQ_PORT_TYPE_APPLICATION );

	if( midiport < 0 )
	{
		fputs( "Cannot create ALSA sequencer port\n", stderr );
		return 1;
	}

	npfd = snd_seq_poll_descriptors_count( seqport, POLLIN );
	pfd = (struct pollfd *)malloc( npfd * sizeof( struct pollfd ) );
	snd_seq_poll_descriptors( seqport, pfd, npfd, POLLIN );


	done = 0;

	while( ! done )
	{
		if( poll( pfd, npfd, 100000 ) > 0 )
		{
			do
			{
				snd_seq_event_input( seqport, &midievent );
				
				if( ( midievent->type == SND_SEQ_EVENT_NOTEON ) && ( midievent->data.note.channel == channel ) )
				{
					note = midievent->data.note.note;
					if( ( note >= BASENOTE ) && ( note < BASENOTE+NUMNOTES ) )
					{
						note -= BASENOTE;

						status[note] = 1;
					}
				}
				else if( ( midievent->type == SND_SEQ_EVENT_NOTEOFF ) && ( midievent->data.note.channel == channel ) )
				{
					note = midievent->data.note.note;
					if( ( note >= BASENOTE ) && ( note < BASENOTE+NUMNOTES ) )
					{
						note -= BASENOTE;
						status[note] = 0;
					}
				}
				else if( ( midievent->type == SND_SEQ_EVENT_CONTROLLER ) && ( midievent->data.control.channel == channel ) )
				{
					if( midievent->data.control.param == 74 )
					{
						cutoff = midievent->data.control.value;
						fcutoff = pow( (cutoff+50.0)/200.0, 5.0 );
						printf( "Cutoff: %i     \r", cutoff );
						fflush( stdout );
					}
					else if( midievent->data.control.param == 71 )
					{
						resonance = midievent->data.control.value;
						freso = resonance/127.0;
						printf( "Resonance: %i     \r", resonance );
						fflush( stdout );
					}
					else if( midievent->data.control.param == 7 )
					{
						volume = midievent->data.control.value;
						printf( "Volume: %i     \r", volume );
						fflush( stdout );
					}
					else if( midievent->data.control.param == 1 )
					{
						feedback = midievent->data.control.value;
						ffeedback = 0.01+pow( feedback/127.0, 4.0)*0.9;
						printf( "Feedback: %i    \r", feedback );
						fflush( stdout );
					}
				}
				
				snd_seq_free_event( midievent );
			}
			while( snd_seq_event_input_pending( seqport, 0 ) > 0 );
		}
	}

	free( pfd );
	snd_seq_delete_port( seqport, midiport );
	snd_seq_close( seqport );
	
	jack_deactivate( jackClient );

	puts( "Freeing data" );
	for( note=0; note<NUMNOTES; note++ )
	{
		free( strings[note] );
	}

	jack_port_unregister( jackClient, outport );
	jack_client_close( jackClient );

	return 0;
}
Example #26
0
static DWORD WINAPI midRecThread(LPVOID arg)
{
    int npfd;
    struct pollfd *pfd;

    TRACE("Thread startup\n");

    while(!end_thread) {
	TRACE("Thread loop\n");
	npfd = snd_seq_poll_descriptors_count(midiSeq, POLLIN);
	pfd = HeapAlloc(GetProcessHeap(), 0, npfd * sizeof(struct pollfd));
	snd_seq_poll_descriptors(midiSeq, pfd, npfd, POLLIN);

	/* Check if an event is present */
	if (poll(pfd, npfd, 250) < 0) {
	    HeapFree(GetProcessHeap(), 0, pfd);
	    continue;
	}

	/* Note: This definitely does not work.  
	 * while(snd_seq_event_input_pending(midiSeq, 0) > 0) {
	       snd_seq_event_t* ev;
	       snd_seq_event_input(midiSeq, &ev);
	       ....................
	       snd_seq_free_event(ev);
	   }*/

	do {
	    WORD wDevID;
	    snd_seq_event_t* ev;
	    snd_seq_event_input(midiSeq, &ev);
	    /* Find the target device */
	    for (wDevID = 0; wDevID < MIDM_NumDevs; wDevID++)
		if ( (ev->source.client == MidiInDev[wDevID].addr.client) && (ev->source.port == MidiInDev[wDevID].addr.port) )
		    break;
	    if ((wDevID == MIDM_NumDevs) || (MidiInDev[wDevID].state != 1))
		FIXME("Unexpected event received, type = %x from %d:%d\n", ev->type, ev->source.client, ev->source.port);
	    else {
		DWORD dwTime, toSend = 0;
		/* FIXME: Should use ev->time instead for better accuracy */
		dwTime = GetTickCount() - MidiInDev[wDevID].startTime;
		TRACE("Event received, type = %x, device = %d\n", ev->type, wDevID);
		switch(ev->type)
		{
		case SND_SEQ_EVENT_NOTEOFF:
		    toSend = (ev->data.note.velocity << 16) | (ev->data.note.note << 8) | MIDI_CMD_NOTE_OFF | ev->data.control.channel;
		    break;
		case SND_SEQ_EVENT_NOTEON:
		    toSend = (ev->data.note.velocity << 16) | (ev->data.note.note << 8) | MIDI_CMD_NOTE_ON | ev->data.control.channel;
		    break;
		case SND_SEQ_EVENT_KEYPRESS:
		    toSend = (ev->data.note.velocity << 16) | (ev->data.note.note << 8) | MIDI_CMD_NOTE_PRESSURE | ev->data.control.channel;
		    break;
		case SND_SEQ_EVENT_CONTROLLER: 
		    toSend = (ev->data.control.value << 16) | (ev->data.control.param << 8) | MIDI_CMD_CONTROL | ev->data.control.channel;
		    break;
		case SND_SEQ_EVENT_PITCHBEND:
		    toSend = (ev->data.control.value << 16) | (ev->data.control.param << 8) | MIDI_CMD_BENDER | ev->data.control.channel;
		    break;
		case SND_SEQ_EVENT_PGMCHANGE:
		    toSend = (ev->data.control.value << 16) | (ev->data.control.param << 8) | MIDI_CMD_PGM_CHANGE | ev->data.control.channel;
		    break;
		case SND_SEQ_EVENT_CHANPRESS:
		    toSend = (ev->data.control.value << 16) | (ev->data.control.param << 8) | MIDI_CMD_CHANNEL_PRESSURE | ev->data.control.channel;
		    break;
		case SND_SEQ_EVENT_SYSEX:
		    {
			int len = ev->data.ext.len;
			LPBYTE ptr = (BYTE*) ev->data.ext.ptr;
			LPMIDIHDR lpMidiHdr;

			/* FIXME: Should handle sysex greater that a single buffer */
			EnterCriticalSection(&crit_sect);
			if ((lpMidiHdr = MidiInDev[wDevID].lpQueueHdr) != NULL) {
			    if (len <= lpMidiHdr->dwBufferLength) {
				lpMidiHdr->dwBytesRecorded = len;
				memcpy(lpMidiHdr->lpData, ptr, len);
				lpMidiHdr->dwFlags &= ~MHDR_INQUEUE;
				lpMidiHdr->dwFlags |= MHDR_DONE;
				MidiInDev[wDevID].lpQueueHdr = (LPMIDIHDR)lpMidiHdr->lpNext;
				if (MIDI_NotifyClient(wDevID, MIM_LONGDATA, (DWORD)lpMidiHdr, dwTime) != MMSYSERR_NOERROR)
				    WARN("Couldn't notify client\n");
			    } else
				FIXME("No enough space in the buffer to store sysex!\n");
			} else
			    FIXME("Sysex received but no buffer to store it!\n");
			LeaveCriticalSection(&crit_sect);
		    }
		    break;
		case SND_SEQ_EVENT_SENSING:
		    /* Noting to do */
		    break;
		default:
		    FIXME("Unhandled event received, type = %x\n", ev->type);
		    break;
		}
		if (toSend != 0) {
		    TRACE("Sending event %08lx (from %d %d)\n", toSend, ev->source.client, ev->source.port);
		    if (MIDI_NotifyClient(wDevID, MIM_DATA, toSend, dwTime) != MMSYSERR_NOERROR) {
			WARN("Couldn't notify client\n");
		    }
		}
	    }
	    snd_seq_free_event(ev);
	} while(snd_seq_event_input_pending(midiSeq, 0) > 0);
	
	HeapFree(GetProcessHeap(), 0, pfd);
    }
    return 0;
}
Example #27
0
int main( int argc, char *argv[] )
{
	jack_client_t *jackClient;

	snd_seq_t *seqport;
	struct pollfd *pfd;
	int npfd;
	snd_seq_event_t *midievent;
	int channel, midiport;
	
	int note, length, i, j, minpos;
	double freq, avg, vol, scale, min;
	double *tempstring;

	puts( "SO-KL5 v.1.2 by 50m30n3 2009-2011" );

	if( argc > 1 )
		channel = atoi( argv[1] );
	else
		channel = 0;

	signal( SIGINT, sig_exit );
	signal( SIGTERM, sig_exit );


	puts( "Connecting to Jack Audio Server" );
	
	jackClient = jack_client_open( "SO-KL5", JackNoStartServer, NULL );
	if( jackClient == NULL )
	{
		fputs( "Cannot connect to Jack Server\n", stderr );
		return 1;
	}

	jack_on_shutdown( jackClient, jack_shutdown, 0 );

	outport = jack_port_register( jackClient, "output", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput | JackPortIsTerminal, 0 );

	jack_set_process_callback( jackClient, process, 0 );

	samplerate = jack_get_sample_rate( jackClient );


	puts( "Initializing synth parameters" );

	sustain = 0;
	cutoff = 64;
	resonance = 100;
	attack = 64;
	volume = 100;

	fcutoff = (cutoff+5.0)/400.0;
	sattack = (attack+5.0)/800.0;
	freso = (resonance/160.0)*(1.0-fcutoff);
	ssustain = 0.6+pow( sustain/127.0, 0.4)*0.4;

	for( note=0; note<NUMNOTES; note++ )
	{
		freq = 440.0*pow( 2.0, (note+BASENOTE-69) / 12.0 );
		stringcutoff[note] = 0.5 + pow( (double)note / (double)NUMNOTES, 0.5 ) * 0.45;
		length = round( (double)samplerate / freq );
		stringlength[note] = length;
		strings[note] = malloc( length * sizeof( double ) );
		if( strings[note] == NULL )
		{
			fputs( "Error allocating memory\n", stderr );
			return 1;
		}
		
		for( i=0; i<length; i++ )
		{
			strings[note][i] = 0.0;
		}
		stringpos[note] = 0;
		status[note] = 0;
	}

	freq = 440.0*pow( 2.0, (BASENOTE-69) / 12.0 );
	length = (double)samplerate / freq;
	tempstring = malloc( length * sizeof( double ) );
	if( tempstring == NULL )
	{
		fputs( "Error allocating memory\n", stderr );
		return 1;
	}

	lpval = lplast = 0.0;

	jack_activate( jackClient );


	printf( "Listening on MIDI channel %i\n", channel );

	if( snd_seq_open( &seqport, "default", SND_SEQ_OPEN_INPUT, 0 ) < 0 )
	{
		fputs( "Cannot connect to ALSA sequencer\n", stderr );
		return 1;
	}

	snd_seq_set_client_name( seqport, "SO-KL5" );

	midiport = snd_seq_create_simple_port( seqport, "input",
		SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE,
		SND_SEQ_PORT_TYPE_APPLICATION );

	if( midiport < 0 )
	{
		fputs( "Cannot create ALSA sequencer port\n", stderr );
		return 1;
	}

	npfd = snd_seq_poll_descriptors_count( seqport, POLLIN );
	pfd = (struct pollfd *)malloc( npfd * sizeof( struct pollfd ) );
	snd_seq_poll_descriptors( seqport, pfd, npfd, POLLIN );


	done = 0;

	while( ! done )
	{
		if( poll( pfd, npfd, 100000 ) > 0 )
		{
			do
			{
				snd_seq_event_input( seqport, &midievent );
				
				if( ( midievent->type == SND_SEQ_EVENT_NOTEON ) && ( midievent->data.note.channel == channel ) )
				{
					note = midievent->data.note.note;
					if( ( note >= BASENOTE ) && ( note < BASENOTE+NUMNOTES ) )
					{
						note -= BASENOTE;

						status[note] = 1;

						for( i=0; i<stringlength[note]; i++ )
						{
							tempstring[i] = ((double)rand()/(double)RAND_MAX)*2.0-1.0;
						}

						freq = stringcutoff[note] * 0.25 + midievent->data.note.velocity/127.0 * 0.2 + sattack + 0.1;

						for( j=0; j<30; j++ )
						{
							tempstring[0] = tempstring[0]*freq + tempstring[stringlength[note]-1]*(1.0-freq);
							for( i=1; i<stringlength[note]; i++ )
							{
								tempstring[i] = tempstring[i]*freq + tempstring[(i-1)%stringlength[note]]*(1.0-freq);
							}
						}

						avg = 0.0;

						for( i=0; i<stringlength[note]; i++ )
						{
							avg += tempstring[i];
						}

						avg /= stringlength[note];

						scale = 0.0;

						for( i=0; i<stringlength[note]; i++ )
						{
							tempstring[i] -= avg;
							if( fabs( tempstring[i] ) > scale )
								scale = fabs( tempstring[i] );
						}

						min = 10.0;
						minpos = 0;

						for( i=0; i<stringlength[note]; i++ )
						{
							tempstring[i] /= scale;
							if( fabs( tempstring[i] ) + fabs( tempstring[i] - tempstring[i-1] ) * 5.0 < min )
							{
								min = fabs( tempstring[i] ) + fabs( tempstring[i] - tempstring[i-1] ) * 5.0;
								minpos = i;
							}
						}

						vol = midievent->data.note.velocity/256.0;

						for( i=0; i<stringlength[note]; i++ )
						{
							strings[note][(stringpos[note]+i)%stringlength[note]] += tempstring[(i+minpos)%stringlength[note]]*vol;
						}
					}
				}
				else if( ( midievent->type == SND_SEQ_EVENT_NOTEOFF ) && ( midievent->data.note.channel == channel ) )
				{
					note = midievent->data.note.note;
					if( ( note >= BASENOTE ) && ( note < BASENOTE+NUMNOTES ) )
					{
						note -= BASENOTE;
						status[note] = 0;
					}
				}
				else if( ( midievent->type == SND_SEQ_EVENT_CONTROLLER ) && ( midievent->data.control.channel == channel ) )
				{
					if( midievent->data.control.param == 74 )
					{
						cutoff = midievent->data.control.value;
						fcutoff = (cutoff+5.0)/400.0;
						printf( "Cutoff: %i     \r", cutoff );
						fflush( stdout );
					}
					else if( midievent->data.control.param == 71 )
					{
						resonance = midievent->data.control.value;
						freso = (resonance/140.0)*(1.0-fcutoff);
						printf( "Resonance: %i     \r", resonance );
						fflush( stdout );
					}
					else if( midievent->data.control.param == 73 )
					{
						attack = midievent->data.control.value;
						sattack = (attack+5.0)/800.0;
						printf( "Attack: %i     \r", attack );
						fflush( stdout );
					}
					else if( midievent->data.control.param == 7 )
					{
						volume = midievent->data.control.value;
						printf( "Volume: %i     \r", volume );
						fflush( stdout );
					}
					else if( ( midievent->data.control.param == 64 ) || ( midievent->data.control.param == 1 ) )
					{
						sustain = midievent->data.control.value;
						ssustain = 0.6+pow( sustain/127.0, 0.4)*0.4;
						printf( "Sustain: %i    \r", sustain );
						fflush( stdout );
					}
				}
				
				snd_seq_free_event( midievent );
			}
			while( snd_seq_event_input_pending( seqport, 0 ) > 0 );
		}
	}

	free( pfd );
	snd_seq_delete_port( seqport, midiport );
	snd_seq_close( seqport );
	
	jack_deactivate( jackClient );

	puts( "Freeing data" );
	for( note=0; note<NUMNOTES; note++ )
	{
		free( strings[note] );
	}
	free( tempstring );

	jack_port_unregister( jackClient, outport );
	jack_client_close( jackClient );

	return 0;
}
Example #28
0
void PrintMidiIn() 
{
	snd_seq_event_t* t_event;
	char bytes[] = {0x00, 0x00, 0xFF}; 

	do 
	{
		snd_seq_event_input(t_seq, &t_event);

		//printf("t_event->source.port: %u\n", t_event->source.port); 
		//printf("t_event->source.client: %u\n", t_event->source.client); 
		if     (t_event->data.addr.port == nIdPortInA) printf("PORTA AA\n");
		else if(t_event->data.addr.port == nIdPortInB) printf("PORTA BB\n");
		else if(t_event->data.addr.port == nIdPortInC) printf("PORTA CC\n");
		else printf("ev->data.addr.port: %u\n", t_event->data.addr.port); 
		//printf("ev->data.addr.client: %u\n", t_event->data.addr.client); 
		if     (t_event->dest.port == nIdPortInA) printf("PORTA A\n");
		else if(t_event->dest.port == nIdPortInB) printf("PORTA B\n");
		else if(t_event->dest.port == nIdPortInC) printf("PORTA C\n");
		else printf("t_event->dest.port: %u\n", t_event->data.addr.port); 

		switch (t_event->type) 
		{

			case SND_SEQ_EVENT_NOTEOFF: 
				bytes[0] = 0x80 + t_event->data.control.channel;
				bytes[1] = t_event->data.note.note;
				bytes[2] = t_event->data.note.velocity; 
				printf("IN     ==> 0x%x Note off           0x%x 0x%x 0x%x\n", bytes[0]&0xF0, bytes[0]&0xF, bytes[1], bytes[2]); 
				break; 

			case SND_SEQ_EVENT_NOTEON:
				bytes[0] = 0x90 + t_event->data.control.channel;
				bytes[1] = t_event->data.note.note;
				bytes[2] = t_event->data.note.velocity;        
				printf("IN     ==> 0x%x Note on            0x%x 0x%x 0x%x\n", bytes[0]&0xF0, bytes[0]&0xF, bytes[1], bytes[2]); 
				break;        

			case SND_SEQ_EVENT_KEYPRESS: 
				bytes[0] = 0x90 + t_event->data.control.channel;
				bytes[1] = t_event->data.note.note;
				bytes[2] = t_event->data.note.velocity;        
				printf("IN     ==> 0x%x Pressure change    0x%x 0x%x 0x%x\n", bytes[0]&0xF0, bytes[0]&0xF, bytes[1], bytes[2]); 
				break;       

			case SND_SEQ_EVENT_CONTROLLER: 
				bytes[0] = 0xB0 + t_event->data.control.channel;
				bytes[1] = t_event->data.control.param;
				bytes[2] = t_event->data.control.value;
				printf("IN     ==> 0x%x Controller change  0x%x 0x%x 0x%x\n", bytes[0]&0xF0, bytes[0]&0xF, bytes[1], bytes[2]); 
				break;   

			case SND_SEQ_EVENT_PGMCHANGE: 
				bytes[0] = 0xC0 + t_event->data.control.channel;
				bytes[1] = t_event->data.control.value;
				printf("IN     ==> 0x%x Program change     0x%x 0x%x 0x%x\n", bytes[0]&0xF0, bytes[0]&0xF, bytes[1], bytes[2]); 
				break;  

			case SND_SEQ_EVENT_CHANPRESS: 
				bytes[0] = 0xD0 + t_event->data.control.channel;
				bytes[1] = t_event->data.control.value;
				printf("IN     ==> 0x%x Channel change     0x%x 0x%x 0x%x\n", bytes[0]&0xF0, bytes[0]&0xF, bytes[1], bytes[2]); 
				break;  

			case SND_SEQ_EVENT_PITCHBEND:
				bytes[0] = 0xE0 + t_event->data.control.channel;
				t_event->data.control.value += 8192;
				bytes[1] = (int)t_event->data.control.value & 0x7F;
				bytes[2] = (int)t_event->data.control.value >> 7;
				printf("IN     ==> 0x%x Pitch bend         %03u %5d\n", bytes[0]&0xF0, bytes[0]&0xF, t_event->data.control.value);
				break;

			default:
				break;
		}

		snd_seq_free_event(t_event);

	} while (snd_seq_event_input_pending(t_seq, 0) > 0);
}
Example #29
0
void MidiAlsaSeq::run()
{
	// watch the pipe and sequencer input events
	int pollfd_count = snd_seq_poll_descriptors_count( m_seqHandle,
								POLLIN );
	struct pollfd * pollfd_set = new struct pollfd[pollfd_count + 1];
	snd_seq_poll_descriptors( m_seqHandle, pollfd_set + 1, pollfd_count,
								POLLIN );
	pollfd_set[0].fd = m_pipe[0];
	pollfd_set[0].events = POLLIN;
	++pollfd_count;

	while( m_quit == false )
	{
		int pollRet = poll( pollfd_set, pollfd_count, EventPollTimeOut );
		if( pollRet == 0 )
		{
			continue;
		}
		else if( pollRet == -1 )
		{
			// gdb may interrupt the poll
			if( errno == EINTR )
			{
				continue;
			}
			qCritical( "error while polling ALSA sequencer handle" );
			break;
		}
		// shutdown?
		if( m_quit )
		{
			break;
		}

		m_seqMutex.lock();

		// while event queue is not empty
		while( snd_seq_event_input_pending( m_seqHandle, true ) > 0 )
		{
			snd_seq_event_t * ev;
			if( snd_seq_event_input( m_seqHandle, &ev ) < 0 )
			{
				m_seqMutex.unlock();

				qCritical( "error while fetching MIDI event from sequencer" );
				break;
			}
			m_seqMutex.unlock();

			snd_seq_addr_t * source = NULL;
			MidiPort * dest = NULL;
			for( int i = 0; i < m_portIDs.size(); ++i )
			{
				if( m_portIDs.values()[i][0] == ev->dest.port )
				{
					dest = m_portIDs.keys()[i];
				}
				if( ( m_portIDs.values()[i][1] != -1 &&
						m_portIDs.values()[i][1] == ev->source.port ) ||
							m_portIDs.values()[i][0] == ev->source.port )
				{
					source = &ev->source;
				}
			}

			if( dest == NULL )
			{
				continue;
			}

			switch( ev->type )
			{
				case SND_SEQ_EVENT_NOTEON:
					dest->processInEvent( MidiEvent( MidiNoteOn,
								ev->data.note.channel,
								ev->data.note.note -
								KeysPerOctave,
								ev->data.note.velocity,
								source
								),
							MidiTime( ev->time.tick ) );
					break;

				case SND_SEQ_EVENT_NOTEOFF:
					dest->processInEvent( MidiEvent( MidiNoteOff,
								ev->data.note.channel,
								ev->data.note.note -
								KeysPerOctave,
								ev->data.note.velocity,
								source
								),
							MidiTime( ev->time.tick) );
					break;

				case SND_SEQ_EVENT_KEYPRESS:
					dest->processInEvent( MidiEvent(
									MidiKeyPressure,
								ev->data.note.channel,
								ev->data.note.note -
								KeysPerOctave,
								ev->data.note.velocity,
								source
								), MidiTime() );
					break;

				case SND_SEQ_EVENT_CONTROLLER:
					dest->processInEvent( MidiEvent(
								MidiControlChange,
							ev->data.control.channel,
							ev->data.control.param,
							ev->data.control.value, source ),
									MidiTime() );
					break;

				case SND_SEQ_EVENT_PGMCHANGE:
					dest->processInEvent( MidiEvent(
								MidiProgramChange,
							ev->data.control.channel,
							ev->data.control.param,
							ev->data.control.value, source ),
									MidiTime() );
					break;

				case SND_SEQ_EVENT_CHANPRESS:
					dest->processInEvent( MidiEvent(
								MidiChannelPressure,
							ev->data.control.channel,
							ev->data.control.param,
							ev->data.control.value, source ),
									MidiTime() );
					break;

				case SND_SEQ_EVENT_PITCHBEND:
					dest->processInEvent( MidiEvent( MidiPitchBend,
							ev->data.control.channel,
							ev->data.control.value + 8192, 0, source ),
									MidiTime() );
					break;

				case SND_SEQ_EVENT_SENSING:
				case SND_SEQ_EVENT_CLOCK:
					break;

				default:
					fprintf( stderr,
						"ALSA-sequencer: unhandled input "
							"event %d\n", ev->type );
					break;
			}	// end switch

			m_seqMutex.lock();

		}	// end while

		m_seqMutex.unlock();

	}

	delete[] pollfd_set;
}
Example #30
0
void *
midi_thread_function(void *arg)
{
    int rc;
    struct sched_param rtparam;
    snd_seq_event_t *ev = 0;

    /* try to get low-priority real-time scheduling */
    memset (&rtparam, 0, sizeof (rtparam));
    rtparam.sched_priority = 1; /* just above SCHED_OTHER */
    if ((rc = pthread_setschedparam (pthread_self(), SCHED_FIFO, &rtparam)) != 0) {
        if (rc == EPERM) {
            ghss_debug_rt(GDB_MIDI, " midi thread: no permission for SCHED_FIFO, continuing...");
        } else {
            ghss_debug_rt(GDB_MIDI, " midi thread: error getting SCHED_FIFO, continuing...");
        }
    }

    midi_thread_running = 1;

    do { /* while(!host_exiting) */

        rc = poll(alsaClient_pfd, alsaClient_npfd, 500);
        if (rc <= 0) {
            if (rc < 0 && rc != EINTR) {
                ghss_debug_rt(GDB_MIDI, " midi thread: poll error: %s", strerror(errno));
                usleep(500);
            }
            continue;
        }

        pthread_mutex_lock(&midiEventBufferMutex);

        do {
        
            if (snd_seq_event_input(alsaClient, &ev) > 0) {

                if (midiEventReadIndex == midiEventWriteIndex + 1) {
                    ghss_debug_rt(GDB_MIDI, " midi thread: MIDI event buffer overflow!");
                    continue;
                }

                midiEventBuffer[midiEventWriteIndex] = *ev;

                ev = &midiEventBuffer[midiEventWriteIndex];

                /* We don't need to handle EVENT_NOTE here, because ALSA
                   won't ever deliver them on the sequencer queue -- it
                   unbundles them into NOTE_ON and NOTE_OFF when they're
                   dispatched.  We would only need worry about them when
                   retrieving MIDI events from some other source. */

                if (ev->type == SND_SEQ_EVENT_NOTEON && ev->data.note.velocity == 0) {
                    ev->type =  SND_SEQ_EVENT_NOTEOFF;
                }

                /* fprintf(stderr, "midi: flags %02x, tick %u, sec %u nsec %u\n",
                 *         ev->flags, ev->time.tick, ev->time.time.tv_sec, ev->time.time.tv_nsec);
                 * fflush(stderr); */

                /* -FIX- Ideally, we would use ev->time to figure out how long ago
                 * this event was generated, and adjust accordingly. Instead, we
                 * take the easy-and-fast route of just restamping the event with
                 * the JACK rolling frame time at its arrival, which seems to work
                 * pretty well.... */
                /* -FIX- Rosegarden has example of setting up input queue, see
                 * /t/src/example/rosegarden-CVS-20050109/sound/AlsaDriver.cpp */
                /* -FIX- snd_seq_ioctl_get_queue_status, aka snd_seq_MUMBLE_get_queue_status()
                 * should return current queue time, subtract event time from that to get offset
                 * into past that event arrived? */
                ev->time.tick = jack_frame_time(jackClient);

                /* fprintf(stderr, "midi: %u\n", ev->time.tick); fflush(stderr); */

                ev->dest.client = 0;  /* flag as from MIDI thread */

                midiEventWriteIndex = (midiEventWriteIndex + 1) % EVENT_BUFFER_SIZE;
            }
        
        } while (snd_seq_event_input_pending(alsaClient, 0) > 0);

        pthread_mutex_unlock(&midiEventBufferMutex);

    } while(!host_exiting);

    midi_thread_running = 0;

    return NULL;
}