]> git.alsa-project.org Git - alsa-lib.git/commitdiff
Takashi Iwai <iwai@ww.uni-erlangen.de>
authorJaroslav Kysela <perex@perex.cz>
Wed, 15 Dec 1999 18:34:12 +0000 (18:34 +0000)
committerJaroslav Kysela <perex@perex.cz>
Wed, 15 Dec 1999 18:34:12 +0000 (18:34 +0000)
Frank van de Pol <frank@vande-pol.demon.nl>
Major sequencer changes and cleanups for 1.0.0.

include/seqmid.h
src/seq/seq.c
src/seq/seqmid.c
test/aconnect.c
test/playmidi1.c
test/seq-decoder.c
test/seq-sender.c
test/seq.c

index eb96dce5f434d4d3dca6bfb461a9fe2b4affca87..cb60a9e5e1b744684d343ed57a78cdf79d396371 100644 (file)
@@ -27,7 +27,7 @@ void snd_seq_ev_set_source(snd_seq_event_t *ev, int port);
 void snd_seq_ev_set_direct(snd_seq_event_t *ev);
   /* scheduled on tick-queue */
 void snd_seq_ev_schedule_tick(snd_seq_event_t *ev, int q, int relative,
-                             unsigned long tick);
+                             snd_seq_tick_time_t tick);
   /* scheduled on real-time-queue */
 void snd_seq_ev_schedule_real(snd_seq_event_t *ev, int q, int relative,
                              snd_seq_real_time_t *real);
@@ -41,7 +41,22 @@ void snd_seq_ev_set_fixed(snd_seq_event_t *ev);
   /* variable size event */
 void snd_seq_ev_set_variable(snd_seq_event_t *ev, int len, void *ptr);
 
-/* queue controls -
+/* set queue control event data */
+/* destination is overwritten to Timer port (0:0) */
+int snd_seq_ev_set_queue_start(snd_seq_event_t *ev, int q);
+int snd_seq_ev_set_queue_stop(snd_seq_event_t *ev, int q);
+int snd_seq_ev_set_queue_continue(snd_seq_event_t *ev, int q);
+int snd_seq_ev_set_queue_tempo(snd_seq_event_t *ev, int q, int tempo);
+int snd_seq_ev_set_queue_control(snd_seq_event_t *ev, int type, int q, int value);
+int snd_seq_ev_set_queue_pos_real(snd_seq_event_t *ev, int q, snd_seq_real_time_t *rtime);
+int snd_seq_ev_set_queue_pos_tick(snd_seq_event_t *ev, int q, snd_seq_tick_time_t tick);
+
+/*
+ * use/unuse a queue
+ */
+int snd_seq_use_queue(snd_seq_t *seq, int q, int use);
+
+/* set and send a queue control event:
  * to send at scheduled time, set the schedule in ev.
  * if ev is NULL, event is sent immediately (to output queue).
  * Note: to send actually to driver, you need to call snd_seq_flush_event()
@@ -52,6 +67,7 @@ int snd_seq_start_queue(snd_seq_t *seq, int q, snd_seq_event_t *ev);
 int snd_seq_stop_queue(snd_seq_t *seq, int q, snd_seq_event_t *ev);
 int snd_seq_continue_queue(snd_seq_t *seq, int q, snd_seq_event_t *ev);
 int snd_seq_change_queue_tempo(snd_seq_t *seq, int q, int tempo, snd_seq_event_t *ev);
+int snd_seq_setpos_queue(snd_seq_t *seq, int q, snd_seq_timestamp_t *rtime, snd_seq_event_t *ev);
 
 /* create a port - simple version - return the port number */
 int snd_seq_create_simple_port(snd_seq_t *seq, char *name,
@@ -87,97 +103,101 @@ int snd_seq_reset_pool_input(snd_seq_t *seq);
 /*
  * equivalent macros
  */
-#define __snd_seq_ev_clear(ev) memset(ev, 0, sizeof(snd_seq_event_t))
-#define __snd_seq_ev_set_dest(ev,c,p) \
+#define snd_seq_ev_clear(ev)   memset(ev, 0, sizeof(snd_seq_event_t))
+#define snd_seq_ev_set_dest(ev,c,p) \
        ((ev)->dest.client = (c), (ev)->dest.port = (p))
-#define __snd_seq_ev_set_subs(ev) \
+#define snd_seq_ev_set_subs(ev) \
        ((ev)->dest.client = SND_SEQ_ADDRESS_SUBSCRIBERS,\
         (ev)->dest.port = SND_SEQ_ADDRESS_UNKNOWN)
-#define __snd_seq_ev_set_broadcast(ev) \
+#define snd_seq_ev_set_broadcast(ev) \
        ((ev)->dest.client = SND_SEQ_ADDRESS_BROADCAST,\
         (ev)->dest.port = SND_SEQ_ADDRESS_BROADCAST)
-#define __snd_seq_ev_set_source(ev,p) ((ev)->source.port = (p))
+#define snd_seq_ev_set_source(ev,p) ((ev)->source.port = (p))
 
-#define __snd_seq_start_queue(seq,q,ev) \
+/*
+ * queue controls
+ */
+#define snd_seq_ev_set_queue_control(ev,t,q,val) \
+       ((ev)->type = (t),\
+        snd_seq_ev_set_dest(ev, SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_TIMER),\
+        (ev)->data.queue.queue = (q),\
+        (ev)->data.queue.param.value = (val))
+#define snd_seq_ev_set_queue_start(ev,q) \
+       snd_seq_ev_set_queue_control(ev,SND_SEQ_EVENT_START,q,0)
+#define snd_seq_ev_set_queue_stop(ev,q) \
+       snd_seq_ev_set_queue_control(ev,SND_SEQ_EVENT_STOP,q,0)
+#define snd_seq_ev_set_queue_continue(ev,q) \
+       snd_seq_ev_set_queue_control(ev,SND_SEQ_EVENT_CONTINUE,q,0)
+#define snd_seq_ev_set_queue_tempo(ev,q,val) \
+       snd_seq_ev_set_queue_control(ev,SND_SEQ_EVENT_TEMPO,q,val)
+#define snd_seq_ev_set_queue_pos_real(ev,q,rtime) \
+       ((ev)->type = SND_SEQ_EVENT_SETPOS_TIME,\
+        snd_seq_ev_set_dest(ev, SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_TIMER),\
+        (ev)->data.queue.queue = (q),\
+        (ev)->data.queue.param.time.real = *(rtime))
+#define snd_seq_ev_set_queue_pos_tick(ev,q,ttime) \
+       ((ev)->type = SND_SEQ_EVENT_SETPOS_TICK,\
+        snd_seq_ev_set_dest(ev, SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_TIMER),\
+        (ev)->data.queue.queue = (q),\
+        (ev)->data.queue.param.time.tick = (ttime))
+
+#define snd_seq_start_queue(seq,q,ev) \
        snd_seq_control_queue(seq, q, SND_SEQ_EVENT_START, 0, ev)
-#define __snd_seq_stop_queue(seq,q,ev) \
+#define snd_seq_stop_queue(seq,q,ev) \
        snd_seq_control_queue(seq, q, SND_SEQ_EVENT_STOP, 0, ev)
-#define __snd_seq_continue_queue(seq,q,ev) \
+#define snd_seq_continue_queue(seq,q,ev) \
        snd_seq_control_queue(seq, q, SND_SEQ_EVENT_CONTINUE, 0, ev)
-#define __snd_seq_change_queue_tempo(seq,q,tempo,ev) \
+#define snd_seq_change_queue_tempo(seq,q,tempo,ev) \
        snd_seq_control_queue(seq, q, SND_SEQ_EVENT_TEMPO, tempo, ev)
 
-/*
- * redefintion
- */
-#define snd_seq_ev_clear(ev)           __snd_seq_ev_clear(ev)
-#define snd_seq_ev_set_dest(ev,c,p)    __snd_seq_ev_set_dest(ev,c,p)
-#define snd_seq_ev_set_subs(ev)                __snd_seq_ev_set_subs(ev)
-#define snd_seq_ev_set_broadcast(ev)   __snd_seq_ev_set_broadcast(ev)
-#define snd_seq_ev_set_source(ev,p)    __snd_seq_ev_set_source(ev,p)
-#define snd_seq_start_queue(seq,q,ev)  __snd_seq_start_queue(seq,q,ev)
-#define snd_seq_stop_queue(seq,q,ev)   __snd_seq_stop_queue(seq,q,ev)
-#define snd_seq_continue_queue(seq,q,ev)       __snd_seq_continue_queue(seq,q,ev)
-#define snd_seq_change_queue_tempo(seq,q,tempo,ev)     __snd_seq_change_queue_tempo(seq,q,tempo,ev)
-
-/*
- * check event flags
- */
-#define snd_seq_ev_is_direct(ev) ((ev)->flags & SND_SEQ_DEST_MASK)
-#define snd_seq_ev_is_prior(ev) ((ev)->flags & SND_SEQ_PRIORITY_MASK)
-#define snd_seq_ev_is_variable(ev) (((ev)->flags & SND_SEQ_EVENT_LENGTH_MASK) == SND_SEQ_EVENT_LENGTH_VARIABLE)
-#define snd_seq_ev_is_realtime(ev) ((ev)->flags & SND_SEQ_TIME_STAMP_MASK)
-#define snd_seq_ev_is_relative(ev) ((ev)->flags & SND_SEQ_TIME_MODE_MASK)
-/* ... etc. */
-
 /*
  * macros to set standard event data
  */
 #define snd_seq_ev_set_note(ev,ch,key,vel,dur) \
        ((ev)->type = SND_SEQ_EVENT_NOTE,\
         snd_seq_ev_set_fixed(ev),\
-        (ev)->dest.channel = (ch),\
+        (ev)->data.note.channel = (ch),\
         (ev)->data.note.note = (key),\
         (ev)->data.note.velocity = (vel),\
         (ev)->data.note.dulation = (dur))
 #define snd_seq_ev_set_noteon(ev,ch,key,vel) \
        ((ev)->type = SND_SEQ_EVENT_NOTEON,\
         snd_seq_ev_set_fixed(ev),\
-        (ev)->dest.channel = (ch),\
+        (ev)->data.note.channel = (ch),\
         (ev)->data.note.note = (key),\
         (ev)->data.note.velocity = (vel))
 #define snd_seq_ev_set_noteoff(ev,ch,key,vel) \
        ((ev)->type = SND_SEQ_EVENT_NOTEOFF,\
         snd_seq_ev_set_fixed(ev),\
-        (ev)->dest.channel = (ch),\
+        (ev)->data.note.channel = (ch),\
         (ev)->data.note.note = (key),\
         (ev)->data.note.velocity = (vel))
 #define snd_seq_ev_set_keypress(ev,ch,key,vel) \
        ((ev)->type = SND_SEQ_EVENT_KEYPRESS,\
         snd_seq_ev_set_fixed(ev),\
-        (ev)->dest.channel = (ch),\
+        (ev)->data.note.channel = (ch),\
         (ev)->data.note.note = (key),\
         (ev)->data.note.velocity = (vel))
 #define snd_seq_ev_set_controller(ev,ch,cc,val) \
        ((ev)->type = SND_SEQ_EVENT_CONTROLLER,\
         snd_seq_ev_set_fixed(ev),\
-        (ev)->dest.channel = (ch),\
+        (ev)->data.control.channel = (ch),\
         (ev)->data.control.param = (cc),\
         (ev)->data.control.value = (val))
 #define snd_seq_ev_set_pgmchange(ev,ch,val) \
        ((ev)->type = SND_SEQ_EVENT_PGMCHANGE,\
         snd_seq_ev_set_fixed(ev),\
-        (ev)->dest.channel = (ch),\
+        (ev)->data.control.channel = (ch),\
         (ev)->data.control.value = (val))
 #define snd_seq_ev_set_pitchbend(ev,ch,val) \
        ((ev)->type = SND_SEQ_EVENT_PITCHBEND,\
         snd_seq_ev_set_fixed(ev),\
-        (ev)->dest.channel = (ch),\
+        (ev)->data.control.channel = (ch),\
         (ev)->data.control.value = (val))
 #define snd_seq_ev_set_chanpress(ev,ch,val) \
        ((ev)->type = SND_SEQ_EVENT_CHANPRESS,\
         snd_seq_ev_set_fixed(ev),\
-        (ev)->dest.channel = (ch),\
+        (ev)->data.control.channel = (ch),\
         (ev)->data.control.value = (val))
 #define snd_seq_ev_set_sysex(ev,datalen,dataptr) \
        ((ev)->type = SND_SEQ_EVENT_SYSEX,\
index 20de7c62207de0771463da0656f595cbf7ddbd69..5b186a12e6462562f3a90a12c127dcb605db2f31 100644 (file)
@@ -31,7 +31,7 @@
 
 #define SND_FILE_SEQ           "/dev/snd/seq"
 #define SND_FILE_ALOADSEQ      "/dev/aloadSEQ"
-#define SND_SEQ_VERSION_MAX    SND_PROTOCOL_VERSION( 0, 0, 1 )
+#define SND_SEQ_VERSION_MAX    SND_PROTOCOL_VERSION( 1, 0, 0 )
 #define SND_SEQ_OBUF_SIZE      (16*1024)       /* should be configurable */
 #define SND_SEQ_IBUF_SIZE      (4*1024)        /* should be configurable */
 
@@ -721,7 +721,10 @@ static int remove_match(snd_seq_remove_events_t *info,
                        return 0;
        }
        if (info->remove_mode & SND_SEQ_REMOVE_DEST_CHANNEL) {
-               if (ev->dest.channel != info->dest.channel)
+               if (! snd_seq_ev_is_channel_type(ev))
+                       return 0;
+               /* data.note.channel and data.control.channel are identical */
+               if (ev->data.note.channel != info->channel)
                        return 0;
        }
        if (info->remove_mode & SND_SEQ_REMOVE_TIME_AFTER) {
index f2999e0db6e103ab9b98344988db4a7a4a1ae6ad..0e1de70db316a590909c1a0cf3acfae914f012a6 100644 (file)
@@ -35,12 +35,12 @@ void snd_seq_ev_set_direct(snd_seq_event_t *ev)
 {
        ev->flags &= ~SND_SEQ_DEST_MASK;
        ev->flags |= SND_SEQ_DEST_DIRECT;
-       ev->dest.queue = SND_SEQ_ADDRESS_UNKNOWN; /* XXX */
+       ev->queue = SND_SEQ_ADDRESS_UNKNOWN; /* XXX */
 }
 
 /* queued on tick */
 void snd_seq_ev_schedule_tick(snd_seq_event_t *ev, int q, int relative,
-                             unsigned long tick)
+                             snd_seq_tick_time_t tick)
 {
        ev->flags &= ~(SND_SEQ_DEST_MASK | SND_SEQ_TIME_STAMP_MASK |
                       SND_SEQ_TIME_MODE_MASK);
@@ -85,11 +85,21 @@ void snd_seq_ev_set_variable(snd_seq_event_t *ev, int len, void *ptr)
        ev->data.ext.ptr = ptr;
 }
 
+
+/* use or unuse a queue */
+int snd_seq_use_queue(snd_seq_t *seq, int q, int use)
+{
+       snd_seq_queue_client_t info;
+
+       memset(&info, 0, sizeof(info));
+       info.used = use;
+       return snd_seq_set_queue_client(seq, q, &info);
+}
+
+
 /* queue controls - start/stop/continue */
 /* if ev is NULL, send events immediately.
-   otherwise, duplicate the given event data.
-   destination is overwritten to Timer port (0:0)
-   */
+   otherwise, duplicate the given event data. */
 int snd_seq_control_queue(snd_seq_t *seq, int q, int type, int value, snd_seq_event_t *ev)
 {
        snd_seq_event_t tmpev;
@@ -98,22 +108,35 @@ int snd_seq_control_queue(snd_seq_t *seq, int q, int type, int value, snd_seq_ev
                ev = &tmpev;
                snd_seq_ev_set_direct(ev);
        }
-
-       ev->type = type;
-       snd_seq_ev_set_dest(ev, SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_TIMER);
-#if 1
-       /* new type */
-       ev->data.queue.addr.queue = q;
-       ev->data.queue.value = value;
-#else
-       /* old type */
-       ev->dest.queue = q;
-       ev->data.control.value = value;
-#endif
-
+       snd_seq_ev_set_queue_control(ev, type, q, value);
        return snd_seq_event_output(seq, ev);
 }
 
+/* reset queue position:
+ * new values of both real-time and tick values must be given.
+ */
+int snd_seq_setpos_queue(snd_seq_t *seq, int q, snd_seq_timestamp_t *rtime, snd_seq_event_t *ev)
+{
+       snd_seq_event_t tmpev;
+       int result;
+
+       if (ev == NULL) {
+               snd_seq_ev_clear(&tmpev);
+               ev = &tmpev;
+               snd_seq_ev_set_direct(ev);
+       }
+       /* stop the timer */
+       result = snd_seq_stop_queue(seq, q, ev);
+       /* reset queue position */
+       snd_seq_ev_set_queue_pos_real(ev, q, &rtime->real);
+       result = snd_seq_event_output(seq, ev);
+       snd_seq_ev_set_queue_pos_tick(ev, q, rtime->tick);
+       result = snd_seq_event_output(seq, ev);
+       /* continue the timer */
+       result = snd_seq_continue_queue(seq, q, ev);
+
+       return result;
+}
 
 /* create a port - simple version
  * return the port number
@@ -295,7 +318,7 @@ int snd_seq_set_client_pool_input(snd_seq_t *seq, int size)
 
 /*
  * reset client input/output pool
- * use REMOVE_EVENTS ioctl instead of RESET_POOL
+ * use REMOVE_EVENTS ioctl
  */
 int snd_seq_reset_pool_output(snd_seq_t *seq)
 {
index 0adf8d6ffc69339999359a2ca14bea7164c2adfd..124afb913884f96d37b152e4b2bb103a0b912a0d 100644 (file)
@@ -78,10 +78,16 @@ static void list_each_subs(snd_seq_t *seq, snd_seq_query_subs_t *subs, int type,
        subs->index = 0;
        while (snd_seq_query_port_subscribers(seq, subs) >= 0) {
                if (subs->index == 0)
-                       printf("\t%s: %d:%d:%d", msg,
-                              subs->addr.queue, subs->addr.client, subs->addr.port);
+                       printf("\t%s: ", msg);
                else
-                       printf(", %d:%d:%d", subs->addr.queue, subs->addr.client, subs->addr.port);
+                       printf(", ");
+               printf("%d:%d", subs->addr.client, subs->addr.port);
+               if (subs->exclusive)
+                       printf("[ex]");
+               if (subs->convert_time)
+                       printf("[%s:%d]",
+                              (subs->realtime ? "real" : "tick"),
+                              subs->queue);
                subs->index++;
        }
        if (subs->index)
@@ -228,7 +234,7 @@ int main(int argc, char **argv)
        memset(&subs, 0, sizeof(subs));
        parse_address(&subs.sender, argv[optind]);
        parse_address(&subs.dest, argv[optind + 1]);
-       subs.sender.queue = subs.dest.queue = queue;
+       subs.queue = queue;
        subs.exclusive = 0;
        subs.convert_time = 0;
        subs.realtime = 0;
index 37446b0e812cf5293c28b068676fd703a7f180b2..91ab16748fe246dd23caec92e7f34d44f03189f0 100644 (file)
@@ -438,7 +438,7 @@ static void wait_start(void)
                                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) {
+                           input_event->data.queue.queue == dest_queue) {
                                snd_seq_free_event(input_event);
                                break;
                        }
@@ -458,7 +458,7 @@ static void usage(void)
        fprintf(stderr, "  -v: verbose mode\n");
        fprintf(stderr, "  -a client:port : set destination address (default=%d:%d)\n",
                DEST_CLIENT_NUMBER, DEST_PORT_NUMBER);
-       fprintf(stderr, "  -s: slave mode (allow external clock synchronisation)\n");
+       fprintf(stderr, "  -s queue: slave mode (allow external clock synchronisation)\n");
 }
 
 /* parse destination address (-a option) */
@@ -476,7 +476,7 @@ int main(int argc, char *argv[])
        int tmp;
        int c;
 
-       while ((c = getopt(argc, argv, "sa:v")) != -1) {
+       while ((c = getopt(argc, argv, "s:a:v")) != -1) {
                switch (c) {
                case 'v':
                        verbose++;
@@ -486,6 +486,11 @@ int main(int argc, char *argv[])
                        break;
                case 's':
                        slave = 1;
+                       dest_queue = atoi(optarg);
+                       if (dest_queue < 0) {
+                               fprintf(stderr, "invalid queue number %d\n", dest_queue);
+                               exit(1);
+                       }
                        break;
                default:
                        usage();
@@ -525,7 +530,7 @@ int main(int argc, char *argv[])
        /* if running in slave mode also listen for START event */
        snd_seq_set_client_event_filter(seq_handle, SND_SEQ_EVENT_ECHO);
        if (slave)
-               snd_seq_set_client_event_filter(seq_handle, SND_SEQ_EVENT_ECHO);
+               snd_seq_set_client_event_filter(seq_handle, SND_SEQ_EVENT_START);
        snd_seq_set_client_name(seq_handle, "MIDI file player");
 
        /* create port */
@@ -539,10 +544,14 @@ int main(int argc, char *argv[])
        }
        
        /* setup queue */
-       dest_queue = snd_seq_alloc_queue(seq_handle);
-       if (dest_queue < 0) {
-               perror("alloc queue");
-               exit(1);
+       if (slave) {
+               snd_seq_use_queue(seq_handle, dest_queue, 1);
+       } else {
+               dest_queue = snd_seq_alloc_queue(seq_handle);
+               if (dest_queue < 0) {
+                       perror("alloc queue");
+                       exit(1);
+               }
        }
 
        /* setup subscriber */
index 1c0e48cd28af494905bcbd3c2e8936b0bc3ad04f..c402d4962d30fba733cc7bb9e0ff05e9b13645f0 100644 (file)
@@ -287,22 +287,20 @@ int decode_event(snd_seq_event_t * ev)
                               (int)ev->time.real.tv_nsec);
                        break;
        }
-       printf("\n%sSource = %d.%d.%d.%d, dest = %d.%d.%d.%d\n",
+       printf("\n%sSource = %d.%d, dest = %d.%d, queue = %d\n",
               space,
-              ev->source.queue,
               ev->source.client,
               ev->source.port,
-              ev->source.channel,
-              ev->dest.queue,
               ev->dest.client,
               ev->dest.port,
-              ev->dest.channel);
+              ev->queue);
 
        printf("%sEvent = %s", space, event_names[ev->type]);
        /* decode actual event data... */
        switch (ev->type) {
                case SND_SEQ_EVENT_NOTE:
-                       printf("; note=%d, velocity=%d, duration=%d\n",
+                       printf("; ch=%d, note=%d, velocity=%d, duration=%d\n",
+                              ev->data.note.channel,
                               ev->data.note.note,
                               ev->data.note.velocity,
                               ev->data.note.duration);
@@ -310,25 +308,31 @@ int decode_event(snd_seq_event_t * ev)
 
                case SND_SEQ_EVENT_NOTEON:
                case SND_SEQ_EVENT_NOTEOFF:
-                       printf("; note=%d, velocity=%d\n",
+               case SND_SEQ_EVENT_KEYPRESS:
+                       printf("; ch=%d, note=%d, velocity=%d\n",
+                              ev->data.note.channel,
                               ev->data.note.note,
                               ev->data.note.velocity);
                        break;
                
-               case SND_SEQ_EVENT_KEYPRESS:
                case SND_SEQ_EVENT_CONTROLLER:
-                       printf("; param=%i, value=%i\n",
-                               ev->data.control.param,
-                               ev->data.control.value);
+                       printf("; ch=%d, param=%i, value=%i\n",
+                              ev->data.control.channel,
+                              ev->data.control.param,
+                              ev->data.control.value);
                        break;
 
                case SND_SEQ_EVENT_PGMCHANGE:
-                       printf("; program=%i\n", ev->data.control.value);
+                       printf("; ch=%d, program=%i\n",
+                              ev->data.control.channel,
+                              ev->data.control.value);
                        break;
                        
                case SND_SEQ_EVENT_CHANPRESS:
                case SND_SEQ_EVENT_PITCHBEND:
-                       printf("; value=%i\n", ev->data.control.value);
+                       printf("; ch=%d, value=%i\n",
+                              ev->data.control.channel,
+                              ev->data.control.value);
                        break;
                        
                case SND_SEQ_EVENT_SYSEX:
@@ -353,10 +357,10 @@ int decode_event(snd_seq_event_t * ev)
                case SND_SEQ_EVENT_START:
                case SND_SEQ_EVENT_CONTINUE:
                case SND_SEQ_EVENT_STOP:
-                       printf("; queue = %i, client = %i\n", ev->data.addr.queue, ev->data.addr.client);
+                       printf("; queue = %i\n", ev->data.queue.queue);
                        break;
 
-               case SND_SEQ_EVENT_HEARTBEAT:
+               case SND_SEQ_EVENT_SENSING:
                        printf("\n");
                        break;
 
@@ -402,18 +406,8 @@ int decode_event(snd_seq_event_t * ev)
 void event_decoder_start_timer(snd_seq_t *handle, int queue, int client, int port)
 {
        int err;
-       snd_seq_event_t ev;
-       
-       bzero(&ev, sizeof(ev));
-       ev.source.queue = queue;
-       ev.source.client = client;
-       ev.source.port = 0;
-       ev.dest.queue = queue;
-       ev.dest.client = SND_SEQ_CLIENT_SYSTEM;
-       ev.dest.port = SND_SEQ_PORT_SYSTEM_TIMER;
-       ev.flags = SND_SEQ_TIME_STAMP_REAL | SND_SEQ_TIME_MODE_REL;
-       ev.type = SND_SEQ_EVENT_START;
-       if ((err = snd_seq_event_output(handle, &ev))<0)
+
+       if ((err = snd_seq_start_queue(handle, queue, NULL))<0)
                fprintf(stderr, "Timer event output error: %s\n", snd_strerror(err));
        while (snd_seq_flush_output(handle)>0)
                sleep(1);
@@ -442,7 +436,7 @@ void event_decoder(snd_seq_t *handle, int argc, char *argv[])
                fprintf(stderr, "Cannot set nonblock mode: %s\n", snd_strerror(err));
        bzero(&port, sizeof(port));
        strcpy(port.name, "Input");
-       port.capability = SND_SEQ_PORT_CAP_WRITE;
+       port.capability = SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_READ; 
        if ((err = snd_seq_create_port(handle, &port)) < 0) {
                fprintf(stderr, "Cannot create input port: %s\n", snd_strerror(err));
                return;
@@ -450,10 +444,8 @@ void event_decoder(snd_seq_t *handle, int argc, char *argv[])
        event_decoder_start_timer(handle, queue, client, port.port);
 
        bzero(&sub, sizeof(sub));
-       sub.sender.queue = queue;
        sub.sender.client = SND_SEQ_CLIENT_SYSTEM;
        sub.sender.port = SND_SEQ_PORT_SYSTEM_ANNOUNCE;
-       sub.dest.queue = queue;
        sub.dest.client = client;
        sub.dest.port = port.port;
        sub.exclusive = 0;
index 595105c3d5e304f6b4b3094d776b074369cd88ef..10dea1807514e4a4daefa8cf33c7ec46ad3e773e 100644 (file)
@@ -1,3 +1,5 @@
+
+#ifdef USE_PCM
 /*
  *  PCM timer layer
  */
@@ -50,7 +52,7 @@ void show_playback_status(snd_pcm_t *phandle)
        printf("    Fragments      : %i\n", pstatus.fragments);
        printf("    Fragment size  : %i\n", pstatus.fragment_size);
 }
-
+#endif
 /*
  *  Simple event sender
  */
@@ -58,8 +60,8 @@ void show_playback_status(snd_pcm_t *phandle)
 void event_sender_start_timer(snd_seq_t *handle, int client, int queue, snd_pcm_t *phandle)
 {
        int err;
-       snd_seq_event_t ev;
        
+#ifdef USE_PCM
        if (phandle) {
                snd_pcm_playback_info_t pinfo;
                snd_seq_queue_timer_t qtimer;
@@ -78,16 +80,8 @@ void event_sender_start_timer(snd_seq_t *handle, int client, int queue, snd_pcm_
                        exit(0);
                }
        }       
-       bzero(&ev, sizeof(ev));
-       ev.source.queue = queue;
-       ev.source.client = client;
-       ev.source.port = 0;
-       ev.dest.queue = queue;
-       ev.dest.client = SND_SEQ_CLIENT_SYSTEM;
-       ev.dest.port = SND_SEQ_PORT_SYSTEM_TIMER;
-       ev.flags = SND_SEQ_TIME_STAMP_REAL | SND_SEQ_TIME_MODE_REL;
-       ev.type = SND_SEQ_EVENT_START;
-       if ((err = snd_seq_event_output(handle, &ev))<0)
+#endif
+       if ((err = snd_seq_start_queue(handle, queue, NULL))<0)
                fprintf(stderr, "Timer event output error: %s\n", snd_strerror(err));
        /* ugly, but working */
        while (snd_seq_flush_output(handle)>0)
@@ -119,7 +113,7 @@ void send_event(snd_seq_t *handle, int queue, int client, int port,
        snd_seq_event_t ev;
        
        bzero(&ev, sizeof(ev));
-       ev.source.queue = ev.dest.queue = queue;
+       ev.queue = queue;
        ev.source.client = ev.dest.client = client;
        ev.source.port = ev.dest.port = port;
        ev.flags = SND_SEQ_TIME_STAMP_REAL | SND_SEQ_TIME_MODE_ABS;
@@ -129,10 +123,11 @@ void send_event(snd_seq_t *handle, int queue, int client, int port,
                fprintf(stderr, "Event output error: %s\n", snd_strerror(err));
        ev.dest.client = sub->dest.client;
        ev.dest.port = sub->dest.port;
-       ev.dest.channel = 0;
        ev.type = SND_SEQ_EVENT_NOTE;
+       ev.data.note.channel = 0;
        ev.data.note.note = 64 + (queue*2);
        ev.data.note.velocity = 127;
+       ev.data.note.off_velocity = 127;
        ev.data.note.duration = 500;    /* 0.5sec */
        if ((err = snd_seq_event_output(handle, &ev))<0)
                fprintf(stderr, "Event output error: %s\n", snd_strerror(err));
@@ -178,10 +173,8 @@ void event_sender(snd_seq_t *handle, int argc, char *argv[])
        }
 
        bzero(&sub, sizeof(sub));
-       sub.sender.queue = queue;
        sub.sender.client = client;
        sub.sender.port = port.port;
-       sub.dest.queue = queue;
        sub.exclusive = 0;
 
        for (max = 0; max < argc; max++) {
@@ -206,6 +199,7 @@ void event_sender(snd_seq_t *handle, int argc, char *argv[])
 
        printf("Destonation client = %i, port = %i\n", sub.dest.client, sub.dest.port);
 
+#ifdef USE_PCM
        if (pcm_flag) {
                if ((err = snd_pcm_open(&phandle, pcard, pdevice, SND_PCM_OPEN_PLAYBACK)) < 0) {
                        fprintf(stderr, "Playback open error: %s\n", snd_strerror(err));
@@ -220,6 +214,7 @@ void event_sender(snd_seq_t *handle, int argc, char *argv[])
                        exit(0);
                }
        }
+#endif
        event_sender_start_timer(handle, client, queue, phandle);
        
        first = 1;
@@ -229,19 +224,23 @@ void event_sender(snd_seq_t *handle, int argc, char *argv[])
                max = snd_seq_file_descriptor(handle);
                FD_SET(snd_seq_file_descriptor(handle), &out);
                FD_SET(snd_seq_file_descriptor(handle), &in);
+#ifdef USE_PCM
                if (phandle) {
                        if (snd_pcm_file_descriptor(phandle) > max)
                                max = snd_pcm_file_descriptor(phandle);
                        FD_SET(snd_pcm_file_descriptor(phandle), &out);
                }
+#endif
                if (select(max + 1, &in, &out, NULL, NULL) < 0)
                        break;
+#ifdef USE_PCM
                if (phandle && FD_ISSET(snd_pcm_file_descriptor(phandle), &out)) {
                        if (snd_pcm_write(phandle, pbuf, pfragment_size) != pfragment_size) {
                                fprintf(stderr, "Playback write error!!\n");
                                exit(0);
                        }
                }
+#endif
                if (FD_ISSET(snd_seq_file_descriptor(handle), &out)) {
                        if (first) {
                                send_event(handle, queue, client, port.port, &sub, &time);
index 6b2453490d149020553b7288ead2f921fe3ccc4c..149f76aa8605922c7b3efc806258e72e0af745f2 100644 (file)
@@ -151,6 +151,8 @@ int main(int argc, char *argv[])
                {"version", 0, NULL, HELPID_VERSION},
                {NULL, 0, NULL, 0},
         };
+        
+        morehelp = 0;
        
        while (1) {
                int c;
@@ -193,6 +195,7 @@ int main(int argc, char *argv[])
        }
        set_name(handle);
        system_info(handle);
+
         if (!strcmp(argv[optind], "system")) {
                show_system_info(handle);
        } else if (!strcmp(argv[optind], "queue")) {