예제 #1
0
파일: midibus.cpp 프로젝트: EQ4/sequencer24
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
}
    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);
    }
예제 #3
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);
}
예제 #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
/*
 * release the midi device if it was registered
 */
int
snd_seq_oss_midi_check_exit_port(int client, int port)
{
	struct seq_oss_midi *mdev;
	unsigned long flags;
	int index;

	if ((mdev = find_slot(client, port)) != NULL) {
		spin_lock_irqsave(&register_lock, flags);
		midi_devs[mdev->seq_device] = NULL;
		spin_unlock_irqrestore(&register_lock, flags);
		snd_use_lock_free(&mdev->use_lock);
		snd_use_lock_sync(&mdev->use_lock);
		snd_midi_event_free(mdev->coder);
		kfree(mdev);
	}
	spin_lock_irqsave(&register_lock, flags);
	for (index = max_midi_devs - 1; index >= 0; index--) {
		if (midi_devs[index])
			break;
	}
	max_midi_devs = index + 1;
	spin_unlock_irqrestore(&register_lock, flags);
	return 0;
}
예제 #6
0
파일: alsa_seqmidi.c 프로젝트: Andux/jack2
static
void stream_close(alsa_seqmidi_t *self, int dir)
{
	stream_t *str = &self->stream[dir];

	if (str->codec)
		snd_midi_event_free(str->codec);
	if (str->new_ports)
		jack_ringbuffer_free(str->new_ports);
}
예제 #7
0
void midi_uninit() {
	if (s_midi == NULL) return;

	snd_midi_event_free(s_midiCoder);
	snd_seq_port_subscribe_free(s_midiSubscription);
	snd_seq_delete_port(s_midi, s_midiPort);
	snd_seq_close(s_midi);

	s_midi = NULL;
}
void AlsaSeqMidiInDriver::close()
{
  if (!this->is_open())
    throw std::logic_error("Device not open");

  if (m_impl->decoder)
    snd_midi_event_free (m_impl->decoder);
  
  snd_seq_close(m_impl->seq);
  m_impl->seq=0;
}
예제 #9
0
static
void
a2j_stream_close (struct a2j * self)
{
	struct a2j_stream *str = &self->stream;

	if (str->codec)
		snd_midi_event_free (str->codec);
	if (str->new_ports)
		jack_ringbuffer_free (str->new_ports);
}
예제 #10
0
/* delete given midi synth port */
static void snd_seq_midisynth_delete(struct seq_midisynth *msynth)
{
    if (msynth == NULL)
        return;

    if (msynth->seq_client > 0) {
        /* delete port */
        snd_seq_event_port_detach(msynth->seq_client, msynth->seq_port);
    }

    snd_midi_event_free(msynth->parser);
}
    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);
        }
    };
예제 #12
0
static int snd_rawmidi_virtual_close(snd_rawmidi_t *rmidi)
{
	snd_rawmidi_virtual_t *virt = rmidi->private_data;
	virt->open--;
	if (virt->open)
		return 0;
	snd_seq_close(virt->handle);
	if (virt->midi_event)
		snd_midi_event_free(virt->midi_event);
	free(virt);
	return 0;
}
예제 #13
0
파일: s_midi_alsa.c 프로젝트: Angeldude/pd
void sys_alsa_close_midi()
{
    alsa_nmidiin = alsa_nmidiout = 0;
    if(midi_handle)
      {
        snd_seq_close(midi_handle);
        if(midiev)
          {
            snd_midi_event_free(midiev);
          }
      }
}
예제 #14
0
파일: alsa.hpp 프로젝트: 5tan/cxxmidi
Alsa::~Alsa()
{
    // Close a connection if it exists.
    closePort();

    // Cleanup.
    if ( _apiData->vport >= 0 ) snd_seq_delete_port( _apiData->seq, _apiData->vport );
    if ( _apiData->coder ) snd_midi_event_free( _apiData->coder );
    if ( _apiData->buffer ) free( _apiData->buffer );
    snd_seq_close( _apiData->seq );
    delete _apiData;
}
예제 #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();
}
예제 #16
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;
    }
예제 #17
0
/* delete given midi synth port */
static void snd_seq_midisynth_delete(seq_midisynth_t *msynth)
{
	snd_seq_port_info_t port;
	
	if (msynth == NULL)
		return;

	if (msynth->seq_client > 0) {
		/* delete port */
		memset(&port, 0, sizeof(port));
		port.addr.client = msynth->seq_client;
		port.addr.port = msynth->seq_port;
		snd_seq_kernel_client_ctl(port.addr.client, SNDRV_SEQ_IOCTL_DELETE_PORT, &port);
	}

	if (msynth->parser)
		snd_midi_event_free(msynth->parser);
}
예제 #18
0
/*
 * release the midi device if it was registered
 */
void
snd_seq_oss_midi_clear_all(void)
{
	int i;
	struct seq_oss_midi *mdev;
	unsigned long flags;

	spin_lock_irqsave(&register_lock, flags);
	for (i = 0; i < max_midi_devs; i++) {
		if ((mdev = midi_devs[i]) != NULL) {
			snd_midi_event_free(mdev->coder);
			kfree(mdev);
			midi_devs[i] = NULL;
		}
	}
	max_midi_devs = 0;
	spin_unlock_irqrestore(&register_lock, flags);
}
INT32 closeMidiDevice(MidiDeviceHandle* handle) {
    int err;

    TRACE0("> closeMidiDevice()\n");
    if (!handle) {
        ERROR0("< ERROR: closeMidiDevice(): handle is NULL\n");
        return MIDI_INVALID_HANDLE;
    }
    if (!handle->deviceHandle) {
        ERROR0("< ERROR: closeMidiDevice(): native handle is NULL\n");
        return MIDI_INVALID_HANDLE;
    }
    err = snd_rawmidi_close((snd_rawmidi_t*) handle->deviceHandle);
    TRACE1("  snd_rawmidi_close() returns %d\n", err);
    if (handle->platformData) {
        snd_midi_event_free((snd_midi_event_t*) handle->platformData);
    }
    free(handle);
    TRACE0("< closeMidiDevice: succeeded\n");
    return err;
}
예제 #20
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
}
예제 #21
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;
}
예제 #22
0
 ~MidiOutputDevice()
 {
     snd_midi_event_free (midiParser);
     snd_seq_close (seqHandle);
 }
예제 #23
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;
}
예제 #24
0
DssiPluginMidiManager::~DssiPluginMidiManager ()
{
    snd_midi_event_free (midiParser);
}
 ~MidiOutputDevice()
 {
     snd_midi_event_free (midiParser);
     port.deletePort();
 }
예제 #26
0
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;
}
예제 #27
0
void samplv1_jack::close (void)
{
#ifdef CONFIG_ALSA_MIDI
    // close alsa sequencer client...
    if (m_alsa_seq) {
        if (m_alsa_thread) {
            delete m_alsa_thread;
            m_alsa_thread = NULL;
        }
        if (m_alsa_buffer) {
            ::jack_ringbuffer_free(m_alsa_buffer);
            m_alsa_buffer = NULL;
        }
        if (m_alsa_decoder) {
            snd_midi_event_free(m_alsa_decoder);
            m_alsa_decoder = NULL;
        }
        if (m_alsa_port >= 0) {
            snd_seq_delete_simple_port(m_alsa_seq, m_alsa_port);
            m_alsa_port = -1;
        }
        snd_seq_close(m_alsa_seq);
        //	m_alsa_client = -1;
        m_alsa_seq = NULL;
    }
#endif

    if (m_client == NULL)
        return;

#ifdef CONFIG_JACK_MIDI
    // unregister midi port
    if (m_midi_in) {
        ::jack_port_unregister(m_client, m_midi_in);
        m_midi_in = NULL;
    }
#endif

    // unregister audio ports
    const uint16_t nchannels = samplv1::channels();

    for (uint16_t k = 0; k < nchannels; ++k) {
        if (m_audio_outs && m_audio_outs[k]) {
            ::jack_port_unregister(m_client, m_audio_outs[k]);
            m_audio_outs[k] = NULL;
        }
        if (m_outs && m_outs[k])
            m_outs[k] = NULL;
        if (m_audio_ins && m_audio_ins[k]) {
            ::jack_port_unregister(m_client, m_audio_ins[k]);
            m_audio_ins[k] = NULL;
        }
        if (m_ins && m_ins[k])
            m_ins[k] = NULL;
    }

    if (m_outs) {
        delete [] m_outs;
        m_outs = NULL;
    }
    if (m_ins) {
        delete [] m_ins;
        m_ins = NULL;
    }

    if (m_audio_outs) {
        delete [] m_audio_outs;
        m_audio_outs = NULL;
    }
    if (m_audio_ins) {
        delete [] m_audio_ins;
        m_audio_ins = NULL;
    }

    // close client
    ::jack_client_close(m_client);
    m_client = NULL;
}
예제 #28
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;
}
예제 #29
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;
}