Exemple #1
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);  
}
Exemple #2
0
// This splits the Midi events from one channel to another two channels
void Spliter::midievents(){
    snd_seq_event_t *midievent;
    midievent=NULL;
    snd_seq_event_input(midi_in,&midievent);
    
    if (midievent==NULL) return;
    if  ((midievent->type==SND_SEQ_EVENT_NOTEON)||(midievent->type==SND_SEQ_EVENT_NOTEOFF)){
	int cmdchan=midievent->data.note.channel;
	if (cmdchan==Pchin){
	snd_seq_ev_set_subs(midievent);  
	snd_seq_ev_set_direct(midievent);
	if (midievent->data.note.note<Psplitpoint) {
	    midievent->data.note.channel=Pchout1;
	    int tmp=midievent->data.note.note;
	    tmp+=Poct1*12;if (tmp>127) tmp=127;if (tmp<0) tmp=0;
	    midievent->data.note.note=tmp;
	    } else {
	    midievent->data.note.channel=Pchout2;
	    int tmp=midievent->data.note.note;
	    tmp+=Poct2*12;if (tmp>127) tmp=127;if (tmp<0) tmp=0;
	    midievent->data.note.note=tmp;
	    };
	snd_seq_event_output_direct(midi_out,midievent);
	} else {
	snd_seq_ev_set_subs(midievent);  
	snd_seq_ev_set_direct(midievent);
	snd_seq_event_output_direct(midi_out,midievent);
	};
				    
    };
    snd_seq_free_event(midievent);
};
Exemple #3
0
void qxgeditMidiDevice::sendSysex (
	unsigned char *pSysex, unsigned short iSysex ) const
{
#ifdef CONFIG_DEBUG
	fprintf(stderr, "qxgeditMidiDevice::sendSysex(%p, %u)", pSysex, iSysex);
	fprintf(stderr, " sysex {");
	for (unsigned short i = 0; i < iSysex; ++i)
		fprintf(stderr, " %02x", pSysex[i]);
	fprintf(stderr, " }\n");
#endif

	// Don't do anything else if engine
	// has not been activated...
	if (m_pAlsaSeq == NULL)
		return;

	// Initialize sequencer event...
	snd_seq_event_t ev;
	snd_seq_ev_clear(&ev);

	// Addressing...
	snd_seq_ev_set_source(&ev, m_iAlsaPort);
	snd_seq_ev_set_subs(&ev);

	// The event will be direct...
	snd_seq_ev_set_direct(&ev);

	// Just set SYSEX stuff and send it out..
	ev.type = SND_SEQ_EVENT_SYSEX;
	snd_seq_ev_set_sysex(&ev, iSysex, pSysex);
	snd_seq_event_output_direct(m_pAlsaSeq, &ev);
}
Exemple #4
0
void aubio_midi_direct_output(aubio_midi_driver_t * d, aubio_midi_event_t * event) 
{
    aubio_alsa_seq_driver_t* dev = (aubio_alsa_seq_driver_t*) d;
    switch(event->type) 
    {
        case NOTE_ON:
            ev.type = SND_SEQ_EVENT_NOTEON;
            ev.data.note.channel  = event->channel;
            ev.data.note.note     = event->param1;
            ev.data.note.velocity = event->param2;
            //AUBIO_ERR( "NOTE_ON %d\n", event->param1);
            break;
        case NOTE_OFF:
            ev.type = SND_SEQ_EVENT_NOTEOFF;
            ev.data.note.channel  = event->channel;
            ev.data.note.note     = event->param1;
            ev.data.note.velocity = event->param2;
            //AUBIO_ERR( "NOTE_OFF %d\n", event->param1);
            break;
        default:
            break;
    }
    if (ev.type == SND_SEQ_EVENT_NOTEOFF || ev.type == SND_SEQ_EVENT_NOTEON ) { 
        snd_seq_ev_set_subs(&ev);
        snd_seq_ev_set_direct(&ev);
        snd_seq_ev_set_source(&ev, dev->seq_port);
        snd_seq_event_output_direct(dev->seq_handle, &ev);
    }
}
Exemple #5
0
void
rimshot_alsa_output_play_note (rimshot_alsa_output_t *output, int channel, int note, unsigned int velocity)
{
    snd_seq_event_t ev;

    snd_seq_ev_clear (&ev);
    snd_seq_ev_set_source (&ev, output->port);
    snd_seq_ev_set_subs (&ev);
    snd_seq_ev_set_direct (&ev);

    snd_seq_ev_set_noteon (&ev, channel, note, velocity);
    snd_seq_event_output_direct (output->seq, &ev);
}
Exemple #6
0
void MidiQueue::enqueueMidiMessage(const snd_seq_event_type messageType, const int sourcePort, const snd_seq_tick_time_t& tick)
{
	snd_seq_event_t event = {};
	event.type = messageType;
	snd_seq_ev_schedule_tick(&event, _id, 1, tick);
	snd_seq_ev_set_source(&event, sourcePort);
	snd_seq_ev_set_subs(&event);
	int result = snd_seq_event_output_direct(_sequencer, &event);
	if (result < 0)
	{
		std::cerr << "MidiQueue::enqueueMidiMessage error:" << snd_strerror(result) << std::endl;
	}
}
Exemple #7
0
void synth_noteStop(synth_t * st,int num, int status)
{
    snd_seq_event_t ev;
    snd_seq_ev_clear(&ev);
    snd_seq_ev_set_direct(&ev);
    snd_seq_ev_set_source(&ev, port_out_id);
    snd_seq_ev_set_subs(&ev);
    //usleep(100000);
    printf("synth_noteStop %d\n", st->runningNote[num]);
    snd_seq_ev_set_noteoff(&ev, st->channel, st->runningNote[num], st->velocity);
    snd_seq_event_output_direct(seq, &ev);
    snd_seq_drain_output(seq);
}
Exemple #8
0
static gboolean
put_click (const DrumClick *click)
{
    snd_seq_event_t ev;
    snd_seq_ev_clear (&ev);

    snd_seq_ev_set_source (&ev, out_port_id);
    snd_seq_ev_set_subs (&ev);
    snd_seq_ev_schedule_tick (&ev, queue_id, 0, click->tick);
    snd_seq_ev_set_note (&ev, 10, 24, click->velocity, 48);

    int err = snd_seq_event_output_direct (seq, &ev);
    return err >= 0;
}
Exemple #9
0
void synth_noteStart(synth_t * st,int num, int status)
{
    snd_seq_event_t ev;
    snd_seq_ev_clear(&ev);
    snd_seq_ev_set_direct(&ev);
    snd_seq_ev_set_source(&ev, port_out_id);
    snd_seq_ev_set_subs(&ev);
    printf("synth_noteStart %d\n", st->btn2note[num]);
    int note = st->btn2note[num]+st->sharp+12*st->octaveUp-12*st->octaveDown;
    st->runningNote[num]=note;
    snd_seq_ev_set_noteon(&ev, st->channel, note, st->velocity);
    snd_seq_event_output_direct(seq, &ev);
    snd_seq_drain_output(seq);
}
Exemple #10
0
void sys_alsa_putmidimess(int portno, int a, int b, int c)
{
    int channel;
    snd_seq_event_t ev;
    snd_seq_ev_clear(&ev);
    if (portno >= 0 && portno < alsa_nmidiout)
    {
        if (a >= 224)   // pitchbend
        {
            channel = a-224;
            snd_seq_ev_set_pitchbend(&ev, channel, (((c<<7)|b)-8192)); /* b and c are already correct but alsa needs to recalculate them */
        }
        else if (a >= 208)      // touch
        {
            channel = a-208;
            snd_seq_ev_set_chanpress(&ev,channel,b);
        }
        else if (a >= 192)      // program
        {
            channel = a-192;
            snd_seq_ev_set_pgmchange(&ev,channel,b);
        }
        else if (a >= 176)      // controller
        {
            channel = a-176;
            snd_seq_ev_set_controller(&ev,channel,b,c);
        }
        else if (a >= 160)      // polytouch
        {
            channel = a-160;
            snd_seq_ev_set_keypress(&ev,channel,b,c);
        }
        else if (a >= 144)      // note
        {
            channel = a-144;
            if (c)
                snd_seq_ev_set_noteon(&ev,channel,b,c);
            else
                snd_seq_ev_set_noteoff(&ev,channel,b,c);
        }
        snd_seq_ev_set_direct(&ev);
        snd_seq_ev_set_subs(&ev);
        snd_seq_ev_set_source(&ev,alsa_midioutfd[portno]);
        snd_seq_event_output_direct(midi_handle,&ev);
    }
    //post("%d %d %d\n",a,b,c);
}
Exemple #11
0
static PyObject *
alsaseq_output(PyObject *self, PyObject *args)
{
  snd_seq_event_t ev;
  static PyObject * data;
        
	if (!PyArg_ParseTuple(args, "(bbbb(ii)(bb)(bb)O)", &ev.type, &ev.flags, &ev.tag, &ev.queue, &ev.time.time.tv_sec, &ev.time.time.tv_nsec, &ev.source.client, &ev.source.port, &ev.dest.client, &ev.dest.port, &data ))
		return NULL;

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

        /* printf ( "event.type: %d\n", ev.type ); */
        switch( ev.type ) {
        case SND_SEQ_EVENT_NOTE:
        case SND_SEQ_EVENT_NOTEON:
        case SND_SEQ_EVENT_NOTEOFF:
        case SND_SEQ_EVENT_KEYPRESS:
            if (!PyArg_ParseTuple( data, "bbbbi;data parameter should have 5 values", &ev.data.note.channel, &ev.data.note.note, &ev.data.note.velocity, &ev.data.note.off_velocity, &ev.data.note.duration))
            return NULL;
            break;

        case SND_SEQ_EVENT_CONTROLLER:
        case SND_SEQ_EVENT_PGMCHANGE:
        case SND_SEQ_EVENT_CHANPRESS:
        case SND_SEQ_EVENT_PITCHBEND:
            if (!PyArg_ParseTuple( data, "bbbbii;data parameter should have 6 values", &ev.data.control.channel, &ev.data.control.unused[0], &ev.data.control.unused[1], &ev.data.control.unused[2], &ev.data.control.param, &ev.data.control.value ))
            return NULL;
            break;
        }
        /* If not a direct event, use the queue */
        if ( ev.queue != SND_SEQ_QUEUE_DIRECT )
            ev.queue = queue_id;
        /* Modify source port if out of bounds */
        if ( ev.source.port < firstoutputport ) 
           snd_seq_ev_set_source(&ev, firstoutputport );
        else if ( ev.source.port > lastoutputport )
           snd_seq_ev_set_source(&ev, lastoutputport );
        /* Use subscribed ports, except if ECHO event */
        if ( ev.type != SND_SEQ_EVENT_ECHO ) snd_seq_ev_set_subs(&ev);
        snd_seq_event_output_direct( seq_handle, &ev );

	Py_INCREF(Py_None);
	return Py_None;
}
Exemple #12
0
//  FUNCTIONS
void JVlibForm::send_data(char * buf,int data_size) {
    snd_seq_event_t ev;
    snd_seq_ev_clear(&ev);
    snd_seq_ev_set_direct(&ev);
    ev.queue = SND_SEQ_QUEUE_DIRECT;
    ev.type = SND_SEQ_EVENT_CONTROLLER;
    ev.dest = ports[0];
    ev.data.control.channel = buf[0];
    if (data_size>1)
      ev.data.control.param = buf[1];
    if (data_size==3)
      ev.data.control.value = buf[2];
    snd_seq_ev_set_fixed(&ev);
    snd_seq_ev_set_direct(&ev);
    snd_seq_event_output_direct(seq, &ev);
    snd_seq_drain_output(seq);
}   // end send_data
    bool sendMessageNow (const MidiMessage& message)
    {
        if (message.getRawDataSize() > maxEventSize)
        {
            maxEventSize = message.getRawDataSize();
            snd_midi_event_free (midiParser);
            snd_midi_event_new ((size_t) maxEventSize, &midiParser);
        }

        snd_seq_event_t event;
        snd_seq_ev_clear (&event);

        long numBytes = (long) message.getRawDataSize();
        const uint8* data = message.getRawData();

        snd_seq_t* seqHandle = port.client->get();
        bool success = true;

        while (numBytes > 0)
        {
            const long numSent = snd_midi_event_encode (midiParser, data, numBytes, &event);

            if (numSent <= 0)
            {
                success = numSent == 0;
                break;
            }

            numBytes -= numSent;
            data += numSent;

            snd_seq_ev_set_source (&event, 0);
            snd_seq_ev_set_subs (&event);
            snd_seq_ev_set_direct (&event);

            if (snd_seq_event_output_direct (seqHandle, &event) < 0)
            {
                success = false;
                break;
            }
        }

        snd_midi_event_reset_encode (midiParser);
        return success;
    }
Exemple #14
0
/* Send sysex buffer (buffer must contain complete sysex msg w/ SYSEX & EOX) */
int
midi_send_sysex(int port, void *buf, int buflen)
{
  int err;
  snd_seq_event_t sendev;

  if (port >= MAX_PORTS) return -1;
 
  snd_seq_ev_clear(&sendev);
  snd_seq_ev_set_source(&sendev, ports[port]);
  snd_seq_ev_set_subs(&sendev);
  snd_seq_ev_set_sysex(&sendev, buflen, buf);
  snd_seq_ev_set_direct(&sendev);
  err = snd_seq_event_output_direct(seq, &sendev);
  if (err < 0)
    eprintf("Couldn't send MIDI sysex: %s\n", snd_strerror(err));
  return err;
}
Exemple #15
0
/* takes an native event, encodes to alsa event, 
   puts it in the queue */
void 
midibus::sysex( event *a_e24 )
{
    lock();

    snd_seq_event_t ev;
   
    /* clear event */
    snd_seq_ev_clear( &ev );
    snd_seq_ev_set_priority( &ev, 1 );

    /* set source */
    snd_seq_ev_set_source(&ev, m_local_addr_port );
    snd_seq_ev_set_subs(&ev);
    
    // its immediate 
    snd_seq_ev_set_direct( &ev );

    
    unsigned char *data = a_e24->get_sysex();
    long data_size =  a_e24->get_size();
    for( long offset = 0;
	 offset < data_size;
	 offset += c_midibus_sysex_chunk ){

      long data_left = data_size - offset;

      snd_seq_ev_set_sysex( &ev, 
			       min( data_left, c_midibus_sysex_chunk), 
			       &data[offset] ); 
      
      /* pump it into the queue */
      snd_seq_event_output_direct(m_seq, &ev);

      usleep(80000);
      
      flush();

    }

    unlock();
}
Exemple #16
0
void send_midi_rencoder(unsigned int i)
{
    if (i>=max_midi_rencoders) return;
    struct midi_rencoder *midi_rencoder = midi_rencoders + i;
    if (midi_rencoder->enabled==0) return;

    if (rencoder_seq_handle!=NULL && midi_rencoder->midi_ctrl>0) {
        snd_seq_event_t ev;
        snd_seq_ev_clear(&ev);
        snd_seq_ev_set_direct(&ev);
        //snd_seq_ev_set_dest(&ev, 64, 0); /* send to 64:0 */
        snd_seq_ev_set_subs(&ev);        /* send to subscribers of source port */
        snd_seq_ev_set_controller(&ev, midi_rencoder->midi_chan, midi_rencoder->midi_ctrl, midi_rencoder->value);
        snd_seq_event_output_direct(rencoder_seq_handle, &ev);
        //snd_seq_drain_output(rencoder_seq_handle);
        //printf("SEND MIDI CHAN %d, CTRL %d = %d\n",midi_rencoder->midi_chan,midi_rencoder->midi_ctrl,midi_rencoder->value);
    }
    else if (rencoder_lo_addr!=NULL && midi_rencoder->osc_path[0]) {
        lo_send(rencoder_lo_addr,midi_rencoder->osc_path, "i", midi_rencoder->value);
        //printf("SEND OSC %s => %d\n",midi_rencoder->osc_path,midi_rencoder->value);
    }
}
Exemple #17
0
void
midibus::sysex (event * e24)
{
#ifdef SEQ64_HAVE_LIBASOUND
    automutex locker(m_mutex);
    snd_seq_event_t ev;
    snd_seq_ev_clear(&ev);                              /* clear event      */
    snd_seq_ev_set_priority(&ev, 1);
    snd_seq_ev_set_source(&ev, m_local_addr_port);      /* set source       */
    snd_seq_ev_set_subs(&ev);
    snd_seq_ev_set_direct(&ev);                         /* it's immediate   */

    /*
     *  Replaced by a vector of midibytes:
     *
     *      midibyte * data = e24->get_sysex();
     *
     *  This is a bit tricky, and relies on the standard property of
     *  std::vector where all n elements of the vector are guaranteed to be
     *  stored contiguously (in order to be accessible via random-access
     *  iterators).
     */

    event::SysexContainer & data = e24->get_sysex();
    int data_size = e24->get_sysex_size();
    for (int offset = 0; offset < data_size; offset += c_midibus_sysex_chunk)
    {
        int data_left = data_size - offset;
        snd_seq_ev_set_sysex
        (
            &ev, min(data_left, c_midibus_sysex_chunk), &data[offset]
        );
        snd_seq_event_output_direct(m_seq, &ev);        /* pump into queue  */
        usleep(SEQ64_USLEEP_US);
        flush();
    }
#endif  // SEQ64_HAVE_LIBASOUND
}
Exemple #18
0
void sys_alsa_putmidibyte(int portno, int byte)
{
  static snd_midi_event_t *dev = NULL;
  int res;
  snd_seq_event_t ev;
  if (!dev) {
    snd_midi_event_new(ALSA_MAX_EVENT_SIZE, &dev);
    //assert(dev);
    snd_midi_event_init(dev);
  }
  snd_seq_ev_clear(&ev);
  res = snd_midi_event_encode_byte(dev, byte, &ev);
  if (res > 0 && ev.type != SND_SEQ_EVENT_NONE) {
    // got a complete event, output it
    snd_seq_ev_set_direct(&ev);
    snd_seq_ev_set_subs(&ev);
    snd_seq_ev_set_source(&ev, alsa_midioutfd[portno]);
    snd_seq_event_output_direct(midi_handle, &ev);
  }
  if (res != 0)
    // reinitialize the parser
    snd_midi_event_init(dev);
}
Exemple #19
0
/**************************************************************************
 * 			modData					[internal]
 */
static DWORD modData(WORD wDevID, DWORD dwParam)
{
    BYTE	evt = LOBYTE(LOWORD(dwParam));
    BYTE	d1  = HIBYTE(LOWORD(dwParam));
    BYTE	d2  = LOBYTE(HIWORD(dwParam));
    
    TRACE("(%04X, %08lX);\n", wDevID, dwParam);

    if (wDevID >= MODM_NumDevs) return MMSYSERR_BADDEVICEID;
    if (!MidiOutDev[wDevID].bEnabled) return MIDIERR_NODEVICE;

    if (midiSeq == NULL) {
	WARN("can't play !\n");
	return MIDIERR_NODEVICE;
    }
    switch (MidiOutDev[wDevID].caps.wTechnology) {
    case MOD_SYNTH:
    case MOD_MIDIPORT:
	{
	    int handled = 1; /* Assume event is handled */
            snd_seq_event_t event;
            snd_seq_ev_clear(&event);
            snd_seq_ev_set_direct(&event);
            snd_seq_ev_set_source(&event, port_out);
            snd_seq_ev_set_dest(&event, MidiOutDev[wDevID].addr.client, MidiOutDev[wDevID].addr.port);
	    
	    switch (evt & 0xF0) {
	    case MIDI_CMD_NOTE_OFF:
		snd_seq_ev_set_noteoff(&event, evt&0x0F, d1, d2);
		break;
	    case MIDI_CMD_NOTE_ON:
		snd_seq_ev_set_noteon(&event, evt&0x0F, d1, d2);
		break;
	    case MIDI_CMD_NOTE_PRESSURE:
		snd_seq_ev_set_keypress(&event, evt&0x0F, d1, d2);
		break;
	    case MIDI_CMD_CONTROL:
		snd_seq_ev_set_controller(&event, evt&0x0F, d1, d2);
		break;
	    case MIDI_CMD_BENDER:
		snd_seq_ev_set_pitchbend(&event, evt&0x0F, ((WORD)d2 << 7 | (WORD)d1) - 0x2000);
		break;
	    case MIDI_CMD_PGM_CHANGE:
		snd_seq_ev_set_pgmchange(&event, evt&0x0F, d1);
		break;
	    case MIDI_CMD_CHANNEL_PRESSURE:
		snd_seq_ev_set_chanpress(&event, evt&0x0F, d1);
		break;
	    case MIDI_CMD_COMMON_SYSEX:
		switch (evt & 0x0F) {
		case 0x00:	/* System Exclusive, don't do it on modData,
				 * should require modLongData*/
		case 0x01:	/* Undefined */
		case 0x04:	/* Undefined. */
		case 0x05:	/* Undefined. */
		case 0x07:	/* End of Exclusive. */
		case 0x09:	/* Undefined. */
		case 0x0D:	/* Undefined. */
		    handled = 0;
		    break;
		case 0x06:	/* Tune Request */
		case 0x08:	/* Timing Clock. */
		case 0x0A:	/* Start. */
		case 0x0B:	/* Continue */
		case 0x0C:	/* Stop */
		case 0x0E: 	/* Active Sensing. */
		    /* FIXME: Is this function suitable for these purposes
		       (and also Song Select and Song Position Pointer) */
	            snd_seq_ev_set_sysex(&event, 1, &evt);
		    break;
		case 0x0F: 	/* Reset */
				/* snd_seq_ev_set_sysex(&event, 1, &evt);
				   this other way may be better */
		    {
			BYTE reset_sysex_seq[] = {MIDI_CMD_COMMON_SYSEX, 0x7e, 0x7f, 0x09, 0x01, 0xf7};
			snd_seq_ev_set_sysex(&event, sizeof(reset_sysex_seq), reset_sysex_seq);
		    }
		    break;
		case 0x03:	/* Song Select. */
		    {
			BYTE buf[2];
			buf[0] = evt;
			buf[1] = d1;
			snd_seq_ev_set_sysex(&event, sizeof(buf), buf);
	            }
	            break;
		case 0x02:	/* Song Position Pointer. */
		    {
			BYTE buf[3];
			buf[0] = evt;
			buf[1] = d1;
			buf[2] = d2;
			snd_seq_ev_set_sysex(&event, sizeof(buf), buf);
	            }
		    break;
		}
		break;
	    }
	    if (handled)
                snd_seq_event_output_direct(midiSeq, &event);
	}
	break;
    default:
	WARN("Technology not supported (yet) %d !\n",
	     MidiOutDev[wDevID].caps.wTechnology);
	return MMSYSERR_NOTENABLED;
    }

    return MMSYSERR_NOERROR;
}
Exemple #20
0
/**************************************************************************
 *		modLongData					[internal]
 */
static DWORD modLongData(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
{
    int		len_add = 0;
    LPBYTE	lpData, lpNewData = NULL;
    snd_seq_event_t event;

    TRACE("(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);

    /* Note: MS doc does not say much about the dwBytesRecorded member of the MIDIHDR structure
     * but it seems to be used only for midi input.
     * Taking a look at the WAVEHDR structure (which is quite similar) confirms this assumption.
     */
    
    if (wDevID >= MODM_NumDevs) return MMSYSERR_BADDEVICEID;
    if (!MidiOutDev[wDevID].bEnabled) return MIDIERR_NODEVICE;

    if (midiSeq == NULL) {
	WARN("can't play !\n");
	return MIDIERR_NODEVICE;
    }

    lpData = (LPBYTE) lpMidiHdr->lpData;
    
    if (lpData == NULL)
	return MIDIERR_UNPREPARED;
    if (!(lpMidiHdr->dwFlags & MHDR_PREPARED))
	return MIDIERR_UNPREPARED;
    if (lpMidiHdr->dwFlags & MHDR_INQUEUE)
	return MIDIERR_STILLPLAYING;
    lpMidiHdr->dwFlags &= ~MHDR_DONE;
    lpMidiHdr->dwFlags |= MHDR_INQUEUE;

    /* FIXME: MS doc is not 100% clear. Will lpData only contain system exclusive
     * data, or can it also contain raw MIDI data, to be split up and sent to
     * modShortData() ?
     * If the latest is true, then the following WARNing will fire up
     */
    if (lpData[0] != 0xF0 || lpData[lpMidiHdr->dwBufferLength - 1] != 0xF7) {
	WARN("Alleged system exclusive buffer is not correct\n\tPlease report with MIDI file\n");
	lpNewData = HeapAlloc(GetProcessHeap(), 0, lpMidiHdr->dwBufferLength + 2);
    }

    TRACE("dwBufferLength=%lu !\n", lpMidiHdr->dwBufferLength);
    TRACE("                 %02X %02X %02X ... %02X %02X %02X\n",
	  lpData[0], lpData[1], lpData[2], lpData[lpMidiHdr->dwBufferLength-3],
	  lpData[lpMidiHdr->dwBufferLength-2], lpData[lpMidiHdr->dwBufferLength-1]);

    switch (MidiOutDev[wDevID].caps.wTechnology) {
    case MOD_FMSYNTH:
	/* FIXME: I don't think there is much to do here */
	break;
    case MOD_MIDIPORT:
	if (lpData[0] != 0xF0) {
	    /* Send start of System Exclusive */
	    len_add = 1;
	    lpData[0] = 0xF0;
	    memcpy(lpNewData, lpData, lpMidiHdr->dwBufferLength);
	    WARN("Adding missing 0xF0 marker at the beginning of "
		 "system exclusive byte stream\n");
	}
	if (lpData[lpMidiHdr->dwBufferLength-1] != 0xF7) {
	    /* Send end of System Exclusive */
	    memcpy(lpData + len_add, lpData, lpMidiHdr->dwBufferLength);
            lpNewData[lpMidiHdr->dwBufferLength + len_add - 1] = 0xF0;
	    len_add++;
	    WARN("Adding missing 0xF7 marker at the end of "
		 "system exclusive byte stream\n");
	}
	snd_seq_ev_clear(&event);
	snd_seq_ev_set_direct(&event);
	snd_seq_ev_set_source(&event, port_out);
	snd_seq_ev_set_dest(&event, MidiOutDev[wDevID].addr.client, MidiOutDev[wDevID].addr.port);
	TRACE("client = %d port = %d\n", MidiOutDev[wDevID].addr.client, MidiOutDev[wDevID].addr.port);
	snd_seq_ev_set_sysex(&event, lpMidiHdr->dwBufferLength + len_add, lpNewData ? lpNewData : lpData);
	snd_seq_event_output_direct(midiSeq, &event);
	if (lpNewData)
		HeapFree(GetProcessHeap(), 0, lpData);
	break;
    default:
	WARN("Technology not supported (yet) %d !\n",
	     MidiOutDev[wDevID].caps.wTechnology);
	return MMSYSERR_NOTENABLED;
    }

    lpMidiHdr->dwFlags &= ~MHDR_INQUEUE;
    lpMidiHdr->dwFlags |= MHDR_DONE;
    if (MIDI_NotifyClient(wDevID, MOM_DONE, (DWORD)lpMidiHdr, 0L) != MMSYSERR_NOERROR) {
	WARN("can't notify client !\n");
	return MMSYSERR_INVALPARAM;
    }
    return MMSYSERR_NOERROR;
}
int main(int argc, char **argv)
{
	int i;
	int listen_port = -1;
	char *client_name = "net2alsamidi";
	char *connect_client = NULL;
	int connect_port = -1;

	for (i = 1; i < argc; i++)
	{
		if (strcmp(argv[i], "--port") == 0)
		{
			if (++i == argc) usage(argv[0]);
			listen_port = atoi(argv[i]);
		}
		else if (strcmp(argv[i], "--name") == 0)
		{
			if (++i == argc) usage(argv[0]);
			client_name = argv[i];
		}
		else if (strcmp(argv[i], "--connect") == 0)
		{
			if (++i == argc) usage(argv[0]);
			connect_client = argv[i];
			if (++i == argc) usage(argv[0]);
			connect_port = atoi(argv[i]);
		}
		else
		{
			usage(argv[0]);
		}
	}

	if (listen_port > 0)
	{
		snd_seq_t *seq;
		int port;

		if (snd_seq_open(&seq, "default", SND_SEQ_OPEN_OUTPUT, 0) < 0)
		{
			fprintf(stderr, "Cannot open the ALSA sequencer.\n");
			exit(1);
		}

		snd_seq_set_client_name(seq, client_name);
		port = snd_seq_create_simple_port(seq, "from NetMIDI client", SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ, SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION);

		if ((connect_client != NULL) && (connect_port >= 0))
		{
			int connect_client_id = -1;

			{
				snd_seq_client_info_t *client_info;
				snd_seq_client_info_malloc(&client_info);

				while (snd_seq_query_next_client(seq, client_info) == 0)
				{
					if (strcmp(snd_seq_client_info_get_name(client_info), connect_client) == 0)
					{
						connect_client_id = snd_seq_client_info_get_client(client_info);
						break;
					}
				}

				snd_seq_client_info_free(client_info);
			}

			if (connect_client_id < 0) connect_client_id = atoi(connect_client);
			snd_seq_connect_to(seq, port, connect_client_id, connect_port);
		}

		{
			int server_socket;
			struct sockaddr_in server_address;

			if ((server_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0)
			{
				fprintf(stderr, "Cannot start a NetMIDI server on port %d.\n", listen_port);
				exit(1);
			}

			server_address.sin_family = AF_INET;
			server_address.sin_port = htons(listen_port);
			server_address.sin_addr.s_addr = INADDR_ANY;

			if (bind(server_socket, (struct sockaddr *)(&server_address), sizeof(server_address)) < 0)
			{
				fprintf(stderr, "Cannot start a NetMIDI server on port %d.\n", listen_port);
				exit(1);
			}

			if (listen(server_socket, 1) < 0)
			{
				fprintf(stderr, "Cannot start a NetMIDI server on port %d.\n", listen_port);
				exit(1);
			}

			while (1)
			{
				int socket_to_client;

				if ((socket_to_client = accept(server_socket, NULL, NULL)) >= 0)
				{
					snd_midi_event_t *midi_event_parser;
					snd_seq_event_t *event;
					unsigned char buffer[BUFFER_SIZE];
					int bytes_read;

					{
						char one = 1;
						setsockopt(socket_to_client, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one));
					}

					snd_midi_event_new(BUFFER_SIZE, &midi_event_parser);

					while ((bytes_read = recv(socket_to_client, buffer, BUFFER_SIZE, 0)) > 0)
					{
						for (i = 0; i < bytes_read; i++)
						{
							if (snd_midi_event_encode_byte(midi_event_parser, buffer[i], event) == 1)
							{
								snd_seq_event_output_direct(seq, event);
							}
						}
					}

					snd_midi_event_free(midi_event_parser);
					close(socket_to_client);
				}
			}

			close(server_socket);
		}

		snd_seq_delete_simple_port(seq, port);
		snd_seq_close(seq);
	}
	else
	{
		usage(argv[0]);
	}

	return 0;
}
Exemple #22
0
void Udp2MidiThread::run()
{
	QUdpSocket *udpSocket = new QUdpSocket();
	bool bres = udpSocket->bind(PC_PORT);
	if( bres == false ) {
                printf("Could not bind to port %d!\n", PC_PORT);
		return;
	}
	
	forever {
		
		if (abort) {
			delete udpSocket;
			
			return;
		}
		
		if( udpSocket->waitForReadyRead(250) == true ) {
			
			// Receive from UDP
			
			QHostAddress from_address;
                        int len = udpSocket->readDatagram((char*)midimsg, MAX_MIDI_MESSAGE_LENGTH, &from_address);
		
                        if( len == -1 ) {
				printf("udp2midi: Error receiving data!\n");
			}
			
                        if( (len == 3) && (midimsg[0] == 0) && (midimsg[1] == 0) && (midimsg[2] == 0) ) {

				string from_ip = from_address.toString().toStdString();
			
				printf("Keepalive from: %s\n", from_ip.c_str());

				midi2udp->add_ip(from_ip);
			
			} else {

				// Send to MIDI
                                printf("udp2midi: Sending event: ");
                                for(int i=0; i<len; ++i) {
                                    printf("0x%x ", midimsg[i]);
                                }
                                printf("\n");
		
                                long res = snd_midi_event_encode(eventparser, midimsg, len, midi_event);
				
				if( res < 0) {
					printf("Error encoding midi event!\n");
				}
				
				snd_midi_event_reset_encode(eventparser);
				
				if(midi_event->type == SND_SEQ_EVENT_NOTEON) {
					printf("udp2midi: Note on: %d, channel %d\n", midi_event->data.note.note, midi_event->data.control.channel);
				} else if(midi_event->type == SND_SEQ_EVENT_NOTEOFF){
					printf("udp2midi: Note off: %d, channel %d\n", midi_event->data.note.note, midi_event->data.control.channel);
				}
				
				snd_seq_ev_set_subs(midi_event);
				snd_seq_ev_set_direct(midi_event);
				snd_seq_ev_set_source(midi_event, midi_out_port);
				
				snd_seq_event_output_direct(seq_handle, midi_event);
				
				snd_seq_free_event(midi_event);
			}
		}
	}
}
Exemple #23
0
void sys_alsa_putmidimess(int portno, int a, int b, int c)
{
    if (portno >= 0 && portno < alsa_nmidiout)
    {
        snd_seq_event_t ev;
        snd_seq_ev_clear(&ev);
        int status = a & 0xf0;
        int channel = a & 0x0f;
        status = (status >= MIDI_SYSEX) ? status : (status & 0xf0);
        switch (status)
        {
            case MIDI_NOTEON:
                snd_seq_ev_set_noteon(&ev, channel, b, c);
                break;
            case MIDI_NOTEOFF:
                snd_seq_ev_set_noteoff(&ev, channel, b, c);
                break;
            case MIDI_POLYAFTERTOUCH:
                snd_seq_ev_set_chanpress(&ev, channel, b);
                break;
            case MIDI_CONTROLCHANGE:
                snd_seq_ev_set_controller(&ev, channel, b, c);
                break;
            case MIDI_PROGRAMCHANGE:
                snd_seq_ev_set_pgmchange(&ev, channel, b);
                break;
            case MIDI_AFTERTOUCH:
                snd_seq_ev_set_chanpress(&ev, channel, b);
                break;
            case MIDI_PITCHBEND:
                /* b and c are already correct but alsa needs to recalculate them */
                snd_seq_ev_set_pitchbend(&ev, channel, (((c<<7)|b)-8192));
                break;
            case MIDI_TIMECODE:
                ev.type = SND_SEQ_EVENT_QFRAME;
                snd_seq_ev_set_fixed(&ev);
                ev.data.raw8.d[0] = a & 0xff; /* status */
                ev.data.raw8.d[1] = b & 0x7f; /* data */
                break;
            case MIDI_SONGPOS:
                ev.type = SND_SEQ_EVENT_SONGPOS;
                snd_seq_ev_set_fixed(&ev);
                ev.data.raw8.d[0] = a & 0xff; /* status */
                ev.data.raw8.d[1] = b & 0x7f; /* data */
                ev.data.raw8.d[2] = c & 0x7f; /* data */
                break;
            case MIDI_SONGSELECT:
                ev.type = SND_SEQ_EVENT_SONGSEL;
                snd_seq_ev_set_fixed(&ev);
                ev.data.raw8.d[0] = a & 0xff; /* status */
                ev.data.raw8.d[1] = b & 0x7f; /* data */
                break;
            default:
                bug("couldn't put alsa midi message");
                break;
        }
        snd_seq_ev_set_direct(&ev);
        snd_seq_ev_set_subs(&ev);
        snd_seq_ev_set_source(&ev, alsa_midioutfd[portno]);
        snd_seq_event_output_direct(midi_handle, &ev);
    }
    //post("%d %d %d\n", a, b, c);
}
Exemple #24
0
int main(int argc, char *argv[]) {

  int getopt_return;
  int option_index;
  int valid;
  snd_seq_t *seq_handle;
  int out_port;
  snd_seq_addr_t seq_addr;
  snd_seq_event_t ev;
  
  valid = 0;
  while (((getopt_return = getopt_long(argc, argv, "ha:p:c:b:n:o:", options, &option_index)) >= 0) && (valid < 2)) {
    switch(getopt_return) {
      case 'a':
        valid++;
        if (snd_seq_open(&seq_handle, "hw", SND_SEQ_OPEN_DUPLEX, 0) < 0) {
          fprintf(stderr, "Error opening ALSA sequencer.\n");
          exit(1);  
        }
        snd_seq_set_client_name(seq_handle, "MidiSend");
        if ((out_port = snd_seq_create_simple_port(seq_handle, "MidiSend",
                        SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ,
                        SND_SEQ_PORT_TYPE_APPLICATION)) < 0) {
          fprintf(stderr, "Error creating sequencer port.\n");
          exit(1);
        }   
        snd_seq_parse_address(seq_handle, &seq_addr, optarg);
        snd_seq_connect_to(seq_handle, out_port, seq_addr.client, seq_addr.port);
        snd_seq_ev_clear(&ev);
        snd_seq_ev_set_subs(&ev);  
        snd_seq_ev_set_direct(&ev);
        snd_seq_ev_set_source(&ev, out_port);
        break;
      case 'p':
        if (valid) {
          valid++;
          if (argc < 6) {
            fprintf(stderr, "\nMissing parameter(s): midisend --program <ch> <prg>\n\n");
          } else {
            ev.data.control.channel = atoi(optarg);
            ev.type = SND_SEQ_EVENT_PGMCHANGE;
            ev.data.control.value = atoi(argv[optind]);
          }
        }  
        break;
      case 'c':
        if (valid) {
          valid++;
          if (argc < 7) {
            fprintf(stderr, "\nMissing parameter(s): midisend --control <ch> <ctrl> <val>\n\n");
          } else {
            ev.data.control.channel = atoi(optarg);
            ev.type = SND_SEQ_EVENT_CONTROLLER;
            ev.data.control.param = atoi(argv[optind]);
            ev.data.control.value = atoi(argv[optind + 1]);
          }   
        }  
        break;
      case 'b':
        if (valid) {
          valid++;
          if (argc < 6) {
            fprintf(stderr, "\nMissing parameter(s): midisend --bend <ch> <val>\n\n");
          } else {
            ev.data.control.channel = atoi(optarg);
            ev.type = SND_SEQ_EVENT_PITCHBEND;
            ev.data.control.value = atoi(argv[optind]) - 8192;
          }
        }  
        break;
      case 'n':
        if (valid) {
          valid++;
          if (argc < 8) {
            fprintf(stderr, "\nMissing parameter(s): midisend --note <ch> <on> <num> <vel>\n\n");
          } else {
            ev.data.control.channel = atoi(optarg);
            ev.type = (atoi(argv[optind])) ? SND_SEQ_EVENT_NOTEON : SND_SEQ_EVENT_NOTEOFF;
            ev.data.note.note = atoi(argv[optind + 1]);
            ev.data.note.velocity = atoi(argv[optind + 2]);
          }  
        }  
        break;
      case 'o':
        if (valid) {
          valid++;
          if (argc < 5) {
            fprintf(stderr, "\nMissing parameter(s): midisend --off <ch>\n\n");
          } else {
            ev.data.control.channel = atoi(optarg);
            ev.type = SND_SEQ_EVENT_CONTROLLER;
            ev.data.control.param = MIDI_CTL_ALL_NOTES_OFF;
            ev.data.control.value = 0;
          }   
        }  
        break;
      case 'h':
        valid = 3;
        printf("\nMidiSend 0.0.1\nWritten by Matthias Nagorni\n");
        printf("(c)2004 SUSE Linux AG Nuremberg\n");
        printf("Licensed under GNU General Public License\n\n");
        printf("--alsa <port>                  ALSA Sequencer Port (e.g. 64:0)\n");
        printf("--program <ch> <prg>           Program Change\n");
        printf("--control <ch> <ctrl> <val>    Control Change\n");
        printf("--bend <ch> <val>              Pitch Bend (0..16383, center = 8192)\n");
        printf("--note <ch> <on> <num> <vel>   Note On (on=1) Note Off (on=0)\n");
        printf("--off <ch>                     All Notes Off\n\n");
        exit(EXIT_SUCCESS);
    }
  }
  if (valid < 2) {
    fprintf(stderr, "\nUsage: midisend PORT COMMAND PARAMETERS\n\n");
    fprintf(stderr, "Type \'midisend -h\' for a list of valid commands.\n\n");
  } else if (valid == 2) {
    snd_seq_event_output_direct(seq_handle, &ev);
  }
}
Exemple #25
0
void SendMidiCommand(int nIdPortOut, char *buf)
{
	/*
	   MIDI COMMANDS
	   -------------------------------------------------------------------
	   name                 status      param 1          param 2
	   -------------------------------------------------------------------
	   note off             0x80+C       key #            velocity
	   note on              0x90+C       key #            velocity
	   poly key pressure    0xA0+C       key #            pressure value
	   control change       0xB0+C       control #        control value
	   program change       0xC0+C       program #        --
	   mono key pressure    0xD0+C       pressure value   --
	   pitch bend           0xE0+C       range (LSB)      range (MSB)
	   system               0xF0+C       manufacturer     model
	   -------------------------------------------------------------------
	   C is the channel number, from 0 to 15;
	   -------------------------------------------------------------------
	   source: http://ftp.ec.vanderbilt.edu/computermusic/musc216site/MIDI.Commands.html
	
	   In this program the pitch bend range will be transmitter as 
	   one single 8-bit number. So the end result is that MIDI commands 
	   will be transmitted as 3 bytes, starting with the operation byte:
	
	   buf[0] --> operation/channel
	   buf[1] --> param1
	   buf[2] --> param2        (param2 not transmitted on program change or key press)


	snd_seq_event_t ev;
	snd_seq_ev_clear(&ev);
	snd_seq_ev_set_source(&ev, nIdPortOut);
	snd_seq_ev_set_subs(&ev);
	snd_seq_ev_set_direct(&ev);

	snd_seq_ev_set_noteoff(&ev, 0, note, 60);
	
	snd_seq_event_output(t_seq, &ev);


   */

	snd_seq_event_t t_event;
	snd_seq_ev_clear(&t_event);
									//			printf("Serial  port: %u\n", nIdPortOut);
	snd_seq_ev_set_source(&t_event, nIdPortOutA);
	snd_seq_ev_set_subs(&t_event);
	snd_seq_ev_set_direct(&t_event);

	int operation, channel, param1, param2;

	operation = buf[0] & 0xF0;
	channel   = buf[0] & 0x0F;
	param1    = buf[1];
	param2    = buf[2];

	switch (operation)
	{
		case 0x80:
			printf("OUT   ==> 0x%x Note off           0x%x 0x%x 0x%x\n", operation, channel, param1, param2);
			snd_seq_ev_set_noteoff(&t_event, channel, param1, param2);
			break;
			
		case 0x90:
			printf("OUT   ==> 0x%x Note on            0x%x 0x%x 0x%x\n", operation, channel, param1, param2);
			snd_seq_ev_set_noteon(&t_event, channel, param1, param2);
			break;
			
		case 0xA0:
			printf("OUT   ==> 0x%x Pressure change    0x%x 0x%x 0x%x\n", operation, channel, param1, param2);
			snd_seq_ev_set_keypress(&t_event, channel, param1, param2);
			break;

		case 0xB0:
			printf("OUT   ==> 0x%x Controller change  0x%x 0x%x 0x%x\n", operation, channel, param1, param2);
			snd_seq_ev_set_controller(&t_event, channel, param1, param2);
			break;

		case 0xC0:
			printf("OUT   ==> 0x%x Program change     0x%x 0x%x 0x%x\n", operation, channel, param1);
			snd_seq_ev_set_pgmchange(&t_event, channel, param1);
			break;

		case 0xD0:
			printf("OUT   ==> 0x%x Channel change     0x%x 0x%x 0x%x\n", operation, channel, param1);
			snd_seq_ev_set_chanpress(&t_event, channel, param1);
			break;

		case 0xE0:
			param1 = (param1 & 0x7F) + ((param2 & 0x7F) << 7);
			printf("OUT   ==> 0x%x Pitch bend         %03u %05i\n", operation, channel, param1);
			snd_seq_ev_set_pitchbend(&t_event, channel, param1 - 8192); // in alsa MIDI we want signed int
			break;

		/* Not implementing system commands (0xF0) */
			
		default:
			printf("OUT       0x%x Unknown MIDI cmd   %03u %03u %03u\n", operation, channel, param1, param2);
			break;
	}

	snd_seq_event_output_direct(t_seq, &t_event);
	//snd_seq_drain_output(t_seq);
	//snd_seq_event_output(t_seq, &t_event);

}