~ubuntu-branches/ubuntu/trusty/alsa-utils/trusty

« back to all changes in this revision

Viewing changes to .pc/spelling_fixes.patch/seq/aseqnet/aseqnet.c

  • Committer: Package Import Robot
  • Author(s): Luke Yelavich
  • Date: 2013-07-26 10:56:44 UTC
  • mfrom: (1.2.17) (93.1.1 saucy-proposed)
  • Revision ID: package-import@ubuntu.com-20130726105644-kim9enke2jnozg73
Tags: 1.0.27.1-1ubuntu1
* Merge from debian unstable.  Remaining changes:
  - Move init script volume settings to new alsactl database:
    + Set sane level for 'Speaker' and 'Headphone', needed for Dell Mini 9
      and Dell E series
    + ute PC Beep on hda cards that support it during initial volume setup
    + Mute *Analog/Digital Control for Creative cards by default
    + Default Digital Input Source to be Digital Mic 1 so that users
      with digital mic will be able to use it out of the box
    + Mute "IEC958 Optical Raw" by default
    + Set sane level for headphone 1 for Dell Studio XPS with 2.6.30
    + Prefer built-in digital mics on newer Dells
    + Unmute 'Line HP Swap' for Dove boards
    + Set reasonable volume levels for VMWare guests using snd.ens1371
  - debian/README.init.cs4236: Include in /usr/share/doc/alsa-utils so that
    users of snd-cs4236 (e.g., ThinkPad 600) can have audible sound
  - debian/patches/unset_pulse_internal.patch: We don't want alsamixer to
    show the pulse mixer by default, since it can be controlled from
    pulseaudio itself
  - Use upstart jobs for storing/restoring card settings
  - Add udev rule to apply UCM profiles for panda and equivalent hardware
  - Add Vcs-Bzr field
* Create a new upstart job for the alsa state daemon, and adjust the
  other upstart jobs accordingly
* Put the daemon file in /var/lib/alsa

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * network server/client for ALSA sequencer
3
 
 *   ver.0.1
4
 
 *
5
 
 * Copyright (C) 1999-2000 Takashi Iwai
6
 
 * 
7
 
 *  This program is free software; you can redistribute it and/or modify
8
 
 *  it under the terms of the GNU General Public License version 2 as
9
 
 *  published by the Free Software Foundation.
10
 
 * 
11
 
 *  This program is distributed in the hope that it will be useful,
12
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
 *  GNU General Public License for more details.
15
 
 *
16
 
 */
17
 
 
18
 
#include <stdio.h>
19
 
#include <stdlib.h>
20
 
#include <ctype.h>
21
 
#include <string.h>
22
 
#include <netinet/in.h>
23
 
#include <sys/socket.h>
24
 
#include <netdb.h>
25
 
#include <locale.h>
26
 
#include <alsa/asoundlib.h>
27
 
#include <getopt.h>
28
 
#include <signal.h>
29
 
#include <assert.h>
30
 
#include "aconfig.h"
31
 
#include "gettext.h"
32
 
 
33
 
/*
34
 
 * prototypes
35
 
 */
36
 
static void usage(void);
37
 
static void init_buf(void);
38
 
static void init_pollfds(void);
39
 
static void close_files(void);
40
 
static void init_seq(char *source, char *dest);
41
 
static int get_port(char *service);
42
 
static void sigterm_exit(int sig);
43
 
static void init_server(int port);
44
 
static void init_client(char *server, int port);
45
 
static void do_loop(void);
46
 
static int copy_local_to_remote(void);
47
 
static int copy_remote_to_local(int fd);
48
 
 
49
 
/*
50
 
 * default TCP port number
51
 
 */
52
 
#define DEFAULT_PORT    40002
53
 
 
54
 
/*
55
 
 * local input buffer
56
 
 */
57
 
static char *readbuf;
58
 
static int max_rdlen;
59
 
static char *writebuf;
60
 
static int cur_wrlen, max_wrlen;
61
 
 
62
 
#define MAX_BUF_EVENTS  200
63
 
#define MAX_CONNECTION  10
64
 
 
65
 
static snd_seq_t *handle;
66
 
static struct pollfd *seqifds = NULL;
67
 
static struct pollfd *seqofds = NULL;
68
 
static struct pollfd *pollfds = NULL;
69
 
static int seqifds_count = 0;
70
 
static int seqofds_count = 0;
71
 
static int pollfds_count = 0;
72
 
static int sockfd, netfd[MAX_CONNECTION] = {[0 ... MAX_CONNECTION-1] = -1};
73
 
static int max_connection;
74
 
static int cur_connected;
75
 
static int seq_port;
76
 
 
77
 
static int server_mode;
78
 
static int verbose = 0;
79
 
static int info = 0;
80
 
 
81
 
 
82
 
/*
83
 
 * main routine
84
 
 */
85
 
 
86
 
static const struct option long_option[] = {
87
 
        {"port", 1, NULL, 'p'},
88
 
        {"source", 1, NULL, 's'},
89
 
        {"dest", 1, NULL, 'd'},
90
 
        {"help", 0, NULL, 'h'},
91
 
        {"verbose", 0, NULL, 'v'},
92
 
        {"info", 0, NULL, 'i'},
93
 
        {NULL, 0, NULL, 0},
94
 
};
95
 
 
96
 
int main(int argc, char **argv)
97
 
{
98
 
        int c;
99
 
        int port = DEFAULT_PORT;
100
 
        char *source = NULL, *dest = NULL;
101
 
 
102
 
#ifdef ENABLE_NLS
103
 
        setlocale(LC_ALL, "");
104
 
        textdomain(PACKAGE);
105
 
#endif
106
 
 
107
 
        while ((c = getopt_long(argc, argv, "p:s:d:vi", long_option, NULL)) != -1) {
108
 
                switch (c) {
109
 
                case 'p':
110
 
                        if (isdigit(*optarg))
111
 
                                port = atoi(optarg);
112
 
                        else
113
 
                                port = get_port(optarg);
114
 
                        break;
115
 
                case 's':
116
 
                        source = optarg;
117
 
                        break;
118
 
                case 'd':
119
 
                        dest = optarg;
120
 
                        break;
121
 
                case 'v':
122
 
                        verbose++;
123
 
                        break;
124
 
                case 'i':
125
 
                        info++;
126
 
                        break;
127
 
                default:
128
 
                        usage();
129
 
                        exit(1);
130
 
                }
131
 
        }
132
 
 
133
 
        signal(SIGINT, sigterm_exit);
134
 
        signal(SIGTERM, sigterm_exit);
135
 
 
136
 
        init_buf();
137
 
        init_seq(source, dest);
138
 
 
139
 
        if (optind >= argc) {
140
 
                server_mode = 1;
141
 
                max_connection = MAX_CONNECTION;
142
 
                init_pollfds();
143
 
                init_server(port);
144
 
        } else {
145
 
                server_mode = 0;
146
 
                max_connection = 1;
147
 
                init_pollfds();
148
 
                init_client(argv[optind], port);
149
 
        }
150
 
 
151
 
        do_loop();
152
 
 
153
 
        close_files();
154
 
 
155
 
        return 0;
156
 
}
157
 
 
158
 
 
159
 
/*
160
 
 * print usage
161
 
 */
162
 
static void usage(void)
163
 
{
164
 
        printf(_("aseqnet - network client/server on ALSA sequencer\n"));
165
 
        printf(_("  Copyright (C) 1999 Takashi Iwai\n"));
166
 
        printf(_("usage:\n"));
167
 
        printf(_("  server mode: aseqnet [-options]\n"));
168
 
        printf(_("  client mode: aseqnet [-options] server_host\n"));
169
 
        printf(_("options:\n"));
170
 
        printf(_("  -p,--port # : sepcify TCP port (digit or service name)\n"));
171
 
        printf(_("  -s,--source addr : read from given addr (client:port)\n"));
172
 
        printf(_("  -d,--dest addr : write to given addr (client:port)\n"));
173
 
        printf(_("  -v, --verbose : print verbose messages\n"));
174
 
        printf(_("  -i, --info : print certain received events\n"));
175
 
}
176
 
 
177
 
 
178
 
/*
179
 
 * allocate and initialize buffers
180
 
 */
181
 
static void init_buf(void)
182
 
{
183
 
        max_wrlen = MAX_BUF_EVENTS * sizeof(snd_seq_event_t);
184
 
        max_rdlen = MAX_BUF_EVENTS * sizeof(snd_seq_event_t);
185
 
        writebuf = malloc(max_wrlen);
186
 
        readbuf = malloc(max_rdlen);
187
 
        if (writebuf == NULL || readbuf == NULL) {
188
 
                fprintf(stderr, _("can't malloc\n"));
189
 
                exit(1);
190
 
        }
191
 
        memset(writebuf, 0, max_wrlen);
192
 
        memset(readbuf, 0, max_rdlen);
193
 
        cur_wrlen = 0;
194
 
}
195
 
 
196
 
/*
197
 
 * allocate and initialize poll array
198
 
 */
199
 
static void init_pollfds(void)
200
 
{
201
 
        pollfds_count = seqifds_count + seqofds_count + 1 + max_connection;
202
 
        pollfds = (struct pollfd *)calloc(pollfds_count, sizeof(struct pollfd));
203
 
        assert(pollfds);
204
 
}
205
 
 
206
 
/*
207
 
 * close all files
208
 
 */
209
 
static void close_files(void)
210
 
{
211
 
        int i;
212
 
        if (verbose)
213
 
                fprintf(stderr, _("closing files..\n"));
214
 
        for (i = 0; i < max_connection; i++) {
215
 
                if (netfd[i] >= 0)
216
 
                        close(netfd[i]);
217
 
        }
218
 
        if (sockfd >= 0)
219
 
                close(sockfd);
220
 
}
221
 
 
222
 
 
223
 
/*
224
 
 * initialize sequencer
225
 
 */
226
 
static void init_seq(char *source, char *dest)
227
 
{
228
 
        snd_seq_addr_t addr;
229
 
        int err, counti, counto;
230
 
 
231
 
        if (snd_seq_open(&handle, "default", SND_SEQ_OPEN_DUPLEX, 0) < 0) {
232
 
                perror("snd_seq_open");
233
 
                exit(1);
234
 
        }
235
 
        if (seqifds)
236
 
                free(seqifds);
237
 
        if (seqofds)
238
 
                free(seqofds);
239
 
        counti = seqifds_count = snd_seq_poll_descriptors_count(handle, POLLIN);
240
 
        assert(counti > 0);
241
 
        counto = seqofds_count = snd_seq_poll_descriptors_count(handle, POLLOUT);
242
 
        assert(counto > 0);
243
 
        seqifds = (struct pollfd *)calloc(counti, sizeof(struct pollfd));
244
 
        assert(seqifds);
245
 
        seqofds = (struct pollfd *)calloc(counto, sizeof(struct pollfd));
246
 
        assert(seqofds);
247
 
        err = snd_seq_poll_descriptors(handle, seqifds, counti, POLLIN);
248
 
        assert(err == counti);
249
 
        err = snd_seq_poll_descriptors(handle, seqofds, counto, POLLOUT);
250
 
        assert(err == counto);
251
 
 
252
 
        snd_seq_nonblock(handle, 1);
253
 
 
254
 
        /* set client info */
255
 
        if (server_mode)
256
 
                snd_seq_set_client_name(handle, "Net Server");
257
 
        else
258
 
                snd_seq_set_client_name(handle, "Net Client");
259
 
 
260
 
        /* create a port */
261
 
        seq_port = snd_seq_create_simple_port(handle, "Network",
262
 
                                              SND_SEQ_PORT_CAP_READ |
263
 
                                              SND_SEQ_PORT_CAP_WRITE |
264
 
                                              SND_SEQ_PORT_CAP_SUBS_READ |
265
 
                                              SND_SEQ_PORT_CAP_SUBS_WRITE,
266
 
                                              SND_SEQ_PORT_TYPE_MIDI_GENERIC);
267
 
        if (seq_port < 0) {
268
 
                perror("create seq port");
269
 
                exit(1);
270
 
        }
271
 
        if (verbose)
272
 
                fprintf(stderr, _("sequencer opened: %d:%d\n"),
273
 
                        snd_seq_client_id(handle), seq_port);
274
 
 
275
 
        /* explicit subscriptions */
276
 
        if (source) {
277
 
                /* read subscription */
278
 
                if (snd_seq_parse_address(handle, &addr, source) < 0) {
279
 
                        fprintf(stderr, _("invalid source address %s\n"), source);
280
 
                        exit(1);
281
 
                }
282
 
                if (snd_seq_connect_from(handle, seq_port, addr.client, addr.port)) {
283
 
                        perror("read subscription");
284
 
                        exit(1);
285
 
                }
286
 
        }
287
 
        if (dest) {
288
 
                /* write subscription */
289
 
                if (snd_seq_parse_address(handle, &addr, dest) < 0) {
290
 
                        fprintf(stderr, _("invalid destination address %s\n"), dest);
291
 
                        exit(1);
292
 
                }
293
 
                if (snd_seq_connect_to(handle, seq_port, addr.client, addr.port)) {
294
 
                        perror("write subscription");
295
 
                        exit(1);
296
 
                }
297
 
        }
298
 
}
299
 
 
300
 
 
301
 
/*
302
 
 * convert from string to TCP port number
303
 
 */
304
 
static int get_port(char *service)
305
 
{
306
 
        struct servent *sp;
307
 
 
308
 
        if ((sp = getservbyname(service, "tcp")) == NULL){
309
 
                fprintf(stderr, _("service '%s' is not found in /etc/services\n"), service);
310
 
                return -1;
311
 
        }
312
 
        return sp->s_port;
313
 
}
314
 
 
315
 
/*
316
 
 * signal handler
317
 
 */
318
 
static void sigterm_exit(int sig)
319
 
{
320
 
        close_files();
321
 
        exit(1);
322
 
}
323
 
 
324
 
 
325
 
/*
326
 
 * initialize network server
327
 
 */
328
 
static void init_server(int port)
329
 
{
330
 
        int i;
331
 
        int curstate = 1;
332
 
        struct sockaddr_in addr;
333
 
 
334
 
        memset(&addr, 0, sizeof(addr));
335
 
 
336
 
        addr.sin_family = AF_INET;
337
 
        addr.sin_addr.s_addr = INADDR_ANY;
338
 
        addr.sin_port = htons(port);
339
 
 
340
 
        sockfd = socket(AF_INET, SOCK_STREAM, 0);
341
 
        if (sockfd < 0)  {
342
 
                perror("create socket");
343
 
                exit(1);
344
 
        }
345
 
        setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &curstate, sizeof(curstate));
346
 
        /* the return value is ignored.. */
347
 
 
348
 
        if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0)  {
349
 
                perror("can't bind");
350
 
                exit(1);
351
 
        }
352
 
 
353
 
        if (listen(sockfd, 5) < 0)  {
354
 
                perror("can't listen");
355
 
                exit(1);
356
 
        }
357
 
 
358
 
        cur_connected = 0;
359
 
        for (i = 0; i < max_connection; i++)
360
 
                netfd[i] = -1;
361
 
}
362
 
 
363
 
/*
364
 
 * start connection on server
365
 
 */
366
 
static void start_connection(void)
367
 
{
368
 
        struct sockaddr_in addr;
369
 
        int i;
370
 
        socklen_t addr_len;
371
 
 
372
 
        for (i = 0; i < max_connection; i++) {
373
 
                if (netfd[i] < 0)
374
 
                        break;
375
 
        }
376
 
        if (i >= max_connection) {
377
 
                fprintf(stderr, _("too many connections!\n"));
378
 
                exit(1);
379
 
        }
380
 
        memset(&addr, 0, sizeof(addr));
381
 
        addr_len = sizeof(addr);
382
 
        netfd[i] = accept(sockfd, (struct sockaddr *)&addr, &addr_len);
383
 
        if (netfd[i] < 0) {
384
 
                perror("accept");
385
 
                exit(1);
386
 
        }
387
 
        if (verbose)
388
 
                fprintf(stderr, _("accepted[%d]\n"), netfd[i]);
389
 
        cur_connected++;
390
 
}
391
 
 
392
 
/*
393
 
 * initialize network client
394
 
 */
395
 
static void init_client(char *server, int port)
396
 
{
397
 
        struct sockaddr_in addr;
398
 
        struct hostent *host;
399
 
        int curstate = 1;
400
 
        int fd;
401
 
 
402
 
        if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0){
403
 
                perror("create socket");
404
 
                exit(1);
405
 
        }
406
 
        if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &curstate, sizeof(curstate)) < 0) {
407
 
                perror("setsockopt");
408
 
                exit(1);
409
 
        }
410
 
        if ((host = gethostbyname(server)) == NULL){
411
 
                fprintf(stderr, _("can't get address %s\n"), server);
412
 
                exit(1);
413
 
        }
414
 
        addr.sin_port = htons(port);
415
 
        addr.sin_family = AF_INET;
416
 
        memcpy(&addr.sin_addr, host->h_addr, host->h_length);
417
 
        if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
418
 
                perror("connect");
419
 
                exit(1);
420
 
        }
421
 
        if (verbose)
422
 
                fprintf(stderr, _("ok.. connected\n"));
423
 
        netfd[0] = fd;
424
 
        cur_connected = 1;
425
 
}
426
 
 
427
 
/*
428
 
 * event loop
429
 
 */
430
 
static void do_loop(void)
431
 
{
432
 
        int i, rc, width;
433
 
        int seqifd_ptr, sockfd_ptr = -1, netfd_ptr;
434
 
 
435
 
        for (;;) {
436
 
                memset(pollfds, 0, pollfds_count * sizeof(struct pollfd));
437
 
                seqifd_ptr = 0;
438
 
                memcpy(pollfds, seqifds, sizeof(*seqifds)*(width = seqifds_count));
439
 
                if (server_mode) {
440
 
                        sockfd_ptr = width;
441
 
                        pollfds[width].fd = sockfd;
442
 
                        pollfds[width].events = POLLIN;
443
 
                        width++;
444
 
                }
445
 
                netfd_ptr = width;
446
 
                for (i = 0; i < max_connection; i++) {
447
 
                        if (netfd[i] >= 0) {
448
 
                                pollfds[width].fd = netfd[i];
449
 
                                pollfds[width].events = POLLIN;
450
 
                                width++;
451
 
                        }
452
 
                }
453
 
                do {
454
 
                        rc = poll(pollfds, width, -1);
455
 
                } while (rc <= 0 && errno == EINTR);
456
 
                if (rc <= 0) {
457
 
                        perror("poll");
458
 
                        exit(1);
459
 
                }
460
 
                if (server_mode) {
461
 
                        if (pollfds[sockfd_ptr].revents & (POLLIN|POLLOUT))
462
 
                                start_connection();
463
 
                }
464
 
                for (i = 0; i < seqifds_count; i++)
465
 
                        if (pollfds[seqifd_ptr + i].revents & (POLLIN|POLLOUT)) {
466
 
                                if (copy_local_to_remote())
467
 
                                        return;
468
 
                                break;
469
 
                        }
470
 
                for (i = 0; i < max_connection; i++) {
471
 
                        if (netfd[i] < 0)
472
 
                                continue;
473
 
                        if (pollfds[netfd_ptr + i].revents & (POLLIN|POLLOUT)) {
474
 
                                if (copy_remote_to_local(netfd[i])) {
475
 
                                        netfd[i] = -1;
476
 
                                        cur_connected--;
477
 
                                        if (cur_connected <= 0)
478
 
                                                return;
479
 
                                }
480
 
                        }
481
 
                }
482
 
        }
483
 
}
484
 
 
485
 
 
486
 
/*
487
 
 * flush write buffer - send data to the socket
488
 
 */
489
 
static void flush_writebuf(void)
490
 
{
491
 
        if (cur_wrlen) {
492
 
                int i;
493
 
                for (i = 0; i < max_connection; i++) {
494
 
                        if (netfd[i] >= 0)
495
 
                                write(netfd[i], writebuf, cur_wrlen);
496
 
                }
497
 
                cur_wrlen = 0;
498
 
        }
499
 
}
500
 
 
501
 
/*
502
 
 * get space from write buffer
503
 
 */
504
 
static char *get_writebuf(int len)
505
 
{
506
 
        char *buf;
507
 
        if (cur_wrlen + len >= max_wrlen)
508
 
                flush_writebuf();
509
 
        buf = writebuf + cur_wrlen;
510
 
        cur_wrlen += len;
511
 
        return buf;
512
 
}
513
 
 
514
 
static void print_event(snd_seq_event_t *ev)
515
 
{
516
 
        switch (ev->type) {
517
 
        case SND_SEQ_EVENT_CONTROLLER: 
518
 
                printf(_("Channel %2d: Control event : %5d\n"),
519
 
                        ev->data.control.channel, ev->data.control.value);
520
 
                break;
521
 
        case SND_SEQ_EVENT_PITCHBEND:
522
 
                printf(_("Channel %2d: Pitchbender   : %5d\n"), 
523
 
                        ev->data.control.channel, ev->data.control.value);
524
 
                break;
525
 
        case SND_SEQ_EVENT_NOTEON:
526
 
                printf(_("Channel %2d: Note On event : %5d\n"),
527
 
                        ev->data.control.channel, ev->data.note.note);
528
 
                break;
529
 
        case SND_SEQ_EVENT_NOTEOFF: 
530
 
                printf(_("Channel %2d: Note Off event: %5d\n"),
531
 
                       ev->data.control.channel, ev->data.note.note);           
532
 
                break;
533
 
        }
534
 
}
535
 
 
536
 
#define EVENT_PACKET_SIZE       32
537
 
 
538
 
/*
539
 
 * copy events from sequencer to port(s)
540
 
 */
541
 
static int copy_local_to_remote(void)
542
 
{
543
 
        int rc;
544
 
        snd_seq_event_t *ev;
545
 
        char *buf;
546
 
 
547
 
        while ((rc = snd_seq_event_input(handle, &ev)) >= 0 && ev) {
548
 
                if (ev->type >= SND_SEQ_EVENT_CLIENT_START &&
549
 
                    ! snd_seq_ev_is_variable_type(ev)) {
550
 
                        snd_seq_free_event(ev);
551
 
                        continue;
552
 
                }
553
 
                if (snd_seq_ev_is_variable(ev)) {
554
 
                        int len;
555
 
                        len = EVENT_PACKET_SIZE + ev->data.ext.len;
556
 
                        buf = get_writebuf(len);
557
 
                        memcpy(buf, ev, sizeof(snd_seq_event_t));
558
 
                        memcpy(buf + EVENT_PACKET_SIZE, ev->data.ext.ptr, ev->data.ext.len);
559
 
                } else {
560
 
                        buf = get_writebuf(EVENT_PACKET_SIZE);
561
 
                        memcpy(buf, ev, EVENT_PACKET_SIZE);
562
 
                }
563
 
                if (info)
564
 
                        print_event(ev);
565
 
                snd_seq_free_event(ev);
566
 
        }
567
 
        flush_writebuf();
568
 
        return 0;
569
 
}
570
 
 
571
 
/*
572
 
 * copy events from a port to sequencer
573
 
 */
574
 
static int copy_remote_to_local(int fd)
575
 
{
576
 
        int count;
577
 
        char *buf;
578
 
        snd_seq_event_t *ev;
579
 
 
580
 
        count = read(fd, readbuf, MAX_BUF_EVENTS * sizeof(snd_seq_event_t));
581
 
        buf = readbuf;
582
 
 
583
 
        if (count == 0) {
584
 
                if (verbose)
585
 
                        fprintf(stderr, _("disconnected\n"));
586
 
                return 1;
587
 
        }
588
 
 
589
 
        while (count > 0) {
590
 
                ev = (snd_seq_event_t*)buf;
591
 
                buf += EVENT_PACKET_SIZE;
592
 
                count -= EVENT_PACKET_SIZE;
593
 
                if (snd_seq_ev_is_variable(ev) && ev->data.ext.len > 0) {
594
 
                        ev->data.ext.ptr = buf;
595
 
                        buf += ev->data.ext.len;
596
 
                        count -= ev->data.ext.len;
597
 
                }
598
 
                snd_seq_ev_set_direct(ev);
599
 
                snd_seq_ev_set_source(ev, seq_port);
600
 
                snd_seq_ev_set_subs(ev);
601
 
                if (info)
602
 
                        print_event(ev);
603
 
                snd_seq_event_output(handle, ev);
604
 
        }
605
 
 
606
 
        snd_seq_drain_output(handle);
607
 
        return 0;
608
 
}
609