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);
    }
 MidiOutputDevice (MidiOutput* const output, const AlsaPort& p)
     : midiOutput (output), port (p),
       maxEventSize (16 * 1024)
 {
     jassert (port.isValid() && midiOutput != nullptr);
     snd_midi_event_new (maxEventSize, &midiParser);
 }
示例#3
0
文件: alsa.hpp 项目: 5tan/cxxmidi
void Alsa::initialize()
{
    // Set up the ALSA sequencer client.
    snd_seq_t *seq;
    int result = snd_seq_open( &seq, "default", SND_SEQ_OPEN_OUTPUT, SND_SEQ_NONBLOCK );
    if ( result < 0 ) {
        std::cerr << "error: CxxMidi::Output::Alsa::initialize: error creating ALSA sequencer client object" << std::endl;
    }

    // Set client name.
    snd_seq_set_client_name( seq, "CxxMidi (RtMidi) output" );

    // Save our api-specific connection information.
    _apiData= new AlsaMidiData;
    _apiData->seq = seq;
    _apiData->vport = -1;
    _apiData->bufferSize = 32;
    _apiData->coder = 0;
    _apiData->buffer = 0;
    result = snd_midi_event_new( _apiData->bufferSize, &_apiData->coder );
    if ( result < 0 ) {
        delete _apiData;
        std::cerr << "error: CxxMidi::Output::Alsa::initialize: error initializing MIDI event parser" << std::endl;
        return;
    }
    _apiData->buffer = (unsigned char *) malloc( _apiData->bufferSize );
    if ( _apiData->buffer == NULL ) {
        delete _apiData;
        std::cerr << "error: CxxMidi::Output::Alsa::initialize: error allocating buffer memory" << std::endl;
    }
    snd_midi_event_init( _apiData->coder );
}
示例#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);
    }
示例#5
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
}
示例#6
0
 MidiOutputDevice (MidiOutput* output, snd_seq_t* handle)
     : midiOutput (output), seqHandle (handle),
       maxEventSize (16 * 1024)
 {
     jassert (seqHandle != 0 && midiOutput != 0);
     snd_midi_event_new (maxEventSize, &midiParser);
 }
示例#7
0
bool Midi2UdpThread::initSeq()
{
	if(snd_seq_open(&seq_handle, "default", SND_SEQ_OPEN_INPUT, 0) < 0) {
    	printf("midi2udp: Error opening ALSA sequencer.\n");
    	return false;
  	}
	
	snd_seq_set_client_name(seq_handle, "DSMIDIWIFI MIDI2UDP");
	
	char portname[64] = "DSMIDIWIFI MIDI2UDP IN";
	
	int res = midi_in_port = snd_seq_create_simple_port(seq_handle, portname, SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE,
              SND_SEQ_PORT_TYPE_APPLICATION);
	
	if(res < 0) {
		printf("midi2udp: Error creating MIDI port!\n");
		
		snd_seq_close(seq_handle);
		return false;
	}
	
        res = snd_midi_event_new(MAX_MIDI_MESSAGE_LENGTH, &eventparser);
	if(res != 0) {
		printf("midi2udp: Error making midi event parser!\n");
		
		snd_seq_close(seq_handle);
		return false;
	}
	snd_midi_event_init(eventparser);
	
	midi_event = (snd_seq_event_t*)malloc(sizeof(snd_seq_event_t));
	
	return true;
}
示例#8
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;
}
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);
}
示例#10
0
static
void stream_init(alsa_seqmidi_t *self, int dir)
{
	stream_t *str = &self->stream[dir];

	str->new_ports = jack_ringbuffer_create(MAX_PORTS*sizeof(port_t*));
	snd_midi_event_new(MAX_EVENT_SIZE, &str->codec);
}
 MidiOutputDevice (MidiOutput* const midiOutput_,
                   snd_seq_t* const seqHandle_)
     :
       midiOutput (midiOutput_),
       seqHandle (seqHandle_),
       maxEventSize (16 * 1024)
 {
     jassert (seqHandle != 0 && midiOutput != 0);
     snd_midi_event_new (maxEventSize, &midiParser);
 }
示例#12
0
static int snd_seq_midisynth_new(seq_midisynth_t *msynth,
				 snd_card_t *card,
				 int device,
				 int subdevice)
{
	if (snd_midi_event_new(MAX_MIDI_EVENT_BUF, &msynth->parser) < 0)
		return -ENOMEM;
	msynth->card = card;
	msynth->device = device;
	msynth->subdevice = subdevice;
	return 0;
}
    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);
        }
    };
示例#14
0
static bool
a2j_stream_init(struct a2j * self)
{
	struct a2j_stream *str = &self->stream;

	str->new_ports = jack_ringbuffer_create (MAX_PORTS * sizeof(struct a2j_port *));
	if (str->new_ports == NULL) {
		return false;
	}
	
	snd_midi_event_new (MAX_EVENT_SIZE, &str->codec);
	INIT_LIST_HEAD (&str->list);

	return true;
}
示例#15
0
文件: midibus.cpp 项目: vext01/seq24
/* 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();
}
void AlsaSeqMidiInDriver::open(device_id_t device)
{
  if (this->is_open())
    throw std::logic_error("Device already open");

  int err;

  err = snd_seq_open(&m_impl->seq, "default", SND_SEQ_OPEN_INPUT,
		     SND_SEQ_NONBLOCK);
  
  if ( err < 0)
    {
      throw std::runtime_error("Error opening ALSA sequencer.");
    }

  std::ostringstream os;
  os << "gephex input " << device;
  std::string device_name = os.str();
  
  err = snd_seq_set_client_name(m_impl->seq, device_name.c_str());


  err = snd_seq_create_simple_port(m_impl->seq, device_name.c_str(),
				   SND_SEQ_PORT_CAP_WRITE|
				   SND_SEQ_PORT_CAP_SUBS_WRITE,
				   SND_SEQ_PORT_TYPE_APPLICATION);

  if (err < 0)
    {
      snd_seq_close (m_impl->seq);
      throw std::runtime_error("Error creating sequencer port.");
    }
  else
    {
      m_impl->portid =  err;
      snd_seq_ev_clear (&m_impl->SEv);
      snd_seq_ev_set_source (&m_impl->SEv, m_impl->portid);
      snd_seq_ev_set_subs (&m_impl->SEv);
      snd_seq_ev_set_direct (&m_impl->SEv);
    }

  if( snd_midi_event_new (32, &m_impl->decoder) )
    throw std::runtime_error ("Error creating midi event parser");

  snd_midi_event_init(m_impl->decoder);
  snd_midi_event_no_status (m_impl->decoder,1);
}
示例#17
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;
    }
示例#18
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
}
示例#19
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
}
示例#20
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);
}
示例#21
0
/*
 * register a new port if it doesn't exist yet
 */
int
snd_seq_oss_midi_check_new_port(struct snd_seq_port_info *pinfo)
{
	int i;
	struct seq_oss_midi *mdev;
	unsigned long flags;

	/* the port must include generic midi */
	if (! (pinfo->type & SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC))
		return 0;
	/* either read or write subscribable */
	if ((pinfo->capability & PERM_WRITE) != PERM_WRITE &&
	    (pinfo->capability & PERM_READ) != PERM_READ)
		return 0;

	/*
	 * look for the identical slot
	 */
	if ((mdev = find_slot(pinfo->addr.client, pinfo->addr.port)) != NULL) {
		/* already exists */
		snd_use_lock_free(&mdev->use_lock);
		return 0;
	}

	/*
	 * allocate midi info record
	 */
	mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
	if (!mdev)
		return -ENOMEM;

	/* copy the port information */
	mdev->client = pinfo->addr.client;
	mdev->port = pinfo->addr.port;
	mdev->flags = pinfo->capability;
	mdev->opened = 0;
	snd_use_lock_init(&mdev->use_lock);

	/* copy and truncate the name of synth device */
	strlcpy(mdev->name, pinfo->name, sizeof(mdev->name));

	/* create MIDI coder */
	if (snd_midi_event_new(MAX_MIDI_EVENT_BUF, &mdev->coder) < 0) {
		pr_err("ALSA: seq_oss: can't malloc midi coder\n");
		kfree(mdev);
		return -ENOMEM;
	}
	/* OSS sequencer adds running status to all sequences */
	snd_midi_event_no_status(mdev->coder, 1);

	/*
	 * look for en empty slot
	 */
	spin_lock_irqsave(&register_lock, flags);
	for (i = 0; i < max_midi_devs; i++) {
		if (midi_devs[i] == NULL)
			break;
	}
	if (i >= max_midi_devs) {
		if (max_midi_devs >= SNDRV_SEQ_OSS_MAX_MIDI_DEVS) {
			spin_unlock_irqrestore(&register_lock, flags);
			snd_midi_event_free(mdev->coder);
			kfree(mdev);
			return -ENOMEM;
		}
		max_midi_devs++;
	}
	mdev->seq_device = i;
	midi_devs[mdev->seq_device] = mdev;
	spin_unlock_irqrestore(&register_lock, flags);

	return 0;
}
示例#22
0
int snd_rawmidi_virtual_open(snd_rawmidi_t **inputp, snd_rawmidi_t **outputp,
			     const char *name, snd_seq_t *seq_handle, int port,
			     int merge, int mode)
{
	int err;
	snd_rawmidi_t *rmidi;
	snd_rawmidi_virtual_t *virt = NULL;
	struct pollfd pfd;

	if (inputp)
		*inputp = 0;
	if (outputp)
		*outputp = 0;

	virt = calloc(1, sizeof(*virt));
	if (virt == NULL) {
		err = -ENOMEM;
		goto _err;
	}
	virt->handle = seq_handle;
	virt->port = port;
	err = snd_midi_event_new(256, &virt->midi_event);
	if (err < 0)
		goto _err;
	snd_midi_event_init(virt->midi_event);
	snd_midi_event_no_status(virt->midi_event, !merge);

	if (inputp) {
		rmidi = calloc(1, sizeof(*rmidi));
		if (rmidi == NULL) {
			err = -ENOMEM;
			goto _err;
		}
		if (name)
			rmidi->name = strdup(name);
		rmidi->type = SND_RAWMIDI_TYPE_VIRTUAL;
		rmidi->stream = SND_RAWMIDI_STREAM_INPUT;
		rmidi->mode = mode;
		err = snd_seq_poll_descriptors(seq_handle, &pfd, 1, POLLIN);
		if (err < 0)
			goto _err;
		rmidi->poll_fd = pfd.fd;
		rmidi->ops = &snd_rawmidi_virtual_ops;
		rmidi->private_data = virt;
		virt->open++;
		*inputp = rmidi;
	}
	if (outputp) {
		rmidi = calloc(1, sizeof(*rmidi));
		if (rmidi == NULL) {
			err = -ENOMEM;
			goto _err;
		}
		if (name)
			rmidi->name = strdup(name);
		rmidi->type = SND_RAWMIDI_TYPE_VIRTUAL;
		rmidi->stream = SND_RAWMIDI_STREAM_OUTPUT;
		rmidi->mode = mode;
		err = snd_seq_poll_descriptors(seq_handle, &pfd, 1, POLLOUT);
		if (err < 0)
			goto _err;
		rmidi->poll_fd = pfd.fd;
		rmidi->ops = &snd_rawmidi_virtual_ops;
		rmidi->private_data = virt;
		virt->open++;
		*outputp = rmidi;
	}

	return 0;

 _err:
	if (seq_handle)
		snd_seq_close(seq_handle);
	if (virt) {
		if (virt->midi_event)
			snd_midi_event_free(virt->midi_event);
		free(virt);
	}
	if (inputp)
		free(*inputp);
	if (outputp)
		free(*outputp);
	return err;
}
int
snd_seq_oss_midi_check_new_port(struct snd_seq_port_info *pinfo)
{
	int i;
	struct seq_oss_midi *mdev;
	unsigned long flags;

	debug_printk(("check for MIDI client %d port %d\n", pinfo->addr.client, pinfo->addr.port));
	/*                                    */
	if (! (pinfo->type & SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC))
		return 0;
	/*                                   */
	if ((pinfo->capability & PERM_WRITE) != PERM_WRITE &&
	    (pinfo->capability & PERM_READ) != PERM_READ)
		return 0;

	/*
                               
  */
	if ((mdev = find_slot(pinfo->addr.client, pinfo->addr.port)) != NULL) {
		/*                */
		snd_use_lock_free(&mdev->use_lock);
		return 0;
	}

	/*
                             
  */
	if ((mdev = kzalloc(sizeof(*mdev), GFP_KERNEL)) == NULL) {
		snd_printk(KERN_ERR "can't malloc midi info\n");
		return -ENOMEM;
	}

	/*                           */
	mdev->client = pinfo->addr.client;
	mdev->port = pinfo->addr.port;
	mdev->flags = pinfo->capability;
	mdev->opened = 0;
	snd_use_lock_init(&mdev->use_lock);

	/*                                            */
	strlcpy(mdev->name, pinfo->name, sizeof(mdev->name));

	/*                   */
	if (snd_midi_event_new(MAX_MIDI_EVENT_BUF, &mdev->coder) < 0) {
		snd_printk(KERN_ERR "can't malloc midi coder\n");
		kfree(mdev);
		return -ENOMEM;
	}
	/*                                                    */
	snd_midi_event_no_status(mdev->coder, 1);

	/*
                          
  */
	spin_lock_irqsave(&register_lock, flags);
	for (i = 0; i < max_midi_devs; i++) {
		if (midi_devs[i] == NULL)
			break;
	}
	if (i >= max_midi_devs) {
		if (max_midi_devs >= SNDRV_SEQ_OSS_MAX_MIDI_DEVS) {
			spin_unlock_irqrestore(&register_lock, flags);
			snd_midi_event_free(mdev->coder);
			kfree(mdev);
			return -ENOMEM;
		}
		max_midi_devs++;
	}
	mdev->seq_device = i;
	midi_devs[mdev->seq_device] = mdev;
	spin_unlock_irqrestore(&register_lock, flags);

	return 0;
}
示例#24
0
//==============================================================================
DssiPluginMidiManager::DssiPluginMidiManager ()
  : maxEventSize (16 * 1024),
    currentMidiCount (0)
{
    snd_midi_event_new (maxEventSize, &midiParser);
}
示例#25
0
bool
mastermidibus::get_midi_event (event * inev)
{
#ifdef SEQ64_HAVE_LIBASOUND

    automutex locker(m_mutex);
    snd_seq_event_t * ev;
    bool sysex = false;
    bool result = false;
    midibyte buffer[0x1000];                /* temporary buffer for MIDI data */
    snd_seq_event_input(m_alsa_seq, &ev);
    if (! rc().manual_alsa_ports())
    {
        switch (ev->type)
        {
        case SND_SEQ_EVENT_PORT_START:
        {
            port_start(ev->data.addr.client, ev->data.addr.port);
            result = true;
            break;
        }
        case SND_SEQ_EVENT_PORT_EXIT:
        {
            port_exit(ev->data.addr.client, ev->data.addr.port);
            result = true;
            break;
        }
        case SND_SEQ_EVENT_PORT_CHANGE:
        {
            result = true;
            break;
        }
        default:
            break;
        }
    }
    if (result)
        return false;

    snd_midi_event_t * midi_ev;                     /* for ALSA MIDI parser  */
    snd_midi_event_new(sizeof(buffer), &midi_ev);   /* make ALSA MIDI parser */
    long bytes = snd_midi_event_decode(midi_ev, buffer, sizeof(buffer), ev);
    if (bytes <= 0)
    {
        /*
         * This happens even at startup, before anything is really happening.
         * Let's not show it.
         *
         * if (bytes < 0)
         * {
         *     errprint("error decoding MIDI event");
         * }
         */

        return false;
    }

    inev->set_timestamp(ev->time.tick);
    inev->set_status_keep_channel(buffer[0]);

    /**
     *  We will only get EVENT_SYSEX on the first packet of MIDI data;
     *  the rest we have to poll for.  SysEx processing is currently
     *  disabled.
     */

#ifdef USE_SYSEX_PROCESSING                    /* currently disabled           */
    inev->set_sysex_size(bytes);
    if (buffer[0] == EVENT_MIDI_SYSEX)
    {
        inev->restart_sysex();              /* set up for sysex if needed   */
        sysex = inev->append_sysex(buffer, bytes);
    }
    else
    {
#endif
        /*
         *  Some keyboards send Note On with velocity 0 for Note Off, so we
         *  take care of that situation here by creating a Note Off event,
         *  with the channel nybble preserved. Note that we call
         *  event :: set_status_keep_channel() instead of using stazed's
         *  set_status function with the "record" parameter.  A little more
         *  confusing, but faster.
         */

        inev->set_data(buffer[1], buffer[2]);
        if (inev->is_note_off_recorded())
            inev->set_status_keep_channel(EVENT_NOTE_OFF);

        sysex = false;

#ifdef USE_SYSEX_PROCESSING
    }
#endif

    while (sysex)       /* sysex messages might be more than one message */
    {
        snd_seq_event_input(m_alsa_seq, &ev);
        long bytes = snd_midi_event_decode(midi_ev, buffer, sizeof(buffer), ev);
        if (bytes > 0)
            sysex = inev->append_sysex(buffer, bytes);
        else
            sysex = false;
    }
    snd_midi_event_free(midi_ev);

#endif  // SEQ64_HAVE_LIBASOUND

    return true;
}
示例#26
0
void samplv1_jack::open ( const char *client_id )
{
    // init param ports
    for (uint32_t i = 0; i < samplv1::NUM_PARAMS; ++i) {
        const samplv1::ParamIndex index = samplv1::ParamIndex(i);
        m_params[i] = samplv1_param::paramDefaultValue(index);
        samplv1::setParamPort(index, &m_params[i]);
    }

    // open client
    m_client = ::jack_client_open(client_id, JackNullOption, NULL);
    if (m_client == NULL)
        return;

    // set sample rate
    samplv1::setSampleRate(float(jack_get_sample_rate(m_client)));
//	samplv1::reset();

    // register audio ports & buffers
    uint16_t nchannels = samplv1::channels();

    m_audio_ins  = new jack_port_t * [nchannels];
    m_audio_outs = new jack_port_t * [nchannels];

    m_ins  = new float * [nchannels];
    m_outs = new float * [nchannels];

    char port_name[32];
    for (uint16_t k = 0; k < nchannels; ++k) {
        ::snprintf(port_name, sizeof(port_name), "in_%d", k + 1);
        m_audio_ins[k] = ::jack_port_register(m_client,
                                              port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
        m_ins[k] = NULL;
        ::snprintf(port_name, sizeof(port_name), "out_%d", k + 1);
        m_audio_outs[k] = ::jack_port_register(m_client,
                                               port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
        m_outs[k] = NULL;
    }

    // register midi port
#ifdef CONFIG_JACK_MIDI
    m_midi_in = ::jack_port_register(m_client,
                                     "in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
#endif
#ifdef CONFIG_ALSA_MIDI
    m_alsa_seq     = NULL;
//	m_alsa_client  = -1;
    m_alsa_port    = -1;
    m_alsa_decoder = NULL;
    m_alsa_buffer  = NULL;
    m_alsa_thread  = NULL;
    // open alsa sequencer client...
    if (snd_seq_open(&m_alsa_seq, "hw", SND_SEQ_OPEN_INPUT, 0) >= 0) {
        snd_seq_set_client_name(m_alsa_seq, client_id);
        //	m_alsa_client = snd_seq_client_id(m_alsa_seq);
        m_alsa_port = snd_seq_create_simple_port(m_alsa_seq, "in",
                      SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE,
                      SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION);
        snd_midi_event_new(1024, &m_alsa_decoder);
        m_alsa_buffer = ::jack_ringbuffer_create(
                            1024 * (sizeof(jack_midi_event_t) + 4));
        m_alsa_thread = new samplv1_alsa_thread(this);
        m_alsa_thread->start(QThread::TimeCriticalPriority);
    }
#endif	// CONFIG_ALSA_MIDI

    // setup any local, initial buffers...
    samplv1::setBufferSize(::jack_get_buffer_size(m_client));

    jack_set_buffer_size_callback(m_client,
                                  samplv1_jack_buffer_size, this);

    // set process callbacks...
    ::jack_set_process_callback(m_client,
                                samplv1_jack_process, this);

#ifdef CONFIG_JACK_SESSION
    // JACK session event callback...
    if (::jack_set_session_callback) {
        ::jack_set_session_callback(m_client,
                                    samplv1_jack_session_event, this);
    }
#endif
}
示例#27
0
文件: midibus.cpp 项目: vext01/seq24
bool
mastermidibus::get_midi_event( event *a_in )
{
    lock();
    
    snd_seq_event_t *ev; 
    
    bool sysex = false;
    
    /* temp for midi data */
    unsigned char buffer[0x1000];
    
    snd_seq_event_input(m_alsa_seq, &ev);
    
    
    
    bool ret = false;

    if (! global_manual_alsa_ports )
    {
        switch( ev->type ){ 

            case SND_SEQ_EVENT_PORT_START:
                {   
                    //printf("SND_SEQ_EVENT_PORT_START:    addr[%d:%d]\n", 
                    //	   ev->data.addr.client, ev->data.addr.port );
                    port_start( ev->data.addr.client, ev->data.addr.port );
                    ret = true; 
                    break;
                }

            case SND_SEQ_EVENT_PORT_EXIT:     
                {
                    //printf("SND_SEQ_EVENT_PORT_EXIT:     addr[%d:%d]\n", 
                    //	   ev->data.addr.client, ev->data.addr.port ); 
                    port_exit( ev->data.addr.client, ev->data.addr.port );
                    ret = true; 
                    break;
                }

            case SND_SEQ_EVENT_PORT_CHANGE:
                {   
                    //printf("SND_SEQ_EVENT_PORT_CHANGE:   addr[%d:%d]\n", 
                    //	   ev->data.addr.client, 
                    //	   ev->data.addr.port ); 
                    ret = true; 
                    break;
                }

            default: break;

        }
    }

    if( ret ){
        unlock();
        return false;
    }
    
    /* alsa midi parser */
    snd_midi_event_t *midi_ev;
    snd_midi_event_new( 0x1000, &midi_ev );
    
    long bytes =
        snd_midi_event_decode( midi_ev,
                               buffer,
                               0x1000,
                               ev ); 
    
    a_in->set_timestamp( ev->time.tick );
    a_in->set_status( buffer[0] );
    a_in->set_size( bytes );
    
    /* we will only get EVENT_SYSEX on the first 
       packet of midi data, the rest we have
       to poll for */
    //if ( buffer[0] == EVENT_SYSEX ){
    if ( 0 ){
    
        /* set up for sysex if needed */
        a_in->start_sysex( );
        sysex = a_in->append_sysex( buffer, bytes );
    }
    else {
        
        a_in->set_data( buffer[1], buffer[2] );
        
        // some keyboards send on's with vel 0 for off
        if ( a_in->get_status() == EVENT_NOTE_ON &&
             a_in->get_note_velocity() == 0x00 ){
            a_in->set_status( EVENT_NOTE_OFF );
        }
        
        sysex = false;
    }
    
    /* sysex messages might be more than one message */
    while ( sysex ){
        
        snd_seq_event_input(m_alsa_seq, &ev);
        
        bytes =
            snd_midi_event_decode( midi_ev,
                                   buffer,
                                   0x1000,
                                   ev ); 
        
        sysex = a_in->append_sysex( buffer, bytes );
        
    }
    
    snd_seq_free_event( ev );
    snd_midi_event_free( midi_ev );
    
    unlock();
    
    return true;
}
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;
}
示例#29
0
void sys_alsa_do_open_midi(int nmidiin, int *midiinvec,
    int nmidiout, int *midioutvec)
{

    char portname[50];
    int err = 0;
    int client;
    int i;
    snd_seq_client_info_t *alsainfo;

    alsa_nmidiin = 0;
    alsa_nmidiout = 0;

    if (nmidiout == 0 && nmidiin == 0) return;

    if(nmidiin>MAXMIDIINDEV )
      {
        post("midi input ports reduced to maximum %d", MAXMIDIINDEV);
        nmidiin=MAXMIDIINDEV;
      }
    if(nmidiout>MAXMIDIOUTDEV)
      {
        post("midi output ports reduced to maximum %d", MAXMIDIOUTDEV);
        nmidiout=MAXMIDIOUTDEV;
      }

    if (nmidiin>0 && nmidiout>0)
        err = snd_seq_open(&midi_handle,"default",SND_SEQ_OPEN_DUPLEX,0);
    else if (nmidiin > 0)
        err = snd_seq_open(&midi_handle,"default",SND_SEQ_OPEN_INPUT,0);
    else if (nmidiout > 0)
        err = snd_seq_open(&midi_handle,"default",SND_SEQ_OPEN_OUTPUT,0);
    
    if (err!=0)
    {
            sys_setalarm(1000000);
            post("couldn't open alsa sequencer");
            return;
    }
    for (i=0;i<nmidiin;i++)
    {
        int port;
        sprintf(portname,"Pure Data Midi-In %d",i+1);
        port = snd_seq_create_simple_port(midi_handle,portname,
                                          SND_SEQ_PORT_CAP_WRITE |SND_SEQ_PORT_CAP_SUBS_WRITE, 
                                          SND_SEQ_PORT_TYPE_APPLICATION);
        alsa_midiinfd[i] = port;        
        if (port < 0) goto error;        
    }

    for (i=0;i<nmidiout;i++)
    {
        int port;
        sprintf(portname,"Pure Data Midi-Out %d",i+1);
        port = snd_seq_create_simple_port(midi_handle,portname,
                                          SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ, 
                                          SND_SEQ_PORT_TYPE_APPLICATION);
        alsa_midioutfd[i] = port;       
        if (port < 0) goto error;        
    }
   
    snd_seq_client_info_malloc(&alsainfo);
    snd_seq_get_client_info(midi_handle,alsainfo);
    snd_seq_client_info_set_name(alsainfo,"Pure Data");
    client = snd_seq_client_info_get_client(alsainfo);
    snd_seq_set_client_info(midi_handle,alsainfo);
    snd_seq_client_info_free(alsainfo);
    post("Opened Alsa Client %d in:%d out:%d",client,nmidiin,nmidiout);
    sys_setalarm(0);
    snd_midi_event_new(ALSA_MAX_EVENT_SIZE,&midiev);
    alsa_nmidiout = nmidiout;
    alsa_nmidiin = nmidiin;

    return;
 error:
    sys_setalarm(1000000);
    post("couldn't open alsa MIDI output device");
    return;
}
/*
  direction has to be either SND_RAWMIDI_STREAM_INPUT or
  SND_RAWMIDI_STREAM_OUTPUT.
  Returns 0 on success. Otherwise, MIDI_OUT_OF_MEMORY, MIDI_INVALID_ARGUMENT
   or a negative ALSA error code is returned.
*/
INT32 openMidiDevice(snd_rawmidi_stream_t direction, INT32 deviceIndex,
                     MidiDeviceHandle** handle) {
    snd_rawmidi_t* native_handle;
    snd_midi_event_t* event_parser = NULL;
    int err;
    UINT32 deviceID;
    char devicename[100];
#ifdef ALSA_MIDI_USE_PLUGHW
    int usePlugHw = 1;
#else
    int usePlugHw = 0;
#endif

    TRACE0("> openMidiDevice()\n");

    (*handle) = (MidiDeviceHandle*) calloc(sizeof(MidiDeviceHandle), 1);
    if (!(*handle)) {
        ERROR0("ERROR: openDevice: out of memory\n");
        return MIDI_OUT_OF_MEMORY;
    }

    // TODO: iterate to get dev ID from index
    err = getMidiDeviceID(direction, deviceIndex, &deviceID);
    TRACE1("  openMidiDevice(): deviceID: %d\n", (int) deviceID);
    getDeviceStringFromDeviceID(devicename, deviceID,
                                usePlugHw, ALSA_RAWMIDI);
    TRACE1("  openMidiDevice(): deviceString: %s\n", devicename);

    // finally open the device
    if (direction == SND_RAWMIDI_STREAM_INPUT) {
        err = snd_rawmidi_open(&native_handle, NULL, devicename,
                               SND_RAWMIDI_NONBLOCK);
    } else if (direction == SND_RAWMIDI_STREAM_OUTPUT) {
        err = snd_rawmidi_open(NULL, &native_handle, devicename,
                               SND_RAWMIDI_NONBLOCK);
    } else {
        ERROR0("  ERROR: openMidiDevice(): direction is neither SND_RAWMIDI_STREAM_INPUT nor SND_RAWMIDI_STREAM_OUTPUT\n");
        err = MIDI_INVALID_ARGUMENT;
    }
    if (err < 0) {
        ERROR1("<  ERROR: openMidiDevice(): snd_rawmidi_open() returned %d\n", err);
        free(*handle);
        (*handle) = NULL;
        return err;
    }
    /* We opened with non-blocking behaviour to not get hung if the device
       is used by a different process. Writing, however, should
       be blocking. So we change it here. */
    if (direction == SND_RAWMIDI_STREAM_OUTPUT) {
        err = snd_rawmidi_nonblock(native_handle, 0);
        if (err < 0) {
            ERROR1("  ERROR: openMidiDevice(): snd_rawmidi_nonblock() returned %d\n", err);
            snd_rawmidi_close(native_handle);
            free(*handle);
            (*handle) = NULL;
            return err;
        }
    }
    if (direction == SND_RAWMIDI_STREAM_INPUT) {
        err = snd_midi_event_new(EVENT_PARSER_BUFSIZE, &event_parser);
        if (err < 0) {
            ERROR1("  ERROR: openMidiDevice(): snd_midi_event_new() returned %d\n", err);
            snd_rawmidi_close(native_handle);
            free(*handle);
            (*handle) = NULL;
            return err;
        }
    }

    (*handle)->deviceHandle = (void*) native_handle;
    (*handle)->startTime = getTimeInMicroseconds();
    (*handle)->platformData = event_parser;
    TRACE0("< openMidiDevice(): succeeded\n");
    return err;
}