mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-11-02 09:01:48 -05:00
Merged pcmfinal branch.
This commit is contained in:
parent
3cc2b957fb
commit
41bb7068f2
57 changed files with 5189 additions and 3088 deletions
|
|
@ -1,7 +1,7 @@
|
|||
EXTRA_LTLIBRARIES=libseq.la
|
||||
|
||||
libseq_la_SOURCES = seq.c seqmid.c
|
||||
noinst_HEADERS = seq_priv.h
|
||||
libseq_la_SOURCES = seq_hw.c seq.c seqmid.c
|
||||
noinst_HEADERS = seq_local.h
|
||||
|
||||
all: libseq.la
|
||||
|
||||
|
|
|
|||
574
src/seq/seq.c
574
src/seq/seq.c
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Sequencer Interface - main file
|
||||
* Copyright (c) 1998 by Jaroslav Kysela <perex@suse.cz>
|
||||
* Copyright (c) 2000 by Jaroslav Kysela <perex@suse.cz>
|
||||
* Abramo Bagnara <abramo@alsa-project.org>
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
|
|
@ -19,81 +20,114 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/poll.h>
|
||||
#include <dlfcn.h>
|
||||
#include "seq_local.h"
|
||||
#include "asoundlib.h"
|
||||
#include "seq_priv.h"
|
||||
|
||||
#define SND_FILE_SEQ "/dev/snd/seq"
|
||||
#define SND_FILE_ALOADSEQ "/dev/aloadSEQ"
|
||||
#define SND_SEQ_VERSION_MAX SND_PROTOCOL_VERSION(1, 0, 0)
|
||||
#define SND_SEQ_OBUF_SIZE (16*1024) /* default size */
|
||||
#define SND_SEQ_IBUF_SIZE 500 /* in event_size aligned */
|
||||
#define DEFAULT_TMPBUF_SIZE 20
|
||||
|
||||
/*
|
||||
* open a sequencer device so that it creates a user-client.
|
||||
*/
|
||||
int snd_seq_open(snd_seq_t **handle, int mode)
|
||||
int snd_seq_open(snd_seq_t **seqp, char *name,
|
||||
int streams, int mode)
|
||||
{
|
||||
int fd, ver, client, flg;
|
||||
char filename[32];
|
||||
snd_seq_t *seq;
|
||||
|
||||
*handle = NULL;
|
||||
|
||||
sprintf(filename, SND_FILE_SEQ);
|
||||
if ((fd = open(filename, mode)) < 0) {
|
||||
close(open(SND_FILE_ALOADSEQ, O_RDWR));
|
||||
if ((fd = open(filename, mode)) < 0)
|
||||
return -errno;
|
||||
char *str;
|
||||
int err;
|
||||
snd_config_t *seq_conf, *conf, *type_conf;
|
||||
snd_config_iterator_t i;
|
||||
char *lib = NULL, *open = NULL;
|
||||
int (*open_func)(snd_seq_t **seqp, char *name, snd_config_t *conf,
|
||||
int streams, int mode);
|
||||
void *h;
|
||||
assert(seqp && name);
|
||||
err = snd_config_update();
|
||||
if (err < 0)
|
||||
return err;
|
||||
err = snd_config_searchv(snd_config, &seq_conf, "seq", name, 0);
|
||||
if (err < 0) {
|
||||
if (strcmp(name, "hw") == 0)
|
||||
return snd_seq_hw_open(seqp, name, streams, mode);
|
||||
ERR("Unknown SEQ %s", name);
|
||||
return -ENOENT;
|
||||
}
|
||||
if (ioctl(fd, SND_SEQ_IOCTL_PVERSION, &ver) < 0) {
|
||||
close(fd);
|
||||
return -errno;
|
||||
if (snd_config_type(seq_conf) != SND_CONFIG_TYPE_COMPOUND) {
|
||||
ERR("Invalid type for SEQ definition");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (SND_PROTOCOL_INCOMPATIBLE(ver, SND_SEQ_VERSION_MAX)) {
|
||||
close(fd);
|
||||
return -SND_ERROR_INCOMPATIBLE_VERSION;
|
||||
err = snd_config_search(seq_conf, "streams", &conf);
|
||||
if (err >= 0) {
|
||||
err = snd_config_string_get(conf, &str);
|
||||
if (err < 0) {
|
||||
ERR("Invalid type for streams");
|
||||
return err;
|
||||
}
|
||||
if (strcmp(str, "output") == 0) {
|
||||
if (streams == SND_SEQ_OPEN_INPUT)
|
||||
return -EINVAL;
|
||||
} else if (strcmp(str, "input") == 0) {
|
||||
if (streams == SND_SEQ_OPEN_OUTPUT)
|
||||
return -EINVAL;
|
||||
} else if (strcmp(str, "duplex") == 0) {
|
||||
if (streams != SND_SEQ_OPEN_DUPLEX)
|
||||
return -EINVAL;
|
||||
} else {
|
||||
ERR("Invalid value for streams");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
if (ioctl(fd, SND_SEQ_IOCTL_CLIENT_ID, &client) < 0) {
|
||||
close(fd);
|
||||
return -errno;
|
||||
err = snd_config_search(seq_conf, "type", &conf);
|
||||
if (err < 0) {
|
||||
ERR("type is not defined");
|
||||
return err;
|
||||
}
|
||||
seq = (snd_seq_t *) calloc(1, sizeof(snd_seq_t));
|
||||
if (seq == NULL) {
|
||||
close(fd);
|
||||
return -ENOMEM;
|
||||
err = snd_config_string_get(conf, &str);
|
||||
if (err < 0) {
|
||||
ERR("Invalid type for type");
|
||||
return err;
|
||||
}
|
||||
seq->client = client;
|
||||
seq->fd = fd;
|
||||
flg = 3;
|
||||
if (mode == SND_SEQ_OPEN_OUT || mode == SND_SEQ_OPEN)
|
||||
seq->obuf = (char *) malloc(seq->obufsize = SND_SEQ_OBUF_SIZE);
|
||||
else
|
||||
flg &= ~1;
|
||||
if (mode == SND_SEQ_OPEN_IN || mode == SND_SEQ_OPEN)
|
||||
seq->ibuf = (snd_seq_event_t *) calloc(sizeof(snd_seq_event_t), seq->ibufsize = SND_SEQ_IBUF_SIZE);
|
||||
else
|
||||
flg &= ~2;
|
||||
if ((!seq->obuf && (flg & 1)) || (!seq->ibuf && (flg & 2))) {
|
||||
if (seq->obuf)
|
||||
free(seq->obuf);
|
||||
if (seq->ibuf)
|
||||
free(seq->ibuf);
|
||||
free(seq);
|
||||
return -ENOMEM;
|
||||
err = snd_config_searchv(snd_config, &type_conf, "seqtype", str, 0);
|
||||
if (err < 0) {
|
||||
ERR("Unknown SEQ type %s", str);
|
||||
return err;
|
||||
}
|
||||
seq->tmpbuf = NULL;
|
||||
seq->tmpbufsize = 0;
|
||||
*handle = seq;
|
||||
return 0;
|
||||
snd_config_foreach(i, type_conf) {
|
||||
snd_config_t *n = snd_config_entry(i);
|
||||
if (strcmp(n->id, "comment") == 0)
|
||||
continue;
|
||||
if (strcmp(n->id, "lib") == 0) {
|
||||
err = snd_config_string_get(n, &lib);
|
||||
if (err < 0) {
|
||||
ERR("Invalid type for lib");
|
||||
return -EINVAL;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (strcmp(n->id, "open") == 0) {
|
||||
err = snd_config_string_get(n, &open);
|
||||
if (err < 0) {
|
||||
ERR("Invalid type for open");
|
||||
return -EINVAL;
|
||||
}
|
||||
continue;
|
||||
ERR("Unknown field: %s", n->id);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
if (!open) {
|
||||
ERR("open is not defined");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!lib)
|
||||
lib = "libasound.so";
|
||||
h = dlopen(lib, RTLD_NOW);
|
||||
if (!h) {
|
||||
ERR("Cannot open shared library %s", lib);
|
||||
return -ENOENT;
|
||||
}
|
||||
open_func = dlsym(h, open);
|
||||
dlclose(h);
|
||||
if (!open_func) {
|
||||
ERR("symbol %s is not defined inside %s", open, lib);
|
||||
return -ENXIO;
|
||||
}
|
||||
return open_func(seqp, name, seq_conf, streams, mode);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -101,19 +135,21 @@ int snd_seq_open(snd_seq_t **handle, int mode)
|
|||
*/
|
||||
int snd_seq_close(snd_seq_t *seq)
|
||||
{
|
||||
int res;
|
||||
|
||||
if (!seq)
|
||||
return -EINVAL;
|
||||
res = close(seq->fd) < 0 ? -errno : 0;
|
||||
int err;
|
||||
assert(seq);
|
||||
err = seq->ops->close(seq);
|
||||
if (err < 0)
|
||||
return err;
|
||||
if (seq->obuf)
|
||||
free(seq->obuf);
|
||||
if (seq->ibuf)
|
||||
free(seq->ibuf);
|
||||
if (seq->tmpbuf)
|
||||
free(seq->tmpbuf);
|
||||
if (seq->name)
|
||||
free(seq->name);
|
||||
free(seq);
|
||||
return res;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -121,28 +157,24 @@ int snd_seq_close(snd_seq_t *seq)
|
|||
*/
|
||||
int snd_seq_poll_descriptor(snd_seq_t *seq)
|
||||
{
|
||||
if (!seq)
|
||||
return -EINVAL;
|
||||
return seq->fd;
|
||||
assert(seq);
|
||||
return seq->poll_fd;
|
||||
}
|
||||
|
||||
/*
|
||||
* set blocking behavior
|
||||
*/
|
||||
int snd_seq_block_mode(snd_seq_t *seq, int enable)
|
||||
int snd_seq_nonblock(snd_seq_t *seq, int nonblock)
|
||||
{
|
||||
long flags;
|
||||
|
||||
if (!seq)
|
||||
return -EINVAL;
|
||||
if ((flags = fcntl(seq->fd, F_GETFL)) < 0)
|
||||
return -errno;
|
||||
if (enable)
|
||||
flags &= ~O_NONBLOCK;
|
||||
int err;
|
||||
assert(seq);
|
||||
err = seq->ops->nonblock(seq, nonblock);
|
||||
if (err < 0)
|
||||
return err;
|
||||
if (nonblock)
|
||||
seq->mode |= SND_SEQ_NONBLOCK;
|
||||
else
|
||||
flags |= O_NONBLOCK;
|
||||
if (fcntl(seq->fd, F_SETFL, flags) < 0)
|
||||
return -errno;
|
||||
seq->mode &= ~SND_SEQ_NONBLOCK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -151,8 +183,7 @@ int snd_seq_block_mode(snd_seq_t *seq, int enable)
|
|||
*/
|
||||
int snd_seq_client_id(snd_seq_t *seq)
|
||||
{
|
||||
if (!seq)
|
||||
return -EINVAL;
|
||||
assert(seq);
|
||||
return seq->client;
|
||||
}
|
||||
|
||||
|
|
@ -161,8 +192,7 @@ int snd_seq_client_id(snd_seq_t *seq)
|
|||
*/
|
||||
int snd_seq_output_buffer_size(snd_seq_t *seq)
|
||||
{
|
||||
if (!seq)
|
||||
return -EINVAL;
|
||||
assert(seq);
|
||||
if (!seq->obuf)
|
||||
return 0;
|
||||
return seq->obufsize;
|
||||
|
|
@ -173,8 +203,7 @@ int snd_seq_output_buffer_size(snd_seq_t *seq)
|
|||
*/
|
||||
int snd_seq_input_buffer_size(snd_seq_t *seq)
|
||||
{
|
||||
if (!seq)
|
||||
return -EINVAL;
|
||||
assert(seq);
|
||||
if (!seq->ibuf)
|
||||
return 0;
|
||||
return seq->ibufsize * sizeof(snd_seq_event_t);
|
||||
|
|
@ -185,10 +214,8 @@ int snd_seq_input_buffer_size(snd_seq_t *seq)
|
|||
*/
|
||||
int snd_seq_resize_output_buffer(snd_seq_t *seq, size_t size)
|
||||
{
|
||||
if (!seq || !seq->obuf)
|
||||
return -EINVAL;
|
||||
if (size < sizeof(snd_seq_event_t))
|
||||
return -EINVAL;
|
||||
assert(seq && seq->obuf);
|
||||
assert(size >= sizeof(snd_seq_event_t));
|
||||
snd_seq_drop_output(seq);
|
||||
if (size != seq->obufsize) {
|
||||
char *newbuf;
|
||||
|
|
@ -207,10 +234,8 @@ int snd_seq_resize_output_buffer(snd_seq_t *seq, size_t size)
|
|||
*/
|
||||
int snd_seq_resize_input_buffer(snd_seq_t *seq, size_t size)
|
||||
{
|
||||
if (!seq || !seq->ibuf)
|
||||
return -EINVAL;
|
||||
if (size < sizeof(snd_seq_event_t))
|
||||
return -EINVAL;
|
||||
assert(seq && seq->ibuf);
|
||||
assert(size >= sizeof(snd_seq_event_t));
|
||||
snd_seq_drop_input(seq);
|
||||
size = (size + sizeof(snd_seq_event_t) - 1) / sizeof(snd_seq_event_t);
|
||||
if (size != seq->ibufsize) {
|
||||
|
|
@ -230,21 +255,8 @@ int snd_seq_resize_input_buffer(snd_seq_t *seq, size_t size)
|
|||
*/
|
||||
int snd_seq_system_info(snd_seq_t *seq, snd_seq_system_info_t * info)
|
||||
{
|
||||
if (!seq || !info)
|
||||
return -EINVAL;
|
||||
if (ioctl(seq->fd, SND_SEQ_IOCTL_SYSTEM_INFO, info) < 0)
|
||||
return -errno;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* obtain the current client information
|
||||
*/
|
||||
int snd_seq_get_client_info(snd_seq_t *seq, snd_seq_client_info_t * info)
|
||||
{
|
||||
if (!seq || !info)
|
||||
return -EINVAL;
|
||||
return snd_seq_get_any_client_info(seq, seq->client, info);
|
||||
assert(seq && info);
|
||||
return seq->ops->system_info(seq, info);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -252,13 +264,18 @@ int snd_seq_get_client_info(snd_seq_t *seq, snd_seq_client_info_t * info)
|
|||
*/
|
||||
int snd_seq_get_any_client_info(snd_seq_t *seq, int client, snd_seq_client_info_t * info)
|
||||
{
|
||||
if (!seq || !info || client < 0)
|
||||
return -EINVAL;
|
||||
bzero(info, sizeof(snd_seq_client_info_t));
|
||||
assert(seq && info && client >= 0);
|
||||
memset(info, 0, sizeof(snd_seq_client_info_t));
|
||||
info->client = client;
|
||||
if (ioctl(seq->fd, SND_SEQ_IOCTL_GET_CLIENT_INFO, info) < 0)
|
||||
return -errno;
|
||||
return 0;
|
||||
return seq->ops->get_client_info(seq, info);
|
||||
}
|
||||
|
||||
/*
|
||||
* obtain the current client information
|
||||
*/
|
||||
int snd_seq_get_client_info(snd_seq_t *seq, snd_seq_client_info_t * info)
|
||||
{
|
||||
return snd_seq_get_any_client_info(seq, seq->client, info);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -266,13 +283,10 @@ int snd_seq_get_any_client_info(snd_seq_t *seq, int client, snd_seq_client_info_
|
|||
*/
|
||||
int snd_seq_set_client_info(snd_seq_t *seq, snd_seq_client_info_t * info)
|
||||
{
|
||||
if (!seq || !info)
|
||||
return -EINVAL;
|
||||
assert(seq && info);
|
||||
info->client = seq->client;
|
||||
info->type = USER_CLIENT;
|
||||
if (ioctl(seq->fd, SND_SEQ_IOCTL_SET_CLIENT_INFO, info) < 0)
|
||||
return -errno;
|
||||
return 0;
|
||||
return seq->ops->set_client_info(seq, info);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
|
|
@ -283,51 +297,37 @@ int snd_seq_set_client_info(snd_seq_t *seq, snd_seq_client_info_t * info)
|
|||
|
||||
int snd_seq_create_port(snd_seq_t *seq, snd_seq_port_info_t * port)
|
||||
{
|
||||
if (!seq || !port)
|
||||
return -EINVAL;
|
||||
assert(seq && port);
|
||||
port->client = seq->client;
|
||||
if (ioctl(seq->fd, SND_SEQ_IOCTL_CREATE_PORT, port) < 0)
|
||||
return -errno;
|
||||
return 0;
|
||||
return seq->ops->create_port(seq, port);
|
||||
}
|
||||
|
||||
int snd_seq_delete_port(snd_seq_t *seq, snd_seq_port_info_t * port)
|
||||
{
|
||||
if (!seq || !port)
|
||||
return -EINVAL;
|
||||
assert(seq && port);
|
||||
port->client = seq->client;
|
||||
if (ioctl(seq->fd, SND_SEQ_IOCTL_DELETE_PORT, port) < 0)
|
||||
return -errno;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int snd_seq_get_port_info(snd_seq_t *seq, int port, snd_seq_port_info_t * info)
|
||||
{
|
||||
if (!seq || !info || port < 0)
|
||||
return -EINVAL;
|
||||
return snd_seq_get_any_port_info(seq, seq->client, port, info);
|
||||
return seq->ops->delete_port(seq, port);
|
||||
}
|
||||
|
||||
int snd_seq_get_any_port_info(snd_seq_t *seq, int client, int port, snd_seq_port_info_t * info)
|
||||
{
|
||||
if (!seq || !info || client < 0 || port < 0)
|
||||
return -EINVAL;
|
||||
bzero(info, sizeof(snd_seq_port_info_t));
|
||||
assert(seq && info && client >= 0 && port >= 0);
|
||||
memset(info, 0, sizeof(snd_seq_port_info_t));
|
||||
info->client = client;
|
||||
info->port = port;
|
||||
if (ioctl(seq->fd, SND_SEQ_IOCTL_GET_PORT_INFO, info) < 0)
|
||||
return -errno;
|
||||
return 0;
|
||||
return seq->ops->get_port_info(seq, info);
|
||||
}
|
||||
|
||||
int snd_seq_get_port_info(snd_seq_t *seq, int port, snd_seq_port_info_t * info)
|
||||
{
|
||||
return snd_seq_get_any_port_info(seq, seq->client, port, info);
|
||||
}
|
||||
|
||||
int snd_seq_set_port_info(snd_seq_t *seq, int port, snd_seq_port_info_t * info)
|
||||
{
|
||||
if (!seq || !info || port < 0)
|
||||
return -EINVAL;
|
||||
assert(seq && info && port >= 0);
|
||||
info->port = port;
|
||||
if (ioctl(seq->fd, SND_SEQ_IOCTL_SET_PORT_INFO, info) < 0)
|
||||
return -errno;
|
||||
return 0;
|
||||
return seq->ops->set_port_info(seq, info);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
|
|
@ -338,38 +338,26 @@ int snd_seq_set_port_info(snd_seq_t *seq, int port, snd_seq_port_info_t * info)
|
|||
|
||||
int snd_seq_get_port_subscription(snd_seq_t *seq, snd_seq_port_subscribe_t * sub)
|
||||
{
|
||||
if (!seq || !sub)
|
||||
return -EINVAL;
|
||||
if (ioctl(seq->fd, SND_SEQ_IOCTL_GET_SUBSCRIPTION, sub) < 0)
|
||||
return -errno;
|
||||
return 0;
|
||||
assert(seq && sub);
|
||||
return seq->ops->get_port_subscription(seq, sub);
|
||||
}
|
||||
|
||||
int snd_seq_subscribe_port(snd_seq_t *seq, snd_seq_port_subscribe_t * sub)
|
||||
{
|
||||
if (!seq || !sub)
|
||||
return -EINVAL;
|
||||
if (ioctl(seq->fd, SND_SEQ_IOCTL_SUBSCRIBE_PORT, sub) < 0)
|
||||
return -errno;
|
||||
return 0;
|
||||
assert(seq && sub);
|
||||
return seq->ops->subscribe_port(seq, sub);
|
||||
}
|
||||
|
||||
int snd_seq_unsubscribe_port(snd_seq_t *seq, snd_seq_port_subscribe_t * sub)
|
||||
{
|
||||
if (!seq || !sub)
|
||||
return -EINVAL;
|
||||
if (ioctl(seq->fd, SND_SEQ_IOCTL_UNSUBSCRIBE_PORT, sub) < 0)
|
||||
return -errno;
|
||||
return 0;
|
||||
assert(seq && sub);
|
||||
return seq->ops->unsubscribe_port(seq, sub);
|
||||
}
|
||||
|
||||
int snd_seq_query_port_subscribers(snd_seq_t *seq, snd_seq_query_subs_t * subs)
|
||||
{
|
||||
if (!seq || !subs)
|
||||
return -EINVAL;
|
||||
if (ioctl(seq->fd, SND_SEQ_IOCTL_QUERY_SUBS, subs) < 0)
|
||||
return -errno;
|
||||
return 0;
|
||||
assert(seq && subs);
|
||||
return seq->ops->query_port_subscribers(seq, subs);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
|
|
@ -380,118 +368,88 @@ int snd_seq_query_port_subscribers(snd_seq_t *seq, snd_seq_query_subs_t * subs)
|
|||
|
||||
int snd_seq_get_queue_status(snd_seq_t *seq, int q, snd_seq_queue_status_t * status)
|
||||
{
|
||||
if (!seq || !status)
|
||||
return -EINVAL;
|
||||
bzero(status, sizeof(snd_seq_queue_status_t));
|
||||
assert(seq && status);
|
||||
memset(status, 0, sizeof(snd_seq_queue_status_t));
|
||||
status->queue = q;
|
||||
if (ioctl(seq->fd, SND_SEQ_IOCTL_GET_QUEUE_STATUS, status) < 0)
|
||||
return -errno;
|
||||
return 0;
|
||||
return seq->ops->get_queue_status(seq, status);
|
||||
}
|
||||
|
||||
int snd_seq_get_queue_tempo(snd_seq_t *seq, int q, snd_seq_queue_tempo_t * tempo)
|
||||
{
|
||||
if (!seq || !tempo)
|
||||
return -EINVAL;
|
||||
bzero(tempo, sizeof(snd_seq_queue_tempo_t));
|
||||
assert(seq && tempo);
|
||||
memset(tempo, 0, sizeof(snd_seq_queue_tempo_t));
|
||||
tempo->queue = q;
|
||||
if (ioctl(seq->fd, SND_SEQ_IOCTL_GET_QUEUE_TEMPO, tempo) < 0)
|
||||
return -errno;
|
||||
return 0;
|
||||
return seq->ops->get_queue_tempo(seq, tempo);
|
||||
}
|
||||
|
||||
int snd_seq_set_queue_tempo(snd_seq_t *seq, int q, snd_seq_queue_tempo_t * tempo)
|
||||
{
|
||||
if (!seq || !tempo)
|
||||
return -EINVAL;
|
||||
assert(seq && tempo);
|
||||
tempo->queue = q;
|
||||
if (ioctl(seq->fd, SND_SEQ_IOCTL_SET_QUEUE_TEMPO, tempo) < 0)
|
||||
return -errno;
|
||||
return 0;
|
||||
return seq->ops->set_queue_tempo(seq, tempo);
|
||||
}
|
||||
|
||||
int snd_seq_get_queue_owner(snd_seq_t *seq, int q, snd_seq_queue_owner_t * owner)
|
||||
{
|
||||
if (!seq || !owner)
|
||||
return -EINVAL;
|
||||
bzero(owner, sizeof(snd_seq_queue_owner_t));
|
||||
assert(seq && owner);
|
||||
memset(owner, 0, sizeof(snd_seq_queue_owner_t));
|
||||
owner->queue = q;
|
||||
if (ioctl(seq->fd, SND_SEQ_IOCTL_GET_QUEUE_OWNER, owner) < 0)
|
||||
return -errno;
|
||||
return 0;
|
||||
return seq->ops->get_queue_owner(seq, owner);
|
||||
}
|
||||
|
||||
int snd_seq_set_queue_owner(snd_seq_t *seq, int q, snd_seq_queue_owner_t * owner)
|
||||
{
|
||||
if (!seq || !owner)
|
||||
return -EINVAL;
|
||||
assert(seq && owner);
|
||||
owner->queue = q;
|
||||
if (ioctl(seq->fd, SND_SEQ_IOCTL_SET_QUEUE_OWNER, owner) < 0)
|
||||
return -errno;
|
||||
return 0;
|
||||
return seq->ops->set_queue_owner(seq, owner);
|
||||
}
|
||||
|
||||
int snd_seq_get_queue_timer(snd_seq_t *seq, int q, snd_seq_queue_timer_t * timer)
|
||||
{
|
||||
if (!seq || !timer)
|
||||
return -EINVAL;
|
||||
bzero(timer, sizeof(snd_seq_queue_timer_t));
|
||||
assert(seq && timer);
|
||||
memset(timer, 0, sizeof(snd_seq_queue_timer_t));
|
||||
timer->queue = q;
|
||||
if (ioctl(seq->fd, SND_SEQ_IOCTL_GET_QUEUE_TIMER, timer) < 0)
|
||||
return -errno;
|
||||
return 0;
|
||||
return seq->ops->get_queue_timer(seq, timer);
|
||||
}
|
||||
|
||||
int snd_seq_set_queue_timer(snd_seq_t *seq, int q, snd_seq_queue_timer_t * timer)
|
||||
{
|
||||
if (!seq || !timer)
|
||||
return -EINVAL;
|
||||
assert(seq && timer);
|
||||
timer->queue = q;
|
||||
if (ioctl(seq->fd, SND_SEQ_IOCTL_SET_QUEUE_TIMER, timer) < 0)
|
||||
return -errno;
|
||||
return 0;
|
||||
return seq->ops->set_queue_timer(seq, timer);
|
||||
}
|
||||
|
||||
int snd_seq_get_queue_client(snd_seq_t *seq, int q, snd_seq_queue_client_t * info)
|
||||
{
|
||||
if (!seq || !info)
|
||||
return -EINVAL;
|
||||
bzero(info, sizeof(snd_seq_queue_client_t));
|
||||
assert(seq && info);
|
||||
memset(info, 0, sizeof(snd_seq_queue_client_t));
|
||||
info->queue = q;
|
||||
info->client = seq->client;
|
||||
if (ioctl(seq->fd, SND_SEQ_IOCTL_GET_QUEUE_CLIENT, info) < 0)
|
||||
return -errno;
|
||||
return 0;
|
||||
return seq->ops->get_queue_client(seq, info);
|
||||
}
|
||||
|
||||
int snd_seq_set_queue_client(snd_seq_t *seq, int q, snd_seq_queue_client_t * info)
|
||||
{
|
||||
if (!seq || !info)
|
||||
return -EINVAL;
|
||||
assert(seq && info);
|
||||
info->queue = q;
|
||||
info->client = seq->client;
|
||||
if (ioctl(seq->fd, SND_SEQ_IOCTL_SET_QUEUE_CLIENT, info) < 0)
|
||||
return -errno;
|
||||
return 0;
|
||||
return seq->ops->set_queue_client(seq, info);
|
||||
}
|
||||
|
||||
int snd_seq_create_queue(snd_seq_t *seq, snd_seq_queue_info_t *info)
|
||||
{
|
||||
if (!seq)
|
||||
return -EINVAL;
|
||||
int err;
|
||||
assert(seq && info);
|
||||
info->owner = seq->client;
|
||||
if (ioctl(seq->fd, SND_SEQ_IOCTL_CREATE_QUEUE, info) < 0)
|
||||
return -errno;
|
||||
err = seq->ops->create_queue(seq, info);
|
||||
if (err < 0)
|
||||
return err;
|
||||
return info->queue;
|
||||
}
|
||||
|
||||
int snd_seq_alloc_named_queue(snd_seq_t *seq, char *name)
|
||||
{
|
||||
snd_seq_queue_info_t info;
|
||||
|
||||
if (!seq)
|
||||
return -EINVAL;
|
||||
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.locked = 1;
|
||||
if (name)
|
||||
|
|
@ -508,10 +466,6 @@ int snd_seq_alloc_queue(snd_seq_t *seq)
|
|||
int snd_seq_alloc_sync_queue(snd_seq_t *seq, char *name)
|
||||
{
|
||||
snd_seq_queue_info_t info;
|
||||
|
||||
if (!seq)
|
||||
return -EINVAL;
|
||||
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.locked = 1;
|
||||
if (name)
|
||||
|
|
@ -524,47 +478,35 @@ int snd_seq_alloc_sync_queue(snd_seq_t *seq, char *name)
|
|||
int snd_seq_free_queue(snd_seq_t *seq, int q)
|
||||
{
|
||||
snd_seq_queue_info_t info;
|
||||
|
||||
if (!seq)
|
||||
return -EINVAL;
|
||||
|
||||
assert(seq);
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.queue = q;
|
||||
if (ioctl(seq->fd, SND_SEQ_IOCTL_DELETE_QUEUE, &info) < 0)
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
return seq->ops->delete_queue(seq, &info);
|
||||
}
|
||||
|
||||
int snd_seq_get_queue_info(snd_seq_t *seq, int q, snd_seq_queue_info_t *info)
|
||||
{
|
||||
if (!seq || !info)
|
||||
return -EINVAL;
|
||||
assert(seq && info);
|
||||
info->queue = q;
|
||||
if (ioctl(seq->fd, SND_SEQ_IOCTL_GET_QUEUE_INFO, info) < 0)
|
||||
return -errno;
|
||||
return 0;
|
||||
return seq->ops->get_queue_info(seq, info);
|
||||
}
|
||||
|
||||
int snd_seq_set_queue_info(snd_seq_t *seq, int q, snd_seq_queue_info_t *info)
|
||||
{
|
||||
if (!seq || !info)
|
||||
return -EINVAL;
|
||||
assert(seq && info);
|
||||
info->queue = q;
|
||||
if (ioctl(seq->fd, SND_SEQ_IOCTL_SET_QUEUE_INFO, info) < 0)
|
||||
return -errno;
|
||||
return 0;
|
||||
return seq->ops->set_queue_info(seq, info);
|
||||
}
|
||||
|
||||
int snd_seq_get_named_queue(snd_seq_t *seq, char *name)
|
||||
{
|
||||
int err;
|
||||
snd_seq_queue_info_t info;
|
||||
|
||||
if (!seq)
|
||||
return -EINVAL;
|
||||
assert(seq && name);
|
||||
strncpy(info.name, name, sizeof(info.name));
|
||||
if (ioctl(seq->fd, SND_SEQ_IOCTL_GET_NAMED_QUEUE, &info) < 0)
|
||||
return -errno;
|
||||
err = seq->ops->get_named_queue(seq, &info);
|
||||
if (err < 0)
|
||||
return err;
|
||||
return info.queue;
|
||||
}
|
||||
|
||||
|
|
@ -687,9 +629,7 @@ int snd_seq_free_event(snd_seq_event_t *ev ATTRIBUTE_UNUSED)
|
|||
ssize_t snd_seq_event_length(snd_seq_event_t *ev)
|
||||
{
|
||||
ssize_t len = sizeof(snd_seq_event_t);
|
||||
|
||||
if (!ev)
|
||||
return -EINVAL;
|
||||
assert(ev);
|
||||
if (snd_seq_ev_is_variable(ev))
|
||||
len += ev->data.ext.len;
|
||||
return len;
|
||||
|
|
@ -726,9 +666,7 @@ int snd_seq_event_output(snd_seq_t *seq, snd_seq_event_t *ev)
|
|||
int snd_seq_event_output_buffer(snd_seq_t *seq, snd_seq_event_t *ev)
|
||||
{
|
||||
int len;
|
||||
|
||||
if (!seq || !ev)
|
||||
return -EINVAL;
|
||||
assert(seq && ev);
|
||||
len = snd_seq_event_length(ev);
|
||||
if (len < 0)
|
||||
return -EINVAL;
|
||||
|
|
@ -773,7 +711,7 @@ static int alloc_tmpbuf(snd_seq_t *seq, size_t len)
|
|||
*/
|
||||
int snd_seq_event_output_direct(snd_seq_t *seq, snd_seq_event_t *ev)
|
||||
{
|
||||
ssize_t len, result;
|
||||
ssize_t len;
|
||||
void *buf;
|
||||
|
||||
len = snd_seq_event_length(ev);
|
||||
|
|
@ -789,9 +727,7 @@ int snd_seq_event_output_direct(snd_seq_t *seq, snd_seq_event_t *ev)
|
|||
buf = seq->tmpbuf;
|
||||
}
|
||||
|
||||
result = write(seq->fd, buf, len);
|
||||
|
||||
return (result < 0) ? -errno : (int)result;
|
||||
return seq->ops->write(seq, buf, len);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -799,8 +735,7 @@ int snd_seq_event_output_direct(snd_seq_t *seq, snd_seq_event_t *ev)
|
|||
*/
|
||||
int snd_seq_event_output_pending(snd_seq_t *seq)
|
||||
{
|
||||
if (!seq)
|
||||
return -EINVAL;
|
||||
assert(seq);
|
||||
return seq->obufused;
|
||||
}
|
||||
|
||||
|
|
@ -809,14 +744,12 @@ int snd_seq_event_output_pending(snd_seq_t *seq)
|
|||
*/
|
||||
int snd_seq_drain_output(snd_seq_t *seq)
|
||||
{
|
||||
int result;
|
||||
|
||||
if (!seq)
|
||||
return -EINVAL;
|
||||
ssize_t result;
|
||||
assert(seq);
|
||||
while (seq->obufused > 0) {
|
||||
result = write(seq->fd, seq->obuf, seq->obufused);
|
||||
result = seq->ops->write(seq, seq->obuf, seq->obufused);
|
||||
if (result < 0)
|
||||
return -errno;
|
||||
return -result;
|
||||
if ((size_t)result < seq->obufused)
|
||||
memmove(seq->obuf, seq->obuf + result, seq->obufused - result);
|
||||
seq->obufused -= result;
|
||||
|
|
@ -832,9 +765,7 @@ int snd_seq_extract_output(snd_seq_t *seq, snd_seq_event_t **ev_res)
|
|||
{
|
||||
size_t len, olen;
|
||||
snd_seq_event_t ev;
|
||||
|
||||
if (!seq)
|
||||
return -EINVAL;
|
||||
assert(seq);
|
||||
if (ev_res)
|
||||
*ev_res = NULL;
|
||||
if ((olen = seq->obufused) < sizeof(snd_seq_event_t))
|
||||
|
|
@ -865,9 +796,9 @@ int snd_seq_extract_output(snd_seq_t *seq, snd_seq_event_t **ev_res)
|
|||
static ssize_t snd_seq_event_read_buffer(snd_seq_t *seq)
|
||||
{
|
||||
ssize_t len;
|
||||
len = read(seq->fd, seq->ibuf, seq->ibufsize * sizeof(snd_seq_event_t));
|
||||
len = seq->ops->read(seq, seq->ibuf, seq->ibufsize * sizeof(snd_seq_event_t));
|
||||
if (len < 0)
|
||||
return -errno;
|
||||
return len;
|
||||
seq->ibuflen = len / sizeof(snd_seq_event_t);
|
||||
seq->ibufptr = 0;
|
||||
return seq->ibuflen;
|
||||
|
|
@ -901,11 +832,8 @@ static int snd_seq_event_retrieve_buffer(snd_seq_t *seq, snd_seq_event_t **retp)
|
|||
int snd_seq_event_input(snd_seq_t *seq, snd_seq_event_t **ev)
|
||||
{
|
||||
int err;
|
||||
|
||||
assert(seq);
|
||||
*ev = NULL;
|
||||
if (!seq)
|
||||
return -EINVAL;
|
||||
|
||||
if (seq->ibuflen <= 0) {
|
||||
if ((err = snd_seq_event_read_buffer(seq)) < 0)
|
||||
return err;
|
||||
|
|
@ -917,15 +845,18 @@ int snd_seq_event_input(snd_seq_t *seq, snd_seq_event_t **ev)
|
|||
/*
|
||||
* read input data from sequencer if available
|
||||
*/
|
||||
static int snd_seq_event_input_feed(snd_seq_t *seq, struct timeval *timeout)
|
||||
static int snd_seq_event_input_feed(snd_seq_t *seq, int timeout)
|
||||
{
|
||||
fd_set rfds;
|
||||
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(seq->fd, &rfds);
|
||||
if (select(seq->fd + 1, &rfds, NULL, NULL, timeout) < 0)
|
||||
struct pollfd pfd;
|
||||
int err;
|
||||
pfd.fd = seq->poll_fd;
|
||||
pfd.events = POLLIN;
|
||||
err = poll(&pfd, 1, timeout);
|
||||
if (err < 0) {
|
||||
SYSERR("poll");
|
||||
return -errno;
|
||||
if (FD_ISSET(seq->fd, &rfds))
|
||||
}
|
||||
if (pfd.revents & POLLIN)
|
||||
return snd_seq_event_read_buffer(seq);
|
||||
return seq->ibuflen;
|
||||
}
|
||||
|
|
@ -936,10 +867,7 @@ static int snd_seq_event_input_feed(snd_seq_t *seq, struct timeval *timeout)
|
|||
int snd_seq_event_input_pending(snd_seq_t *seq, int fetch_sequencer)
|
||||
{
|
||||
if (seq->ibuflen == 0 && fetch_sequencer) {
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
return snd_seq_event_input_feed(seq, &tv);
|
||||
return snd_seq_event_input_feed(seq, 0);
|
||||
}
|
||||
return seq->ibuflen;
|
||||
}
|
||||
|
|
@ -955,8 +883,7 @@ int snd_seq_event_input_pending(snd_seq_t *seq, int fetch_sequencer)
|
|||
*/
|
||||
int snd_seq_drop_output_buffer(snd_seq_t *seq)
|
||||
{
|
||||
if (!seq)
|
||||
return -EINVAL;
|
||||
assert(seq);
|
||||
seq->obufused = 0;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -966,8 +893,7 @@ int snd_seq_drop_output_buffer(snd_seq_t *seq)
|
|||
*/
|
||||
int snd_seq_drop_input_buffer(snd_seq_t *seq)
|
||||
{
|
||||
if (!seq)
|
||||
return -EINVAL;
|
||||
assert(seq);
|
||||
seq->ibufptr = 0;
|
||||
seq->ibuflen = 0;
|
||||
return 0;
|
||||
|
|
@ -979,10 +905,7 @@ int snd_seq_drop_input_buffer(snd_seq_t *seq)
|
|||
int snd_seq_drop_output(snd_seq_t *seq)
|
||||
{
|
||||
snd_seq_remove_events_t rminfo;
|
||||
|
||||
if (!seq)
|
||||
return -EINVAL;
|
||||
|
||||
assert(seq);
|
||||
seq->obufused = 0; /* drain output buffer */
|
||||
|
||||
memset(&rminfo, 0, sizeof(rminfo));
|
||||
|
|
@ -997,9 +920,7 @@ int snd_seq_drop_output(snd_seq_t *seq)
|
|||
int snd_seq_drop_input(snd_seq_t *seq)
|
||||
{
|
||||
snd_seq_remove_events_t rminfo;
|
||||
|
||||
if (!seq)
|
||||
return -EINVAL;
|
||||
assert(seq);
|
||||
|
||||
seq->ibufptr = 0; /* drain input buffer */
|
||||
seq->ibuflen = 0;
|
||||
|
|
@ -1131,10 +1052,7 @@ int snd_seq_remove_events(snd_seq_t *seq, snd_seq_remove_events_t *rmp)
|
|||
}
|
||||
}
|
||||
|
||||
if (ioctl(seq->fd, SND_SEQ_IOCTL_REMOVE_EVENTS, rmp) < 0)
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
return seq->ops->remove_events(seq, rmp);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
|
|
@ -1145,22 +1063,16 @@ int snd_seq_remove_events(snd_seq_t *seq, snd_seq_remove_events_t *rmp)
|
|||
|
||||
int snd_seq_get_client_pool(snd_seq_t *seq, snd_seq_client_pool_t *info)
|
||||
{
|
||||
if (!seq || !info)
|
||||
return -EINVAL;
|
||||
assert(seq && info);
|
||||
info->client = seq->client;
|
||||
if (ioctl(seq->fd, SND_SEQ_IOCTL_GET_CLIENT_POOL, info) < 0)
|
||||
return -errno;
|
||||
return 0;
|
||||
return seq->ops->get_client_pool(seq, info);
|
||||
}
|
||||
|
||||
int snd_seq_set_client_pool(snd_seq_t *seq, snd_seq_client_pool_t *info)
|
||||
{
|
||||
if (!seq || !info)
|
||||
return -EINVAL;
|
||||
assert(seq && info);
|
||||
info->client = seq->client;
|
||||
if (ioctl(seq->fd, SND_SEQ_IOCTL_SET_CLIENT_POOL, info) < 0)
|
||||
return -errno;
|
||||
return 0;
|
||||
return seq->ops->set_client_pool(seq, info);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
|
|
@ -1171,20 +1083,14 @@ int snd_seq_set_client_pool(snd_seq_t *seq, snd_seq_client_pool_t *info)
|
|||
|
||||
int snd_seq_query_next_client(snd_seq_t *seq, snd_seq_client_info_t *info)
|
||||
{
|
||||
if (!seq || !info)
|
||||
return -EINVAL;
|
||||
if (ioctl(seq->fd, SND_SEQ_IOCTL_QUERY_NEXT_CLIENT, info) < 0)
|
||||
return -errno;
|
||||
return 0;
|
||||
assert(seq && info);
|
||||
return seq->ops->query_next_client(seq, info);
|
||||
}
|
||||
|
||||
int snd_seq_query_next_port(snd_seq_t *seq, snd_seq_port_info_t *info)
|
||||
{
|
||||
if (!seq || !info)
|
||||
return -EINVAL;
|
||||
if (ioctl(seq->fd, SND_SEQ_IOCTL_QUERY_NEXT_PORT, info) < 0)
|
||||
return -errno;
|
||||
return 0;
|
||||
assert(seq && info);
|
||||
return seq->ops->query_next_port(seq, info);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
|
|
|
|||
545
src/seq/seq_hw.c
Normal file
545
src/seq/seq_hw.c
Normal file
|
|
@ -0,0 +1,545 @@
|
|||
/*
|
||||
* Sequencer Interface - main file
|
||||
* Copyright (c) 2000 by Jaroslav Kysela <perex@suse.cz>
|
||||
* Abramo Bagnara <abramo@alsa-project.org>
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Library General Public License as
|
||||
* published by the Free Software Foundation; either version 2 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 Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include "seq_local.h"
|
||||
#include "asoundlib.h"
|
||||
|
||||
#define SND_FILE_SEQ "/dev/snd/seq"
|
||||
#define SND_FILE_ALOADSEQ "/dev/aloadSEQ"
|
||||
#define SND_SEQ_VERSION_MAX SND_PROTOCOL_VERSION(1, 0, 0)
|
||||
|
||||
typedef struct {
|
||||
int fd;
|
||||
} snd_seq_hw_t;
|
||||
|
||||
static int snd_seq_hw_close(snd_seq_t *seq)
|
||||
{
|
||||
snd_seq_hw_t *hw = seq->private;
|
||||
if (close(hw->fd)) {
|
||||
SYSERR("close failed\n");
|
||||
return -errno;
|
||||
}
|
||||
free(hw);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_seq_hw_nonblock(snd_seq_t *seq, int nonblock)
|
||||
{
|
||||
snd_seq_hw_t *hw = seq->private;
|
||||
long flags;
|
||||
|
||||
if ((flags = fcntl(hw->fd, F_GETFL)) < 0) {
|
||||
SYSERR("F_GETFL failed");
|
||||
return -errno;
|
||||
}
|
||||
if (nonblock)
|
||||
flags &= ~O_NONBLOCK;
|
||||
else
|
||||
flags |= O_NONBLOCK;
|
||||
if (fcntl(hw->fd, F_SETFL, flags) < 0) {
|
||||
SYSERR("F_SETFL for O_NONBLOCK failed");
|
||||
return -errno;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_seq_hw_client_id(snd_seq_t *seq)
|
||||
{
|
||||
snd_seq_hw_t *hw = seq->private;
|
||||
int client;
|
||||
if (ioctl(hw->fd, SND_SEQ_IOCTL_CLIENT_ID, &client) < 0) {
|
||||
SYSERR("SND_SEQ_IOCTL_CLIENT_ID failed");
|
||||
return -errno;
|
||||
}
|
||||
return client;
|
||||
}
|
||||
|
||||
static int snd_seq_hw_system_info(snd_seq_t *seq, snd_seq_system_info_t * info)
|
||||
{
|
||||
snd_seq_hw_t *hw = seq->private;
|
||||
if (ioctl(hw->fd, SND_SEQ_IOCTL_SYSTEM_INFO, info) < 0) {
|
||||
SYSERR("SND_SEQ_IOCTL_SYSTEM_INFO failed");
|
||||
return -errno;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_seq_hw_get_client_info(snd_seq_t *seq, snd_seq_client_info_t * info)
|
||||
{
|
||||
snd_seq_hw_t *hw = seq->private;
|
||||
if (ioctl(hw->fd, SND_SEQ_IOCTL_GET_CLIENT_INFO, info) < 0) {
|
||||
SYSERR("SND_SEQ_IOCTL_GET_CLIENT_INFO failed");
|
||||
return -errno;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_seq_hw_set_client_info(snd_seq_t *seq, snd_seq_client_info_t * info)
|
||||
{
|
||||
snd_seq_hw_t *hw = seq->private;
|
||||
if (ioctl(hw->fd, SND_SEQ_IOCTL_SET_CLIENT_INFO, info) < 0) {
|
||||
SYSERR("SND_SEQ_IOCTL_SET_CLIENT_INFO failed");
|
||||
return -errno;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_seq_hw_create_port(snd_seq_t *seq, snd_seq_port_info_t * port)
|
||||
{
|
||||
snd_seq_hw_t *hw = seq->private;
|
||||
if (ioctl(hw->fd, SND_SEQ_IOCTL_CREATE_PORT, port) < 0) {
|
||||
SYSERR("SND_SEQ_IOCTL_CREATE_PORT failed");
|
||||
return -errno;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_seq_hw_delete_port(snd_seq_t *seq, snd_seq_port_info_t * port)
|
||||
{
|
||||
snd_seq_hw_t *hw = seq->private;
|
||||
if (ioctl(hw->fd, SND_SEQ_IOCTL_DELETE_PORT, port) < 0) {
|
||||
SYSERR("SND_SEQ_IOCTL_DELETE_PORT failed");
|
||||
return -errno;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_seq_hw_get_port_info(snd_seq_t *seq, snd_seq_port_info_t * info)
|
||||
{
|
||||
snd_seq_hw_t *hw = seq->private;
|
||||
if (ioctl(hw->fd, SND_SEQ_IOCTL_GET_PORT_INFO, info) < 0) {
|
||||
SYSERR("SND_SEQ_IOCTL_GET_PORT_INFO failed");
|
||||
return -errno;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_seq_hw_set_port_info(snd_seq_t *seq, snd_seq_port_info_t * info)
|
||||
{
|
||||
snd_seq_hw_t *hw = seq->private;
|
||||
if (ioctl(hw->fd, SND_SEQ_IOCTL_SET_PORT_INFO, info) < 0) {
|
||||
SYSERR("SND_SEQ_IOCTL_SET_PORT_INFO failed");
|
||||
return -errno;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_seq_hw_get_port_subscription(snd_seq_t *seq, snd_seq_port_subscribe_t * sub)
|
||||
{
|
||||
snd_seq_hw_t *hw = seq->private;
|
||||
if (ioctl(hw->fd, SND_SEQ_IOCTL_GET_SUBSCRIPTION, sub) < 0) {
|
||||
SYSERR("SND_SEQ_IOCTL_GET_SUBSCRIPTION failed");
|
||||
return -errno;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_seq_hw_subscribe_port(snd_seq_t *seq, snd_seq_port_subscribe_t * sub)
|
||||
{
|
||||
snd_seq_hw_t *hw = seq->private;
|
||||
if (ioctl(hw->fd, SND_SEQ_IOCTL_SUBSCRIBE_PORT, sub) < 0) {
|
||||
SYSERR("SND_SEQ_IOCTL_SUBSCRIBE_PORT failed");
|
||||
return -errno;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_seq_hw_unsubscribe_port(snd_seq_t *seq, snd_seq_port_subscribe_t * sub)
|
||||
{
|
||||
snd_seq_hw_t *hw = seq->private;
|
||||
if (ioctl(hw->fd, SND_SEQ_IOCTL_UNSUBSCRIBE_PORT, sub) < 0) {
|
||||
SYSERR("SND_SEQ_IOCTL_UNSUBSCRIBE_PORT failed");
|
||||
return -errno;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_seq_hw_query_port_subscribers(snd_seq_t *seq, snd_seq_query_subs_t * subs)
|
||||
{
|
||||
snd_seq_hw_t *hw = seq->private;
|
||||
if (ioctl(hw->fd, SND_SEQ_IOCTL_QUERY_SUBS, subs) < 0) {
|
||||
SYSERR("SND_SEQ_IOCTL_QUERY_SUBS failed");
|
||||
return -errno;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_seq_hw_get_queue_status(snd_seq_t *seq, snd_seq_queue_status_t * status)
|
||||
{
|
||||
snd_seq_hw_t *hw = seq->private;
|
||||
if (ioctl(hw->fd, SND_SEQ_IOCTL_GET_QUEUE_STATUS, status) < 0) {
|
||||
SYSERR("SND_SEQ_IOCTL_GET_QUEUE_STATUS failed");
|
||||
return -errno;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_seq_hw_get_queue_tempo(snd_seq_t *seq, snd_seq_queue_tempo_t * tempo)
|
||||
{
|
||||
snd_seq_hw_t *hw = seq->private;
|
||||
if (ioctl(hw->fd, SND_SEQ_IOCTL_GET_QUEUE_TEMPO, tempo) < 0) {
|
||||
SYSERR("SND_SEQ_IOCTL_GET_QUEUE_TEMPO failed");
|
||||
return -errno;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_seq_hw_set_queue_tempo(snd_seq_t *seq, snd_seq_queue_tempo_t * tempo)
|
||||
{
|
||||
snd_seq_hw_t *hw = seq->private;
|
||||
if (ioctl(hw->fd, SND_SEQ_IOCTL_SET_QUEUE_TEMPO, tempo) < 0) {
|
||||
SYSERR("SND_SEQ_IOCTL_SET_QUEUE_TEMPO failed");
|
||||
return -errno;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_seq_hw_get_queue_owner(snd_seq_t *seq, snd_seq_queue_owner_t * owner)
|
||||
{
|
||||
snd_seq_hw_t *hw = seq->private;
|
||||
if (ioctl(hw->fd, SND_SEQ_IOCTL_GET_QUEUE_OWNER, owner) < 0) {
|
||||
SYSERR("SND_SEQ_IOCTL_GET_QUEUE_OWNER failed");
|
||||
return -errno;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_seq_hw_set_queue_owner(snd_seq_t *seq, snd_seq_queue_owner_t * owner)
|
||||
{
|
||||
snd_seq_hw_t *hw = seq->private;
|
||||
if (ioctl(hw->fd, SND_SEQ_IOCTL_SET_QUEUE_OWNER, owner) < 0) {
|
||||
SYSERR("SND_SEQ_IOCTL_SET_QUEUE_OWNER failed");
|
||||
return -errno;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_seq_hw_get_queue_timer(snd_seq_t *seq, snd_seq_queue_timer_t * timer)
|
||||
{
|
||||
snd_seq_hw_t *hw = seq->private;
|
||||
if (ioctl(hw->fd, SND_SEQ_IOCTL_GET_QUEUE_TIMER, timer) < 0) {
|
||||
SYSERR("SND_SEQ_IOCTL_GET_QUEUE_TIMER failed");
|
||||
return -errno;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_seq_hw_set_queue_timer(snd_seq_t *seq, snd_seq_queue_timer_t * timer)
|
||||
{
|
||||
snd_seq_hw_t *hw = seq->private;
|
||||
if (ioctl(hw->fd, SND_SEQ_IOCTL_SET_QUEUE_TIMER, timer) < 0) {
|
||||
SYSERR("SND_SEQ_IOCTL_SET_QUEUE_TIMER failed");
|
||||
return -errno;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_seq_hw_get_queue_client(snd_seq_t *seq, snd_seq_queue_client_t * info)
|
||||
{
|
||||
snd_seq_hw_t *hw = seq->private;
|
||||
if (ioctl(hw->fd, SND_SEQ_IOCTL_GET_QUEUE_CLIENT, info) < 0) {
|
||||
SYSERR("SND_SEQ_IOCTL_GET_QUEUE_CLIENT failed");
|
||||
return -errno;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_seq_hw_set_queue_client(snd_seq_t *seq, snd_seq_queue_client_t * info)
|
||||
{
|
||||
snd_seq_hw_t *hw = seq->private;
|
||||
if (ioctl(hw->fd, SND_SEQ_IOCTL_SET_QUEUE_CLIENT, info) < 0) {
|
||||
SYSERR("SND_SEQ_IOCTL_SET_QUEUE_CLIENT failed");
|
||||
return -errno;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_seq_hw_create_queue(snd_seq_t *seq, snd_seq_queue_info_t *info)
|
||||
{
|
||||
snd_seq_hw_t *hw = seq->private;
|
||||
if (ioctl(hw->fd, SND_SEQ_IOCTL_CREATE_QUEUE, info) < 0) {
|
||||
SYSERR("SND_SEQ_IOCTL_CREATE_QUEUE failed");
|
||||
return -errno;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_seq_hw_delete_queue(snd_seq_t *seq, snd_seq_queue_info_t *info)
|
||||
{
|
||||
snd_seq_hw_t *hw = seq->private;
|
||||
if (ioctl(hw->fd, SND_SEQ_IOCTL_DELETE_QUEUE, info) < 0) {
|
||||
SYSERR("SND_SEQ_IOCTL_DELETE_QUEUE failed");
|
||||
return -errno;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_seq_hw_get_queue_info(snd_seq_t *seq, snd_seq_queue_info_t *info)
|
||||
{
|
||||
snd_seq_hw_t *hw = seq->private;
|
||||
if (ioctl(hw->fd, SND_SEQ_IOCTL_GET_QUEUE_INFO, info) < 0) {
|
||||
SYSERR("SND_SEQ_IOCTL_GET_QUEUE_INFO failed");
|
||||
return -errno;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_seq_hw_set_queue_info(snd_seq_t *seq, snd_seq_queue_info_t *info)
|
||||
{
|
||||
snd_seq_hw_t *hw = seq->private;
|
||||
if (ioctl(hw->fd, SND_SEQ_IOCTL_SET_QUEUE_INFO, info) < 0) {
|
||||
SYSERR("SND_SEQ_IOCTL_SET_QUEUE_INFO failed");
|
||||
return -errno;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_seq_hw_get_named_queue(snd_seq_t *seq, snd_seq_queue_info_t *info)
|
||||
{
|
||||
snd_seq_hw_t *hw = seq->private;
|
||||
if (ioctl(hw->fd, SND_SEQ_IOCTL_GET_NAMED_QUEUE, info) < 0) {
|
||||
SYSERR("SND_SEQ_IOCTL_GET_NAMED_QUEUE failed");
|
||||
return -errno;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t snd_seq_hw_write(snd_seq_t *seq, void *buf, size_t len)
|
||||
{
|
||||
snd_seq_hw_t *hw = seq->private;
|
||||
ssize_t result = write(hw->fd, buf, len);
|
||||
if (result < 0)
|
||||
return -errno;
|
||||
return result;
|
||||
}
|
||||
|
||||
static ssize_t snd_seq_hw_read(snd_seq_t *seq, void *buf, size_t len)
|
||||
{
|
||||
snd_seq_hw_t *hw = seq->private;
|
||||
ssize_t result = read(hw->fd, buf, len);
|
||||
if (result < 0)
|
||||
return -errno;
|
||||
return result;
|
||||
}
|
||||
|
||||
static int snd_seq_hw_remove_events(snd_seq_t *seq, snd_seq_remove_events_t *rmp)
|
||||
{
|
||||
snd_seq_hw_t *hw = seq->private;
|
||||
if (ioctl(hw->fd, SND_SEQ_IOCTL_REMOVE_EVENTS, rmp) < 0) {
|
||||
SYSERR("SND_SEQ_IOCTL_REMOVE_EVENTS failed");
|
||||
return -errno;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_seq_hw_get_client_pool(snd_seq_t *seq, snd_seq_client_pool_t *info)
|
||||
{
|
||||
snd_seq_hw_t *hw = seq->private;
|
||||
if (ioctl(hw->fd, SND_SEQ_IOCTL_GET_CLIENT_POOL, info) < 0) {
|
||||
SYSERR("SND_SEQ_IOCTL_GET_CLIENT_POOL failed");
|
||||
return -errno;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_seq_hw_set_client_pool(snd_seq_t *seq, snd_seq_client_pool_t *info)
|
||||
{
|
||||
snd_seq_hw_t *hw = seq->private;
|
||||
if (ioctl(hw->fd, SND_SEQ_IOCTL_SET_CLIENT_POOL, info) < 0) {
|
||||
SYSERR("SND_SEQ_IOCTL_SET_CLIENT_POOL failed");
|
||||
return -errno;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_seq_hw_query_next_client(snd_seq_t *seq, snd_seq_client_info_t *info)
|
||||
{
|
||||
snd_seq_hw_t *hw = seq->private;
|
||||
if (ioctl(hw->fd, SND_SEQ_IOCTL_QUERY_NEXT_CLIENT, info) < 0) {
|
||||
SYSERR("SND_SEQ_IOCTL_QUERY_NEXT_CLIENT failed");
|
||||
return -errno;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_seq_hw_query_next_port(snd_seq_t *seq, snd_seq_port_info_t *info)
|
||||
{
|
||||
snd_seq_hw_t *hw = seq->private;
|
||||
if (ioctl(hw->fd, SND_SEQ_IOCTL_QUERY_NEXT_PORT, info) < 0) {
|
||||
SYSERR("SND_SEQ_IOCTL_QUERY_NEXT_PORT failed");
|
||||
return -errno;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
snd_seq_ops_t snd_seq_hw_ops = {
|
||||
close: snd_seq_hw_close,
|
||||
nonblock: snd_seq_hw_nonblock,
|
||||
system_info: snd_seq_hw_system_info,
|
||||
get_client_info: snd_seq_hw_get_client_info,
|
||||
set_client_info: snd_seq_hw_set_client_info,
|
||||
create_port: snd_seq_hw_create_port,
|
||||
delete_port: snd_seq_hw_delete_port,
|
||||
get_port_info: snd_seq_hw_get_port_info,
|
||||
set_port_info: snd_seq_hw_set_port_info,
|
||||
get_port_subscription: snd_seq_hw_get_port_subscription,
|
||||
subscribe_port: snd_seq_hw_subscribe_port,
|
||||
unsubscribe_port: snd_seq_hw_unsubscribe_port,
|
||||
query_port_subscribers: snd_seq_hw_query_port_subscribers,
|
||||
get_queue_status: snd_seq_hw_get_queue_status,
|
||||
get_queue_tempo: snd_seq_hw_get_queue_tempo,
|
||||
set_queue_tempo: snd_seq_hw_set_queue_tempo,
|
||||
get_queue_owner: snd_seq_hw_get_queue_owner,
|
||||
set_queue_owner: snd_seq_hw_set_queue_owner,
|
||||
get_queue_timer: snd_seq_hw_get_queue_timer,
|
||||
set_queue_timer: snd_seq_hw_set_queue_timer,
|
||||
get_queue_client: snd_seq_hw_get_queue_client,
|
||||
set_queue_client: snd_seq_hw_set_queue_client,
|
||||
create_queue: snd_seq_hw_create_queue,
|
||||
delete_queue: snd_seq_hw_delete_queue,
|
||||
get_queue_info: snd_seq_hw_get_queue_info,
|
||||
set_queue_info: snd_seq_hw_set_queue_info,
|
||||
get_named_queue: snd_seq_hw_get_named_queue,
|
||||
write: snd_seq_hw_write,
|
||||
read: snd_seq_hw_read,
|
||||
remove_events: snd_seq_hw_remove_events,
|
||||
get_client_pool: snd_seq_hw_get_client_pool,
|
||||
set_client_pool: snd_seq_hw_set_client_pool,
|
||||
query_next_client: snd_seq_hw_query_next_client,
|
||||
query_next_port: snd_seq_hw_query_next_port,
|
||||
};
|
||||
|
||||
int snd_seq_hw_open(snd_seq_t **handle, char *name, int streams, int mode)
|
||||
{
|
||||
int fd, ver, client, fmode;
|
||||
char filename[32];
|
||||
snd_seq_t *seq;
|
||||
snd_seq_hw_t *hw;
|
||||
|
||||
*handle = NULL;
|
||||
|
||||
switch (streams) {
|
||||
case SND_SEQ_OPEN_OUTPUT:
|
||||
fmode = O_WRONLY;
|
||||
break;
|
||||
case SND_SEQ_OPEN_INPUT:
|
||||
fmode = O_RDONLY;
|
||||
break;
|
||||
case SND_SEQ_OPEN_DUPLEX:
|
||||
fmode = O_RDWR;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (mode & SND_SEQ_NONBLOCK)
|
||||
fmode |= O_NONBLOCK;
|
||||
|
||||
sprintf(filename, SND_FILE_SEQ);
|
||||
if ((fd = open(filename, fmode)) < 0) {
|
||||
close(open(SND_FILE_ALOADSEQ, O_RDWR));
|
||||
if ((fd = open(filename, fmode)) < 0) {
|
||||
SYSERR("open %s failed", filename);
|
||||
return -errno;
|
||||
}
|
||||
}
|
||||
if (ioctl(fd, SND_SEQ_IOCTL_PVERSION, &ver) < 0) {
|
||||
SYSERR("SND_SEQ_IOCTL_PVERSION failed");
|
||||
close(fd);
|
||||
return -errno;
|
||||
}
|
||||
if (SND_PROTOCOL_INCOMPATIBLE(ver, SND_SEQ_VERSION_MAX)) {
|
||||
close(fd);
|
||||
return -SND_ERROR_INCOMPATIBLE_VERSION;
|
||||
}
|
||||
hw = calloc(1, sizeof(snd_seq_hw_t));
|
||||
if (hw == NULL) {
|
||||
close(fd);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
seq = calloc(1, sizeof(snd_seq_t));
|
||||
if (seq == NULL) {
|
||||
free(hw);
|
||||
close(fd);
|
||||
return -ENOMEM;
|
||||
}
|
||||
hw->fd = fd;
|
||||
if (streams & SND_SEQ_OPEN_OUTPUT) {
|
||||
seq->obuf = (char *) malloc(seq->obufsize = SND_SEQ_OBUF_SIZE);
|
||||
if (!seq->obuf) {
|
||||
free(hw);
|
||||
free(seq);
|
||||
close(fd);
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
if (streams & SND_SEQ_OPEN_INPUT) {
|
||||
seq->ibuf = (snd_seq_event_t *) calloc(sizeof(snd_seq_event_t), seq->ibufsize = SND_SEQ_IBUF_SIZE);
|
||||
if (!seq->ibuf) {
|
||||
free(seq->ibuf);
|
||||
free(hw);
|
||||
free(seq);
|
||||
close(fd);
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
if (name)
|
||||
seq->name = strdup(name);
|
||||
seq->type = SND_SEQ_TYPE_HW;
|
||||
seq->streams = streams;
|
||||
seq->mode = mode;
|
||||
seq->tmpbuf = NULL;
|
||||
seq->tmpbufsize = 0;
|
||||
seq->poll_fd = fd;
|
||||
seq->ops = &snd_seq_hw_ops;
|
||||
seq->private = hw;
|
||||
client = snd_seq_hw_client_id(seq);
|
||||
if (client < 0) {
|
||||
snd_seq_close(seq);
|
||||
return client;
|
||||
} else
|
||||
seq->client = client;
|
||||
*handle = seq;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _snd_seq_hw_open(snd_seq_t **handlep, char *name, snd_config_t *conf,
|
||||
int streams, int mode)
|
||||
{
|
||||
snd_config_iterator_t i;
|
||||
snd_config_foreach(i, conf) {
|
||||
snd_config_t *n = snd_config_entry(i);
|
||||
if (strcmp(n->id, "comment") == 0)
|
||||
continue;
|
||||
if (strcmp(n->id, "type") == 0)
|
||||
continue;
|
||||
if (strcmp(n->id, "streams") == 0)
|
||||
continue;
|
||||
return -EINVAL;
|
||||
}
|
||||
return snd_seq_hw_open(handlep, name, streams, mode);
|
||||
}
|
||||
|
||||
105
src/seq/seq_local.h
Normal file
105
src/seq/seq_local.h
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* Sequencer Interface - definition of sequencer event handler
|
||||
* Copyright (c) 2000 by Jaroslav Kysela <perex@suse.cz>
|
||||
* Abramo Bagnara <abramo@alsa-project.org>
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Library General Public License as
|
||||
* published by the Free Software Foundation; either version 2 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 Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SEQ_LOCAL_H
|
||||
#define __SEQ_LOCAL_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
#include "asoundlib.h"
|
||||
|
||||
#define SND_SEQ_OBUF_SIZE (16*1024) /* default size */
|
||||
#define SND_SEQ_IBUF_SIZE 500 /* in event_size aligned */
|
||||
#define DEFAULT_TMPBUF_SIZE 20
|
||||
|
||||
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95)
|
||||
#define ERR(...) snd_lib_error(__FILE__, __LINE__, __FUNCTION__, 0, __VA_ARGS__)
|
||||
#define SYSERR(...) snd_lib_error(__FILE__, __LINE__, __FUNCTION__, errno, __VA_ARGS__)
|
||||
#else
|
||||
#define ERR(args...) snd_lib_error(__FILE__, __LINE__, __FUNCTION__, 0, ##args)
|
||||
#define SYSERR(args...) snd_lib_error(__FILE__, __LINE__, __FUNCTION__, errno, ##args)
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
int (*close)(snd_seq_t *seq);
|
||||
int (*nonblock)(snd_seq_t *seq, int nonblock);
|
||||
int (*system_info)(snd_seq_t *seq, snd_seq_system_info_t * info);
|
||||
int (*get_client_info)(snd_seq_t *seq, snd_seq_client_info_t * info);
|
||||
int (*set_client_info)(snd_seq_t *seq, snd_seq_client_info_t * info);
|
||||
int (*create_port)(snd_seq_t *seq, snd_seq_port_info_t * port);
|
||||
int (*delete_port)(snd_seq_t *seq, snd_seq_port_info_t * port);
|
||||
int (*get_port_info)(snd_seq_t *seq, snd_seq_port_info_t * info);
|
||||
int (*set_port_info)(snd_seq_t *seq, snd_seq_port_info_t * info);
|
||||
int (*get_port_subscription)(snd_seq_t *seq, snd_seq_port_subscribe_t * sub);
|
||||
int (*subscribe_port)(snd_seq_t *seq, snd_seq_port_subscribe_t * sub);
|
||||
int (*unsubscribe_port)(snd_seq_t *seq, snd_seq_port_subscribe_t * sub);
|
||||
int (*query_port_subscribers)(snd_seq_t *seq, snd_seq_query_subs_t * subs);
|
||||
int (*get_queue_status)(snd_seq_t *seq, snd_seq_queue_status_t * status);
|
||||
int (*get_queue_tempo)(snd_seq_t *seq, snd_seq_queue_tempo_t * tempo);
|
||||
int (*set_queue_tempo)(snd_seq_t *seq, snd_seq_queue_tempo_t * tempo);
|
||||
int (*get_queue_owner)(snd_seq_t *seq, snd_seq_queue_owner_t * owner);
|
||||
int (*set_queue_owner)(snd_seq_t *seq, snd_seq_queue_owner_t * owner);
|
||||
int (*get_queue_timer)(snd_seq_t *seq, snd_seq_queue_timer_t * timer);
|
||||
int (*set_queue_timer)(snd_seq_t *seq, snd_seq_queue_timer_t * timer);
|
||||
int (*get_queue_client)(snd_seq_t *seq, snd_seq_queue_client_t * client);
|
||||
int (*set_queue_client)(snd_seq_t *seq, snd_seq_queue_client_t * client);
|
||||
int (*create_queue)(snd_seq_t *seq, snd_seq_queue_info_t *info);
|
||||
int (*delete_queue)(snd_seq_t *seq, snd_seq_queue_info_t *info);
|
||||
int (*get_queue_info)(snd_seq_t *seq, snd_seq_queue_info_t *info);
|
||||
int (*set_queue_info)(snd_seq_t *seq, snd_seq_queue_info_t *info);
|
||||
int (*get_named_queue)(snd_seq_t *seq, snd_seq_queue_info_t *info);
|
||||
ssize_t (*write)(snd_seq_t *seq, void *buf, size_t len);
|
||||
ssize_t (*read)(snd_seq_t *seq, void *buf, size_t len);
|
||||
int (*remove_events)(snd_seq_t *seq, snd_seq_remove_events_t *rmp);
|
||||
int (*get_client_pool)(snd_seq_t *seq, snd_seq_client_pool_t *info);
|
||||
int (*set_client_pool)(snd_seq_t *seq, snd_seq_client_pool_t *info);
|
||||
int (*query_next_client)(snd_seq_t *seq, snd_seq_client_info_t *info);
|
||||
int (*query_next_port)(snd_seq_t *seq, snd_seq_port_info_t *info);
|
||||
} snd_seq_ops_t;
|
||||
|
||||
struct _snd_seq {
|
||||
char *name;
|
||||
int type;
|
||||
int streams;
|
||||
int mode;
|
||||
int poll_fd;
|
||||
snd_seq_ops_t *ops;
|
||||
void *private;
|
||||
int client; /* client number */
|
||||
/* buffers */
|
||||
char *obuf; /* output buffer */
|
||||
size_t obufsize; /* output buffer size */
|
||||
size_t obufused; /* output buffer used size */
|
||||
snd_seq_event_t *ibuf; /* input buffer */
|
||||
size_t ibufptr; /* current pointer of input buffer */
|
||||
size_t ibuflen; /* queued length */
|
||||
size_t ibufsize; /* input buffer size */
|
||||
snd_seq_event_t *tmpbuf; /* temporary event for extracted event */
|
||||
size_t tmpbufsize; /* size of errbuf */
|
||||
};
|
||||
|
||||
int snd_seq_hw_open(snd_seq_t **handle, char *name, int streams, int mode);
|
||||
|
||||
#endif
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
/*
|
||||
* Sequencer Interface - definition of sequencer event handler
|
||||
* Copyright (c) 1998 by Jaroslav Kysela <perex@suse.cz>
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Library General Public License as
|
||||
* published by the Free Software Foundation; either version 2 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 Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SEQ_PRIV_H
|
||||
#define __SEQ_PRIV_H
|
||||
|
||||
struct snd_seq {
|
||||
int client; /* client number */
|
||||
int fd;
|
||||
/* buffers */
|
||||
char *obuf; /* output buffer */
|
||||
size_t obufsize; /* output buffer size */
|
||||
size_t obufused; /* output buffer used size */
|
||||
snd_seq_event_t *ibuf; /* input buffer */
|
||||
size_t ibufptr; /* current pointer of input buffer */
|
||||
size_t ibuflen; /* queued length */
|
||||
size_t ibufsize; /* input buffer size */
|
||||
snd_seq_event_t *tmpbuf; /* temporary event for extracted event */
|
||||
size_t tmpbufsize; /* size of errbuf */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -28,7 +28,7 @@
|
|||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include "asoundlib.h"
|
||||
#include "seq_priv.h"
|
||||
#include "seq_local.h"
|
||||
|
||||
/* direct passing (without queued) */
|
||||
void snd_seq_ev_set_direct(snd_seq_event_t *ev)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue