Пример #1
0
static int osc_midi ( DssiEditor *pDssiEditor, lo_arg **argv )
{
	static snd_midi_event_t *s_pAlsaCoder = NULL;
	static snd_seq_event_t   s_aAlsaEvent[4];

	const unsigned char *data = argv[0]->m;

#ifdef CONFIG_DEBUG
	qDebug("osc_midi: path \"%s\", midi 0x%02x 0x%02x 0x%02x 0x%02x",
		pDssiEditor->path, data[0], data[1], data[2], data[3]);
#endif

	qtractorDssiPlugin *pDssiPlugin = pDssiEditor->plugin;
	if (pDssiPlugin == NULL)
		return 1;

	qtractorMidiManager *pMidiManager = (pDssiPlugin->list())->midiManager();
	if (pMidiManager == NULL)
		return 1;

	if (s_pAlsaCoder == NULL && snd_midi_event_new(4, &s_pAlsaCoder))
		return 1;

	snd_midi_event_reset_encode(s_pAlsaCoder);	
	if (snd_midi_event_encode(s_pAlsaCoder, &data[1], 3, s_aAlsaEvent) < 1)
		return 1;

	// Send the event directly to
	snd_seq_event_t *pEvent = &s_aAlsaEvent[0];
	if (snd_seq_ev_is_channel_type(pEvent))
		pMidiManager->direct(pEvent);

	return 0;
}
Пример #2
0
void DssiPluginMidiManager::convertMidiMessages (MidiBuffer& midiMessages,
                                                 const int blockSamples)
{
    const uint8* data;
    int numBytesOfMidiData,
        samplePosition;
    MidiBuffer::Iterator it (midiMessages);

    currentMidiCount = 0;

    while (it.getNextEvent (data,
                            numBytesOfMidiData,
                            samplePosition))
    {
        if (numBytesOfMidiData > maxEventSize)
        {
            maxEventSize = numBytesOfMidiData;
            snd_midi_event_free (midiParser);
            snd_midi_event_new (maxEventSize, &midiParser);
        }

        snd_seq_event_t* event = & midiEventsBuffer [currentMidiCount];
        snd_seq_ev_clear (event);

        snd_midi_event_encode (midiParser,
                               data,
                               numBytesOfMidiData,
                               event);

        if (++currentMidiCount >= 2048)
            break;
    }

    snd_midi_event_reset_encode (midiParser);
}
Пример #3
0
void
midibus::play (event * a_e24, unsigned char a_channel)
{
#ifdef HAVE_LIBASOUND
    automutex locker(m_mutex);
    snd_seq_event_t ev;
    snd_midi_event_t *midi_ev;      /* ALSA MIDI parser   */
    unsigned char buffer[3];        /* temp for MIDI data */

    /* fill buffer and set midi channel */

    buffer[0] = a_e24->get_status();
    buffer[0] += (a_channel & 0x0F);
    a_e24->get_data(&buffer[1], &buffer[2]);
    snd_midi_event_new(10, &midi_ev);

    /* clear event */

    snd_seq_ev_clear(&ev);
    snd_midi_event_encode(midi_ev, buffer, 3, &ev);
    snd_midi_event_free(midi_ev);

    /* set source */

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

    /* pump it into the queue */

    snd_seq_event_output(m_seq, &ev);
#endif  // HAVE_LIBASOUND
}
Пример #4
0
    void sendMessageNow (const MidiMessage& message)
    {
        if (message.getRawDataSize() > maxEventSize)
        {
            maxEventSize = message.getRawDataSize();
            snd_midi_event_free (midiParser);
            snd_midi_event_new (maxEventSize, &midiParser);
        }

        snd_seq_event_t event;
        snd_seq_ev_clear (&event);

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

        while (numBytes > 0)
        {
            const long numSent = snd_midi_event_encode (midiParser, data, numBytes, &event);
            if (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);

            snd_seq_event_output (seqHandle, &event);
        }

        snd_seq_drain_output (seqHandle);
        snd_midi_event_reset_encode (midiParser);
    }
    void sendMessageNow (const MidiMessage& message)
    {
        if (message.getRawDataSize() > maxEventSize)
        {
            maxEventSize = message.getRawDataSize();
            snd_midi_event_free (midiParser);
            snd_midi_event_new (maxEventSize, &midiParser);
        }

        snd_seq_event_t event;
        snd_seq_ev_clear (&event);

        snd_midi_event_encode (midiParser,
                               message.getRawData(),
                               message.getRawDataSize(),
                               &event);

        snd_midi_event_reset_encode (midiParser);

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

        snd_seq_event_output (seqHandle, &event);
        snd_seq_drain_output (seqHandle);
    }
Пример #6
0
static
void do_jack_output(alsa_seqmidi_t *self, port_t *port, struct process_info* info)
{
	stream_t *str = &self->stream[info->dir];
	int nevents = jack_midi_get_event_count(port->jack_buf);
	int i;
	for (i=0; i<nevents; ++i) {
		jack_midi_event_t jack_event;
		snd_seq_event_t alsa_event;
		int64_t frame_offset;
		int64_t out_time;
		snd_seq_real_time_t out_rt;
		int err;

		jack_midi_event_get(&jack_event, port->jack_buf, i);

		snd_seq_ev_clear(&alsa_event);
		snd_midi_event_reset_encode(str->codec);
		if (!snd_midi_event_encode(str->codec, jack_event.buffer, jack_event.size, &alsa_event))
			continue; // invalid event

		snd_seq_ev_set_source(&alsa_event, self->port_id);
		snd_seq_ev_set_dest(&alsa_event, port->remote.client, port->remote.port);

		/* NOTE: in case of xrun it could become negative, so it is essential to use signed type! */
		frame_offset = (int64_t)jack_event.time + info->period_start + info->nframes - info->cur_frames;
		if (frame_offset < 0) {
			frame_offset = info->nframes + jack_event.time;
			error_log("internal xrun detected: frame_offset = %"PRId64"\n", frame_offset);
		}
		/* Ken Ellinwood reported problems with this assert.
		 * Seems, magic 2 should be replaced with nperiods. */
		//FIXME: assert (frame_offset < info->nframes*2);
		//if (frame_offset < info->nframes * info->nperiods)
		//        debug_log("alsa_out: BLAH-BLAH-BLAH");

		out_time = info->alsa_time + (frame_offset * NSEC_PER_SEC) / info->sample_rate;

		debug_log("alsa_out: frame_offset = %lld, info->alsa_time = %lld, out_time = %lld, port->last_out_time = %lld",
			frame_offset, info->alsa_time, out_time, port->last_out_time);

		// we should use absolute time to prevent reordering caused by rounding errors
		if (out_time < port->last_out_time) {
			debug_log("alsa_out: limiting out_time %lld at %lld", out_time, port->last_out_time);
			out_time = port->last_out_time;
		} else
			port->last_out_time = out_time;

		out_rt.tv_nsec = out_time % NSEC_PER_SEC;
		out_rt.tv_sec = out_time / NSEC_PER_SEC;
		snd_seq_ev_schedule_real(&alsa_event, self->queue, 0, &out_rt);

		err = snd_seq_event_output(self->seq, &alsa_event);
		debug_log("alsa_out: written %d bytes to %s at %+d (%lld): %d", (int)jack_event.size, port->name, (int)frame_offset, out_time, err);
	}
}
Пример #7
0
/* takes an native event, encodes to alsa event, 
   puts it in the queue */
void 
midibus::play( event *a_e24, unsigned char a_channel )
{
    lock();

  

		snd_seq_event_t ev;
		
		/* alsa midi parser */
		snd_midi_event_t *midi_ev;
		
		/* temp for midi data */
		unsigned char buffer[3];
		
		/* fill buffer and set midi channel */
		buffer[0] = a_e24->get_status();
		buffer[0] += (a_channel & 0x0F);
		
		a_e24->get_data( &buffer[1], &buffer[2] );
		
		snd_midi_event_new( 10, &midi_ev );
		
		/* clear event */
		snd_seq_ev_clear( &ev );
		snd_midi_event_encode( midi_ev,
							   buffer,
							   3,
							   &ev ); 
		
		snd_midi_event_free( midi_ev );
		
		/* set source */
		snd_seq_ev_set_source(&ev, m_local_addr_port );
		snd_seq_ev_set_subs(&ev);
		
		/* set tag unique to each sequence for removal purposes */
		//ev.tag = a_tag;
		
		// its immediate 
		snd_seq_ev_set_direct( &ev );
		
		/* pump it into the queue */
		snd_seq_event_output(m_seq, &ev);
	

    unlock();
}
Пример #8
0
void midi_send(uint32 data)
{
	snd_seq_event_t ev;

	if (s_midi == NULL) return;

	snd_seq_ev_clear(&ev);
	snd_seq_ev_set_source(&ev, s_midiPort);
	snd_seq_ev_set_subs(&ev);
	snd_seq_ev_set_direct(&ev);

	snd_midi_event_encode(s_midiCoder, (uint8 *)&data, sizeof(uint32), &ev);

	snd_seq_event_output(s_midi, &ev);
	snd_seq_drain_output(s_midi);
}
Пример #9
0
    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;
    }
Пример #10
0
static ssize_t snd_rawmidi_virtual_write(snd_rawmidi_t *rmidi, const void *buffer, size_t size)
{
	snd_rawmidi_virtual_t *virt = rmidi->private_data;
	ssize_t result = 0;
	ssize_t size1;
	int err;

	if (virt->pending) {
		err = snd_seq_event_output(virt->handle, &virt->out_event);
		if (err < 0) {
			if (err != -EAGAIN)
				/* we got some fatal error. removing this event
				 * at the next time
				 */
				virt->pending = 0;
			return err;
		}
		virt->pending = 0;
	}

	while (size > 0) {
		size1 = snd_midi_event_encode(virt->midi_event, buffer, size, &virt->out_event);
		if (size1 <= 0)
			break;
		size -= size1;
		result += size1;
		buffer += size1;
		if (virt->out_event.type == SND_SEQ_EVENT_NONE)
			continue;
		snd_seq_ev_set_subs(&virt->out_event);
		snd_seq_ev_set_source(&virt->out_event, virt->port);
		snd_seq_ev_set_direct(&virt->out_event);
		err = snd_seq_event_output(virt->handle, &virt->out_event);
		if (err < 0) {
			virt->pending = 1;
			return result > 0 ? result : err;
		}
	}

	if (result > 0)
		snd_seq_drain_output(virt->handle);

	return result;
}
Пример #11
0
/* handle rawmidi input event (MIDI v1.0 stream) */
static void snd_midi_input_event(snd_rawmidi_substream_t * substream)
{
	snd_rawmidi_runtime_t *runtime;
	seq_midisynth_t *msynth;
	snd_seq_event_t ev;
	char buf[16], *pbuf;
	long res, count;

	if (substream == NULL)
		return;
	runtime = substream->runtime;
	msynth = (seq_midisynth_t *) runtime->private_data;
	if (msynth == NULL)
		return;
	memset(&ev, 0, sizeof(ev));
	while (runtime->avail > 0) {
		res = snd_rawmidi_kernel_read(substream, buf, sizeof(buf));
		if (res <= 0)
			continue;
		if (msynth->parser == NULL)
			continue;
		pbuf = buf;
		while (res > 0) {
			count = snd_midi_event_encode(msynth->parser, pbuf, res, &ev);
			if (count < 0)
				break;
			pbuf += count;
			res -= count;
			if (ev.type != SNDRV_SEQ_EVENT_NONE) {
				ev.source.port = msynth->seq_port;
				ev.dest.client = SNDRV_SEQ_ADDRESS_SUBSCRIBERS;
				snd_seq_kernel_client_dispatch(msynth->seq_client, &ev, 1, 0);
				/* clear event and reset header */
				memset(&ev, 0, sizeof(ev));
			}
		}
	}
}
Пример #12
0
void
midibus::play (event * e24, midibyte channel)
{
#ifdef SEQ64_HAVE_LIBASOUND
    automutex locker(m_mutex);
    midibyte buffer[4];                             /* temp for MIDI data   */
    buffer[0] = e24->get_status();                  /* fill buffer          */
    buffer[0] += (channel & 0x0F);
    e24->get_data(buffer[1], buffer[2]);            /* set MIDI data        */

    snd_midi_event_t * midi_ev;                     /* ALSA MIDI parser     */
    snd_midi_event_new(SEQ64_MIDI_EVENT_SIZE_MAX, &midi_ev);

    snd_seq_event_t ev;
    snd_seq_ev_clear(&ev);                          /* clear event          */
    snd_midi_event_encode(midi_ev, buffer, 3, &ev); /* encode 3 raw bytes   */
    snd_midi_event_free(midi_ev);                   /* free the parser      */
    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 is immediate      */
    snd_seq_event_output(m_seq, &ev);               /* pump into the queue  */
#endif  // SEQ64_HAVE_LIBASOUND
}
Пример #13
0
void QMidi::outSendMsg(qint32 msg)
{
#if defined(Q_OS_WIN)
    midiOutShortMsg(midiOutPtr,(DWORD)msg);
#elif defined(Q_OS_LINUX)
    snd_seq_event_t ev;
    snd_midi_event_t* mev;

    snd_seq_ev_clear(&ev);
    snd_seq_ev_set_source(&ev, 0);
    snd_seq_ev_set_subs(&ev);
    snd_seq_ev_set_direct(&ev);

    snd_midi_event_new(sizeof(msg), &mev);
    snd_midi_event_resize_buffer(mev, sizeof(msg));
    snd_midi_event_encode(mev,(unsigned char*)&msg, sizeof(msg), &ev);

    snd_seq_event_output(midiOutPtr, &ev);
    snd_seq_drain_output(midiOutPtr);
#elif defined(Q_OS_HAIKU)
    midiOutLocProd->SprayData((void*)&msg,sizeof(msg),true);
#endif
}
Пример #14
0
void Alsa::sendMessage(const std::vector<uint8_t> *msg_ )
{
    int result;
    unsigned int nBytes = msg_->size();
    if ( nBytes > _apiData->bufferSize ) {
        _apiData->bufferSize = nBytes;
        result = snd_midi_event_resize_buffer ( _apiData->coder, nBytes);
        if ( result != 0 ) {
            std::cerr << "error: CxxMidi::Output::Alsa::sendMessage: ALSA error resizing MIDI event buffer" << std::endl;
        }
        free (_apiData->buffer);
        _apiData->buffer = (unsigned char *) malloc( _apiData->bufferSize );
        if ( _apiData->buffer == NULL ) {
            std::cerr << "error: CxxMidi::Output::Alsa::sendMessage: error allocating buffer memory" << std::endl;
        }
    }

    snd_seq_event_t ev;
    snd_seq_ev_clear(&ev);
    snd_seq_ev_set_source(&ev, _apiData->vport);
    snd_seq_ev_set_subs(&ev);
    snd_seq_ev_set_direct(&ev);
    for ( unsigned int i=0; i<nBytes; ++i ) _apiData->buffer[i] = msg_->at(i);
    result = snd_midi_event_encode( _apiData->coder, _apiData->buffer, (long)nBytes, &ev );
    if ( result < (int)nBytes ) {
        std::cerr << "error: CxxMidi::Output::Alsa::sendMessage: event parsing error" << std::endl;
        return;
    }

    // Send the event.
    result = snd_seq_event_output(_apiData->seq, &ev);
    if ( result < 0 ) {
        std::cerr << "error: CxxMidi::Output::Alsa::sendMessage: error sending MIDI message to port" << std::endl;
    }
    snd_seq_drain_output(_apiData->seq);
}
Пример #15
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);
			}
		}
	}
}