mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-29 05:40:25 -04:00
Takashi Iwai <iwai@ww.uni-erlangen.de> Mon, 30 Aug 1999 14:56:38 +0200
This commit is contained in:
parent
f247f920e1
commit
11ce43d87c
4 changed files with 82 additions and 98 deletions
|
|
@ -826,7 +826,6 @@ int snd_seq_query_next_client(snd_seq_t *seq, snd_seq_client_info_t *info)
|
||||||
{
|
{
|
||||||
if (!seq || !info)
|
if (!seq || !info)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
info->client = seq->client;
|
|
||||||
if (ioctl(seq->fd, SND_SEQ_IOCTL_QUERY_NEXT_CLIENT, info) < 0)
|
if (ioctl(seq->fd, SND_SEQ_IOCTL_QUERY_NEXT_CLIENT, info) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -836,7 +835,6 @@ int snd_seq_query_next_port(snd_seq_t *seq, snd_seq_port_info_t *info)
|
||||||
{
|
{
|
||||||
if (!seq || !info)
|
if (!seq || !info)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
info->client = seq->client;
|
|
||||||
if (ioctl(seq->fd, SND_SEQ_IOCTL_QUERY_NEXT_PORT, info) < 0)
|
if (ioctl(seq->fd, SND_SEQ_IOCTL_QUERY_NEXT_PORT, info) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
================================================================
|
================================================================
|
||||||
aconnect - control subscriptions
|
aconnect - control subscriptions
|
||||||
ver.0.1.1
|
ver.0.1.2
|
||||||
Copyright (C) 1999 Takashi Iwai
|
Copyright (C) 1999 Takashi Iwai
|
||||||
================================================================
|
================================================================
|
||||||
|
|
||||||
|
|
@ -40,8 +40,7 @@ Some ports may have permission for its own group.
|
||||||
In such a case, change the group of aconnect to the appropriate one by
|
In such a case, change the group of aconnect to the appropriate one by
|
||||||
using -g option.
|
using -g option.
|
||||||
|
|
||||||
The option -l together with -i or -o shows subscribers and tracking
|
The option -l together with -i or -o shows subscribers for each port.
|
||||||
for each port.
|
|
||||||
|
|
||||||
The option -D specifies the sequencer device file (as default,
|
The option -D specifies the sequencer device file (as default,
|
||||||
/dev/snd/seq). Usually, you don't have to change it.
|
/dev/snd/seq). Usually, you don't have to change it.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* connect / disconnect two subscriber ports
|
* connect / disconnect two subscriber ports
|
||||||
* ver.0.1.1
|
* ver.0.1.2
|
||||||
*
|
*
|
||||||
* Copyright (C) 1999 Takashi Iwai
|
* Copyright (C) 1999 Takashi Iwai
|
||||||
*
|
*
|
||||||
|
|
@ -96,10 +96,8 @@ static void list_subscribers(snd_seq_t *seq, int client, int port)
|
||||||
memset(&subs, 0, sizeof(subs));
|
memset(&subs, 0, sizeof(subs));
|
||||||
subs.client = client;
|
subs.client = client;
|
||||||
subs.port = port;
|
subs.port = port;
|
||||||
list_each_subs(seq, &subs, SND_SEQ_QUERY_SUBS_READ, "Read Subscribers");
|
list_each_subs(seq, &subs, SND_SEQ_QUERY_SUBS_READ, "Connecting To");
|
||||||
list_each_subs(seq, &subs, SND_SEQ_QUERY_SUBS_WRITE, "Write Subscribers");
|
list_each_subs(seq, &subs, SND_SEQ_QUERY_SUBS_WRITE, "Connected From");
|
||||||
list_each_subs(seq, &subs, SND_SEQ_QUERY_SUBS_READ_TRACK, "Read Tracking");
|
|
||||||
list_each_subs(seq, &subs, SND_SEQ_QUERY_SUBS_WRITE_TRACK, "Write Tracking");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -231,6 +229,7 @@ int main(int argc, char **argv)
|
||||||
parse_address(&subs.dest, argv[optind + 1]);
|
parse_address(&subs.dest, argv[optind + 1]);
|
||||||
subs.sender.queue = subs.dest.queue = queue;
|
subs.sender.queue = subs.dest.queue = queue;
|
||||||
subs.exclusive = 0;
|
subs.exclusive = 0;
|
||||||
|
subs.convert_time = 0;
|
||||||
subs.realtime = 0;
|
subs.realtime = 0;
|
||||||
|
|
||||||
if (command == UNSUBSCRIBE) {
|
if (command == UNSUBSCRIBE) {
|
||||||
|
|
@ -245,7 +244,7 @@ int main(int argc, char **argv)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (snd_seq_get_port_subscription(seq, &subs) < 0) {
|
if (snd_seq_get_port_subscription(seq, &subs) == 0) {
|
||||||
snd_seq_close(seq);
|
snd_seq_close(seq);
|
||||||
fprintf(stderr, "Connection is already subscribed\n");
|
fprintf(stderr, "Connection is already subscribed\n");
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
||||||
162
test/playmidi1.c
162
test/playmidi1.c
|
|
@ -12,6 +12,9 @@
|
||||||
* - fix tempo event bug
|
* - fix tempo event bug
|
||||||
* - add command line options
|
* - add command line options
|
||||||
*
|
*
|
||||||
|
* 19990827 Takashi Iwai <iwai@ww.uni-erlangen.de>
|
||||||
|
* - use snd_seq_alloc_queue()
|
||||||
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
|
@ -49,7 +52,6 @@
|
||||||
#define USE_BLOCKING_MODE
|
#define USE_BLOCKING_MODE
|
||||||
|
|
||||||
/* default destination queue, client and port numbers */
|
/* default destination queue, client and port numbers */
|
||||||
#define DEST_QUEUE_NUMBER 7
|
|
||||||
#define DEST_CLIENT_NUMBER 65
|
#define DEST_CLIENT_NUMBER 65
|
||||||
#define DEST_PORT_NUMBER 0
|
#define DEST_PORT_NUMBER 0
|
||||||
|
|
||||||
|
|
@ -66,7 +68,7 @@ static double local_secs = 0;
|
||||||
static int local_ticks = 0;
|
static int local_ticks = 0;
|
||||||
static int local_tempo = 500000;
|
static int local_tempo = 500000;
|
||||||
|
|
||||||
static int dest_queue = DEST_QUEUE_NUMBER;
|
static int dest_queue = 0;
|
||||||
static int dest_client = DEST_CLIENT_NUMBER;
|
static int dest_client = DEST_CLIENT_NUMBER;
|
||||||
static int dest_port = DEST_PORT_NUMBER;
|
static int dest_port = DEST_PORT_NUMBER;
|
||||||
static int source_channel = 0;
|
static int source_channel = 0;
|
||||||
|
|
@ -413,38 +415,11 @@ static void do_sysex(int len, char *msg)
|
||||||
write_ev_var(&ev, len, msg);
|
write_ev_var(&ev, len, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* synchronize to the end of event */
|
static snd_seq_event_t *wait_for_event(void)
|
||||||
static void alsa_sync(void)
|
|
||||||
{
|
{
|
||||||
int left;
|
int left;
|
||||||
snd_seq_event_t* input_event;
|
snd_seq_event_t *input_event;
|
||||||
snd_seq_event_t ev;
|
|
||||||
|
|
||||||
/* send echo event to self client. */
|
|
||||||
if (verbose >= VERB_MUCH)
|
|
||||||
printf("alsa_sync syncing... send ECHO(%d) event to myself. time=%f\n",
|
|
||||||
SND_SEQ_EVENT_ECHO, (double) Mf_currtime+1);
|
|
||||||
ev.source.port = source_port;
|
|
||||||
ev.source.channel = source_channel;
|
|
||||||
ev.dest.queue = dest_queue;
|
|
||||||
ev.dest.client = snd_seq_client_id(seq_handle);
|
|
||||||
ev.dest.port = source_port;
|
|
||||||
ev.dest.channel = 0; /* don't care */
|
|
||||||
|
|
||||||
#ifdef USE_REALTIME
|
|
||||||
ev.flags = SND_SEQ_TIME_STAMP_REAL | SND_SEQ_TIME_MODE_ABS;
|
|
||||||
tick2time(&ev.time.real, Mf_currtime+1);
|
|
||||||
#else
|
|
||||||
ev.flags = SND_SEQ_TIME_STAMP_TICK | SND_SEQ_TIME_MODE_ABS;
|
|
||||||
ev.time.tick = Mf_currtime+1;
|
|
||||||
#endif
|
|
||||||
ev.type = SND_SEQ_EVENT_ECHO;
|
|
||||||
write_ev(&ev);
|
|
||||||
|
|
||||||
/* dump buffer */
|
|
||||||
left = snd_seq_flush_output(seq_handle);
|
|
||||||
|
|
||||||
/* wait for the timer start event */
|
|
||||||
#ifdef USE_BLOCKING_MODE
|
#ifdef USE_BLOCKING_MODE
|
||||||
/* read event - blocked until any event is read */
|
/* read event - blocked until any event is read */
|
||||||
left = snd_seq_event_input(seq_handle, &input_event);
|
left = snd_seq_event_input(seq_handle, &input_event);
|
||||||
|
|
@ -465,14 +440,54 @@ static void alsa_sync(void)
|
||||||
#endif
|
#endif
|
||||||
if (left < 0) {
|
if (left < 0) {
|
||||||
printf("alsa_sync error!:%s\n", snd_strerror(left));
|
printf("alsa_sync error!:%s\n", snd_strerror(left));
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verbose >= VERB_MUCH)
|
return input_event;
|
||||||
printf("alsa_sync got event. type=%d, flags=%d\n",
|
}
|
||||||
input_event->type, input_event->flags);
|
|
||||||
snd_seq_free_event(input_event);
|
/* synchronize to the end of event */
|
||||||
|
static void alsa_sync(void)
|
||||||
|
{
|
||||||
|
int left;
|
||||||
|
snd_seq_event_t *input_event;
|
||||||
|
snd_seq_event_t ev;
|
||||||
|
|
||||||
|
/* send echo event to self client. */
|
||||||
|
if (verbose >= VERB_MUCH)
|
||||||
|
printf("alsa_sync syncing... send ECHO(%d) event to myself. time=%f\n",
|
||||||
|
SND_SEQ_EVENT_ECHO, (double) Mf_currtime+1);
|
||||||
|
ev.source.port = source_port;
|
||||||
|
ev.dest.queue = dest_queue;
|
||||||
|
ev.dest.client = snd_seq_client_id(seq_handle);
|
||||||
|
ev.dest.port = source_port;
|
||||||
|
ev.dest.channel = 0; /* don't care */
|
||||||
|
|
||||||
|
#ifdef USE_REALTIME
|
||||||
|
ev.flags = SND_SEQ_TIME_STAMP_REAL | SND_SEQ_TIME_MODE_ABS;
|
||||||
|
tick2time(&ev.time.real, Mf_currtime+1);
|
||||||
|
#else
|
||||||
|
ev.flags = SND_SEQ_TIME_STAMP_TICK | SND_SEQ_TIME_MODE_ABS;
|
||||||
|
ev.time.tick = Mf_currtime+1;
|
||||||
|
#endif
|
||||||
|
ev.type = SND_SEQ_EVENT_ECHO;
|
||||||
|
write_ev(&ev);
|
||||||
|
|
||||||
|
/* dump buffer */
|
||||||
|
left = snd_seq_flush_output(seq_handle);
|
||||||
|
|
||||||
|
/* wait for the timer start event */
|
||||||
|
for (;;) {
|
||||||
|
input_event = wait_for_event();
|
||||||
|
if (input_event) {
|
||||||
|
if (verbose >= VERB_MUCH)
|
||||||
|
printf("alsa_sync got event. type=%d, flags=%d\n",
|
||||||
|
input_event->type, input_event->flags);
|
||||||
|
if (input_event->type == SND_SEQ_EVENT_ECHO)
|
||||||
|
break;
|
||||||
|
snd_seq_free_event(input_event);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (verbose >= VERB_MUCH)
|
if (verbose >= VERB_MUCH)
|
||||||
printf("alsa_sync synced\n");
|
printf("alsa_sync synced\n");
|
||||||
}
|
}
|
||||||
|
|
@ -481,41 +496,21 @@ static void alsa_sync(void)
|
||||||
/* wait for start of the queue */
|
/* wait for start of the queue */
|
||||||
static void wait_start(void)
|
static void wait_start(void)
|
||||||
{
|
{
|
||||||
int left;
|
snd_seq_event_t *input_event;
|
||||||
snd_seq_event_t* input_event;
|
|
||||||
|
|
||||||
/* wait the start event from the system timer */
|
|
||||||
do {
|
|
||||||
#ifdef USE_BLOCKING_MODE
|
|
||||||
/* read event - blocked until any event is read */
|
|
||||||
left = snd_seq_event_input(seq_handle, &input_event);
|
|
||||||
#else
|
|
||||||
/* read event - using select syscall */
|
|
||||||
while ((left = snd_seq_event_input(seq_handle, &input_event)) >= 0 &&
|
|
||||||
input_event == NULL) {
|
|
||||||
int seqfd;
|
|
||||||
fd_set fds;
|
|
||||||
seqfd = snd_seq_file_descriptor(seq_handle);
|
|
||||||
FD_ZERO(&fds);
|
|
||||||
FD_SET(seqfd, &fds);
|
|
||||||
if ((left = select(seqfd + 1, &fds, NULL, NULL, NULL)) < 0) {
|
|
||||||
printf("select error = %i (%s)\n", left, snd_strerror(left));
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (left < 0) {
|
|
||||||
printf("alsa_sync error!:%s\n", snd_strerror(left));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (verbose >= VERB_MUCH)
|
/* wait the start event from the system timer */
|
||||||
printf("wait_start got event. type=%d, flags=%d\n",
|
for (;;) {
|
||||||
input_event->type, input_event->flags);
|
input_event = wait_for_event();
|
||||||
snd_seq_free_event(input_event);
|
if (input_event) {
|
||||||
|
if (verbose >= VERB_MUCH)
|
||||||
} while (input_event->type != SND_SEQ_EVENT_START);
|
printf("wait_start got event. type=%d, flags=%d\n",
|
||||||
|
input_event->type, input_event->flags);
|
||||||
|
if (input_event->type == SND_SEQ_EVENT_START &&
|
||||||
|
input_event->data.addr.queue == dest_queue)
|
||||||
|
break;
|
||||||
|
snd_seq_free_event(input_event);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (verbose >= VERB_MUCH)
|
if (verbose >= VERB_MUCH)
|
||||||
printf("start received\n");
|
printf("start received\n");
|
||||||
}
|
}
|
||||||
|
|
@ -527,30 +522,25 @@ static void usage(void)
|
||||||
fprintf(stderr, "usage: playmidi1 [options] [file]\n");
|
fprintf(stderr, "usage: playmidi1 [options] [file]\n");
|
||||||
fprintf(stderr, " options:\n");
|
fprintf(stderr, " options:\n");
|
||||||
fprintf(stderr, " -v: verbose mode\n");
|
fprintf(stderr, " -v: verbose mode\n");
|
||||||
fprintf(stderr, " -a queue:client:port : set destination address (default=%d:%d:%d)\n",
|
fprintf(stderr, " -a client:port : set destination address (default=%d:%d)\n",
|
||||||
DEST_QUEUE_NUMBER, DEST_CLIENT_NUMBER, DEST_PORT_NUMBER);
|
DEST_CLIENT_NUMBER, DEST_PORT_NUMBER);
|
||||||
fprintf(stderr, " -s: slave mode (allow external clock synchronisation)\n");
|
fprintf(stderr, " -s: slave mode (allow external clock synchronisation)\n");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* parse destination address (-a option) */
|
/* parse destination address (-a option) */
|
||||||
void parse_address(char *arg, int *queuep, int *clientp, int *portp)
|
void parse_address(char *arg, int *clientp, int *portp)
|
||||||
{
|
{
|
||||||
char *next;
|
char *next;
|
||||||
|
|
||||||
*queuep = atoi(arg);
|
*clientp = atoi(arg);
|
||||||
if ((next = strchr(arg, ':')) != NULL) {
|
if ((next = strchr(arg, ':')) != NULL)
|
||||||
*clientp = atoi(next + 1);
|
*portp = atoi(next + 1);
|
||||||
if ((next = strchr(next + 1, ':')) != NULL)
|
|
||||||
*portp = atoi(next + 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
snd_seq_client_info_t inf;
|
snd_seq_client_info_t inf;
|
||||||
snd_seq_port_info_t src_port_info;
|
snd_seq_port_info_t src_port_info;
|
||||||
snd_seq_queue_client_t queue_info;
|
|
||||||
snd_seq_port_subscribe_t subscribe;
|
snd_seq_port_subscribe_t subscribe;
|
||||||
snd_seq_client_pool_t pool;
|
snd_seq_client_pool_t pool;
|
||||||
int tmp;
|
int tmp;
|
||||||
|
|
@ -562,7 +552,7 @@ int main(int argc, char *argv[])
|
||||||
verbose++;
|
verbose++;
|
||||||
break;
|
break;
|
||||||
case 'a':
|
case 'a':
|
||||||
parse_address(optarg, &dest_queue, &dest_client, &dest_port);
|
parse_address(optarg, &dest_client, &dest_port);
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
slave = 1;
|
slave = 1;
|
||||||
|
|
@ -630,11 +620,9 @@ int main(int argc, char *argv[])
|
||||||
source_port = src_port_info.port;
|
source_port = src_port_info.port;
|
||||||
|
|
||||||
/* setup queue */
|
/* setup queue */
|
||||||
bzero(&queue_info,sizeof(queue_info));
|
dest_queue = snd_seq_alloc_queue(seq_handle);
|
||||||
queue_info.used = 1;
|
if (dest_queue < 0) {
|
||||||
tmp = snd_seq_set_queue_client(seq_handle, dest_queue, &queue_info);
|
perrror("alloc queue");
|
||||||
if (tmp < 0) {
|
|
||||||
perror("queue_client");
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue