summaryrefslogtreecommitdiffstats
path: root/alsa-lib/src/rawmidi/rawmidi_virt.c
diff options
context:
space:
mode:
Diffstat (limited to 'alsa-lib/src/rawmidi/rawmidi_virt.c')
-rw-r--r--alsa-lib/src/rawmidi/rawmidi_virt.c469
1 files changed, 0 insertions, 469 deletions
diff --git a/alsa-lib/src/rawmidi/rawmidi_virt.c b/alsa-lib/src/rawmidi/rawmidi_virt.c
deleted file mode 100644
index 52b8984..0000000
--- a/alsa-lib/src/rawmidi/rawmidi_virt.c
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- * RawMIDI - Virtual (sequencer mode)
- * Copyright (c) 2003 by Takashi Iwai <tiwai@suse.de>
- *
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include "rawmidi_local.h"
-#include "seq.h"
-#include "seq_midi_event.h"
-
-#ifndef PIC
-/* entry for static linking */
-const char *_snd_module_rawmidi_virt = "";
-#endif
-
-
-#ifndef DOC_HIDDEN
-typedef struct {
- int open;
-
- snd_seq_t *handle;
- int port;
-
- snd_midi_event_t *midi_event;
-
- snd_seq_event_t *in_event;
- int in_buf_size;
- int in_buf_ofs;
- char *in_buf_ptr;
- char in_tmp_buf[16];
-
- snd_seq_event_t out_event;
- int pending;
-} snd_rawmidi_virtual_t;
-
-int _snd_seq_open_lconf(snd_seq_t **seqp, const char *name,
- int streams, int mode, snd_config_t *lconf,
- snd_config_t *parent_conf);
-#endif
-
-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;
-}
-
-static int snd_rawmidi_virtual_nonblock(snd_rawmidi_t *rmidi, int nonblock)
-{
- snd_rawmidi_virtual_t *virt = rmidi->private_data;
-
- return snd_seq_nonblock(virt->handle, nonblock);
-}
-
-static int snd_rawmidi_virtual_info(snd_rawmidi_t *rmidi, snd_rawmidi_info_t * info)
-{
- // snd_rawmidi_virtual_t *virt = rmidi->private_data;
-
- info->stream = rmidi->stream;
- /* FIXME: what values should be there? */
- info->card = 0;
- info->device = 0;
- info->subdevice = 0;
- info->flags = 0;
- strcpy((char *)info->id, "Virtual");
- strcpy((char *)info->name, "Virtual RawMIDI");
- strcpy((char *)info->subname, "Virtual RawMIDI");
- info->subdevices_count = 1;
- info->subdevices_avail = 0;
- return 0;
-}
-
-static int snd_rawmidi_virtual_input_params(snd_rawmidi_virtual_t *virt, snd_rawmidi_params_t *params)
-{
- int err;
-
- // snd_rawmidi_drain_input(substream);
- if (params->buffer_size < sizeof(snd_seq_event_t) ||
- params->buffer_size > 1024L * 1024L) {
- return -EINVAL;
- }
- if (params->buffer_size != snd_seq_get_input_buffer_size(virt->handle)) {
- err = snd_seq_set_input_buffer_size(virt->handle, params->buffer_size);
- if (err < 0)
- return err;
- params->buffer_size = snd_seq_get_input_buffer_size(virt->handle);
- /* FIXME: input pool size? */
- }
- return 0;
-}
-
-
-static int snd_rawmidi_virtual_output_params(snd_rawmidi_virtual_t *virt, snd_rawmidi_params_t *params)
-{
- int err;
-
- // snd_rawmidi_drain_output(substream);
- if (params->buffer_size < sizeof(snd_seq_event_t) ||
- params->buffer_size > 1024L * 1024L) {
- return -EINVAL;
- }
- if (params->buffer_size != snd_seq_get_output_buffer_size(virt->handle)) {
- err = snd_seq_set_output_buffer_size(virt->handle, params->buffer_size);
- if (err < 0)
- return err;
- params->buffer_size = snd_seq_get_output_buffer_size(virt->handle);
- }
- return 0;
-}
-
-
-static int snd_rawmidi_virtual_params(snd_rawmidi_t *rmidi, snd_rawmidi_params_t * params)
-{
- snd_rawmidi_virtual_t *virt = rmidi->private_data;
- params->stream = rmidi->stream;
-
- if (rmidi->stream == SND_RAWMIDI_STREAM_INPUT)
- return snd_rawmidi_virtual_input_params(virt, params);
- else
- return snd_rawmidi_virtual_output_params(virt, params);
-}
-
-static int snd_rawmidi_virtual_status(snd_rawmidi_t *rmidi, snd_rawmidi_status_t * status)
-{
- // snd_rawmidi_virtual_t *virt = rmidi->private_data;
- memset(status, 0, sizeof(*status));
- status->stream = rmidi->stream;
- return 0;
-}
-
-static int snd_rawmidi_virtual_drop(snd_rawmidi_t *rmidi)
-{
- snd_rawmidi_virtual_t *virt = rmidi->private_data;
- if (rmidi->stream == SND_RAWMIDI_STREAM_OUTPUT) {
- snd_seq_drop_output(virt->handle);
- snd_midi_event_reset_encode(virt->midi_event);
- virt->pending = 0;
- } else {
- snd_seq_drop_input(virt->handle);
- snd_midi_event_reset_decode(virt->midi_event);
- virt->in_buf_ofs = 0;
- }
- return 0;
-}
-
-static int snd_rawmidi_virtual_drain(snd_rawmidi_t *rmidi)
-{
- snd_rawmidi_virtual_t *virt = rmidi->private_data;
- int err;
-
- if (rmidi->stream == SND_RAWMIDI_STREAM_OUTPUT) {
- if (virt->pending) {
- err = snd_seq_event_output(virt->handle, &virt->out_event);
- if (err < 0)
- return err;
- virt->pending = 0;
- }
- snd_seq_drain_output(virt->handle);
- snd_seq_sync_output_queue(virt->handle);
- }
- return snd_rawmidi_virtual_drop(rmidi);
-}
-
-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;
-}
-
-static ssize_t snd_rawmidi_virtual_read(snd_rawmidi_t *rmidi, void *buffer, size_t size)
-{
- snd_rawmidi_virtual_t *virt = rmidi->private_data;
- ssize_t result = 0;
- int size1, err;
-
- while (size > 0) {
- if (! virt->in_buf_ofs) {
- err = snd_seq_event_input_pending(virt->handle, 1);
- if (err <= 0 && result > 0)
- return result;
- err = snd_seq_event_input(virt->handle, &virt->in_event);
- if (err < 0)
- return result > 0 ? result : err;
-
- if (virt->in_event->type == SND_SEQ_EVENT_SYSEX) {
- virt->in_buf_ptr = virt->in_event->data.ext.ptr;
- virt->in_buf_size = virt->in_event->data.ext.len;
- } else {
- virt->in_buf_ptr = virt->in_tmp_buf;
- virt->in_buf_size = snd_midi_event_decode(virt->midi_event,
- (unsigned char *)virt->in_tmp_buf,
- sizeof(virt->in_tmp_buf),
- virt->in_event);
- }
- if (virt->in_buf_size <= 0)
- continue;
- }
- size1 = virt->in_buf_size - virt->in_buf_ofs;
- if ((size_t)size1 > size) {
- virt->in_buf_ofs += size1 - size;
- memcpy(buffer, virt->in_buf_ptr, size);
- result += size;
- break;
- }
- memcpy(buffer, virt->in_buf_ptr + virt->in_buf_ofs, size1);
- size -= size1;
- result += size1;
- buffer += size1;
- virt->in_buf_ofs = 0;
- }
-
- return result;
-}
-
-static const snd_rawmidi_ops_t snd_rawmidi_virtual_ops = {
- .close = snd_rawmidi_virtual_close,
- .nonblock = snd_rawmidi_virtual_nonblock,
- .info = snd_rawmidi_virtual_info,
- .params = snd_rawmidi_virtual_params,
- .status = snd_rawmidi_virtual_status,
- .drop = snd_rawmidi_virtual_drop,
- .drain = snd_rawmidi_virtual_drain,
- .write = snd_rawmidi_virtual_write,
- .read = snd_rawmidi_virtual_read,
-};
-
-
-/*! \page rawmidi RawMidi interface
-
-\section rawmidi_virt Virtual RawMidi interface
-
-The "virtual" plugin creates a virtual RawMidi instance on the ALSA
-sequencer, which can be accessed through the connection of the sequencer
-ports.
-There is no connection established as default.
-
-For creating a virtual RawMidi instance, pass "virtual" as its name at
-creation.
-
-Example:
-\code
-snd_rawmidi_open(&read_handle, &write_handle, "virtual", 0);
-\endcode
-
-*/
-
-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->midi_event)
- snd_midi_event_free(virt->midi_event);
- free(virt);
- if (inputp)
- free(*inputp);
- if (outputp)
- free(*outputp);
- return err;
-}
-
-int _snd_rawmidi_virtual_open(snd_rawmidi_t **inputp, snd_rawmidi_t **outputp,
- char *name, snd_config_t *root ATTRIBUTE_UNUSED,
- snd_config_t *conf, int mode)
-{
- snd_config_iterator_t i, next;
- const char *slave_str = NULL;
- int err;
- int streams, seq_mode;
- int merge = 1;
- int port;
- unsigned int caps;
- snd_seq_t *seq_handle;
-
- snd_config_for_each(i, next, conf) {
- snd_config_t *n = snd_config_iterator_entry(i);
- const char *id;
- if (snd_config_get_id(n, &id) < 0)
- continue;
- if (snd_rawmidi_conf_generic_id(id))
- continue;
- if (strcmp(id, "slave") == 0) {
- err = snd_config_get_string(n, &slave_str);
- if (err < 0)
- return err;
- continue;
- }
- if (strcmp(id, "merge") == 0) {
- merge = snd_config_get_bool(n);
- continue;
- }
- return -EINVAL;
- }
-
- streams = 0;
- if (inputp)
- streams |= SND_SEQ_OPEN_INPUT;
- if (outputp)
- streams |= SND_SEQ_OPEN_OUTPUT;
- if (! streams)
- return -EINVAL;
-
- seq_mode = 0;
- if (mode & SND_RAWMIDI_NONBLOCK)
- seq_mode |= SND_SEQ_NONBLOCK;
-
- if (! slave_str)
- slave_str = "default";
- err = _snd_seq_open_lconf(&seq_handle, slave_str, streams, seq_mode,
- root, conf);
- if (err < 0)
- return err;
-
- caps = 0;
- if (inputp)
- caps |= SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SYNC_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE;
- if (outputp)
- caps |= SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SYNC_READ | SND_SEQ_PORT_CAP_SUBS_READ;
- if (inputp && outputp)
- caps |= SNDRV_SEQ_PORT_CAP_DUPLEX;
-
- port = snd_seq_create_simple_port(seq_handle, "Virtual RawMIDI",
- caps, SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC);
- if (port < 0) {
- snd_seq_close(seq_handle);
- return port;
- }
-
- return snd_rawmidi_virtual_open(inputp, outputp, name, seq_handle, port,
- merge, mode);
-}
-
-#ifndef DOC_HIDDEN
-SND_DLSYM_BUILD_VERSION(_snd_rawmidi_virtual_open, SND_RAWMIDI_DLSYM_VERSION);
-#endif